rr 0.10.11 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +5 -0
- data/Gemfile +6 -0
- data/README.rdoc +28 -2
- data/VERSION.yml +3 -3
- data/lib/rr.rb +23 -17
- data/lib/rr/adapters/rr_methods.rb +43 -17
- data/lib/rr/blank_slate.rb +2 -2
- data/lib/rr/class_instance_method_defined.rb +9 -0
- data/lib/rr/double.rb +2 -2
- data/lib/rr/double_definitions/double_definition.rb +29 -16
- data/lib/rr/double_definitions/double_definition_create.rb +52 -86
- data/lib/rr/double_definitions/double_injections/any_instance_of.rb +28 -0
- data/lib/rr/double_definitions/double_injections/instance.rb +16 -0
- data/lib/rr/double_definitions/double_injections/new_instance_of.rb +53 -0
- data/lib/rr/double_definitions/strategies/double_injection/any_instance_of.rb +31 -0
- data/lib/rr/double_definitions/strategies/double_injection/double_injection_strategy.rb +10 -0
- data/lib/rr/double_definitions/strategies/double_injection/instance.rb +17 -0
- data/lib/rr/double_definitions/strategies/double_injection/new_instance_of.rb +37 -0
- data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +0 -5
- data/lib/rr/double_definitions/strategies/implementation/proxy.rb +0 -2
- data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +0 -2
- data/lib/rr/double_definitions/strategies/strategy.rb +0 -27
- data/lib/rr/double_definitions/strategies/strategy_methods.rb +53 -0
- data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +0 -2
- data/lib/rr/double_definitions/strategies/verification/mock.rb +0 -2
- data/lib/rr/double_definitions/strategies/verification/stub.rb +0 -2
- data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +0 -5
- data/lib/rr/hash_with_object_id_key.rb +4 -0
- data/lib/rr/injections/double_injection.rb +94 -71
- data/lib/rr/injections/injection.rb +8 -10
- data/lib/rr/injections/method_missing_injection.rb +13 -20
- data/lib/rr/injections/singleton_method_added_injection.rb +19 -17
- data/lib/rr/method_dispatches/base_method_dispatch.rb +1 -1
- data/lib/rr/method_dispatches/method_dispatch.rb +4 -4
- data/lib/rr/method_dispatches/method_missing_dispatch.rb +17 -14
- data/lib/rr/recorded_calls.rb +1 -1
- data/lib/rr/space.rb +6 -6
- data/lib/rr/times_called_matchers/times_called_matcher.rb +2 -2
- data/scratch.rb +118 -0
- data/spec/api/any_instance_of/all_instances_of_spec.rb +14 -0
- data/spec/api/any_instance_of/any_instance_of_spec.rb +47 -0
- data/spec/api/mock/mock_spec.rb +2 -2
- data/spec/api/new_instance_of/instance_of_spec.rb +15 -0
- data/spec/api/new_instance_of/new_instance_of_spec.rb +61 -0
- data/spec/environment_fixture_setup.rb +3 -2
- data/spec/rr/adapters/rr_methods_space_spec.rb +8 -10
- data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +1 -1
- data/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb +6 -2
- data/spec/rr/double_definitions/double_definition_create_spec.rb +1 -52
- data/spec/rr/double_injection/double_injection_verify_spec.rb +1 -1
- data/spec/rr/rspec/rspec_adapter_spec.rb +5 -5
- data/spec/rr/space/space_spec.rb +58 -67
- data/spec/spec_helper.rb +2 -2
- metadata +33 -9
- data/lib/rr/double_definitions/strategies/scope/instance.rb +0 -15
- data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +0 -50
- data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +0 -15
data/CHANGES
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
1.0.0
|
2
|
+
- Added any_instance_of (aliased by all_instances_of), which binds methods directly to the class (instead of the eigenclass).
|
3
|
+
- Subclasses of a injected class do not have their methods overridden.
|
4
|
+
- any_instance_of and new_instance_of now have a block syntax
|
5
|
+
|
1
6
|
0.10.11
|
2
7
|
- Added RR.blank_slate_whitelist
|
3
8
|
- Fixed class_eval method redefinition warning in jruby
|
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -213,9 +213,33 @@ renders the partial.
|
|
213
213
|
html
|
214
214
|
end
|
215
215
|
|
216
|
-
===
|
217
|
-
|
216
|
+
=== any_instance_of
|
217
|
+
Allows stubs to be added to all instances of a class. It works by binding to methods from the class itself, rather than the eigenclass.
|
218
|
+
This allows all instances (excluding instances with the method redefined in the eigenclass) to get the change.
|
218
219
|
|
220
|
+
Due to Ruby runtime limitations, mocks will not work as expected. It's not obviously feasible (without an ObjectSpace lookup) to support all of RR's methods (such as mocking).
|
221
|
+
ObjectSpace is not readily supported in jRuby, since it causes general slowness in the intreperter.
|
222
|
+
I'm of the opinion that test speed is more important than having mocks on all instances of a class.
|
223
|
+
If there is another solution, I'd be willing to add it.
|
224
|
+
|
225
|
+
any_instance_of(User) do |u|
|
226
|
+
stub(u).valid? {false}
|
227
|
+
end
|
228
|
+
# or
|
229
|
+
any_instance_of(User, :valid? => false)
|
230
|
+
# or
|
231
|
+
any_instance_of(User, :valid? => lambda {false})
|
232
|
+
|
233
|
+
=== new_instance_of
|
234
|
+
Stubs the new method of the class and allows doubles to be bound to new instances.
|
235
|
+
|
236
|
+
Mocks can be used, because new instances are deterministically bound.
|
237
|
+
|
238
|
+
new_instance_of(User) do |u|
|
239
|
+
mock(u).valid? {false}
|
240
|
+
end
|
241
|
+
|
242
|
+
# Deprecated syntax
|
219
243
|
mock.instance_of(User).valid? {false}
|
220
244
|
|
221
245
|
=== Spies
|
@@ -338,7 +362,9 @@ If you have directly contributed to RR and I missed you in this list, please let
|
|
338
362
|
* Dave Myron for a bug report
|
339
363
|
* David Chelimsky for encouragement to make the RR framework, for developing the Rspec mock framework, syntax ideas, and patches
|
340
364
|
* Daniel Sudol for identifing performance issues with RR
|
365
|
+
* Dmitry Ratnikov for patches
|
341
366
|
* Felix Morio for pairing with me
|
367
|
+
* Gabriel Horner for patches
|
342
368
|
* Gerard Meszaros for his excellent book "xUnit Test Patterns"
|
343
369
|
* James Mead for developing Mocha
|
344
370
|
* Jeff Whitmire for documentation suggestions
|
data/VERSION.yml
CHANGED
data/lib/rr.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
dir = File.dirname(__FILE__)
|
2
|
-
require 'rubygems'
|
3
2
|
require 'forwardable'
|
4
3
|
|
5
4
|
require "#{dir}/rr/blank_slate"
|
@@ -17,6 +16,27 @@ require "#{dir}/rr/errors/spy_verification_errors/double_injection_not_found_err
|
|
17
16
|
require "#{dir}/rr/errors/spy_verification_errors/invocation_count_error"
|
18
17
|
|
19
18
|
require "#{dir}/rr/space"
|
19
|
+
|
20
|
+
require "#{dir}/rr/double_definitions/strategies/strategy"
|
21
|
+
require "#{dir}/rr/double_definitions/strategies/strategy_methods"
|
22
|
+
require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
|
23
|
+
require "#{dir}/rr/double_definitions/strategies/verification/mock"
|
24
|
+
require "#{dir}/rr/double_definitions/strategies/verification/stub"
|
25
|
+
require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
|
26
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
|
27
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
|
28
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation"
|
29
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
|
30
|
+
require "#{dir}/rr/double_definitions/strategies/double_injection/double_injection_strategy"
|
31
|
+
require "#{dir}/rr/double_definitions/strategies/double_injection/instance"
|
32
|
+
require "#{dir}/rr/double_definitions/strategies/double_injection/any_instance_of"
|
33
|
+
require "#{dir}/rr/double_definitions/strategies/double_injection/new_instance_of"
|
34
|
+
require "#{dir}/rr/adapters/rr_methods"
|
35
|
+
require "#{dir}/rr/double_definitions/double_injections/instance"
|
36
|
+
require "#{dir}/rr/double_definitions/double_injections/any_instance_of"
|
37
|
+
require "#{dir}/rr/double_definitions/double_injections/new_instance_of"
|
38
|
+
require "#{dir}/rr/double_definitions/double_definition"
|
39
|
+
|
20
40
|
require "#{dir}/rr/injections/injection"
|
21
41
|
require "#{dir}/rr/injections/double_injection"
|
22
42
|
require "#{dir}/rr/injections/method_missing_injection"
|
@@ -27,26 +47,13 @@ require "#{dir}/rr/method_dispatches/method_missing_dispatch"
|
|
27
47
|
require "#{dir}/rr/hash_with_object_id_key"
|
28
48
|
require "#{dir}/rr/recorded_calls"
|
29
49
|
require "#{dir}/rr/proc_from_block"
|
50
|
+
require "#{dir}/rr/class_instance_method_defined"
|
30
51
|
|
31
52
|
require "#{dir}/rr/double_definitions/double_definition_create_blank_slate"
|
32
53
|
require "#{dir}/rr/double_definitions/double_definition_create"
|
33
54
|
require "#{dir}/rr/double_definitions/child_double_definition_create"
|
34
|
-
require "#{dir}/rr/adapters/rr_methods"
|
35
55
|
|
36
56
|
require "#{dir}/rr/double"
|
37
|
-
require "#{dir}/rr/double_definitions/double_definition"
|
38
|
-
require "#{dir}/rr/double_definitions/strategies/strategy"
|
39
|
-
require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
|
40
|
-
require "#{dir}/rr/double_definitions/strategies/verification/mock"
|
41
|
-
require "#{dir}/rr/double_definitions/strategies/verification/stub"
|
42
|
-
require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
|
43
|
-
require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
|
44
|
-
require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
|
45
|
-
require "#{dir}/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation"
|
46
|
-
require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
|
47
|
-
require "#{dir}/rr/double_definitions/strategies/scope/scope_strategy"
|
48
|
-
require "#{dir}/rr/double_definitions/strategies/scope/instance"
|
49
|
-
require "#{dir}/rr/double_definitions/strategies/scope/instance_of_class"
|
50
57
|
require "#{dir}/rr/double_matches"
|
51
58
|
|
52
59
|
require "#{dir}/rr/expectations/argument_equality_expectation"
|
@@ -84,12 +91,11 @@ module RR
|
|
84
91
|
class << self
|
85
92
|
include Adapters::RRMethods
|
86
93
|
(RR::Space.instance_methods - Object.instance_methods).each do |method_name|
|
87
|
-
|
94
|
+
class_eval((<<-METHOD), __FILE__, __LINE__ + 1)
|
88
95
|
def #{method_name}(*args, &block)
|
89
96
|
RR::Space.instance.__send__(:#{method_name}, *args, &block)
|
90
97
|
end
|
91
98
|
METHOD
|
92
|
-
class_eval(returns_method, __FILE__, __LINE__ - 4)
|
93
99
|
end
|
94
100
|
end
|
95
101
|
end
|
@@ -1,22 +1,40 @@
|
|
1
1
|
module RR
|
2
2
|
module Adapters
|
3
3
|
module RRMethods
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
4
|
+
include ::RR::DoubleDefinitions::Strategies::StrategyMethods
|
5
|
+
def mock(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
6
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
7
|
+
double_definition_create.mock(subject, method_name, &definition_eval_block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
11
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
12
|
+
double_definition_create.stub(subject, method_name, &definition_eval_block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def dont_allow(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
16
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
17
|
+
double_definition_create.dont_allow(subject, method_name, &definition_eval_block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def proxy(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
21
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
22
|
+
double_definition_create.proxy(subject, method_name, &definition_eval_block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def strong(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
26
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
27
|
+
double_definition_create.strong(subject, method_name, &definition_eval_block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def any_instance_of(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
31
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
32
|
+
double_definition_create.any_instance_of(subject, method_name, &definition_eval_block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def instance_of(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
36
|
+
double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
|
37
|
+
double_definition_create.instance_of(subject, method_name, &definition_eval_block)
|
20
38
|
end
|
21
39
|
|
22
40
|
# Verifies all the DoubleInjection objects have met their
|
@@ -102,7 +120,7 @@ module RR
|
|
102
120
|
|
103
121
|
def spy(subject)
|
104
122
|
methods_to_stub = subject.public_methods.map {|method_name| method_name.to_sym} -
|
105
|
-
[:methods, :==, :__send__, :__id__, :object_id]
|
123
|
+
[:methods, :==, :__send__, :__id__, :object_id, :class]
|
106
124
|
methods_to_stub.each do |method|
|
107
125
|
stub.proxy(subject, method)
|
108
126
|
end
|
@@ -112,6 +130,14 @@ module RR
|
|
112
130
|
RR::SpyVerificationProxy.new(subject)
|
113
131
|
end
|
114
132
|
|
133
|
+
def new_instance_of(*args, &block)
|
134
|
+
RR::DoubleDefinitions::DoubleInjections::NewInstanceOf.call(*args, &block)
|
135
|
+
end
|
136
|
+
|
137
|
+
def any_instance_of(*args, &block)
|
138
|
+
RR::DoubleDefinitions::DoubleInjections::AnyInstanceOf.call(*args, &block)
|
139
|
+
end
|
140
|
+
|
115
141
|
instance_methods.each do |name|
|
116
142
|
alias_method "rr_#{name}", name
|
117
143
|
end
|
data/lib/rr/blank_slate.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
module RR
|
2
|
+
module ClassInstanceMethodDefined
|
3
|
+
def self.call(klass, instance_method, include_super=true)
|
4
|
+
klass.instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym} ||
|
5
|
+
klass.protected_instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym} ||
|
6
|
+
klass.private_instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/lib/rr/double.rb
CHANGED
@@ -3,7 +3,7 @@ module RR
|
|
3
3
|
# It has the ArgumentEqualityExpectation, TimesCalledExpectation,
|
4
4
|
# and the implementation.
|
5
5
|
class Double
|
6
|
-
|
6
|
+
extend(Module.new do
|
7
7
|
def formatted_name(method_name, args)
|
8
8
|
formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
|
9
9
|
"#{method_name}(#{formatted_errors})"
|
@@ -14,7 +14,7 @@ module RR
|
|
14
14
|
"- #{formatted_name(double.method_name, double.expected_arguments)}"
|
15
15
|
end.join("\n")
|
16
16
|
end
|
17
|
-
end
|
17
|
+
end)
|
18
18
|
|
19
19
|
attr_reader :times_called, :double_injection, :definition, :times_called_expectation
|
20
20
|
include Space::Reader
|
@@ -1,22 +1,6 @@
|
|
1
1
|
module RR
|
2
2
|
module DoubleDefinitions
|
3
3
|
class DoubleDefinition #:nodoc:
|
4
|
-
class << self
|
5
|
-
def register_strategy_class(strategy_class, method_name)
|
6
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
7
|
-
def #{method_name}(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
8
|
-
ChildDoubleDefinitionCreate.new(self).#{method_name}(subject, method_name, &definition_eval_block)
|
9
|
-
end
|
10
|
-
CLASS
|
11
|
-
|
12
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
13
|
-
def #{method_name}!(method_name=nil, &definition_eval_block)
|
14
|
-
ChildDoubleDefinitionCreate.new(self).#{method_name}!(method_name, &definition_eval_block)
|
15
|
-
end
|
16
|
-
CLASS
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
4
|
ORIGINAL_METHOD = Object.new
|
21
5
|
attr_accessor(
|
22
6
|
:argument_expectation,
|
@@ -349,6 +333,35 @@ module RR
|
|
349
333
|
end
|
350
334
|
end
|
351
335
|
include StateQueryMethods
|
336
|
+
include ::RR::DoubleDefinitions::Strategies::StrategyMethods
|
337
|
+
|
338
|
+
def mock(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
339
|
+
ChildDoubleDefinitionCreate.new(self).mock(subject, method_name, &definition_eval_block)
|
340
|
+
end
|
341
|
+
|
342
|
+
def stub(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
343
|
+
ChildDoubleDefinitionCreate.new(self).stub(subject, method_name, &definition_eval_block)
|
344
|
+
end
|
345
|
+
|
346
|
+
def dont_allow(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
347
|
+
ChildDoubleDefinitionCreate.new(self).dont_allow(subject, method_name, &definition_eval_block)
|
348
|
+
end
|
349
|
+
|
350
|
+
def proxy(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
351
|
+
ChildDoubleDefinitionCreate.new(self).proxy(subject, method_name, &definition_eval_block)
|
352
|
+
end
|
353
|
+
|
354
|
+
def strong(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
355
|
+
ChildDoubleDefinitionCreate.new(self).strong(subject, method_name, &definition_eval_block)
|
356
|
+
end
|
357
|
+
|
358
|
+
def any_instance_of(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
359
|
+
ChildDoubleDefinitionCreate.new(self).any_instance_of(subject, method_name, &definition_eval_block)
|
360
|
+
end
|
361
|
+
|
362
|
+
def instance_of(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
363
|
+
ChildDoubleDefinitionCreate.new(self).instance_of(subject, method_name, &definition_eval_block)
|
364
|
+
end
|
352
365
|
end
|
353
366
|
end
|
354
367
|
end
|
@@ -1,82 +1,51 @@
|
|
1
1
|
module RR
|
2
2
|
module DoubleDefinitions
|
3
3
|
class DoubleDefinitionCreate # :nodoc
|
4
|
-
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
self.add_verification_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
|
4
|
+
extend(Module.new do
|
5
|
+
def default_double_injection_strategy
|
6
|
+
@default_double_injection_strategy ||= lambda do |double_injection_create|
|
7
|
+
Strategies::DoubleInjection::Instance.new(double_injection_create)
|
9
8
|
end
|
10
|
-
CLASS
|
11
|
-
|
12
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
13
|
-
def #{strategy_method_name}!(method_name=nil, &definition_eval_block)
|
14
|
-
#{strategy_method_name}(Object.new, method_name, &definition_eval_block)
|
15
|
-
end
|
16
|
-
CLASS
|
17
9
|
end
|
18
|
-
|
19
|
-
def register_implementation_strategy_class(strategy_class, strategy_method_name)
|
20
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
21
|
-
def #{strategy_method_name}(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
22
|
-
self.add_implementation_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
|
23
|
-
end
|
24
|
-
CLASS
|
25
10
|
|
26
|
-
|
27
|
-
|
28
|
-
|
11
|
+
def set_default_double_injection_strategy(strategy_lambda)
|
12
|
+
original_strategy_lambda = default_double_injection_strategy
|
13
|
+
begin
|
14
|
+
@default_double_injection_strategy = strategy_lambda
|
15
|
+
yield
|
16
|
+
ensure
|
17
|
+
@default_double_injection_strategy = original_strategy_lambda
|
29
18
|
end
|
30
|
-
CLASS
|
31
19
|
end
|
20
|
+
end)
|
32
21
|
|
33
|
-
|
34
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
35
|
-
def #{strategy_method_name}(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
36
|
-
self.add_scope_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
|
37
|
-
end
|
38
|
-
CLASS
|
39
|
-
|
40
|
-
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
41
|
-
def #{strategy_method_name}!(method_name=nil, &definition_eval_block)
|
42
|
-
#{strategy_method_name}(Object.new, method_name, &definition_eval_block)
|
43
|
-
end
|
44
|
-
CLASS
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
attr_reader :subject,
|
49
|
-
:verification_strategy,
|
50
|
-
:implementation_strategy,
|
51
|
-
:scope_strategy
|
22
|
+
attr_reader :subject, :verification_strategy, :implementation_strategy, :double_injection_strategy
|
52
23
|
NO_SUBJECT = Object.new
|
53
24
|
|
54
25
|
include Space::Reader
|
55
26
|
|
56
27
|
def initialize
|
57
|
-
@verification_strategy =
|
28
|
+
@verification_strategy = Strategies::Verification::Stub.new(self)
|
58
29
|
@implementation_strategy = Strategies::Implementation::Reimplementation.new(self)
|
59
|
-
@
|
30
|
+
@double_injection_strategy = self.class.default_double_injection_strategy.call(self)
|
60
31
|
end
|
61
32
|
|
62
33
|
def call(method_name, *args, &handler)
|
63
|
-
raise DoubleDefinitionCreateError if no_subject?
|
64
34
|
definition = DoubleDefinition.new(self)
|
65
|
-
verification_strategy || no_strategy_error
|
66
35
|
verification_strategy.call(definition, method_name, args, handler)
|
67
36
|
implementation_strategy.call(definition, method_name, args, handler)
|
68
|
-
|
37
|
+
double_injection_strategy.call(definition, method_name, args, handler)
|
69
38
|
definition
|
70
39
|
end
|
71
|
-
|
40
|
+
|
72
41
|
def root_subject
|
73
42
|
subject
|
74
43
|
end
|
75
|
-
|
44
|
+
|
76
45
|
def method_name
|
77
46
|
@verification_strategy.method_name
|
78
47
|
end
|
79
|
-
|
48
|
+
|
80
49
|
module StrategySetupMethods
|
81
50
|
def no_subject?
|
82
51
|
subject.__id__ === NO_SUBJECT.__id__
|
@@ -95,9 +64,9 @@ module RR
|
|
95
64
|
end
|
96
65
|
end
|
97
66
|
|
98
|
-
def
|
67
|
+
def add_double_injection_strategy(double_injection_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
99
68
|
add_strategy(subject, method_name, definition_eval_block) do
|
100
|
-
self.
|
69
|
+
self.double_injection_strategy = double_injection_strategy_class.new(self)
|
101
70
|
end
|
102
71
|
end
|
103
72
|
|
@@ -119,56 +88,53 @@ module RR
|
|
119
88
|
end
|
120
89
|
|
121
90
|
def verification_strategy=(verification_strategy)
|
122
|
-
verify_no_verification_strategy
|
123
|
-
verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
|
124
91
|
@verification_strategy = verification_strategy
|
125
92
|
verification_strategy
|
126
93
|
end
|
127
94
|
|
128
95
|
def implementation_strategy=(implementation_strategy)
|
129
|
-
verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
|
130
96
|
@implementation_strategy = implementation_strategy
|
131
97
|
end
|
132
98
|
|
133
|
-
def
|
134
|
-
|
135
|
-
@scope_strategy = scope_strategy
|
99
|
+
def double_injection_strategy=(double_injection_strategy)
|
100
|
+
@double_injection_strategy = double_injection_strategy
|
136
101
|
end
|
102
|
+
end
|
103
|
+
include StrategySetupMethods
|
137
104
|
|
138
|
-
|
139
|
-
|
140
|
-
end
|
105
|
+
class DoubleDefinitionCreateError < Errors::RRError
|
106
|
+
end
|
141
107
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
108
|
+
# Verification Strategies
|
109
|
+
include ::RR::DoubleDefinitions::Strategies::StrategyMethods
|
110
|
+
def mock(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
111
|
+
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Mock, subject, method_name, &definition_eval_block)
|
112
|
+
end
|
148
113
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
implementation_strategy.is_a?(Strategies::Implementation::Proxy)
|
153
|
-
end
|
114
|
+
def stub(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
115
|
+
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Stub, subject, method_name, &definition_eval_block)
|
116
|
+
end
|
154
117
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
"Doubles cannot be proxied when using dont_allow strategy"
|
159
|
-
)
|
160
|
-
end
|
118
|
+
def dont_allow(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
119
|
+
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::DontAllow, subject, method_name, &definition_eval_block)
|
120
|
+
end
|
161
121
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
"This Double has no strategy"
|
166
|
-
)
|
167
|
-
end
|
122
|
+
# Implementation Strategies
|
123
|
+
def proxy(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
124
|
+
self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::Proxy, subject, method_name, &definition_eval_block)
|
168
125
|
end
|
169
|
-
include StrategySetupMethods
|
170
126
|
|
171
|
-
|
127
|
+
def strong(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
128
|
+
self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::StronglyTypedReimplementation, subject, method_name, &definition_eval_block)
|
129
|
+
end
|
130
|
+
|
131
|
+
# DoubleInjection Strategies
|
132
|
+
def any_instance_of(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
133
|
+
self.add_double_injection_strategy(::RR::DoubleDefinitions::Strategies::DoubleInjection::AnyInstanceOf, subject, method_name, &definition_eval_block)
|
134
|
+
end
|
135
|
+
|
136
|
+
def instance_of(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
|
137
|
+
self.add_double_injection_strategy(::RR::DoubleDefinitions::Strategies::DoubleInjection::NewInstanceOf, subject, method_name, &definition_eval_block)
|
172
138
|
end
|
173
139
|
end
|
174
140
|
end
|