rubocop-rspec-1.22.2/0000755000004100000410000000000013237614066014421 5ustar www-datawww-datarubocop-rspec-1.22.2/Rakefile0000644000004100000410000000306213237614066016067 0ustar www-datawww-datarequire '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' 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 sh('codeclimate-test-reporter') if ENV['CI'] 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 task default: %i[build_config coverage internal_investigation confirm_config] 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 generator = RuboCop::Cop::Generator.new(cop_name) 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 rubocop-rspec-1.22.2/rubocop-rspec.gemspec0000644000004100000410000000232513237614066020553 0ustar www-datawww-data$LOAD_PATH.unshift File.expand_path('../lib', __FILE__) 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 = 'http://github.com/backus/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.1.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.add_runtime_dependency 'rubocop', '>= 0.52.1' spec.add_development_dependency 'rake' spec.add_development_dependency 'rspec', '>= 3.4' spec.add_development_dependency 'simplecov' spec.add_development_dependency 'yard' end rubocop-rspec-1.22.2/Gemfile0000644000004100000410000000045513237614066015720 0ustar www-datawww-datasource 'https://rubygems.org' gemspec group :test do gem 'codeclimate-test-reporter', '~> 1.0.0' gem 'simplecov', '~> 0.12.0', require: false end local_gemfile = 'Gemfile.local' if File.exist?(local_gemfile) eval(File.read(local_gemfile)) # rubocop:disable Security/Eval end rubocop-rspec-1.22.2/spec/0000755000004100000410000000000013237614066015353 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/0000755000004100000410000000000013237614066017024 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/cop/0000755000004100000410000000000013237614066017605 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/cop/rspec/0000755000004100000410000000000013237614066020721 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/cop/rspec/return_from_stub_spec.rb0000644000004100000410000001554513237614066025671 0ustar www-datawww-dataRSpec.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 '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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/expect_in_hook_spec.rb0000644000004100000410000000437113237614066025263 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/multiple_subjects_spec.rb0000644000004100000410000000415413237614066026021 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/message_expectation_spec.rb0000644000004100000410000000244013237614066026307 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/example_without_description_spec.rb0000644000004100000410000000402513237614066030102 0ustar www-datawww-dataRSpec.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 end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/example_length_spec.rb0000644000004100000410000000251413237614066025256 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/context_wording_spec.rb0000644000004100000410000000336613237614066025505 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/empty_line_after_subject_spec.rb0000644000004100000410000000326113237614066027327 0ustar www-datawww-data# 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 '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 let 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/shared_context_spec.rb0000644000004100000410000000650213237614066025275 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/let_setup_spec.rb0000644000004100000410000000254613237614066024273 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/be_eql_spec.rb0000644000004100000410000000345113237614066023512 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/describe_method_spec.rb0000644000004100000410000000147613237614066025410 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/described_class_spec.rb0000644000004100000410000001755613237614066025407 0ustar www-datawww-dataRSpec.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 skip 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/repeated_description_spec.rb0000644000004100000410000000330613237614066026456 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/iterated_expectation_spec.rb0000644000004100000410000000456713237614066026500 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/scattered_let_spec.rb0000644000004100000410000000144013237614066025101 0ustar www-datawww-dataRSpec.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 it 'does not encounter an error when handling an empty describe' do expect { inspect_source('RSpec.describe(User) do end', 'a_spec.rb') } .not_to raise_error end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/before_after_all_spec.rb0000644000004100000410000000263713237614066025543 0ustar www-datawww-dataRSpec.describe RuboCop::Cop::RSpec::BeforeAfterAll, :config do subject(:cop) { described_class.new(config) } 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/cop_spec.rb0000644000004100000410000000451113237614066023042 0ustar www-datawww-data# 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 self.name 'RuboCop::RSpec::FakeCop' end 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/expect_actual_spec.rb0000644000004100000410000001074213237614066025105 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/around_block_spec.rb0000644000004100000410000000535513237614066024732 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/it_behaves_like_spec.rb0000644000004100000410000000271113237614066025376 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/nested_groups_spec.rb0000644000004100000410000000327113237614066025144 0ustar www-datawww-data# 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 '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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/scattered_setup_spec.rb0000644000004100000410000000470013237614066025457 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/instance_spy_spec.rb0000644000004100000410000000323513237614066024762 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/describe_symbol_spec.rb0000644000004100000410000000216513237614066025431 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/implicit_expect_spec.rb0000644000004100000410000000563413237614066025452 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/hook_argument_spec.rb0000644000004100000410000001242413237614066025125 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/predicate_matcher_spec.rb0000644000004100000410000003463313237614066025734 0ustar www-datawww-dataRSpec.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.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/repeated_example_spec.rb0000644000004100000410000000335413237614066025571 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/multiple_describes_spec.rb0000644000004100000410000000146713237614066026146 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb0000644000004100000410000000752213237614066030317 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/empty_example_group_spec.rb0000644000004100000410000000357113237614066026353 0ustar www-datawww-data# 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 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/align_right_let_brace_spec.rb0000644000004100000410000000256313237614066026555 0ustar www-datawww-dataRSpec.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 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/leading_subject_spec.rb0000644000004100000410000000466013237614066025410 0ustar www-datawww-data# 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 bad_code = <<-RUBY RSpec.describe User do 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 } 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/example_wording_spec.rb0000644000004100000410000000643113237614066025450 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/expect_output_spec.rb0000644000004100000410000000277613237614066025204 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/named_subject_spec.rb0000644000004100000410000000322413237614066025064 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/message_chain_spec.rb0000644000004100000410000000111113237614066025040 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/not_to_not_spec.rb0000644000004100000410000000247413237614066024451 0ustar www-datawww-dataRSpec.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 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 }' 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 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 }' end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/factory_bot/0000755000004100000410000000000013237614066023234 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/cop/rspec/factory_bot/dynamic_attribute_defined_statically_spec.rb0000644000004100000410000000533213237614066034214 0ustar www-datawww-data# frozen_string_literal: true # rubocop:disable Metrics/LineLength RSpec.describe RuboCop::Cop::RSpec::FactoryBot::DynamicAttributeDefinedStatically do # rubocop:enable Metrics/LineLength subject(:cop) { described_class.new(config) } let(:config) { RuboCop::Config.new } %w[FactoryBot FactoryGirl].each do |factory_bot| context "when using #{factory_bot}" do it 'registers an offense for offending code' do expect_offense(<<-RUBY) #{factory_bot}.define do factory :post do published_at 1.day.from_now ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute. status [:draft, :published].sample ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute. created_at 1.day.ago ^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute. end end RUBY end it 'registers an offense in a trait' do expect_offense(<<-RUBY) #{factory_bot}.define do factory :post do title "Something" trait :published do published_at 1.day.from_now ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute. end end end RUBY end it 'accepts' do expect_no_offenses(<<-RUBY) #{factory_bot}.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) } tag Tag::MAGIC end end RUBY end it 'does not add offense if out of factory girl block' do expect_no_offenses(<<-RUBY) status [:draft, :published].sample published_at 1.day.from_now created_at 1.day.ago RUBY end bad = <<-RUBY #{factory_bot}.define do factory :post do status([:draft, :published].sample) published_at 1.day.from_now created_at(1.day.ago) updated_at Time.current end end RUBY corrected = <<-RUBY #{factory_bot}.define do factory :post do status { [:draft, :published].sample } published_at { 1.day.from_now } created_at { 1.day.ago } updated_at { Time.current } end end RUBY include_examples 'autocorrect', bad, corrected end end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/instance_variable_spec.rb0000644000004100000410000000433013237614066025731 0ustar www-datawww-dataRSpec.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 } ^^^^ Use `let` instead of an instance variable. 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 } ^^^^ Use `let` instead of an instance variable. 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 } ^^^^ Use `let` instead of an instance variable. 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/void_expect_spec.rb0000644000004100000410000000236413237614066024576 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/empty_line_after_final_let_spec.rb0000644000004100000410000000562513237614066027633 0ustar www-datawww-data# 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 ^^^^^^^^^^^ Add an empty line after the last `let` block. b end 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 '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 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 end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/any_instance_spec.rb0000644000004100000410000000162113237614066024733 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/describe_class_spec.rb0000644000004100000410000000737213237614066025236 0ustar www-datawww-dataRSpec.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) 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/invalid_predicate_matcher_spec.rb0000644000004100000410000000210013237614066027422 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/file_path_spec.rb0000644000004100000410000001341313237614066024215 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/capybara/0000755000004100000410000000000013237614066022503 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/cop/rspec/capybara/current_path_expectation_spec.rb0000644000004100000410000000177113237614066031151 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb0000644000004100000410000000327013237614066027222 0ustar www-datawww-dataRSpec.describe RuboCop::Cop::RSpec::Capybara::FeatureMethods do subject(:cop) { described_class.new } it 'flags violations for `background`' do expect_offense(<<-RUBY) background do; end ^^^^^^^^^^ Use `before` instead of `background`. RUBY end it 'flags violations for `scenario`' do expect_offense(<<-RUBY) scenario 'Foo' do; end ^^^^^^^^ Use `it` instead of `scenario`. RUBY end it 'flags violations for `xscenario`' do expect_offense(<<-RUBY) RSpec.xscenario 'Foo' do; end ^^^^^^^^^ Use `xit` instead of `xscenario`. RUBY end it 'flags violations for `given`' do expect_offense(<<-RUBY) given(:foo) { :foo } ^^^^^ Use `let` instead of `given`. RUBY end it 'flags violations for `given!`' do expect_offense(<<-RUBY) given!(:foo) { :foo } ^^^^^^ Use `let!` instead of `given!`. 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 include_examples 'autocorrect', 'background { }', 'before { }' include_examples 'autocorrect', 'scenario { }', 'it { }' include_examples 'autocorrect', 'xscenario { }', 'xit { }' include_examples 'autocorrect', 'given(:foo) { }', 'let(:foo) { }' include_examples 'autocorrect', 'given!(:foo) { }', 'let!(:foo) { }' include_examples 'autocorrect', 'RSpec.feature { }', 'RSpec.describe { }' end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/verified_doubles_spec.rb0000644000004100000410000000333013237614066025571 0ustar www-datawww-dataRSpec.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 'ignores doubles without a name' do expect_no_offenses(<<-RUBY) it do foo = double end RUBY end it 'ignores instance_doubles' do expect_no_offenses(<<-RUBY) it do foo = instance_double("Foo") end RUBY end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/focus_spec.rb0000644000004100000410000001175113237614066023404 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/align_left_let_brace_spec.rb0000644000004100000410000000246513237614066026373 0ustar www-datawww-dataRSpec.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 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/multiple_expectations_spec.rb0000644000004100000410000001430413237614066026703 0ustar www-datawww-data# 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).to eq('Max' => 3) end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/let_before_examples_spec.rb0000644000004100000410000000612713237614066026272 0ustar www-datawww-dataRSpec.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 it 'does not encounter an error when handling an empty describe' do expect { inspect_source('RSpec.describe(User) do end', 'a_spec.rb') } .not_to raise_error 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/overwriting_setup_spec.rb0000644000004100000410000000216613237614066026064 0ustar www-datawww-dataRSpec.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 '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 'does not encounter an error when handling an empty describe' do expect { inspect_source('RSpec.describe(User) do end', 'a_spec.rb') } .not_to raise_error end end rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/subject_stub_spec.rb0000644000004100000410000001160413237614066024756 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/expect_change_spec.rb0000644000004100000410000000372513237614066025064 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/cop/rspec/message_spies_spec.rb0000644000004100000410000001216713237614066025116 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/rspec/0000755000004100000410000000000013237614066020140 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/rspec/hook_spec.rb0000644000004100000410000000325213237614066022441 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/rspec/example_spec.rb0000644000004100000410000000315413237614066023135 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/rspec/wording_spec.rb0000644000004100000410000000440613237614066023154 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/rspec/example_group_spec.rb0000644000004100000410000000153313237614066024350 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/spec/rubocop/rspec/config_formatter_spec.rb0000644000004100000410000000212213237614066025024 0ustar www-datawww-datarequire '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 rubocop-rspec-1.22.2/spec/rubocop/rspec/description_extractor_spec.rb0000644000004100000410000000236213237614066026120 0ustar www-datawww-datarequire '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 rubocop-rspec-1.22.2/spec/rubocop/rspec/util/0000755000004100000410000000000013237614066021115 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/rspec/util/one_spec.rb0000644000004100000410000000134613237614066023241 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/rubocop/rspec/language/0000755000004100000410000000000013237614066021723 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/rubocop/rspec/language/selector_set_spec.rb0000644000004100000410000000243113237614066025755 0ustar www-datawww-dataRSpec.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 _ {:foo :bar} ...)') end end describe '#block_pattern' do it 'builds a block matching pattern' do expect(selector_set.block_pattern).to eql( '(block (send _ {:foo :bar} ...) ...)' ) end end end rubocop-rspec-1.22.2/spec/spec_helper.rb0000644000004100000410000000205613237614066020174 0ustar www-datawww-datarequire 'rubocop' require 'rubocop/rspec/support' if ENV['CI'] 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.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' rubocop-rspec-1.22.2/spec/shared/0000755000004100000410000000000013237614066016621 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/shared/autocorrect_behavior.rb0000644000004100000410000000036013237614066023356 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/shared/detects_style_behavior.rb0000644000004100000410000000040013237614066023672 0ustar www-datawww-dataRSpec.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 rubocop-rspec-1.22.2/spec/project/0000755000004100000410000000000013237614066017021 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/project/project_requires_spec.rb0000644000004100000410000000044313237614066023746 0ustar www-datawww-dataRSpec.describe 'Project requires' do it 'alphabetizes cop requires' do source = SpecHelper::ROOT.join('lib', 'rubocop-rspec.rb').read requires = source.split("\n").grep(%r{rubocop/cop/rspec/[^(?:cop)]}) expect(requires.join("\n")).to eql(requires.sort.join("\n")) end end rubocop-rspec-1.22.2/spec/project/default_config_spec.rb0000644000004100000410000000321313237614066023330 0ustar www-datawww-dataRSpec.describe 'config/default.yml' do subject(:default_config) do RuboCop::ConfigLoader.load_file('config/default.yml') end let(:cop_names) do namespaces = { 'rspec' => 'RSpec', 'capybara' => 'Capybara', 'factory_bot' => 'FactoryBot' } glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec', '{capybara/,,factory_bot/}*.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.sort).to eq(config_keys.sort) 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 rubocop-rspec-1.22.2/spec/project/changelog_spec.rb0000644000004100000410000000402313237614066022306 0ustar www-datawww-dataRSpec.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(/\[(?[#\d]+)\]\((?[^\)]+)\)/) 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 rubocop-rspec-1.22.2/spec/support/0000755000004100000410000000000013237614066017067 5ustar www-datawww-datarubocop-rspec-1.22.2/spec/support/expect_offense.rb0000644000004100000410000000066413237614066022417 0ustar www-datawww-data# 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 rubocop-rspec-1.22.2/lib/0000755000004100000410000000000013237614066015167 5ustar www-datawww-datarubocop-rspec-1.22.2/lib/rubocop/0000755000004100000410000000000013237614066016640 5ustar www-datawww-datarubocop-rspec-1.22.2/lib/rubocop/cop/0000755000004100000410000000000013237614066017421 5ustar www-datawww-datarubocop-rspec-1.22.2/lib/rubocop/cop/rspec_cops.rb0000644000004100000410000000460313237614066022111 0ustar www-datawww-datarequire_relative 'rspec/capybara/current_path_expectation' require_relative 'rspec/capybara/feature_methods' require_relative 'rspec/factory_bot/dynamic_attribute_defined_statically' require_relative 'rspec/align_left_let_brace' require_relative 'rspec/align_right_let_brace' require_relative 'rspec/any_instance' require_relative 'rspec/around_block' require_relative 'rspec/be_eql' require_relative 'rspec/before_after_all' require_relative 'rspec/context_wording' require_relative 'rspec/describe_class' require_relative 'rspec/described_class' require_relative 'rspec/describe_method' require_relative 'rspec/describe_symbol' require_relative 'rspec/empty_example_group' require_relative 'rspec/empty_line_after_final_let' require_relative 'rspec/empty_line_after_subject' require_relative 'rspec/example_length' require_relative 'rspec/example_without_description' require_relative 'rspec/example_wording' require_relative 'rspec/expect_actual' require_relative 'rspec/expect_change' require_relative 'rspec/expect_in_hook' require_relative 'rspec/expect_output' require_relative 'rspec/file_path' require_relative 'rspec/focus' require_relative 'rspec/hook_argument' require_relative 'rspec/implicit_expect' require_relative 'rspec/instance_spy' require_relative 'rspec/instance_variable' require_relative 'rspec/invalid_predicate_matcher' require_relative 'rspec/it_behaves_like' require_relative 'rspec/iterated_expectation' require_relative 'rspec/leading_subject' require_relative 'rspec/let_before_examples' require_relative 'rspec/let_setup' require_relative 'rspec/message_chain' require_relative 'rspec/message_expectation' require_relative 'rspec/message_spies' require_relative 'rspec/multiple_describes' require_relative 'rspec/multiple_expectations' require_relative 'rspec/multiple_subjects' require_relative 'rspec/named_subject' require_relative 'rspec/nested_groups' require_relative 'rspec/not_to_not' require_relative 'rspec/overwriting_setup' require_relative 'rspec/predicate_matcher' require_relative 'rspec/repeated_description' require_relative 'rspec/repeated_example' require_relative 'rspec/return_from_stub' require_relative 'rspec/scattered_let' require_relative 'rspec/scattered_setup' require_relative 'rspec/shared_context' require_relative 'rspec/single_argument_message_chain' require_relative 'rspec/subject_stub' require_relative 'rspec/verified_doubles' require_relative 'rspec/void_expect' rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/0000755000004100000410000000000013237614066020535 5ustar www-datawww-datarubocop-rspec-1.22.2/lib/rubocop/cop/rspec/named_subject.rb0000644000004100000410000000367213237614066023675 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for explicitly referenced test subjects. # # RSpec lets you declare an "implicit subject" using `subject { ... }` # which allows for tests like `it { should be_valid }`. If you need to # reference your test subject you should explicitly name it using # `subject(:your_subject_name) { ... }`. Your test subjects should be # the most important object in your tests so they deserve a descriptive # name. # # @example # # bad # RSpec.describe User do # subject { described_class.new } # # it 'is valid' do # expect(subject.valid?).to be(true) # end # end # # # good # RSpec.describe Foo do # subject(:user) { described_class.new } # # it 'is valid' do # expect(user.valid?).to be(true) # end # end # # # also good # RSpec.describe Foo do # subject(:user) { described_class.new } # # it { should be_valid } # end class NamedSubject < Cop MSG = 'Name your test subject if you need '\ 'to reference it explicitly.'.freeze def_node_matcher :rspec_block?, <<-PATTERN { #{Examples::ALL.block_pattern} #{Hooks::ALL.block_pattern} } PATTERN def_node_matcher :unnamed_subject, '$(send nil? :subject)' def on_block(node) return unless rspec_block?(node) subject_usage(node) do |subject_node| add_offense(subject_node, location: :selector) end end private def subject_usage(node, &block) unnamed_subject(node, &block) node.each_child_node do |child| subject_usage(child, &block) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/described_class.rb0000644000004100000410000000674313237614066024205 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that tests use `described_class`. # # If the first argument of describe is a class, the class is exposed to # each example via described_class. # # This cop can be configured using the `EnforcedStyle` option # # @example `EnforcedStyle: described_class` # # bad # describe MyClass do # subject { MyClass.do_something } # end # # # good # describe MyClass do # subject { described_class.do_something } # end # # @example `EnforcedStyle: explicit` # # bad # describe MyClass do # subject { described_class.do_something } # end # # # good # describe MyClass do # subject { MyClass.do_something } # end # class DescribedClass < Cop include RuboCop::RSpec::TopLevelDescribe include ConfigurableEnforcedStyle DESCRIBED_CLASS = 'described_class'.freeze MSG = 'Use `%s` instead of `%s`.'.freeze def_node_matcher :common_instance_exec_closure?, <<-PATTERN (block (send (const nil? {:Class :Module}) :new ...) ...) PATTERN def_node_matcher :rspec_block?, RuboCop::RSpec::Language::ALL.block_pattern def_node_matcher :scope_changing_syntax?, '{def class module}' def on_block(node) # In case the explicit style is used, we needs to remember what's # being described. Thus, we use an ivar for @described_class. describe, @described_class, body = described_constant(node) return if body.nil? return unless top_level_describe?(describe) find_usage(body) do |match| add_offense( match, location: :expression, message: message(match.const_name) ) end end def autocorrect(node) replacement = if style == :described_class DESCRIBED_CLASS else @described_class.const_name end lambda do |corrector| corrector.replace(node.loc.expression, replacement) end end private def find_usage(node, &block) yield(node) if offensive?(node) return if scope_change?(node) || node.const_type? node.each_child_node do |child| find_usage(child, &block) end end def message(offense) if style == :described_class format(MSG, replacement: DESCRIBED_CLASS, src: offense) else format(MSG, replacement: @described_class.const_name, src: DESCRIBED_CLASS) end end def scope_change?(node) scope_changing_syntax?(node) || common_instance_exec_closure?(node) || skippable_block?(node) end def skippable_block?(node) node.block_type? && !rspec_block?(node) && skip_blocks? end def skip_blocks? cop_config['SkipBlocks'].equal?(true) end def offensive?(node) if style == :described_class node.eql?(@described_class) else node.method_name == :described_class end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/multiple_describes.rb0000644000004100000410000000203313237614066024736 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for multiple top level describes. # # Multiple descriptions for the same class or module should either # be nested or separated into different test files. # # @example # # bad # describe MyClass, '.do_something' do # end # describe MyClass, '.do_something_else' do # end # # # good # describe MyClass do # describe '.do_something' do # end # describe '.do_something_else' do # end # end class MultipleDescribes < Cop include RuboCop::RSpec::TopLevelDescribe MSG = 'Do not use multiple top level describes - '\ 'try to nest them.'.freeze def on_top_level_describe(node, _args) return if single_top_level_describe? return unless top_level_nodes.first.equal?(node) add_offense(node, location: :expression) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/empty_line_after_subject.rb0000644000004100000410000000230613237614066026130 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if there is an empty line after subject block. # # @example # # bad # subject(:obj) { described_class } # let(:foo) { bar } # # # good # subject(:obj) { described_class } # # let(:foo) { bar } class EmptyLineAfterSubject < Cop MSG = 'Add empty line after `subject`.'.freeze def_node_matcher :subject?, '(block $(send nil? :subject ...) args ...)' def on_block(node) return unless subject?(node) && !in_spec_block?(node) return if node.equal?(node.parent.children.last) send_line = node.loc.end.line next_line = processed_source[send_line] return if next_line.blank? add_offense(node, location: :expression, message: MSG) end def autocorrect(node) ->(corrector) { corrector.insert_after(node.loc.end, "\n") } end private def in_spec_block?(node) node.each_ancestor(:block).any? do |ancestor| Examples::ALL.include?(ancestor.method_name) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/leading_subject.rb0000644000004100000410000000404413237614066024206 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for `subject` definitions that come after `let` definitions. # # @example # # bad # RSpec.describe User do # let(:params) { blah } # subject { described_class.new(params) } # # it 'is valid' do # expect(subject.valid?).to be(true) # end # end # # # good # RSpec.describe User do # subject { described_class.new(params) } # # let(:params) { blah } # # it 'is valid' do # expect(subject.valid?).to be(true) # end # end class LeadingSubject < Cop MSG = 'Declare `subject` above any other `let` declarations.'.freeze def_node_matcher :subject?, '(block $(send nil? :subject ...) args ...)' def on_block(node) return unless subject?(node) && !in_spec_block?(node) node.parent.each_child_node do |sibling| break if sibling.equal?(node) break add_offense(node, location: :expression) if let?(sibling) end end def autocorrect(node) lambda do |corrector| first_let = find_first_let(node) first_let_position = first_let.loc.expression indent = "\n" + ' ' * first_let.loc.column corrector.insert_before(first_let_position, node.source + indent) corrector.remove(node_range(node)) end end private def let?(node) %i[let let!].include?(node.method_name) end def find_first_let(node) node.parent.children.find { |sibling| let?(sibling) } end def node_range(node) range_by_whole_lines(node.source_range, include_final_newline: true) end def in_spec_block?(node) node.each_ancestor(:block).any? do |ancestor| Examples::ALL.include?(ancestor.method_name) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/scattered_let.rb0000644000004100000410000000245513237614066023712 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for let scattered across the example group. # # Group lets together # # @example # # bad # describe Foo do # let(:foo) { 1 } # subject { Foo } # let(:bar) { 2 } # before { prepare } # let!(:baz) { 3 } # end # # # good # describe Foo do # subject { Foo } # before { prepare } # let(:foo) { 1 } # let(:bar) { 2 } # let!(:baz) { 3 } # end # class ScatteredLet < Cop MSG = 'Group all let/let! blocks in the example group together.'.freeze def_node_matcher :let?, '(block (send nil? {:let :let!} ...) ...)' def on_block(node) return unless example_group_with_body?(node) check_let_declarations(node.body) end private def check_let_declarations(body) lets = body.each_child_node.select { |node| let?(node) } first_let = lets.first lets.each_with_index do |node, idx| next if node.sibling_index == first_let.sibling_index + idx add_offense(node, location: :expression) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/return_from_stub.rb0000644000004100000410000001137613237614066024471 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for consistent style of stub's return setting. # # Enforces either `and_return` or block-style return in the cases # where the returned value is constant. Ignores dynamic returned values # are the result would be different # # This cop can be configured using the `EnforcedStyle` option # # @example `EnforcedStyle: block` # # bad # allow(Foo).to receive(:bar).and_return("baz") # expect(Foo).to receive(:bar).and_return("baz") # # # good # allow(Foo).to receive(:bar) { "baz" } # expect(Foo).to receive(:bar) { "baz" } # # also good as the returned value is dynamic # allow(Foo).to receive(:bar).and_return(bar.baz) # # @example `EnforcedStyle: and_return` # # bad # allow(Foo).to receive(:bar) { "baz" } # expect(Foo).to receive(:bar) { "baz" } # # # good # allow(Foo).to receive(:bar).and_return("baz") # expect(Foo).to receive(:bar).and_return("baz") # # also good as the returned value is dynamic # allow(Foo).to receive(:bar) { bar.baz } # class ReturnFromStub < Cop include ConfigurableEnforcedStyle MSG_AND_RETURN = 'Use `and_return` for static values.'.freeze MSG_BLOCK = 'Use block for static values.'.freeze def_node_search :contains_stub?, '(send nil? :receive (...))' def_node_search :and_return_value, <<-PATTERN $(send _ :and_return $(...)) PATTERN def on_send(node) return unless contains_stub?(node) return unless style == :block check_and_return_call(node) end def on_block(node) return unless contains_stub?(node) return unless style == :and_return check_block_body(node) end def autocorrect(node) if style == :block AndReturnCallCorrector.new(node) else BlockBodyCorrector.new(node) end end private def check_and_return_call(node) and_return_value(node) do |and_return, args| unless dynamic?(args) add_offense( and_return, location: :selector, message: MSG_BLOCK ) end end end def check_block_body(block) body = block.body unless body && dynamic?(body) # rubocop:disable Style/GuardClause add_offense( block, location: :begin, message: MSG_AND_RETURN ) end end def dynamic?(node) !node.recursive_literal? end # :nodoc: class AndReturnCallCorrector def initialize(node) @node = node @receiver, _method_name, @args = *node end def call(corrector) # Heredoc autocorrection is not yet implemented. return if heredoc? corrector.replace(range, " { #{replacement} }") end private attr_reader :node, :receiver, :args def heredoc? args.loc.is_a?(Parser::Source::Map::Heredoc) end def range Parser::Source::Range.new( node.source_range.source_buffer, receiver.source_range.end_pos, node.source_range.end_pos ) end def replacement if hash_without_braces? "{ #{args.source} }" else args.source end end def hash_without_braces? args.hash_type? && !args.braces? end end # :nodoc: class BlockBodyCorrector def initialize(block) @block = block @node = block.parent @body = block.body || NULL_BLOCK_BODY end def call(corrector) # Heredoc autocorrection is not yet implemented. return if heredoc? corrector.replace( block.loc.expression, "#{block.send_node.source}.and_return(#{body.source})" ) end private attr_reader :node, :block, :body def range Parser::Source::Range.new( block.source_range.source_buffer, node.source_range.end_pos, block.source_range.end_pos ) end def heredoc? body.loc.is_a?(Parser::Source::Map::Heredoc) end NULL_BLOCK_BODY = Struct.new(:loc, :source).new(nil, 'nil') end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/repeated_description.rb0000644000004100000410000000275113237614066025263 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Check for repeated description strings in example groups. # # @example # # # bad # RSpec.describe User do # it 'is valid' do # # ... # end # # it 'is valid' do # # ... # end # end # # # good # RSpec.describe User do # it 'is valid when first and last name are present' do # # ... # end # # it 'is valid when last name only is present' do # # ... # end # end # class RepeatedDescription < Cop MSG = "Don't repeat descriptions within an example group.".freeze def on_block(node) return unless example_group?(node) repeated_descriptions(node).each do |repeated_description| add_offense(repeated_description, location: :expression) end end private # Select examples in the current scope with repeated description strings def repeated_descriptions(node) grouped_examples = RuboCop::RSpec::ExampleGroup.new(node) .examples .group_by(&:doc_string) grouped_examples .select { |description, group| description && group.size > 1 } .values .flatten .map(&:definition) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/example_without_description.rb0000644000004100000410000000506113237614066026705 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for examples without a description. # # RSpec allows for auto-generated example descriptions when there is no # description provided or the description is an empty one. # # This cop removes empty descriptions. # It also defines whether auto-generated description is allowed, based # on the configured style. # # This cop can be configured using the `EnforcedStyle` option # # @example `EnforcedStyle: always_allow` # # bad # it('') { is_expected.to be_good } # it '' do # result = service.call # expect(result).to be(true) # end # # # good # it { is_expected.to be_good } # it do # result = service.call # expect(result).to be(true) # end # # @example `EnforcedStyle: single_line_only` # # bad # it('') { is_expected.to be_good } # it do # result = service.call # expect(result).to be(true) # end # # # good # it { is_expected.to be_good } # # @example `EnforcedStyle: disallow` # # bad # it { is_expected.to be_good } # it do # result = service.call # expect(result).to be(true) # end class ExampleWithoutDescription < Cop include ConfigurableEnforcedStyle MSG_DEFAULT_ARGUMENT = 'Omit the argument when you want to ' \ 'have auto-generated description.'.freeze MSG_ADD_DESCRIPTION = 'Add a description.'.freeze def_node_matcher :example?, Examples::ALL.send_pattern def_node_matcher :example_description, '(send nil? _ $(str $_))' def on_send(node) return unless example?(node) check_example_without_description(node) example_description(node) do |message_node, message| return unless message.to_s.empty? add_offense(message_node, message: MSG_DEFAULT_ARGUMENT) end end private def check_example_without_description(node) _send, _method, arg = *node return unless arg.nil? return unless disallow_empty_description?(node) add_offense(node, message: MSG_ADD_DESCRIPTION) end def disallow_empty_description?(node) style == :disallow || (style == :single_line_only && node.parent.multiline?) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/describe_symbol.rb0000644000004100000410000000140113237614066024223 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Avoid describing symbols. # # @example # # bad # describe :my_method do # ... # end # # # good # describe '#my_method' do # ... # end # # @see https://github.com/rspec/rspec-core/issues/1610 class DescribeSymbol < Cop MSG = 'Avoid describing symbols.'.freeze def_node_matcher :describe_symbol?, <<-PATTERN (send {(const nil? :RSpec) nil?} :describe $sym ...) PATTERN def on_send(node) describe_symbol?(node) do |match| add_offense(match, location: :expression) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/message_spies.rb0000644000004100000410000000437413237614066023721 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that message expectations are set using spies. # # This cop can be configured in your configuration using the # `EnforcedStyle` option and supports `--auto-gen-config`. # # @example `EnforcedStyle: have_received` # # # bad # expect(foo).to receive(:bar) # # # good # expect(foo).to have_received(:bar) # # @example `EnforcedStyle: receive` # # # bad # expect(foo).to have_received(:bar) # # # good # expect(foo).to receive(:bar) # class MessageSpies < Cop include ConfigurableEnforcedStyle MSG_RECEIVE = 'Prefer `receive` for setting message '\ 'expectations.'.freeze MSG_HAVE_RECEIVED = 'Prefer `have_received` for setting message '\ 'expectations. Setup `%s` as a spy using '\ '`allow` or `instance_spy`.'.freeze SUPPORTED_STYLES = %w[have_received receive].freeze def_node_matcher :message_expectation, %( (send (send nil? :expect $_) {:to :to_not :not_to} ...) ) def_node_search :receive_message, %( $(send nil? {:receive :have_received} ...) ) def on_send(node) receive_message_matcher(node) do |receiver, message_matcher| return correct_style_detected if preferred_style?(message_matcher) add_offense( message_matcher, location: :selector, message: error_message(receiver) ) { opposite_style_detected } end end private def receive_message_matcher(node) return unless (receiver = message_expectation(node)) receive_message(node) { |match| yield(receiver, match) } end def preferred_style?(expectation) expectation.method_name.equal?(style) end def error_message(receiver) case style when :receive MSG_RECEIVE when :have_received format(MSG_HAVE_RECEIVED, source: receiver.source) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/implicit_expect.rb0000644000004100000410000000545413237614066024254 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Check that a consistent implicit expectation style is used. # # This cop can be configured using the `EnforcedStyle` option # and supports the `--auto-gen-config` flag. # # @example `EnforcedStyle: is_expected` # # # bad # it { should be_truthy } # # # good # it { is_expected.to be_truthy } # # @example `EnforcedStyle: should` # # # bad # it { is_expected.to be_truthy } # # # good # it { should be_truthy } # class ImplicitExpect < Cop include ConfigurableEnforcedStyle MSG = 'Prefer `%s` over `%s`.'.freeze def_node_matcher :implicit_expect, <<-PATTERN { (send nil? ${:should :should_not} ...) (send (send nil? $:is_expected) {:to :to_not :not_to} ...) } PATTERN alternatives = { 'is_expected.to' => 'should', 'is_expected.not_to' => 'should_not', 'is_expected.to_not' => 'should_not' } ENFORCED_REPLACEMENTS = alternatives.merge(alternatives.invert).freeze def on_send(node) # rubocop:disable Metrics/MethodLength return unless (source_range = offending_expect(node)) expectation_source = source_range.source if expectation_source.start_with?(style.to_s) correct_style_detected else opposite_style_detected add_offense( node, location: source_range, message: offense_message(expectation_source) ) end end def autocorrect(node) lambda do |corrector| offense = offending_expect(node) replacement = replacement_source(offense.source) corrector.replace(offense, replacement) end end private def offending_expect(node) case implicit_expect(node) when :is_expected is_expected_range(node.loc) when :should, :should_not node.loc.selector end end def is_expected_range(source_map) # rubocop:disable PredicateName Parser::Source::Range.new( source_map.expression.source_buffer, source_map.expression.begin_pos, source_map.selector.end_pos ) end def offense_message(offending_source) format( MSG, good: replacement_source(offending_source), bad: offending_source ) end def replacement_source(offending_source) ENFORCED_REPLACEMENTS.fetch(offending_source) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/nested_groups.rb0000644000004100000410000000734013237614066023747 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for nested example groups. # # This cop is configurable using the `Max` option # # @example # # bad # context 'when using some feature' do # let(:some) { :various } # let(:feature) { :setup } # # context 'when user is signed in' do # flagged by rubocop # let(:user) do # UserCreate.call(user_attributes) # end # # let(:user_attributes) do # { # name: 'John', # age: 22, # role: role # } # end # # context 'when user is an admin' do # flagged by rubocop # let(:role) { 'admin' } # # it 'blah blah' # it 'yada yada' # end # end # end # # # better # context 'using some feature as an admin' do # let(:some) { :various } # let(:feature) { :setup } # # let(:user) do # UserCreate.call( # name: 'John', # age: 22, # role: 'admin' # ) # end # # it 'blah blah' # it 'yada yada' # end # # @example configuration # # # .rubocop.yml # RSpec/NestedGroups: # Max: 2 # # context 'when using some feature' do # let(:some) { :various } # let(:feature) { :setup } # # context 'when user is signed in' do # let(:user) do # UserCreate.call(user_attributes) # end # # let(:user_attributes) do # { # name: 'John', # age: 22 # role: role # } # end # # context 'when user is an admin' do # flagged by rubocop # let(:role) { 'admin' } # # it 'blah blah' # it 'yada yada' # end # end # end # class NestedGroups < Cop include RuboCop::RSpec::TopLevelDescribe MSG = 'Maximum example group nesting exceeded ' \ '[%d/%d].'.freeze DEPRECATED_MAX_KEY = 'MaxNesting'.freeze DEPRECATION_WARNING = "Configuration key `#{DEPRECATED_MAX_KEY}` for #{cop_name} is " \ 'deprecated in favor of `Max`. Please use that instead.'.freeze def_node_search :find_contexts, ExampleGroups::ALL.block_pattern def on_top_level_describe(node, _) find_nested_contexts(node.parent) do |context, nesting| add_offense( context.children.first, location: :expression, message: message(nesting) ) end end private def find_nested_contexts(node, nesting: 1, &block) find_contexts(node) do |nested_context| yield(nested_context, nesting) if nesting > max_nesting nested_context.each_child_node do |child| find_nested_contexts(child, nesting: nesting + 1, &block) end end end def message(nesting) format(MSG, total: nesting, max: max_nesting) end def max_nesting @max_nesting ||= Integer(max_nesting_config) end def max_nesting_config if cop_config.key?(DEPRECATED_MAX_KEY) warn DEPRECATION_WARNING cop_config.fetch(DEPRECATED_MAX_KEY) else cop_config.fetch('Max', 3) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/scattered_setup.rb0000644000004100000410000000231113237614066024255 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for setup scattered across multiple hooks in an example group. # # Unify `before`, `after`, and `around` hooks when possible. # # @example # # bad # describe Foo do # before { setup1 } # before { setup2 } # end # # # good # describe Foo do # before do # setup1 # setup2 # end # end # class ScatteredSetup < Cop MSG = 'Do not define multiple hooks in the same example group.'.freeze def on_block(node) return unless example_group?(node) analyzable_hooks(node).each do |repeated_hook| add_offense(repeated_hook, location: :expression) end end def analyzable_hooks(node) RuboCop::RSpec::ExampleGroup.new(node) .hooks .select { |hook| hook.knowable_scope? && hook.valid_scope? } .group_by { |hook| [hook.name, hook.scope] } .values .reject(&:one?) .flatten .map(&:to_node) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/multiple_subjects.rb0000644000004100000410000000442313237614066024622 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if an example group defines `subject` multiple times. # # @example # # # bad # describe Foo do # subject(:user) { User.new } # subject(:post) { Post.new } # end # # # good # describe Foo do # let(:user) { User.new } # subject(:post) { Post.new } # end # # The autocorrect behavior for this cop depends on the type of # duplication: # # - If multiple named subjects are defined then this probably indicates # that the overwritten subjects (all subjects except the last # definition) are effectively being used to define helpers. In this # case they are replaced with `let`. # # - If multiple unnamed subjects are defined though then this can *only* # be dead code and we remove the overwritten subject definitions. # # - If subjects are defined with `subject!` then we don't autocorrect. # This is enough of an edge case that people can just move this to # a `before` hook on their own class MultipleSubjects < Cop MSG = 'Do not set more than one subject per example group'.freeze def_node_matcher :named_subject?, <<-PATTERN (block (send nil? :subject $sym) args ...) PATTERN def on_block(node) return unless example_group?(node) subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects subjects[0...-1].each do |subject| add_offense(subject, location: :expression) end end def autocorrect(node) return unless node.method_name.equal?(:subject) # Ignore `subject!` if named_subject?(node) rename_autocorrect(node) else remove_autocorrect(node) end end private def rename_autocorrect(node) lambda do |corrector| corrector.replace(node.send_node.loc.selector, 'let') end end def remove_autocorrect(node) lambda do |corrector| corrector.remove(node.loc.expression) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/repeated_example.rb0000644000004100000410000000232713237614066024372 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Check for repeated examples within example groups. # # @example # # it 'is valid' do # expect(user).to be_valid # end # # it 'validates the user' do # expect(user).to be_valid # end # class RepeatedExample < Cop MSG = "Don't repeat examples within an example group.".freeze def on_block(node) return unless example_group?(node) repeated_examples(node).each do |repeated_example| add_offense(repeated_example, location: :expression) end end private def repeated_examples(node) RuboCop::RSpec::ExampleGroup.new(node) .examples .group_by { |example| example_signature(example) } .values .reject(&:one?) .flatten .map(&:to_node) end def example_signature(example) key_parts = [example.metadata, example.implementation] if example.definition.method_name == :its key_parts << example.definition.arguments end key_parts end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/empty_line_after_final_let.rb0000644000004100000410000000334713237614066026434 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if there is an empty line after the last let block. # # @example # # bad # let(:foo) { bar } # let(:something) { other } # it { does_something } # # # good # let(:foo) { bar } # let(:something) { other } # # it { does_something } class EmptyLineAfterFinalLet < Cop MSG = 'Add an empty line after the last `let` block.'.freeze def_node_matcher :let?, '(block $(send nil? {:let :let!} ...) args ...)' def on_block(node) return unless example_group_with_body?(node) latest_let = node.body.child_nodes.select { |child| let?(child) }.last return if latest_let.nil? return if latest_let.equal?(node.body.children.last) no_new_line_after(latest_let) do add_offense(latest_let, location: :expression) end end def autocorrect(node) loc = last_node_loc(node) ->(corrector) { corrector.insert_after(loc.end, "\n") } end private def no_new_line_after(node) loc = last_node_loc(node) next_line = processed_source[loc.line] yield unless next_line.blank? end def last_node_loc(node) last_line = node.loc.end.line heredoc_line(node) do |loc| return loc if loc.line > last_line end node.loc.end end def heredoc_line(node, &block) yield node.loc.heredoc_end if node.loc.respond_to?(:heredoc_end) node.each_child_node { |child| heredoc_line(child, &block) } end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/it_behaves_like.rb0000644000004100000410000000235113237614066024200 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that only one `it_behaves_like` style is used. # # @example when configuration is `EnforcedStyle: it_behaves_like` # # bad # it_should_behave_like 'a foo' # # # good # it_behaves_like 'a foo' # # @example when configuration is `EnforcedStyle: it_should_behave_like` # # bad # it_behaves_like 'a foo' # # # good # it_should_behave_like 'a foo' class ItBehavesLike < Cop include ConfigurableEnforcedStyle MSG = 'Prefer `%s` over `%s` when including '\ 'examples in a nested context.'.freeze def_node_matcher :example_inclusion_offense, '(send _ % ...)' def on_send(node) example_inclusion_offense(node, alternative_style) do add_offense(node, location: :expression) end end def autocorrect(node) ->(corrector) { corrector.replace(node.loc.selector, style.to_s) } end private def message(_node) format(MSG, replacement: style, original: alternative_style) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/multiple_expectations.rb0000644000004100000410000000631413237614066025507 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if examples contain too many `expect` calls. # # @see http://betterspecs.org/#single Single expectation test # # This cop is configurable using the `Max` option # and works with `--auto-gen-config`. # # @example # # # bad # describe UserCreator do # it 'builds a user' do # expect(user.name).to eq("John") # expect(user.age).to eq(22) # end # end # # # good # describe UserCreator do # it 'sets the users name' do # expect(user.name).to eq("John") # end # # it 'sets the users age' do # expect(user.age).to eq(22) # end # end # # @example configuration # # # .rubocop.yml # RSpec/MultipleExpectations: # Max: 2 # # # not flagged by rubocop # describe UserCreator do # it 'builds a user' do # expect(user.name).to eq("John") # expect(user.age).to eq(22) # end # end # class MultipleExpectations < Cop include ConfigurableMax MSG = 'Example has too many expectations [%d/%d].'.freeze def_node_search :with_aggregated_failures?, '(sym :aggregate_failures)' def_node_search :disabled_aggregated_failures?, <<-PATTERN (pair (sym :aggregate_failures) (false)) PATTERN def_node_matcher :expect?, Expectations::ALL.send_pattern def_node_matcher :aggregate_failures?, <<-PATTERN (block (send _ :aggregate_failures ...) ...) PATTERN def on_block(node) return unless example?(node) return if example_with_aggregated_failures?(node) expectations_count = to_enum(:find_expectation, node).count return if expectations_count <= max_expectations self.max = expectations_count flag_example(node, expectation_count: expectations_count) end private def example_with_aggregated_failures?(node) example = node.children.first (aggregated_failures_by_default? || with_aggregated_failures?(example)) && !disabled_aggregated_failures?(example) end def find_expectation(node, &block) yield if expect?(node) || aggregate_failures?(node) # do not search inside of aggregate_failures block return if aggregate_failures?(node) node.each_child_node do |child| find_expectation(child, &block) end end def flag_example(node, expectation_count:) add_offense( node.send_node, location: :expression, message: format( MSG, total: expectation_count, max: max_expectations ) ) end def max_expectations Integer(cop_config.fetch('Max', 1)) end def aggregated_failures_by_default? cop_config.fetch('AggregateFailuresByDefault', false) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/void_expect.rb0000644000004100000410000000231613237614066023375 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # This cop checks void `expect()`. # # @example # # bad # expect(something) # # # good # expect(something).to be(1) class VoidExpect < Cop MSG = 'Do not use `expect()` without `.to` or `.not_to`. ' \ 'Chain the methods or remove it.'.freeze def_node_matcher :expect?, <<-PATTERN (send nil? :expect ...) PATTERN def_node_matcher :expect_block?, <<-PATTERN (block #expect? (args) _body) PATTERN def on_send(node) return unless expect?(node) check_expect(node) end def on_block(node) return unless expect_block?(node) check_expect(node) end private def check_expect(node) return unless void?(node) add_offense(node, location: :expression) end def void?(expect) parent = expect.parent return true unless parent return true if parent.begin_type? return true if parent.block_type? && parent.children[2] == expect end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/file_path.rb0000644000004100000410000000641713237614066023025 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that spec file paths are consistent with the test subject. # # Checks the path of the spec file and enforces that it reflects the # described class/module and its optionally called out method. # # With the configuration option `IgnoreMethods` the called out method will # be ignored when determining the enforced path. # # With the configuration option `CustomTransform` modules or classes can # be specified that should not as usual be transformed from CamelCase to # snake_case (e.g. 'RuboCop' => 'rubocop' ). # # @example # # bad # whatever_spec.rb # describe MyClass # # # bad # my_class_spec.rb # describe MyClass, '#method' # # # good # my_class_spec.rb # describe MyClass # # # good # my_class_method_spec.rb # describe MyClass, '#method' # # # good # my_class/method_spec.rb # describe MyClass, '#method' # # @example when configuration is `IgnoreMethods: true` # # bad # whatever_spec.rb # describe MyClass # # # good # my_class_spec.rb # describe MyClass # # # good # my_class_spec.rb # describe MyClass, '#method' # class FilePath < Cop include RuboCop::RSpec::TopLevelDescribe MSG = 'Spec path should end with `%s`.'.freeze def_node_search :const_described?, '(send _ :describe (const ...) ...)' def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))' def on_top_level_describe(node, args) return unless const_described?(node) && single_top_level_describe? return if routing_spec?(args) glob = glob_for(args) return if filename_ends_with?(glob) add_offense( node, location: :expression, message: format(MSG, suffix: glob) ) end private def routing_spec?(args) args.any?(&method(:routing_metadata?)) end def glob_for((described_class, method_name)) "#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb" end def name_glob(name) return unless name && name.str_type? "*#{name.str_content.gsub(/\W/, '')}" unless ignore_methods? end def expected_path(constant) File.join( constant.const_name.split('::').map do |name| custom_transform.fetch(name) { camel_to_snake_case(name) } end ) end def camel_to_snake_case(string) string .gsub(/([^A-Z])([A-Z]+)/, '\1_\2') .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2') .downcase end def custom_transform cop_config.fetch('CustomTransform', {}) end def ignore_methods? cop_config['IgnoreMethods'] end def filename_ends_with?(glob) File.fnmatch?("*#{glob}", processed_source.buffer.name) end def relevant_rubocop_rspec_file?(_) true end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/example_wording.rb0000644000004100000410000000471013237614066024250 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for common mistakes in example descriptions. # # This cop will correct docstrings that begin with 'should' and 'it'. # # @see http://betterspecs.org/#should # # The autocorrect is experimental - use with care! It can be configured # with CustomTransform (e.g. have => has) and IgnoredWords (e.g. only). # # @example # # bad # it 'should find nothing' do # end # # # good # it 'finds nothing' do # end # # @example # # bad # it 'it does things' do # end # # # good # it 'does things' do # end class ExampleWording < Cop MSG_SHOULD = 'Do not use should when describing your tests.'.freeze MSG_IT = "Do not repeat 'it' when describing your tests.".freeze SHOULD_PREFIX = /\Ashould(?:n't)?\b/i IT_PREFIX = /\Ait /i def_node_matcher( :it_description, '(block (send _ :it $(str $_) ...) ...)' ) def on_block(node) it_description(node) do |description_node, message| if message =~ SHOULD_PREFIX add_wording_offense(description_node, MSG_SHOULD) elsif message =~ IT_PREFIX add_wording_offense(description_node, MSG_IT) end end end def autocorrect(range) ->(corrector) { corrector.replace(range, replacement_text(range)) } end private def add_wording_offense(node, message) expr = node.loc.expression docstring = Parser::Source::Range.new( expr.source_buffer, expr.begin_pos + 1, expr.end_pos - 1 ) add_offense(docstring, location: docstring, message: message) end def replacement_text(range) text = range.source if text =~ SHOULD_PREFIX RuboCop::RSpec::Wording.new( text, ignore: ignored_words, replace: custom_transform ).rewrite else text.sub(IT_PREFIX, '') end end def custom_transform cop_config.fetch('CustomTransform', {}) end def ignored_words cop_config.fetch('IgnoredWords', []) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/cop.rb0000644000004100000410000000515613237614066021652 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop # rubocop:disable Style/Documentation WorkaroundCop = Cop.dup # Clone of the the normal RuboCop::Cop::Cop class so we can rewrite # the inherited method without breaking functionality class WorkaroundCop # Remove the Cop.inherited method to be a noop. Our RSpec::Cop # class will invoke the inherited hook instead class << self undef inherited def inherited(*) end end # Special case `Module#<` so that the rspec support rubocop exports # is compatible with our subclass def self.<(other) other.equal?(RuboCop::Cop::Cop) || super end end private_constant(:WorkaroundCop) module RSpec # @abstract parent class to rspec cops # # The criteria for whether rubocop-rspec analyzes a certain ruby file # is configured via `AllCops/RSpec`. For example, if you want to # customize your project to scan all files within a `test/` directory # then you could add this to your configuration: # # @example configuring analyzed paths # # AllCops: # RSpec: # Patterns: # - '_test.rb$' # - '(?:^|/)test/' class Cop < WorkaroundCop include RuboCop::RSpec::Language include RuboCop::RSpec::Language::NodePattern DEFAULT_CONFIGURATION = RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec') DEFAULT_PATTERN_RE = Regexp.union( DEFAULT_CONFIGURATION.fetch('Patterns') .map(&Regexp.public_method(:new)) ) # Invoke the original inherited hook so our cops are recognized def self.inherited(subclass) RuboCop::Cop::Cop.inherited(subclass) end def relevant_file?(file) relevant_rubocop_rspec_file?(file) && super end private def relevant_rubocop_rspec_file?(file) rspec_pattern =~ file end def rspec_pattern if rspec_pattern_config? Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new))) else DEFAULT_PATTERN_RE end end def all_cops_config config .for_all_cops end def rspec_pattern_config? return unless all_cops_config.key?('RSpec') all_cops_config.fetch('RSpec').key?('Patterns') end def rspec_pattern_config all_cops_config .fetch('RSpec', DEFAULT_CONFIGURATION) .fetch('Patterns') end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/expect_actual.rb0000644000004100000410000000317013237614066023704 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for `expect(...)` calls containing literal values. # # @example # # bad # expect(5).to eq(price) # expect(/foo/).to eq(pattern) # expect("John").to eq(name) # # # good # expect(price).to eq(5) # expect(pattern).to eq(/foo/) # expect(name).to eq("John") # class ExpectActual < Cop MSG = 'Provide the actual you are testing to `expect(...)`.'.freeze SIMPLE_LITERALS = %i[ true false nil int float str sym complex rational regopt ].freeze COMPLEX_LITERALS = %i[ array hash pair irange erange regexp ].freeze def_node_matcher :expect_literal, '(send _ :expect $#literal?)' def on_send(node) expect_literal(node) do |argument| add_offense(argument, location: :expression) end end private # This is not implement using a NodePattern because it seems # to not be able to match against an explicit (nil) sexp def literal?(node) node && (simple_literal?(node) || complex_literal?(node)) end def simple_literal?(node) SIMPLE_LITERALS.include?(node.type) end def complex_literal?(node) COMPLEX_LITERALS.include?(node.type) && node.each_child_node.all?(&method(:literal?)) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/predicate_matcher.rb0000644000004100000410000002463713237614066024541 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # A helper for `inflected` style module InflectedHelper extend NodePattern::Macros MSG_INFLECTED = 'Prefer using `%s` matcher over ' \ '`%s`.'.freeze private def check_inflected(node) predicate_in_actual?(node) do |predicate| add_offense( node, location: :expression, message: message_inflected(predicate) ) end end def_node_matcher :predicate_in_actual?, <<-PATTERN (send (send nil? :expect { (block $(send !nil? #predicate? ...) ...) $(send !nil? #predicate? ...)}) ${:to :not_to :to_not} $#boolean_matcher?) PATTERN def_node_matcher :be_bool?, <<-PATTERN (send nil? {:be :eq :eql :equal} {true false}) PATTERN def_node_matcher :be_boolthy?, <<-PATTERN (send nil? {:be_truthy :be_falsey :be_falsy :a_truthy_value :a_falsey_value :a_falsy_value}) PATTERN def boolean_matcher?(node) if cop_config['Strict'] be_boolthy?(node) else be_bool?(node) || be_boolthy?(node) end end def predicate?(sym) sym.to_s.end_with?('?') end def message_inflected(predicate) _recv, predicate_name, = *predicate format(MSG_INFLECTED, predicate_name: predicate_name, matcher_name: to_predicate_matcher(predicate_name)) end # rubocop:disable Metrics/MethodLength def to_predicate_matcher(name) case name = name.to_s when 'is_a?' 'be_a' when 'instance_of?' 'be_an_instance_of' when 'include?', 'respond_to?' name[0..-2] when /^has_/ name.sub('has_', 'have_')[0..-2] else "be_#{name[0..-2]}" end end # rubocop:enable Metrics/MethodLength def autocorrect_inflected(node) predicate_in_actual?(node) do |predicate, to, matcher| lambda do |corrector| remove_predicate(corrector, predicate) corrector.replace(node.loc.selector, true?(to, matcher) ? 'to' : 'not_to') rewrite_matcher(corrector, predicate, matcher) end end end def remove_predicate(corrector, predicate) range = range_between( predicate.loc.dot.begin_pos, predicate.loc.expression.end_pos ) corrector.remove(range) block_range = block_loc(predicate) corrector.remove(block_range) if block_range end def rewrite_matcher(corrector, predicate, matcher) args = args_loc(predicate).source block_loc = block_loc(predicate) block = block_loc ? block_loc.source : '' _recv, name, = *predicate corrector.replace(matcher.loc.expression, to_predicate_matcher(name) + args + block) end def true?(to, matcher) _recv, name, arg = *matcher result = case name when :be, :eq arg.true_type? when :be_truthy, :a_truthy_value true when :be_falsey, :be_falsy, :a_falsey_value, :a_falsy_value false end to == :to ? result : !result end end # A helper for `explicit` style # rubocop:disable Metrics/ModuleLength module ExplicitHelper extend NodePattern::Macros MSG_EXPLICIT = 'Prefer using `%s` over ' \ '`%s` matcher.'.freeze BUILT_IN_MATCHERS = %w[ be_truthy be_falsey be_falsy have_attributes have_received be_between be_within ].freeze private def check_explicit(node) # rubocop:disable Metrics/MethodLength predicate_matcher_block?(node) do |_actual, matcher| add_offense( node, location: :expression, message: message_explicit(matcher) ) ignore_node(node.children.first) return end return if part_of_ignored_node?(node) predicate_matcher?(node) do |_actual, matcher| add_offense( node, location: :expression, message: message_explicit(matcher) ) end end def_node_matcher :predicate_matcher?, <<-PATTERN (send (send nil? :expect $!nil?) {:to :not_to :to_not} {$(send nil? #predicate_matcher_name? ...) (block $(send nil? #predicate_matcher_name? ...) ...)}) PATTERN def_node_matcher :predicate_matcher_block?, <<-PATTERN (block (send (send nil? :expect $!nil?) {:to :not_to :to_not} $(send nil? #predicate_matcher_name?)) ...) PATTERN def predicate_matcher_name?(name) name = name.to_s name.start_with?('be_', 'have_') && !BUILT_IN_MATCHERS.include?(name) && !name.end_with?('?') end def message_explicit(matcher) _recv, name, = *matcher format(MSG_EXPLICIT, predicate_name: to_predicate_method(name), matcher_name: name) end def autocorrect_explicit(node) autocorrect_explicit_send(node) || autocorrect_explicit_block(node) end def autocorrect_explicit_send(node) predicate_matcher?(node) do |actual, matcher| corrector_explicit(node, actual, matcher, matcher) end end def autocorrect_explicit_block(node) predicate_matcher_block?(node) do |actual, matcher| to, = *node corrector_explicit(to, actual, matcher, to) end end def corrector_explicit(to, actual, matcher, block_child) lambda do |corrector| replacement_matcher = replacement_matcher(to) corrector.replace(matcher.loc.expression, replacement_matcher) move_predicate(corrector, actual, matcher, block_child) corrector.replace(to.loc.selector, 'to') end end def move_predicate(corrector, actual, matcher, block_child) predicate = to_predicate_method(matcher.method_name) args = args_loc(matcher).source block_loc = block_loc(block_child) block = block_loc ? block_loc.source : '' corrector.remove(block_loc) if block_loc corrector.insert_after(actual.loc.expression, ".#{predicate}" + args + block) end # rubocop:disable Metrics/MethodLength def to_predicate_method(matcher) case matcher = matcher.to_s when 'be_a', 'be_an', 'be_a_kind_of', 'a_kind_of', 'be_kind_of' 'is_a?' when 'be_an_instance_of', 'be_instance_of', 'an_instance_of' 'instance_of?' when 'include', 'respond_to' matcher + '?' when /^have_(.+)/ "has_#{Regexp.last_match(1)}?" else matcher[/^be_(.+)/, 1] + '?' end end # rubocop:enable Metrics/MethodLength def replacement_matcher(node) case [cop_config['Strict'], node.method_name == :to] when [true, true] 'be(true)' when [true, false] 'be(false)' when [false, true] 'be_truthy' when [false, false] 'be_falsey' end end end # rubocop:enable Metrics/ModuleLength # Prefer using predicate matcher over using predicate method directly. # # RSpec defines magic matchers for predicate methods. # This cop recommends to use the predicate matcher instead of using # predicate method directly. # # @example Strict: true, EnforcedStyle: inflected (default) # # bad # expect(foo.something?).to be_truthy # # # good # expect(foo).to be_something # # # also good - It checks "true" strictly. # expect(foo).to be(true) # # @example Strict: false, EnforcedStyle: inflected # # bad # expect(foo.something?).to be_truthy # expect(foo).to be(true) # # # good # expect(foo).to be_something # # @example Strict: true, EnforcedStyle: explicit # # bad # expect(foo).to be_something # # # good - the above code is rewritten to it by this cop # expect(foo.something?).to be(true) # # @example Strict: false, EnforcedStyle: explicit # # bad # expect(foo).to be_something # # # good - the above code is rewritten to it by this cop # expect(foo.something?).to be_truthy class PredicateMatcher < Cop include ConfigurableEnforcedStyle include InflectedHelper include ExplicitHelper def on_send(node) case style when :inflected check_inflected(node) when :explicit check_explicit(node) end end def on_block(node) check_explicit(node) if style == :explicit end def autocorrect(node) case style when :inflected autocorrect_inflected(node) when :explicit autocorrect_explicit(node) end end private # returns args location with whitespace # @example # foo 1, 2 # ^^^^^ def args_loc(send_node) range_between(send_node.loc.selector.end_pos, send_node.loc.expression.end_pos) end # returns block location with whitespace # @example # foo { bar } # ^^^^^^^^ def block_loc(send_node) parent = send_node.parent return unless parent.block_type? range_between( send_node.loc.expression.end_pos, parent.loc.expression.end_pos ) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb0000644000004100000410000000210113237614066026225 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Checks invalid usage for predicate matcher. # # Predicate matcher does not need a question. # This cop checks an unnecessary question in predicate matcher. # # @example # # # bad # expect(foo).to be_something? # # # good # expect(foo).to be_something class InvalidPredicateMatcher < Cop MSG = 'Omit `?` from `%s`.'.freeze def_node_matcher :invalid_predicate_matcher?, <<-PATTERN (send (send nil? :expect ...) {:to :not_to :to_not} $(send nil? #predicate?)) PATTERN def on_send(node) invalid_predicate_matcher?(node) do |predicate| add_offense(predicate, location: :expression) end end private def predicate?(name) name = name.to_s name.start_with?('be_', 'have_') && name.end_with?('?') end def message(predicate) format(MSG, matcher: predicate.method_name) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/align_right_let_brace.rb0000644000004100000410000000223413237614066025352 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that right braces for adjacent single line lets are aligned. # # @example # # # bad # let(:foobar) { blahblah } # let(:baz) { bar } # let(:a) { b } # # # good # let(:foobar) { blahblah } # let(:baz) { bar } # let(:a) { b } # class AlignRightLetBrace < Cop MSG = 'Align right let brace'.freeze def self.autocorrect_incompatible_with [Layout::ExtraSpacing] end def investigate(_) token_aligner.offending_tokens.each do |let| add_offense(let, location: :end) end end def autocorrect(let) lambda do |corrector| corrector.insert_before( let.loc.end, token_aligner.indent_for(let) ) end end private def token_aligner @token_aligner ||= RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/before_after_all.rb0000644000004100000410000000253213237614066024337 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Check that before/after(:all) isn't being used. # # @example # # bad # # # # Faster but risk of state leaking between examples # # # describe MyClass do # before(:all) { Widget.create } # after(:all) { Widget.delete_all } # end # # # good # # # # Slower but examples are properly isolated # # # describe MyClass do # before(:each) { Widget.create } # after(:each) { Widget.delete_all } # end class BeforeAfterAll < Cop MSG = 'Beware of using `%s` as it may cause state to leak '\ 'between tests. If you are using `rspec-rails`, and '\ '`use_transactional_fixtures` is enabled, then records created '\ 'in `%s` are not automatically rolled back.'.freeze def_node_matcher :before_or_after_all, <<-PATTERN $(send _ {:before :after} (sym {:all :context})) PATTERN def on_send(node) before_or_after_all(node) do |hook| add_offense( node, location: :expression, message: format(MSG, hook: hook.source) ) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/expect_output.rb0000644000004100000410000000315513237614066023776 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for opportunities to use `expect { ... }.to output`. # # @example # # bad # $stdout = StringIO.new # my_app.print_report # $stdout = STDOUT # expect($stdout.string).to eq('Hello World') # # # good # expect { my_app.print_report }.to output('Hello World').to_stdout class ExpectOutput < Cop MSG = 'Use `expect { ... }.to output(...).to_%s` '\ 'instead of mutating $%s.'.freeze def_node_matcher :hook?, Hooks::ALL.block_pattern def on_gvasgn(node) return unless inside_example_scope?(node) variable_name, _rhs = *node name = variable_name[1..-1] return unless name.eql?('stdout') || name.eql?('stderr') add_offense(node, location: :name, message: format(MSG, name: name)) end private # Detect if we are inside the scope of a single example # # We want to encourage using `expect { ... }.to output` so # we only care about situations where you would replace with # an expectation. Therefore, assignments to stderr or stdout # within a `before(:all)` or otherwise outside of an example # don't matter. def inside_example_scope?(node) return false if node.nil? || example_group?(node) return true if example?(node) return RuboCop::RSpec::Hook.new(node).example? if hook?(node) inside_example_scope?(node.parent) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/empty_example_group.rb0000644000004100000410000000452513237614066025155 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if an example group does not include any tests. # # This cop is configurable using the `CustomIncludeMethods` option # # @example usage # # # bad # describe Bacon do # let(:bacon) { Bacon.new(chunkiness) } # let(:chunkiness) { false } # # context 'extra chunky' do # flagged by rubocop # let(:chunkiness) { true } # end # # it 'is chunky' do # expect(bacon.chunky?).to be_truthy # end # end # # # good # describe Bacon do # let(:bacon) { Bacon.new(chunkiness) } # let(:chunkiness) { false } # # it 'is chunky' do # expect(bacon.chunky?).to be_truthy # end # end # # @example configuration # # # .rubocop.yml # RSpec/EmptyExampleGroup: # CustomIncludeMethods: # - include_tests # # # spec_helper.rb # RSpec.configure do |config| # config.alias_it_behaves_like_to(:include_tests) # end # # # bacon_spec.rb # describe Bacon do # let(:bacon) { Bacon.new(chunkiness) } # let(:chunkiness) { false } # # context 'extra chunky' do # not flagged by rubocop # let(:chunkiness) { true } # # include_tests 'shared tests' # end # end # class EmptyExampleGroup < Cop MSG = 'Empty example group detected.'.freeze def_node_search :contains_example?, <<-PATTERN { #{(Examples::ALL + Includes::ALL).send_pattern} (send _ #custom_include? ...) } PATTERN def on_block(node) return unless example_group?(node) && !contains_example?(node) add_offense(node.children.first, location: :expression) end private def custom_include?(method_name) custom_include_methods.include?(method_name) end def custom_include_methods cop_config .fetch('CustomIncludeMethods', []) .map(&:to_sym) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/example_length.rb0000644000004100000410000000244213237614066024060 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for long examples. # # A long example is usually more difficult to understand. Consider # extracting out some behaviour, e.g. with a `let` block, or a helper # method. # # @example # # bad # it do # service = described_class.new # more_setup # more_setup # result = service.call # expect(result).to be(true) # end # # # good # it do # service = described_class.new # result = service.call # expect(result).to be(true) # end class ExampleLength < Cop include CodeLength MSG = 'Example has too many lines [%d/%d].'.freeze def on_block(node) return unless example?(node) length = code_length(node) return unless length > max_length add_offense(node, location: :expression, message: message(length)) end private def code_length(node) node.source.lines[1..-2].count { |line| !irrelevant_line(line) } end def message(length) format(MSG, total: length, max: max_length) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/around_block.rb0000644000004100000410000000334513237614066023531 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Checks that around blocks actually run the test. # # @example # # bad # around do # some_method # end # # around do |test| # some_method # end # # # good # around do |test| # some_method # test.call # end # # around do |test| # some_method # test.run # end class AroundBlock < Cop MSG_NO_ARG = 'Test object should be passed to around block.'.freeze MSG_UNUSED_ARG = 'You should call `%s.call` '\ 'or `%s.run`.'.freeze def_node_matcher :hook, <<-PATTERN (block {(send nil? :around) (send nil? :around sym)} (args $...) ...) PATTERN def_node_search :find_arg_usage, <<-PATTERN {(send $... {:call :run}) (send _ _ $...) (yield $...) (block-pass $...)} PATTERN def on_block(node) hook(node) do |(example_proxy)| if example_proxy.nil? add_no_arg_offense(node) else check_for_unused_proxy(node, example_proxy) end end end private def add_no_arg_offense(node) add_offense(node, location: :expression, message: MSG_NO_ARG) end def check_for_unused_proxy(block, proxy) name, = *proxy find_arg_usage(block) do |usage| return if usage.include?(s(:lvar, name)) end add_offense( proxy, location: :expression, message: format(MSG_UNUSED_ARG, arg: name) ) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/describe_method.rb0000644000004100000410000000175013237614066024205 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks that the second argument to `describe` specifies a method. # # @example # # bad # describe MyClass, 'do something' do # end # # # good # describe MyClass, '#my_instance_method' do # end # # describe MyClass, '.my_class_method' do # end class DescribeMethod < Cop include RuboCop::RSpec::TopLevelDescribe include RuboCop::RSpec::Util MSG = 'The second argument to describe should be the method '\ "being tested. '#instance' or '.class'.".freeze METHOD_STRING_MATCHER = /\A[\#\.].+/ def on_top_level_describe(_node, (_, second_arg)) return unless second_arg && second_arg.str_type? return if METHOD_STRING_MATCHER =~ one(second_arg.children) add_offense(second_arg, location: :expression) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/expect_change.rb0000644000004100000410000000571713237614066023671 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for consistent style of change matcher. # # Enforces either passing object and attribute as arguments to the matcher # or passing a block that reads the attribute value. # # This cop can be configured using the `EnforcedStyle` option. # # @example `EnforcedStyle: block` # # bad # expect(run).to change(Foo, :bar) # # # good # expect(run).to change { Foo.bar } # # @example `EnforcedStyle: method_call` # # bad # expect(run).to change { Foo.bar } # expect(run).to change { foo.baz } # # # good # expect(run).to change(Foo, :bar) # expect(run).to change(foo, :baz) # # also good when there are arguments or chained method calls # expect(run).to change { Foo.bar(:count) } # expect(run).to change { user.reload.name } # class ExpectChange < Cop include ConfigurableEnforcedStyle MSG_BLOCK = 'Prefer `change(%s, :%s)`.'.freeze MSG_CALL = 'Prefer `change { %s.%s }`.'.freeze def_node_matcher :expect_change_with_arguments, <<-PATTERN (send nil? :change ({const send} nil? $_) (sym $_)) PATTERN def_node_matcher :expect_change_with_block, <<-PATTERN (block (send nil? :change) (args) (send ({const send} nil? $_) $_) ) PATTERN def on_send(node) return unless style == :block expect_change_with_arguments(node) do |receiver, message| add_offense( node, message: format(MSG_CALL, obj: receiver, attr: message) ) end end def on_block(node) return unless style == :method_call expect_change_with_block(node) do |receiver, message| add_offense( node, message: format(MSG_BLOCK, obj: receiver, attr: message) ) end end def autocorrect(node) if style == :block autocorrect_method_call_to_block(node) else autocorrect_block_to_method_call(node) end end private def autocorrect_method_call_to_block(node) lambda do |corrector| expect_change_with_arguments(node) do |receiver, message| replacement = "change { #{receiver}.#{message} }" corrector.replace(node.loc.expression, replacement) end end end def autocorrect_block_to_method_call(node) lambda do |corrector| expect_change_with_block(node) do |receiver, message| replacement = "change(#{receiver}, :#{message})" corrector.replace(node.loc.expression, replacement) end end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/single_argument_message_chain.rb0000644000004100000410000000400513237614066027112 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Checks that chains of messages contain more than one element. # # @example # # bad # allow(foo).to receive_message_chain(:bar).and_return(42) # # # good # allow(foo).to receive(:bar).and_return(42) # # # also good # allow(foo).to receive(:bar, :baz) # allow(foo).to receive("bar.baz") # class SingleArgumentMessageChain < Cop MSG = 'Use `%s` instead of calling '\ '`%s` with a single argument.'.freeze def_node_matcher :message_chain, <<-PATTERN (send _ #{Matchers::MESSAGE_CHAIN.node_pattern_union} $_) PATTERN def_node_matcher :single_key_hash?, '(hash pair)' def on_send(node) message_chain(node) do |arg| return if arg.to_s.include?('.') return if arg.hash_type? && !single_key_hash?(arg) add_offense(node, location: :selector) end end def autocorrect(node) lambda do |corrector| corrector.replace(node.loc.selector, replacement(node.method_name)) message_chain(node) do |arg| autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg) end end end private def autocorrect_hash_arg(corrector, arg) key, value = *arg.children.first corrector.replace(arg.loc.expression, key_to_arg(key)) corrector.insert_after(arg.parent.loc.end, ".and_return(#{value.source})") end def key_to_arg(node) key, = *node node.sym_type? ? ":#{key}" : node.source end def replacement(method) method.equal?(:receive_message_chain) ? 'receive' : 'stub' end def message(node) method = node.method_name format(MSG, recommended: replacement(method), called: method) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/expect_in_hook.rb0000644000004100000410000000271513237614066024065 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Do not use `expect` in hooks such as `before`. # # @example # # bad # before do # expect(something).to eq 'foo' # end # # # bad # after do # expect_any_instance_of(Something).to receive(:foo) # end # # # good # it do # expect(something).to eq 'foo' # end class ExpectInHook < Cop MSG = 'Do not use `%s` in `%s` hook'.freeze HOOKS = Hooks::ALL.node_pattern_union.freeze def_node_matcher :hook, <<-PATTERN (block (send _ $#{HOOKS} ...) _ $!nil?) PATTERN def_node_search :expect, <<-PATTERN { #{Expectations::ALL.send_pattern} #{Expectations::ALL.block_pattern} } PATTERN def on_block(node) hook(node) do |hook_name, body| expect(body) do |expect| method = send_node(expect) add_offense(method, location: :selector, message: message(method, hook_name)) end end end private def message(expect, hook) format(MSG, expect: expect.method_name, hook: hook) end def send_node(node) return node if node.send_type? node.children.first end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/factory_bot/0000755000004100000410000000000013237614066023050 5ustar www-datawww-datarubocop-rspec-1.22.2/lib/rubocop/cop/rspec/factory_bot/dynamic_attribute_defined_statically.rb0000644000004100000410000000454713237614066033025 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec module FactoryBot # Prefer declaring dynamic attribute values in a block. # # @example # # bad # kind [:active, :rejected].sample # # # good # kind { [:active, :rejected].sample } # # # bad # closed_at 1.day.from_now # # # good # closed_at { 1.day.from_now } # # # good # kind :static # # # good # comments_count 0 # # # good # type User::MAGIC class DynamicAttributeDefinedStatically < Cop MSG = 'Use a block to set a dynamic value to an attribute.'.freeze def_node_matcher :dynamic_defined_statically?, <<-PATTERN (send nil? _ (send ... )) PATTERN def_node_search :factory_attributes, <<-PATTERN (block (send nil? {:factory :trait} ...) _ { (begin $...) $(send ...) } ) PATTERN def on_block(node) return if node.method_name == :trait factory_attributes(node).to_a.flatten.each do |attribute| if dynamic_defined_statically?(attribute) add_offense(attribute, location: :expression) end end end def autocorrect(node) if method_uses_parens?(node.location) autocorrect_replacing_parens(node) else autocorrect_without_parens(node) end end private def method_uses_parens?(location) return false unless location.begin && location.end location.begin.source == '(' && location.end.source == ')' end def autocorrect_replacing_parens(node) lambda do |corrector| corrector.replace(node.location.begin, ' { ') corrector.replace(node.location.end, ' }') end end def autocorrect_without_parens(node) lambda do |corrector| arguments = node.descendants.first expression = arguments.location.expression corrector.insert_before(expression, '{ ') corrector.insert_after(expression, ' }') end end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/verified_doubles.rb0000644000004100000410000000163513237614066024401 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Prefer using verifying doubles over normal doubles. # # @see https://relishapp.com/rspec/rspec-mocks/docs/verifying-doubles # # @example # # bad # it '...' do # widget = double("Widget") # end # # # good # it '...' do # widget = instance_double("Widget") # end class VerifiedDoubles < Cop MSG = 'Prefer using verifying doubles over normal doubles.'.freeze def_node_matcher :unverified_double, <<-PATTERN {(send nil? {:double :spy} $_ ...) } PATTERN def on_send(node) unverified_double(node) do |name| return if name.sym_type? && cop_config['IgnoreSymbolicNames'] add_offense(node, location: :expression) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/not_to_not.rb0000644000004100000410000000172113237614066023245 0ustar www-datawww-datamodule RuboCop module Cop module RSpec # Checks for consistent method usage for negating expectations. # # @example # # bad # it '...' do # expect(false).to_not be_true # end # # # good # it '...' do # expect(false).not_to be_true # end class NotToNot < Cop include ConfigurableEnforcedStyle MSG = 'Prefer `%s` over `%s`.'.freeze def_node_matcher :not_to_not_offense, '(send _ % ...)' def on_send(node) not_to_not_offense(node, alternative_style) do add_offense(node, location: :expression) end end def autocorrect(node) ->(corrector) { corrector.replace(node.loc.selector, style.to_s) } end private def message(_node) format(MSG, replacement: style, original: alternative_style) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/describe_class.rb0000644000004100000410000000315713237614066024035 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Check that the first argument to the top level describe is a constant. # # @example # # bad # describe 'Do something' do # end # # # good # describe TestedClass do # end # # describe "A feature example", type: :feature do # end class DescribeClass < Cop include RuboCop::RSpec::TopLevelDescribe MSG = 'The first argument to describe should be '\ 'the class or module being tested.'.freeze def_node_matcher :valid_describe?, <<-PATTERN {(send {(const nil? :RSpec) nil?} :describe const ...) (send nil? :describe)} PATTERN def_node_matcher :describe_with_metadata, <<-PATTERN (send {(const nil? :RSpec) nil?} :describe !const ... (hash $...)) PATTERN def_node_matcher :rails_metadata?, <<-PATTERN (pair (sym :type) (sym {:request :feature :system :routing :view})) PATTERN def_node_matcher :shared_group?, <<-PATTERN (block (send {(const nil? :RSpec) nil?} #{SharedGroups::ALL.node_pattern_union} ...) ...) PATTERN def on_top_level_describe(node, args) return if shared_group?(root_node) return if valid_describe?(node) describe_with_metadata(node) do |pairs| return if pairs.any?(&method(:rails_metadata?)) end add_offense(args.first, location: :expression) end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/let_before_examples.rb0000644000004100000410000000561713237614066025077 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for `let` definitions that come after an example. # # @example # # Bad # let(:foo) { bar } # # it 'checks what foo does' do # expect(foo).to be # end # # let(:some) { other } # # it 'checks what some does' do # expect(some).to be # end # # # Good # let(:foo) { bar } # let(:some) { other } # # it 'checks what foo does' do # expect(foo).to be # end # # it 'checks what some does' do # expect(some).to be # end class LetBeforeExamples < Cop MSG = 'Move `let` before the examples in the group.'.freeze def_node_matcher :let?, '(block (send nil? {:let :let!} ...) ...)' def_node_matcher :example_or_group?, <<-PATTERN { #{(Examples::ALL + ExampleGroups::ALL).block_pattern} #{Includes::EXAMPLES.send_pattern} } PATTERN def on_block(node) return unless example_group_with_body?(node) check_let_declarations(node.body) if multiline_block?(node.body) end def autocorrect(node) lambda do |corrector| first_example = find_first_example(node.parent) first_example_pos = first_example.loc.expression indent = "\n" + ' ' * first_example.loc.column corrector.insert_before(first_example_pos, source(node) + indent) corrector.remove(node_range_with_surrounding_space(node)) end end private def multiline_block?(block) block.begin_type? end def check_let_declarations(node) first_example = find_first_example(node) return unless first_example node.each_child_node do |child| next if child.sibling_index < first_example.sibling_index add_offense(child, location: :expression) if let?(child) end end def find_first_example(node) node.children.find { |sibling| example_or_group?(sibling) } end def node_range_with_surrounding_space(node) range = node_range(node) range_by_whole_lines(range, include_final_newline: true) end def source(node) node_range(node).source end def node_range(node) range_between(node.loc.expression.begin_pos, last_node_loc(node)) end def last_node_loc(node) heredoc = heredoc_lines(node).last if heredoc heredoc.loc.heredoc_end.end_pos else node.loc.end.end_pos end end def heredoc_lines(node) node.body.child_nodes.select { |n| n.loc.respond_to?(:heredoc_end) } end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/focus.rb0000644000004100000410000000275413237614066022211 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks if examples are focused. # # @example # # bad # describe MyClass, focus: true do # end # # describe MyClass, :focus do # end # # fdescribe MyClass do # end # # # good # describe MyClass do # end class Focus < Cop MSG = 'Focused spec found.'.freeze focusable = ExampleGroups::GROUPS + ExampleGroups::SKIPPED + Examples::EXAMPLES + Examples::SKIPPED focused = ExampleGroups::FOCUSED + Examples::FOCUSED FOCUSABLE_SELECTORS = focusable.node_pattern_union FOCUS_SYMBOL = s(:sym, :focus) FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true)) def_node_matcher :metadata, <<-PATTERN {(send nil? #{FOCUSABLE_SELECTORS} ... (hash $...)) (send nil? #{FOCUSABLE_SELECTORS} $...)} PATTERN def_node_matcher :focused_block?, focused.send_pattern def on_send(node) focus_metadata(node) do |focus| add_offense(focus, location: :expression) end end private def focus_metadata(node, &block) yield(node) if focused_block?(node) metadata(node) do |matches| matches.grep(FOCUS_SYMBOL, &block) matches.grep(FOCUS_TRUE, &block) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/let_setup.rb0000644000004100000410000000252613237614066023073 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks unreferenced `let!` calls being used for test setup. # # @example # # Bad # let!(:my_widget) { create(:widget) } # # it 'counts widgets' do # expect(Widget.count).to eq(1) # end # # # Good # it 'counts widgets' do # create(:widget) # expect(Widget.count).to eq(1) # end # # # Good # before { create(:widget) } # # it 'counts widgets' do # expect(Widget.count).to eq(1) # end class LetSetup < Cop include RuboCop::RSpec::TopLevelDescribe MSG = 'Do not use `let!` for test setup.'.freeze def_node_search :let_bang, <<-PATTERN (block $(send nil? :let! (sym $_)) args ...) PATTERN def_node_search :method_called?, '(send nil? %)' def on_block(node) return unless example_group?(node) unused_let_bang(node) do |let| add_offense(let, location: :expression) end end private def unused_let_bang(node) let_bang(node) do |method_send, method_name| yield(method_send) unless method_called?(node, method_name) end end end end end end rubocop-rspec-1.22.2/lib/rubocop/cop/rspec/message_expectation.rb0000644000004100000410000000301613237614066025111 0ustar www-datawww-data# frozen_string_literal: true module RuboCop module Cop module RSpec # Checks for consistent message expectation style. # # This cop can be configured in your configuration using the # `EnforcedStyle` option and supports `--auto-gen-config`. # # @example `EnforcedStyle: allow` # # # bad # expect(foo).to receive(:bar) # # # good # allow(foo).to receive(:bar) # # @example `EnforcedStyle: expect` # # # bad # allow(foo).to receive(:bar) # # # good # expect(foo).to receive(:bar) # class MessageExpectation < Cop include ConfigurableEnforcedStyle MSG = 'Prefer `%