diff --git a/.gitignore b/.gitignore index a4cd169ec1c396787220eb065d1cc7a356d68d45..7d9ad4550cbfb7f69dd37158d006708ed931b11c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,9 @@ **/.bundle/cache **/vendor/bundle **/vendor/ruby +**/vendor/bundle-standalone/ruby/*/bin **/vendor/bundle-standalone/ruby/*/cache +**/vendor/bundle-standalone/ruby/*/extensions **/vendor/bundle-standalone/ruby/*/gems/*/* **/vendor/bundle-standalone/ruby/*/specifications @@ -39,6 +41,17 @@ **/vendor/bundle-standalone/ruby/*/gems/thread_safe-*/lib **/vendor/bundle-standalone/ruby/*/gems/tzinfo-*/lib +# Ignore rubocop dependencies we don't wish to vendor +**/vendor/bundle-standalone/ruby/*/gems/ast-*/ +**/vendor/bundle-standalone/ruby/*/gems/jaro_winkler-*/ +**/vendor/bundle-standalone/ruby/*/gems/parallel-*/ +**/vendor/bundle-standalone/ruby/*/gems/parser-*/ +**/vendor/bundle-standalone/ruby/*/gems/powerpack-*/ +**/vendor/bundle-standalone/ruby/*/gems/rainbow-*/ +**/vendor/bundle-standalone/ruby/*/gems/rubocop-*/ +**/vendor/bundle-standalone/ruby/*/gems/ruby-progressbar-*/ +**/vendor/bundle-standalone/ruby/*/gems/unicode-display_width-*/ + # Ignore `bin` contents (again). /bin diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 36281a4d62a3cc3a0b1572b532f341897a0d9a95..d6cfcb03bc735c56f4ded87cdbd2d56ce25979ca 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -5,9 +5,7 @@ AllCops: - '**/vendor/**/*' DisplayCopNames: false -require: - - ./Homebrew/rubocops.rb - - rubocop-rspec +require: ./Homebrew/rubocops.rb # enable all formulae audits FormulaAudit: diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index b5dd08187bf88118d73518a35f723e94e9ac9254..aed555d72a824ddc9c29d309444863bf828f78bb 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -1,5 +1,6 @@ require_relative "load_path" +require "rubocop-rspec" require "rubocops/formula_desc_cop" require "rubocops/components_order_cop" require "rubocops/components_redundancy_cop" diff --git a/Library/Homebrew/test/Gemfile b/Library/Homebrew/test/Gemfile index 6ff11dc88d51c985a304148a214bd7229178f9c1..74f7fe4225d06e59b863c0f02b1e77f316fbe1c2 100644 --- a/Library/Homebrew/test/Gemfile +++ b/Library/Homebrew/test/Gemfile @@ -8,7 +8,6 @@ gem "rspec-its", require: false gem "rspec-retry", require: false gem "rspec-wait", require: false gem "rubocop", HOMEBREW_RUBOCOP_VERSION -gem "rubocop-rspec", require: false group :development do gem "ronn", require: false diff --git a/Library/Homebrew/vendor/Gemfile b/Library/Homebrew/vendor/Gemfile index 0ea1675a5a45ad28ea6ae734aa22fcd304d2e528..93cfca2cd7cb6b208262ff7317692408e7a50414 100644 --- a/Library/Homebrew/vendor/Gemfile +++ b/Library/Homebrew/vendor/Gemfile @@ -5,3 +5,8 @@ gem "concurrent-ruby" gem "backports" gem "plist" gem "ruby-macho" +gem "rubocop-rspec" + +# not actually vendored but used to ensure the version matches here. +require_relative "../constants" +gem "rubocop", HOMEBREW_RUBOCOP_VERSION diff --git a/Library/Homebrew/vendor/Gemfile.lock b/Library/Homebrew/vendor/Gemfile.lock index 78396810246125ac4322f35cfc2e4b2c6fe0edce..910bf2da6251cfab31e11ad083284a7dd116aea4 100644 --- a/Library/Homebrew/vendor/Gemfile.lock +++ b/Library/Homebrew/vendor/Gemfile.lock @@ -6,16 +6,35 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + ast (2.4.0) backports (3.11.4) concurrent-ruby (1.0.5) i18n (1.1.0) concurrent-ruby (~> 1.0) + jaro_winkler (1.5.1) minitest (5.11.3) + parallel (1.12.1) + parser (2.5.1.2) + ast (~> 2.4.0) plist (3.4.0) + powerpack (0.1.2) + rainbow (3.0.0) + rubocop (0.59.1) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.5, != 2.5.1.1) + powerpack (~> 0.1) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + rubocop-rspec (1.30.0) + rubocop (>= 0.58.0) ruby-macho (2.1.0) + ruby-progressbar (1.10.0) thread_safe (0.3.6) tzinfo (1.2.5) thread_safe (~> 0.1) + unicode-display_width (1.4.0) PLATFORMS ruby @@ -25,7 +44,9 @@ DEPENDENCIES backports concurrent-ruby plist + rubocop (= 0.59.1) + rubocop-rspec ruby-macho BUNDLED WITH - 1.16.4 + 1.16.6 diff --git a/Library/Homebrew/vendor/bundle-standalone/bundler/setup.rb b/Library/Homebrew/vendor/bundle-standalone/bundler/setup.rb index 76c3cfbf1f483a8ca112d500495bab11f28fd6b5..e5b194b9c47b78b728f097c6533a938e29a42597 100644 --- a/Library/Homebrew/vendor/bundle-standalone/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle-standalone/bundler/setup.rb @@ -9,7 +9,18 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.11.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thread_safe-0.3.6/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-1.2.5/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-5.2.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/backports-3.11.4/lib" $:.unshift "#{path}/" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-18/2.3.0/jaro_winkler-1.5.1" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/jaro_winkler-1.5.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.12.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.5.1.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.4.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/powerpack-0.1.2/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.4.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.59.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.30.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.1.0/lib" diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/config/default.yml b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/config/default.yml new file mode 100644 index 0000000000000000000000000000000000000000..7fc26d85898f8063cd87b6ecb6fd32da6fb20bf7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/config/default.yml @@ -0,0 +1,451 @@ +--- +AllCops: + RSpec: + Patterns: + - _spec.rb + - "(?:^|/)spec/" + RSpec/FactoryBot: + Patterns: + - spec/factories.rb + - spec/factories/**/*.rb + - features/support/factories/**/*.rb + +RSpec/AlignLeftLetBrace: + Description: Checks that left braces for adjacent single line lets are aligned. + Enabled: false + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AlignLeftLetBrace + +RSpec/AlignRightLetBrace: + Description: Checks that right braces for adjacent single line lets are aligned. + Enabled: false + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AlignRightLetBrace + +RSpec/AnyInstance: + Description: Check that instances are not being stubbed globally. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AnyInstance + +RSpec/AroundBlock: + Description: Checks that around blocks actually run the test. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AroundBlock + +RSpec/Be: + Description: Check for expectations where `be` is used without argument. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Be + +RSpec/BeEql: + Description: Check for expectations where `be(...)` can replace `eql(...)`. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEql + +RSpec/BeforeAfterAll: + Description: Check that before/after(:all) isn't being used. + Enabled: true + Exclude: + - spec/spec_helper.rb + - spec/rails_helper.rb + - spec/support/**/*.rb + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll + +RSpec/ContextWording: + Description: "`context` block descriptions should start with 'when', or 'with'." + Enabled: true + Prefixes: + - when + - with + - without + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextWording + +RSpec/DescribeClass: + Description: Check that the first argument to the top level describe is a constant. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass + +RSpec/DescribeMethod: + Description: Checks that the second argument to `describe` specifies a method. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeMethod + +RSpec/DescribeSymbol: + Description: Avoid describing symbols. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeSymbol + +RSpec/DescribedClass: + Description: Checks that tests use `described_class`. + SkipBlocks: false + Enabled: true + EnforcedStyle: described_class + SupportedStyles: + - described_class + - explicit + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClass + +RSpec/EmptyExampleGroup: + Description: Checks if an example group does not include any tests. + Enabled: true + CustomIncludeMethods: [] + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyExampleGroup + +RSpec/EmptyLineAfterExampleGroup: + Description: Checks if there is an empty line after example group blocks. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterExampleGroup + +RSpec/EmptyLineAfterFinalLet: + Description: Checks if there is an empty line after the last let block. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterFinalLet + +RSpec/EmptyLineAfterHook: + Description: Checks if there is an empty line after hook blocks. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterHook + +RSpec/EmptyLineAfterSubject: + Description: Checks if there is an empty line after subject block. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterSubject + +RSpec/ExampleLength: + Description: Checks for long examples. + Enabled: true + Max: 5 + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleLength + +RSpec/ExampleWithoutDescription: + Description: Checks for examples without a description. + Enabled: true + EnforcedStyle: always_allow + SupportedStyles: + - always_allow + - single_line_only + - disallow + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWithoutDescription + +RSpec/ExampleWording: + Description: Checks for common mistakes in example descriptions. + Enabled: true + CustomTransform: + be: is + BE: IS + have: has + HAVE: HAS + IgnoredWords: [] + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWording + +RSpec/ExpectActual: + Description: Checks for `expect(...)` calls containing literal values. + Enabled: true + Exclude: + - spec/routing/**/* + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectActual + +RSpec/ExpectChange: + Description: Checks for consistent style of change matcher. + Enabled: true + EnforcedStyle: method_call + SupportedStyles: + - method_call + - block + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectChange + +RSpec/ExpectInHook: + Enabled: true + Description: Do not use `expect` in hooks such as `before`. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectInHook + +RSpec/ExpectOutput: + Description: Checks for opportunities to use `expect { ... }.to output`. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectOutput + +RSpec/FilePath: + Description: Checks that spec file paths are consistent with the test subject. + Enabled: true + CustomTransform: + RuboCop: rubocop + RSpec: rspec + IgnoreMethods: false + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FilePath + +RSpec/Focus: + Description: Checks if examples are focused. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Focus + +RSpec/HookArgument: + Description: Checks the arguments passed to `before`, `around`, and `after`. + Enabled: true + EnforcedStyle: implicit + SupportedStyles: + - implicit + - each + - example + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HookArgument + +RSpec/HooksBeforeExamples: + Enabled: true + Description: Checks for before/around/after hooks that come after an example. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HooksBeforeExamples + +RSpec/ImplicitExpect: + Description: Check that a consistent implicit expectation style is used. + Enabled: true + EnforcedStyle: is_expected + SupportedStyles: + - is_expected + - should + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitExpect + +RSpec/ImplicitSubject: + Enabled: true + Description: Checks for usage of implicit subject (`is_expected` / `should`). + EnforcedStyle: single_line_only + SupportedStyles: + - single_line_only + - single_statement_only + - disallow + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitSubject + +RSpec/InstanceSpy: + Description: Checks for `instance_double` used with `have_received`. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InstanceSpy + +RSpec/InstanceVariable: + Description: Checks for instance variable usage in specs. + AssignmentOnly: false + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InstanceVariable + +RSpec/InvalidPredicateMatcher: + Description: Checks invalid usage for predicate matcher. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InvalidPredicateMatcher + +RSpec/ItBehavesLike: + Description: Checks that only one `it_behaves_like` style is used. + Enabled: true + EnforcedStyle: it_behaves_like + SupportedStyles: + - it_behaves_like + - it_should_behave_like + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ItBehavesLike + +RSpec/IteratedExpectation: + Description: Check that `all` matcher is used instead of iterating over an array. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IteratedExpectation + +RSpec/LeadingSubject: + Description: Enforce that subject is the first definition in the test. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LeadingSubject + +RSpec/LetBeforeExamples: + Description: Checks for `let` definitions that come after an example. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LetBeforeExamples + +RSpec/LetSetup: + Description: Checks unreferenced `let!` calls being used for test setup. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LetSetup + +RSpec/MessageChain: + Description: Check that chains of messages are not being stubbed. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageChain + +RSpec/MessageExpectation: + Description: Checks for consistent message expectation style. + Enabled: false + EnforcedStyle: allow + SupportedStyles: + - allow + - expect + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageExpectation + +RSpec/MessageSpies: + Description: Checks that message expectations are set using spies. + Enabled: true + EnforcedStyle: have_received + SupportedStyles: + - have_received + - receive + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageSpies + +RSpec/MissingExampleGroupArgument: + Description: Checks that the first argument to an example group is not empty. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MissingExampleGroupArgument + +RSpec/MultipleDescribes: + Description: Checks for multiple top level describes. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleDescribes + +RSpec/MultipleExpectations: + Description: Checks if examples contain too many `expect` calls. + Enabled: true + Max: 1 + AggregateFailuresByDefault: false + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleExpectations + +RSpec/MultipleSubjects: + Description: Checks if an example group defines `subject` multiple times. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleSubjects + +RSpec/NamedSubject: + Description: Checks for explicitly referenced test subjects. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NamedSubject + +RSpec/NestedGroups: + Description: Checks for nested example groups. + Enabled: true + Max: 3 + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NestedGroups + +RSpec/NotToNot: + Description: Checks for consistent method usage for negating expectations. + EnforcedStyle: not_to + SupportedStyles: + - not_to + - to_not + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot + +RSpec/OverwritingSetup: + Enabled: true + Description: Checks if there is a let/subject that overwrites an existing one. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/OverwritingSetup + +RSpec/Pending: + Enabled: false + Description: Checks for any pending or skipped examples. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Pending + +RSpec/PredicateMatcher: + Description: Prefer using predicate matcher over using predicate method directly. + Enabled: true + Strict: true + EnforcedStyle: inflected + SupportedStyles: + - inflected + - explicit + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PredicateMatcher + +RSpec/ReceiveCounts: + Enabled: true + Description: Check for `once` and `twice` receive counts matchers usage. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveCounts + +RSpec/ReceiveNever: + Enabled: true + Description: Prefer `not_to receive(...)` over `receive(...).never`. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveNever + +RSpec/RepeatedDescription: + Enabled: true + Description: Check for repeated description strings in example groups. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedDescription + +RSpec/RepeatedExample: + Enabled: true + Description: Check for repeated examples within example groups. + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExample + +RSpec/ReturnFromStub: + Enabled: true + Description: Checks for consistent style of stub's return setting. + EnforcedStyle: and_return + SupportedStyles: + - and_return + - block + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReturnFromStub + +RSpec/ScatteredLet: + Description: Checks for let scattered across the example group. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet + +RSpec/ScatteredSetup: + Description: Checks for setup scattered across multiple hooks in an example group. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredSetup + +RSpec/SharedContext: + Description: Checks for proper shared_context and shared_examples usage. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SharedContext + +RSpec/SharedExamples: + Description: Enforces use of string to titleize shared examples. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SharedExamples + +RSpec/SingleArgumentMessageChain: + Description: Checks that chains of messages contain more than one element. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain + +RSpec/SubjectStub: + Description: Checks for stubbed test subjects. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SubjectStub + +RSpec/UnspecifiedException: + Description: Checks for a specified error in checking raised errors. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/UnspecifiedException + +RSpec/VerifiedDoubles: + Description: Prefer using verifying doubles over normal doubles. + Enabled: true + IgnoreNameless: true + IgnoreSymbolicNames: false + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubles + +RSpec/VoidExpect: + Description: This cop checks void `expect()`. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect + +Capybara/CurrentPathExpectation: + Description: Checks that no expectations are set on Capybara's `current_path`. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/CurrentPathExpectation + +Capybara/FeatureMethods: + Description: Checks for consistent method usage in feature specs. + Enabled: true + EnabledMethods: [] + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods + +FactoryBot/AttributeDefinedStatically: + Description: Always declare attribute values as blocks. + Enabled: true + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/AttributeDefinedStatically + +FactoryBot/CreateList: + Description: Checks for create_list usage. + Enabled: true + EnforcedStyle: create_list + SupportedStyles: + - create_list + - n_times + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/CreateList + +Rails/HttpStatus: + Description: Enforces use of symbolic or numeric value to describe HTTP status. + Enabled: true + EnforcedStyle: symbolic + SupportedStyles: + - numeric + - symbolic + StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop-rspec.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop-rspec.rb new file mode 100644 index 0000000000000000000000000000000000000000..0c1719cea985b9b8880719a1a65194b5b0606eec --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop-rspec.rb @@ -0,0 +1,43 @@ +require 'pathname' +require 'yaml' + +require 'rubocop' + +require_relative 'rubocop/rspec' +require_relative 'rubocop/rspec/version' +require_relative 'rubocop/rspec/inject' +require_relative 'rubocop/rspec/node' +require_relative 'rubocop/rspec/top_level_describe' +require_relative 'rubocop/rspec/wording' +require_relative 'rubocop/rspec/util' +require_relative 'rubocop/rspec/language' +require_relative 'rubocop/rspec/language/node_pattern' +require_relative 'rubocop/rspec/concept' +require_relative 'rubocop/rspec/example_group' +require_relative 'rubocop/rspec/example' +require_relative 'rubocop/rspec/hook' +require_relative 'rubocop/cop/rspec/cop' +require_relative 'rubocop/rspec/align_let_brace' +require_relative 'rubocop/rspec/final_end_location' +require_relative 'rubocop/rspec/blank_line_separation' + +RuboCop::RSpec::Inject.defaults! + +require_relative 'rubocop/cop/rspec_cops' + +# We have to register our autocorrect incompatibilies in RuboCop's cops as well +# so we do not hit infinite loops + +module RuboCop + module Cop + module Layout + class ExtraSpacing # rubocop:disable Style/Documentation + def self.autocorrect_incompatible_with + [RSpec::AlignLeftLetBrace, RSpec::AlignRightLetBrace] + end + end + end + end +end + +RuboCop::AST::Node.include(RuboCop::RSpec::Node) diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_left_let_brace.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_left_let_brace.rb new file mode 100644 index 0000000000000000000000000000000000000000..8bbc9658edb0358f84b4a7f6ba1e64153ed389eb --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_left_let_brace.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that left braces for adjacent single line lets are aligned. + # + # @example + # + # # bad + # let(:foobar) { blahblah } + # let(:baz) { bar } + # let(:a) { b } + # + # # good + # let(:foobar) { blahblah } + # let(:baz) { bar } + # let(:a) { b } + # + class AlignLeftLetBrace < Cop + MSG = 'Align left let brace'.freeze + + def self.autocorrect_incompatible_with + [Layout::ExtraSpacing] + end + + def investigate(_processed_source) + return if processed_source.blank? + + token_aligner.offending_tokens.each do |let| + add_offense(let, location: :begin) + end + end + + def autocorrect(let) + lambda do |corrector| + corrector.insert_before( + let.loc.begin, + token_aligner.indent_for(let) + ) + end + end + + private + + def token_aligner + @token_aligner ||= + RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_right_let_brace.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_right_let_brace.rb new file mode 100644 index 0000000000000000000000000000000000000000..7eea9b9bdd12f7306792576833f152b749499273 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/align_right_let_brace.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that right braces for adjacent single line lets are aligned. + # + # @example + # + # # bad + # let(:foobar) { blahblah } + # let(:baz) { bar } + # let(:a) { b } + # + # # good + # let(:foobar) { blahblah } + # let(:baz) { bar } + # let(:a) { b } + # + class AlignRightLetBrace < Cop + MSG = 'Align right let brace'.freeze + + def self.autocorrect_incompatible_with + [Layout::ExtraSpacing] + end + + def investigate(_processed_source) + return if processed_source.blank? + + token_aligner.offending_tokens.each do |let| + add_offense(let, location: :end) + end + end + + def autocorrect(let) + lambda do |corrector| + corrector.insert_before( + let.loc.end, + token_aligner.indent_for(let) + ) + end + end + + private + + def token_aligner + @token_aligner ||= + RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/any_instance.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/any_instance.rb new file mode 100644 index 0000000000000000000000000000000000000000..a3890a09140f078988f76681a089470fbbabc267 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/any_instance.rb @@ -0,0 +1,42 @@ +module RuboCop + module Cop + module RSpec + # Check that instances are not being stubbed globally. + # + # Prefer instance doubles over stubbing any instance of a class + # + # @example + # # bad + # describe MyClass do + # before { allow_any_instance_of(MyClass).to receive(:foo) } + # end + # + # # good + # describe MyClass do + # let(:my_instance) { instance_double(MyClass) } + # + # before do + # allow(MyClass).to receive(:new).and_return(my_instance) + # allow(my_instance).to receive(:foo) + # end + # end + class AnyInstance < Cop + MSG = 'Avoid stubbing using `%<method>s`.'.freeze + + def_node_matcher :disallowed_stub, <<-PATTERN + (send _ ${:any_instance :allow_any_instance_of :expect_any_instance_of} ...) + PATTERN + + def on_send(node) + disallowed_stub(node) do |method| + add_offense( + node, + location: :expression, + message: format(MSG, method: method) + ) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/around_block.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/around_block.rb new file mode 100644 index 0000000000000000000000000000000000000000..42761e79ea5feeb1def3594d4bfbed162d97d48d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/around_block.rb @@ -0,0 +1,71 @@ +module RuboCop + module Cop + module RSpec + # Checks that around blocks actually run the test. + # + # @example + # # bad + # around do + # some_method + # end + # + # around do |test| + # some_method + # end + # + # # good + # around do |test| + # some_method + # test.call + # end + # + # around do |test| + # some_method + # test.run + # end + class AroundBlock < Cop + MSG_NO_ARG = 'Test object should be passed to around block.'.freeze + MSG_UNUSED_ARG = 'You should call `%<arg>s.call` '\ + 'or `%<arg>s.run`.'.freeze + + def_node_matcher :hook, <<-PATTERN + (block {(send nil? :around) (send nil? :around sym)} (args $...) ...) + PATTERN + + def_node_search :find_arg_usage, <<-PATTERN + {(send $... {:call :run}) (send _ _ $...) (yield $...) (block-pass $...)} + PATTERN + + def on_block(node) + hook(node) do |(example_proxy)| + if example_proxy.nil? + add_no_arg_offense(node) + else + check_for_unused_proxy(node, example_proxy) + end + end + end + + private + + def add_no_arg_offense(node) + add_offense(node, location: :expression, message: MSG_NO_ARG) + end + + def check_for_unused_proxy(block, proxy) + name, = *proxy + + find_arg_usage(block) do |usage| + return if usage.include?(s(:lvar, name)) + end + + add_offense( + proxy, + location: :expression, + message: format(MSG_UNUSED_ARG, arg: name) + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be.rb new file mode 100644 index 0000000000000000000000000000000000000000..1347811b10a7c1373f669880e170f9fe366b84a6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be.rb @@ -0,0 +1,35 @@ +module RuboCop + module Cop + module RSpec + # Check for expectations where `be` is used without argument. + # + # The `be` matcher is too generic, as it pass on everything that is not + # nil or false. If that is the exact intend, use `be_truthy`. In all other + # cases it's better to specify what exactly is the expected value. + # + # @example + # + # # bad + # expect(foo).to be + # + # # good + # expect(foo).to be_truthy + # expect(foo).to be 1.0 + # expect(foo).to be(true) + # + class Be < Cop + MSG = 'Don\'t use `be` without an argument.'.freeze + + def_node_matcher :be_without_args, <<-PATTERN + (send _ {:to :not_to :to_not} $(send nil? :be)) + PATTERN + + def on_send(node) + be_without_args(node) do |matcher| + add_offense(matcher, location: :selector) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be_eql.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be_eql.rb new file mode 100644 index 0000000000000000000000000000000000000000..be0ca2858d8ed947365f2f6e8411cdd6397335b1 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/be_eql.rb @@ -0,0 +1,55 @@ +module RuboCop + module Cop + module RSpec + # Check for expectations where `be(...)` can replace `eql(...)`. + # + # The `be` matcher compares by identity while the `eql` matcher + # compares using `eql?`. Integers, floats, booleans, symbols, and nil + # can be compared by identity and therefore the `be` matcher is + # preferable as it is a more strict test. + # + # @example + # + # # bad + # expect(foo).to eql(1) + # expect(foo).to eql(1.0) + # expect(foo).to eql(true) + # expect(foo).to eql(false) + # expect(foo).to eql(:bar) + # expect(foo).to eql(nil) + # + # # good + # expect(foo).to be(1) + # expect(foo).to be(1.0) + # expect(foo).to be(true) + # expect(foo).to be(false) + # expect(foo).to be(:bar) + # expect(foo).to be(nil) + # + # This cop only looks for instances of `expect(...).to eql(...)`. We + # do not check `to_not` or `not_to` since `!eql?` is more strict + # than `!equal?`. We also do not try to flag `eq` because if + # `a == b`, and `b` is comparable by identity, `a` is still not + # necessarily the same type as `b` since the `#==` operator can + # coerce objects for comparison. + # + class BeEql < Cop + MSG = 'Prefer `be` over `eql`.'.freeze + + def_node_matcher :eql_type_with_identity, <<-PATTERN + (send _ :to $(send nil? :eql {true false int float sym nil_type?})) + PATTERN + + def on_send(node) + eql_type_with_identity(node) do |eql| + add_offense(eql, location: :selector) + end + end + + def autocorrect(node) + ->(corrector) { corrector.replace(node.loc.selector, 'be') } + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/before_after_all.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/before_after_all.rb new file mode 100644 index 0000000000000000000000000000000000000000..bf9f93df8db16f0ce55c43b40cb0d7b9bc9e0271 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/before_after_all.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Check that before/after(:all) isn't being used. + # + # @example + # # bad + # # + # # Faster but risk of state leaking between examples + # # + # describe MyClass do + # before(:all) { Widget.create } + # after(:all) { Widget.delete_all } + # end + # + # # good + # # + # # Slower but examples are properly isolated + # # + # describe MyClass do + # before(:each) { Widget.create } + # after(:each) { Widget.delete_all } + # end + class BeforeAfterAll < Cop + MSG = 'Beware of using `%<hook>s` as it may cause state to leak '\ + 'between tests. If you are using `rspec-rails`, and '\ + '`use_transactional_fixtures` is enabled, then records created '\ + 'in `%<hook>s` are not automatically rolled back.'.freeze + + def_node_matcher :before_or_after_all, <<-PATTERN + $(send _ {:before :after} (sym {:all :context})) + PATTERN + + def on_send(node) + before_or_after_all(node) do |hook| + add_offense( + node, + location: :expression, + message: format(MSG, hook: hook.source) + ) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb new file mode 100644 index 0000000000000000000000000000000000000000..53d2cd638babea3a0253ce75def2eebe219c3458 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb @@ -0,0 +1,42 @@ +module RuboCop + module Cop + module RSpec + module Capybara + # Checks that no expectations are set on Capybara's `current_path`. + # + # The `have_current_path` matcher (http://www.rubydoc.info/github/ + # teamcapybara/capybara/master/Capybara/RSpecMatchers#have_current_path- + # instance_method) should be used on `page` to set expectations on + # Capybara's current path, since it uses Capybara's waiting + # functionality (https://github.com/teamcapybara/capybara/blob/master/ + # README.md#asynchronous-javascript-ajax-and-friends) which ensures that + # preceding actions (like `click_link`) have completed. + # + # @example + # # bad + # expect(current_path).to eq('/callback') + # expect(page.current_path).to match(/widgets/) + # + # # good + # expect(page).to have_current_path("/callback") + # expect(page).to have_current_path(/widgets/) + # + class CurrentPathExpectation < Cop + MSG = 'Do not set an RSpec expectation on `current_path` in ' \ + 'Capybara feature specs - instead, use the ' \ + '`have_current_path` matcher on `page`'.freeze + + def_node_matcher :expectation_set_on_current_path, <<-PATTERN + (send nil? :expect (send {(send nil? :page) nil?} :current_path)) + PATTERN + + def on_send(node) + expectation_set_on_current_path(node) do + add_offense(node, location: :selector) + end + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/feature_methods.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/feature_methods.rb new file mode 100644 index 0000000000000000000000000000000000000000..8d60d3a771125b987b793d0d6f3a37c5856079fb --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/capybara/feature_methods.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + module Capybara + # Checks for consistent method usage in feature specs. + # + # By default, the cop disables all Capybara-specific methods that have + # the same native RSpec method (e.g. are just aliases). Some teams + # however may prefer using some of the Capybara methods (like `feature`) + # to make it obvious that the test uses Capybara, while still disable + # the rest of the methods, like `given` (alias for `let`), `background` + # (alias for `before`), etc. You can configure which of the methods to + # be enabled by using the EnabledMethods configuration option. + # + # @example + # # bad + # feature 'User logs in' do + # given(:user) { User.new } + # + # background do + # visit new_session_path + # end + # + # scenario 'with OAuth' do + # # ... + # end + # end + # + # # good + # describe 'User logs in' do + # let(:user) { User.new } + # + # before do + # visit new_session_path + # end + # + # it 'with OAuth' do + # # ... + # end + # end + class FeatureMethods < Cop + MSG = 'Use `%<replacement>s` instead of `%<method>s`.'.freeze + + # https://git.io/v7Kwr + MAP = { + background: :before, + scenario: :it, + xscenario: :xit, + given: :let, + given!: :let!, + feature: :describe + }.freeze + + def_node_matcher :spec?, <<-PATTERN + (block + (send {(const nil? :RSpec) nil?} {:describe :feature} ...) + ...) + PATTERN + + def_node_matcher :feature_method, <<-PATTERN + (block + $(send {(const nil? :RSpec) nil?} ${#{MAP.keys.map(&:inspect).join(' ')}} ...) + ...) + PATTERN + + def on_block(node) + return unless inside_spec?(node) + + feature_method(node) do |send_node, match| + next if enabled?(match) + + add_offense( + send_node, + location: :selector, + message: format(MSG, method: match, replacement: MAP[match]) + ) + end + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.loc.selector, MAP[node.method_name].to_s) + end + end + + private + + def inside_spec?(node) + return spec?(node) if root_node?(node) + + root = node.ancestors.find { |parent| root_node?(parent) } + spec?(root) + end + + def root_node?(node) + node.parent.nil? || root_with_siblings?(node.parent) + end + + def root_with_siblings?(node) + node.begin_type? && node.parent.nil? + end + + def enabled?(method_name) + enabled_methods.include?(method_name) + end + + def enabled_methods + cop_config + .fetch('EnabledMethods', []) + .map(&:to_sym) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/context_wording.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/context_wording.rb new file mode 100644 index 0000000000000000000000000000000000000000..1cfed8767c8a95de7cdc13c03abb6bb789498150 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/context_wording.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # `context` block descriptions should start with 'when', or 'with'. + # + # @see https://github.com/reachlocal/rspec-style-guide#context-descriptions + # @see http://www.betterspecs.org/#contexts + # + # @example `Prefixes` configuration option, defaults: 'when', 'with', and + # 'without' + # Prefixes: + # - when + # - with + # - without + # - if + # + # @example + # # bad + # context 'the display name not present' do + # # ... + # end + # + # # good + # context 'when the display name is not present' do + # # ... + # end + class ContextWording < Cop + MSG = 'Start context description with %<prefixes>s.'.freeze + + def_node_matcher :context_wording, <<-PATTERN + (block (send _ { :context :shared_context } $(str #bad_prefix?)) ...) + PATTERN + + def on_block(node) + context_wording(node) do |context| + add_offense(context, message: message) + end + end + + private + + def bad_prefix?(description) + !prefixes.include?(description.split.first) + end + + def prefixes + cop_config['Prefixes'] || [] + end + + def message + format(MSG, prefixes: joined_prefixes) + end + + def joined_prefixes + quoted = prefixes.map { |prefix| "'#{prefix}'" } + return quoted.first if quoted.size == 1 + + quoted << "or #{quoted.pop}" + quoted.join(', ') + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/cop.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/cop.rb new file mode 100644 index 0000000000000000000000000000000000000000..636333212b92984d8804e793f4665bfb29cbae79 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/cop.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module RuboCop + module Cop # rubocop:disable Style/Documentation + WorkaroundCop = Cop.dup + + # Clone of the the normal RuboCop::Cop::Cop class so we can rewrite + # the inherited method without breaking functionality + class WorkaroundCop + # Remove the Cop.inherited method to be a noop. Our RSpec::Cop + # class will invoke the inherited hook instead + class << self + undef inherited + def inherited(*) end + end + + # Special case `Module#<` so that the rspec support rubocop exports + # is compatible with our subclass + def self.<(other) + other.equal?(RuboCop::Cop::Cop) || super + end + end + private_constant(:WorkaroundCop) + + module RSpec + # @abstract parent class to rspec cops + # + # The criteria for whether rubocop-rspec analyzes a certain ruby file + # is configured via `AllCops/RSpec`. For example, if you want to + # customize your project to scan all files within a `test/` directory + # then you could add this to your configuration: + # + # @example configuring analyzed paths + # + # AllCops: + # RSpec: + # Patterns: + # - '_test.rb$' + # - '(?:^|/)test/' + class Cop < WorkaroundCop + include RuboCop::RSpec::Language + include RuboCop::RSpec::Language::NodePattern + + DEFAULT_CONFIGURATION = + RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec') + + DEFAULT_PATTERN_RE = Regexp.union( + DEFAULT_CONFIGURATION.fetch('Patterns') + .map(&Regexp.public_method(:new)) + ) + + # Invoke the original inherited hook so our cops are recognized + def self.inherited(subclass) + RuboCop::Cop::Cop.inherited(subclass) + end + + def relevant_file?(file) + relevant_rubocop_rspec_file?(file) && super + end + + private + + def relevant_rubocop_rspec_file?(file) + rspec_pattern =~ file + end + + def rspec_pattern + if rspec_pattern_config? + Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new))) + else + DEFAULT_PATTERN_RE + end + end + + def all_cops_config + config + .for_all_cops + end + + def rspec_pattern_config? + return unless all_cops_config.key?('RSpec') + + all_cops_config.fetch('RSpec').key?('Patterns') + end + + def rspec_pattern_config + all_cops_config + .fetch('RSpec', DEFAULT_CONFIGURATION) + .fetch('Patterns') + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_class.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_class.rb new file mode 100644 index 0000000000000000000000000000000000000000..ff2211dcf8532bdd0f50053cdb3a206cee1ad923 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_class.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Check that the first argument to the top level describe is a constant. + # + # @example + # # bad + # describe 'Do something' do + # end + # + # # good + # describe TestedClass do + # end + # + # describe "A feature example", type: :feature do + # end + class DescribeClass < Cop + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'The first argument to describe should be '\ + 'the class or module being tested.'.freeze + + def_node_matcher :valid_describe?, <<-PATTERN + { + (send {(const nil? :RSpec) nil?} :describe const ...) + (send {(const nil? :RSpec) nil?} :describe) + } + PATTERN + + def_node_matcher :describe_with_metadata, <<-PATTERN + (send {(const nil? :RSpec) nil?} :describe + !const + ... + (hash $...)) + PATTERN + + def_node_matcher :rails_metadata?, <<-PATTERN + (pair + (sym :type) + (sym {:request :feature :system :routing :view})) + PATTERN + + def_node_matcher :shared_group?, SharedGroups::ALL.block_pattern + + def on_top_level_describe(node, args) + return if shared_group?(root_node) + return if valid_describe?(node) + + describe_with_metadata(node) do |pairs| + return if pairs.any?(&method(:rails_metadata?)) + end + + add_offense(args.first, location: :expression) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_method.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_method.rb new file mode 100644 index 0000000000000000000000000000000000000000..109c556529ef2dcfc474aec8489781fd713071f2 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_method.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that the second argument to `describe` specifies a method. + # + # @example + # # bad + # describe MyClass, 'do something' do + # end + # + # # good + # describe MyClass, '#my_instance_method' do + # end + # + # describe MyClass, '.my_class_method' do + # end + class DescribeMethod < Cop + include RuboCop::RSpec::TopLevelDescribe + include RuboCop::RSpec::Util + + MSG = 'The second argument to describe should be the method '\ + "being tested. '#instance' or '.class'.".freeze + + def on_top_level_describe(_node, (_, second_arg)) + return unless second_arg && second_arg.str_type? + return if second_arg.str_content.start_with?('#', '.') + + add_offense(second_arg, location: :expression) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_symbol.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_symbol.rb new file mode 100644 index 0000000000000000000000000000000000000000..95bb0b4c779610fcd67d78f10c62cbbf36d33ec3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/describe_symbol.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Avoid describing symbols. + # + # @example + # # bad + # describe :my_method do + # # ... + # end + # + # # good + # describe '#my_method' do + # # ... + # end + # + # @see https://github.com/rspec/rspec-core/issues/1610 + class DescribeSymbol < Cop + MSG = 'Avoid describing symbols.'.freeze + + def_node_matcher :describe_symbol?, <<-PATTERN + (send {(const nil? :RSpec) nil?} :describe $sym ...) + PATTERN + + def on_send(node) + describe_symbol?(node) do |match| + add_offense(match, location: :expression) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/described_class.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/described_class.rb new file mode 100644 index 0000000000000000000000000000000000000000..cabc7666530f872c6c18b670f568616829c20606 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/described_class.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that tests use `described_class`. + # + # If the first argument of describe is a class, the class is exposed to + # each example via described_class. + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: described_class` + # # bad + # describe MyClass do + # subject { MyClass.do_something } + # end + # + # # good + # describe MyClass do + # subject { described_class.do_something } + # end + # + # @example `EnforcedStyle: explicit` + # # bad + # describe MyClass do + # subject { described_class.do_something } + # end + # + # # good + # describe MyClass do + # subject { MyClass.do_something } + # end + # + class DescribedClass < Cop + include RuboCop::RSpec::TopLevelDescribe + include ConfigurableEnforcedStyle + + DESCRIBED_CLASS = 'described_class'.freeze + MSG = 'Use `%<replacement>s` instead of `%<src>s`.'.freeze + + def_node_matcher :common_instance_exec_closure?, <<-PATTERN + (block (send (const nil? {:Class :Module}) :new ...) ...) + PATTERN + + def_node_matcher :rspec_block?, + RuboCop::RSpec::Language::ALL.block_pattern + + def_node_matcher :scope_changing_syntax?, '{def class module}' + + def on_block(node) + # In case the explicit style is used, we needs to remember what's + # being described. Thus, we use an ivar for @described_class. + describe, @described_class, body = described_constant(node) + + return if body.nil? + return unless top_level_describe?(describe) + + find_usage(body) do |match| + add_offense( + match, + location: :expression, + message: message(match.const_name) + ) + end + end + + def autocorrect(node) + replacement = if style == :described_class + DESCRIBED_CLASS + else + @described_class.const_name + end + lambda do |corrector| + corrector.replace(node.loc.expression, replacement) + end + end + + private + + def find_usage(node, &block) + yield(node) if offensive?(node) + + return if scope_change?(node) || node.const_type? + + node.each_child_node do |child| + find_usage(child, &block) + end + end + + def message(offense) + if style == :described_class + format(MSG, replacement: DESCRIBED_CLASS, src: offense) + else + format(MSG, replacement: @described_class.const_name, + src: DESCRIBED_CLASS) + end + end + + def scope_change?(node) + scope_changing_syntax?(node) || + common_instance_exec_closure?(node) || + skippable_block?(node) + end + + def skippable_block?(node) + node.block_type? && !rspec_block?(node) && skip_blocks? + end + + def skip_blocks? + cop_config['SkipBlocks'].equal?(true) + end + + def offensive?(node) + if style == :described_class + node.eql?(@described_class) + else + node.send_type? && node.method_name == :described_class + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_example_group.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_example_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..3ee001dd64149b92917afc392b509ad8873898c7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_example_group.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if an example group does not include any tests. + # + # This cop is configurable using the `CustomIncludeMethods` option + # + # @example usage + # + # # bad + # describe Bacon do + # let(:bacon) { Bacon.new(chunkiness) } + # let(:chunkiness) { false } + # + # context 'extra chunky' do # flagged by rubocop + # let(:chunkiness) { true } + # end + # + # it 'is chunky' do + # expect(bacon.chunky?).to be_truthy + # end + # end + # + # # good + # describe Bacon do + # let(:bacon) { Bacon.new(chunkiness) } + # let(:chunkiness) { false } + # + # it 'is chunky' do + # expect(bacon.chunky?).to be_truthy + # end + # end + # + # @example configuration + # + # # .rubocop.yml + # # RSpec/EmptyExampleGroup: + # # CustomIncludeMethods: + # # - include_tests + # + # # spec_helper.rb + # RSpec.configure do |config| + # config.alias_it_behaves_like_to(:include_tests) + # end + # + # # bacon_spec.rb + # describe Bacon do + # let(:bacon) { Bacon.new(chunkiness) } + # let(:chunkiness) { false } + # + # context 'extra chunky' do # not flagged by rubocop + # let(:chunkiness) { true } + # + # include_tests 'shared tests' + # end + # end + # + class EmptyExampleGroup < Cop + MSG = 'Empty example group detected.'.freeze + + def_node_search :contains_example?, <<-PATTERN + { + #{(Examples::ALL + Includes::ALL).send_pattern} + (send _ #custom_include? ...) + } + PATTERN + + def on_block(node) + return unless example_group?(node) && !contains_example?(node) + + add_offense(node.send_node, location: :expression) + end + + private + + def custom_include?(method_name) + custom_include_methods.include?(method_name) + end + + def custom_include_methods + cop_config + .fetch('CustomIncludeMethods', []) + .map(&:to_sym) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_example_group.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_example_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..4279e68eb06b401a62abca6551d187be76f8b3de --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_example_group.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if there is an empty line after example group blocks. + # + # @example + # # bad + # RSpec.describe Foo do + # describe '#bar' do + # end + # describe '#baz' do + # end + # end + # + # # good + # RSpec.describe Foo do + # describe '#bar' do + # end + # + # describe '#baz' do + # end + # end + # + class EmptyLineAfterExampleGroup < Cop + include RuboCop::RSpec::BlankLineSeparation + + MSG = 'Add an empty line after `%<example_group>s`.'.freeze + + def on_block(node) + return unless example_group?(node) + return if last_child?(node) + + missing_separating_line(node) do |location| + add_offense( + node, + location: location, + message: format(MSG, example_group: node.method_name) + ) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_final_let.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_final_let.rb new file mode 100644 index 0000000000000000000000000000000000000000..f5f1ba77fa06d401255f59d7d18dcc5e369442e8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_final_let.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if there is an empty line after the last let block. + # + # @example + # # bad + # let(:foo) { bar } + # let(:something) { other } + # it { does_something } + # + # # good + # let(:foo) { bar } + # let(:something) { other } + # + # it { does_something } + class EmptyLineAfterFinalLet < Cop + include RuboCop::RSpec::BlankLineSeparation + + MSG = 'Add an empty line after the last `let` block.'.freeze + + def on_block(node) + return unless example_group_with_body?(node) + + latest_let = node.body.child_nodes.select { |child| let?(child) }.last + + return if latest_let.nil? + return if last_child?(latest_let) + + missing_separating_line(latest_let) do |location| + add_offense(latest_let, location: location) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_hook.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_hook.rb new file mode 100644 index 0000000000000000000000000000000000000000..8ce719f5d1e142f73b9fa4ee58e0a47677506d3c --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_hook.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if there is an empty line after hook blocks. + # + # @example + # # bad + # before { do_something } + # it { does_something } + # + # # bad + # after { do_something } + # it { does_something } + # + # # bad + # around { |test| test.run } + # it { does_something } + # + # # good + # before { do_something } + # + # it { does_something } + # + # # good + # after { do_something } + # + # it { does_something } + # + # # good + # around { |test| test.run } + # + # it { does_something } + # + class EmptyLineAfterHook < Cop + include RuboCop::RSpec::BlankLineSeparation + + MSG = 'Add an empty line after `%<hook>s`.'.freeze + + def on_block(node) + return unless hook?(node) + return if last_child?(node) + + missing_separating_line(node) do |location| + add_offense( + node, + location: location, + message: format(MSG, hook: node.method_name) + ) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_subject.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_subject.rb new file mode 100644 index 0000000000000000000000000000000000000000..e41824b2b5a4fbf579384afef2d03d42e7511a7a --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/empty_line_after_subject.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if there is an empty line after subject block. + # + # @example + # # bad + # subject(:obj) { described_class } + # let(:foo) { bar } + # + # # good + # subject(:obj) { described_class } + # + # let(:foo) { bar } + class EmptyLineAfterSubject < Cop + include RuboCop::RSpec::BlankLineSeparation + + MSG = 'Add empty line after `subject`.'.freeze + + def on_block(node) + return unless subject?(node) && !in_spec_block?(node) + return if last_child?(node) + + missing_separating_line(node) do |location| + add_offense(node, location: location, message: MSG) + end + end + + private + + def in_spec_block?(node) + node.each_ancestor(:block).any? do |ancestor| + Examples::ALL.include?(ancestor.method_name) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_length.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_length.rb new file mode 100644 index 0000000000000000000000000000000000000000..a867bf530d05cb73ca8a6b044a7c4702704a1650 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_length.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for long examples. + # + # A long example is usually more difficult to understand. Consider + # extracting out some behaviour, e.g. with a `let` block, or a helper + # method. + # + # @example + # # bad + # it do + # service = described_class.new + # more_setup + # more_setup + # result = service.call + # expect(result).to be(true) + # end + # + # # good + # it do + # service = described_class.new + # result = service.call + # expect(result).to be(true) + # end + class ExampleLength < Cop + include CodeLength + + MSG = 'Example has too many lines [%<total>d/%<max>d].'.freeze + + def on_block(node) + return unless example?(node) + + length = code_length(node) + + return unless length > max_length + + add_offense(node, location: :expression, message: message(length)) + end + + private + + def code_length(node) + node.source.lines[1..-2].count { |line| !irrelevant_line(line) } + end + + def message(length) + format(MSG, total: length, max: max_length) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_without_description.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_without_description.rb new file mode 100644 index 0000000000000000000000000000000000000000..fdb7316c081285ecb22eba2acb067df64b4e3c1f --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_without_description.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for examples without a description. + # + # RSpec allows for auto-generated example descriptions when there is no + # description provided or the description is an empty one. + # + # This cop removes empty descriptions. + # It also defines whether auto-generated description is allowed, based + # on the configured style. + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: always_allow` + # # bad + # it('') { is_expected.to be_good } + # it '' do + # result = service.call + # expect(result).to be(true) + # end + # + # # good + # it { is_expected.to be_good } + # it do + # result = service.call + # expect(result).to be(true) + # end + # + # @example `EnforcedStyle: single_line_only` + # # bad + # it('') { is_expected.to be_good } + # it do + # result = service.call + # expect(result).to be(true) + # end + # + # # good + # it { is_expected.to be_good } + # + # @example `EnforcedStyle: disallow` + # # bad + # it { is_expected.to be_good } + # it do + # result = service.call + # expect(result).to be(true) + # end + class ExampleWithoutDescription < Cop + include ConfigurableEnforcedStyle + + MSG_DEFAULT_ARGUMENT = 'Omit the argument when you want to ' \ + 'have auto-generated description.'.freeze + MSG_ADD_DESCRIPTION = 'Add a description.'.freeze + + def_node_matcher :example_description, '(send nil? _ $(str $_))' + + def on_block(node) + return unless example?(node) + + check_example_without_description(node.send_node) + + example_description(node.send_node) do |message_node, message| + return unless message.to_s.empty? + + add_offense(message_node, message: MSG_DEFAULT_ARGUMENT) + end + end + + private + + def check_example_without_description(node) + return if node.arguments? + return unless disallow_empty_description?(node) + + add_offense(node, message: MSG_ADD_DESCRIPTION) + end + + def disallow_empty_description?(node) + style == :disallow || + (style == :single_line_only && node.parent.multiline?) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_wording.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_wording.rb new file mode 100644 index 0000000000000000000000000000000000000000..ba8ae11758d57abe1ec3b1cade7ab096a99c0159 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/example_wording.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for common mistakes in example descriptions. + # + # This cop will correct docstrings that begin with 'should' and 'it'. + # + # @see http://betterspecs.org/#should + # + # The autocorrect is experimental - use with care! It can be configured + # with CustomTransform (e.g. have => has) and IgnoredWords (e.g. only). + # + # @example + # # bad + # it 'should find nothing' do + # end + # + # # good + # it 'finds nothing' do + # end + # + # @example + # # bad + # it 'it does things' do + # end + # + # # good + # it 'does things' do + # end + class ExampleWording < Cop + MSG_SHOULD = 'Do not use should when describing your tests.'.freeze + MSG_IT = "Do not repeat 'it' when describing your tests.".freeze + + SHOULD_PREFIX = /\Ashould(?:n't)?\b/i + IT_PREFIX = /\Ait /i + + def_node_matcher( + :it_description, + '(block (send _ :it $(str $_) ...) ...)' + ) + + def on_block(node) + it_description(node) do |description_node, message| + if message =~ SHOULD_PREFIX + add_wording_offense(description_node, MSG_SHOULD) + elsif message =~ IT_PREFIX + add_wording_offense(description_node, MSG_IT) + end + end + end + + def autocorrect(range) + ->(corrector) { corrector.replace(range, replacement_text(range)) } + end + + private + + def add_wording_offense(node, message) + expr = node.loc.expression + + docstring = + Parser::Source::Range.new( + expr.source_buffer, + expr.begin_pos + 1, + expr.end_pos - 1 + ) + + add_offense(docstring, location: docstring, message: message) + end + + def replacement_text(range) + text = range.source + + if text =~ SHOULD_PREFIX + RuboCop::RSpec::Wording.new( + text, + ignore: ignored_words, + replace: custom_transform + ).rewrite + else + text.sub(IT_PREFIX, '') + end + end + + def custom_transform + cop_config.fetch('CustomTransform', {}) + end + + def ignored_words + cop_config.fetch('IgnoredWords', []) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_actual.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_actual.rb new file mode 100644 index 0000000000000000000000000000000000000000..9da8b7cc83278523bc9795bdc55b970b043670b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_actual.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for `expect(...)` calls containing literal values. + # + # @example + # # bad + # expect(5).to eq(price) + # expect(/foo/).to eq(pattern) + # expect("John").to eq(name) + # + # # good + # expect(price).to eq(5) + # expect(pattern).to eq(/foo/) + # expect(name).to eq("John") + # + class ExpectActual < Cop + MSG = 'Provide the actual you are testing to `expect(...)`.'.freeze + + SIMPLE_LITERALS = %i[ + true + false + nil + int + float + str + sym + complex + rational + regopt + ].freeze + + COMPLEX_LITERALS = %i[ + array + hash + pair + irange + erange + regexp + ].freeze + + def_node_matcher :expect_literal, '(send _ :expect $#literal?)' + + def on_send(node) + expect_literal(node) do |argument| + add_offense(argument, location: :expression) + end + end + + private + + # This is not implement using a NodePattern because it seems + # to not be able to match against an explicit (nil) sexp + def literal?(node) + node && (simple_literal?(node) || complex_literal?(node)) + end + + def simple_literal?(node) + SIMPLE_LITERALS.include?(node.type) + end + + def complex_literal?(node) + COMPLEX_LITERALS.include?(node.type) && + node.each_child_node.all?(&method(:literal?)) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_change.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_change.rb new file mode 100644 index 0000000000000000000000000000000000000000..552b2d763a1fa7df0b6b35ca6a29f45bdbf3b17b --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_change.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for consistent style of change matcher. + # + # Enforces either passing object and attribute as arguments to the matcher + # or passing a block that reads the attribute value. + # + # This cop can be configured using the `EnforcedStyle` option. + # + # @example `EnforcedStyle: block` + # # bad + # expect(run).to change(Foo, :bar) + # + # # good + # expect(run).to change { Foo.bar } + # + # @example `EnforcedStyle: method_call` + # # bad + # expect(run).to change { Foo.bar } + # expect(run).to change { foo.baz } + # + # # good + # expect(run).to change(Foo, :bar) + # expect(run).to change(foo, :baz) + # # also good when there are arguments or chained method calls + # expect(run).to change { Foo.bar(:count) } + # expect(run).to change { user.reload.name } + # + class ExpectChange < Cop + include ConfigurableEnforcedStyle + + MSG_BLOCK = 'Prefer `change(%<obj>s, :%<attr>s)`.'.freeze + MSG_CALL = 'Prefer `change { %<obj>s.%<attr>s }`.'.freeze + + def_node_matcher :expect_change_with_arguments, <<-PATTERN + (send nil? :change ({const send} nil? $_) (sym $_)) + PATTERN + + def_node_matcher :expect_change_with_block, <<-PATTERN + (block + (send nil? :change) + (args) + (send ({const send} nil? $_) $_) + ) + PATTERN + + def on_send(node) + return unless style == :block + + expect_change_with_arguments(node) do |receiver, message| + add_offense( + node, + message: format(MSG_CALL, obj: receiver, attr: message) + ) + end + end + + def on_block(node) + return unless style == :method_call + + expect_change_with_block(node) do |receiver, message| + add_offense( + node, + message: format(MSG_BLOCK, obj: receiver, attr: message) + ) + end + end + + def autocorrect(node) + if style == :block + autocorrect_method_call_to_block(node) + else + autocorrect_block_to_method_call(node) + end + end + + private + + def autocorrect_method_call_to_block(node) + lambda do |corrector| + expect_change_with_arguments(node) do |receiver, message| + replacement = "change { #{receiver}.#{message} }" + corrector.replace(node.loc.expression, replacement) + end + end + end + + def autocorrect_block_to_method_call(node) + lambda do |corrector| + expect_change_with_block(node) do |receiver, message| + replacement = "change(#{receiver}, :#{message})" + corrector.replace(node.loc.expression, replacement) + end + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_in_hook.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_in_hook.rb new file mode 100644 index 0000000000000000000000000000000000000000..22232f60f802b04718dcc2b7d434f02e25dd2c59 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_in_hook.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Do not use `expect` in hooks such as `before`. + # + # @example + # # bad + # before do + # expect(something).to eq 'foo' + # end + # + # # bad + # after do + # expect_any_instance_of(Something).to receive(:foo) + # end + # + # # good + # it do + # expect(something).to eq 'foo' + # end + class ExpectInHook < Cop + MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'.freeze + + def_node_search :expectation, Expectations::ALL.send_pattern + + def on_block(node) + return unless hook?(node) + return if node.body.nil? + + expectation(node.body) do |expect| + add_offense(expect, location: :selector, + message: message(expect, node)) + end + end + + private + + def message(expect, hook) + format(MSG, expect: expect.method_name, hook: hook.method_name) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_output.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_output.rb new file mode 100644 index 0000000000000000000000000000000000000000..d23e7159daf1556c9e1e6ef4dfd4ca3c96ae209c --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/expect_output.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for opportunities to use `expect { ... }.to output`. + # + # @example + # # bad + # $stdout = StringIO.new + # my_app.print_report + # $stdout = STDOUT + # expect($stdout.string).to eq('Hello World') + # + # # good + # expect { my_app.print_report }.to output('Hello World').to_stdout + class ExpectOutput < Cop + MSG = 'Use `expect { ... }.to output(...).to_%<name>s` '\ + 'instead of mutating $%<name>s.'.freeze + + def on_gvasgn(node) + return unless inside_example_scope?(node) + + variable_name, _rhs = *node + name = variable_name[1..-1] + return unless name.eql?('stdout') || name.eql?('stderr') + + add_offense(node, location: :name, message: format(MSG, name: name)) + end + + private + + # Detect if we are inside the scope of a single example + # + # We want to encourage using `expect { ... }.to output` so + # we only care about situations where you would replace with + # an expectation. Therefore, assignments to stderr or stdout + # within a `before(:all)` or otherwise outside of an example + # don't matter. + def inside_example_scope?(node) + return false if node.nil? || example_group?(node) + return true if example?(node) + return RuboCop::RSpec::Hook.new(node).example? if hook?(node) + + inside_example_scope?(node.parent) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb new file mode 100644 index 0000000000000000000000000000000000000000..21b522b79faf8df296a1fa0f102c333fe567b61d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + module FactoryBot + # Always declare attribute values as blocks. + # + # @example + # # bad + # kind [:active, :rejected].sample + # + # # good + # kind { [:active, :rejected].sample } + # + # # bad + # closed_at 1.day.from_now + # + # # good + # closed_at { 1.day.from_now } + # + # # bad + # count 1 + # + # # good + # count { 1 } + class AttributeDefinedStatically < Cop + MSG = 'Use a block to declare attribute values.'.freeze + + ATTRIBUTE_DEFINING_METHODS = %i[factory trait transient ignore].freeze + + UNPROXIED_METHODS = %i[ + __send__ + __id__ + nil? + send + object_id + extend + instance_eval + initialize + block_given? + raise + caller + method + ].freeze + + DEFINITION_PROXY_METHODS = %i[ + add_attribute + after + association + before + callback + ignore + initialize_with + sequence + skip_create + to_create + ].freeze + + RESERVED_METHODS = + DEFINITION_PROXY_METHODS + + UNPROXIED_METHODS + + ATTRIBUTE_DEFINING_METHODS + + def_node_matcher :value_matcher, <<-PATTERN + (send {self nil?} !#reserved_method? $...) + PATTERN + + def_node_search :factory_attributes, <<-PATTERN + (block (send nil? #attribute_defining_method? ...) _ { (begin $...) $(send ...) } ) + PATTERN + + def on_block(node) + factory_attributes(node).to_a.flatten.each do |attribute| + next if proc?(attribute) || association?(attribute) + + add_offense(attribute, location: :expression) + end + end + + def autocorrect(node) + if node.parenthesized? + autocorrect_replacing_parens(node) + else + autocorrect_without_parens(node) + end + end + + private + + def proc?(attribute) + value_matcher(attribute).to_a.all?(&:block_pass_type?) + end + + def association?(attribute) + argument = attribute.first_argument + argument.hash_type? && factory_key?(argument) + end + + def factory_key?(hash_node) + hash_node.keys.any? { |key| key.sym_type? && key.value == :factory } + end + + def autocorrect_replacing_parens(node) + left_braces, right_braces = braces(node) + + lambda do |corrector| + corrector.replace(node.location.begin, ' ' + left_braces) + corrector.replace(node.location.end, right_braces) + end + end + + def autocorrect_without_parens(node) + left_braces, right_braces = braces(node) + + lambda do |corrector| + argument = node.first_argument + expression = argument.location.expression + corrector.insert_before(expression, left_braces) + corrector.insert_after(expression, right_braces) + end + end + + def braces(node) + if value_hash_without_braces?(node.first_argument) + ['{ { ', ' } }'] + else + ['{ ', ' }'] + end + end + + def value_hash_without_braces?(node) + node.hash_type? && !node.braces? + end + + def reserved_method?(method_name) + RESERVED_METHODS.include?(method_name) + end + + def attribute_defining_method?(method_name) + ATTRIBUTE_DEFINING_METHODS.include?(method_name) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/create_list.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/create_list.rb new file mode 100644 index 0000000000000000000000000000000000000000..8eb690609acad5a8d9947b532414b22cdb64c7d0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/factory_bot/create_list.rb @@ -0,0 +1,149 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + module FactoryBot + # Checks for create_list usage. + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: create_list` + # # bad + # 3.times { create :user } + # + # # good + # create_list :user, 3 + # + # # good + # 3.times { |n| create :user, created_at: n.months.ago } + # + # @example `EnforcedStyle: n_times` + # # bad + # create_list :user, 3 + # + # # good + # 3.times { create :user } + class CreateList < Cop + include ConfigurableEnforcedStyle + + MSG_CREATE_LIST = 'Prefer create_list.'.freeze + MSG_N_TIMES = 'Prefer %<number>s.times.'.freeze + + def_node_matcher :n_times_block?, <<-PATTERN + (block + (send (int _) :times) + ... + ) + PATTERN + + def_node_matcher :factory_call, <<-PATTERN + (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create (sym $_) $...) + PATTERN + + def_node_matcher :factory_list_call, <<-PATTERN + (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create_list (sym $_) (int $_) $...) + PATTERN + + def on_block(node) + return unless style == :create_list + return unless n_times_block?(node) + return unless contains_only_factory?(node.body) + + add_offense(node.send_node, + location: :expression, message: MSG_CREATE_LIST) + end + + def on_send(node) + return unless style == :n_times + + factory_list_call(node) do |_receiver, _factory, count, _| + add_offense( + node, + location: :selector, + message: format(MSG_N_TIMES, number: count) + ) + end + end + + def autocorrect(node) + if style == :create_list + autocorrect_n_times_to_create_list(node) + else + autocorrect_create_list_to_n_times(node) + end + end + + private + + def contains_only_factory?(node) + if node.block_type? + factory_call(node.send_node) + else + factory_call(node) + end + end + + def autocorrect_n_times_to_create_list(node) + block = node.parent + count = block.receiver.source + replacement = factory_call_replacement(block.body, count) + + lambda do |corrector| + corrector.replace(block.loc.expression, replacement) + end + end + + def autocorrect_create_list_to_n_times(node) + replacement = generate_n_times_block(node) + lambda do |corrector| + corrector.replace(node.loc.expression, replacement) + end + end + + def generate_n_times_block(node) + receiver, factory, count, options = *factory_list_call(node) + + arguments = ":#{factory}" + options = build_options_string(options) + arguments += ", #{options}" unless options.empty? + + replacement = format_receiver(receiver) + replacement += format_method_call(node, 'create', arguments) + "#{count}.times { #{replacement} }" + end + + def factory_call_replacement(body, count) + receiver, factory, options = *factory_call(body) + + arguments = ":#{factory}, #{count}" + options = build_options_string(options) + arguments += ", #{options}" unless options.empty? + + replacement = format_receiver(receiver) + replacement += format_method_call(body, 'create_list', arguments) + replacement + end + + def build_options_string(options) + options.map(&:source).join(', ') + end + + def format_method_call(node, method, arguments) + if node.parenthesized? + "#{method}(#{arguments})" + else + "#{method} #{arguments}" + end + end + + def format_receiver(receiver) + return '' unless receiver + + "#{receiver.source}." + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/file_path.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/file_path.rb new file mode 100644 index 0000000000000000000000000000000000000000..44df621366e24b1a0993917e555a4d4e5428c355 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/file_path.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that spec file paths are consistent with the test subject. + # + # Checks the path of the spec file and enforces that it reflects the + # described class/module and its optionally called out method. + # + # With the configuration option `IgnoreMethods` the called out method will + # be ignored when determining the enforced path. + # + # With the configuration option `CustomTransform` modules or classes can + # be specified that should not as usual be transformed from CamelCase to + # snake_case (e.g. 'RuboCop' => 'rubocop' ). + # + # @example + # # bad + # whatever_spec.rb # describe MyClass + # + # # bad + # my_class_spec.rb # describe MyClass, '#method' + # + # # good + # my_class_spec.rb # describe MyClass + # + # # good + # my_class_method_spec.rb # describe MyClass, '#method' + # + # # good + # my_class/method_spec.rb # describe MyClass, '#method' + # + # @example when configuration is `IgnoreMethods: true` + # # bad + # whatever_spec.rb # describe MyClass + # + # # good + # my_class_spec.rb # describe MyClass + # + # # good + # my_class_spec.rb # describe MyClass, '#method' + # + class FilePath < Cop + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'Spec path should end with `%<suffix>s`.'.freeze + + def_node_search :const_described?, '(send _ :describe (const ...) ...)' + def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))' + + def on_top_level_describe(node, args) + return unless const_described?(node) && single_top_level_describe? + return if routing_spec?(args) + + glob = glob_for(args) + + return if filename_ends_with?(glob) + + add_offense( + node, + location: :expression, + message: format(MSG, suffix: glob) + ) + end + + private + + def routing_spec?(args) + args.any?(&method(:routing_metadata?)) + end + + def glob_for((described_class, method_name)) + "#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb" + end + + def name_glob(name) + return unless name && name.str_type? + + "*#{name.str_content.gsub(/\W/, '')}" unless ignore_methods? + end + + def expected_path(constant) + File.join( + constant.const_name.split('::').map do |name| + custom_transform.fetch(name) { camel_to_snake_case(name) } + end + ) + end + + def camel_to_snake_case(string) + string + .gsub(/([^A-Z])([A-Z]+)/, '\1_\2') + .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2') + .downcase + end + + def custom_transform + cop_config.fetch('CustomTransform', {}) + end + + def ignore_methods? + cop_config['IgnoreMethods'] + end + + def filename_ends_with?(glob) + File.fnmatch?("*#{glob}", processed_source.buffer.name) + end + + def relevant_rubocop_rspec_file?(_file) + true + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/focus.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/focus.rb new file mode 100644 index 0000000000000000000000000000000000000000..0322aae8d21ba6acde48ff3829e54455a2be09b3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/focus.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if examples are focused. + # + # @example + # # bad + # describe MyClass, focus: true do + # end + # + # describe MyClass, :focus do + # end + # + # fdescribe MyClass do + # end + # + # # good + # describe MyClass do + # end + class Focus < Cop + MSG = 'Focused spec found.'.freeze + + focusable = + ExampleGroups::GROUPS + + ExampleGroups::SKIPPED + + Examples::EXAMPLES + + Examples::SKIPPED + + focused = ExampleGroups::FOCUSED + Examples::FOCUSED + + FOCUSABLE_SELECTORS = focusable.node_pattern_union + + FOCUS_SYMBOL = s(:sym, :focus) + FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true)) + + def_node_matcher :metadata, <<-PATTERN + {(send nil? #{FOCUSABLE_SELECTORS} ... (hash $...)) + (send nil? #{FOCUSABLE_SELECTORS} $...)} + PATTERN + + def_node_matcher :focused_block?, focused.send_pattern + + def on_send(node) + focus_metadata(node) do |focus| + add_offense(focus, location: :expression) + end + end + + private + + def focus_metadata(node, &block) + yield(node) if focused_block?(node) + + metadata(node) do |matches| + matches.grep(FOCUS_SYMBOL, &block) + matches.grep(FOCUS_TRUE, &block) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hook_argument.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hook_argument.rb new file mode 100644 index 0000000000000000000000000000000000000000..2f83353c15fd4b747e431d24dff24195e1f252cc --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hook_argument.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks the arguments passed to `before`, `around`, and `after`. + # + # This cop checks for consistent style when specifying RSpec + # hooks which run for each example. There are three supported + # styles: "implicit", "each", and "example." All styles have + # the same behavior. + # + # @example when configuration is `EnforcedStyle: implicit` + # # bad + # before(:each) do + # # ... + # end + # + # # bad + # before(:example) do + # # ... + # end + # + # # good + # before do + # # ... + # end + # + # @example when configuration is `EnforcedStyle: each` + # # bad + # before(:example) do + # # ... + # end + # + # # good + # before do + # # ... + # end + # + # # good + # before(:each) do + # # ... + # end + # + # @example when configuration is `EnforcedStyle: example` + # # bad + # before(:each) do + # # ... + # end + # + # # bad + # before do + # # ... + # end + # + # # good + # before(:example) do + # # ... + # end + class HookArgument < Cop + include ConfigurableEnforcedStyle + include RangeHelp + + IMPLICIT_MSG = 'Omit the default `%<scope>p` ' \ + 'argument for RSpec hooks.'.freeze + EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'.freeze + + HOOKS = Hooks::ALL.node_pattern_union.freeze + + def_node_matcher :scoped_hook, <<-PATTERN + (block $(send _ #{HOOKS} (sym ${:each :example})) ...) + PATTERN + + def_node_matcher :unscoped_hook, "(block $(send _ #{HOOKS}) ...)" + + def on_block(node) + hook(node) do |method_send, scope_name| + return correct_style_detected if scope_name.equal?(style) + return check_implicit(method_send) unless scope_name + + style_detected(scope_name) + add_offense( + method_send, + location: :expression, + message: explicit_message(scope_name) + ) + end + end + + def autocorrect(node) + scope = implicit_style? ? '' : "(#{style.inspect})" + + lambda do |corrector| + corrector.replace(argument_range(node), scope) + end + end + + private + + def check_implicit(method_send) + style_detected(:implicit) + return if implicit_style? + + add_offense( + method_send, + location: :selector, + message: format(EXPLICIT_MSG, scope: style) + ) + end + + def explicit_message(scope) + if implicit_style? + format(IMPLICIT_MSG, scope: scope) + else + format(EXPLICIT_MSG, scope: style) + end + end + + def implicit_style? + style.equal?(:implicit) + end + + def hook(node, &block) + scoped_hook(node, &block) || unscoped_hook(node, &block) + end + + def argument_range(send_node) + range_between( + send_node.loc.selector.end_pos, + send_node.loc.expression.end_pos + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hooks_before_examples.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hooks_before_examples.rb new file mode 100644 index 0000000000000000000000000000000000000000..d81f6860a34e54e382e3bcb167d3257d102b7231 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/hooks_before_examples.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for before/around/after hooks that come after an example. + # + # @example + # # Bad + # + # it 'checks what foo does' do + # expect(foo).to be + # end + # + # before { prepare } + # after { clean_up } + # + # # Good + # before { prepare } + # after { clean_up } + # + # it 'checks what foo does' do + # expect(foo).to be + # end + # + class HooksBeforeExamples < Cop + include RangeHelp + include RuboCop::RSpec::FinalEndLocation + + MSG = 'Move `%<hook>s` above the examples in the group.'.freeze + + def_node_matcher :example_or_group?, <<-PATTERN + { + #{(Examples::ALL + ExampleGroups::ALL).block_pattern} + #{Includes::EXAMPLES.send_pattern} + } + PATTERN + + def on_block(node) + return unless example_group_with_body?(node) + + check_hooks(node.body) if multiline_block?(node.body) + end + + def autocorrect(node) + lambda do |corrector| + first_example = find_first_example(node.parent) + first_example_pos = first_example.loc.expression + indent = "\n" + ' ' * first_example.loc.column + + corrector.insert_before(first_example_pos, source(node) + indent) + corrector.remove(node_range_with_surrounding_space(node)) + end + end + + private + + def multiline_block?(block) + block.begin_type? + end + + def check_hooks(node) + first_example = find_first_example(node) + return unless first_example + + node.each_child_node do |child| + next if child.sibling_index < first_example.sibling_index + next unless hook?(child) + + add_offense( + child, + message: format(MSG, hook: child.method_name) + ) + end + end + + def find_first_example(node) + node.children.find { |sibling| example_or_group?(sibling) } + end + + def node_range_with_surrounding_space(node) + range = node_range(node) + range_by_whole_lines(range, include_final_newline: true) + end + + def source(node) + node_range(node).source + end + + def node_range(node) + range_between( + node.loc.expression.begin_pos, + final_end_location(node).end_pos + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_expect.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_expect.rb new file mode 100644 index 0000000000000000000000000000000000000000..eb3272588b2bedba42a8391d17809bbe161aedb2 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_expect.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Check that a consistent implicit expectation style is used. + # + # This cop can be configured using the `EnforcedStyle` option + # and supports the `--auto-gen-config` flag. + # + # @example `EnforcedStyle: is_expected` + # + # # bad + # it { should be_truthy } + # + # # good + # it { is_expected.to be_truthy } + # + # @example `EnforcedStyle: should` + # + # # bad + # it { is_expected.to be_truthy } + # + # # good + # it { should be_truthy } + # + class ImplicitExpect < Cop + include ConfigurableEnforcedStyle + + MSG = 'Prefer `%<good>s` over `%<bad>s`.'.freeze + + def_node_matcher :implicit_expect, <<-PATTERN + { + (send nil? ${:should :should_not} ...) + (send (send nil? $:is_expected) {:to :to_not :not_to} ...) + } + PATTERN + + alternatives = { + 'is_expected.to' => 'should', + 'is_expected.not_to' => 'should_not', + 'is_expected.to_not' => 'should_not' + } + + ENFORCED_REPLACEMENTS = alternatives.merge(alternatives.invert).freeze + + def on_send(node) # rubocop:disable Metrics/MethodLength + return unless (source_range = offending_expect(node)) + + expectation_source = source_range.source + + if expectation_source.start_with?(style.to_s) + correct_style_detected + else + opposite_style_detected + + add_offense( + node, + location: source_range, + message: offense_message(expectation_source) + ) + end + end + + def autocorrect(node) + lambda do |corrector| + offense = offending_expect(node) + replacement = replacement_source(offense.source) + + corrector.replace(offense, replacement) + end + end + + private + + def offending_expect(node) + case implicit_expect(node) + when :is_expected + is_expected_range(node.loc) + when :should, :should_not + node.loc.selector + end + end + + def is_expected_range(source_map) # rubocop:disable PredicateName + Parser::Source::Range.new( + source_map.expression.source_buffer, + source_map.expression.begin_pos, + source_map.selector.end_pos + ) + end + + def offense_message(offending_source) + format( + MSG, + good: replacement_source(offending_source), + bad: offending_source + ) + end + + def replacement_source(offending_source) + ENFORCED_REPLACEMENTS.fetch(offending_source) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_subject.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_subject.rb new file mode 100644 index 0000000000000000000000000000000000000000..85877475f4574f830dd2ec9ea9458127098feac2 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/implicit_subject.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for usage of implicit subject (`is_expected` / `should`). + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: single_line_only` + # # bad + # it do + # is_expected.to be_truthy + # end + # + # # good + # it { is_expected.to be_truthy } + # it do + # expect(subject).to be_truthy + # end + # + # @example `EnforcedStyle: disallow` + # # bad + # it { is_expected.to be_truthy } + # + # # good + # it { expect(subject).to be_truthy } + # + class ImplicitSubject < Cop + include ConfigurableEnforcedStyle + + MSG = "Don't use implicit subject.".freeze + + def_node_matcher :implicit_subject?, <<-PATTERN + (send nil? {:should :should_not :is_expected} ...) + PATTERN + + def on_send(node) + return unless implicit_subject?(node) + return if valid_usage?(node) + + add_offense(node) + end + + def autocorrect(node) + replacement = 'expect(subject)' + if node.method_name == :should + replacement += '.to' + elsif node.method_name == :should_not + replacement += '.not_to' + end + + ->(corrector) { corrector.replace(node.loc.selector, replacement) } + end + + private + + def valid_usage?(node) + example = node.ancestors.find { |parent| example?(parent) } + return false if example.nil? + + example.method_name == :its || allowed_by_style?(example) + end + + def allowed_by_style?(example) + if style == :single_line_only + example.single_line? + elsif style == :single_statement_only + !example.body.begin_type? + else + false + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_spy.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_spy.rb new file mode 100644 index 0000000000000000000000000000000000000000..9f40ac71732ae7d797716bd42e3e10f76c43e33e --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_spy.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for `instance_double` used with `have_received`. + # + # @example + # # bad + # it do + # foo = instance_double(Foo).as_null_object + # expect(foo).to have_received(:bar) + # end + # + # # good + # it do + # foo = instance_spy(Foo) + # expect(foo).to have_received(:bar) + # end + # + class InstanceSpy < Cop + MSG = 'Use `instance_spy` when you check your double '\ + 'with `have_received`.'.freeze + + def_node_search :null_double, <<-PATTERN + (lvasgn $_ + (send + $(send nil? :instance_double + ...) :as_null_object)) + PATTERN + + def_node_search :have_received_usage, <<-PATTERN + (send + (send nil? :expect + (lvar $_)) :to + (send nil? :have_received + ...) + ...) + PATTERN + + def on_block(node) + return unless example?(node) + + null_double(node) do |var, receiver| + have_received_usage(node) do |expected| + add_offense(receiver, location: :expression) if expected == var + end + end + end + + def autocorrect(node) + lambda do |corrector| + replacement = 'instance_spy' + corrector.replace(node.loc.selector, replacement) + + double_source_map = node.parent.loc + as_null_object_range = double_source_map + .dot + .join(double_source_map.selector) + corrector.remove(as_null_object_range) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_variable.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_variable.rb new file mode 100644 index 0000000000000000000000000000000000000000..fab437d9d7577c3d5a5c274c6343fbfc13bf87c8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/instance_variable.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for instance variable usage in specs. + # + # This cop can be configured with the option `AssignmentOnly` which + # will configure the cop to only register offenses on instance + # variable usage if the instance variable is also assigned within + # the spec + # + # @example + # # bad + # describe MyClass do + # before { @foo = [] } + # it { expect(@foo).to be_empty } + # end + # + # # good + # describe MyClass do + # let(:foo) { [] } + # it { expect(foo).to be_empty } + # end + # + # @example with AssignmentOnly configuration + # + # # rubocop.yml + # # RSpec/InstanceVariable: + # # AssignmentOnly: false + # + # # bad + # describe MyClass do + # before { @foo = [] } + # it { expect(@foo).to be_empty } + # end + # + # # allowed + # describe MyClass do + # it { expect(@foo).to be_empty } + # end + # + # # good + # describe MyClass do + # let(:foo) { [] } + # it { expect(foo).to be_empty } + # end + # + class InstanceVariable < Cop + MSG = 'Replace instance variable with local variable or `let`.'.freeze + + EXAMPLE_GROUP_METHODS = ExampleGroups::ALL + SharedGroups::ALL + + def_node_matcher :spec_group?, EXAMPLE_GROUP_METHODS.block_pattern + + def_node_matcher :dynamic_class?, <<-PATTERN + (block (send (const nil? :Class) :new ...) ...) + PATTERN + + def_node_search :ivar_usage, '$(ivar $_)' + + def_node_search :ivar_assigned?, '(ivasgn % ...)' + + def on_block(node) + return unless spec_group?(node) + + ivar_usage(node) do |ivar, name| + return if inside_dynamic_class?(ivar) + return if assignment_only? && !ivar_assigned?(node, name) + + add_offense(ivar, location: :expression) + end + end + + private + + def inside_dynamic_class?(node) + node.each_ancestor(:block).any? { |block| dynamic_class?(block) } + end + + def assignment_only? + cop_config['AssignmentOnly'] + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb new file mode 100644 index 0000000000000000000000000000000000000000..828588171f88ba514e52a2646a0ab2a1ca6af264 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb @@ -0,0 +1,42 @@ +module RuboCop + module Cop + module RSpec + # Checks invalid usage for predicate matcher. + # + # Predicate matcher does not need a question. + # This cop checks an unnecessary question in predicate matcher. + # + # @example + # + # # bad + # expect(foo).to be_something? + # + # # good + # expect(foo).to be_something + class InvalidPredicateMatcher < Cop + MSG = 'Omit `?` from `%<matcher>s`.'.freeze + + def_node_matcher :invalid_predicate_matcher?, <<-PATTERN + (send (send nil? :expect ...) {:to :not_to :to_not} $(send nil? #predicate?)) + PATTERN + + def on_send(node) + invalid_predicate_matcher?(node) do |predicate| + add_offense(predicate, location: :expression) + end + end + + private + + def predicate?(name) + name = name.to_s + name.start_with?('be_', 'have_') && name.end_with?('?') + end + + def message(predicate) + format(MSG, matcher: predicate.method_name) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/it_behaves_like.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/it_behaves_like.rb new file mode 100644 index 0000000000000000000000000000000000000000..b7ede3c09ccd92d0c00d3532a500d01fc9471819 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/it_behaves_like.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that only one `it_behaves_like` style is used. + # + # @example when configuration is `EnforcedStyle: it_behaves_like` + # # bad + # it_should_behave_like 'a foo' + # + # # good + # it_behaves_like 'a foo' + # + # @example when configuration is `EnforcedStyle: it_should_behave_like` + # # bad + # it_behaves_like 'a foo' + # + # # good + # it_should_behave_like 'a foo' + class ItBehavesLike < Cop + include ConfigurableEnforcedStyle + + MSG = 'Prefer `%<replacement>s` over `%<original>s` when including '\ + 'examples in a nested context.'.freeze + + def_node_matcher :example_inclusion_offense, '(send _ % ...)' + + def on_send(node) + example_inclusion_offense(node, alternative_style) do + add_offense(node, location: :expression) + end + end + + def autocorrect(node) + ->(corrector) { corrector.replace(node.loc.selector, style.to_s) } + end + + private + + def message(_node) + format(MSG, replacement: style, original: alternative_style) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/iterated_expectation.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/iterated_expectation.rb new file mode 100644 index 0000000000000000000000000000000000000000..3fa5f6b4c607ce568695d35ebfd6bf207764f2a5 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/iterated_expectation.rb @@ -0,0 +1,52 @@ +module RuboCop + module Cop + module RSpec + # Check that `all` matcher is used instead of iterating over an array. + # + # @example + # # bad + # it 'validates users' do + # [user1, user2, user3].each { |user| expect(user).to be_valid } + # end + # + # # good + # it 'validates users' do + # expect([user1, user2, user3]).to all(be_valid) + # end + class IteratedExpectation < Cop + MSG = 'Prefer using the `all` matcher instead ' \ + 'of iterating over an array.'.freeze + + def_node_matcher :each?, <<-PATTERN + (block + (send ... :each) + (args (arg $_)) + $(...) + ) + PATTERN + + def_node_matcher :expectation?, <<-PATTERN + (send (send nil? :expect (lvar %)) :to ...) + PATTERN + + def on_block(node) + each?(node) do |arg, body| + if single_expectation?(body, arg) || only_expectations?(body, arg) + add_offense(node.send_node, location: :expression) + end + end + end + + private + + def single_expectation?(body, arg) + expectation?(body, arg) + end + + def only_expectations?(body, arg) + body.each_child_node.all? { |child| expectation?(child, arg) } + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/leading_subject.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/leading_subject.rb new file mode 100644 index 0000000000000000000000000000000000000000..bc21c2929ddfdff9606f42cef7f832b747739fa3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/leading_subject.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Enforce that subject is the first definition in the test. + # + # @example + # # bad + # let(:params) { blah } + # subject { described_class.new(params) } + # + # before { do_something } + # subject { described_class.new(params) } + # + # it { expect_something } + # subject { described_class.new(params) } + # it { expect_something_else } + # + # + # # good + # subject { described_class.new(params) } + # let(:params) { blah } + # + # # good + # subject { described_class.new(params) } + # before { do_something } + # + # # good + # subject { described_class.new(params) } + # it { expect_something } + # it { expect_something_else } + # + class LeadingSubject < Cop + include RangeHelp + + MSG = 'Declare `subject` above any other `%<offending>s` ' \ + 'declarations.'.freeze + + def on_block(node) + return unless subject?(node) && !in_spec_block?(node) + + check_previous_nodes(node) + end + + def check_previous_nodes(node) + node.parent.each_child_node do |sibling| + if offending?(sibling) + add_offense( + node, + location: :expression, + message: format(MSG, offending: sibling.method_name) + ) + end + + break if offending?(sibling) || sibling.equal?(node) + end + end + + def autocorrect(node) + lambda do |corrector| + first_node = find_first_offending_node(node) + first_node_position = first_node.loc.expression + indent = "\n" + ' ' * first_node.loc.column + corrector.insert_before(first_node_position, node.source + indent) + corrector.remove(node_range(node)) + end + end + + private + + def offending?(node) + let?(node) || hook?(node) || example?(node) + end + + def find_first_offending_node(node) + node.parent.children.find { |sibling| offending?(sibling) } + end + + def node_range(node) + range_by_whole_lines(node.source_range, include_final_newline: true) + end + + def in_spec_block?(node) + node.each_ancestor(:block).any? do |ancestor| + example?(ancestor) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_before_examples.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_before_examples.rb new file mode 100644 index 0000000000000000000000000000000000000000..f8d9f533e31bccdb07f52718778cbd476050af19 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_before_examples.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for `let` definitions that come after an example. + # + # @example + # # Bad + # let(:foo) { bar } + # + # it 'checks what foo does' do + # expect(foo).to be + # end + # + # let(:some) { other } + # + # it 'checks what some does' do + # expect(some).to be + # end + # + # # Good + # let(:foo) { bar } + # let(:some) { other } + # + # it 'checks what foo does' do + # expect(foo).to be + # end + # + # it 'checks what some does' do + # expect(some).to be + # end + class LetBeforeExamples < Cop + include RangeHelp + include RuboCop::RSpec::FinalEndLocation + + MSG = 'Move `let` before the examples in the group.'.freeze + + def_node_matcher :example_or_group?, <<-PATTERN + { + #{(Examples::ALL + ExampleGroups::ALL).block_pattern} + #{Includes::EXAMPLES.send_pattern} + } + PATTERN + + def on_block(node) + return unless example_group_with_body?(node) + + check_let_declarations(node.body) if multiline_block?(node.body) + end + + def autocorrect(node) + lambda do |corrector| + first_example = find_first_example(node.parent) + first_example_pos = first_example.loc.expression + indent = "\n" + ' ' * first_example.loc.column + + corrector.insert_before(first_example_pos, source(node) + indent) + corrector.remove(node_range_with_surrounding_space(node)) + end + end + + private + + def multiline_block?(block) + block.begin_type? + end + + def check_let_declarations(node) + first_example = find_first_example(node) + return unless first_example + + node.each_child_node do |child| + next if child.sibling_index < first_example.sibling_index + + add_offense(child, location: :expression) if let?(child) + end + end + + def find_first_example(node) + node.children.find { |sibling| example_or_group?(sibling) } + end + + def node_range_with_surrounding_space(node) + range = node_range(node) + range_by_whole_lines(range, include_final_newline: true) + end + + def source(node) + node_range(node).source + end + + def node_range(node) + range_between( + node.loc.expression.begin_pos, + final_end_location(node).end_pos + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_setup.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_setup.rb new file mode 100644 index 0000000000000000000000000000000000000000..f271f3d0d673c0a869c3f816df3f3b57e246ce1b --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/let_setup.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks unreferenced `let!` calls being used for test setup. + # + # @example + # # Bad + # let!(:my_widget) { create(:widget) } + # + # it 'counts widgets' do + # expect(Widget.count).to eq(1) + # end + # + # # Good + # it 'counts widgets' do + # create(:widget) + # expect(Widget.count).to eq(1) + # end + # + # # Good + # before { create(:widget) } + # + # it 'counts widgets' do + # expect(Widget.count).to eq(1) + # end + class LetSetup < Cop + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'Do not use `let!` for test setup.'.freeze + + def_node_search :let_bang, <<-PATTERN + (block $(send nil? :let! (sym $_)) args ...) + PATTERN + + def_node_search :method_called?, '(send nil? %)' + + def on_block(node) + return unless example_group?(node) + + unused_let_bang(node) do |let| + add_offense(let, location: :expression) + end + end + + private + + def unused_let_bang(node) + let_bang(node) do |method_send, method_name| + yield(method_send) unless method_called?(node, method_name) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_chain.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_chain.rb new file mode 100644 index 0000000000000000000000000000000000000000..88b4b221b55ce204b2c296f09231a4318cf45e9e --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_chain.rb @@ -0,0 +1,31 @@ +module RuboCop + module Cop + module RSpec + # Check that chains of messages are not being stubbed. + # + # @example + # # bad + # allow(foo).to receive_message_chain(:bar, :baz).and_return(42) + # + # # better + # thing = Thing.new(baz: 42) + # allow(foo).to receive(bar: thing) + # + class MessageChain < Cop + MSG = 'Avoid stubbing using `%<method>s`.'.freeze + + def_node_matcher :message_chain, <<-PATTERN + (send _ {:receive_message_chain :stub_chain} ...) + PATTERN + + def on_send(node) + message_chain(node) { add_offense(node, location: :selector) } + end + + def message(node) + format(MSG, method: node.method_name) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_expectation.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_expectation.rb new file mode 100644 index 0000000000000000000000000000000000000000..cd1972dcd55d71275fb4b9e499e3cb8f100b0e8e --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_expectation.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for consistent message expectation style. + # + # This cop can be configured in your configuration using the + # `EnforcedStyle` option and supports `--auto-gen-config`. + # + # @example `EnforcedStyle: allow` + # + # # bad + # expect(foo).to receive(:bar) + # + # # good + # allow(foo).to receive(:bar) + # + # @example `EnforcedStyle: expect` + # + # # bad + # allow(foo).to receive(:bar) + # + # # good + # expect(foo).to receive(:bar) + # + class MessageExpectation < Cop + include ConfigurableEnforcedStyle + + MSG = 'Prefer `%<style>s` for setting message expectations.'.freeze + + SUPPORTED_STYLES = %w[allow expect].freeze + + def_node_matcher :message_expectation, <<-PATTERN + (send $(send nil? {:expect :allow} ...) :to #receive_message?) + PATTERN + + def_node_search :receive_message?, '(send nil? :receive ...)' + + def on_send(node) + message_expectation(node) do |match| + return correct_style_detected if preferred_style?(match) + + message = format(MSG, style: style) + add_offense(match, location: :selector, message: message) do + opposite_style_detected + end + end + end + + private + + def preferred_style?(expectation) + expectation.method_name.equal?(style) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_spies.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_spies.rb new file mode 100644 index 0000000000000000000000000000000000000000..fc76dba07770a8effae790d4ad86f3360eb087e4 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/message_spies.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that message expectations are set using spies. + # + # This cop can be configured in your configuration using the + # `EnforcedStyle` option and supports `--auto-gen-config`. + # + # @example `EnforcedStyle: have_received` + # + # # bad + # expect(foo).to receive(:bar) + # + # # good + # expect(foo).to have_received(:bar) + # + # @example `EnforcedStyle: receive` + # + # # bad + # expect(foo).to have_received(:bar) + # + # # good + # expect(foo).to receive(:bar) + # + class MessageSpies < Cop + include ConfigurableEnforcedStyle + + MSG_RECEIVE = 'Prefer `receive` for setting message '\ + 'expectations.'.freeze + + MSG_HAVE_RECEIVED = 'Prefer `have_received` for setting message '\ + 'expectations. Setup `%<source>s` as a spy using '\ + '`allow` or `instance_spy`.'.freeze + + SUPPORTED_STYLES = %w[have_received receive].freeze + + def_node_matcher :message_expectation, %( + (send (send nil? :expect $_) {:to :to_not :not_to} ...) + ) + + def_node_search :receive_message, %( + $(send nil? {:receive :have_received} ...) + ) + + def on_send(node) + receive_message_matcher(node) do |receiver, message_matcher| + return correct_style_detected if preferred_style?(message_matcher) + + add_offense( + message_matcher, + location: :selector, + message: error_message(receiver) + ) { opposite_style_detected } + end + end + + private + + def receive_message_matcher(node) + return unless (receiver = message_expectation(node)) + + receive_message(node) { |match| yield(receiver, match) } + end + + def preferred_style?(expectation) + expectation.method_name.equal?(style) + end + + def error_message(receiver) + case style + when :receive + MSG_RECEIVE + when :have_received + format(MSG_HAVE_RECEIVED, source: receiver.source) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/missing_example_group_argument.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/missing_example_group_argument.rb new file mode 100644 index 0000000000000000000000000000000000000000..c412d0c42107a9c2a52d30eb315c44ad59771d60 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/missing_example_group_argument.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks that the first argument to an example group is not empty. + # + # @example + # # bad + # describe do + # end + # + # RSpec.describe do + # end + # + # # good + # describe TestedClass do + # end + # + # describe "A feature example" do + # end + class MissingExampleGroupArgument < Cop + MSG = 'The first argument to `%<method>s` should not be empty.'.freeze + + def on_block(node) + return unless example_group?(node) + return if node.send_node.arguments? + + add_offense(node, location: :expression, + message: format(MSG, method: node.method_name)) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_describes.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_describes.rb new file mode 100644 index 0000000000000000000000000000000000000000..be558933773629cdef0a214c5af28572e5930e6a --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_describes.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for multiple top level describes. + # + # Multiple descriptions for the same class or module should either + # be nested or separated into different test files. + # + # @example + # # bad + # describe MyClass, '.do_something' do + # end + # describe MyClass, '.do_something_else' do + # end + # + # # good + # describe MyClass do + # describe '.do_something' do + # end + # describe '.do_something_else' do + # end + # end + class MultipleDescribes < Cop + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'Do not use multiple top level describes - '\ + 'try to nest them.'.freeze + + def on_top_level_describe(node, _args) + return if single_top_level_describe? + return unless top_level_nodes.first.equal?(node) + + add_offense(node, location: :expression) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_expectations.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_expectations.rb new file mode 100644 index 0000000000000000000000000000000000000000..fd93aea0d6765ee0e05fffadc23dda8e957f8084 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_expectations.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if examples contain too many `expect` calls. + # + # @see http://betterspecs.org/#single Single expectation test + # + # This cop is configurable using the `Max` option + # and works with `--auto-gen-config`. + # + # @example + # + # # bad + # describe UserCreator do + # it 'builds a user' do + # expect(user.name).to eq("John") + # expect(user.age).to eq(22) + # end + # end + # + # # good + # describe UserCreator do + # it 'sets the users name' do + # expect(user.name).to eq("John") + # end + # + # it 'sets the users age' do + # expect(user.age).to eq(22) + # end + # end + # + # @example configuration + # + # # .rubocop.yml + # # RSpec/MultipleExpectations: + # # Max: 2 + # + # # not flagged by rubocop + # describe UserCreator do + # it 'builds a user' do + # expect(user.name).to eq("John") + # expect(user.age).to eq(22) + # end + # end + # + class MultipleExpectations < Cop + include ConfigurableMax + + MSG = 'Example has too many expectations [%<total>d/%<max>d].'.freeze + + def_node_search :with_aggregated_failures?, '(sym :aggregate_failures)' + def_node_search :disabled_aggregated_failures?, <<-PATTERN + (pair (sym :aggregate_failures) (false)) + PATTERN + + def_node_matcher :expect?, Expectations::ALL.send_pattern + def_node_matcher :aggregate_failures?, <<-PATTERN + (block (send _ :aggregate_failures ...) ...) + PATTERN + + def on_block(node) + return unless example?(node) + + return if example_with_aggregated_failures?(node) + + expectations_count = to_enum(:find_expectation, node).count + + return if expectations_count <= max_expectations + + self.max = expectations_count + + flag_example(node, expectation_count: expectations_count) + end + + private + + def example_with_aggregated_failures?(node) + example = node.send_node + + (aggregated_failures_by_default? || + with_aggregated_failures?(example)) && + !disabled_aggregated_failures?(example) + end + + def find_expectation(node, &block) + yield if expect?(node) || aggregate_failures?(node) + + # do not search inside of aggregate_failures block + return if aggregate_failures?(node) + + node.each_child_node do |child| + find_expectation(child, &block) + end + end + + def flag_example(node, expectation_count:) + add_offense( + node.send_node, + location: :expression, + message: format( + MSG, + total: expectation_count, + max: max_expectations + ) + ) + end + + def max_expectations + Integer(cop_config.fetch('Max', 1)) + end + + def aggregated_failures_by_default? + cop_config.fetch('AggregateFailuresByDefault', false) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_subjects.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_subjects.rb new file mode 100644 index 0000000000000000000000000000000000000000..895fe549c9a116f3e71a858a6b98744b5fd2ab15 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/multiple_subjects.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if an example group defines `subject` multiple times. + # + # @example + # + # # bad + # describe Foo do + # subject(:user) { User.new } + # subject(:post) { Post.new } + # end + # + # # good + # describe Foo do + # let(:user) { User.new } + # subject(:post) { Post.new } + # end + # + # The autocorrect behavior for this cop depends on the type of + # duplication: + # + # - If multiple named subjects are defined then this probably indicates + # that the overwritten subjects (all subjects except the last + # definition) are effectively being used to define helpers. In this + # case they are replaced with `let`. + # + # - If multiple unnamed subjects are defined though then this can *only* + # be dead code and we remove the overwritten subject definitions. + # + # - If subjects are defined with `subject!` then we don't autocorrect. + # This is enough of an edge case that people can just move this to + # a `before` hook on their own + class MultipleSubjects < Cop + MSG = 'Do not set more than one subject per example group'.freeze + + def on_block(node) + return unless example_group?(node) + + subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects + + subjects[0...-1].each do |subject| + add_offense(subject, location: :expression) + end + end + + def autocorrect(node) + return unless node.method_name.equal?(:subject) # Ignore `subject!` + + if named_subject?(node) + rename_autocorrect(node) + else + remove_autocorrect(node) + end + end + + private + + def named_subject?(node) + node.send_node.arguments? + end + + def rename_autocorrect(node) + lambda do |corrector| + corrector.replace(node.send_node.loc.selector, 'let') + end + end + + def remove_autocorrect(node) + lambda do |corrector| + corrector.remove(node.loc.expression) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/named_subject.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/named_subject.rb new file mode 100644 index 0000000000000000000000000000000000000000..5c40e1d23c8d9ac46893ac43704f50855180984e --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/named_subject.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for explicitly referenced test subjects. + # + # RSpec lets you declare an "implicit subject" using `subject { ... }` + # which allows for tests like `it { should be_valid }`. If you need to + # reference your test subject you should explicitly name it using + # `subject(:your_subject_name) { ... }`. Your test subjects should be + # the most important object in your tests so they deserve a descriptive + # name. + # + # @example + # # bad + # RSpec.describe User do + # subject { described_class.new } + # + # it 'is valid' do + # expect(subject.valid?).to be(true) + # end + # end + # + # # good + # RSpec.describe Foo do + # subject(:user) { described_class.new } + # + # it 'is valid' do + # expect(user.valid?).to be(true) + # end + # end + # + # # also good + # RSpec.describe Foo do + # subject(:user) { described_class.new } + # + # it { should be_valid } + # end + class NamedSubject < Cop + MSG = 'Name your test subject if you need '\ + 'to reference it explicitly.'.freeze + + def_node_matcher :rspec_block?, <<-PATTERN + { + #{Examples::ALL.block_pattern} + #{Hooks::ALL.block_pattern} + } + PATTERN + + def_node_search :subject_usage, '$(send nil? :subject)' + + def on_block(node) + return unless rspec_block?(node) + + subject_usage(node) do |subject_node| + add_offense(subject_node, location: :selector) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/nested_groups.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/nested_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..e476a5549d1414c2fbbf22b037aa9462e9eb7c6d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/nested_groups.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for nested example groups. + # + # This cop is configurable using the `Max` option + # and supports `--auto-gen-config + # + # @example + # # bad + # context 'when using some feature' do + # let(:some) { :various } + # let(:feature) { :setup } + # + # context 'when user is signed in' do # flagged by rubocop + # let(:user) do + # UserCreate.call(user_attributes) + # end + # + # let(:user_attributes) do + # { + # name: 'John', + # age: 22, + # role: role + # } + # end + # + # context 'when user is an admin' do # flagged by rubocop + # let(:role) { 'admin' } + # + # it 'blah blah' + # it 'yada yada' + # end + # end + # end + # + # # better + # context 'using some feature as an admin' do + # let(:some) { :various } + # let(:feature) { :setup } + # + # let(:user) do + # UserCreate.call( + # name: 'John', + # age: 22, + # role: 'admin' + # ) + # end + # + # it 'blah blah' + # it 'yada yada' + # end + # + # @example configuration + # + # # .rubocop.yml + # # RSpec/NestedGroups: + # # Max: 2 + # + # context 'when using some feature' do + # let(:some) { :various } + # let(:feature) { :setup } + # + # context 'when user is signed in' do + # let(:user) do + # UserCreate.call(user_attributes) + # end + # + # let(:user_attributes) do + # { + # name: 'John', + # age: 22, + # role: role + # } + # end + # + # context 'when user is an admin' do # flagged by rubocop + # let(:role) { 'admin' } + # + # it 'blah blah' + # it 'yada yada' + # end + # end + # end + # + class NestedGroups < Cop + include ConfigurableMax + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'Maximum example group nesting exceeded ' \ + '[%<total>d/%<max>d].'.freeze + + DEPRECATED_MAX_KEY = 'MaxNesting'.freeze + + DEPRECATION_WARNING = + "Configuration key `#{DEPRECATED_MAX_KEY}` for #{cop_name} is " \ + 'deprecated in favor of `Max`. Please use that instead.'.freeze + + def_node_search :find_contexts, ExampleGroups::ALL.block_pattern + + def on_top_level_describe(node, _args) + find_nested_contexts(node.parent) do |context, nesting| + self.max = nesting + add_offense( + context.send_node, + location: :expression, + message: message(nesting) + ) + end + end + + private + + def find_nested_contexts(node, nesting: 1, &block) + find_contexts(node) do |nested_context| + yield(nested_context, nesting) if nesting > max_nesting + + nested_context.each_child_node do |child| + find_nested_contexts(child, nesting: nesting + 1, &block) + end + end + end + + def message(nesting) + format(MSG, total: nesting, max: max_nesting) + end + + def max_nesting + @max_nesting ||= Integer(max_nesting_config) + end + + def max_nesting_config + if cop_config.key?(DEPRECATED_MAX_KEY) + warn DEPRECATION_WARNING + cop_config.fetch(DEPRECATED_MAX_KEY) + else + cop_config.fetch('Max', 3) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/not_to_not.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/not_to_not.rb new file mode 100644 index 0000000000000000000000000000000000000000..02a04a3e3074a543fc3062121c0406e12266756c --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/not_to_not.rb @@ -0,0 +1,41 @@ +module RuboCop + module Cop + module RSpec + # Checks for consistent method usage for negating expectations. + # + # @example + # # bad + # it '...' do + # expect(false).to_not be_true + # end + # + # # good + # it '...' do + # expect(false).not_to be_true + # end + class NotToNot < Cop + include ConfigurableEnforcedStyle + + MSG = 'Prefer `%<replacement>s` over `%<original>s`.'.freeze + + def_node_matcher :not_to_not_offense, '(send _ % ...)' + + def on_send(node) + not_to_not_offense(node, alternative_style) do + add_offense(node, location: :selector) + end + end + + def autocorrect(node) + ->(corrector) { corrector.replace(node.loc.selector, style.to_s) } + end + + private + + def message(_node) + format(MSG, replacement: style, original: alternative_style) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/overwriting_setup.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/overwriting_setup.rb new file mode 100644 index 0000000000000000000000000000000000000000..e8472f25ca138976ebf1d06eb6daaea191c14d91 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/overwriting_setup.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks if there is a let/subject that overwrites an existing one. + # + # @example + # # bad + # let(:foo) { bar } + # let(:foo) { baz } + # + # subject(:foo) { bar } + # let(:foo) { baz } + # + # let(:foo) { bar } + # let!(:foo) { baz } + # + # # good + # subject(:test) { something } + # let(:foo) { bar } + # let(:baz) { baz } + # let!(:other) { other } + class OverwritingSetup < Cop + MSG = '`%<name>s` is already defined.'.freeze + + def_node_matcher :setup?, (Helpers::ALL + Subject::ALL).block_pattern + def_node_matcher :first_argument_name, '(send _ _ ({str sym} $_))' + + def on_block(node) + return unless example_group_with_body?(node) + + find_duplicates(node.body) do |duplicate, name| + add_offense( + duplicate, + location: :expression, + message: format(MSG, name: name) + ) + end + end + + private + + def find_duplicates(node) + setup_expressions = Set.new + node.each_child_node(:block) do |child| + next unless common_setup?(child) + + name = if child.send_node.arguments? + first_argument_name(child.send_node).to_sym + else + :subject + end + + yield child, name unless setup_expressions.add?(name) + end + end + + def common_setup?(node) + return false unless setup?(node) + + # Search only for setup with basic_literal arguments (e.g. :sym, :str) + # or no arguments at all. + node.send_node.arguments.all?(&:basic_literal?) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/pending.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/pending.rb new file mode 100644 index 0000000000000000000000000000000000000000..c1b3c84dfd5e27a5de5e8d6971d9c2926bb0d006 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/pending.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for any pending or skipped examples. + # + # @example + # # bad + # describe MyClass do + # it "should be true" + # end + # + # describe MyClass do + # it "should be true" do + # pending + # end + # end + # + # describe MyClass do + # xit "should be true" do + # end + # end + # + # # good + # describe MyClass do + # end + class Pending < Cop + MSG = 'Pending spec found.'.freeze + + PENDING_EXAMPLES = Examples::PENDING + Examples::SKIPPED \ + + ExampleGroups::SKIPPED + SKIPPABLE_EXAMPLES = ExampleGroups::GROUPS + Examples::EXAMPLES + SKIPPABLE_SELECTORS = SKIPPABLE_EXAMPLES.node_pattern_union + + SKIP_SYMBOL = s(:sym, :skip) + PENDING_SYMBOL = s(:sym, :pending) + + def_node_matcher :metadata, <<-PATTERN + {(send nil? #{SKIPPABLE_SELECTORS} ... (hash $...)) + (send nil? #{SKIPPABLE_SELECTORS} $...)} + PATTERN + + def_node_matcher :pending_block?, PENDING_EXAMPLES.send_pattern + + def on_send(node) + return unless pending_block?(node) || skipped_from_metadata?(node) + + add_offense(node, location: :expression) + end + + private + + def skipped_from_metadata?(node) + (metadata(node) || []).any? { |n| skip_node?(n) } + end + + def skip_node?(node) + if node.respond_to?(:key) + skip_symbol?(node.key) && node.value.truthy_literal? + else + skip_symbol?(node) + end + end + + def skip_symbol?(symbol_node) + [SKIP_SYMBOL, PENDING_SYMBOL].include?(symbol_node) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/predicate_matcher.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/predicate_matcher.rb new file mode 100644 index 0000000000000000000000000000000000000000..8e307d779875621f9039dec775bf0b0afd318446 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/predicate_matcher.rb @@ -0,0 +1,350 @@ +module RuboCop + module Cop + module RSpec + # A helper for `inflected` style + module InflectedHelper + extend NodePattern::Macros + + MSG_INFLECTED = 'Prefer using `%<matcher_name>s` matcher over ' \ + '`%<predicate_name>s`.'.freeze + + private + + def check_inflected(node) + predicate_in_actual?(node) do |predicate| + add_offense( + node, + location: :expression, + message: message_inflected(predicate) + ) + end + end + + def_node_matcher :predicate_in_actual?, <<-PATTERN + (send + (send nil? :expect { + (block $(send !nil? #predicate? ...) ...) + $(send !nil? #predicate? ...)}) + ${:to :not_to :to_not} + $#boolean_matcher?) + PATTERN + + def_node_matcher :be_bool?, <<-PATTERN + (send nil? {:be :eq :eql :equal} {true false}) + PATTERN + + def_node_matcher :be_boolthy?, <<-PATTERN + (send nil? {:be_truthy :be_falsey :be_falsy :a_truthy_value :a_falsey_value :a_falsy_value}) + PATTERN + + def boolean_matcher?(node) + if cop_config['Strict'] + be_boolthy?(node) + else + be_bool?(node) || be_boolthy?(node) + end + end + + def predicate?(sym) + sym.to_s.end_with?('?') + end + + def message_inflected(predicate) + format(MSG_INFLECTED, + predicate_name: predicate.method_name, + matcher_name: to_predicate_matcher(predicate.method_name)) + end + + # rubocop:disable Metrics/MethodLength + def to_predicate_matcher(name) + case name = name.to_s + when 'is_a?' + 'be_a' + when 'instance_of?' + 'be_an_instance_of' + when 'include?', 'respond_to?' + name[0..-2] + when /^has_/ + name.sub('has_', 'have_')[0..-2] + else + "be_#{name[0..-2]}" + end + end + # rubocop:enable Metrics/MethodLength + + def autocorrect_inflected(node) + predicate_in_actual?(node) do |predicate, to, matcher| + lambda do |corrector| + remove_predicate(corrector, predicate) + corrector.replace(node.loc.selector, + true?(to, matcher) ? 'to' : 'not_to') + rewrite_matcher(corrector, predicate, matcher) + end + end + end + + def remove_predicate(corrector, predicate) + range = range_between( + predicate.loc.dot.begin_pos, + predicate.loc.expression.end_pos + ) + corrector.remove(range) + + block_range = block_loc(predicate) + corrector.remove(block_range) if block_range + end + + def rewrite_matcher(corrector, predicate, matcher) + args = args_loc(predicate).source + block_loc = block_loc(predicate) + block = block_loc ? block_loc.source : '' + + corrector.replace( + matcher.loc.expression, + to_predicate_matcher(predicate.method_name) + args + block + ) + end + + def true?(to_symbol, matcher) + result = case matcher.method_name + when :be, :eq + matcher.first_argument.true_type? + when :be_truthy, :a_truthy_value + true + when :be_falsey, :be_falsy, :a_falsey_value, :a_falsy_value + false + end + to_symbol == :to ? result : !result + end + end + + # A helper for `explicit` style + # rubocop:disable Metrics/ModuleLength + module ExplicitHelper + extend NodePattern::Macros + + MSG_EXPLICIT = 'Prefer using `%<predicate_name>s` over ' \ + '`%<matcher_name>s` matcher.'.freeze + BUILT_IN_MATCHERS = %w[ + be_truthy be_falsey be_falsy + have_attributes have_received + be_between be_within + ].freeze + + private + + def check_explicit(node) # rubocop:disable Metrics/MethodLength + predicate_matcher_block?(node) do |_actual, matcher| + add_offense( + node, + location: :expression, + message: message_explicit(matcher) + ) + ignore_node(node.children.first) + return + end + + return if part_of_ignored_node?(node) + + predicate_matcher?(node) do |_actual, matcher| + add_offense( + node, + location: :expression, + message: message_explicit(matcher) + ) + end + end + + def_node_matcher :predicate_matcher?, <<-PATTERN + (send + (send nil? :expect $!nil?) + {:to :not_to :to_not} + {$(send nil? #predicate_matcher_name? ...) + (block $(send nil? #predicate_matcher_name? ...) ...)}) + PATTERN + + def_node_matcher :predicate_matcher_block?, <<-PATTERN + (block + (send + (send nil? :expect $!nil?) + {:to :not_to :to_not} + $(send nil? #predicate_matcher_name?)) + ...) + PATTERN + + def predicate_matcher_name?(name) + name = name.to_s + name.start_with?('be_', 'have_') && + !BUILT_IN_MATCHERS.include?(name) && + !name.end_with?('?') + end + + def message_explicit(matcher) + format(MSG_EXPLICIT, + predicate_name: to_predicate_method(matcher.method_name), + matcher_name: matcher.method_name) + end + + def autocorrect_explicit(node) + autocorrect_explicit_send(node) || + autocorrect_explicit_block(node) + end + + def autocorrect_explicit_send(node) + predicate_matcher?(node) do |actual, matcher| + corrector_explicit(node, actual, matcher, matcher) + end + end + + def autocorrect_explicit_block(node) + predicate_matcher_block?(node) do |actual, matcher| + to_node = node.send_node + corrector_explicit(to_node, actual, matcher, to_node) + end + end + + def corrector_explicit(to_node, actual, matcher, block_child) + lambda do |corrector| + replacement_matcher = replacement_matcher(to_node) + corrector.replace(matcher.loc.expression, replacement_matcher) + move_predicate(corrector, actual, matcher, block_child) + corrector.replace(to_node.loc.selector, 'to') + end + end + + def move_predicate(corrector, actual, matcher, block_child) + predicate = to_predicate_method(matcher.method_name) + args = args_loc(matcher).source + block_loc = block_loc(block_child) + block = block_loc ? block_loc.source : '' + + corrector.remove(block_loc) if block_loc + corrector.insert_after(actual.loc.expression, + ".#{predicate}" + args + block) + end + + # rubocop:disable Metrics/MethodLength + def to_predicate_method(matcher) + case matcher = matcher.to_s + when 'be_a', 'be_an', 'be_a_kind_of', 'a_kind_of', 'be_kind_of' + 'is_a?' + when 'be_an_instance_of', 'be_instance_of', 'an_instance_of' + 'instance_of?' + when 'include', 'respond_to' + matcher + '?' + when /^have_(.+)/ + "has_#{Regexp.last_match(1)}?" + else + matcher[/^be_(.+)/, 1] + '?' + end + end + # rubocop:enable Metrics/MethodLength + + def replacement_matcher(node) + case [cop_config['Strict'], node.method_name == :to] + when [true, true] + 'be(true)' + when [true, false] + 'be(false)' + when [false, true] + 'be_truthy' + when [false, false] + 'be_falsey' + end + end + end + # rubocop:enable Metrics/ModuleLength + + # Prefer using predicate matcher over using predicate method directly. + # + # RSpec defines magic matchers for predicate methods. + # This cop recommends to use the predicate matcher instead of using + # predicate method directly. + # + # @example Strict: true, EnforcedStyle: inflected (default) + # # bad + # expect(foo.something?).to be_truthy + # + # # good + # expect(foo).to be_something + # + # # also good - It checks "true" strictly. + # expect(foo).to be(true) + # + # @example Strict: false, EnforcedStyle: inflected + # # bad + # expect(foo.something?).to be_truthy + # expect(foo).to be(true) + # + # # good + # expect(foo).to be_something + # + # @example Strict: true, EnforcedStyle: explicit + # # bad + # expect(foo).to be_something + # + # # good - the above code is rewritten to it by this cop + # expect(foo.something?).to be(true) + # + # @example Strict: false, EnforcedStyle: explicit + # # bad + # expect(foo).to be_something + # + # # good - the above code is rewritten to it by this cop + # expect(foo.something?).to be_truthy + class PredicateMatcher < Cop + include ConfigurableEnforcedStyle + include InflectedHelper + include ExplicitHelper + include RangeHelp + + def on_send(node) + case style + when :inflected + check_inflected(node) + when :explicit + check_explicit(node) + end + end + + def on_block(node) + check_explicit(node) if style == :explicit + end + + def autocorrect(node) + case style + when :inflected + autocorrect_inflected(node) + when :explicit + autocorrect_explicit(node) + end + end + + private + + # returns args location with whitespace + # @example + # foo 1, 2 + # ^^^^^ + def args_loc(send_node) + range_between(send_node.loc.selector.end_pos, + send_node.loc.expression.end_pos) + end + + # returns block location with whitespace + # @example + # foo { bar } + # ^^^^^^^^ + def block_loc(send_node) + parent = send_node.parent + return unless parent.block_type? + + range_between( + send_node.loc.expression.end_pos, + parent.loc.expression.end_pos + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/rails/http_status.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/rails/http_status.rb new file mode 100644 index 0000000000000000000000000000000000000000..897496a27e1dd1a84ce61af1a0d2134489063ecd --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/rails/http_status.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +require 'rack/utils' + +module RuboCop + module Cop + module RSpec + module Rails + # Enforces use of symbolic or numeric value to describe HTTP status. + # + # @example `EnforcedStyle: symbolic` (default) + # # bad + # it { is_expected.to have_http_status 200 } + # it { is_expected.to have_http_status 404 } + # + # # good + # it { is_expected.to have_http_status :ok } + # it { is_expected.to have_http_status :not_found } + # it { is_expected.to have_http_status :success } + # it { is_expected.to have_http_status :error } + # + # @example `EnforcedStyle: numeric` + # # bad + # it { is_expected.to have_http_status :ok } + # it { is_expected.to have_http_status :not_found } + # + # # good + # it { is_expected.to have_http_status 200 } + # it { is_expected.to have_http_status 404 } + # it { is_expected.to have_http_status :success } + # it { is_expected.to have_http_status :error } + # + class HttpStatus < Cop + include ConfigurableEnforcedStyle + + def_node_matcher :http_status, <<-PATTERN + (send nil? :have_http_status ${int sym}) + PATTERN + + def on_send(node) + http_status(node) do |ast_node| + checker = checker_class.new(ast_node) + return unless checker.offensive? + + add_offense(checker.node, message: checker.message) + end + end + + def autocorrect(node) + lambda do |corrector| + checker = checker_class.new(node) + corrector.replace(node.loc.expression, checker.preferred_style) + end + end + + private + + def checker_class + case style + when :symbolic + SymbolicStyleChecker + when :numeric + NumericStyleChecker + end + end + + # :nodoc: + class SymbolicStyleChecker + MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \ + 'to describe HTTP status code.'.freeze + + attr_reader :node + def initialize(node) + @node = node + end + + def offensive? + !node.sym_type? && !custom_http_status_code? + end + + def message + format(MSG, prefer: preferred_style, current: number.to_s) + end + + def preferred_style + symbol.inspect + end + + private + + def symbol + ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number) + end + + def number + node.source.to_i + end + + def custom_http_status_code? + node.int_type? && + !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(node.source.to_i) + end + end + + # :nodoc: + class NumericStyleChecker + MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \ + 'to describe HTTP status code.'.freeze + + WHITELIST_STATUS = %i[error success missing redirect].freeze + + attr_reader :node + def initialize(node) + @node = node + end + + def offensive? + !node.int_type? && !whitelisted_symbol? + end + + def message + format(MSG, prefer: preferred_style, current: symbol.inspect) + end + + def preferred_style + number.to_s + end + + private + + def number + ::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol] + end + + def symbol + node.value + end + + def whitelisted_symbol? + node.sym_type? && WHITELIST_STATUS.include?(node.value) + end + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_counts.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_counts.rb new file mode 100644 index 0000000000000000000000000000000000000000..e3c90fe204cf039600f7176c468af0b940f06243 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_counts.rb @@ -0,0 +1,86 @@ +module RuboCop + module Cop + module RSpec + # Check for `once` and `twice` receive counts matchers usage. + # + # @example + # + # # bad + # expect(foo).to receive(:bar).exactly(1).times + # expect(foo).to receive(:bar).exactly(2).times + # expect(foo).to receive(:bar).at_least(1).times + # expect(foo).to receive(:bar).at_least(2).times + # expect(foo).to receive(:bar).at_most(1).times + # expect(foo).to receive(:bar).at_most(2).times + # + # # good + # expect(foo).to receive(:bar).once + # expect(foo).to receive(:bar).twice + # expect(foo).to receive(:bar).at_least(:once) + # expect(foo).to receive(:bar).at_least(:twice) + # expect(foo).to receive(:bar).at_most(:once) + # expect(foo).to receive(:bar).at_most(:twice).times + # + class ReceiveCounts < Cop + include RangeHelp + + MSG = 'Use `%<alternative>s` instead of `%<original>s`.'.freeze + + def_node_matcher :receive_counts, <<-PATTERN + (send $(send _ {:exactly :at_least :at_most} (int {1 2})) :times) + PATTERN + + def on_send(node) + receive_counts(node) do |offending_node| + offending_range = range(node, offending_node) + + add_offense( + offending_node, + message: message_for(offending_node, offending_range.source), + location: offending_range + ) + end + end + + def autocorrect(node) + lambda do |corrector| + replacement = matcher_for( + node.method_name, + node.first_argument.source.to_i + ) + corrector.replace( + range(node.parent, node), + replacement + ) + end + end + + private + + def message_for(node, source) + alternative = matcher_for( + node.method_name, + node.first_argument.source.to_i + ) + format(MSG, alternative: alternative, original: source) + end + + def matcher_for(method, count) + matcher = count == 1 ? 'once' : 'twice' + if method == :exactly + ".#{matcher}" + else + ".#{method}(:#{matcher})" + end + end + + def range(node, offending_node) + range_between( + offending_node.loc.dot.begin_pos, + node.loc.expression.end_pos + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_never.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_never.rb new file mode 100644 index 0000000000000000000000000000000000000000..7a511ad0c993ae162c6fa46321c4243c5b051dde --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/receive_never.rb @@ -0,0 +1,43 @@ +module RuboCop + module Cop + module RSpec + # Prefer `not_to receive(...)` over `receive(...).never`. + # + # @example + # + # # bad + # expect(foo).to receive(:bar).never + # + # # good + # expect(foo).not_to receive(:bar) + # + class ReceiveNever < Cop + include RangeHelp + + MSG = 'Use `not_to receive` instead of `never`.'.freeze + + def_node_search :method_on_stub?, '(send nil? :receive ...)' + + def on_send(node) + return unless node.method_name == :never && method_on_stub?(node) + + add_offense( + node, + location: :selector + ) + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.parent.loc.selector, 'not_to') + range = range_between( + node.loc.dot.begin_pos, + node.loc.selector.end_pos + ) + corrector.remove(range) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_description.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_description.rb new file mode 100644 index 0000000000000000000000000000000000000000..af50789fe48c2dd664a4b82185b922bebd7ddad8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_description.rb @@ -0,0 +1,59 @@ +module RuboCop + module Cop + module RSpec + # Check for repeated description strings in example groups. + # + # @example + # + # # bad + # RSpec.describe User do + # it 'is valid' do + # # ... + # end + # + # it 'is valid' do + # # ... + # end + # end + # + # # good + # RSpec.describe User do + # it 'is valid when first and last name are present' do + # # ... + # end + # + # it 'is valid when last name only is present' do + # # ... + # end + # end + # + class RepeatedDescription < Cop + MSG = "Don't repeat descriptions within an example group.".freeze + + def on_block(node) + return unless example_group?(node) + + repeated_descriptions(node).each do |repeated_description| + add_offense(repeated_description, location: :expression) + end + end + + private + + # Select examples in the current scope with repeated description strings + def repeated_descriptions(node) + grouped_examples = + RuboCop::RSpec::ExampleGroup.new(node) + .examples + .group_by(&:doc_string) + + grouped_examples + .select { |description, group| description && group.size > 1 } + .values + .flatten + .map(&:definition) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_example.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_example.rb new file mode 100644 index 0000000000000000000000000000000000000000..7565c48583de08fb93e5c17f0f93f2edbc6bde41 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/repeated_example.rb @@ -0,0 +1,51 @@ +module RuboCop + module Cop + module RSpec + # Check for repeated examples within example groups. + # + # @example + # + # it 'is valid' do + # expect(user).to be_valid + # end + # + # it 'validates the user' do + # expect(user).to be_valid + # end + # + class RepeatedExample < Cop + MSG = "Don't repeat examples within an example group.".freeze + + def on_block(node) + return unless example_group?(node) + + repeated_examples(node).each do |repeated_example| + add_offense(repeated_example, location: :expression) + end + end + + private + + def repeated_examples(node) + RuboCop::RSpec::ExampleGroup.new(node) + .examples + .group_by { |example| example_signature(example) } + .values + .reject(&:one?) + .flatten + .map(&:to_node) + end + + def example_signature(example) + key_parts = [example.metadata, example.implementation] + + if example.definition.method_name == :its + key_parts << example.definition.arguments + end + + key_parts + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/return_from_stub.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/return_from_stub.rb new file mode 100644 index 0000000000000000000000000000000000000000..72d4ba20430148548dfa4dd72208a1bab6b46e22 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/return_from_stub.rb @@ -0,0 +1,173 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for consistent style of stub's return setting. + # + # Enforces either `and_return` or block-style return in the cases + # where the returned value is constant. Ignores dynamic returned values + # are the result would be different + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: block` + # # bad + # allow(Foo).to receive(:bar).and_return("baz") + # expect(Foo).to receive(:bar).and_return("baz") + # + # # good + # allow(Foo).to receive(:bar) { "baz" } + # expect(Foo).to receive(:bar) { "baz" } + # # also good as the returned value is dynamic + # allow(Foo).to receive(:bar).and_return(bar.baz) + # + # @example `EnforcedStyle: and_return` + # # bad + # allow(Foo).to receive(:bar) { "baz" } + # expect(Foo).to receive(:bar) { "baz" } + # + # # good + # allow(Foo).to receive(:bar).and_return("baz") + # expect(Foo).to receive(:bar).and_return("baz") + # # also good as the returned value is dynamic + # allow(Foo).to receive(:bar) { bar.baz } + # + class ReturnFromStub < Cop + include ConfigurableEnforcedStyle + + MSG_AND_RETURN = 'Use `and_return` for static values.'.freeze + MSG_BLOCK = 'Use block for static values.'.freeze + + def_node_search :contains_stub?, '(send nil? :receive (...))' + def_node_search :and_return_value, <<-PATTERN + $(send _ :and_return $(...)) + PATTERN + + def on_send(node) + return unless contains_stub?(node) + return unless style == :block + + check_and_return_call(node) + end + + def on_block(node) + return unless contains_stub?(node) + return unless style == :and_return + + check_block_body(node) + end + + def autocorrect(node) + if style == :block + AndReturnCallCorrector.new(node) + else + BlockBodyCorrector.new(node) + end + end + + private + + def check_and_return_call(node) + and_return_value(node) do |and_return, args| + unless dynamic?(args) + add_offense( + and_return, + location: :selector, + message: MSG_BLOCK + ) + end + end + end + + def check_block_body(block) + body = block.body + unless dynamic?(body) # rubocop:disable Style/GuardClause + add_offense( + block, + location: :begin, + message: MSG_AND_RETURN + ) + end + end + + def dynamic?(node) + node && !node.recursive_literal_or_const? + end + + # :nodoc: + class AndReturnCallCorrector + def initialize(node) + @node = node + @receiver = node.receiver + @arg = node.first_argument + end + + def call(corrector) + # Heredoc autocorrection is not yet implemented. + return if heredoc? + + corrector.replace(range, " { #{replacement} }") + end + + private + + attr_reader :node, :receiver, :arg + + def heredoc? + arg.loc.is_a?(Parser::Source::Map::Heredoc) + end + + def range + Parser::Source::Range.new( + node.source_range.source_buffer, + receiver.source_range.end_pos, + node.source_range.end_pos + ) + end + + def replacement + if hash_without_braces? + "{ #{arg.source} }" + else + arg.source + end + end + + def hash_without_braces? + arg.hash_type? && !arg.braces? + end + end + + # :nodoc: + class BlockBodyCorrector + def initialize(block) + @block = block + @node = block.parent + @body = block.body || NULL_BLOCK_BODY + end + + def call(corrector) + # Heredoc autocorrection is not yet implemented. + return if heredoc? + + corrector.replace( + block.loc.expression, + "#{block.send_node.source}.and_return(#{body.source})" + ) + end + + private + + attr_reader :node, :block, :body + + def heredoc? + body.loc.is_a?(Parser::Source::Map::Heredoc) + end + + NULL_BLOCK_BODY = Struct.new(:loc, :source).new(nil, 'nil') + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_let.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_let.rb new file mode 100644 index 0000000000000000000000000000000000000000..b640e40eaaef4ab1454fc80c1683ba27465cffb0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_let.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for let scattered across the example group. + # + # Group lets together + # + # @example + # # bad + # describe Foo do + # let(:foo) { 1 } + # subject { Foo } + # let(:bar) { 2 } + # before { prepare } + # let!(:baz) { 3 } + # end + # + # # good + # describe Foo do + # subject { Foo } + # before { prepare } + # let(:foo) { 1 } + # let(:bar) { 2 } + # let!(:baz) { 3 } + # end + # + class ScatteredLet < Cop + MSG = 'Group all let/let! blocks in the example group together.'.freeze + + def on_block(node) + return unless example_group_with_body?(node) + + check_let_declarations(node.body) + end + + private + + def check_let_declarations(body) + lets = body.each_child_node.select { |node| let?(node) } + + first_let = lets.first + lets.each_with_index do |node, idx| + next if node.sibling_index == first_let.sibling_index + idx + + add_offense(node, location: :expression) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_setup.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_setup.rb new file mode 100644 index 0000000000000000000000000000000000000000..f6ba564aa05d1539fc3049ca86588f7f44a13d64 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/scattered_setup.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for setup scattered across multiple hooks in an example group. + # + # Unify `before`, `after`, and `around` hooks when possible. + # + # @example + # # bad + # describe Foo do + # before { setup1 } + # before { setup2 } + # end + # + # # good + # describe Foo do + # before do + # setup1 + # setup2 + # end + # end + # + class ScatteredSetup < Cop + MSG = 'Do not define multiple hooks in the same example group.'.freeze + + def on_block(node) + return unless example_group?(node) + + analyzable_hooks(node).each do |repeated_hook| + add_offense(repeated_hook, location: :expression) + end + end + + def analyzable_hooks(node) + RuboCop::RSpec::ExampleGroup.new(node) + .hooks + .select { |hook| hook.knowable_scope? && hook.valid_scope? } + .group_by { |hook| [hook.name, hook.scope] } + .values + .reject(&:one?) + .flatten + .map(&:to_node) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_context.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_context.rb new file mode 100644 index 0000000000000000000000000000000000000000..9d774888615ff61ef5d4e04ad1e3371e5e9760a8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_context.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for proper shared_context and shared_examples usage. + # + # If there are no examples defined, use shared_context. + # If there is no setup defined, use shared_examples. + # + # @example + # # bad + # RSpec.shared_context 'only examples here' do + # it 'does x' do + # end + # + # it 'does y' do + # end + # end + # + # # good + # RSpec.shared_examples 'only examples here' do + # it 'does x' do + # end + # + # it 'does y' do + # end + # end + # + # @example + # # bad + # RSpec.shared_examples 'only setup here' do + # subject(:foo) { :bar } + # + # let(:baz) { :bazz } + # + # before do + # something + # end + # end + # + # # good + # RSpec.shared_context 'only setup here' do + # subject(:foo) { :bar } + # + # let(:baz) { :bazz } + # + # before do + # something + # end + # end + # + class SharedContext < Cop + MSG_EXAMPLES = "Use `shared_examples` when you don't "\ + 'define context.'.freeze + + MSG_CONTEXT = "Use `shared_context` when you don't "\ + 'define examples.'.freeze + + examples = (Examples::ALL + Includes::EXAMPLES) + def_node_search :examples?, examples.send_pattern + + context = (Hooks::ALL + Helpers::ALL + Includes::CONTEXT + Subject::ALL) + def_node_search :context?, context.send_pattern + + def_node_matcher :shared_context, SharedGroups::CONTEXT.block_pattern + def_node_matcher :shared_example, SharedGroups::EXAMPLES.block_pattern + + def on_block(node) + context_with_only_examples(node) do + add_shared_item_offense(node.send_node, MSG_EXAMPLES) + end + + examples_with_only_context(node) do + add_shared_item_offense(node.send_node, MSG_CONTEXT) + end + end + + def autocorrect(node) + lambda do |corrector| + context_with_only_examples(node.parent) do + corrector.replace(node.loc.selector, 'shared_examples') + end + + examples_with_only_context(node.parent) do + corrector.replace(node.loc.selector, 'shared_context') + end + end + end + + private + + def context_with_only_examples(node) + shared_context(node) { yield if examples?(node) && !context?(node) } + end + + def examples_with_only_context(node) + shared_example(node) { yield if context?(node) && !examples?(node) } + end + + def add_shared_item_offense(node, message) + add_offense( + node, + location: :expression, + message: message + ) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_examples.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_examples.rb new file mode 100644 index 0000000000000000000000000000000000000000..173e8e4c0817fa29395ff46285b98f13177de235 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/shared_examples.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Enforces use of string to titleize shared examples. + # + # @example + # # bad + # it_behaves_like :foo_bar_baz + # it_should_behave_like :foo_bar_baz + # shared_examples :foo_bar_baz + # shared_examples_for :foo_bar_baz + # include_examples :foo_bar_baz + # + # # good + # it_behaves_like 'foo bar baz' + # it_should_behave_like 'foo bar baz' + # shared_examples 'foo bar baz' + # shared_examples_for 'foo bar baz' + # include_examples 'foo bar baz' + # + class SharedExamples < Cop + def_node_matcher :shared_examples, <<-PATTERN + (send + {(const nil? :RSpec) nil?} + {#{(SharedGroups::ALL + Includes::ALL).node_pattern}} $sym ...) + PATTERN + + def on_send(node) + shared_examples(node) do |ast_node| + checker = Checker.new(ast_node) + add_offense(checker.node, message: checker.message) + end + end + + def autocorrect(node) + lambda do |corrector| + checker = Checker.new(node) + corrector.replace(node.loc.expression, checker.preferred_style) + end + end + + # :nodoc: + class Checker + MSG = 'Prefer %<prefer>s over `%<current>s` ' \ + 'to titleize shared examples.'.freeze + + attr_reader :node + def initialize(node) + @node = node + end + + def message + format(MSG, prefer: preferred_style, current: symbol.inspect) + end + + def preferred_style + string = symbol.to_s.tr('_', ' ') + wrap_with_single_quotes(string) + end + + private + + def symbol + node.value + end + + def wrap_with_single_quotes(string) + "'#{string}'" + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/single_argument_message_chain.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/single_argument_message_chain.rb new file mode 100644 index 0000000000000000000000000000000000000000..60a262e2a0a4060d07eabcdd1b6681b9e9739ddc --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/single_argument_message_chain.rb @@ -0,0 +1,73 @@ +module RuboCop + module Cop + module RSpec + # Checks that chains of messages contain more than one element. + # + # @example + # # bad + # allow(foo).to receive_message_chain(:bar).and_return(42) + # + # # good + # allow(foo).to receive(:bar).and_return(42) + # + # # also good + # allow(foo).to receive(:bar, :baz) + # allow(foo).to receive("bar.baz") + # + class SingleArgumentMessageChain < Cop + MSG = 'Use `%<recommended>s` instead of calling '\ + '`%<called>s` with a single argument.'.freeze + + def_node_matcher :message_chain, <<-PATTERN + (send _ {:receive_message_chain :stub_chain} $_) + PATTERN + + def_node_matcher :single_key_hash?, '(hash pair)' + + def on_send(node) + message_chain(node) do |arg| + return if arg.to_s.include?('.') + + return if arg.hash_type? && !single_key_hash?(arg) + + add_offense(node, location: :selector) + end + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.loc.selector, replacement(node.method_name)) + message_chain(node) do |arg| + autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg) + end + end + end + + private + + def autocorrect_hash_arg(corrector, arg) + key, value = *arg.children.first + + corrector.replace(arg.loc.expression, key_to_arg(key)) + corrector.insert_after(arg.parent.loc.end, + ".and_return(#{value.source})") + end + + def key_to_arg(node) + key, = *node + node.sym_type? ? ":#{key}" : node.source + end + + def replacement(method) + method.equal?(:receive_message_chain) ? 'receive' : 'stub' + end + + def message(node) + method = node.method_name + + format(MSG, recommended: replacement(method), called: method) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/subject_stub.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/subject_stub.rb new file mode 100644 index 0000000000000000000000000000000000000000..4447b941b833d09d2c6f903f3ca692f2efed78b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/subject_stub.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Checks for stubbed test subjects. + # + # @see https://robots.thoughtbot.com/don-t-stub-the-system-under-test + # + # @example + # # bad + # describe Foo do + # subject(:bar) { baz } + # + # before do + # allow(bar).to receive(:qux?).and_return(true) + # end + # end + # + class SubjectStub < Cop + include RuboCop::RSpec::TopLevelDescribe + + MSG = 'Do not stub your test subject.'.freeze + + # @!method subject(node) + # Find a named or unnamed subject definition + # + # @example anonymous subject + # subject(parse('subject { foo }').ast) do |name| + # name # => :subject + # end + # + # @example named subject + # subject(parse('subject(:thing) { foo }').ast) do |name| + # name # => :thing + # end + # + # @param node [RuboCop::Node] + # + # @yield [Symbol] subject name + def_node_matcher :subject, <<-PATTERN + { + (block (send nil? :subject (sym $_)) args ...) + (block (send nil? $:subject) args ...) + } + PATTERN + + # @!method message_expectation?(node, method_name) + # Match `allow` and `expect(...).to receive` + # + # @example source that matches + # allow(foo).to receive(:bar) + # allow(foo).to receive(:bar).with(1) + # allow(foo).to receive(:bar).with(1).and_return(2) + # expect(foo).to receive(:bar) + # expect(foo).to receive(:bar).with(1) + # expect(foo).to receive(:bar).with(1).and_return(2) + # + # @example source that not matches + # expect(foo).to all(receive(:bar)) + # + def_node_matcher :message_expectation?, <<-PATTERN + { + (send nil? :allow (send nil? %)) + (send (send nil? :expect (send nil? %)) :to #expectation?) + } + PATTERN + + def_node_matcher :all_matcher?, '(send nil? :all ...)' + + def_node_search :receive_message?, '(send nil? :receive ...)' + + def expectation?(node) + return if all_matcher?(node) + + receive_message?(node) + end + + def on_block(node) + return unless example_group?(node) + + find_subject_stub(node) do |stub| + add_offense(stub, location: :expression) + end + end + + private + + # Find subjects within tree and then find (send) nodes for that subject + # + # @param node [RuboCop::Node] example group + # + # @yield [RuboCop::Node] message expectations for subject + def find_subject_stub(node, &block) + find_subject(node) do |subject_name, context| + find_subject_expectation(context, subject_name, &block) + end + end + + # Find a subject message expectation + # + # @param node [RuboCop::Node] + # @param subject_name [Symbol] name of subject + # + # @yield [RuboCop::Node] message expectation + def find_subject_expectation(node, subject_name, &block) + # Do not search node if it is an example group with its own subject. + return if example_group?(node) && redefines_subject?(node) + + # Yield the current node if it is a message expectation. + yield(node) if message_expectation?(node, subject_name) + + # Recurse through node's children looking for a message expectation. + node.each_child_node do |child| + find_subject_expectation(child, subject_name, &block) + end + end + + # Check if node's children contain a subject definition + # + # @param node [RuboCop::Node] + # + # @return [Boolean] + def redefines_subject?(node) + node.each_child_node.any? do |child| + subject(child) || redefines_subject?(child) + end + end + + # Find a subject definition + # + # @param node [RuboCop::Node] + # @param parent [RuboCop::Node,nil] + # + # @yieldparam subject_name [Symbol] name of subject being defined + # @yieldparam parent [RuboCop::Node] parent of subject definition + def find_subject(node, parent: nil, &block) + subject(node) { |name| yield(name, parent) } + + node.each_child_node do |child| + find_subject(child, parent: node, &block) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/unspecified_exception.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/unspecified_exception.rb new file mode 100644 index 0000000000000000000000000000000000000000..abe79eab89671de8067dcfab08807583125e1038 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/unspecified_exception.rb @@ -0,0 +1,64 @@ +module RuboCop + module Cop + module RSpec + # Checks for a specified error in checking raised errors. + # + # Enforces one of an Exception type, a string, or a regular + # expression to match against the exception message as a parameter + # to `raise_error` + # + # @example + # + # # bad + # expect { + # raise StandardError.new('error') + # }.to raise_error + # + # # good + # expect { + # raise StandardError.new('error') + # }.to raise_error(StandardError) + # + # expect { + # raise StandardError.new('error') + # }.to raise_error('error') + # + # expect { + # raise StandardError.new('error') + # }.to raise_error(/err/) + # + # expect { do_something }.not_to raise_error + class UnspecifiedException < Cop + MSG = 'Specify the exception being captured'.freeze + + def_node_matcher :empty_raise_error_or_exception, <<-PATTERN.freeze + (send + (block + (send nil? :expect) ...) + :to + (send nil? {:raise_error :raise_exception}) + ) + PATTERN + + def on_send(node) + return unless empty_exception_matcher?(node) + + add_offense( + node.children.last, + location: :expression + ) + end + + def empty_exception_matcher?(node) + empty_raise_error_or_exception(node) && !block_with_args?(node.parent) + end + + def block_with_args?(node) + return unless node && node.block_type? + + node.arguments? + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/verified_doubles.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/verified_doubles.rb new file mode 100644 index 0000000000000000000000000000000000000000..d9be17c9aecd543678ef600da547ec995baa4210 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/verified_doubles.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # Prefer using verifying doubles over normal doubles. + # + # @see https://relishapp.com/rspec/rspec-mocks/docs/verifying-doubles + # + # @example + # # bad + # let(:foo) do + # double(method_name: 'returned value') + # end + # + # # bad + # let(:foo) do + # double("ClassName", method_name: 'returned value') + # end + # + # # good + # let(:foo) do + # instance_double("ClassName", method_name: 'returned value') + # end + class VerifiedDoubles < Cop + MSG = 'Prefer using verifying doubles over normal doubles.'.freeze + + def_node_matcher :unverified_double, <<-PATTERN + {(send nil? {:double :spy} $...)} + PATTERN + + def on_send(node) + unverified_double(node) do |name, *_args| + return if name.nil? && cop_config['IgnoreNameless'] + return if symbol?(name) && cop_config['IgnoreSymbolicNames'] + + add_offense(node, location: :expression) + end + end + + private + + def symbol?(name) + name && name.sym_type? + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/void_expect.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/void_expect.rb new file mode 100644 index 0000000000000000000000000000000000000000..4a78035ec3996d413c18508c91d270ce7e0fdd5d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec/void_expect.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module RSpec + # This cop checks void `expect()`. + # + # @example + # # bad + # expect(something) + # + # # good + # expect(something).to be(1) + class VoidExpect < Cop + MSG = 'Do not use `expect()` without `.to` or `.not_to`. ' \ + 'Chain the methods or remove it.'.freeze + + def_node_matcher :expect?, <<-PATTERN + (send nil? :expect ...) + PATTERN + + def_node_matcher :expect_block?, <<-PATTERN + (block #expect? (args) _body) + PATTERN + + def on_send(node) + return unless expect?(node) + + check_expect(node) + end + + def on_block(node) + return unless expect_block?(node) + + check_expect(node) + end + + private + + def check_expect(node) + return unless void?(node) + + add_offense(node, location: :expression) + end + + def void?(expect) + parent = expect.parent + return true unless parent + return true if parent.begin_type? + return true if parent.block_type? && parent.body == expect + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec_cops.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec_cops.rb new file mode 100644 index 0000000000000000000000000000000000000000..42eb3057eda8d5aa60722a825651605c6c2e4faf --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/cop/rspec_cops.rb @@ -0,0 +1,77 @@ +require_relative 'rspec/capybara/current_path_expectation' +require_relative 'rspec/capybara/feature_methods' + +require_relative 'rspec/factory_bot/attribute_defined_statically' +require_relative 'rspec/factory_bot/create_list' + +begin + require_relative 'rspec/rails/http_status' +rescue LoadError # rubocop:disable Lint/HandleExceptions + # Rails/HttpStatus cannot be loaded if rack/utils is unavailable. +end + +require_relative 'rspec/align_left_let_brace' +require_relative 'rspec/align_right_let_brace' +require_relative 'rspec/any_instance' +require_relative 'rspec/around_block' +require_relative 'rspec/be' +require_relative 'rspec/be_eql' +require_relative 'rspec/before_after_all' +require_relative 'rspec/context_wording' +require_relative 'rspec/describe_class' +require_relative 'rspec/describe_method' +require_relative 'rspec/describe_symbol' +require_relative 'rspec/described_class' +require_relative 'rspec/empty_example_group' +require_relative 'rspec/empty_line_after_example_group' +require_relative 'rspec/empty_line_after_final_let' +require_relative 'rspec/empty_line_after_hook' +require_relative 'rspec/empty_line_after_subject' +require_relative 'rspec/example_length' +require_relative 'rspec/example_without_description' +require_relative 'rspec/example_wording' +require_relative 'rspec/expect_actual' +require_relative 'rspec/expect_change' +require_relative 'rspec/expect_in_hook' +require_relative 'rspec/expect_output' +require_relative 'rspec/file_path' +require_relative 'rspec/focus' +require_relative 'rspec/hook_argument' +require_relative 'rspec/hooks_before_examples' +require_relative 'rspec/implicit_expect' +require_relative 'rspec/implicit_subject' +require_relative 'rspec/instance_spy' +require_relative 'rspec/instance_variable' +require_relative 'rspec/invalid_predicate_matcher' +require_relative 'rspec/it_behaves_like' +require_relative 'rspec/iterated_expectation' +require_relative 'rspec/leading_subject' +require_relative 'rspec/let_before_examples' +require_relative 'rspec/let_setup' +require_relative 'rspec/message_chain' +require_relative 'rspec/message_expectation' +require_relative 'rspec/message_spies' +require_relative 'rspec/missing_example_group_argument' +require_relative 'rspec/multiple_describes' +require_relative 'rspec/multiple_expectations' +require_relative 'rspec/multiple_subjects' +require_relative 'rspec/named_subject' +require_relative 'rspec/nested_groups' +require_relative 'rspec/not_to_not' +require_relative 'rspec/overwriting_setup' +require_relative 'rspec/pending' +require_relative 'rspec/predicate_matcher' +require_relative 'rspec/receive_counts' +require_relative 'rspec/receive_never' +require_relative 'rspec/repeated_description' +require_relative 'rspec/repeated_example' +require_relative 'rspec/return_from_stub' +require_relative 'rspec/scattered_let' +require_relative 'rspec/scattered_setup' +require_relative 'rspec/shared_context' +require_relative 'rspec/shared_examples' +require_relative 'rspec/single_argument_message_chain' +require_relative 'rspec/subject_stub' +require_relative 'rspec/unspecified_exception' +require_relative 'rspec/verified_doubles' +require_relative 'rspec/void_expect' diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec.rb new file mode 100644 index 0000000000000000000000000000000000000000..13861d71995d734f0f410f32fd8c2fc4d1253ce5 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec.rb @@ -0,0 +1,10 @@ +module RuboCop + # RuboCop RSpec project namespace + module RSpec + PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze + CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze + CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze + + private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT) + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/align_let_brace.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/align_let_brace.rb new file mode 100644 index 0000000000000000000000000000000000000000..83c684bfeb9f7f9683beda983a674e80fd428e8e --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/align_let_brace.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Shared behavior for aligning braces for single line lets + class AlignLetBrace + include RuboCop::RSpec::Language::NodePattern + + def initialize(root, token) + @root = root + @token = token + end + + def offending_tokens + single_line_lets.reject do |let| + target_column_for(let) == let_token(let).column + end + end + + def indent_for(node) + ' ' * (target_column_for(node) - let_token(node).column) + end + + private + + def let_token(node) + node.loc.public_send(token) + end + + def target_column_for(let) + let_group_for(let).map { |member| let_token(member).column }.max + end + + def let_group_for(let) + adjacent_let_chunks.detect do |chunk| + chunk.any? do |member| + member == let && member.loc.line == let.loc.line + end + end + end + + def adjacent_let_chunks + last_line = nil + + single_line_lets.chunk do |node| + line = node.loc.line + last_line = (line if last_line.nil? || last_line + 1 == line) + last_line.nil? + end.map(&:last) + end + + def single_line_lets + @single_line_lets ||= + root.each_node(:block).select do |node| + let?(node) && node.single_line? + end + end + + attr_reader :root, :token + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/blank_line_separation.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/blank_line_separation.rb new file mode 100644 index 0000000000000000000000000000000000000000..f187ffbc754bc50f6defe7f2a0e881cdd758bee7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/blank_line_separation.rb @@ -0,0 +1,43 @@ +module RuboCop + module RSpec + # Helps determine the offending location if there is not a blank line + # following the node. Allows comments to follow directly after. + module BlankLineSeparation + include FinalEndLocation + include RuboCop::Cop::RangeHelp + + def missing_separating_line(node) + line = final_end_location(node).line + + line += 1 while comment_line?(processed_source[line]) + + return if processed_source[line].blank? + + yield offending_loc(line) + end + + def offending_loc(last_line) + offending_line = processed_source[last_line - 1] + + content_length = offending_line.lstrip.length + start = offending_line.length - content_length + + source_range(processed_source.buffer, last_line, start, content_length) + end + + def last_child?(node) + return true unless node.parent && node.parent.begin_type? + + node.equal?(node.parent.children.last) + end + + def autocorrect(node) + lambda do |corrector| + missing_separating_line(node) do |location| + corrector.insert_after(location.end, "\n") + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/concept.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/concept.rb new file mode 100644 index 0000000000000000000000000000000000000000..9a66ede9d5ceb28296587070be3f0b3a04d85259 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/concept.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Wrapper for RSpec DSL methods + class Concept + include Language + include Language::NodePattern + extend NodePattern::Macros + + def initialize(node) + @node = node + end + + def eql?(other) + node == other.node + end + + alias == eql? + + def hash + [self.class, node].hash + end + + def to_node + node + end + + protected + + attr_reader :node + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/config_formatter.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/config_formatter.rb new file mode 100644 index 0000000000000000000000000000000000000000..1cfd9e12c229ee52e8ee011aeb02809ccf543655 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/config_formatter.rb @@ -0,0 +1,36 @@ +require 'yaml' + +module RuboCop + module RSpec + # Builds a YAML config file from two config hashes + class ConfigFormatter + NAMESPACES = /^(RSpec|Capybara|FactoryBot|Rails)/ + STYLE_GUIDE_BASE_URL = 'http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/'.freeze + + def initialize(config, descriptions) + @config = config + @descriptions = descriptions + end + + def dump + YAML.dump(unified_config).gsub(NAMESPACES, "\n\\1") + end + + private + + def unified_config + cops.each_with_object(config.dup) do |cop, unified| + unified[cop] = config.fetch(cop) + .merge(descriptions.fetch(cop)) + .merge('StyleGuide' => STYLE_GUIDE_BASE_URL + cop.sub('RSpec/', '')) + end + end + + def cops + (descriptions.keys | config.keys).grep(NAMESPACES) + end + + attr_reader :config, :descriptions + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/description_extractor.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/description_extractor.rb new file mode 100644 index 0000000000000000000000000000000000000000..ed48ce2060c8ca935fc2ed55b85d81b6111a537d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/description_extractor.rb @@ -0,0 +1,84 @@ +module RuboCop + module RSpec + # Extracts cop descriptions from YARD docstrings + class DescriptionExtractor + def initialize(yardocs) + @code_objects = yardocs.map(&CodeObject.public_method(:new)) + end + + def to_h + code_objects + .select(&:rspec_cop?) + .map(&:configuration) + .reduce(:merge) + end + + private + + attr_reader :code_objects + + # Decorator of a YARD code object for working with documented rspec cops + class CodeObject + COP_CLASS_NAMES = %w[RuboCop::Cop RuboCop::Cop::RSpec::Cop].freeze + RSPEC_NAMESPACE = 'RuboCop::Cop::RSpec'.freeze + + def initialize(yardoc) + @yardoc = yardoc + end + + # Test if the YARD code object documents a concrete rspec cop class + # + # @return [Boolean] + def rspec_cop? + class_documentation? && + rspec_cop_namespace? && + cop_subclass? && + !abstract? + end + + # Configuration for the documented cop that would live in default.yml + # + # @return [Hash] + def configuration + { cop_name => { 'Description' => description } } + end + + private + + def cop_name + Object.const_get(documented_constant).cop_name + end + + def description + yardoc.docstring.split("\n\n").first.to_s + end + + def class_documentation? + yardoc.type.equal?(:class) + end + + def rspec_cop_namespace? + documented_constant.start_with?(RSPEC_NAMESPACE) + end + + def documented_constant + yardoc.to_s + end + + def cop_subclass? + # YARD superclass resolution is a bit flaky: All classes loaded before + # RuboCop::Cop::WorkaroundCop are shown as having RuboCop::Cop as + # superclass, while all the following classes are listed as having + # RuboCop::Cop::RSpec::Cop as their superclass. + COP_CLASS_NAMES.include?(yardoc.superclass.path) + end + + def abstract? + yardoc.tags.any? { |tag| tag.tag_name.eql?('abstract') } + end + + attr_reader :yardoc + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example.rb new file mode 100644 index 0000000000000000000000000000000000000000..025fc6a4310185a36e5b66bdd3526037c66d9465 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Wrapper for RSpec examples + class Example < Concept + def_node_matcher :extract_doc_string, '(send _ _ $str ...)' + def_node_matcher :extract_metadata, '(send _ _ _ $...)' + def_node_matcher :extract_implementation, '(block send args $_)' + + def doc_string + extract_doc_string(definition) + end + + def metadata + extract_metadata(definition) + end + + def implementation + extract_implementation(node) + end + + def definition + if node.send_type? + node + else + node.send_node + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example_group.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..8a88ed3f07e35cdb4e132543f733db9d225b3760 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/example_group.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Wrapper for RSpec example groups + class ExampleGroup < Concept + # @!method scope_change?(node) + # + # Detect if the node is an example group or shared example + # + # Selectors which indicate that we should stop searching + # + def_node_matcher :scope_change?, ( + ExampleGroups::ALL + SharedGroups::ALL + Includes::ALL + ).block_pattern + + def subjects + subjects_in_scope(node) + end + + def examples + examples_in_scope(node).map(&Example.public_method(:new)) + end + + def hooks + hooks_in_scope(node).map(&Hook.public_method(:new)) + end + + private + + def subjects_in_scope(node) + node.each_child_node.flat_map do |child| + find_subjects(child) + end + end + + def find_subjects(node) + return [] if scope_change?(node) + + if subject?(node) + [node] + else + subjects_in_scope(node) + end + end + + def hooks_in_scope(node) + node.each_child_node.flat_map do |child| + find_hooks(child) + end + end + + def find_hooks(node) + return [] if scope_change?(node) || example?(node) + + if hook?(node) + [node] + else + hooks_in_scope(node) + end + end + + def examples_in_scope(node, &blk) + node.each_child_node.flat_map do |child| + find_examples(child, &blk) + end + end + + # Recursively search for examples within the current scope + # + # Searches node for examples and halts when a scope change is detected + # + # @param node [RuboCop::Node] node to recursively search for examples + # + # @return [Array<RuboCop::Node>] discovered example nodes + def find_examples(node) + return [] if scope_change?(node) + + if example?(node) + [node] + else + examples_in_scope(node) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/final_end_location.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/final_end_location.rb new file mode 100644 index 0000000000000000000000000000000000000000..ee1dc9dddf45ff7ca24f500929b0f9db877ef24d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/final_end_location.rb @@ -0,0 +1,15 @@ +module RuboCop + module RSpec + # Helps find the true end location of nodes which might contain heredocs. + module FinalEndLocation + def final_end_location(start_node) + heredoc_endings = + start_node.each_node(:str, :dstr, :xstr) + .select(&:heredoc?) + .map { |node| node.loc.heredoc_end } + + [start_node.loc.end, *heredoc_endings].max_by(&:line) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/hook.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/hook.rb new file mode 100644 index 0000000000000000000000000000000000000000..a942b794da799f0e2554d9f6d08de7d744b4c429 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/hook.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Wrapper for RSpec hook + class Hook < Concept + STANDARDIZED_SCOPES = %i[each context suite].freeze + private_constant(:STANDARDIZED_SCOPES) + + def name + node.method_name + end + + def knowable_scope? + return true unless scope_argument + + scope_argument.sym_type? + end + + def valid_scope? + STANDARDIZED_SCOPES.include?(scope) + end + + def example? + scope.equal?(:each) + end + + def scope + case scope_name + when nil, :each, :example then :each + when :context, :all then :context + when :suite then :suite + else + scope_name + end + end + + private + + def scope_name + scope_argument.to_a.first + end + + def scope_argument + node.send_node.first_argument + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/inject.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/inject.rb new file mode 100644 index 0000000000000000000000000000000000000000..3389bba3aae039eea925f3ed07935013867e814f --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/inject.rb @@ -0,0 +1,16 @@ +module RuboCop + module RSpec + # Because RuboCop doesn't yet support plugins, we have to monkey patch in a + # bit of our configuration. + module Inject + def self.defaults! + path = CONFIG_DEFAULT.to_s + hash = ConfigLoader.send(:load_yaml_configuration, path) + config = Config.new(hash, path) + puts "configuration from #{path}" if ConfigLoader.debug? + config = ConfigLoader.merge_with_default(config, path) + ConfigLoader.instance_variable_set(:@default_configuration, config) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language.rb new file mode 100644 index 0000000000000000000000000000000000000000..93992b988b76185317659b1a4d9bc00c11665bbd --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # RSpec public API methods that are commonly used in cops + module Language + # Set of method selectors + class SelectorSet + def initialize(selectors) + @selectors = selectors + end + + def ==(other) + selectors.eql?(other.selectors) + end + + def +(other) + self.class.new(selectors + other.selectors) + end + + def include?(selector) + selectors.include?(selector) + end + + def block_pattern + "(block #{send_pattern} ...)" + end + + def send_pattern + "(send {(const nil? :RSpec) nil?} #{node_pattern_union} ...)" + end + + def node_pattern_union + "{#{node_pattern}}" + end + + def node_pattern + selectors.map(&:inspect).join(' ') + end + + protected + + attr_reader :selectors + end + + module ExampleGroups + GROUPS = SelectorSet.new(%i[describe context feature example_group]) + SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature]) + FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature]) + + ALL = GROUPS + SKIPPED + FOCUSED + end + + module SharedGroups + EXAMPLES = SelectorSet.new(%i[shared_examples shared_examples_for]) + CONTEXT = SelectorSet.new(%i[shared_context]) + + ALL = EXAMPLES + CONTEXT + end + + module Includes + EXAMPLES = SelectorSet.new( + %i[ + it_behaves_like + it_should_behave_like + include_examples + ] + ) + CONTEXT = SelectorSet.new(%i[include_context]) + + ALL = EXAMPLES + CONTEXT + end + + module Examples + EXAMPLES = SelectorSet.new(%i[it specify example scenario its]) + FOCUSED = SelectorSet.new(%i[fit fspecify fexample fscenario focus]) + SKIPPED = SelectorSet.new(%i[xit xspecify xexample xscenario skip]) + PENDING = SelectorSet.new(%i[pending]) + + ALL = EXAMPLES + FOCUSED + SKIPPED + PENDING + end + + module Hooks + ALL = SelectorSet.new( + %i[ + prepend_before + before + append_before + around + prepend_after + after + append_after + ] + ) + end + + module Helpers + ALL = SelectorSet.new(%i[let let!]) + end + + module Subject + ALL = SelectorSet.new(%i[subject subject!]) + end + + module Expectations + ALL = SelectorSet.new(%i[expect is_expected expect_any_instance_of]) + end + + ALL = + ExampleGroups::ALL + + SharedGroups::ALL + + Examples::ALL + + Hooks::ALL + + Helpers::ALL + + Subject::ALL + + Expectations::ALL + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language/node_pattern.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language/node_pattern.rb new file mode 100644 index 0000000000000000000000000000000000000000..63378fd4222dde14f4cc2340fc7d18a5f8b96216 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/language/node_pattern.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + module Language + # Common node matchers used for matching against the rspec DSL + module NodePattern + extend RuboCop::NodePattern::Macros + + def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern + + def_node_matcher :example_group_with_body?, <<-PATTERN + (block #{ExampleGroups::ALL.send_pattern} args [!nil?]) + PATTERN + + def_node_matcher :example?, Examples::ALL.block_pattern + + def_node_matcher :hook?, Hooks::ALL.block_pattern + + def_node_matcher :let?, Helpers::ALL.block_pattern + + def_node_matcher :subject?, Subject::ALL.block_pattern + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/node.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/node.rb new file mode 100644 index 0000000000000000000000000000000000000000..5281dfaf439f30f131223932a36fedffeb214724 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/node.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # RuboCop-RSpec specific extensions of RuboCop::AST::Node + module Node + # In various cops we want to regard const as literal althought it's not + # strictly literal. + def recursive_literal_or_const? + case type + when :begin, :pair, *AST::Node::COMPOSITE_LITERALS + children.all?(&:recursive_literal_or_const?) + else + literal? || const_type? + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/top_level_describe.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/top_level_describe.rb new file mode 100644 index 0000000000000000000000000000000000000000..f40af18aa6b702704fff0ee93be694d6cdfa4e26 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/top_level_describe.rb @@ -0,0 +1,54 @@ +module RuboCop + module RSpec + # Helper methods for top level describe cops + module TopLevelDescribe + extend NodePattern::Macros + + def_node_matcher :described_constant, <<-PATTERN + (block $(send _ :describe $(const ...)) (args) $_) + PATTERN + + def on_send(node) + return unless respond_to?(:on_top_level_describe) + return unless top_level_describe?(node) + + on_top_level_describe(node, node.arguments) + end + + private + + def top_level_describe?(node) + return false unless node.method_name == :describe + + top_level_nodes.include?(node) + end + + def top_level_nodes + nodes = describe_statement_children(root_node) + # If we have no top level describe statements, we need to check any + # blocks on the top level (e.g. after a require). + if nodes.empty? + nodes = root_node.each_child_node(:block).flat_map do |child| + describe_statement_children(child) + end + end + + nodes + end + + def root_node + processed_source.ast + end + + def single_top_level_describe? + top_level_nodes.one? + end + + def describe_statement_children(node) + node.each_child_node(:send).select do |element| + element.method_name == :describe + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/util.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/util.rb new file mode 100644 index 0000000000000000000000000000000000000000..33a55c16a869bff9c13ad7ee49a705fd1c54816d --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/util.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Utility methods + module Util + # Error raised by `Util.one` if size is less than zero or greater than one + SizeError = Class.new(IndexError) + + # Return only element in array if it contains exactly one member + def one(array) + return array.first if array.one? + + raise SizeError, + "expected size to be exactly 1 but size was #{array.size}" + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/version.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/version.rb new file mode 100644 index 0000000000000000000000000000000000000000..fac9981953ac5afc7cc1e8f2ce25a6a27f7718e4 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # Version information for the RSpec RuboCop plugin. + module Version + STRING = '1.30.0'.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/wording.rb b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/wording.rb new file mode 100644 index 0000000000000000000000000000000000000000..9eb7a05d9d883538a8d5d558f8490b1fd1e15e71 --- /dev/null +++ b/Library/Homebrew/vendor/bundle-standalone/ruby/2.3.0/gems/rubocop-rspec-1.30.0/lib/rubocop/rspec/wording.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module RuboCop + module RSpec + # RSpec example wording rewriter + class Wording + SHOULDNT_PREFIX = /\Ashould(?:n't| not)\b/i + SHOULDNT_BE_PREFIX = /#{SHOULDNT_PREFIX} be\b/i + ES_SUFFIX_PATTERN = /(?:o|s|x|ch|sh|z)\z/i + IES_SUFFIX_PATTERN = /[^aeou]y\z/i + + def initialize(text, ignore:, replace:) + @text = text + @ignores = ignore + @replacements = replace + end + + def rewrite + case text + when SHOULDNT_BE_PREFIX + replace_prefix(SHOULDNT_BE_PREFIX, 'is not') + when SHOULDNT_PREFIX + replace_prefix(SHOULDNT_PREFIX, 'does not') + else + remove_should_and_pluralize + end + end + + private + + attr_reader :text, :ignores, :replacements + + def replace_prefix(pattern, replacement) + text.sub(pattern) do |shouldnt| + uppercase?(shouldnt) ? replacement.upcase : replacement + end + end + + def uppercase?(word) + word.upcase.eql?(word) + end + + def remove_should_and_pluralize + _should, *words = text.split + + words.each_with_index do |word, index| + next if ignored_word?(word) + + words[index] = substitute(word) + + break + end + + words.join(' ') + end + + def ignored_word?(word) + ignores.any? { |ignore| ignore.casecmp(word).zero? } + end + + def substitute(word) + # NOTE: Custom replacements are case sensitive. + return replacements.fetch(word) if replacements.key?(word) + + case word + when ES_SUFFIX_PATTERN then append_suffix(word, 'es') + when IES_SUFFIX_PATTERN then append_suffix(word[0..-2], 'ies') + else append_suffix(word, 's') + end + end + + def append_suffix(word, suffix) + suffix = suffix.upcase if uppercase?(word) + + "#{word}#{suffix}" + end + + private_constant(*constants(false)) + end + end +end