Skip to content

Commit

Permalink
Improve examples for LeakyConstantDeclaration cop
Browse files Browse the repository at this point in the history
As mentioned here
rubocop#765 (comment),
it's not even necessary in some cases to stub a constant, a so-called
"sacrificial class" will do.
Originally mentioned article
http://blog.bitwrangler.com/2016/11/10/sacrificial-test-classes.html in
this comment rubocop#197 (comment)
  • Loading branch information
pirj committed Jun 20, 2019
1 parent 9e90461 commit 1d238e5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
28 changes: 22 additions & 6 deletions lib/rubocop/cop/rspec/leaky_constant_declaration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,51 @@ module RSpec
# # bad
# describe SomeClass do
# OtherClass = Struct.new
# CONSTANT_HERE = 'is also denied'
# CONSTANT_HERE = 'I leak into global namespace'
# end
#
# # good
# describe SomeClass do
# before do
# stub_const('OtherClass', Struct.new)
# stub_const('CONSTANT_HERE', 'is also denied')
# stub_const('CONSTANT_HERE', 'I am undefined after the example')
# end
# end
#
# @example
# # bad
# describe SomeClass do
# class OtherClass < described_class
# def do_something
# class FooClass < described_class
# def double_that
# some_base_method * 2
# end
# end
#
# it { expect(FooClass.new.double_that).to eq(4) }
# end
#
# # good
# # good - sacrificial class, no constant needs to be defined
# let(:foo_class) do
# Class.new(described_class) do
# def double_that
# some_base_method * 2
# end
# end
#
# it { expect(foo_class.new.double_that).to eq(4) }
# end
#
# # good - constant is stubbed
# describe SomeClass do
# before do
# fake_class = Class.new(described_class) do
# def do_something
# end
# end
# stub_const('OtherClass', fake_class)
# stub_const('FooClass', fake_class)
# end
#
# it { expect(FooClass.new.double_that).to eq(4) }
# end
#
# @example
Expand Down
28 changes: 22 additions & 6 deletions manual/cops_rspec.md
Original file line number Diff line number Diff line change
Expand Up @@ -1506,35 +1506,51 @@ namespace name clashes.
# bad
describe SomeClass do
OtherClass = Struct.new
CONSTANT_HERE = 'is also denied'
CONSTANT_HERE = 'I leak into global namespace'
end

# good
describe SomeClass do
before do
stub_const('OtherClass', Struct.new)
stub_const('CONSTANT_HERE', 'is also denied')
stub_const('CONSTANT_HERE', 'I am undefined after the example')
end
end
```
```ruby
# bad
describe SomeClass do
class OtherClass < described_class
def do_something
class FooClass < described_class
def double_that
some_base_method * 2
end
end

it { expect(FooClass.new.double_that).to eq(4) }
end

# good
# good - sacrificial class, no constant needs to be defined
let(:foo_class) do
Class.new(described_class) do
def double_that
some_base_method * 2
end
end

it { expect(foo_class.new.double_that).to eq(4) }
end

# good - constant is stubbed
describe SomeClass do
before do
fake_class = Class.new(described_class) do
def do_something
end
end
stub_const('OtherClass', fake_class)
stub_const('FooClass', fake_class)
end

it { expect(FooClass.new.double_that).to eq(4) }
end
```
```ruby
Expand Down

0 comments on commit 1d238e5

Please sign in to comment.