Skip to content

Commit

Permalink
Use declared subject as default target for with helper
Browse files Browse the repository at this point in the history
  • Loading branch information
svoop committed Aug 25, 2023
1 parent def3780 commit a64e69a
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#### Additions
* Refactor to support class variables as well
* Use declared subject as default target for with helper

## 0.1.0

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ end
config.instance_variable_get('@version') # => 1
```

:warning: The target `on` is set explicitly in this case. If you omit this argument, `self` will be used as target by default.

Class variables can be substituted as well:

```ruby
Expand Down Expand Up @@ -137,6 +139,8 @@ with '@version', on: Config do
end
```

:warning: The target `on` is set explicitly in this case. If you omit this argument, `:subject` will be used as target by default which refers to the subject defined by the `subject {}` helper.

It's safe to use multiple `with` statements within one `describe` block.

(The spec integration is borrowed from [minitest-around](https://rubygems.org/gems/minitest-around) for elegance and compatibility.)
Expand Down
6 changes: 4 additions & 2 deletions lib/minitest/substitute/spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
#
# @param variable [String] instance or global variable name
# @param substitute [Object] temporary substitution value
# @param on [Object, nil] substitute in the context of this object
# @param on [Object, Symbol, nil] substitute in the context of this object
# or in the context of the declared subject if +:subject+ is set
# @yield temporary substitution value (takes precedence over +substitute+ param)
def with(variable, substitute=nil, on: self)
def with(variable, substitute=nil, on: :subject)
substitute = yield if block_given?
substitutor = Minitest::Substitute::Substitutor.new(variable, substitute, on: on)
before do
substitutor.on = subject if on == :subject && respond_to?(:subject)
substitutor.commit
end
after do
Expand Down
4 changes: 3 additions & 1 deletion lib/minitest/substitute/substitutor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ class Substitutor

EVAL_METHODS = [:instance_eval, :instance_eval, :class_eval].freeze

attr_writer :on

def initialize(variable, substitute, on:)
@variable, @substitute, @on = variable, substitute, on
@original = get
end

def commit
@original = get
set @substitute
end

Expand Down
3 changes: 1 addition & 2 deletions spec/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ def initialize
@@counter = 0
end

$_spec_config_instance = Config.new
$_spec_global_variable = :original
$spec_global_variable = :original
44 changes: 28 additions & 16 deletions spec/lib/minitest/substitute/spec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,61 @@
describe :with do
10.times do # test rollback even though order is random
describe "instance variable" do
subject do
Config.new
end

context 'untouched' do
it "returns the original value" do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 1
_(subject.instance_variable_get(:@version)).must_equal 1
end
end

context 'substituted' do
with '@version', 2, on: $_spec_config_instance
with '@version', 2

it "returns the substitute value" do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 2
_(subject.instance_variable_get(:@version)).must_equal 2
end
end
end
end

10.times do # test rollback even though order is random
describe "class variable" do
subject do
Config
end

context 'untouched' do
it "returns the original value" do
_(Config.class_variable_get(:@@counter)).must_equal 0
_(subject.class_variable_get(:@@counter)).must_equal 0
end
end

context 'substituted' do
with '@@counter', 42, on: Config
with '@@counter', 42

it "returns the substitute value" do
_(Config.class_variable_get(:@@counter)).must_equal 42
_(subject.class_variable_get(:@@counter)).must_equal 42
end
end
end
end

10.times do # test rollback even though order is random
10.times do # test rollback even though order is random
describe "global variable" do
context 'untouched' do
it "returns the original value" do
_($_spec_global_variable).must_equal :original
_($spec_global_variable).must_equal :original
end
end

context 'substituted' do
with "$_spec_global_variable", 'oggy'
with "$spec_global_variable", 'oggy'

it "returns the substitute value" do
_($_spec_global_variable).must_equal 'oggy'
_($spec_global_variable).must_equal 'oggy'
end
end
end
Expand All @@ -78,22 +86,26 @@

10.times do # test rollback even though order is random
describe "multiple substitutions" do
subject do
Config.new
end

context 'untouched' do
it "returns the original values" do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 1
_($_spec_config_instance.instance_variable_get(:@released_on)).must_equal '2023-08-24'
_(subject.instance_variable_get(:@version)).must_equal 1
_(subject.instance_variable_get(:@released_on)).must_equal '2023-08-24'
end
end

context 'substituted' do
with '@version', 2, on: $_spec_config_instance
with '@released_on', on: $_spec_config_instance do
with '@version', 2
with '@released_on' do
'2012-12-12'
end

it "returns the substitute values" do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 2
_($_spec_config_instance.instance_variable_get(:@released_on)).must_equal '2012-12-12'
_(subject.instance_variable_get(:@version)).must_equal 2
_(subject.instance_variable_get(:@released_on)).must_equal '2012-12-12'
end
end
end
Expand Down
26 changes: 14 additions & 12 deletions spec/lib/minitest/substitute/with_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
describe :with do
describe "instance variable" do
it "substitutes the value for the duration of a block" do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 1
with '@version', 2, on: $_spec_config_instance do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 2
config = Config.new
_(config.instance_variable_get(:@version)).must_equal 1
with '@version', 2, on: config do
_(config.instance_variable_get(:@version)).must_equal 2
end
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 1
_(config.instance_variable_get(:@version)).must_equal 1
end
end

Expand All @@ -26,11 +27,11 @@

describe "global variable" do
it "substitutes the value for the duration of a block" do
_($_spec_global_variable).must_equal :original
with "$_spec_global_variable", 'oggy' do
_($_spec_global_variable).must_equal 'oggy'
_($spec_global_variable).must_equal :original
with "$spec_global_variable", 'oggy' do
_($spec_global_variable).must_equal 'oggy'
end
_($_spec_global_variable).must_equal :original
_($spec_global_variable).must_equal :original
end
end

Expand All @@ -46,10 +47,11 @@

describe "nested substitutions" do
it "substitutes the values for the duration of a block" do
with '@version', 2, on: $_spec_config_instance do
with '@released_on', '2012-12-12', on: $_spec_config_instance do
_($_spec_config_instance.instance_variable_get(:@version)).must_equal 2
_($_spec_config_instance.instance_variable_get(:@released_on)).must_equal '2012-12-12'
config = Config.new
with '@version', 2, on: config do
with '@released_on', '2012-12-12', on: config do
_(config.instance_variable_get(:@version)).must_equal 2
_(config.instance_variable_get(:@released_on)).must_equal '2012-12-12'
end
end
end
Expand Down

0 comments on commit a64e69a

Please sign in to comment.