From bd1c9ce363a782cdedb6d04b483c29bc9cf05d70 Mon Sep 17 00:00:00 2001 From: Christoph Olszowka Date: Fri, 6 Oct 2017 22:34:34 +0200 Subject: [PATCH] Add ruby and tooling: RSpec, Rubocop, Overcommit, Guard, .gitignore, .editorconfig --- .editorconfig | 15 ++++++ .gitignore | 2 + .overcommit.yml | 40 ++++++++++++++++ .rspec | 4 ++ .rubocop | 3 ++ .rubocop.yml | 47 +++++++++++++++++++ .ruby-version | 1 + .simplecov | 3 ++ Gemfile | 21 +++++++++ Gemfile.lock | 111 ++++++++++++++++++++++++++++++++++++++++++++ Guardfile | 101 ++++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 102 ++++++++++++++++++++++++++++++++++++++++ 12 files changed, 450 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100755 .overcommit.yml create mode 100644 .rspec create mode 100644 .rubocop create mode 100644 .rubocop.yml create mode 100644 .ruby-version create mode 100644 .simplecov create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Guardfile create mode 100644 spec/spec_helper.rb diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..ce3bf999 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# http://EditorConfig.org +root = true + +[*] +# Unix-style newlines +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# Default indentation +indent_style = space +indent_size = 2 + +# Set default charset +charset = utf-8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..96a0d9db --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +coverage +tmp diff --git a/.overcommit.yml b/.overcommit.yml new file mode 100755 index 00000000..b1635c5d --- /dev/null +++ b/.overcommit.yml @@ -0,0 +1,40 @@ +# extend the default configuration defined in: +# https://github.com/brigade/overcommit/blob/master/config/default.yml +# +# At the topmost level of this YAML file is a key representing type of hook +# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can +# customize each hook, such as whether to only run it on certain files (via +# `include`), whether to only display output if it fails (via `quiet`), etc. +# +# For a complete list of hooks, see: +# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook +# +# For a complete list of options that you can use to customize hooks, see: +# https://github.com/brigade/overcommit#configuration +# +PostCheckout: + BundleInstall: + enabled: true + +PostMerge: + BundleInstall: + enabled: true + +PostRewrite: + BundleInstall: + enabled: true + +PreCommit: + BundleCheck: + enabled: true + LocalPathsInGemfile: + enabled: true + RuboCop: + enabled: true + YamlSyntax: + enabled: true + +PrePush: + RSpec: + enabled: true + diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..414eb64a --- /dev/null +++ b/.rspec @@ -0,0 +1,4 @@ +--color +--format documentation +--order rand +--require spec_helper diff --git a/.rubocop b/.rubocop new file mode 100644 index 00000000..4ee03e86 --- /dev/null +++ b/.rubocop @@ -0,0 +1,3 @@ +--display-cop-names +--display-style-guide +--extra-details diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..43c7be97 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,47 @@ +# +# Our adjustments to rubocop default code policies. +# +# See http://rubocop.readthedocs.io/en/latest/ for detailed configuration options documentation + +# Additional cops for working with RSpec. See https://github.com/backus/rubocop-rspec +require: rubocop-rspec + +AllCops: + Exclude: + - 'tmp/**/*.rb' + +Metrics/BlockLength: + Exclude: + # The default guard-rspec config fails this, but it's ok. + - 'Guardfile' + - 'spec/**/*_spec.rb' + +# Big screens are common :) +Metrics/LineLength: + Max: 120 + +# We use RSpec as a format linter, so no specific classes under test neccessarily :) +RSpec/DescribeClass: + Enabled: false + +# Prefer to use the up-front message expectations +RSpec/MessageSpies: + Enabled: false + +# Prefer structure over small indentation +RSpec/NestedGroups: + Max: 5 + +Style/Documentation: + Enabled: false + +# Prefer to create "real" booleans using double negation +Style/DoubleNegation: + Enabled: false + +Style/StringLiterals: + EnforcedStyle: double_quotes + +Style/TrailingCommaInLiteral: + EnforcedStyleForMultiline: comma + diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..8e8299dc --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.4.2 diff --git a/.simplecov b/.simplecov new file mode 100644 index 00000000..3cee2731 --- /dev/null +++ b/.simplecov @@ -0,0 +1,3 @@ +SimpleCov.start do + minimum_coverage 100 +end diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..a90e4346 --- /dev/null +++ b/Gemfile @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +ruby File.read(File.join(__dir__, ".ruby-version")).strip + +group :test do + gem "rspec" + gem "simplecov" +end + +group :development do + gem "guard-bundler" + gem "guard-rspec" + gem "guard-rubocop" + + gem "overcommit" + + gem "rubocop" + gem "rubocop-rspec" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..8ffbf1dd --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,111 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.3.0) + childprocess (0.8.0) + ffi (~> 1.0, >= 1.0.11) + coderay (1.1.2) + diff-lcs (1.3) + docile (1.1.5) + ffi (1.9.18) + formatador (0.2.5) + guard (2.14.1) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.1.0) + bundler (~> 1.0) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + guard-rspec (4.7.3) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) + guard-rubocop (1.3.0) + guard (~> 2.0) + rubocop (~> 0.20) + iniparse (1.4.4) + json (2.1.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + lumberjack (1.0.12) + method_source (0.9.0) + nenv (0.3.0) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + overcommit (0.41.0) + childprocess (~> 0.6, >= 0.6.3) + iniparse (~> 1.4) + parallel (1.12.0) + parser (2.4.0.0) + ast (~> 2.2) + powerpack (0.1.1) + pry (0.11.1) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + rainbow (2.2.2) + rake + rake (12.1.0) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rubocop (0.50.0) + parallel (~> 1.10) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 2.2.2, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + rubocop-rspec (1.18.0) + rubocop (>= 0.50.0) + ruby-progressbar (1.9.0) + ruby_dep (1.5.0) + shellany (0.0.1) + simplecov (0.15.1) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + thor (0.20.0) + unicode-display_width (1.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-bundler + guard-rspec + guard-rubocop + overcommit + rspec + rubocop + rubocop-rspec + simplecov + +RUBY VERSION + ruby 2.4.2p198 + +BUNDLED WITH + 1.15.4 diff --git a/Guardfile b/Guardfile new file mode 100644 index 00000000..4efde883 --- /dev/null +++ b/Guardfile @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +## Uncomment and set this to only include directories you want to watch +# directories %w(app lib config test spec features) \ +# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")} + +## Note: if you are using the `directories` clause above and you are not +## watching the project directory ('.'), then you will want to move +## the Guardfile to a watched dir and symlink it back, e.g. +# +# $ mkdir config +# $ mv Guardfile config/ +# $ ln -s config/Guardfile . +# +# and, you'll have to watch "config/Guardfile" instead of "Guardfile" + +guard :bundler do + require "guard/bundler" + require "guard/bundler/verify" + helper = Guard::Bundler::Verify.new + + files = ["Gemfile"] + files += Dir["*.gemspec"] if files.any? { |f| helper.uses_gemspec?(f) } + + # Assume files are symlinked from somewhere + files.each { |file| watch(helper.real_path(file)) } +end + +# Note: The cmd option is now required due to the increasing number of ways +# rspec may be run, below are examples of the most common uses. +# * bundler: 'bundle exec rspec' +# * bundler binstubs: 'bin/rspec' +# * spring: 'bin/rspec' (This will use spring if running and you have +# installed the spring binstubs per the docs) +# * zeus: 'zeus rspec' (requires the server to be started separately) +# * 'just' rspec: 'rspec' + +guard :rspec, cmd: "bundle exec rspec" do + require "guard/rspec/dsl" + dsl = Guard::RSpec::Dsl.new(self) + + # Feel free to open issues for suggestions and improvements + + # RSpec files + rspec = dsl.rspec + watch(rspec.spec_helper) { rspec.spec_dir } + watch(rspec.spec_support) { rspec.spec_dir } + watch(rspec.spec_files) + + # Ruby files + ruby = dsl.ruby + dsl.watch_spec_files_for(ruby.lib_files) + + # Rails files + rails = dsl.rails(view_extensions: %w[erb haml slim]) + dsl.watch_spec_files_for(rails.app_files) + dsl.watch_spec_files_for(rails.views) + + watch(rails.controllers) do |m| + [ + rspec.spec.call("routing/#{m[1]}_routing"), + rspec.spec.call("controllers/#{m[1]}_controller"), + rspec.spec.call("acceptance/#{m[1]}"), + ] + end + + # Rails config changes + watch(rails.spec_helper) { rspec.spec_dir } + watch(rails.routes) { "#{rspec.spec_dir}/routing" } + watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" } + + # Capybara features specs + watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") } + watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") } + + # Turnip features and steps + watch(%r{^spec/acceptance/(.+)\.feature$}) + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m| + Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance" + end +end + +rubocop_cli_args = [] + +if ENV["AUTOCORRECT"] + puts "*" * 80, "Rubocop auto-correct mode enabled", "*" * 80 + rubocop_cli_args << "--auto-correct" +else + puts "*" * 80 + puts "You can set Rubocop to auto-correct fixable offenses by setting ENV['AUTOCORRECT']" + puts "e.g. `$ AUTOCORRECT=yesplease guard`" + puts "*" * 80 +end + +guard :rubocop, run_on_start: true, cli: rubocop_cli_args.join(" ") do + watch(/.+\.rb$/) + watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) } +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..8942ba26 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require "simplecov" + +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # This allows you to limit a spec run to individual examples or groups + # # you care about by tagging them with `:focus` metadata. When nothing + # # is tagged with `:focus`, all examples get run. RSpec also provides + # # aliases for `it`, `describe`, and `context` that include `:focus` + # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + # config.filter_run_when_matching :focus + # + # # Allows RSpec to persist some state between runs in order to support + # # the `--only-failures` and `--next-failure` CLI options. We recommend + # # you configure your source control system to ignore this file. + # config.example_status_persistence_file_path = "spec/examples.txt" + # + # # Limits the available syntax to the non-monkey patched syntax that is + # # recommended. For more details, see: + # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + # config.disable_monkey_patching! + # + # # This setting enables warnings. It's recommended, but in some cases may + # # be too noisy due to issues in dependencies. + # config.warnings = true + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = "doc" + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed +end