brew vendor-gems: commit updates.
This commit is contained in:
parent
86d935d147
commit
4f86e1d54e
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,6 +31,7 @@
|
||||
|
||||
# Unignore vendored gems
|
||||
!**/vendor/bundle-standalone/ruby/*/gems/*/lib
|
||||
!**/vendor/bundle-standalone/ruby/*/gems/rubocop-rspec-*/config
|
||||
|
||||
# Ignore partially included gems where we don't need all files
|
||||
**/vendor/bundle-standalone/ruby/2.3.0/gems/activesupport-*/lib/active_support.rb
|
||||
|
||||
@ -21,6 +21,6 @@ $:.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.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.61.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.30.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.62.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.31.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.1.0/lib"
|
||||
|
||||
@ -1,391 +0,0 @@
|
||||
# Change log
|
||||
|
||||
## Master (Unreleased)
|
||||
|
||||
## 1.30.1 (2018-11-01)
|
||||
|
||||
* `FactoryBot/CreateList` now ignores `times` blocks with an argument. ([@Darhazer][])
|
||||
|
||||
## 1.30.0 (2018-10-08)
|
||||
|
||||
* Add config to `RSpec/VerifiedDoubles` to enforcement of verification on unnamed doubles. ([@BrentWheeldon][])
|
||||
* Fix `FactoryBot/AttributeDefinedStatically` not working when there is a non-symbol key. ([@vzvu3k6k][])
|
||||
* Fix false positive in `RSpec/ImplicitSubject` when `is_expected` is used inside `its()` block. ([@Darhazer][])
|
||||
* Add `single_statement_only` style to `RSpec/ImplicitSubject` as a more relaxed alternative to `single_line_only`. ([@Darhazer][])
|
||||
* Add `RSpec/UnspecifiedException` as a default cop to encourage more-specific `expect{}.to raise_error(ExceptionType)`, or `raise_exception` style handling of exceptions. ([@daveworth][])
|
||||
|
||||
## 1.29.1 (2018-09-01)
|
||||
|
||||
* Fix false negative in `FactoryBot/AttributeDefinedStatically` when attribute is defined on `self`. ([@Darhazer][])
|
||||
* `RSpec/FactoryBot` cops will now also inspect the `spec/factories.rb` path by default. ([@bquorning][])
|
||||
|
||||
## 1.29.0 (2018-08-25)
|
||||
|
||||
* `RSpec/InstanceVariable` - Recommend local variables in addition to `let`. ([@jaredbeck][])
|
||||
* Add `RSpec/ImplicitSubject` cop. ([@Darhazer][])
|
||||
* Add `RSpec/HooksBeforeExamples` cop. ([@Darhazer][])
|
||||
|
||||
## 1.28.0 (2018-08-14)
|
||||
|
||||
* Add `RSpec/ReceiveNever` cop enforcing usage of `not_to receive` instead of `never` matcher. ([@Darhazer][])
|
||||
* Fix false positive in `RSpec/EmptyLineAfterExampleGroup` cop when example is inside `if`. ([@Darhazer][])
|
||||
* Add `RSpec/MissingExampleGroupArgument` to enforce first argument for an example group. ([@geniou][])
|
||||
* Drop support for ruby `2.1`. ([@bquorning][])
|
||||
* Add `FactoryBot/AttributeDefinedStatically` cop to help FactoryBot users with the deprecation of static attributes. ([@composerinteralia][], [@seanpdoyle][])
|
||||
* Remove `FactoryBot/DynamicAttributeDefinedStatically` and `FactoryBot/StaticAttributeDefinedDynamically` cops. ([@composerinteralia][])
|
||||
|
||||
## 1.27.0 (2018-06-14)
|
||||
|
||||
* `RSpec/LeadingSubject` now enforces subject to be before any examples, hooks or let declarations. ([@Darhazer][])
|
||||
* Fix `RSpec/NotToNot` to highlight only the selector (`not_to` or `to_not`), so it works also on `expect { ... }` blocks. ([@bquorning][])
|
||||
* Add `RSpec/EmptyLineAfterHook` cop. ([@bquorning][])
|
||||
* Add `RSpec/EmptyLineAfterExampleGroup` cop to check that there is an empty line after example group blocks. ([@bquorning][])
|
||||
* Fix `RSpec/DescribeClass` crashing on `RSpec.describe` without arguments. ([@Darhazer][])
|
||||
* Bump RuboCop requirement to v0.56.0. ([@bquorning][])
|
||||
* Fix `RSpec/OverwritingSetup` crashing if a variable is used as an argument for `let`. ([@Darhazer][])
|
||||
|
||||
## 1.26.0 (2018-06-06)
|
||||
|
||||
* Fix false positive in `RSpec/EmptyExampleGroup` cop when methods named like a RSpec method are used. ([@Darhazer][])
|
||||
* Fix `Capybara/FeatureMethods` not working when there is require before the spec. ([@Darhazer][])
|
||||
* Fix `RSpec/EmptyLineAfterFinalLet`: allow a comment to be placed after latest let, requiring empty line after the comment. ([@Darhazer][])
|
||||
* Add `RSpec/ReceiveCounts` cop to enforce usage of :once and :twice matchers. ([@Darhazer][])
|
||||
|
||||
## 1.25.1 (2018-04-10)
|
||||
|
||||
* Fix false positive in `RSpec/Pending` cop when pending is used as a method name. ([@Darhazer][])
|
||||
* Fix `FactoryBot/DynamicAttributeDefinedStatically` false positive when using symbol proc argument for a sequence. ([@tdeo][])
|
||||
|
||||
## 1.25.0 (2018-04-07)
|
||||
|
||||
* Add `RSpec/SharedExamples` cop to enforce consistent usage of string to titleize shared examples. ([@anthony-robin][])
|
||||
* Add `RSpec/Be` cop to enforce passing argument to the generic `be` matcher. ([@Darhazer][])
|
||||
* Fix false positives in `StaticAttributeDefinedDynamically` and `ReturnFromStub` when a const is used in an array or hash. ([@Darhazer][])
|
||||
* Add `RSpec/Pending` cop to enforce no existing pending or skipped examples. This is disabled by default. ([@patrickomatic][])
|
||||
* Fix `RSpec/NestedGroups` cop support --auto-gen-config. ([@walf443][])
|
||||
* Fix false positives in `Capybara/FeatureMethods` when feature methods are used as property names in a factory. ([@Darhazer][])
|
||||
* Allow configuring enabled methods in `Capybara/FeatureMethods`. ([@Darhazer][])
|
||||
* Add `FactoryBot/CreateList` cop. ([@Darhazer][])
|
||||
|
||||
## 1.24.0 (2018-03-06)
|
||||
|
||||
* Compatibility with RuboCop v0.53.0. ([@bquorning][])
|
||||
* The `Rails/HttpStatus` cop is unavailable if the `rack` gem cannot be loaded. ([@bquorning][])
|
||||
* Fix `Rails/HttpStatus` not working with custom HTTP status codes. ([@bquorning][])
|
||||
* Fix `FactoryBot/StaticAttributeDefinedDynamically` to handle empty block. ([@abrom][])
|
||||
* Fix false positive in `FactoryBot/DynamicAttributeDefinedStatically` when a before/after callback has a symbol proc argument. ([@abrom][])
|
||||
|
||||
## 1.23.0 (2018-02-23)
|
||||
|
||||
* Add `RSpec/Rails/HttpStatus` cop to enforce consistent usage of the status format (numeric or symbolic). ([@anthony-robin][], [@jojos003][])
|
||||
* Fix false negative in `RSpec/ReturnFromStub` when a constant is being returned by the stub. ([@Darhazer][])
|
||||
* Fix `FactoryBot/DynamicAttributeDefinedStatically` to handle dynamic attributes inside arrays/hashes. ([@abrom][])
|
||||
* Add `FactoryBot/StaticAttributeDefinedDynamically` (based on dynamic attribute cop). ([@abrom][])
|
||||
|
||||
## 1.22.2 (2018-02-01)
|
||||
|
||||
* Fix error in `RSpec/DescribedClass` when working on an empty `describe` block. ([@bquorning][])
|
||||
|
||||
## 1.22.1 (2018-01-17)
|
||||
|
||||
* Fix false positives in `RSpec/ReturnFromStub`. ([@Darhazer][])
|
||||
|
||||
## 1.22.0 (2018-01-10)
|
||||
|
||||
* Updates `describe_class` to account for RSpecs `:system` wrapper of rails system tests. ([@EliseFitz15][])
|
||||
* Add `RSpec/ExpectChange` cop to enforce consistent usage of the change matcher. ([@Darhazer][])
|
||||
* Add autocorrect support to `RSpec/LetBeforeExamples`. ([@Darhazer][])
|
||||
* Fix `RSpec/InstanceVariable` flagging instance variables inside dynamically defined class. ([@Darhazer][])
|
||||
* Add autocorrect support for `RSpec/ReturnFromStub` cop. ([@bquorning][])
|
||||
* Add `RSpec/ExampleWithoutDescription` cop. ([@Darhazer][])
|
||||
|
||||
## 1.21.0 (2017-12-13)
|
||||
|
||||
* Compatibility with RuboCop v0.52.0. ([@bquorning][])
|
||||
* Improve performance when user does not override default RSpec Pattern config. ([@walf443][])
|
||||
* Add `AggregateFailuresByDefault` configuration for `RSpec/MultipleExpectations` cop. ([@onk][])
|
||||
|
||||
## 1.20.1 (2017-11-15)
|
||||
|
||||
* Add "without" to list of default allowed prefixes for `RSpec/ContextWording`. ([@bquorning][])
|
||||
|
||||
## 1.20.0 (2017-11-09)
|
||||
|
||||
* Rename namespace `FactoryGirl` to `FactoryBot` following original library update. ([@walf443][])
|
||||
* Fix exception in `RSpec/ReturnFromStub` on empty block. ([@yevhene][])
|
||||
* Add `RSpec/ContextWording` cop. ([@pirj][], [@telmofcosta][])
|
||||
* Fix `RSpec/SubjectStub` cop matches receive message inside all matcher. ([@walf443][])
|
||||
|
||||
## 1.19.0 (2017-10-18)
|
||||
|
||||
Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
||||
|
||||
## 1.18.0 (2017-09-29)
|
||||
|
||||
* Fix false positive in `Capybara/FeatureMethods`. ([@Darhazer][])
|
||||
* Add `RSpec/Capybara/CurrentPathExpectation` cop for feature specs, disallowing setting expectations on `current_path`. ([@timrogers][])
|
||||
* Fix false positive in `RSpec/LetBeforeExamples` cop when example group contains single let. ([@Darhazer][])
|
||||
|
||||
## 1.17.1 (2017-09-20)
|
||||
|
||||
* Improved `RSpec/ReturnFromStub` to handle string interpolation, hashes and do..end blocks. ([@Darhazer][])
|
||||
* Fixed compatibility with JRuby. ([@zverok][])
|
||||
|
||||
## 1.17.0 (2017-09-14)
|
||||
|
||||
* Add `RSpec/Capybara` namespace including the first cop for feature specs: `Capybara/FeatureMethods`. ([@rspeicher][])
|
||||
* Update to RuboCop 0.50.0. ([@bquorning][])
|
||||
|
||||
## 1.16.0 (2017-09-06)
|
||||
|
||||
* Add `RSpec/FactoryGirl` namespace including the first cop for factories: `FactoryGirl/DynamicAttributeDefinedStatically`. ([@jonatas][])
|
||||
* Add disabled by default `RSpec/AlignLeftLetBrace`. ([@backus][])
|
||||
* Add disabled by default `RSpec/AlignRightLetBrace`. ([@backus][])
|
||||
* Add `RSpec/LetBeforeExamples` cop. ([@Darhazer][])
|
||||
* Add `RSpec/MultipleSubjects` cop. ([@backus][])
|
||||
* Add `RSpec/ReturnFromStub` cop. ([@Darhazer][])
|
||||
* Add `RSpec/VoidExpect` cop. ([@pocke][])
|
||||
* Add `RSpec/InvalidPredicateMatcher` cop. ([@pocke][])
|
||||
* Change HookArgument cop to detect when hook has a receiver. ([@pocke][])
|
||||
* Add `RSpec/PredicateMatcher` cop. ([@pocke][])
|
||||
* Add `RSpec/ExpectInHook` cop. ([@pocke][])
|
||||
* `RSpec/MultipleExpectations` now detects usage of expect_any_instance_of. ([@Darhazer][])
|
||||
* `RSpec/MultipleExpectations` now detects usage of is_expected. ([@bmorrall][])
|
||||
|
||||
## 1.15.1 (2017-04-30)
|
||||
|
||||
* Fix the handling of various edge cases in the `RSpec/ExampleWording` cop, including one that would cause autocorrect to crash. ([@dgollahon][])
|
||||
* Fix `RSpec/IteratedExpectation` crashing when there is an assignment in the iteration. ([@Darhazer][])
|
||||
* Fix false positive in `RSpec/SingleArgumentMessageChain` cop when the single argument is a hash. ([@Darhazer][])
|
||||
|
||||
## 1.15.0 (2017-03-24)
|
||||
|
||||
* Add `RSpec/DescribeSymbol` cop. ([@rspeicher][])
|
||||
* Fix error when `RSpec/OverwritingSetup` and `RSpec/ScatteredLet` analyzed empty example groups. ([@backus][])
|
||||
|
||||
## 1.14.0 (2017-03-24)
|
||||
|
||||
* Add `RSpec/OverwritingSetup` cop. ([@Darhazer][])
|
||||
* Add autocorrect support for `RSpec/LeadingSubject` cop. ([@Darhazer][])
|
||||
* Add `RSpec/ScatteredLet` cop. ([@Darhazer][])
|
||||
* Add `RSpec/IteratedExpectation` cop. ([@Darhazer][])
|
||||
* Add `RSpec/EmptyLineAfterSubject` cop. ([@Darhazer][])
|
||||
* Add `RSpec/EmptyLineAfterFinalLet` cop. ([@Darhazer][])
|
||||
|
||||
## 1.13.0 (2017-03-07)
|
||||
|
||||
* Add repeated 'it' detection to `RSpec/ExampleWording` cop. ([@dgollahon][])
|
||||
* Add [observed_nesting/max_nesting] info to `RSpec/NestedGroups` messages. ([@dgollahon][])
|
||||
* Add `RSpec/ItBehavesLike` cop. ([@dgollahon][])
|
||||
* Add `RSpec/SharedContext` cop. ([@Darhazer][])
|
||||
* `Rspec/MultipleExpectations`: Count aggregate_failures block as single expectation. ([@Darhazer][])
|
||||
* Fix `ExpectActual` cop flagging `rspec-rails` routing specs. ([@backus][])
|
||||
* Fix `FilePath` cop not registering offenses for files like `spec/blog/user.rb` when it should be `spec/blog/user_spec.rb`. ([@backus][])
|
||||
|
||||
## 1.12.0 (2017-02-21)
|
||||
|
||||
* Add `RSpec/InstanceSpy` cop. ([@Darhazer][])
|
||||
* Add `RSpec/BeforeAfterAll` for avoiding leaky global test setup. ([@cfabianski][])
|
||||
|
||||
## 1.11.0 (2017-02-16)
|
||||
|
||||
* Add `AroundBlock` cop. ([@Darhazer][])
|
||||
* Add `EnforcedStyle` configuration for `RSpec/DescribedClass` cop. ([@Darhazer][])
|
||||
* Fix false positive for `RSpec/RepeatedExample` cop. ([@redross][])
|
||||
|
||||
## 1.10.0 (2017-01-15)
|
||||
|
||||
* Fix false negative for `RSpec/MessageSpies` cop. ([@onk][])
|
||||
* Fix internal dependencies on RuboCop to be compatible with 0.47 release. ([@backus][])
|
||||
* Add autocorrect support for `SingleArgumentMessageChain` cop. ([@bquorning][])
|
||||
* Rename `NestedGroups`' configuration key from `MaxNesting` to `Max` in order to be consistent with other cop configuration. ([@backus][])
|
||||
* Add `RepeatedExample` cop for detecting repeated examples within example groups. ([@backus][])
|
||||
* Add `ScatteredSetup` cop for enforcing that only one `before`, `around`, and `after` hook are used per example group scope. ([@backus][])
|
||||
* Add `ExpectOutput` cop for recommending `expect { ... }.to output(...).to_stdout`. ([@backus][])
|
||||
|
||||
## 1.9.1 (2017-01-02)
|
||||
|
||||
* Fix unintentional regression change in `NestedGroups` reported in #270. ([@backus][])
|
||||
* Change `MaxNesting` for `NestedGroups` from 2 to 3. ([@backus][])
|
||||
|
||||
## 1.9.0 (2016-12-29)
|
||||
|
||||
* Add `MessageSpies` cop for enforcing consistent style of either `expect(...).to have_received` or `expect(...).to receive`, intended as a replacement for the `MessageExpectation` cop. ([@bquorning][])
|
||||
* Fix `DescribeClass` to not flag `describe` at the top of a block of shared examples. ([@clupprich][])
|
||||
* Add `SingleArgumentMessageChain` cop for recommending use of `receive` instead of `receive_message_chain` where possible. ([@bquorning][])
|
||||
* Add `RepeatedDescription` cop for detecting repeated example descriptions within example groups. ([@backus][])
|
||||
|
||||
## 1.8.0 (2016-10-27)
|
||||
|
||||
* Optionally ignore method names in the `describe` argument when running the `FilePath` cop. ([@bquorning][])
|
||||
* Fix regression in how `FilePath` converts alphanumeric class names into paths. ([@bquorning][])
|
||||
* Add `ImplicitExpect` cop for enforcing `should` vs. `is_expected.to`. ([@backus][])
|
||||
* Disable `MessageExpectation` cop in the default configuration. ([@bquorning][])
|
||||
|
||||
## 1.7.0 (2016-08-24)
|
||||
|
||||
* Add support for checking all example groups with `ExampleLength`. ([@backus][])
|
||||
* Add support for checking shared example groups for `DescribedClass`. ([@backus][])
|
||||
* Add support for checking `its` from [rspec-its](https://github.com/rspec/rspec-its). ([@backus][])
|
||||
* Add `EmptyExampleGroup` cop for detecting `describe`s and `context`s without any tests inside. ([@backus][])
|
||||
* Add `CustomIncludeMethods` configuration option for `EmptyExampleGroup`. ([@backus][])
|
||||
* Add `NestedGroups` cop for detecting excessive example group nesting. ([@backus][])
|
||||
* Add `MaxNesting` configuration option for `NestedGroups` cop. ([@backus][])
|
||||
* Add `ExpectActual` cop for detecting literal values within `expect(...)`. ([@backus][])
|
||||
* Add `MultipleExpectations` cop for detecting multiple `expect(...)` calls within one example. ([@backus][])
|
||||
* Add `Max` configuration option for `MultipleExpectations`. ([@backus][])
|
||||
* Add `SubjectStub` cop for testing stubbed test subjects. ([@backus][])
|
||||
* Add `LetSetup` cop for detecting cases where `let!` is used for test setup. ([@backus][])
|
||||
* Change all cops to only inspect files with names following rspec convention (`*/spec/*` and/or `_spec.rb`). ([@backus][])
|
||||
* Add `AllCops/RSpec` configuration option for specifying custom spec file patterns. ([@backus][])
|
||||
* Add `AssignmentOnly` configuration option for `RSpec/InstanceVariable` cop. ([@backus][])
|
||||
* Add `BeEql` cop which looks for expectations that can use `be(...)` instead of `eql(...)`. ([@backus][])
|
||||
* Add autocorrect support for `BeEql` cop. ([@backus][])
|
||||
* Add `MessageExpectation` cop for enforcing consistent style of either `expect(...).to receive` or `allow(...).to receive`. ([@backus][])
|
||||
* Add `MessageChain` cop. ([@bquorning][])
|
||||
|
||||
## 1.6.0 (2016-08-03)
|
||||
|
||||
* Add `SkipBlocks` option for `DescribedClass` cop. ([@backus][])
|
||||
|
||||
## 1.5.3 (2016-08-02)
|
||||
|
||||
* Add `RSpec/NamedSubject` cop. ([@backus][])
|
||||
|
||||
## 1.5.2 (2016-08-01)
|
||||
|
||||
* Drop support for ruby `2.0.0` and `2.1.0`. ([@backus][])
|
||||
* Internal refactorings and improved test coverage. ([@backus][])
|
||||
|
||||
## 1.5.1 (2016-07-20)
|
||||
|
||||
* Fix `unrecognized parameter RSpec/VerifiedDoubles:IgnoreSymbolicNames` warning. ([@jeffreyc][])
|
||||
* Update to rubocop 0.41.2. ([@backus][])
|
||||
|
||||
## 1.5.0 (2016-05-17)
|
||||
|
||||
* Expand `VerifiedDoubles` cop to check for `spy` as well as `double`. ([@andyw8][])
|
||||
* Enable `VerifiedDoubles` cop by default. ([@andyw8][])
|
||||
* Add `IgnoreSymbolicNames` option for `VerifiedDoubles` cop. ([@andyw8][])
|
||||
* Add `RSpec::ExampleLength` cop. ([@andyw8][])
|
||||
* Handle alphanumeric class names in `FilePath` cop. ([@andyw8][])
|
||||
* Skip `DescribeClass` cop for view specs. ([@andyw8][])
|
||||
* Skip `FilePath` cop for Rails routing specs. ([@andyw8][])
|
||||
* Add cop to check for focused specs. ([@renanborgescampos][], [@jaredmoody][])
|
||||
* Clean-up `RSpec::NotToNot` to use same configuration semantics as other Rubocop cops, add autocorrect support for `RSpec::NotToNot`. ([@baberthal][])
|
||||
* Update to rubocop 0.40.0. ([@nijikon][])
|
||||
|
||||
## 1.4.1 (2016-04-03)
|
||||
|
||||
* Ignore routing specs for DescribeClass cop. ([@nijikon][])
|
||||
* Move rubocop dependency to runtime. ([@nijikon][])
|
||||
* Update to rubocop 0.39.0. ([@nijikon][])
|
||||
|
||||
## 1.4.0 (2016-02-15)
|
||||
|
||||
* Update to rubocop 0.37.2. ([@nijikon][])
|
||||
* Update ruby versions we test against. ([@nijikon][])
|
||||
* Add `RSpec::NotToNot` cop. ([@miguelfteixeira][])
|
||||
* Add `Rspec/AnyInstance` cop. ([@mlarraz][])
|
||||
|
||||
## 1.3.1
|
||||
|
||||
* Fix auto correction issue - syntax had changed in RuboCop v0.31. ([@bquorning][])
|
||||
* Add RuboCop clone to vendor folder - see #39 for details. ([@bquorning][])
|
||||
|
||||
## 1.3.0
|
||||
|
||||
* Ignore non string arguments for FilePathCop - thanks to @deivid-rodriguez. ([@geniou][])
|
||||
* Skip DescribeMethod cop for tagged specs. ([@deivid-rodriguez][])
|
||||
* Skip DescribeClass cop for feature/request specs. ([@deivid-rodriguez][])
|
||||
|
||||
## 1.2.2
|
||||
|
||||
* Make `RSpec::ExampleWording` case insensitive. ([@geniou][])
|
||||
|
||||
## 1.2.1
|
||||
|
||||
* Add `RSpec::VerifiedDoubles` cop. ([@andyw8][])
|
||||
|
||||
## 1.2.0
|
||||
|
||||
* Drop support of ruby `1.9.2`. ([@geniou][])
|
||||
* Update to RuboCop `~> 0.24`. ([@geniou][])
|
||||
* Add `autocorrect` to `RSpec::ExampleWording`. This experimental - use with care and check the changes. ([@geniou][])
|
||||
* Fix config loader debug output. ([@geniou][])
|
||||
* Rename `FileName` cop to `FilePath` as a workaround - see [#19](https://github.com/nevir/rubocop-rspec/issues/19). ([@geniou][])
|
||||
|
||||
## 1.1.0
|
||||
|
||||
* Add `autocorrect` to `RSpec::DescribedClass` cop. ([@geniou][])
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* Add `config` folder to gemspec. ([@pstengel][])
|
||||
|
||||
## 1.0.rc3
|
||||
|
||||
* Update to RuboCop `>= 0.23`. ([@geniou][])
|
||||
* Add configuration option for `CustomTransformation` to `FileName` cop. ([@geniou][])
|
||||
|
||||
## 1.0.rc2
|
||||
|
||||
* Gem is no longer 20MB (sorry!). ([@nevir][])
|
||||
* `RspecFileName` cop allows for method specs to organized into directories by class and type. ([@nevir][])
|
||||
|
||||
## 1.0.rc1
|
||||
|
||||
* Update code to work with rubocop `>= 0.19`. ([@geniou][])
|
||||
* Split `UnitSpecNaming` cop into `RSpecDescribeClass`, `RSpecDescribeMethod` and `RSpecFileName` and enabled them all by default. ([@geniou][])
|
||||
* Add `RSpecExampleWording` cop to prevent to use of should at the beginning of the spec description. ([@geniou][])
|
||||
* Fix `RSpecFileName` cop for non-class specs. ([@geniou][])
|
||||
* Adapt `RSpecFileName` cop to commen naming convention and skip spec with multiple top level describes. ([@geniou][])
|
||||
* Add `RSpecMultipleDescribes` cop to check for multiple top level describes. ([@geniou][])
|
||||
* Add `RSpecDescribedClass` to promote the use of `described_class`. ([@geniou][])
|
||||
* Add `RSpecInstanceVariable` cop to check for the usage of instance variables. ([@geniou][])
|
||||
|
||||
<!-- Contributors -->
|
||||
|
||||
[@andyw8]: https://github.com/andyw8
|
||||
[@backus]: https://github.com/backus
|
||||
[@bquorning]: https://github.com/bquorning
|
||||
[@deivid-rodriguez]: https://github.com/deivid-rodriguez
|
||||
[@geniou]: https://github.com/geniou
|
||||
[@jaredbeck]: https://github.com/jaredbeck
|
||||
[@jawshooah]: https://github.com/jawshooah
|
||||
[@nevir]: https://github.com/nevir
|
||||
[@nijikon]: https://github.com/nijikon
|
||||
[@pstengel]: https://github.com/pstengel
|
||||
[@miguelfteixeira]: https://github.com/miguelfteixeira
|
||||
[@mlarraz]: https://github.com/mlarraz
|
||||
[@renanborgescampos]: https://github.com/renanborgescampos
|
||||
[@jaredmoody]: https://github.com/jaredmoody
|
||||
[@baberthal]: https://github.com/baberthal
|
||||
[@jeffreyc]: https://github.com/jeffreyc
|
||||
[@clupprich]: https://github.com/clupprich
|
||||
[@onk]: https://github.com/onk
|
||||
[@Darhazer]: https://github.com/Darhazer
|
||||
[@redross]: https://github.com/redross
|
||||
[@cfabianski]: https://github.com/cfabianski
|
||||
[@dgollahon]: https://github.com/dgollahon
|
||||
[@rspeicher]: https://github.com/rspeicher
|
||||
[@jonatas]: https://github.com/jonatas
|
||||
[@pocke]: https://github.com/pocke
|
||||
[@bmorrall]: https:/github.com/bmorrall
|
||||
[@zverok]: https:/github.com/zverok
|
||||
[@timrogers]: https://github.com/timrogers
|
||||
[@yevhene]: https://github.com/yevhene
|
||||
[@walf443]: https://github.com/walf443
|
||||
[@pirj]: https://github.com/pirj
|
||||
[@telmofcosta]: https://github.com/telmofcosta
|
||||
[@EliseFitz15]: https://github.com/EliseFitz15
|
||||
[@anthony-robin]: https://github.com/anthony-robin
|
||||
[@jojos003]: https://github.com/jojos003
|
||||
[@abrom]: https://github.com/abrom
|
||||
[@patrickomatic]: https://github.com/patrickomatic
|
||||
[@tdeo]: https://github.com/tdeo
|
||||
[@composerinteralia]: https://github.com/composerinteralia
|
||||
[@seanpdoyle]: https://github.com/seanpdoyle
|
||||
[@vzvu3k6k]: https://github.com/vzvu3k6k
|
||||
[@BrentWheeldon]: https://github.com/BrentWheeldon
|
||||
[@daveworth]: https://github.com/daveworth
|
||||
@ -1,9 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gemspec
|
||||
|
||||
local_gemfile = 'Gemfile.local'
|
||||
|
||||
if File.exist?(local_gemfile)
|
||||
eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
|
||||
end
|
||||
@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright (c) 2014 Ian MacLeod <ian@nevir.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,146 +0,0 @@
|
||||
# RuboCop RSpec
|
||||
|
||||
[](https://gitter.im/rubocop-rspec/Lobby)
|
||||
[](https://rubygems.org/gems/rubocop-rspec)
|
||||
[](https://circleci.com/gh/rubocop-hq/rubocop-rspec)
|
||||
[](https://codeclimate.com/github/rubocop-hq/rubocop-rspec/test_coverage)
|
||||
[](https://codeclimate.com/github/rubocop-hq/rubocop-rspec/maintainability)
|
||||
|
||||
RSpec-specific analysis for your projects, as an extension to
|
||||
[RuboCop](https://github.com/rubocop-hq/rubocop).
|
||||
|
||||
## Installation
|
||||
|
||||
Just install the `rubocop-rspec` gem
|
||||
|
||||
```bash
|
||||
gem install rubocop-rspec
|
||||
```
|
||||
|
||||
or if you use bundler put this in your `Gemfile`
|
||||
|
||||
```
|
||||
gem 'rubocop-rspec'
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
You need to tell RuboCop to load the RSpec extension. There are three
|
||||
ways to do this:
|
||||
|
||||
### RuboCop configuration file
|
||||
|
||||
Put this into your `.rubocop.yml`.
|
||||
|
||||
```
|
||||
require: rubocop-rspec
|
||||
```
|
||||
|
||||
Now you can run `rubocop` and it will automatically load the RuboCop RSpec
|
||||
cops together with the standard cops.
|
||||
|
||||
### Command line
|
||||
|
||||
```bash
|
||||
rubocop --require rubocop-rspec
|
||||
```
|
||||
|
||||
### Rake task
|
||||
|
||||
```ruby
|
||||
RuboCop::RakeTask.new do |task|
|
||||
task.requires << 'rubocop-rspec'
|
||||
end
|
||||
```
|
||||
|
||||
### Code Climate
|
||||
|
||||
rubocop-rspec is available on Code Climate as part of the rubocop engine. [Learn More](https://codeclimate.com/changelog/55a433bbe30ba00852000fac).
|
||||
|
||||
## Documentation
|
||||
|
||||
You can read more about RuboCop-RSpec in its [official manual](http://rubocop-rspec.readthedocs.io).
|
||||
|
||||
## Inspecting files that don't end with `_spec.rb`
|
||||
|
||||
By default, `rubocop-rspec` only inspects code within paths ending in `_spec.rb` or including `spec/`. You can override this setting in your config file by specifying one or more patterns:
|
||||
|
||||
```yaml
|
||||
# Inspect all files
|
||||
AllCops:
|
||||
RSpec:
|
||||
Patterns:
|
||||
- '.+'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Inspect only files ending with `_test.rb`
|
||||
AllCops:
|
||||
RSpec:
|
||||
Patterns:
|
||||
- '_test.rb$'
|
||||
```
|
||||
|
||||
## The Cops
|
||||
|
||||
All cops are located under
|
||||
[`lib/rubocop/cop/rspec`](lib/rubocop/cop/rspec), and contain
|
||||
examples/documentation.
|
||||
|
||||
In your `.rubocop.yml`, you may treat the RSpec cops just like any other
|
||||
cop. For example:
|
||||
|
||||
```yaml
|
||||
RSpec/FilePath:
|
||||
Exclude:
|
||||
- spec/my_poorly_named_spec_file.rb
|
||||
```
|
||||
|
||||
## Non-goals of RuboCop RSpec
|
||||
|
||||
### Enforcing `should` vs. `expect` syntax
|
||||
|
||||
Enforcing
|
||||
|
||||
```ruby
|
||||
expect(calculator.compute(line_item)).to eq(5)
|
||||
```
|
||||
|
||||
over
|
||||
|
||||
```ruby
|
||||
calculator.compute(line_item).should == 5
|
||||
```
|
||||
|
||||
is a feature of RSpec itself – you can read about it in the [RSpec Documentation](https://relishapp.com/rspec/rspec-expectations/docs/syntax-configuration#disable-should-syntax)
|
||||
|
||||
### Enforcing an explicit RSpec receiver for top-level methods (disabling monkey patching)
|
||||
|
||||
Enforcing
|
||||
|
||||
```ruby
|
||||
Rspec.describe MyClass do
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
over
|
||||
|
||||
```ruby
|
||||
describe MyClass do
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
can be achieved using RSpec's `disable_monkey_patching!` method, which you can read more about in the [RSpec Documentation](https://relishapp.com/rspec/rspec-core/v/3-7/docs/configuration/zero-monkey-patching-mode#monkey-patched-methods-are-undefined-with-%60disable-monkey-patching!%60). This will also prevent `should` from being defined on every object in your system.
|
||||
|
||||
Before disabling `should` you will need all your specs to use the `expect` syntax. You can use [Transpec](http://yujinakayama.me/transpec/), which will do the conversion for you.
|
||||
|
||||
## Contributing
|
||||
|
||||
Checkout the [contribution guidelines](.github/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
`rubocop-rspec` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
|
||||
the full text.
|
||||
@ -1,85 +0,0 @@
|
||||
require 'open3'
|
||||
|
||||
require 'bundler'
|
||||
require 'bundler/gem_tasks'
|
||||
|
||||
begin
|
||||
Bundler.setup(:default, :development)
|
||||
rescue Bundler::BundlerError => e
|
||||
warn e.message
|
||||
warn 'Run `bundle install` to install missing gems'
|
||||
exit e.status_code
|
||||
end
|
||||
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
Dir['tasks/**/*.rake'].each { |t| load t }
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec) do |spec|
|
||||
spec.pattern = FileList['spec/**/*_spec.rb']
|
||||
end
|
||||
|
||||
desc 'Run RSpec with code coverage'
|
||||
task :coverage do
|
||||
ENV['COVERAGE'] = 'true'
|
||||
Rake::Task['spec'].execute
|
||||
end
|
||||
|
||||
desc 'Run RuboCop over this gem'
|
||||
task :internal_investigation do
|
||||
sh('bundle exec rubocop --require rubocop-rspec')
|
||||
end
|
||||
|
||||
desc 'Build config/default.yml'
|
||||
task :build_config do
|
||||
sh('bin/build_config')
|
||||
end
|
||||
|
||||
desc 'Confirm config/default.yml is up to date'
|
||||
task confirm_config: :build_config do
|
||||
_, stdout, _, process =
|
||||
Open3.popen3('git diff --exit-code config/default.yml')
|
||||
|
||||
unless process.value.success?
|
||||
raise "default.yml is out of sync:\n\n#{stdout.read}\nRun bin/build_config"
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Confirm documentation is up to date'
|
||||
task confirm_documentation: :generate_cops_documentation do
|
||||
_, _, _, process =
|
||||
Open3.popen3('git diff --exit-code manual/')
|
||||
|
||||
unless process.value.success?
|
||||
raise 'Please run `rake generate_cops_documentation` ' \
|
||||
'and add manual/ to the commit.'
|
||||
end
|
||||
end
|
||||
|
||||
task default: %i[build_config coverage
|
||||
internal_investigation
|
||||
confirm_config
|
||||
documentation_syntax_check
|
||||
confirm_documentation]
|
||||
|
||||
desc 'Generate a new cop template'
|
||||
task :new_cop, [:cop] do |_task, args|
|
||||
require 'rubocop'
|
||||
|
||||
cop_name = args.fetch(:cop) do
|
||||
warn 'usage: bundle exec rake new_cop[Department/Name]'
|
||||
exit!
|
||||
end
|
||||
|
||||
github_user = `git config github.user`.chop
|
||||
github_user = 'your_id' if github_user.empty?
|
||||
|
||||
generator = RuboCop::Cop::Generator.new(cop_name, github_user)
|
||||
|
||||
generator.write_source
|
||||
generator.write_spec
|
||||
generator.inject_require(root_file_path: 'lib/rubocop/cop/rspec_cops.rb')
|
||||
generator.inject_config(config_file_path: 'config/default.yml')
|
||||
|
||||
puts generator.todo
|
||||
end
|
||||
@ -1,42 +0,0 @@
|
||||
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
|
||||
@ -1,47 +0,0 @@
|
||||
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
||||
require 'rubocop/rspec/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'rubocop-rspec'
|
||||
spec.summary = 'Code style checking for RSpec files'
|
||||
spec.description = <<-DESCRIPTION
|
||||
Code style checking for RSpec files.
|
||||
A plugin for the RuboCop code style enforcing & linting tool.
|
||||
DESCRIPTION
|
||||
spec.homepage = 'https://github.com/rubocop-hq/rubocop-rspec'
|
||||
spec.authors = ['John Backus', 'Ian MacLeod', 'Nils Gemeinhardt']
|
||||
spec.email = [
|
||||
'johncbackus@gmail.com',
|
||||
'ian@nevir.net',
|
||||
'git@nilsgemeinhardt.de'
|
||||
]
|
||||
spec.licenses = ['MIT']
|
||||
|
||||
spec.version = RuboCop::RSpec::Version::STRING
|
||||
spec.platform = Gem::Platform::RUBY
|
||||
spec.required_ruby_version = '>= 2.2.0'
|
||||
|
||||
spec.require_paths = ['lib']
|
||||
spec.files = Dir[
|
||||
'{config,lib,spec}/**/*',
|
||||
'*.md',
|
||||
'*.gemspec',
|
||||
'Gemfile',
|
||||
'Rakefile'
|
||||
]
|
||||
spec.test_files = spec.files.grep(%r{^spec/})
|
||||
spec.extra_rdoc_files = ['MIT-LICENSE.md', 'README.md']
|
||||
|
||||
spec.metadata = {
|
||||
'changelog_uri' => 'https://github.com/rubocop-hq/rubocop-rspec/blob/master/CHANGELOG.md',
|
||||
'documentation_uri' => 'https://rubocop-rspec.readthedocs.io/'
|
||||
}
|
||||
|
||||
spec.add_runtime_dependency 'rubocop', '>= 0.60.0'
|
||||
|
||||
spec.add_development_dependency 'rack'
|
||||
spec.add_development_dependency 'rake'
|
||||
spec.add_development_dependency 'rspec', '>= 3.4'
|
||||
spec.add_development_dependency 'simplecov'
|
||||
spec.add_development_dependency 'yard'
|
||||
end
|
||||
@ -1,74 +0,0 @@
|
||||
RSpec.describe 'CHANGELOG.md' do
|
||||
subject(:changelog) { SpecHelper::ROOT.join('CHANGELOG.md').read }
|
||||
|
||||
it 'has link definitions for all implicit links' do
|
||||
implicit_link_names = changelog.scan(/\[([^\]]+)\]\[\]/).flatten.uniq
|
||||
implicit_link_names.each do |name|
|
||||
expect(changelog).to include("[#{name}]: http")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'entry' do
|
||||
subject(:entries) { lines.grep(/^\*/).map(&:chomp) }
|
||||
|
||||
let(:lines) { changelog.each_line }
|
||||
|
||||
it 'has a whitespace between the * and the body' do
|
||||
expect(entries).to all(match(/^\* \S/))
|
||||
end
|
||||
|
||||
it 'has a link to the contributors at the end' do
|
||||
expect(entries).to all(match(/\(\[@\S+\]\[\](?:, \[@\S+\]\[\])*\)$/))
|
||||
end
|
||||
|
||||
describe 'link to related issue on github' do
|
||||
let(:issues) do
|
||||
entries.map do |entry|
|
||||
entry.match(/\[(?<number>[#\d]+)\]\((?<url>[^\)]+)\)/)
|
||||
end.compact
|
||||
end
|
||||
|
||||
it 'has an issue number prefixed with #' do
|
||||
issues.each do |issue|
|
||||
expect(issue[:number]).to match(/^#\d+$/)
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a valid URL' do
|
||||
issues.each do |issue|
|
||||
number = issue[:number].gsub(/\D/, '')
|
||||
pattern = %r{^https://github\.com/.+/.+/(?:issues|pull)/#{number}$} # rubocop:disable LineLength
|
||||
expect(issue[:url]).to match(pattern)
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a colon and a whitespace at the end' do
|
||||
entries_including_issue_link = entries.select do |entry|
|
||||
entry.match(/^\*\s*\[/)
|
||||
end
|
||||
|
||||
expect(entries_including_issue_link).to all(include('): '))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'body' do
|
||||
let(:bodies) do
|
||||
entries.map do |entry|
|
||||
entry
|
||||
.sub(/^\*\s*(?:\[.+?\):\s*)?/, '')
|
||||
.sub(/\s*\([^\)]+\)$/, '')
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not start with a lower case' do
|
||||
bodies.each do |body|
|
||||
expect(body).not_to match(/^[a-z]/)
|
||||
end
|
||||
end
|
||||
|
||||
it 'ends with a punctuation' do
|
||||
expect(bodies).to all(match(/[\.\!]$/))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,74 +0,0 @@
|
||||
RSpec.describe 'config/default.yml' do
|
||||
subject(:default_config) do
|
||||
RuboCop::ConfigLoader.load_file('config/default.yml')
|
||||
end
|
||||
|
||||
let(:namespaces) do
|
||||
{
|
||||
'rspec' => 'RSpec',
|
||||
'capybara' => 'Capybara',
|
||||
'factory_bot' => 'FactoryBot',
|
||||
'rails' => 'Rails'
|
||||
}
|
||||
end
|
||||
|
||||
let(:cop_names) do
|
||||
glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec',
|
||||
'{,capybara,factory_bot,rails}', '*.rb')
|
||||
cop_names =
|
||||
Pathname.glob(glob).map do |file|
|
||||
file_name = file.basename('.rb').to_s
|
||||
cop_name = file_name.gsub(/(^|_)(.)/) { Regexp.last_match(2).upcase }
|
||||
namespace = namespaces[file.dirname.basename.to_s]
|
||||
"#{namespace}/#{cop_name}"
|
||||
end
|
||||
|
||||
cop_names - %w[RSpec/Cop]
|
||||
end
|
||||
|
||||
let(:config_keys) do
|
||||
cop_names + %w[AllCops]
|
||||
end
|
||||
|
||||
def cop_configuration(config_key)
|
||||
cop_names.map do |cop_name|
|
||||
cop_config = default_config[cop_name]
|
||||
|
||||
cop_config.fetch(config_key) do
|
||||
raise "Expected #{cop_name} to have #{config_key} configuration key"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has configuration for all cops' do
|
||||
expect(default_config.keys).to match_array(config_keys)
|
||||
end
|
||||
|
||||
it 'sorts configuration keys alphabetically' do
|
||||
namespaces.each do |_path, prefix|
|
||||
expected = config_keys.select { |key| key.start_with?(prefix) }.sort
|
||||
actual = default_config.keys.select { |key| key.start_with?(prefix) }
|
||||
actual.each_with_index do |key, idx|
|
||||
expect(key).to eq expected[idx]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has descriptions for all cops' do
|
||||
expect(cop_configuration('Description')).to all(be_a(String))
|
||||
end
|
||||
|
||||
it 'does not have newlines in cop descriptions' do
|
||||
cop_configuration('Description').each do |value|
|
||||
expect(value).not_to include("\n")
|
||||
end
|
||||
end
|
||||
|
||||
it 'ends every description with a period' do
|
||||
expect(cop_configuration('Description')).to all(end_with('.'))
|
||||
end
|
||||
|
||||
it 'includes Enabled: true for every cop' do
|
||||
expect(cop_configuration('Enabled')).to all(be(true).or(be(false)))
|
||||
end
|
||||
end
|
||||
@ -1,18 +0,0 @@
|
||||
RSpec.describe 'Project requires' do
|
||||
it 'alphabetizes cop requires' do
|
||||
source = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec_cops.rb')
|
||||
captures = source.read.scan(%r{^(require_relative 'rspec/(.*?/)?(.*?)')$})
|
||||
|
||||
require_statements = captures.map(&:first)
|
||||
sorted_require_statements =
|
||||
captures.sort_by do |_require_statement, cop_category, name|
|
||||
[cop_category || 'rspec', name]
|
||||
end.map(&:first)
|
||||
|
||||
aggregate_failures do
|
||||
# Sanity check that we actually discovered require statements.
|
||||
expect(captures).not_to be_empty
|
||||
expect(require_statements).to eql(sorted_require_statements)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,66 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::AlignLeftLetBrace do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers offense for unaligned braces' do
|
||||
expect_offense(<<-RUBY)
|
||||
let(:foo) { bar }
|
||||
^ Align left let brace
|
||||
let(:hi) { baz }
|
||||
^ Align left let brace
|
||||
let(:blahblah) { baz }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:blahblah) { baz }
|
||||
let(:blah) { thing }
|
||||
^ Align left let brace
|
||||
let(:a) { thing }
|
||||
^ Align left let brace
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'works with empty file' do
|
||||
expect_no_offenses('')
|
||||
end
|
||||
|
||||
offensive_source = <<-RUBY
|
||||
let(:foo) { bar }
|
||||
let(:hi) { baz }
|
||||
let(:blahblah) { baz }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:long_name) { thing }
|
||||
let(:blah) { thing }
|
||||
let(:a) { thing }
|
||||
end
|
||||
RUBY
|
||||
|
||||
corrected_source = <<-RUBY
|
||||
let(:foo) { bar }
|
||||
let(:hi) { baz }
|
||||
let(:blahblah) { baz }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:long_name) { thing }
|
||||
let(:blah) { thing }
|
||||
let(:a) { thing }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', offensive_source, corrected_source
|
||||
end
|
||||
@ -1,66 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::AlignRightLetBrace do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers offense for unaligned braces' do
|
||||
expect_offense(<<-RUBY)
|
||||
let(:foo) { a }
|
||||
^ Align right let brace
|
||||
let(:hi) { ab }
|
||||
^ Align right let brace
|
||||
let(:blahblah) { abcd }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:blahblah) { a }
|
||||
^ Align right let brace
|
||||
let(:blah) { bc }
|
||||
^ Align right let brace
|
||||
let(:a) { abc }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'works with empty file' do
|
||||
expect_no_offenses('')
|
||||
end
|
||||
|
||||
offensive_source = <<-RUBY
|
||||
let(:foo) { a }
|
||||
let(:hi) { ab }
|
||||
let(:blahblah) { abcd }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:blahblah) { a }
|
||||
let(:blah) { bc }
|
||||
let(:a) { abc }
|
||||
end
|
||||
RUBY
|
||||
|
||||
corrected_source = <<-RUBY
|
||||
let(:foo) { a }
|
||||
let(:hi) { ab }
|
||||
let(:blahblah) { abcd }
|
||||
|
||||
let(:thing) { ignore_this }
|
||||
let(:other) {
|
||||
ignore_this_too
|
||||
}
|
||||
|
||||
describe 'blah' do
|
||||
let(:blahblah) { a }
|
||||
let(:blah) { bc }
|
||||
let(:a) { abc }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', offensive_source, corrected_source
|
||||
end
|
||||
@ -1,30 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::AnyInstance do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'finds `allow_any_instance_of` instead of an instance double' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
allow_any_instance_of(Object).to receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `allow_any_instance_of`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds `expect_any_instance_of` instead of an instance double' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
expect_any_instance_of(Object).to receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `expect_any_instance_of`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds old `any_instance` syntax instead of an instance double' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
Object.any_instance.should_receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `any_instance`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,119 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::AroundBlock do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'when no value is yielded' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do
|
||||
^^^^^^^^^ Test object should be passed to around block.
|
||||
do_something
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the hook is scoped with a symbol' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
around(:each) do
|
||||
^^^^^^^^^^^^^^^^ Test object should be passed to around block.
|
||||
do_something
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the yielded value is unused' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do |test|
|
||||
^^^^ You should call `test.call` or `test.run`.
|
||||
do_something
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when two values are yielded and the first is unused' do
|
||||
it 'registers an offense for the first argument' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do |test, unused|
|
||||
^^^^ You should call `test.call` or `test.run`.
|
||||
unused.run
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the yielded value is referenced but not used' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do |test|
|
||||
^^^^ You should call `test.call` or `test.run`.
|
||||
test
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a method other than #run or #call is called' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do |test|
|
||||
^^^^ You should call `test.call` or `test.run`.
|
||||
test.inspect
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when #run is called' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
around do |test|
|
||||
test.run
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when #call is called' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
around do |test|
|
||||
test.call
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when used as a block arg' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
around do |test|
|
||||
1.times(&test)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passed to another method' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
around do |test|
|
||||
something_that_might_run_test(test, another_arg)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when yielded to another block' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
around do |test|
|
||||
foo { yield(some_arg, test) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,60 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::BeEql do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for `eql` when argument is a boolean' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to eql(true) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
it { expect(foo).to eql(false) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for `eql` when argument is an integer' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to eql(0) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
it { expect(foo).to eql(123) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for `eql` when argument is a float' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to eql(1.0) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
it { expect(foo).to eql(1.23) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for `eql` when argument is a symbol' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to eql(:foo) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for `eql` when argument is nil' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to eql(nil) }
|
||||
^^^ Prefer `be` over `eql`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `eql` when argument is a string' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(foo).to eql('foo') }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `eql` when expectation is negated' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(foo).to_not eql(1) }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { expect(foo).to eql(1) }',
|
||||
'it { expect(foo).to be(1) }'
|
||||
end
|
||||
@ -1,33 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::Be do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for `be` without an argument' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).to be }
|
||||
^^ Don't use `be` without an argument.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for not_to be' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(foo).not_to be }
|
||||
^^ Don't use `be` without an argument.
|
||||
it { expect(foo).to_not be }
|
||||
^^ Don't use `be` without an argument.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `be` with an argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(foo).to be(1) }
|
||||
it { expect(foo).not_to be(0) }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows specific `be_` matchers' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(foo).to be_truthy }
|
||||
it { expect(foo).not_to be_falsy }
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,50 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::BeforeAfterAll do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
def message(hook)
|
||||
"Beware of using `#{hook}` 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}` are not automatically rolled "\
|
||||
'back.'
|
||||
end
|
||||
|
||||
context 'when using before all' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:all) { do_something }
|
||||
^^^^^^^^^^^^ #{message('before(:all)')}
|
||||
before(:context) { do_something }
|
||||
^^^^^^^^^^^^^^^^ #{message('before(:context)')}
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using after all' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
after(:all) { do_something }
|
||||
^^^^^^^^^^^ #{message('after(:all)')}
|
||||
after(:context) { do_something }
|
||||
^^^^^^^^^^^^^^^ #{message('after(:context)')}
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using before each' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:each) { do_something }
|
||||
before(:example) { do_something }
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using after each' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
after(:each) { do_something }
|
||||
after(:example) { do_something }
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,29 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::Capybara::CurrentPathExpectation do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags violations for `expect(current_path)`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(current_path).to eq("/callback")
|
||||
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `expect(page.current_path)`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(page.current_path).to eq("/callback")
|
||||
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "doesn't flag a violation for other expectations" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(current_user).to eq(user)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "doesn't flag a violation for other references to `current_path`" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
current_path = WalkingRoute.last.path
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,128 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::Capybara::FeatureMethods, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) { { 'EnabledMethods' => [] } }
|
||||
|
||||
it 'flags violations for `background`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'some feature' do
|
||||
background do; end
|
||||
^^^^^^^^^^ Use `before` instead of `background`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `scenario`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe 'some feature' do
|
||||
scenario 'Foo' do; end
|
||||
^^^^^^^^ Use `it` instead of `scenario`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `xscenario`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'Foo' do
|
||||
RSpec.xscenario 'Baz' do; end
|
||||
^^^^^^^^^ Use `xit` instead of `xscenario`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `given`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe 'Foo' do
|
||||
given(:foo) { :foo }
|
||||
^^^^^ Use `let` instead of `given`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `given!`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'Foo' do
|
||||
given!(:foo) { :foo }
|
||||
^^^^^^ Use `let!` instead of `given!`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `feature`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.feature 'Foo' do; end
|
||||
^^^^^^^ Use `describe` instead of `feature`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores variables inside examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'is valid code' do
|
||||
given(feature)
|
||||
assign(background)
|
||||
run scenario
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores feature calls outside spec' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :company do
|
||||
feature { "a company" }
|
||||
background { Faker::Lorem.sentence }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows includes before the spec' do
|
||||
expect_offense(<<-RUBY)
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.feature 'Foo' do; end
|
||||
^^^^^^^ Use `describe` instead of `feature`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'with configured `EnabledMethods`' do
|
||||
let(:cop_config) { { 'EnabledMethods' => %w[feature] } }
|
||||
|
||||
it 'ignores usage of the enabled method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.feature 'feature is enabled' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags other methods' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.feature 'feature is enabled' do
|
||||
given(:foo) { :foo }
|
||||
^^^^^ Use `let` instead of `given`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'autocorrect_spec' do |original, corrected|
|
||||
original = <<-RUBY
|
||||
describe Foo do
|
||||
#{original}
|
||||
end
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
describe Foo do
|
||||
#{corrected}
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
|
||||
include_examples 'autocorrect_spec', 'background { }', 'before { }'
|
||||
include_examples 'autocorrect_spec', 'scenario { }', 'it { }'
|
||||
include_examples 'autocorrect_spec', 'xscenario { }', 'xit { }'
|
||||
include_examples 'autocorrect_spec', 'given(:foo) { }', 'let(:foo) { }'
|
||||
include_examples 'autocorrect_spec', 'given!(:foo) { }', 'let!(:foo) { }'
|
||||
include_examples 'autocorrect_spec', 'RSpec.feature { }', 'RSpec.describe { }'
|
||||
end
|
||||
@ -1,62 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ContextWording, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) { { 'Prefixes' => %w[when with] } }
|
||||
|
||||
it 'skips describe blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'the display name not present' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds context without `when` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
context 'the display name not present' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Start context description with 'when', or 'with'.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds shared_context without `when` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_context 'the display name not present' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Start context description with 'when', or 'with'.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "skips descriptions beginning with 'when'" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
context 'when the display name is not present' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds context without separate `when` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
context 'whenever you do' do
|
||||
^^^^^^^^^^^^^^^^^ Start context description with 'when', or 'with'.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when configured' do
|
||||
let(:cop_config) { { 'Prefixes' => %w[if] } }
|
||||
|
||||
it 'finds context without whitelisted prefixes at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
context 'when display name is present' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Start context description with 'if'.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips descriptions with whitelisted prefixes at the beginning' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
context 'if display name is present' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,95 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::Cop do
|
||||
subject(:cop) { fake_cop.new(config) }
|
||||
|
||||
let(:config) do
|
||||
rubocop_config =
|
||||
{
|
||||
'AllCops' => {
|
||||
'RSpec' => {
|
||||
'Patterns' => rspec_patterns
|
||||
}
|
||||
},
|
||||
'RSpec/FakeCop' => {
|
||||
'Exclude' => %w[bar_spec.rb]
|
||||
}
|
||||
}
|
||||
|
||||
RuboCop::Config.new(rubocop_config, 'fake_cop_config.yml')
|
||||
end
|
||||
|
||||
let(:fake_cop) do
|
||||
stub_const('RuboCop::RSpec', Module.new)
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class RuboCop::RSpec::FakeCop < described_class
|
||||
def on_send(node)
|
||||
add_offense(node, location: :expression, message: 'I flag everything')
|
||||
end
|
||||
end
|
||||
# rubocop:enable ClassAndModuleChildren
|
||||
RuboCop::RSpec::FakeCop
|
||||
end
|
||||
|
||||
let(:rspec_patterns) { ['_spec.rb$', '(?:^|/)spec/'] }
|
||||
|
||||
context 'when the source path ends with `_spec.rb`' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY, 'foo_spec.rb')
|
||||
foo(1)
|
||||
^^^^^^ I flag everything
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores the file if it is ignored' do
|
||||
expect_no_offenses(<<-RUBY, 'bar_spec.rb')
|
||||
foo(1)
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the source path contains `/spec/`' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY, '/spec/support/thing.rb')
|
||||
foo(1)
|
||||
^^^^^^ I flag everything
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the source path starts with `spec/`' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<-RUBY, 'spec/support/thing.rb')
|
||||
foo(1)
|
||||
^^^^^^ I flag everything
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the file is a source file without "spec" in the name' do
|
||||
it 'ignores the source when the path is not a spec file' do
|
||||
expect_no_offenses(<<-RUBY, 'foo.rb')
|
||||
foo(1)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores the source when the path is not a specified pattern' do
|
||||
expect_no_offenses(<<-RUBY, 'foo_test.rb')
|
||||
foo(1)
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when custom patterns are specified' do
|
||||
let(:rspec_patterns) do
|
||||
['_test\.rb$']
|
||||
end
|
||||
|
||||
it 'registers offenses when the path matches a custom specified pattern' do
|
||||
expect_offense(<<-RUBY, 'foo_test.rb')
|
||||
foo(1)
|
||||
^^^^^^ I flag everything
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,159 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::DescribeClass do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks first-line describe statements' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe "bad describe" do
|
||||
^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'supports RSpec.describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe Foo do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks describe statements after a require' do
|
||||
expect_offense(<<-RUBY)
|
||||
require 'spec_helper'
|
||||
describe "bad describe" do
|
||||
^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks highlights the first argument of a describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe "bad describe", "blah blah" do
|
||||
^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores nested describe statements' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Some::Class do
|
||||
describe "bad describe" do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores request specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'my new feature', type: :request do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores feature specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'my new feature', type: :feature do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores system specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'my new system test', type: :system do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores feature specs when RSpec.describe is used' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe 'my new feature', type: :feature do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags specs with non :type metadata' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'my new feature', foo: :feature do
|
||||
^^^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags normal metadata in describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'my new feature', blah, type: :wow do
|
||||
^^^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores feature specs - also with complex options' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'my new feature', :test, :type => :feature, :foo => :bar do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores an empty describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe do
|
||||
end
|
||||
|
||||
describe do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores routing specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'my new route', type: :routing do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores view specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'widgets/index', type: :view do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "doesn't blow up on single-line describes" do
|
||||
expect_no_offenses('describe Some::Class')
|
||||
end
|
||||
|
||||
it "doesn't flag top level describe in a shared example" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_examples 'Common::Interface' do
|
||||
describe '#public_interface' do
|
||||
it 'conforms to interface' do
|
||||
# ...
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "doesn't flag top level describe in a shared context" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.shared_context 'Common::Interface' do
|
||||
describe '#public_interface' do
|
||||
it 'conforms to interface' do
|
||||
# ...
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "doesn't flag top level describe in an unnamed shared context" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_context do
|
||||
describe '#public_interface' do
|
||||
it 'conforms to interface' do
|
||||
# ...
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,32 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::DescribeMethod do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'ignores describes with only a class' do
|
||||
expect_no_offenses('describe Some::Class do; end')
|
||||
end
|
||||
|
||||
it 'enforces non-method names' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Some::Class, 'nope', '.incorrect_usage' do
|
||||
^^^^^^ The second argument to describe should be the method being tested. '#instance' or '.class'.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips methods starting with a . or #' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Some::Class, '.asdf' do
|
||||
end
|
||||
|
||||
describe Some::Class, '#fdsa' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips specs not having a string second argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Some::Class, :config do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,42 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::DescribeSymbol do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags violations for `describe :symbol`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe(:some_method) { }
|
||||
^^^^^^^^^^^^ Avoid describing symbols.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `describe :symbol` with multiple arguments' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe(:some_method, "description") { }
|
||||
^^^^^^^^^^^^ Avoid describing symbols.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for `RSpec.describe :symbol`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe(:some_method, "description") { }
|
||||
^^^^^^^^^^^^ Avoid describing symbols.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags violations for a nested `describe`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe Foo do
|
||||
describe :to_s do
|
||||
^^^^^ Avoid describing symbols.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag non-Symbol arguments' do
|
||||
expect_no_offenses('describe("#some_method") { }')
|
||||
end
|
||||
|
||||
it 'does not flag `context :symbol`' do
|
||||
expect_no_offenses('context(:some_method) { }')
|
||||
end
|
||||
end
|
||||
@ -1,304 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::DescribedClass, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
shared_examples 'SkipBlocks enabled' do
|
||||
it 'does not flag violations within non-rspec blocks' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
controller(ApplicationController) do
|
||||
bar = MyClass
|
||||
end
|
||||
|
||||
before do
|
||||
MyClass
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
|
||||
Foo.custom_block do
|
||||
MyClass
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'SkipBlocks disabled' do
|
||||
it 'flags violations within all blocks' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
controller(ApplicationController) do
|
||||
bar = MyClass
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
MyClass
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
|
||||
Foo.custom_block do
|
||||
MyClass
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when SkipBlocks is `true`' do
|
||||
let(:cop_config) { { 'SkipBlocks' => true } }
|
||||
|
||||
include_examples 'SkipBlocks enabled'
|
||||
end
|
||||
|
||||
context 'when SkipBlocks anything besides `true`' do
|
||||
let(:cop_config) { { 'SkipBlocks' => 'yes' } }
|
||||
|
||||
include_examples 'SkipBlocks disabled'
|
||||
end
|
||||
|
||||
context 'when SkipBlocks is not set' do
|
||||
let(:cop_config) { {} }
|
||||
|
||||
include_examples 'SkipBlocks disabled'
|
||||
end
|
||||
|
||||
context 'when SkipBlocks is `false`' do
|
||||
let(:cop_config) { { 'SkipBlocks' => false } }
|
||||
|
||||
include_examples 'SkipBlocks disabled'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :described_class' do
|
||||
let(:enforced_style) { :described_class }
|
||||
|
||||
it 'checks for the use of the described class' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
include MyClass
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
|
||||
subject { MyClass.do_something }
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
|
||||
before { MyClass.do_something }
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores described class as string' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
subject { "MyClass" }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores describe that do not reference to a class' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe "MyClass" do
|
||||
subject { "MyClass" }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores class if the scope is changing' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
Class.new { foo = MyClass }
|
||||
Module.new { bar = MyClass }
|
||||
|
||||
def method
|
||||
include MyClass
|
||||
end
|
||||
|
||||
class OtherClass
|
||||
include MyClass
|
||||
end
|
||||
|
||||
module MyModle
|
||||
include MyClass
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'only takes class from top level describes' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
describe MyClass::Foo do
|
||||
subject { MyClass::Foo }
|
||||
|
||||
let(:foo) { MyClass }
|
||||
^^^^^^^ Use `described_class` instead of `MyClass`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores subclasses' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
subject { MyClass::SubClass }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores if namespace is not matching' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyNamespace::MyClass do
|
||||
subject { ::MyClass }
|
||||
let(:foo) { MyClass }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for the use of described class with namespace' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyNamespace::MyClass do
|
||||
subject { MyNamespace::MyClass }
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `described_class` instead of `MyNamespace::MyClass`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag violations within a class scope change' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyNamespace::MyClass do
|
||||
before do
|
||||
class Foo
|
||||
thing = MyNamespace::MyClass.new
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag violations within a hook scope change' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe do
|
||||
before do
|
||||
MyNamespace::MyClass.new
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for the use of described class with module' do
|
||||
pending
|
||||
|
||||
expect_offense(<<-RUBY)
|
||||
module MyNamespace
|
||||
describe MyClass do
|
||||
subject { MyNamespace::MyClass }
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `described_class` instead of `MyNamespace::MyClass`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts an empty block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { include Foo }',
|
||||
'describe(Foo) { include described_class }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { subject { Foo.do_action } }',
|
||||
'describe(Foo) { subject { described_class.do_action } }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { before { Foo.do_action } }',
|
||||
'describe(Foo) { before { described_class.do_action } }'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :explicit' do
|
||||
let(:enforced_style) { :explicit }
|
||||
|
||||
it 'checks for the use of the described_class' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
include described_class
|
||||
^^^^^^^^^^^^^^^ Use `MyClass` instead of `described_class`.
|
||||
|
||||
subject { described_class.do_something }
|
||||
^^^^^^^^^^^^^^^ Use `MyClass` instead of `described_class`.
|
||||
|
||||
before { described_class.do_something }
|
||||
^^^^^^^^^^^^^^^ Use `MyClass` instead of `described_class`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores described_class as string' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
subject { "described_class" }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores describe that do not reference to a class' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe "MyClass" do
|
||||
subject { described_class }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag violations within a class scope change' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyNamespace::MyClass do
|
||||
before do
|
||||
class Foo
|
||||
thing = described_class.new
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag violations within a hook scope change' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe do
|
||||
before do
|
||||
described_class.new
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { include described_class }',
|
||||
'describe(Foo) { include Foo }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { subject { described_class.do_action } }',
|
||||
'describe(Foo) { subject { Foo.do_action } }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'describe(Foo) { before { described_class.do_action } }',
|
||||
'describe(Foo) { before { Foo.do_action } }'
|
||||
|
||||
original = <<-RUBY
|
||||
describe(Foo) { include described_class }
|
||||
describe(Bar) { include described_class }
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
describe(Foo) { include Foo }
|
||||
describe(Bar) { include Bar }
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
end
|
||||
@ -1,93 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::EmptyExampleGroup, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
it 'flags an empty context' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
context 'when bar' do
|
||||
^^^^^^^^^^^^^^^^^^ Empty example group detected.
|
||||
|
||||
let(:foo) { bar }
|
||||
end
|
||||
|
||||
describe '#thingy?' do
|
||||
specify do
|
||||
expect(whatever.thingy?).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
it { should be_true }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags an empty top level describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
^^^^^^^^^^^^ Empty example group detected.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag include_examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
context "when something is true" do
|
||||
include_examples "some expectations"
|
||||
end
|
||||
|
||||
context "when something else is true" do
|
||||
include_context "some expectations"
|
||||
end
|
||||
|
||||
context "when a third thing is true" do
|
||||
it_behaves_like "some thingy"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag methods matching example group names' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'yields a block when given' do
|
||||
value = nil
|
||||
|
||||
helper.feature('whatevs') { value = 5 }
|
||||
|
||||
expect(value).to be 5
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not recognize custom include methods by default' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
^^^^^^^^^^^^ Empty example group detected.
|
||||
context "when I do something clever" do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Empty example group detected.
|
||||
it_has_special_behavior
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when a custom include method is specified' do
|
||||
let(:cop_config) do
|
||||
{ 'CustomIncludeMethods' => %w[it_has_special_behavior] }
|
||||
end
|
||||
|
||||
it 'does not flag an otherwise empty example group' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
context "when I do something clever" do
|
||||
it_has_special_behavior
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,102 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterExampleGroup do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks for empty line after describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe Foo do
|
||||
describe '#bar' do
|
||||
end
|
||||
^^^ Add an empty line after `describe`.
|
||||
describe '#baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'highlights single line formulations correctly' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe Foo do
|
||||
describe('#bar') { }
|
||||
^^^^^^^^^^^^^^^^^^^^ Add an empty line after `describe`.
|
||||
describe '#baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for empty line after context' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.context 'foo' do
|
||||
context 'bar' do
|
||||
end
|
||||
^^^ Add an empty line after `context`.
|
||||
context 'baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe Foo do
|
||||
describe '#bar' do
|
||||
end
|
||||
|
||||
describe '#baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.context 'foo' do
|
||||
context 'bar' do
|
||||
end
|
||||
|
||||
context 'baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles describes in an if block' do
|
||||
expect_offense(<<-RUBY)
|
||||
if RUBY_VERSION < 2.3
|
||||
describe 'skips checks under old ruby' do
|
||||
end
|
||||
else
|
||||
describe 'first check' do
|
||||
end
|
||||
^^^ Add an empty line after `describe`.
|
||||
describe 'second check' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe Foo do
|
||||
describe '#bar' do
|
||||
end
|
||||
describe '#baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe Foo do
|
||||
describe '#bar' do
|
||||
end
|
||||
|
||||
describe '#baz' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
end
|
||||
@ -1,231 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterFinalLet do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks for empty line after last let' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) { b }
|
||||
^^^^^^^^^^^^^ Add an empty line after the last `let` block.
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'check for empty line after the last `let!`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let!(:b) do
|
||||
b
|
||||
end
|
||||
^^^ Add an empty line after the last `let` block.
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) { b }
|
||||
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows comment followed by an empty line after let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) { b }
|
||||
# end of setup
|
||||
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags missing empty line after the comment that comes after last let' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) { b }
|
||||
# end of setup
|
||||
^^^^^^^^^^^^^^ Add an empty line after the last `let` block.
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores empty lines between the lets' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
|
||||
subject { described_class }
|
||||
|
||||
let!(:b) { b }
|
||||
^^^^^^^^^^^^^^ Add an empty line after the last `let` block.
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles let in tests' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
# This shouldn't really ever happen in a sane codebase but I still
|
||||
# want to avoid false positives
|
||||
it "doesn't mind me calling a method called let in the test" do
|
||||
let(foo)
|
||||
subject { bar }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles multiline let block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) do
|
||||
b
|
||||
end
|
||||
|
||||
it { expect(a).to eq(b) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles let being the latest node' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:b) { b }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles HEREDOC for let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:foo) do
|
||||
<<-BAR
|
||||
hello
|
||||
world
|
||||
BAR
|
||||
end
|
||||
|
||||
it 'uses heredoc' do
|
||||
expect(foo).to eql(" hello\n world\n")
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles silly HEREDOC syntax for let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe 'silly heredoc syntax' do
|
||||
let(:foo) { <<-BAR }
|
||||
hello
|
||||
world
|
||||
BAR
|
||||
|
||||
it 'has tricky syntax' do
|
||||
expect(foo).to eql(" hello\n world\n")
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles silly HEREDOC offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe 'silly heredoc syntax' do
|
||||
let(:foo) { <<-BAR }
|
||||
hello
|
||||
world
|
||||
BAR
|
||||
^^^ Add an empty line after the last `let` block.
|
||||
it 'has tricky syntax' do
|
||||
expect(foo).to eql(" hello\n world\n")
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
# a multiline comment marking
|
||||
# the end of setup
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
# a multiline comment marking
|
||||
# the end of setup
|
||||
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { <<-DOC }
|
||||
I'm super annoying!
|
||||
DOC
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { <<-DOC }
|
||||
I'm super annoying!
|
||||
DOC
|
||||
|
||||
it 'has a new line' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
end
|
||||
@ -1,128 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterHook do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks for empty line after `before` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before { do_something }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Add an empty line after `before`.
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for empty line after `after` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
after { do_something }
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Add an empty line after `after`.
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for empty line after `around` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
around { |test| test.run }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^ Add an empty line after `around`.
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after `before` hook' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before { do_something }
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after `after` hook' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
after { do_something }
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after `around` hook' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
around { |test| test.run }
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles multiline `before` block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before do
|
||||
do_something
|
||||
end
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles multiline `after` block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
after do
|
||||
do_something
|
||||
end
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles multiline `around` block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
around do |test|
|
||||
test.run
|
||||
end
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles `before` being the latest node' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before { do_something }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
before { do_something }
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
before { do_something }
|
||||
|
||||
it { does_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
end
|
||||
@ -1,97 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterSubject do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks for empty line after subject' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add empty line after `subject`.
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks for empty line after subject!' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject! { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add empty line after `subject`.
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after subject' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves empty line after subject!' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject! { described_class.new }
|
||||
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles subjects in tests' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
# This shouldn't really ever happen in a sane codebase but I still
|
||||
# want to avoid false positives
|
||||
it "doesn't mind me calling a method called subject in the test" do
|
||||
subject { bar }
|
||||
let(foo)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles multiline subject block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles subject being the latest node' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_user }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_example = <<-RUBY
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_example,
|
||||
good_example
|
||||
end
|
||||
@ -1,76 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExampleLength, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) { { 'Max' => 3 } }
|
||||
|
||||
it 'ignores non-spec blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
foo do
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows an empty example' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows a short example' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores comments' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
line 1
|
||||
line 2
|
||||
# comment
|
||||
line 3
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when inspecting large examples' do
|
||||
it 'flags the example' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
^^^^^ Example has too many lines [4/3].
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with CountComments enabled' do
|
||||
let(:cop_config) do
|
||||
{ 'Max' => 3, 'CountComments' => true }
|
||||
end
|
||||
|
||||
it 'flags the example' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
^^^^^ Example has too many lines [4/3].
|
||||
line 1
|
||||
line 2
|
||||
# comment
|
||||
line 3
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,90 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExampleWithoutDescription, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `always_allow`' do
|
||||
let(:enforced_style) { 'always_allow' }
|
||||
|
||||
it 'flags empty strings for description' do
|
||||
expect_offense(<<-RUBY)
|
||||
it '' do
|
||||
^^ Omit the argument when you want to have auto-generated description.
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `it` with a description' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'is good' do
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `it` without an argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `single_line_only`' do
|
||||
let(:enforced_style) { 'single_line_only' }
|
||||
|
||||
it 'flags missing description in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
^^ Add a description.
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores missing description in single-line examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(subject).to be_good }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags example with an empty string for description' do
|
||||
expect_offense(<<-RUBY)
|
||||
it('') { expect(subject).to be_good }
|
||||
^^ Omit the argument when you want to have auto-generated description.
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `disallow`' do
|
||||
let(:enforced_style) { 'disallow' }
|
||||
|
||||
it 'flags missing description in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
^^ Add a description.
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags missing description in single-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(subject).to be_good }
|
||||
^^ Add a description.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `it` with a description' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'is good' do
|
||||
expect(subject).to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,119 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'with configuration' do
|
||||
let(:cop_config) do
|
||||
{
|
||||
'CustomTransform' => { 'have' => 'has' },
|
||||
'IgnoredWords' => %w[only really]
|
||||
}
|
||||
end
|
||||
|
||||
it 'ignores non-example blocks' do
|
||||
expect_no_offenses('foo "should do something" do; end')
|
||||
end
|
||||
|
||||
it 'finds description with `should` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'should do something' do
|
||||
^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds description with `Should` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'Should do something' do
|
||||
^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds description with `shouldn\'t` at the beginning' do
|
||||
expect_offense(<<-RUBY)
|
||||
it "shouldn't do something" do
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags a lone should' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'should' do
|
||||
^^^^^^ Do not use should when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags a lone should not' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'should not' do
|
||||
^^^^^^^^^^ Do not use should when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds leading its' do
|
||||
expect_offense(<<-RUBY)
|
||||
it "it does something" do
|
||||
^^^^^^^^^^^^^^^^^ Do not repeat 'it' when describing your tests.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "skips words beginning with 'it'" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'itemizes items' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips descriptions without `should` at the beginning' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'finds no should here' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips descriptions starting with words that begin with `should`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'shoulders the burden' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "should only have trait" do end',
|
||||
'it "only has trait" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "SHOULDN\'T only have trait" do end',
|
||||
'it "DOES NOT only have trait" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "it does something" do end',
|
||||
'it "does something" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "It does something" do end',
|
||||
'it "does something" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "should" do end',
|
||||
'it "" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "should not" do end',
|
||||
'it "does not" do end'
|
||||
end
|
||||
|
||||
context 'when configuration is empty' do
|
||||
include_examples 'autocorrect',
|
||||
'it "should have trait" do end',
|
||||
'it "haves trait" do end'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it "should only fail" do end',
|
||||
'it "onlies fail" do end'
|
||||
end
|
||||
end
|
||||
@ -1,150 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExpectActual, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
it 'flags numeric literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(123).to eq(bar)
|
||||
^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(12.3).to eq(bar)
|
||||
^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(1i).to eq(bar)
|
||||
^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(1r).to eq(bar)
|
||||
^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags boolean literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(true).to eq(bar)
|
||||
^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(false).to eq(bar)
|
||||
^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags string and symbol literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect("foo").to eq(bar)
|
||||
^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(:foo).to eq(bar)
|
||||
^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags literal nil value within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(nil).to eq(bar)
|
||||
^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag dynamic values within expect(...)' do
|
||||
expect_no_offenses(<<-'RUBY')
|
||||
describe Foo do
|
||||
it 'uses expect correctly' do
|
||||
expect(foo).to eq(bar)
|
||||
expect("foo#{baz}").to eq(bar)
|
||||
expect(:"foo#{baz}").to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags arrays containing only literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect([123]).to eq(bar)
|
||||
^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect([[123]]).to eq(bar)
|
||||
^^^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags hashes containing only literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(foo: 1, bar: 2).to eq(bar)
|
||||
^^^^^^^^^^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(foo: 1, bar: [{}]).to eq(bar)
|
||||
^^^^^^^^^^^^^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags ranges containing only literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(1..2).to eq(bar)
|
||||
^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
expect(1...2).to eq(bar)
|
||||
^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags regexps containing only literal values within expect(...)' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect(/foo|bar/).to eq(bar)
|
||||
^^^^^^^^^ Provide the actual you are testing to `expect(...)`.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag complex values with dynamic parts within expect(...)' do
|
||||
expect_no_offenses(<<-'RUBY')
|
||||
describe Foo do
|
||||
it 'uses expect incorrectly' do
|
||||
expect.to eq(bar)
|
||||
expect([foo]).to eq(bar)
|
||||
expect([[foo]]).to eq(bar)
|
||||
expect(foo: 1, bar: foo).to eq(bar)
|
||||
expect(1..foo).to eq(bar)
|
||||
expect(1...foo).to eq(bar)
|
||||
expect(/foo|#{bar}/).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when inspecting rspec-rails routing specs' do
|
||||
let(:cop_config) { {} }
|
||||
|
||||
it 'ignores rspec-rails routing specs' do
|
||||
inspect_source(
|
||||
'expect(get: "/foo").to be_routeable',
|
||||
'spec/routing/foo_spec.rb'
|
||||
)
|
||||
|
||||
expect(cop.offenses).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,78 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExpectChange, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `method_call`' do
|
||||
let(:enforced_style) { 'method_call' }
|
||||
|
||||
it 'finds blocks that contain simple message sending' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
expect(run).to change { User.count }
|
||||
^^^^^^^^^^^^^^^^^^^^^ Prefer `change(User, :count)`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores blocks that cannot be converted to obj/attribute pair' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
expect(run).to change { User.sum(:points) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores change method of object that happens to receive a block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
Record.change { User.count }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'expect(run).to change { User.count }.by(1)',
|
||||
'expect(run).to change(User, :count).by(1)'
|
||||
)
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `block`' do
|
||||
let(:enforced_style) { 'block' }
|
||||
|
||||
it 'finds change matcher without block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
expect(run).to change(User, :count)
|
||||
^^^^^^^^^^^^^^^^^^^^ Prefer `change { User.count }`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds change matcher when receiver is a variable' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
expect(run).to change(user, :count)
|
||||
^^^^^^^^^^^^^^^^^^^^ Prefer `change { user.count }`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores methods called change' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
record.change(user, :count)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'expect(run).to change(User, :count).by(1)',
|
||||
'expect(run).to change { User.count }.by(1)'
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -1,79 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExpectInHook do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'adds an offense for `expect` in `before` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
expect(something).to eq('foo')
|
||||
^^^^^^ Do not use `expect` in `before` hook
|
||||
is_expected.to eq('foo')
|
||||
^^^^^^^^^^^ Do not use `is_expected` in `before` hook
|
||||
expect_any_instance_of(Something).to receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Do not use `expect_any_instance_of` in `before` hook
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'adds an offense for `expect` in `after` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
after do
|
||||
expect(something).to eq('foo')
|
||||
^^^^^^ Do not use `expect` in `after` hook
|
||||
is_expected.to eq('foo')
|
||||
^^^^^^^^^^^ Do not use `is_expected` in `after` hook
|
||||
expect_any_instance_of(Something).to receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Do not use `expect_any_instance_of` in `after` hook
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'adds an offense for `expect` in `around` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
around do
|
||||
expect(something).to eq('foo')
|
||||
^^^^^^ Do not use `expect` in `around` hook
|
||||
is_expected(something).to eq('foo')
|
||||
^^^^^^^^^^^ Do not use `is_expected` in `around` hook
|
||||
expect_any_instance_of(Something).to receive(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Do not use `expect_any_instance_of` in `around` hook
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'adds an offense for `expect` with block in `before` hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
expect { something }.to eq('foo')
|
||||
^^^^^^ Do not use `expect` in `before` hook
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts an empty `before` hook' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts `allow` in `before` hook' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
allow(something).to receive(:foo)
|
||||
allow_any_instance_of(something).to receive(:foo)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts `expect` in `it`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
expect(something).to eq('foo')
|
||||
is_expected.to eq('foo')
|
||||
expect_any_instance_of(something).to receive(:foo)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,62 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ExpectOutput do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for overwriting $stdout within an example' do
|
||||
expect_offense(<<-RUBY)
|
||||
specify do
|
||||
$stdout = StringIO.new
|
||||
^^^^^^^ Use `expect { ... }.to output(...).to_stdout` instead of mutating $stdout.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for overwriting $stderr ' \
|
||||
'within an example scoped hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:each) do
|
||||
$stderr = StringIO.new
|
||||
^^^^^^^ Use `expect { ... }.to output(...).to_stderr` instead of mutating $stderr.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for interacting with $stdout' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
specify do
|
||||
$stdout.puts("hi")
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag assignments to other global variables' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
specify do
|
||||
$blah = StringIO.new
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag assignments to $stdout outside of example scope' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:suite) do
|
||||
$stderr = StringIO.new
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag assignments to $stdout in example_group scope' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
$stderr = StringIO.new
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag assigns to $stdout when in the root scope' do
|
||||
expect_no_offenses('$stderr = StringIO.new')
|
||||
end
|
||||
end
|
||||
@ -1,172 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically do # rubocop:disable Metrics/LineLength
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for offending code' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
title "Something"
|
||||
^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
published_at 1.day.from_now
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
status [:draft, :published].sample
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
created_at 1.day.ago
|
||||
^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
update_times [Time.current]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
meta_tags(foo: Time.current)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense in a trait' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
trait :published do
|
||||
title "Something"
|
||||
^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
published_at 1.day.from_now
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense in a transient block' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
transient do
|
||||
title "Something"
|
||||
^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
published_at 1.day.from_now
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for an attribute defined on `self`' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
self.start { Date.today }
|
||||
self.end Date.tomorrow
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Use a block to declare attribute values.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts valid factory definitions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
trait :published do
|
||||
published_at { 1.day.from_now }
|
||||
end
|
||||
created_at { 1.day.ago }
|
||||
status { :draft }
|
||||
comments_count { 0 }
|
||||
title { "Static" }
|
||||
description { FFaker::Lorem.paragraph(10) }
|
||||
recent_statuses { [] }
|
||||
tags { { like_count: 2 } }
|
||||
|
||||
before(:create, &:initialize_something)
|
||||
after(:create, &:rebuild_cache)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not add offense if out of factory bot block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
status [:draft, :published].sample
|
||||
published_at 1.day.from_now
|
||||
created_at 1.day.ago
|
||||
update_times [Time.current]
|
||||
meta_tags(foo: Time.current)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts valid association definitions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
author age: 42, factory: :user
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts valid sequence definition' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
sequence :negative_numbers, &:-@
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad = <<-RUBY
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
title "Something"
|
||||
comments_count 0
|
||||
tag Tag::MAGIC
|
||||
recent_statuses []
|
||||
status([:draft, :published].sample)
|
||||
published_at 1.day.from_now
|
||||
created_at(1.day.ago)
|
||||
updated_at Time.current
|
||||
update_times [Time.current]
|
||||
meta_tags(foo: Time.current)
|
||||
other_tags({ foo: Time.current })
|
||||
options color: :blue
|
||||
other_options Tag::MAGIC => :magic
|
||||
self.end Date.tomorrow
|
||||
|
||||
trait :old do
|
||||
published_at 1.week.ago
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
corrected = <<-RUBY
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
title { "Something" }
|
||||
comments_count { 0 }
|
||||
tag { Tag::MAGIC }
|
||||
recent_statuses { [] }
|
||||
status { [:draft, :published].sample }
|
||||
published_at { 1.day.from_now }
|
||||
created_at { 1.day.ago }
|
||||
updated_at { Time.current }
|
||||
update_times { [Time.current] }
|
||||
meta_tags { { foo: Time.current } }
|
||||
other_tags { { foo: Time.current } }
|
||||
options { { color: :blue } }
|
||||
other_options { { Tag::MAGIC => :magic } }
|
||||
self.end { Date.tomorrow }
|
||||
|
||||
trait :old do
|
||||
published_at { 1.week.ago }
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad, corrected
|
||||
end
|
||||
@ -1,139 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::FactoryBot::CreateList, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :create_list' do
|
||||
let(:enforced_style) { :create_list }
|
||||
|
||||
it 'flags usage of n.times with no arguments' do
|
||||
expect_offense(<<-RUBY)
|
||||
3.times { create :user }
|
||||
^^^^^^^ Prefer create_list.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of n.times when FactoryGirl.create is used' do
|
||||
expect_offense(<<-RUBY)
|
||||
3.times { FactoryGirl.create :user }
|
||||
^^^^^^^ Prefer create_list.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of n.times when FactoryBot.create is used' do
|
||||
expect_offense(<<-RUBY)
|
||||
3.times { FactoryBot.create :user }
|
||||
^^^^^^^ Prefer create_list.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores create method of other object' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
3.times { SomeFactory.create :user }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores create in other block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
allow(User).to receive(:create) { create :user }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores n.times with argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
3.times { |n| create :user, created_at: n.days.ago }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores n.times when there is no create call inside' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
3.times { do_something }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores n.times when there is other calls but create' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
used_passwords = []
|
||||
3.times do
|
||||
u = create :user
|
||||
expect(used_passwords).not_to include(u.password)
|
||||
used_passwords << u.password
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags FactoryGirl.create calls with a block' do
|
||||
expect_offense(<<-RUBY)
|
||||
3.times do
|
||||
^^^^^^^ Prefer create_list.
|
||||
create(:user) { |user| create :account, user: user }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'5.times { create :user }',
|
||||
'create_list :user, 5'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'5.times { create(:user, :trait) }',
|
||||
'create_list(:user, 5, :trait)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'5.times { create :user, :trait, key: val }',
|
||||
'create_list :user, 5, :trait, key: val'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'5.times { FactoryGirl.create :user }',
|
||||
'FactoryGirl.create_list :user, 5'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :n_times' do
|
||||
let(:enforced_style) { :n_times }
|
||||
|
||||
it 'flags usage of create_list' do
|
||||
expect_offense(<<-RUBY)
|
||||
create_list :user, 3
|
||||
^^^^^^^^^^^ Prefer 3.times.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of FactoryGirl.create_list' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryGirl.create_list :user, 3
|
||||
^^^^^^^^^^^ Prefer 3.times.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of FactoryGirl.create_list with a block' do
|
||||
expect_offense(<<-RUBY)
|
||||
FactoryGirl.create_list(:user, 3) { |user| user.points = rand(1000) }
|
||||
^^^^^^^^^^^ Prefer 3.times.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores create method of other object' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
SomeFactory.create_list :user, 3
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'create_list :user, 5',
|
||||
'5.times { create :user }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'create_list(:user, 5, :trait)',
|
||||
'5.times { create(:user, :trait) }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'create_list :user, 5, :trait, key: val',
|
||||
'5.times { create :user, :trait, key: val }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'FactoryGirl.create_list :user, 5',
|
||||
'5.times { FactoryGirl.create :user }'
|
||||
end
|
||||
end
|
||||
@ -1,198 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::FilePath, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
it 'registers an offense for a bad path' do
|
||||
expect_offense(<<-RUBY, 'wrong_path_foo_spec.rb')
|
||||
describe MyClass, 'foo' do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*foo*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a wrong class but a correct method' do
|
||||
expect_offense(<<-RUBY, 'wrong_class_foo_spec.rb')
|
||||
describe MyClass, '#foo' do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*foo*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a repeated .rb' do
|
||||
expect_offense(<<-RUBY, 'my_class/foo_spec.rb.rb')
|
||||
describe MyClass, '#foo' do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*foo*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a file missing a .rb' do
|
||||
expect_offense(<<-RUBY, 'my_class/foo_specorb')
|
||||
describe MyClass, '#foo' do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*foo*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a wrong class and highlights metadata' do
|
||||
expect_offense(<<-RUBY, 'wrong_class_foo_spec.rb')
|
||||
describe MyClass, '#foo', blah: :blah do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*foo*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a wrong class name' do
|
||||
expect_offense(<<-RUBY, 'wrong_class_spec.rb')
|
||||
describe MyClass do; end
|
||||
^^^^^^^^^^^^^^^^ Spec path should end with `my_class*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a wrong class name with a symbol argument' do
|
||||
expect_offense(<<-RUBY, 'wrong_class_spec.rb')
|
||||
describe MyClass, :foo do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `my_class*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a file missing _spec' do
|
||||
expect_offense(<<-RUBY, 'user.rb')
|
||||
describe User do; end
|
||||
^^^^^^^^^^^^^ Spec path should end with `user*_spec.rb`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips specs that do not describe a class / method' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/spec.rb')
|
||||
describe 'Test something' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips specs that do have multiple top level describes' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/spec.rb')
|
||||
describe MyClass, 'do_this' do; end
|
||||
describe MyClass, 'do_that' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks class specs' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class_spec.rb')
|
||||
describe Some::Class do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows different parent directories' do
|
||||
expect_no_offenses(<<-RUBY, 'parent_dir/some/class_spec.rb')
|
||||
describe Some::Class do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles CamelCaps class names' do
|
||||
expect_no_offenses(<<-RUBY, 'my_class_spec.rb')
|
||||
describe MyClass do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles ACRONYMClassNames' do
|
||||
expect_no_offenses(<<-RUBY, 'abc_one/two_spec.rb')
|
||||
describe ABCOne::Two do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles ALLCAPS class names' do
|
||||
expect_no_offenses(<<-RUBY, 'allcaps_spec.rb')
|
||||
describe ALLCAPS do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles alphanumeric class names' do
|
||||
expect_no_offenses(<<-RUBY, 'ipv4_and_ipv6_spec.rb')
|
||||
describe IPV4AndIPV6 do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks instance methods' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/inst_spec.rb')
|
||||
describe Some::Class, '#inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks class methods' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/inst_spec.rb')
|
||||
describe Some::Class, '.inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows flat hierarchies for instance methods' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class_inst_spec.rb')
|
||||
describe Some::Class, '#inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows flat hierarchies for class methods' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class_inst_spec.rb')
|
||||
describe Some::Class, '.inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows subdirs for instance methods' do
|
||||
filename = 'some/class/instance_methods/inst_spec.rb'
|
||||
expect_no_offenses(<<-RUBY, filename)
|
||||
describe Some::Class, '#inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows subdirs for class methods' do
|
||||
filename = 'some/class/class_methods/inst_spec.rb'
|
||||
expect_no_offenses(<<-RUBY, filename)
|
||||
describe Some::Class, '.inst' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores non-alphanumeric characters' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/pred_spec.rb')
|
||||
describe Some::Class, '#pred?' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows bang method' do
|
||||
expect_no_offenses(<<-RUBY, 'some/class/bang_spec.rb')
|
||||
describe Some::Class, '#bang!' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows flexibility with predicates' do
|
||||
filename = 'some/class/thing_predicate_spec.rb'
|
||||
expect_no_offenses(<<-RUBY, filename)
|
||||
describe Some::Class, '#thing?' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows flexibility with operators' do
|
||||
filename = 'my_little_class/spaceship_operator_spec.rb'
|
||||
expect_no_offenses(<<-RUBY, filename)
|
||||
describe MyLittleClass, '#<=>' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when configured with CustomTransform' do
|
||||
let(:cop_config) { { 'CustomTransform' => { 'FooFoo' => 'foofoo' } } }
|
||||
|
||||
it 'respects custom module name transformation' do
|
||||
expect_no_offenses(<<-RUBY, 'foofoo/some/class/bar_spec.rb')
|
||||
describe FooFoo::Some::Class, '#bar' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores routing specs' do
|
||||
expect_no_offenses(<<-RUBY, 'foofoo/some/class/bar_spec.rb')
|
||||
describe MyController, "#foo", type: :routing do; end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when configured with IgnoreMethods' do
|
||||
let(:cop_config) { { 'IgnoreMethods' => true } }
|
||||
|
||||
it 'does not care about the described method' do
|
||||
expect_no_offenses(<<-RUBY, 'my_class_spec.rb')
|
||||
describe MyClass, '#look_here_a_method' do; end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,131 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::Focus do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
# rubocop:disable RSpec/ExampleLength
|
||||
it 'flags all rspec example blocks with that include `focus: true`' do
|
||||
expect_offense(<<-RUBY)
|
||||
example 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xit 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
describe 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
it 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xspecify 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
specify 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
example_group 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
scenario 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xexample 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xdescribe 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
context 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xcontext 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
feature 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xfeature 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
xscenario 'test', meta: true, focus: true do; end
|
||||
^^^^^^^^^^^ Focused spec found.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags all rspec example blocks that include `:focus`' do
|
||||
expect_offense(<<-RUBY)
|
||||
example_group 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
feature 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xexample 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xdescribe 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xscenario 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
specify 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
example 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xfeature 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xspecify 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
scenario 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
describe 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xit 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
context 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
xcontext 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
it 'test', :focus do; end
|
||||
^^^^^^ Focused spec found.
|
||||
RUBY
|
||||
end
|
||||
# rubocop:enable RSpec/ExampleLength
|
||||
|
||||
it 'does not flag unfocused specs' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
xcontext 'test' do; end
|
||||
xscenario 'test' do; end
|
||||
xspecify 'test' do; end
|
||||
describe 'test' do; end
|
||||
example 'test' do; end
|
||||
xexample 'test' do; end
|
||||
scenario 'test' do; end
|
||||
specify 'test' do; end
|
||||
xit 'test' do; end
|
||||
feature 'test' do; end
|
||||
xfeature 'test' do; end
|
||||
context 'test' do; end
|
||||
it 'test' do; end
|
||||
example_group 'test' do; end
|
||||
xdescribe 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag a method that is focused twice' do
|
||||
expect_offense(<<-RUBY)
|
||||
fit "foo", :focus do
|
||||
^^^^^^^^^^^^^^^^^ Focused spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores non-rspec code with :focus blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
some_method "foo", focus: true do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags focused block types' do
|
||||
expect_offense(<<-RUBY)
|
||||
fdescribe 'test' do; end
|
||||
^^^^^^^^^^^^^^^^ Focused spec found.
|
||||
ffeature 'test' do; end
|
||||
^^^^^^^^^^^^^^^ Focused spec found.
|
||||
fcontext 'test' do; end
|
||||
^^^^^^^^^^^^^^^ Focused spec found.
|
||||
fit 'test' do; end
|
||||
^^^^^^^^^^ Focused spec found.
|
||||
fscenario 'test' do; end
|
||||
^^^^^^^^^^^^^^^^ Focused spec found.
|
||||
fexample 'test' do; end
|
||||
^^^^^^^^^^^^^^^ Focused spec found.
|
||||
fspecify 'test' do; end
|
||||
^^^^^^^^^^^^^^^ Focused spec found.
|
||||
focus 'test' do; end
|
||||
^^^^^^^^^^^^ Focused spec found.
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,171 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::HookArgument, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
shared_examples 'ignored hooks' do
|
||||
it 'ignores :context and :suite' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:suite) { true }
|
||||
after(:suite) { true }
|
||||
before(:context) { true }
|
||||
after(:context) { true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores hooks with more than one argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:each, :something_custom) { true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores non-rspec hooks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
setup(:each) { true }
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'hook autocorrect' do |output|
|
||||
include_examples 'autocorrect', 'before(:each) { }', output
|
||||
include_examples 'autocorrect', 'before(:example) { }', output
|
||||
include_examples 'autocorrect', 'before { }', output
|
||||
|
||||
include_examples 'autocorrect', 'config.before(:each) { }',
|
||||
'config.' + output
|
||||
include_examples 'autocorrect', 'config.before(:example) { }',
|
||||
'config.' + output
|
||||
include_examples 'autocorrect', 'config.before { }',
|
||||
'config.' + output
|
||||
end
|
||||
|
||||
shared_examples 'an example hook' do
|
||||
include_examples 'ignored hooks'
|
||||
include_examples 'detects style', 'before(:each) { foo }', 'each'
|
||||
include_examples 'detects style', 'before(:example) { foo }', 'example'
|
||||
include_examples 'detects style', 'before { foo }', 'implicit'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :implicit' do
|
||||
let(:enforced_style) { :implicit }
|
||||
|
||||
it 'detects :each for hooks' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:each) { true }
|
||||
^^^^^^^^^^^^^ Omit the default `:each` argument for RSpec hooks.
|
||||
after(:each) { true }
|
||||
^^^^^^^^^^^^ Omit the default `:each` argument for RSpec hooks.
|
||||
around(:each) { true }
|
||||
^^^^^^^^^^^^^ Omit the default `:each` argument for RSpec hooks.
|
||||
config.after(:each) { true }
|
||||
^^^^^^^^^^^^^^^^^^^ Omit the default `:each` argument for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects :example for hooks' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:example) { true }
|
||||
^^^^^^^^^^^^^^^^ Omit the default `:example` argument for RSpec hooks.
|
||||
after(:example) { true }
|
||||
^^^^^^^^^^^^^^^ Omit the default `:example` argument for RSpec hooks.
|
||||
around(:example) { true }
|
||||
^^^^^^^^^^^^^^^^ Omit the default `:example` argument for RSpec hooks.
|
||||
config.before(:example) { true }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Omit the default `:example` argument for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag hooks without default scopes' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before { true }
|
||||
after { true }
|
||||
config.before { true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'an example hook'
|
||||
include_examples 'hook autocorrect', 'before { }'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :each' do
|
||||
let(:enforced_style) { :each }
|
||||
|
||||
it 'detects :each for hooks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:each) { true }
|
||||
after(:each) { true }
|
||||
around(:each) { true }
|
||||
config.before(:each) { true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects :example for hooks' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:example) { true }
|
||||
^^^^^^^^^^^^^^^^ Use `:each` for RSpec hooks.
|
||||
after(:example) { true }
|
||||
^^^^^^^^^^^^^^^ Use `:each` for RSpec hooks.
|
||||
around(:example) { true }
|
||||
^^^^^^^^^^^^^^^^ Use `:each` for RSpec hooks.
|
||||
config.before(:example) { true }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Use `:each` for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects hooks without default scopes' do
|
||||
expect_offense(<<-RUBY)
|
||||
before { true }
|
||||
^^^^^^ Use `:each` for RSpec hooks.
|
||||
after { true }
|
||||
^^^^^ Use `:each` for RSpec hooks.
|
||||
config.before { true }
|
||||
^^^^^^ Use `:each` for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'an example hook'
|
||||
include_examples 'hook autocorrect', 'before(:each) { }'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is :example' do
|
||||
let(:enforced_style) { :example }
|
||||
|
||||
it 'detects :example for hooks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before(:example) { true }
|
||||
after(:example) { true }
|
||||
around(:example) { true }
|
||||
config.before(:example) { true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects :each for hooks' do
|
||||
expect_offense(<<-RUBY)
|
||||
before(:each) { true }
|
||||
^^^^^^^^^^^^^ Use `:example` for RSpec hooks.
|
||||
after(:each) { true }
|
||||
^^^^^^^^^^^^ Use `:example` for RSpec hooks.
|
||||
around(:each) { true }
|
||||
^^^^^^^^^^^^^ Use `:example` for RSpec hooks.
|
||||
config.before(:each) { true }
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `:example` for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag hooks without default scopes' do
|
||||
expect_offense(<<-RUBY)
|
||||
before { true }
|
||||
^^^^^^ Use `:example` for RSpec hooks.
|
||||
after { true }
|
||||
^^^^^ Use `:example` for RSpec hooks.
|
||||
config.before { true }
|
||||
^^^^^^ Use `:example` for RSpec hooks.
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'an example hook'
|
||||
include_examples 'hook autocorrect', 'before(:example) { }'
|
||||
end
|
||||
end
|
||||
@ -1,135 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::HooksBeforeExamples do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags `before` after `it`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
it { is_expected.to be_after_let }
|
||||
before { setup }
|
||||
^^^^^^^^^^^^^^^^ Move `before` above the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `before` after `context`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
context 'a context' do
|
||||
it { is_expected.to be_after_let }
|
||||
end
|
||||
|
||||
before { setup }
|
||||
^^^^^^^^^^^^^^^^ Move `before` above the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `before` after `include_examples`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_examples('should be after let')
|
||||
|
||||
before { setup }
|
||||
^^^^^^^^^^^^^^^^ Move `before` above the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `after` after an example' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
it { is_expected.to be_after_let }
|
||||
after { cleanup }
|
||||
^^^^^^^^^^^^^^^^^ Move `after` above the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags scoped hook after an example' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
it { is_expected.to be_after_let }
|
||||
before(:each) { cleanup }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^ Move `before` above the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag hooks before the examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before(:each) { setup }
|
||||
after(:each) { cleanup }
|
||||
|
||||
it { is_expected.to be_after_let }
|
||||
|
||||
context 'a context' do
|
||||
it { is_expected.to work }
|
||||
end
|
||||
|
||||
include_examples('everything is fine')
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag `before` in a nested context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before { setup }
|
||||
|
||||
context 'something else' do
|
||||
before { additional_setup }
|
||||
it { is_expected.to work }
|
||||
end
|
||||
|
||||
include_examples('everything is fine')
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows inclusion of context before hooks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_context 'special user'
|
||||
|
||||
before { setup }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores single-line example blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_examples 'special user' do
|
||||
before { setup }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
include_examples('should be after hook')
|
||||
context 'another one' do
|
||||
before { another_setup }
|
||||
include_examples('should be ok')
|
||||
end
|
||||
|
||||
after { cleanup }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
after { cleanup }
|
||||
include_examples('should be after hook')
|
||||
context 'another one' do
|
||||
before { another_setup }
|
||||
include_examples('should be ok')
|
||||
end
|
||||
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code, good_code
|
||||
end
|
||||
@ -1,101 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ImplicitExpect, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'when EnforcedStyle is is_expected' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'is_expected' }
|
||||
end
|
||||
|
||||
it 'flags it { should }' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { should be_truthy }
|
||||
^^^^^^ Prefer `is_expected.to` over `should`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags it { should_not }' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { should_not be_truthy }
|
||||
^^^^^^^^^^ Prefer `is_expected.to_not` over `should_not`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of is_expected.to' do
|
||||
expect_no_offenses('it { is_expected.to be_truthy }')
|
||||
end
|
||||
|
||||
it 'approves of is_expected.to_not' do
|
||||
expect_no_offenses('it { is_expected.to_not be_truthy }')
|
||||
end
|
||||
|
||||
it 'approves of is_expected.not_to' do
|
||||
expect_no_offenses('it { is_expected.not_to be_truthy }')
|
||||
end
|
||||
|
||||
include_examples 'detects style', 'it { should be_truthy }', 'should'
|
||||
include_examples 'autocorrect',
|
||||
'it { should be_truthy }',
|
||||
'it { is_expected.to be_truthy }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { should_not be_truthy }',
|
||||
'it { is_expected.to_not be_truthy }'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is should' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'should' }
|
||||
end
|
||||
|
||||
it 'flags it { is_expected.to }' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.to be_truthy }
|
||||
^^^^^^^^^^^^^^ Prefer `should` over `is_expected.to`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags it { is_expected.to_not }' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.to_not be_truthy }
|
||||
^^^^^^^^^^^^^^^^^^ Prefer `should_not` over `is_expected.to_not`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags it { is_expected.not_to }' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.not_to be_truthy }
|
||||
^^^^^^^^^^^^^^^^^^ Prefer `should_not` over `is_expected.not_to`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of should' do
|
||||
expect_no_offenses('it { should be_truthy }')
|
||||
end
|
||||
|
||||
it 'approves of should_not' do
|
||||
expect_no_offenses('it { should_not be_truthy }')
|
||||
end
|
||||
|
||||
include_examples 'detects style',
|
||||
'it { is_expected.to be_truthy }',
|
||||
'is_expected'
|
||||
|
||||
include_examples 'detects style',
|
||||
'it { should be_truthy }',
|
||||
'should'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to be_truthy }',
|
||||
'it { should be_truthy }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to_not be_truthy }',
|
||||
'it { should_not be_truthy }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.not_to be_truthy }',
|
||||
'it { should_not be_truthy }'
|
||||
end
|
||||
end
|
||||
@ -1,200 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ImplicitSubject, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `single_line_only`' do
|
||||
let(:enforced_style) { 'single_line_only' }
|
||||
|
||||
it 'flags `is_expected` in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
is_expected.to be_good
|
||||
^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `is_expected` inside `its` block, in multi-line examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
its(:quality) do
|
||||
is_expected.to be :high
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `should` in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
should be_good
|
||||
^^^^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `is_expected` in single-line examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { is_expected.to be_good }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `should` in single-line examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { should be_good }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag methods called is_expected and should' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'uses some similar sounding methods' do
|
||||
expect(baz).to receive(:is_expected)
|
||||
baz.is_expected
|
||||
foo.should(deny_access)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects usage of `is_expected` inside helper methods' do
|
||||
expect_offense(<<-RUBY)
|
||||
def permits(actions)
|
||||
actions.each { |action| is_expected.to permit_action(action) }
|
||||
^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_code = <<-RUBY
|
||||
it 'works' do
|
||||
is_expected.to be_truthy
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
it 'works' do
|
||||
expect(subject).to be_truthy
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_code,
|
||||
good_code
|
||||
|
||||
bad_code = <<-RUBY
|
||||
it 'works' do
|
||||
should be_truthy
|
||||
should_not be_falsy
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
it 'works' do
|
||||
expect(subject).to be_truthy
|
||||
expect(subject).not_to be_falsy
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_code,
|
||||
good_code
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `single_statement_only`' do
|
||||
let(:enforced_style) { 'single_statement_only' }
|
||||
|
||||
it 'allows `is_expected` in multi-line example with single statement' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
is_expected.to be_good
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `is_expected` in multi-statement examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
subject.age = 18
|
||||
is_expected.to be_valid
|
||||
^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_code = <<-RUBY
|
||||
it 'is valid' do
|
||||
subject.age = 18
|
||||
is_expected.to be_valid
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
it 'is valid' do
|
||||
subject.age = 18
|
||||
expect(subject).to be_valid
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_code,
|
||||
good_code
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_code,
|
||||
good_code
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `disallow`' do
|
||||
let(:enforced_style) { 'disallow' }
|
||||
|
||||
it 'flags `is_expected` in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
is_expected.to be_good
|
||||
^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `is_expected` in single-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.to be_good }
|
||||
^^^^^^^^^^^ Don't use implicit subject.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `should` in multi-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'expect subject to be used' do
|
||||
should be_good
|
||||
^^^^^^^^^^^^^^ Don't use implicit subject.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `should` in single-line examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { should be_good }
|
||||
^^^^^^^^^^^^^^ Don't use implicit subject.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `is_expected` inside `its` block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
its(:quality) { is_expected.to be :high }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to be_truthy }',
|
||||
'it { expect(subject).to be_truthy }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { should be_truthy }',
|
||||
'it { expect(subject).to be_truthy }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { should_not be_truthy }',
|
||||
'it { expect(subject).not_to be_truthy }'
|
||||
end
|
||||
end
|
||||
@ -1,60 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::InstanceSpy do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'when used with `have_received`' do
|
||||
it 'adds an offense for an instance_double with single argument' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = instance_double(Foo).as_null_object
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `instance_spy` when you check your double with `have_received`.
|
||||
expect(foo).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'adds an offense for an instance_double with multiple arguments' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = instance_double(Foo, :name).as_null_object
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `instance_spy` when you check your double with `have_received`.
|
||||
expect(foo).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores instance_double when it is not used with as_null_object' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
foo = instance_double(Foo)
|
||||
expect(bar).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not used with `have_received`' do
|
||||
it 'does not add an offence' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
foo = instance_double(Foo).as_null_object
|
||||
expect(bar).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
original = <<-RUBY
|
||||
it do
|
||||
foo = instance_double(Foo, :name).as_null_object
|
||||
expect(foo).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
it do
|
||||
foo = instance_spy(Foo, :name)
|
||||
expect(foo).to have_received(:bar)
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
@ -1,93 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::InstanceVariable do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'finds an instance variable inside a describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
before { @foo = [] }
|
||||
it { expect(@foo).to be_empty }
|
||||
^^^^ Replace instance variable with local variable or `let`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores non-spec blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
not_rspec do
|
||||
before { @foo = [] }
|
||||
it { expect(@foo).to be_empty }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds an instance variable inside a shared example' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_examples 'shared example' do
|
||||
it { expect(@foo).to be_empty }
|
||||
^^^^ Replace instance variable with local variable or `let`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores an instance variable without describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
@foo = []
|
||||
@foo.empty?
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores an instance variable inside a dynamic class' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
let(:object) do
|
||||
Class.new(OtherClass) do
|
||||
def initialize(resource)
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def serialize
|
||||
@resource.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
# Regression test for nevir/rubocop-rspec#115
|
||||
it 'ignores instance variables outside of specs' do
|
||||
expect_no_offenses(<<-RUBY, 'lib/source_code.rb')
|
||||
feature do
|
||||
@foo = bar
|
||||
|
||||
@foo
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when configured with AssignmentOnly', :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'AssignmentOnly' => true }
|
||||
end
|
||||
|
||||
it 'flags an instance variable when it is also assigned' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
before { @foo = [] }
|
||||
it { expect(@foo).to be_empty }
|
||||
^^^^ Replace instance variable with local variable or `let`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores an instance variable when it is not assigned' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe MyClass do
|
||||
it { expect(@foo).to be_empty }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,37 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::InvalidPredicateMatcher do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for double question' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to be_something?
|
||||
^^^^^^^^^^^^^ Omit `?` from `be_something?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for double question with `not_to`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).not_to be_something?
|
||||
^^^^^^^^^^^^^ Omit `?` from `be_something?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for double question with `to_not`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to_not be_something?
|
||||
^^^^^^^^^^^^^ Omit `?` from `be_something?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for double question with `have_something?`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to have_something?
|
||||
^^^^^^^^^^^^^^^ Omit `?` from `have_something?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts valid predicate matcher' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to be_something
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,49 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ItBehavesLike, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'when the enforced style is `it_behaves_like`' do
|
||||
let(:enforced_style) { :it_behaves_like }
|
||||
|
||||
it 'flags a violation for it_should_behave_like' do
|
||||
expect_offense(<<-RUBY)
|
||||
it_should_behave_like 'a foo'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `it_behaves_like` over `it_should_behave_like` when including examples in a nested context.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag a violation for it_behaves_like' do
|
||||
expect_no_offenses("it_behaves_like 'a foo'")
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
"foo(); it_should_behave_like 'a foo'",
|
||||
"foo(); it_behaves_like 'a foo'"
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the enforced style is `it_should_behave_like`' do
|
||||
let(:enforced_style) { :it_should_behave_like }
|
||||
|
||||
it 'flags a violation for it_behaves_like' do
|
||||
expect_offense(<<-RUBY)
|
||||
it_behaves_like 'a foo'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Prefer `it_should_behave_like` over `it_behaves_like` when including examples in a nested context.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag a violation for it_behaves_like' do
|
||||
expect_no_offenses("it_should_behave_like 'a foo'")
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
"foo(); it_behaves_like 'a foo'",
|
||||
"foo(); it_should_behave_like 'a foo'"
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -1,80 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::IteratedExpectation do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags `each` with an expectation' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each { |user| expect(user).to be_valid }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using the `all` matcher instead of iterating over an array.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `each` when expectation calls method with arguments' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each { |user| expect(user).to be_a(User) }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using the `all` matcher instead of iterating over an array.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `each` without expectation' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each { |user| allow(user).to receive(:method) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `each` with multiple expectations' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each do |user|
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using the `all` matcher instead of iterating over an array.
|
||||
expect(user).to receive(:method)
|
||||
expect(user).to receive(:other_method)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignore `each` when the body does not contain only expectations' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each do |user|
|
||||
allow(Something).to receive(:method).and_return(user)
|
||||
expect(user).to receive(:method)
|
||||
expect(user).to receive(:other_method)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `each` with expectation on property' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each { |user| expect(user.name).to be }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores assignments in the iteration' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each { |user| array = array.concat(user) }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores `each` when there is a negative expectation' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'validates users' do
|
||||
[user1, user2, user3].each do |user|
|
||||
expect(user).not_to receive(:method)
|
||||
expect(user).to receive(:other_method)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,135 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::LeadingSubject do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks subject below let' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
|
||||
subject { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Declare `subject` above any other `let` declarations.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks subject below let!' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let!(:params) { foo }
|
||||
|
||||
subject { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Declare `subject` above any other `let!` declarations.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of subject above let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
context 'blah' do
|
||||
end
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
let(:params) { foo }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles subjects in contexts' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
|
||||
context "when something happens" do
|
||||
subject { described_class.new }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles subjects in tests' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
# This shouldn't really ever happen in a sane codebase but I still
|
||||
# want to avoid false positives
|
||||
it "doesn't mind me calling a method called subject in the test" do
|
||||
let(foo)
|
||||
subject { bar }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks subject below hook' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
before { allow(Foo).to receive(:bar) }
|
||||
|
||||
subject { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Declare `subject` above any other `before` declarations.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks subject below example' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
it { is_expected.to be_present }
|
||||
|
||||
subject { described_class.new }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Declare `subject` above any other `it` declarations.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
before { allow(Foo).to receive(:bar) }
|
||||
let(:params) { foo }
|
||||
let(:bar) { baz }
|
||||
|
||||
subject { described_class.new }
|
||||
it { is_expected.to do_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
before { allow(Foo).to receive(:bar) }
|
||||
let(:params) { foo }
|
||||
let(:bar) { baz }
|
||||
|
||||
it { is_expected.to do_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code, good_code
|
||||
|
||||
bad_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:params) { foo }
|
||||
let(:bar) { baz }
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
it { is_expected.to do_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
let(:params) { foo }
|
||||
let(:bar) { baz }
|
||||
it { is_expected.to do_something }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code, good_code
|
||||
end
|
||||
@ -1,136 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::LetBeforeExamples do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags `let` after `it`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
it { is_expected.to be_after_let }
|
||||
let(:foo) { bar }
|
||||
^^^^^^^^^^^^^^^^^ Move `let` before the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `let` after `context`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
context 'a context' do
|
||||
it { is_expected.to be_after_let }
|
||||
end
|
||||
|
||||
let(:foo) { bar }
|
||||
^^^^^^^^^^^^^^^^^ Move `let` before the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags `let` after `include_examples`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_examples('should be after let')
|
||||
|
||||
let(:foo) { bar }
|
||||
^^^^^^^^^^^^^^^^^ Move `let` before the examples in the group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag `let` before the examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:foo) { bar }
|
||||
|
||||
it { is_expected.to be_after_let }
|
||||
|
||||
context 'a context' do
|
||||
it { is_expected.to work }
|
||||
end
|
||||
|
||||
include_examples('everything is fine')
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag `let` in a nested context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:foo) { bar }
|
||||
|
||||
context 'something else' do
|
||||
let(:foo) { baz }
|
||||
it { is_expected.to work }
|
||||
end
|
||||
|
||||
include_examples('everything is fine')
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows inclusion of context before `let`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_context 'special user'
|
||||
|
||||
let(:foo) { bar }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores single-line example blocks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
include_examples 'special user' do
|
||||
let(:foo) { bar }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
bad_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
include_examples('should be after let')
|
||||
context 'another one' do
|
||||
let(:foo) { baz }
|
||||
include_examples('should be ok')
|
||||
end
|
||||
|
||||
let(:foo) { bar }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:foo) { bar }
|
||||
include_examples('should be after let')
|
||||
context 'another one' do
|
||||
let(:foo) { baz }
|
||||
include_examples('should be ok')
|
||||
end
|
||||
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code, good_code
|
||||
|
||||
bad_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
include_examples('should be after let')
|
||||
|
||||
let(:foo) { (<<-SOURCE) }
|
||||
some long text here
|
||||
SOURCE
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code = <<-RUBY
|
||||
RSpec.describe User do
|
||||
let(:foo) { (<<-SOURCE) }
|
||||
some long text here
|
||||
SOURCE
|
||||
include_examples('should be after let')
|
||||
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code, good_code
|
||||
end
|
||||
@ -1,66 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::LetSetup do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'complains when let! is used and not referenced' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
let!(:foo) { bar }
|
||||
^^^^^^^^^^ Do not use `let!` for test setup.
|
||||
|
||||
it 'does not use foo' do
|
||||
expect(baz).to eq(qux)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores let! when used in `before`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
let!(:foo) { bar }
|
||||
|
||||
before do
|
||||
foo
|
||||
end
|
||||
|
||||
it 'does not use foo' do
|
||||
expect(baz).to eq(qux)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores let! when used in example' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
let!(:foo) { bar }
|
||||
|
||||
it 'uses foo' do
|
||||
foo
|
||||
expect(baz).to eq(qux)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'complains when let! is used and not referenced within nested group' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
context 'when something special happens' do
|
||||
let!(:foo) { bar }
|
||||
^^^^^^^^^^ Do not use `let!` for test setup.
|
||||
|
||||
it 'does not use foo' do
|
||||
expect(baz).to eq(qux)
|
||||
end
|
||||
end
|
||||
|
||||
it 'references some other foo' do
|
||||
foo
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,21 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::MessageChain do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'finds `receive_message_chain`' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain(:one, :two) { :three }
|
||||
^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `receive_message_chain`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds old `stub_chain` syntax' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
foo.stub_chain(:one, :two).and_return(:three)
|
||||
^^^^^^^^^^ Avoid stubbing using `stub_chain`.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,45 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::MessageExpectation, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'when EnforcedStyle is allow' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'allow' }
|
||||
end
|
||||
|
||||
it 'flags expect(...).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar)
|
||||
^^^^^^ Prefer `allow` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of allow(...).to receive' do
|
||||
expect_no_offenses('allow(foo).to receive(:bar)')
|
||||
end
|
||||
|
||||
include_examples 'detects style', 'allow(foo).to receive(:bar)', 'allow'
|
||||
include_examples 'detects style', 'expect(foo).to receive(:bar)', 'expect'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is expect' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'expect' }
|
||||
end
|
||||
|
||||
it 'flags allow(...).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
allow(foo).to receive(:bar)
|
||||
^^^^^ Prefer `expect` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of expect(...).to receive' do
|
||||
expect_no_offenses('expect(foo).to receive(:bar)')
|
||||
end
|
||||
|
||||
include_examples 'detects style', 'expect(foo).to receive(:bar)', 'expect'
|
||||
include_examples 'detects style', 'allow(foo).to receive(:bar)', 'allow'
|
||||
end
|
||||
end
|
||||
@ -1,151 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::MessageSpies, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'when EnforcedStyle is have_received' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'have_received' }
|
||||
end
|
||||
|
||||
it 'flags expect(send).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(lvar).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
foo = baz
|
||||
expect(foo).to receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(ivar).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(@foo).to receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `@foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(const).to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(Foo).to receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `Foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).not_to receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).not_to receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to_not receive' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to_not receive(:bar)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to receive with' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).with(:baz)
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to receive at_most' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).at_most(42).times
|
||||
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of expect(...).to have_received' do
|
||||
expect_no_offenses('expect(foo).to have_received(:bar)')
|
||||
end
|
||||
|
||||
include_examples 'detects style', 'expect(foo).to receive(:bar)', 'receive'
|
||||
|
||||
include_examples 'detects style',
|
||||
'expect(foo).to have_received(:bar)',
|
||||
'have_received'
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is receive' do
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => 'receive' }
|
||||
end
|
||||
|
||||
it 'flags expect(send).to have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(lvar).to have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
foo = baz
|
||||
expect(foo).to have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(ivar).to have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(@foo).to have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(const).to have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(Foo).to have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).not_to have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).not_to have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to_not have_received' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to_not have_received(:bar)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to have_received with' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to have_received(:bar).with(:baz)
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags expect(...).to have_received at_most' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to have_received(:bar).at_most(42).times
|
||||
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of expect(...).to receive' do
|
||||
expect_no_offenses('expect(foo).to receive(:bar)')
|
||||
end
|
||||
|
||||
include_examples 'detects style', 'expect(foo).to receive(:bar)', 'receive'
|
||||
|
||||
include_examples 'detects style',
|
||||
'expect(foo).to have_received(:bar)',
|
||||
'have_received'
|
||||
end
|
||||
end
|
||||
@ -1,55 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::MissingExampleGroupArgument do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'accepts describe with an argument' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe FooClass do
|
||||
end
|
||||
|
||||
RSpec.describe FooClass do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts methods with a name like an example block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
Scenario.context do
|
||||
'static'
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks first argument of describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe do
|
||||
^^^^^^^^^^^ The first argument to `describe` should not be empty.
|
||||
end
|
||||
|
||||
RSpec.describe do
|
||||
^^^^^^^^^^^^^^^^^ The first argument to `describe` should not be empty.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks first argument of nested describe' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe FooClass do
|
||||
describe do
|
||||
^^^^^^^^^^^ The first argument to `describe` should not be empty.
|
||||
end
|
||||
|
||||
RSpec.describe do
|
||||
^^^^^^^^^^^^^^^^^ The first argument to `describe` should not be empty.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks first argument of context' do
|
||||
expect_offense(<<-RUBY)
|
||||
context do
|
||||
^^^^^^^^^^ The first argument to `context` should not be empty.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,28 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::MultipleDescribes do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'finds multiple top level describes with class and method' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass, '.do_something' do; end
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use multiple top level describes - try to nest them.
|
||||
describe MyClass, '.do_something_else' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds multiple top level describes only with class' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do; end
|
||||
^^^^^^^^^^^^^^^^ Do not use multiple top level describes - try to nest them.
|
||||
describe MyOtherClass do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'skips single top level describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
require 'spec_helper'
|
||||
|
||||
describe MyClass do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,234 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::MultipleExpectations, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'without configuration' do
|
||||
let(:cop_config) { {} }
|
||||
|
||||
it 'flags multiple expectations' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'approves of one expectation per example' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'does something neat' do
|
||||
expect(neat).to be(true)
|
||||
end
|
||||
|
||||
it 'does something cool' do
|
||||
expect(cool).to be(true)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags multiple expect_any_instance_of' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect_any_instance_of twice' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
expect_any_instance_of(Foo).to receive(:bar)
|
||||
expect_any_instance_of(Foo).to receive(:baz)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags multiple is_expected' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect_any_instance_of twice' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
is_expected.to receive(:bar)
|
||||
is_expected.to receive(:baz)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags multiple expects with blocks' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect with block twice' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
expect { something }.to change(Foo.count)
|
||||
expect { something }.to change(Bar.count)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'counts aggregate_failures as one expectation' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'aggregates failures' do
|
||||
aggregate_failures do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'counts every aggregate_failures as an expectation' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'has multiple aggregate_failures calls' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
aggregate_failures do
|
||||
end
|
||||
aggregate_failures do
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with meta data' do
|
||||
it 'ignores examples with `:aggregate_failures`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', :aggregate_failures do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores examples with `aggregate_failures: true`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', aggregate_failures: true do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks examples with `aggregate_failures: false`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', aggregate_failures: false do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with Max configuration' do
|
||||
let(:cop_config) do
|
||||
{ 'Max' => '2' }
|
||||
end
|
||||
|
||||
it 'permits two expectations' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice' do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags three expectations' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect three times' do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [3/2].
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
expect(qux).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with AggregateFailuresByDefault configuration' do
|
||||
let(:cop_config) do
|
||||
{ 'AggregateFailuresByDefault' => true }
|
||||
end
|
||||
|
||||
it 'ignores examples without metadata' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice' do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores examples with `:aggregate_failures`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', :aggregate_failures do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores examples with `aggregate_failures: true`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', aggregate_failures: true do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks examples with `aggregate_failures: false`' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
it 'uses expect twice', aggregate_failures: false do
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
it 'generates a todo based on the worst violation' do
|
||||
inspect_source(<<-RUBY, 'spec/foo_spec.rb')
|
||||
describe Foo do
|
||||
it 'uses expect twice' do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
end
|
||||
|
||||
it 'uses expect three times' do
|
||||
expect(foo).to eq(bar)
|
||||
expect(baz).to eq(bar)
|
||||
expect(qux).to eq(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.config_to_allow_offenses[:exclude_limit]).to eq('Max' => 3)
|
||||
end
|
||||
end
|
||||
@ -1,96 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::MultipleSubjects do
|
||||
let(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for every overwritten subject' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'hello there' do
|
||||
subject(:foo) { 1 }
|
||||
^^^^^^^^^^^^^^^^^^^ Do not set more than one subject per example group
|
||||
subject(:bar) { 2 }
|
||||
^^^^^^^^^^^^^^^^^^^ Do not set more than one subject per example group
|
||||
subject { 3 }
|
||||
^^^^^^^^^^^^^ Do not set more than one subject per example group
|
||||
subject(:baz) { 4 }
|
||||
|
||||
describe 'baz' do
|
||||
subject(:norf) { 1 }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not try to autocorrect subject!' do
|
||||
source = <<-RUBY
|
||||
describe Foo do
|
||||
subject! { a }
|
||||
subject! { b }
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(autocorrect_source(source, 'example_spec.rb')).to eql(source)
|
||||
end
|
||||
|
||||
it 'does not flag shared example groups' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
it_behaves_like 'user' do
|
||||
subject { described_class.new(user, described_class) }
|
||||
|
||||
it { expect(subject).not_to be_accessible }
|
||||
end
|
||||
|
||||
it_behaves_like 'admin' do
|
||||
subject { described_class.new(user, described_class) }
|
||||
|
||||
it { expect(subject).to be_accessible }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
<<-RUBY,
|
||||
describe 'hello there' do
|
||||
subject(:foo) { 1 }
|
||||
subject(:bar) { 2 }
|
||||
subject(:baz) { 3 }
|
||||
|
||||
describe 'baz' do
|
||||
subject(:norf) { 1 }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
<<-RUBY
|
||||
describe 'hello there' do
|
||||
let(:foo) { 1 }
|
||||
let(:bar) { 2 }
|
||||
subject(:baz) { 3 }
|
||||
|
||||
describe 'baz' do
|
||||
subject(:norf) { 1 }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
)
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
<<-RUBY.strip_indent.chomp,
|
||||
describe 'hello there' do
|
||||
subject { 1 }
|
||||
subject { 2 }
|
||||
subject { 3 }
|
||||
end
|
||||
RUBY
|
||||
[
|
||||
"describe 'hello there' do",
|
||||
' ',
|
||||
' ',
|
||||
' subject { 3 }',
|
||||
'end'
|
||||
].join("\n")
|
||||
)
|
||||
end
|
||||
@ -1,62 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::NamedSubject do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'checks `it` and `specify` for explicit subject usage' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
|
||||
it "is valid" do
|
||||
expect(subject.valid?).to be(true)
|
||||
^^^^^^^ Name your test subject if you need to reference it explicitly.
|
||||
end
|
||||
|
||||
specify do
|
||||
expect(subject.valid?).to be(true)
|
||||
^^^^^^^ Name your test subject if you need to reference it explicitly.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks before and after for explicit subject usage' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
|
||||
before(:each) do
|
||||
do_something_with(subject)
|
||||
^^^^^^^ Name your test subject if you need to reference it explicitly.
|
||||
end
|
||||
|
||||
after do
|
||||
do_something_with(subject)
|
||||
^^^^^^^ Name your test subject if you need to reference it explicitly.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'checks around(:each) for explicit subject usage' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { described_class.new }
|
||||
|
||||
around(:each) do |test|
|
||||
do_something_with(subject)
|
||||
^^^^^^^ Name your test subject if you need to reference it explicitly.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores subject when not wrapped inside a test' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
def foo
|
||||
it(subject)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,81 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::NestedGroups, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
it 'flags nested contexts' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
context 'when foo' do
|
||||
context 'when bar' do
|
||||
context 'when baz' do
|
||||
^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded [4/3].
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when qux' do
|
||||
context 'when norf' do
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'support --auto-gen-config' do
|
||||
inspect_source(<<-RUBY, 'spec/foo_spec.rb')
|
||||
describe MyClass do
|
||||
context 'when foo' do
|
||||
context 'when bar' do
|
||||
context 'when baz' do
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.config_to_allow_offenses[:exclude_limit]).to eq('Max' => 4)
|
||||
end
|
||||
|
||||
it 'ignores non-spec context methods' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
class MyThingy
|
||||
context 'this is not rspec' do
|
||||
context 'but it uses contexts' do
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when Max is configured as 2' do
|
||||
let(:cop_config) { { 'Max' => '2' } }
|
||||
|
||||
it 'flags two levels of nesting' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe MyClass do
|
||||
context 'when foo' do
|
||||
context 'when bar' do
|
||||
^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded [3/2].
|
||||
context 'when baz' do
|
||||
^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded [4/2].
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when configured with MaxNesting' do
|
||||
let(:cop_config) { { 'MaxNesting' => '1' } }
|
||||
|
||||
it 'emits a deprecation warning' do
|
||||
expect { inspect_source('describe(Foo) { }', 'foo_spec.rb') }
|
||||
.to output(
|
||||
'Configuration key `MaxNesting` for RSpec/NestedGroups is ' \
|
||||
"deprecated in favor of `Max`. Please use that instead.\n"
|
||||
).to_stderr
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,87 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::NotToNot, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'when EnforcedStyle is `not_to`' do
|
||||
let(:cop_config) { { 'EnforcedStyle' => 'not_to' } }
|
||||
|
||||
it 'detects the `to_not` offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(false).to_not be_true }
|
||||
^^^^^^ Prefer `not_to` over `to_not`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects the `to_not` offense on an expect block' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect {
|
||||
2 + 2
|
||||
}.to_not raise_error
|
||||
^^^^^^ Prefer `not_to` over `to_not`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects no offense when using `not_to`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(false).not_to be_true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { expect(0).to_not equal 1 }',
|
||||
'it { expect(0).not_to equal 1 }'
|
||||
|
||||
original = <<-RUBY
|
||||
expect {
|
||||
2 + 2
|
||||
}.to_not raise_error
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
expect {
|
||||
2 + 2
|
||||
}.not_to raise_error
|
||||
RUBY
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
|
||||
context 'when AcceptedMethod is `to_not`' do
|
||||
let(:cop_config) { { 'EnforcedStyle' => 'to_not' } }
|
||||
|
||||
it 'detects the `not_to` offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { expect(false).not_to be_true }
|
||||
^^^^^^ Prefer `to_not` over `not_to`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects the `not_to` offense on an expect block' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect {
|
||||
2 + 2
|
||||
}.not_to raise_error
|
||||
^^^^^^ Prefer `to_not` over `not_to`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'detects no offense when using `to_not`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { expect(false).to_not be_true }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { expect(0).not_to equal 1 }',
|
||||
'it { expect(0).to_not equal 1 }'
|
||||
|
||||
original = <<-RUBY
|
||||
expect {
|
||||
2 + 2
|
||||
}.not_to raise_error
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
expect {
|
||||
2 + 2
|
||||
}.to_not raise_error
|
||||
RUBY
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
end
|
||||
@ -1,89 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::OverwritingSetup do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'finds overwriten `let`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
let(:a) { b }
|
||||
^^^^^^^^^^^^^ `a` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds overwriten `subject`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject(:a) { a }
|
||||
|
||||
let(:a) { b }
|
||||
^^^^^^^^^^^^^ `a` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'works with `subject!` and `let!`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject!(:a) { a }
|
||||
|
||||
let!(:a) { b }
|
||||
^^^^^^^^^^^^^^ `a` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds `let!` overwriting `let`' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { b }
|
||||
let!(:a) { b }
|
||||
^^^^^^^^^^^^^^ `a` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores overwriting in different context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
|
||||
context `different` do
|
||||
let(:a) { b }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles unnamed subjects' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { a }
|
||||
|
||||
let(:subject) { b }
|
||||
^^^^^^^^^^^^^^^^^^^ `subject` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles dynamic names for `let`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject(:name) { a }
|
||||
|
||||
let(name) { b }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles string arguments' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject(:name) { a }
|
||||
|
||||
let("name") { b }
|
||||
^^^^^^^^^^^^^^^^^ `name` is already defined.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,176 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::Pending do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags xcontext' do
|
||||
expect_offense(<<-RUBY)
|
||||
xcontext 'test' do
|
||||
^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xdescribe' do
|
||||
expect_offense(<<-RUBY)
|
||||
xdescribe 'test' do
|
||||
^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xexample' do
|
||||
expect_offense(<<-RUBY)
|
||||
xexample 'test' do
|
||||
^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xfeature' do
|
||||
expect_offense(<<-RUBY)
|
||||
xfeature 'test' do
|
||||
^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xit' do
|
||||
expect_offense(<<-RUBY)
|
||||
xit 'test' do
|
||||
^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xscenario' do
|
||||
expect_offense(<<-RUBY)
|
||||
xscenario 'test' do
|
||||
^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags xspecify' do
|
||||
expect_offense(<<-RUBY)
|
||||
xspecify 'test' do
|
||||
^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags skip inside of an it' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'test' do
|
||||
skip
|
||||
^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags skip blocks' do
|
||||
expect_offense(<<-RUBY)
|
||||
skip 'test' do
|
||||
^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags blocks with skip symbol metadata' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'test', :skip do
|
||||
^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags blocks with pending symbol metadata' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'test', :pending do
|
||||
^^^^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags blocks with skip: true metadata' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'test', skip: true do
|
||||
^^^^^^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags pending blocks' do
|
||||
expect_offense(<<-RUBY)
|
||||
pending 'test' do
|
||||
^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags pending examples when receiver is explicit' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.xit 'test' do
|
||||
^^^^^^^^^^^^^^^^ Pending spec found.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag describe' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag example' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
example 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag scenario' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
scenario 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag specify' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
specify 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag feature' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
feature 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
context 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag it' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag it with skip: false metadata' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'test', skip: false do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag example_group' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
example_group 'test' do; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag method called pending' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
subject { Project.pending }
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,339 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::PredicateMatcher, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style,
|
||||
'Strict' => strict }
|
||||
end
|
||||
|
||||
context 'when enforced style is `inflected`' do
|
||||
let(:enforced_style) { 'inflected' }
|
||||
|
||||
shared_examples 'inflected common' do
|
||||
it 'registers an offense for a predicate method in actual' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo.empty?).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).not_to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).to_not be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).to be_falsey
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.has_something?).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `have_something` matcher over `has_something?`.
|
||||
expect(foo.include?(something)).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `include` matcher over `include?`.
|
||||
expect(foo.respond_to?(:bar)).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `respond_to` matcher over `respond_to?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a predicate method with argument' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo.something?('foo')).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_something` matcher over `something?`.
|
||||
expect(foo.something?('foo', 'bar')).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_something` matcher over `something?`.
|
||||
expect(foo.has_key?('foo')).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `have_key` matcher over `has_key?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a predicate method with a block' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo.all?(&:present?)).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_all` matcher over `all?`.
|
||||
expect(foo.all? { |x| x.present? }).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_all` matcher over `all?`.
|
||||
expect(foo.all? { present }).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_all` matcher over `all?`.
|
||||
expect(foo.something?(x) { |y| y.present? }).to be_truthy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_something` matcher over `something?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts a predicate method that is not ckeced true/false' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo.something?).to eq "something"
|
||||
expect(foo.has_something?).to eq "something"
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts non-predicate method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo.something).to be(true)
|
||||
expect(foo.has_something).to be(true)
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to be_truthy',
|
||||
'expect(foo).to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).not_to be_truthy',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to_not be_truthy',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to be_falsey',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).not_to be_falsey',
|
||||
'expect(foo).to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).not_to a_truthy_value',
|
||||
'expect(foo).not_to be_empty'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.is_a?(Array)).to be_truthy',
|
||||
'expect(foo).to be_a(Array)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.instance_of?(Array)).to be_truthy',
|
||||
'expect(foo).to be_an_instance_of(Array)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.has_something?).to be_truthy',
|
||||
'expect(foo).to have_something'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.has_something?).not_to be_truthy',
|
||||
'expect(foo).not_to have_something'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.include?(something)).to be_truthy',
|
||||
'expect(foo).to include(something)'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.respond_to?(:bar)).to be_truthy',
|
||||
'expect(foo).to respond_to(:bar)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.something?()).to be_truthy',
|
||||
'expect(foo).to be_something()'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.something? 1, 2).to be_truthy',
|
||||
'expect(foo).to be_something 1, 2'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.has_key?("foo")).to be_truthy',
|
||||
'expect(foo).to have_key("foo")'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.something?(1, 2)).to be_truthy',
|
||||
'expect(foo).to be_something(1, 2)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.all? { |x| x.present? }).to be_truthy',
|
||||
'expect(foo).to be_all { |x| x.present? }'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.all?(n) { |x| x.present? }).to be_truthy',
|
||||
'expect(foo).to be_all(n) { |x| x.present? }'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.all? { present }).to be_truthy',
|
||||
'expect(foo).to be_all { present }'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.all? { }).to be_truthy',
|
||||
'expect(foo).to be_all { }'
|
||||
include_examples 'autocorrect',
|
||||
<<-BEFORE, <<-AFTER
|
||||
expect(foo.all? do |x|
|
||||
x + 1
|
||||
x >= 2
|
||||
end).to be_truthy
|
||||
BEFORE
|
||||
expect(foo).to be_all do |x|
|
||||
x + 1
|
||||
x >= 2
|
||||
end
|
||||
AFTER
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.all? do; end).to be_truthy',
|
||||
'expect(foo).to be_all do; end'
|
||||
end
|
||||
|
||||
context 'when strict is true' do
|
||||
let(:strict) { true }
|
||||
|
||||
include_examples 'inflected common'
|
||||
|
||||
it 'accepts strict checking boolean matcher' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo.empty?).to eq(true)
|
||||
expect(foo.empty?).to be(true)
|
||||
expect(foo.empty?).to be(false)
|
||||
expect(foo.empty?).not_to be true
|
||||
expect(foo.empty?).not_to be false
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when strict is false' do
|
||||
let(:strict) { false }
|
||||
|
||||
include_examples 'inflected common'
|
||||
|
||||
it 'registers an offense for a predicate method in actual' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo.empty?).to eq(true)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).to be(true)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).to be(false)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).not_to be true
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
expect(foo.empty?).not_to be false
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `be_empty` matcher over `empty?`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to eq(true)',
|
||||
'expect(foo).to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to eq(false)',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to be(true)',
|
||||
'expect(foo).to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).to be(false)',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).not_to be(true)',
|
||||
'expect(foo).not_to be_empty'
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo.empty?).not_to be(false)',
|
||||
'expect(foo).to be_empty'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when enforced style is `explicit`' do
|
||||
let(:enforced_style) { 'explicit' }
|
||||
|
||||
shared_examples 'explicit common' do
|
||||
it 'registers an offense for a predicate mather' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to be_empty
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `empty?` over `be_empty` matcher.
|
||||
expect(foo).not_to be_empty
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `empty?` over `be_empty` matcher.
|
||||
expect(foo).to have_something
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `has_something?` over `have_something` matcher.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a predicate mather with argument' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to be_something(1, 2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `something?` over `be_something` matcher.
|
||||
expect(foo).to have_key(1)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `has_key?` over `have_key` matcher.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for a predicate matcher with a block' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to be_all(&:present?)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `all?` over `be_all` matcher.
|
||||
expect(foo).to be_all { |x| x.present? }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `all?` over `be_all` matcher.
|
||||
expect(foo).to be_all { present }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `all?` over `be_all` matcher.
|
||||
expect(foo).to be_something(x) { |y| y.present? }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `something?` over `be_something` matcher.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts built in matchers' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to be_truthy
|
||||
expect(foo).to be_falsey
|
||||
expect(foo).to be_falsy
|
||||
expect(foo).to have_attributes(name: 'foo')
|
||||
expect(foo).to have_received(:foo)
|
||||
expect(foo).to be_between(1, 10)
|
||||
expect(foo).to be_within(0.1).of(10.0)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts non-predicate matcher' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to be(true)
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'explicit autocorrect' do |matcher_true, matcher_false|
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_something',
|
||||
"expect(foo.something?).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).not_to be_something',
|
||||
"expect(foo.something?).to #{matcher_false}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to have_something',
|
||||
"expect(foo.has_something?).to #{matcher_true}"
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_a(Array)',
|
||||
"expect(foo.is_a?(Array)).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_instance_of(Array)',
|
||||
"expect(foo.instance_of?(Array)).to #{matcher_true}"
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_something()',
|
||||
"expect(foo.something?()).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_something(1)',
|
||||
"expect(foo.something?(1)).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_something(1, 2)',
|
||||
"expect(foo.something?(1, 2)).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_something 1, 2',
|
||||
"expect(foo.something? 1, 2).to #{matcher_true}"
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_all { |x| x.present? }',
|
||||
"expect(foo.all? { |x| x.present? }).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_all(n) { |x| x.ok? }',
|
||||
"expect(foo.all?(n) { |x| x.ok? }).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_all { present }',
|
||||
"expect(foo.all? { present }).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_all { }',
|
||||
"expect(foo.all? { }).to #{matcher_true}"
|
||||
include_examples 'autocorrect',
|
||||
<<-BEFORE, <<-AFTER
|
||||
expect(foo).to be_all do |x|
|
||||
x + 1
|
||||
x >= 2
|
||||
end
|
||||
BEFORE
|
||||
expect(foo.all? do |x|
|
||||
x + 1
|
||||
x >= 2
|
||||
end).to #{matcher_true}
|
||||
AFTER
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to be_all do; end',
|
||||
"expect(foo.all? do; end).to #{matcher_true}"
|
||||
end
|
||||
|
||||
context 'when strict is true' do
|
||||
let(:strict) { true }
|
||||
|
||||
include_examples 'explicit common'
|
||||
include_examples 'explicit autocorrect', 'be(true)', 'be(false)'
|
||||
end
|
||||
|
||||
context 'when strict is false' do
|
||||
let(:strict) { false }
|
||||
|
||||
include_examples 'explicit common'
|
||||
include_examples 'explicit autocorrect', 'be_truthy', 'be_falsey'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,90 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::Rails::HttpStatus, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
context 'when EnforcedStyle is `symbolic`' do
|
||||
let(:cop_config) { { 'EnforcedStyle' => 'symbolic' } }
|
||||
|
||||
it 'registers an offense when using numeric value' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.to have_http_status 200 }
|
||||
^^^ Prefer `:ok` over `200` to describe HTTP status code.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using symbolic value' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { is_expected.to have_http_status :ok }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using custom HTTP code' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { is_expected.to have_http_status 550 }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status 200 }',
|
||||
'it { is_expected.to have_http_status :ok }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status 404 }',
|
||||
'it { is_expected.to have_http_status :not_found }'
|
||||
|
||||
context 'with parenthesis' do
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status(200) }',
|
||||
'it { is_expected.to have_http_status(:ok) }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status(404) }',
|
||||
'it { is_expected.to have_http_status(:not_found) }'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when EnforcedStyle is `numeric`' do
|
||||
let(:cop_config) { { 'EnforcedStyle' => 'numeric' } }
|
||||
|
||||
it 'registers an offense when using symbolic value' do
|
||||
expect_offense(<<-RUBY)
|
||||
it { is_expected.to have_http_status :ok }
|
||||
^^^ Prefer `200` over `:ok` to describe HTTP status code.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using numeric value' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { is_expected.to have_http_status 200 }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using whitelisted symbols' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it { is_expected.to have_http_status :error }
|
||||
it { is_expected.to have_http_status :success }
|
||||
it { is_expected.to have_http_status :missing }
|
||||
it { is_expected.to have_http_status :redirect }
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status :ok }',
|
||||
'it { is_expected.to have_http_status 200 }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status :not_found }',
|
||||
'it { is_expected.to have_http_status 404 }'
|
||||
|
||||
context 'with parenthesis' do
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status(:ok) }',
|
||||
'it { is_expected.to have_http_status(200) }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it { is_expected.to have_http_status(:not_found) }',
|
||||
'it { is_expected.to have_http_status(404) }'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,88 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ReceiveCounts do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags usage of `exactly(1).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(1).times
|
||||
^^^^^^^^^^^^^^^^^ Use `.once` instead of `.exactly(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `exactly(2).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(2).times
|
||||
^^^^^^^^^^^^^^^^^ Use `.twice` instead of `.exactly(2).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `exactly(3).times`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(3).times
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows `exactly(n).times`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(n).times
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `exactly(1).times` after `with`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).with(baz).exactly(1).times
|
||||
^^^^^^^^^^^^^^^^^ Use `.once` instead of `.exactly(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `exactly(1).times` with return value' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(1).times.and_return(true)
|
||||
^^^^^^^^^^^^^^^^^ Use `.once` instead of `.exactly(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `exactly(1).times` with a block' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).exactly(1).times { true }
|
||||
^^^^^^^^^^^^^^^^^ Use `.once` instead of `.exactly(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `at_least(1).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).at_least(1).times
|
||||
^^^^^^^^^^^^^^^^^^ Use `.at_least(:once)` instead of `.at_least(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `at_least(2).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).at_least(2).times
|
||||
^^^^^^^^^^^^^^^^^^ Use `.at_least(:twice)` instead of `.at_least(2).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `at_most(1).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).at_most(1).times
|
||||
^^^^^^^^^^^^^^^^^ Use `.at_most(:once)` instead of `.at_most(1).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `at_most(2).times`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).at_most(2).times
|
||||
^^^^^^^^^^^^^^^^^ Use `.at_most(:twice)` instead of `.at_most(2).times`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to receive(:bar).exactly(1).times { true }',
|
||||
'expect(foo).to receive(:bar).once { true }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to receive(:bar).at_least(2).times { true }',
|
||||
'expect(foo).to receive(:bar).at_least(:twice) { true }'
|
||||
end
|
||||
@ -1,45 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::ReceiveNever do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags usage of `never`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).never
|
||||
^^^^^ Use `not_to receive` instead of `never`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `never` after `with`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect(foo).to receive(:bar).with(baz).never
|
||||
^^^^^ Use `not_to receive` instead of `never`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `never` with `is_expected`' do
|
||||
expect_offense(<<-RUBY)
|
||||
is_expected.to receive(:bar).with(baz).never
|
||||
^^^^^ Use `not_to receive` instead of `never`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags usage of `never` with `expect_any_instance_of`' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect_any_instance_of(Foo).to receive(:bar).with(baz).never
|
||||
^^^^^ Use `not_to receive` instead of `never`.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows method called `never`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect(foo).to receive(:bar).with(Value.never)
|
||||
expect(foo.never).to eq(bar.never)
|
||||
is_expected.to be never
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'expect(foo).to receive(:bar).with(0).never',
|
||||
'expect(foo).not_to receive(:bar).with(0)'
|
||||
end
|
||||
@ -1,76 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::RepeatedDescription do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for repeated descriptions' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
^^^^^^^^^^^ Don't repeat descriptions within an example group.
|
||||
end
|
||||
|
||||
it "does x" do
|
||||
^^^^^^^^^^^ Don't repeat descriptions within an example group.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers offense for repeated descriptions separated by a context' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
^^^^^^^^^^^ Don't repeat descriptions within an example group.
|
||||
end
|
||||
|
||||
context 'during some use case' do
|
||||
it "does x" do
|
||||
# this should be fine
|
||||
end
|
||||
end
|
||||
|
||||
it "does x" do
|
||||
^^^^^^^^^^^ Don't repeat descriptions within an example group.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores descriptions repeated in a shared context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
end
|
||||
|
||||
shared_context 'shared behavior' do
|
||||
it "does x" do
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores repeated descriptions in a nested context' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
end
|
||||
|
||||
context 'in a certain use case' do
|
||||
it "does x" do
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag tests which do not contain description strings' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it { foo }
|
||||
it { bar }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,74 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::RepeatedExample do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense for repeated example' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
^^^^^^^^^^^^^^ Don't repeat examples within an example group.
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
|
||||
it "does y" do
|
||||
^^^^^^^^^^^^^^ Don't repeat examples within an example group.
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register a violation if rspec tag magic is involved' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
|
||||
it "does y", :focus do
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag examples with different implementations' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
expect(foo).to have_attribute(foo: 1)
|
||||
end
|
||||
|
||||
it "does y" do
|
||||
expect(foo).to have_attribute(bar: 2)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag examples when different its arguments are used' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
its(:x) { is_expected.to be_present }
|
||||
its(:y) { is_expected.to be_present }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag repeated examples in different scopes' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe 'doing x' do
|
||||
it "does x" do
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
|
||||
context 'when the scope changes' do
|
||||
it 'does not flag anything' do
|
||||
expect(foo).to be(bar)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,266 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ReturnFromStub, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
let(:cop_config) do
|
||||
{ 'EnforcedStyle' => enforced_style }
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `and_return`' do
|
||||
let(:enforced_style) { 'and_return' }
|
||||
|
||||
it 'finds static values returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { 42 }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds empty values returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) {}
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds array with only static values returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { [42, 43] }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds hash with only static values returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { {a: 42, b: 43} }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds static values in a block when there are chained methods' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Question).to receive(:meaning).with(:universe) { 42 }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds constants returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { Life::MEANING }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds nested constants returned from block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { {Life::MEANING => 42} }
|
||||
^ Use `and_return` for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores dynamic values returned from block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { baz }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores variables return from block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
$bar = 42
|
||||
baz = 123
|
||||
allow(Foo).to receive(:bar) { $bar }
|
||||
allow(Foo).to receive(:baz) { baz }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores array with dynamic values returned from block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { [42, baz] }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores hash with dynamic values returned from block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) { {a: 42, b: baz} }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores block returning string with interpolation' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
bar = 42
|
||||
allow(Foo).to receive(:bar) { "You called \#{bar}" }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds concatenated strings with no variables' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar) do
|
||||
^^ Use `and_return` for static values.
|
||||
"You called" \
|
||||
"me"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores stubs without return value' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'handles stubs in a method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
def stub_foo
|
||||
allow(Foo).to receive(:bar)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar) { 42 }',
|
||||
'allow(Foo).to receive(:bar).and_return(42)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar) { { foo: 42 } }',
|
||||
'allow(Foo).to receive(:bar).and_return({ foo: 42 })'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).with(1) { 42 }',
|
||||
'allow(Foo).to receive(:bar).with(1).and_return(42)'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar) {}',
|
||||
'allow(Foo).to receive(:bar).and_return(nil)'
|
||||
|
||||
original = <<-RUBY
|
||||
allow(Foo).to receive(:bar) do
|
||||
'You called ' \\
|
||||
'me'
|
||||
end
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
allow(Foo).to receive(:bar).and_return('You called ' \\
|
||||
'me')
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
|
||||
context 'with EnforcedStyle `block`' do
|
||||
let(:enforced_style) { 'block' }
|
||||
|
||||
it 'finds static values returned from method' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar).and_return(42)
|
||||
^^^^^^^^^^ Use block for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds static values returned from chained method' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar).with(1).and_return(42)
|
||||
^^^^^^^^^^ Use block for static values.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores dynamic values returned from method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar).and_return(baz)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores string with interpolation returned from method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
bar = 42
|
||||
allow(Foo).to receive(:bar).and_return("You called \#{bar}")
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores multiple values being returned from method' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
allow(Foo).to receive(:bar).and_return(42, 43, 44)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).and_return(42)',
|
||||
'allow(Foo).to receive(:bar) { 42 }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).with(1).and_return(foo: 42)',
|
||||
'allow(Foo).to receive(:bar).with(1) { { foo: 42 } }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).and_return({ foo: 42 })',
|
||||
'allow(Foo).to receive(:bar) { { foo: 42 } }'
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).and_return(foo: 42)',
|
||||
'allow(Foo).to receive(:bar) { { foo: 42 } }'
|
||||
|
||||
original = <<-RUBY
|
||||
allow(Foo).to receive(:bar).and_return(
|
||||
a: 42,
|
||||
b: 43
|
||||
)
|
||||
RUBY
|
||||
corrected = <<-RUBY # Not perfect, but good enough.
|
||||
allow(Foo).to receive(:bar) { { a: 42,
|
||||
b: 43 } }
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'allow(Foo).to receive(:bar).and_return(nil)',
|
||||
'allow(Foo).to receive(:bar) { nil }'
|
||||
|
||||
original = <<-RUBY
|
||||
allow(Foo).to receive(:bar).and_return('You called ' \\
|
||||
'me')
|
||||
RUBY
|
||||
corrected = <<-RUBY
|
||||
allow(Foo).to receive(:bar) { 'You called ' \\
|
||||
'me' }
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', original, corrected
|
||||
end
|
||||
end
|
||||
@ -1,26 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ScatteredLet do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags `let` after the first different node ' do
|
||||
expect_offense(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
let(:a) { a }
|
||||
subject { User }
|
||||
let(:b) { b }
|
||||
^^^^^^^^^^^^^ Group all let/let! blocks in the example group together.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'doesnt flag `let!` in the middle of multiple `let`s' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
RSpec.describe User do
|
||||
subject { User }
|
||||
|
||||
let(:a) { a }
|
||||
let!(:b) { b }
|
||||
let(:c) { c }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,96 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::ScatteredSetup do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'flags multiple hooks in the same example group' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
before { baz }
|
||||
^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags multiple hooks of the same scope with different symbols' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
before(:each) { baz }
|
||||
^^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
before(:example) { baz }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags multiple before(:all) hooks in the same example group' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
before(:all) { bar }
|
||||
^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
before(:all) { baz }
|
||||
^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag different hooks' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
after { baz }
|
||||
around { qux }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag different hook types' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
before(:all) { baz }
|
||||
before(:suite) { baz }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag hooks in different example groups' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
|
||||
describe '.baz' do
|
||||
before { baz }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag hooks in different shared contexts' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
shared_context 'one' do
|
||||
before { bar }
|
||||
end
|
||||
|
||||
shared_context 'two' do
|
||||
before { baz }
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not flag similar method names inside of examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
before { bar }
|
||||
|
||||
it 'uses an instance method called before' do
|
||||
expect(before { tricky }).to_not confuse_rubocop_rspec
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,142 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::SharedContext do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
describe 'shared_context' do
|
||||
it 'does not register an offense for empty contexts' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_context 'empty' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for shared_context with only examples' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_context 'foo' do
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `shared_examples` when you don't define context.
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `shared_context` with let' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_context 'foo' do
|
||||
let(:foo) { :bar }
|
||||
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `shared_context` with subject' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_context 'foo' do
|
||||
subject(:foo) { :bar }
|
||||
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `shared_context` with before' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_context 'foo' do
|
||||
before do
|
||||
something
|
||||
end
|
||||
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
describe 'shared_examples' do
|
||||
it 'does not register an offense for empty examples' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_examples 'empty' do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for shared_examples with only let' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_examples 'foo' do
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `shared_context` when you don't define examples.
|
||||
let(:foo) { :bar }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for shared_examples with only subject' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_examples 'foo' do
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `shared_context` when you don't define examples.
|
||||
subject(:foo) { :bar }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers an offense for shared_examples with only hooks' do
|
||||
expect_offense(<<-RUBY)
|
||||
shared_examples 'foo' do
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `shared_context` when you don't define examples.
|
||||
before do
|
||||
foo
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense for `shared_examples` with it' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
shared_examples 'foo' do
|
||||
subject(:foo) { 'foo' }
|
||||
let(:bar) { :baz }
|
||||
before { initialize }
|
||||
|
||||
it 'works' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
bad_shared_context = <<-RUBY
|
||||
shared_context 'foo' do
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_shared_context = <<-RUBY
|
||||
shared_examples 'foo' do
|
||||
it 'performs actions' do
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_shared_context,
|
||||
good_shared_context
|
||||
|
||||
bad_shared_examples = <<-RUBY
|
||||
shared_examples 'foo' do
|
||||
let(:foo) { :bar }
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_shared_examples = <<-RUBY
|
||||
shared_context 'foo' do
|
||||
let(:foo) { :bar }
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect',
|
||||
bad_shared_examples,
|
||||
good_shared_examples
|
||||
end
|
||||
@ -1,93 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::SharedExamples do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers an offense when using symbolic title' do
|
||||
expect_offense(<<-RUBY)
|
||||
it_behaves_like :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
it_should_behave_like :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
shared_examples :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
shared_examples_for :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
include_examples :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
include_examples :foo_bar_baz, 'foo', 'bar'
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
|
||||
shared_examples :foo_bar_baz do |param|
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
# ...
|
||||
end
|
||||
|
||||
RSpec.shared_examples :foo_bar_baz
|
||||
^^^^^^^^^^^^ Prefer 'foo bar baz' over `:foo_bar_baz` to titleize shared examples.
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using string title' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
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'
|
||||
include_examples 'foo bar baz', 'foo', 'bar'
|
||||
|
||||
shared_examples 'foo bar baz', 'foo', 'bar' do |param|
|
||||
# ...
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'does not register an offense when using Module/Class title' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it_behaves_like FooBarBaz
|
||||
it_should_behave_like FooBarBaz
|
||||
shared_examples FooBarBaz
|
||||
shared_examples_for FooBarBaz
|
||||
include_examples FooBarBaz
|
||||
include_examples FooBarBaz, 'foo', 'bar'
|
||||
|
||||
shared_examples FooBarBaz, 'foo', 'bar' do |param|
|
||||
# ...
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples 'autocorrect',
|
||||
'it_behaves_like :foo_bar_baz',
|
||||
"it_behaves_like 'foo bar baz'"
|
||||
include_examples 'autocorrect',
|
||||
'it_should_behave_like :foo_bar_baz',
|
||||
"it_should_behave_like 'foo bar baz'"
|
||||
include_examples 'autocorrect',
|
||||
'shared_examples :foo_bar_baz',
|
||||
"shared_examples 'foo bar baz'"
|
||||
include_examples 'autocorrect',
|
||||
'shared_examples_for :foo_bar_baz',
|
||||
"shared_examples_for 'foo bar baz'"
|
||||
include_examples 'autocorrect',
|
||||
'include_examples :foo_bar_baz',
|
||||
"include_examples 'foo bar baz'"
|
||||
include_examples 'autocorrect',
|
||||
"include_examples :foo_bar_baz, 'foo', 'bar'",
|
||||
"include_examples 'foo bar baz', 'foo', 'bar'"
|
||||
|
||||
bad_code_with_block = <<-RUBY
|
||||
shared_examples :foo_bar_baz, 'foo', 'bar' do |param|
|
||||
# ...
|
||||
end
|
||||
RUBY
|
||||
|
||||
good_code_with_block = <<-RUBY
|
||||
shared_examples 'foo bar baz', 'foo', 'bar' do |param|
|
||||
# ...
|
||||
end
|
||||
RUBY
|
||||
|
||||
include_examples 'autocorrect', bad_code_with_block, good_code_with_block
|
||||
end
|
||||
@ -1,138 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
describe 'receive_message_chain' do
|
||||
it 'reports single-argument calls' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain(:one) { :two }
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { allow(foo).to receive_message_chain(:one) { :two } }',
|
||||
'before { allow(foo).to receive(:one) { :two } }'
|
||||
)
|
||||
|
||||
it 'accepts multi-argument calls' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain(:one, :two) { :three }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'reports single-argument string calls' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain("one") { :two }
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { allow(foo).to receive_message_chain("one") { :two } }',
|
||||
'before { allow(foo).to receive("one") { :two } }'
|
||||
)
|
||||
|
||||
it 'accepts multi-argument string calls' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain("one.two") { :three }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'with single-key hash argument' do
|
||||
it 'reports an offence' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain(bar: 42)
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { allow(foo).to receive_message_chain(bar: 42) }',
|
||||
'before { allow(foo).to receive(:bar).and_return(42) }'
|
||||
)
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { allow(foo).to receive_message_chain("bar" => 42) }',
|
||||
'before { allow(foo).to receive("bar").and_return(42) }'
|
||||
)
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { allow(foo).to receive_message_chain(:"#{foo}" => 42) }',
|
||||
'before { allow(foo).to receive(:"#{foo}").and_return(42) }'
|
||||
)
|
||||
end
|
||||
|
||||
context 'with multiple keys hash argument' do
|
||||
it "doesn't report an offence" do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
allow(foo).to receive_message_chain(bar: 42, baz: 42)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'stub_chain' do
|
||||
it 'reports single-argument calls' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
foo.stub_chain(:one) { :two }
|
||||
^^^^^^^^^^ Use `stub` instead of calling `stub_chain` with a single argument.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { foo.stub_chain(:one) { :two } }',
|
||||
'before { foo.stub(:one) { :two } }'
|
||||
)
|
||||
|
||||
it 'accepts multi-argument calls' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
foo.stub_chain(:one, :two) { :three }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'reports single-argument string calls' do
|
||||
expect_offense(<<-RUBY)
|
||||
before do
|
||||
foo.stub_chain("one") { :two }
|
||||
^^^^^^^^^^ Use `stub` instead of calling `stub_chain` with a single argument.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
include_examples(
|
||||
'autocorrect',
|
||||
'before { foo.stub_chain("one") { :two } }',
|
||||
'before { foo.stub("one") { :two } }'
|
||||
)
|
||||
|
||||
it 'accepts multi-argument string calls' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
before do
|
||||
foo.stub_chain("one.two") { :three }
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,194 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::Cop::RSpec::SubjectStub do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'complains when subject is stubbed' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
before do
|
||||
allow(foo).to receive(:bar).and_return(baz)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
|
||||
it 'uses expect twice' do
|
||||
expect(foo.bar).to eq(baz)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'complains when subject is mocked' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
before do
|
||||
expect(foo).to receive(:bar).and_return(baz)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
|
||||
expect(foo).to receive(:bar)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
|
||||
expect(foo).to receive(:bar).with(1)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
|
||||
expect(foo).to receive(:bar).with(1).and_return(2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
|
||||
it 'uses expect twice' do
|
||||
expect(foo.bar).to eq(baz)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores stub within context where subject name changed' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I shake things up' do
|
||||
subject(:bar) { described_class.new }
|
||||
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
allow(foo).to receive(:baz)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores stub when inside all matcher' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { [Object.new] }
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
expect(foo).to all(receive(:baz))
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags nested subject stubs when nested subject uses same name' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I shake things up' do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
before do
|
||||
allow(foo).to receive(:wow)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
expect(foo).to eql(:neat)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'ignores nested stubs when nested subject is anonymous' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I shake things up' do
|
||||
subject { described_class.new }
|
||||
|
||||
before do
|
||||
allow(foo).to receive(:wow)
|
||||
end
|
||||
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
expect(foo).to eql(:neat)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags nested subject stubs when example group does not define subject' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I shake things up' do
|
||||
before do
|
||||
allow(foo).to receive(:wow)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
expect(foo).to eql(:neat)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags nested subject stubs' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I shake things up' do
|
||||
subject(:bar) { described_class.new }
|
||||
|
||||
before do
|
||||
allow(foo).to receive(:wow)
|
||||
allow(bar).to receive(:wow)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
|
||||
it 'tries to trick rubocop-rspec' do
|
||||
expect(bar).to eql(foo)
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags nested subject stubs when adjacent context redefines' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'when I do something in a context' do
|
||||
subject { blah }
|
||||
end
|
||||
|
||||
it 'still flags this test' do
|
||||
allow(foo).to receive(:blah)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'flags deeply nested subject stubs' do
|
||||
expect_offense(<<-RUBY)
|
||||
describe Foo do
|
||||
subject(:foo) { described_class.new }
|
||||
|
||||
context 'level 1' do
|
||||
subject(:bar) { described_class.new }
|
||||
|
||||
context 'level 2' do
|
||||
subject(:baz) { described_class.new }
|
||||
|
||||
before do
|
||||
allow(foo).to receive(:wow)
|
||||
allow(bar).to receive(:wow)
|
||||
allow(baz).to receive(:wow)
|
||||
^^^^^^^^^^ Do not stub your test subject.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,175 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::UnspecifiedException do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'with raise_error matcher' do
|
||||
it 'detects the `unspecified_exception` offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.to raise_error
|
||||
^^^^^^^^^^^ Specify the exception being captured
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows empty exception specification when not expecting an error' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.not_to raise_error
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception classes' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.to raise_error(StandardError)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception messages' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error('error')
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception types with messages' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error(StandardError, 'error')
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception matching regular expressions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error(/err/)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception types with matching regular expressions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error(StandardError, /err/)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows classes with blocks with braces' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error { |err| err.data }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows classes with blocks with do/end' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_error do |error|
|
||||
error.data
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows parameterized exceptions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
my_exception = StandardError.new('my exception')
|
||||
expect {
|
||||
raise my_exception
|
||||
}.to raise_error(my_exception)
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'with raise_exception matcher' do
|
||||
it 'detects the `unspecified_exception` offense' do
|
||||
expect_offense(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.to raise_exception
|
||||
^^^^^^^^^^^^^^^ Specify the exception being captured
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows empty exception specification when not expecting an error' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.not_to raise_exception
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception classes' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError
|
||||
}.to raise_exception(StandardError)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception messages' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception('error')
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception types with messages' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception(StandardError, 'error')
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception matching regular expressions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception(/err/)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows exception types with matching regular expressions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception(StandardError, /err/)
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows classes with blocks with braces' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception { |err| err.data }
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows classes with blocks with do/end' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
expect {
|
||||
raise StandardError.new('error')
|
||||
}.to raise_exception do |error|
|
||||
error.data
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'allows parameterized exceptions' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
my_exception = StandardError.new('my exception')
|
||||
expect {
|
||||
raise my_exception
|
||||
}.to raise_exception(my_exception)
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,84 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::VerifiedDoubles, :config do
|
||||
subject(:cop) { described_class.new(config) }
|
||||
|
||||
it 'finds a `double` instead of an `instance_double`' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = double("Widget")
|
||||
^^^^^^^^^^^^^^^^ Prefer using verifying doubles over normal doubles.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when configuration does not specify IgnoreSymbolicNames' do
|
||||
let(:cop_config) { {} }
|
||||
|
||||
it 'find doubles whose name is a symbol' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = double(:widget)
|
||||
^^^^^^^^^^^^^^^ Prefer using verifying doubles over normal doubles.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'finds a `spy` instead of an `instance_spy`' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = spy("Widget")
|
||||
^^^^^^^^^^^^^ Prefer using verifying doubles over normal doubles.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'when configured to ignore symbolic names' do
|
||||
let(:cop_config) { { 'IgnoreSymbolicNames' => true } }
|
||||
|
||||
it 'ignores doubles whose name is a symbol' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
foo = double(:widget)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'still flags doubles whose name is a string' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = double("widget")
|
||||
^^^^^^^^^^^^^^^^ Prefer using verifying doubles over normal doubles.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
it 'doubles that have no name specified' do
|
||||
expect_offense(<<-RUBY)
|
||||
it do
|
||||
foo = double
|
||||
^^^^^^ Prefer using verifying doubles over normal doubles.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
context 'when configured to ignore nameless doubles' do
|
||||
let(:cop_config) { { 'IgnoreNameless' => true } }
|
||||
|
||||
it 'ignores doubles that have no name specified' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
foo = double
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
it 'ignores instance_doubles' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it do
|
||||
foo = instance_double("Foo")
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,47 +0,0 @@
|
||||
RSpec.describe RuboCop::Cop::RSpec::VoidExpect do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
it 'registers offenses to void `expect`' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'something' do
|
||||
something = 1
|
||||
expect(something)
|
||||
^^^^^^^^^^^^^^^^^ Do not use `expect()` without `.to` or `.not_to`. Chain the methods or remove it.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers offenses to void `expect` when block has one expression' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'something' do
|
||||
expect(something)
|
||||
^^^^^^^^^^^^^^^^^ Do not use `expect()` without `.to` or `.not_to`. Chain the methods or remove it.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'registers offenses to void `expect` with block' do
|
||||
expect_offense(<<-RUBY)
|
||||
it 'something' do
|
||||
expect{something}
|
||||
^^^^^^^^^^^^^^^^^ Do not use `expect()` without `.to` or `.not_to`. Chain the methods or remove it.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts non-void `expect`' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'something' do
|
||||
expect(something).to be 1
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it 'accepts non-void `expect` with block' do
|
||||
expect_no_offenses(<<-RUBY)
|
||||
it 'something' do
|
||||
expect{something}.to raise_error(StandardError)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
@ -1,50 +0,0 @@
|
||||
require 'rubocop/rspec/config_formatter'
|
||||
|
||||
RSpec.describe RuboCop::RSpec::ConfigFormatter do
|
||||
let(:config) do
|
||||
{
|
||||
'AllCops' => {
|
||||
'Setting' => 'fourty two'
|
||||
},
|
||||
'RSpec/Foo' => {
|
||||
'Config' => 2,
|
||||
'Enabled' => true
|
||||
},
|
||||
'RSpec/Bar' => {
|
||||
'Enabled' => true
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
let(:descriptions) do
|
||||
{
|
||||
'RSpec/Foo' => {
|
||||
'Description' => 'Blah'
|
||||
},
|
||||
'RSpec/Bar' => {
|
||||
'Description' => 'Wow'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'builds a YAML dump with spacing between cops' do
|
||||
formatter = described_class.new(config, descriptions)
|
||||
|
||||
expect(formatter.dump).to eql(<<-YAML.gsub(/^\s+\|/, ''))
|
||||
|---
|
||||
|AllCops:
|
||||
| Setting: fourty two
|
||||
|
|
||||
|RSpec/Foo:
|
||||
| Config: 2
|
||||
| Enabled: true
|
||||
| Description: Blah
|
||||
| StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Foo
|
||||
|
|
||||
|RSpec/Bar:
|
||||
| Enabled: true
|
||||
| Description: Wow
|
||||
| StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Bar
|
||||
YAML
|
||||
end
|
||||
end
|
||||
@ -1,61 +0,0 @@
|
||||
require 'yard'
|
||||
|
||||
require 'rubocop/rspec/description_extractor'
|
||||
|
||||
RSpec.describe RuboCop::RSpec::DescriptionExtractor do
|
||||
let(:yardocs) do
|
||||
YARD.parse_string(<<-RUBY)
|
||||
# This is not a cop
|
||||
class RuboCop::Cop::Mixin::Sneaky
|
||||
end
|
||||
|
||||
# This is not a concrete cop
|
||||
#
|
||||
# @abstract
|
||||
class RuboCop::Cop::RSpec::Cop
|
||||
end
|
||||
|
||||
# Checks foo
|
||||
#
|
||||
# Some description
|
||||
#
|
||||
# @note only works with foo
|
||||
class RuboCop::Cop::RSpec::Foo < RuboCop::Cop::RSpec::Cop
|
||||
# Hello
|
||||
def bar
|
||||
end
|
||||
|
||||
# :nodoc:
|
||||
class HelperClassForFoo
|
||||
end
|
||||
end
|
||||
|
||||
class RuboCop::Cop::RSpec::Undocumented < RuboCop::Cop::RSpec::Cop
|
||||
# Hello
|
||||
def bar
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
YARD::Registry.all
|
||||
end
|
||||
|
||||
def stub_cop_const(name)
|
||||
stub_const(
|
||||
"RuboCop::Cop::RSpec::#{name}",
|
||||
Class.new(RuboCop::Cop.const_get(:WorkaroundCop))
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
stub_cop_const('Foo')
|
||||
stub_cop_const('Undocumented')
|
||||
end
|
||||
|
||||
it 'builds a hash of descriptions' do
|
||||
expect(described_class.new(yardocs).to_h).to eql(
|
||||
'RSpec/Foo' => { 'Description' => 'Checks foo' },
|
||||
'RSpec/Undocumented' => { 'Description' => '' }
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -1,44 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::RSpec::ExampleGroup do
|
||||
include RuboCop::AST::Sexp
|
||||
|
||||
subject(:group) { described_class.new(parse_source(source).ast) }
|
||||
|
||||
let(:source) do
|
||||
<<-RUBY
|
||||
RSpec.describe Foo do
|
||||
it 'does x' do
|
||||
x
|
||||
end
|
||||
|
||||
it 'does y' do
|
||||
y
|
||||
end
|
||||
|
||||
context 'nested' do
|
||||
it 'does z' do
|
||||
z
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:example_nodes) do
|
||||
[
|
||||
s(:block,
|
||||
s(:send, nil, :it,
|
||||
s(:str, 'does x')),
|
||||
s(:args), s(:send, nil, :x)),
|
||||
s(:block,
|
||||
s(:send, nil, :it,
|
||||
s(:str, 'does y')),
|
||||
s(:args), s(:send, nil, :y))
|
||||
].map { |node| RuboCop::RSpec::Example.new(node) }
|
||||
end
|
||||
|
||||
it 'exposes examples in scope' do
|
||||
expect(group.examples).to eql(example_nodes)
|
||||
end
|
||||
end
|
||||
@ -1,62 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::RSpec::Example do
|
||||
include RuboCop::AST::Sexp
|
||||
|
||||
def example(source)
|
||||
described_class.new(parse_source(source).ast)
|
||||
end
|
||||
|
||||
it 'extracts doc string' do
|
||||
expect(example("it('does x') { foo }").doc_string)
|
||||
.to eq(s(:str, 'does x'))
|
||||
end
|
||||
|
||||
it 'extracts doc string for unimplemented examples' do
|
||||
expect(example("it('does x')").doc_string)
|
||||
.to eq(s(:str, 'does x'))
|
||||
end
|
||||
|
||||
it 'returns nil for examples without doc strings' do
|
||||
expect(example('it { foo }').doc_string).to be(nil)
|
||||
end
|
||||
|
||||
it 'extracts keywords' do
|
||||
expect(example("it('foo', :bar, baz: :qux) { a }").metadata)
|
||||
.to eq([s(:sym, :bar), s(:hash, s(:pair, s(:sym, :baz), s(:sym, :qux)))])
|
||||
end
|
||||
|
||||
it 'extracts implementation' do
|
||||
expect(example('it("foo") { bar; baz }').implementation)
|
||||
.to eq(s(:begin, s(:send, nil, :bar), s(:send, nil, :baz)))
|
||||
end
|
||||
|
||||
it 'returns node' do
|
||||
node = s(:sym, :node)
|
||||
expect(described_class.new(node).to_node).to be(node)
|
||||
end
|
||||
|
||||
describe 'value object semantics' do
|
||||
it 'compares by value' do
|
||||
aggregate_failures 'equality semantics' do
|
||||
expect(example('it("foo")')).to eq(example('it("foo")'))
|
||||
expect(example('it("foo")')).not_to eq(example('it("bar")'))
|
||||
end
|
||||
end
|
||||
|
||||
it 'can be used as a key in a hash' do
|
||||
hash = {}
|
||||
|
||||
hash[example('it("foo")')] = 123
|
||||
|
||||
expect(hash[example('it("foo")')]).to be(123)
|
||||
end
|
||||
|
||||
it 'computes #hash based on class and node' do
|
||||
node = s(:node)
|
||||
|
||||
expect(described_class.new(node).hash)
|
||||
.to eql([described_class, node].hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,53 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe RuboCop::RSpec::Hook do
|
||||
include RuboCop::AST::Sexp
|
||||
|
||||
def hook(source)
|
||||
described_class.new(parse_source(source).ast)
|
||||
end
|
||||
|
||||
it 'extracts name' do
|
||||
expect(hook('around(:each) { }').name).to be(:around)
|
||||
end
|
||||
|
||||
it 'does not break if a hook is not given a symbol literal' do
|
||||
expect(hook('before(scope) { example_setup }').knowable_scope?).to be(false)
|
||||
end
|
||||
|
||||
it 'knows the scope of a hook with a symbol literal' do
|
||||
expect(hook('before { example_setup }').knowable_scope?).to be(true)
|
||||
end
|
||||
|
||||
it 'ignores other arguments to hooks' do
|
||||
expect(hook('before(:each, :metadata) { example_setup }').scope)
|
||||
.to be(:each)
|
||||
end
|
||||
|
||||
it 'classifies nonstandard hook arguments as invalid' do
|
||||
expect(hook('before(:nothing) { example_setup }').valid_scope?).to be(false)
|
||||
end
|
||||
|
||||
it 'classifies :each as a valid hook argument' do
|
||||
expect(hook('before(:each) { example_setup }').valid_scope?).to be(true)
|
||||
end
|
||||
|
||||
it 'classifies :each as an example hook' do
|
||||
expect(hook('before(:each) { }').example?).to be(true)
|
||||
end
|
||||
|
||||
shared_examples 'standardizes scope' do |source, scope|
|
||||
it "interprets #{source} as having scope #{scope}" do
|
||||
expect(hook(source).scope).to equal(scope)
|
||||
end
|
||||
end
|
||||
|
||||
include_examples 'standardizes scope', 'before(:each) { }', :each
|
||||
include_examples 'standardizes scope', 'around(:example) { }', :each
|
||||
include_examples 'standardizes scope', 'after { }', :each
|
||||
|
||||
include_examples 'standardizes scope', 'before(:all) { }', :context
|
||||
include_examples 'standardizes scope', 'around(:context) { }', :context
|
||||
|
||||
include_examples 'standardizes scope', 'after(:suite) { }', :suite
|
||||
end
|
||||
@ -1,51 +0,0 @@
|
||||
RSpec.describe RuboCop::RSpec::Language::SelectorSet do
|
||||
subject(:selector_set) { described_class.new(%i[foo bar]) }
|
||||
|
||||
it 'composes sets' do
|
||||
combined = selector_set + described_class.new(%i[baz])
|
||||
|
||||
expect(combined).to eq(described_class.new(%i[foo bar baz]))
|
||||
end
|
||||
|
||||
it 'compares by value' do
|
||||
expect(selector_set).not_to eq(described_class.new(%i[foo bar baz]))
|
||||
end
|
||||
|
||||
describe '#include?' do
|
||||
it 'returns false for selectors not in the set' do
|
||||
expect(selector_set.include?(:baz)).to be(false)
|
||||
end
|
||||
|
||||
it 'returns true for selectors in the set' do
|
||||
expect(selector_set.include?(:foo)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#node_pattern' do
|
||||
it 'builds a node pattern' do
|
||||
expect(selector_set.node_pattern).to eql(':foo :bar')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#node_pattern_union' do
|
||||
it 'builds a node pattern union' do
|
||||
expect(selector_set.node_pattern_union).to eql('{:foo :bar}')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_pattern' do
|
||||
it 'builds a send matching pattern' do
|
||||
expect(selector_set.send_pattern).to eql(
|
||||
'(send {(const nil? :RSpec) nil?} {:foo :bar} ...)'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#block_pattern' do
|
||||
it 'builds a block matching pattern' do
|
||||
expect(selector_set.block_pattern).to eql(
|
||||
'(block (send {(const nil? :RSpec) nil?} {:foo :bar} ...) ...)'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,21 +0,0 @@
|
||||
RSpec.describe RuboCop::RSpec::Util, '.one' do
|
||||
let(:first) { instance_double(Object) }
|
||||
let(:array) { instance_double(Array, one?: true, first: first) }
|
||||
let(:client) { Class.new.extend(described_class) }
|
||||
|
||||
it 'returns first element' do
|
||||
expect(client.one(array)).to be(first)
|
||||
end
|
||||
|
||||
it 'fails if the list is empty' do
|
||||
expect { client.one([]) }
|
||||
.to raise_error(described_class::SizeError)
|
||||
.with_message('expected size to be exactly 1 but size was 0')
|
||||
end
|
||||
|
||||
it 'fails if the list has more than one element' do
|
||||
expect { client.one([1, 2]) }
|
||||
.to raise_error(described_class::SizeError)
|
||||
.with_message('expected size to be exactly 1 but size was 2')
|
||||
end
|
||||
end
|
||||
@ -1,50 +0,0 @@
|
||||
RSpec.describe RuboCop::RSpec::Wording do
|
||||
let(:replacements) { { 'have' => 'has' } }
|
||||
let(:ignores) { %w[only really] }
|
||||
|
||||
expected_rewrites =
|
||||
{
|
||||
'should return something' => 'returns something',
|
||||
'should not return something' => 'does not return something',
|
||||
'should do nothing' => 'does nothing',
|
||||
'should have sweets' => 'has sweets',
|
||||
'should worry about the future' => 'worries about the future',
|
||||
'should pay for pizza' => 'pays for pizza',
|
||||
'should obey my orders' => 'obeys my orders',
|
||||
'should deploy the app' => 'deploys the app',
|
||||
'should buy the product' => 'buys the product',
|
||||
'should miss me' => 'misses me',
|
||||
'should fax the document' => 'faxes the document',
|
||||
'should amass debt' => 'amasses debt',
|
||||
'should echo the input' => 'echoes the input',
|
||||
'should alias the method' => 'aliases the method',
|
||||
'should search the internet' => 'searches the internet',
|
||||
'should wish me luck' => 'wishes me luck',
|
||||
'should really only return one item' => 'really only returns one item',
|
||||
"shouldn't return something" => 'does not return something',
|
||||
'SHOULD RETAIN UPPERCASE' => 'RETAINS UPPERCASE',
|
||||
"shouldn't be true" => 'is not true',
|
||||
"SHOULDN'T BE true" => 'IS NOT true',
|
||||
"SHOULDN'T NOT RETAIN UPPERCASE" => 'DOES NOT NOT RETAIN UPPERCASE',
|
||||
'should WORRY' => 'WORRIES',
|
||||
'should WISH me luck' => 'WISHES me luck',
|
||||
'' => '',
|
||||
'should' => '',
|
||||
"shouldn't" => 'does not',
|
||||
'should not' => 'does not',
|
||||
'should fizz' => 'fizzes'
|
||||
}
|
||||
|
||||
expected_rewrites.each do |old, new|
|
||||
it %(rewrites "#{old}" as "#{new}") do
|
||||
rewrite =
|
||||
described_class.new(
|
||||
old,
|
||||
replace: replacements,
|
||||
ignore: ignores
|
||||
).rewrite
|
||||
|
||||
expect(rewrite).to eql(new)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,7 +0,0 @@
|
||||
RSpec.shared_examples 'autocorrect' do |original, corrected|
|
||||
it "autocorrects `#{original}` to `#{corrected}`" do
|
||||
autocorrected = autocorrect_source(original, 'spec/foo_spec.rb')
|
||||
|
||||
expect(autocorrected).to eql(corrected)
|
||||
end
|
||||
end
|
||||
@ -1,7 +0,0 @@
|
||||
RSpec.shared_examples 'detects style' do |source, style, filename: 'x_spec.rb'|
|
||||
it 'generates a todo based on the detected style' do
|
||||
inspect_source(source, filename)
|
||||
|
||||
expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => style)
|
||||
end
|
||||
end
|
||||
@ -1,25 +0,0 @@
|
||||
RSpec.shared_examples 'smoke test', type: :cop_spec do
|
||||
context 'with default configuration' do
|
||||
# This is overridden to avoid a number of specs that define `cop_config`
|
||||
# (so it is referenced in the 'config' shared context) but do not define
|
||||
# all of the dependent configuration options until inside of a context
|
||||
# that is out of scope, causing a NameError.
|
||||
let(:cop_config) { {} }
|
||||
|
||||
stress_tests = Pathname.glob('spec/smoke_tests/*.rb')
|
||||
|
||||
raise 'No smoke tests could be found!' if stress_tests.empty?
|
||||
|
||||
stress_tests.each do |path|
|
||||
it "does not crash on smoke test: #{path}" do
|
||||
source = path.read
|
||||
file_name = path.to_s
|
||||
|
||||
aggregate_failures do
|
||||
expect { inspect_source(source, file_name) }.not_to raise_error
|
||||
expect { autocorrect_source(source, file_name) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Since FactoryBot is not a dependency, none of this should be executed. We just
|
||||
# need the AST to exist.
|
||||
if false
|
||||
FactoryBot.define do
|
||||
factory :foo do
|
||||
bar {}
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,4 +0,0 @@
|
||||
# frozen_string_literal:
|
||||
|
||||
# This is sort of a test, but there's no rspec to see here.
|
||||
raise 'Uh oh, the Party seems to have gotten into ruby.' if 2 + 2 == 5
|
||||
@ -1,233 +0,0 @@
|
||||
RSpec.describe 'Weirdness' do
|
||||
subject! { nil }
|
||||
subject { nil }
|
||||
subject(:foo) { nil }
|
||||
subject!(:foo) { nil }
|
||||
|
||||
subject! (:foo) { |something| nil }
|
||||
subject :foo do end
|
||||
|
||||
let(:foo) { |something| something }
|
||||
let (:foo) { 1 }
|
||||
let! (:bar){}
|
||||
|
||||
let :a do end
|
||||
|
||||
let(:bar) { <<-HEREDOC }
|
||||
What a pain.
|
||||
HEREDOC
|
||||
|
||||
let(:bar) { <<-'HEREDOC' }
|
||||
Even odder.
|
||||
HEREDOC
|
||||
|
||||
let(:baz) do
|
||||
<<-INSIDE
|
||||
Hi. I'm in your lets.
|
||||
INSIDE
|
||||
end
|
||||
|
||||
let(:hi) {}
|
||||
let(:bye) do
|
||||
end
|
||||
|
||||
let(:doop) { foo; 1 }
|
||||
|
||||
it {}
|
||||
specify {}
|
||||
|
||||
it 'works', metadata: true do
|
||||
end
|
||||
|
||||
describe {}
|
||||
context {}
|
||||
|
||||
describe '#nothing' do
|
||||
end
|
||||
|
||||
it 'is empty' do
|
||||
end
|
||||
|
||||
it '' do end
|
||||
describe do end
|
||||
context do end
|
||||
shared_examples 'a' do end
|
||||
|
||||
describe 'things' do
|
||||
context 'with context' do
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'weird rspec' do
|
||||
end
|
||||
|
||||
shared_examples :something do
|
||||
end
|
||||
|
||||
context 'test' do
|
||||
include_examples 'weird rspec'
|
||||
include_examples('weird rspec', serious: true) do
|
||||
it_behaves_like :something
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like :something
|
||||
it_should_behave_like :something
|
||||
|
||||
it_behaves_like :something do
|
||||
let(:foo) { 'bar' }
|
||||
end
|
||||
|
||||
it_behaves_like(:something) do |arg, *args, &block|
|
||||
end
|
||||
|
||||
before {}
|
||||
context 'never run' do
|
||||
around {}
|
||||
end
|
||||
after {}
|
||||
|
||||
before { <<-DOC }
|
||||
Eh, what's up?
|
||||
DOC
|
||||
|
||||
around { |test| test.run; <<-DOC }
|
||||
Eh, what's up?
|
||||
DOC
|
||||
|
||||
after { <<-DOC }
|
||||
Eh, what's up?
|
||||
DOC
|
||||
|
||||
around do |test|
|
||||
test.run
|
||||
end
|
||||
|
||||
it 'is expecting you' do
|
||||
expect('you').to eql('you')
|
||||
end
|
||||
|
||||
it 'is expecting you not to raise an error' do
|
||||
expect { 'you' }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'has chained expectations' do
|
||||
expect('you').to eql('you').and(match(/y/))
|
||||
end
|
||||
|
||||
%w[who likes dynamic examples].each do |word|
|
||||
let(word) { word }
|
||||
|
||||
describe "#{word}" do
|
||||
context "#{word}" do
|
||||
it "lets the word '#{word}' be '#{word}'" do
|
||||
expect(send(word)).to eql(word)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it { foo; 1 && 2}
|
||||
it('has a description too') { foo; 1 && 2}
|
||||
|
||||
it %{quotes a string weird} do
|
||||
end
|
||||
|
||||
it((' '.strip! ; 1 && 'isnt a simple string')) do
|
||||
expect(nil).to be(nil)
|
||||
end
|
||||
|
||||
it((' '.strip! ; 1 && 'isnt a simple string')) do
|
||||
double = double(:foo)
|
||||
|
||||
allow(double).to receive(:oogabooga).with(nil).and_return(nil)
|
||||
|
||||
expect(double.oogabooga(nil)).to be(nil)
|
||||
|
||||
expect(double).to have_received(:oogabooga).once
|
||||
end
|
||||
|
||||
it 'uses a matcher' do
|
||||
expect([].empty?).to be(true)
|
||||
expect([]).to be_empty
|
||||
end
|
||||
|
||||
let(:klass) do
|
||||
Class.new do
|
||||
def initialize(thing)
|
||||
@thing = thing
|
||||
end
|
||||
|
||||
def announce
|
||||
'wooo, so dynamic!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'it does a thing' do
|
||||
end
|
||||
|
||||
it 'It does a thing' do
|
||||
end
|
||||
|
||||
it 'should not do the thing' do
|
||||
end
|
||||
|
||||
specify do
|
||||
foo = double(:bar)
|
||||
allow(foo).to receive_message_chain(bar: 42, baz: 42)
|
||||
allow(foo).to receive(:bar)
|
||||
allow(foo).to receive_messages(bar: 42, baz: 42)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe {}
|
||||
RSpec.shared_examples('pointless') {}
|
||||
RSpec.shared_context('even pointless-er') {}
|
||||
RSpec.describe do end
|
||||
RSpec.shared_examples('pointless2') do end
|
||||
RSpec.shared_context('even pointless-er2') do end
|
||||
|
||||
class Broken
|
||||
end
|
||||
|
||||
RSpec.describe Broken do
|
||||
end
|
||||
|
||||
RSpec.describe 'RubocopBug' do
|
||||
subject { true }
|
||||
|
||||
before do
|
||||
each_row = allow(double(:exporter)).to receive(:each_row)
|
||||
|
||||
[1, 2].each do |sig|
|
||||
each_row = each_row.and_yield(sig)
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a single example' do
|
||||
expect(subject).to be_truthy
|
||||
end
|
||||
|
||||
it 'has an expectation' do
|
||||
stats = double(event: nil)
|
||||
|
||||
stats.event('tada!')
|
||||
|
||||
expect(stats)
|
||||
.to have_received(:event)
|
||||
.with('tada!')
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe do
|
||||
let(:uh_oh) { <<-HERE.strip + ", #{<<-THERE.strip}" }
|
||||
Seriously
|
||||
HERE
|
||||
who designed these things?
|
||||
THERE
|
||||
|
||||
it 'is insane' do
|
||||
expect(uh_oh).to eql('Seriously, who designed these things?')
|
||||
end
|
||||
end
|
||||
@ -1,48 +0,0 @@
|
||||
require 'rubocop'
|
||||
|
||||
require 'rubocop/rspec/support'
|
||||
|
||||
if ENV['COVERAGE'] == 'true'
|
||||
require 'simplecov'
|
||||
SimpleCov.start
|
||||
end
|
||||
|
||||
module SpecHelper
|
||||
ROOT = Pathname.new(__dir__).parent.freeze
|
||||
end
|
||||
|
||||
spec_helper_glob = File.expand_path('{support,shared}/*.rb', __dir__)
|
||||
Dir.glob(spec_helper_glob).map(&method(:require))
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.define_derived_metadata(file_path: %r{/spec/rubocop/cop/}) do |meta|
|
||||
meta[:type] = :cop_spec
|
||||
end
|
||||
|
||||
config.order = :random
|
||||
|
||||
config.expect_with :rspec do |expectations|
|
||||
expectations.syntax = :expect # Disable `should`
|
||||
end
|
||||
|
||||
config.mock_with :rspec do |mocks|
|
||||
mocks.syntax = :expect # Disable `should_receive` and `stub`
|
||||
end
|
||||
|
||||
# Forbid RSpec from monkey patching any of our objects
|
||||
config.disable_monkey_patching!
|
||||
|
||||
# We should address configuration warnings when we upgrade
|
||||
config.raise_errors_for_deprecations!
|
||||
|
||||
# RSpec gives helpful warnings when you are doing something wrong.
|
||||
# We should take their advice!
|
||||
config.raise_on_warning = true
|
||||
|
||||
config.include(ExpectOffense)
|
||||
end
|
||||
|
||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
||||
|
||||
require 'rubocop-rspec'
|
||||
@ -1,17 +0,0 @@
|
||||
# rubocop-rspec gem extension of RuboCop's ExpectOffense module.
|
||||
#
|
||||
# This mixin is the same as rubocop's ExpectOffense except the default
|
||||
# filename ends with `_spec.rb`
|
||||
module ExpectOffense
|
||||
include RuboCop::RSpec::ExpectOffense
|
||||
|
||||
DEFAULT_FILENAME = 'example_spec.rb'.freeze
|
||||
|
||||
def expect_offense(source, filename = DEFAULT_FILENAME)
|
||||
super
|
||||
end
|
||||
|
||||
def expect_no_offenses(source, filename = DEFAULT_FILENAME)
|
||||
super
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user