rr 0.4.10 → 0.6.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 +14 -0
- data/README.rdoc +67 -13
- data/Rakefile +1 -1
- data/lib/rr.rb +29 -9
- data/lib/rr/adapters/rr_methods.rb +38 -158
- data/lib/rr/double.rb +46 -41
- data/lib/rr/double_definitions/child_double_definition_creator.rb +23 -0
- data/lib/rr/double_definitions/double_definition.rb +212 -0
- data/lib/rr/double_definitions/double_definition_creator.rb +153 -0
- data/lib/rr/double_definitions/double_definition_creator_proxy.rb +25 -0
- data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
- data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
- data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
- data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +43 -0
- data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
- data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
- data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
- data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
- data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
- data/lib/rr/double_injection.rb +21 -15
- data/lib/rr/expectations/argument_equality_expectation.rb +2 -1
- data/lib/rr/space.rb +23 -22
- data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
- data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
- data/spec/high_level_spec.rb +111 -64
- data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +1 -1
- data/spec/rr/adapters/rr_methods_creator_spec.rb +99 -315
- data/spec/rr/adapters/rr_methods_space_spec.rb +90 -109
- data/spec/rr/adapters/rr_methods_spec_helper.rb +1 -1
- data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +1 -1
- data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +103 -0
- data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +83 -0
- data/spec/rr/double_definitions/double_definition_creator_spec.rb +495 -0
- data/spec/rr/double_definitions/double_definition_spec.rb +1116 -0
- data/spec/rr/double_injection/double_injection_bind_spec.rb +111 -0
- data/spec/rr/double_injection/double_injection_dispatching_spec.rb +245 -0
- data/spec/rr/{double → double_injection}/double_injection_has_original_method_spec.rb +9 -9
- data/spec/rr/double_injection/double_injection_reset_spec.rb +90 -0
- data/spec/rr/double_injection/double_injection_spec.rb +77 -0
- data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
- data/spec/rr/double_spec.rb +156 -136
- data/spec/rr/errors/rr_error_spec.rb +1 -1
- data/spec/rr/expectations/any_argument_expectation_spec.rb +1 -1
- data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +6 -30
- data/spec/rr/expectations/argument_equality_expectation_spec.rb +35 -18
- data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +22 -41
- data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
- data/spec/rr/expectations/hash_including_spec.rb +17 -0
- data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
- data/spec/rr/expectations/satisfy_spec.rb +14 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +30 -28
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +55 -54
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +49 -48
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +9 -7
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +77 -76
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +58 -57
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +59 -58
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +25 -24
- data/spec/rr/rspec/rspec_adapter_spec.rb +12 -11
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +10 -8
- data/spec/rr/rspec/rspec_usage_spec.rb +1 -1
- data/spec/rr/space/hash_with_object_id_key_spec.rb +1 -1
- data/spec/rr/space/space_spec.rb +330 -192
- data/spec/rr/test_unit/test_helper.rb +1 -2
- data/spec/rr/test_unit/test_unit_backtrace_test.rb +1 -2
- data/spec/rr/test_unit/test_unit_integration_test.rb +1 -2
- data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/integer_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/proc_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/range_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +1 -1
- data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
- data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
- data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
- data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
- data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
- data/spec/rr_spec.rb +28 -0
- data/spec/spec_helper.rb +84 -0
- metadata +43 -29
- data/lib/rr/double_creator.rb +0 -271
- data/lib/rr/double_definition.rb +0 -179
- data/lib/rr/double_definition_builder.rb +0 -44
- data/lib/rr/double_definition_creator.rb +0 -156
- data/lib/rr/double_definition_creator_proxy.rb +0 -20
- data/spec/rr/double/double_injection_bind_spec.rb +0 -105
- data/spec/rr/double/double_injection_dispatching_spec.rb +0 -228
- data/spec/rr/double/double_injection_reset_spec.rb +0 -86
- data/spec/rr/double/double_injection_spec.rb +0 -72
- data/spec/rr/double/double_injection_verify_spec.rb +0 -24
- data/spec/rr/double_definition_creator_proxy_spec.rb +0 -85
- data/spec/rr/double_definition_creator_spec.rb +0 -496
- data/spec/rr/double_definition_spec.rb +0 -815
- data/spec/rr/expectations/anything_spec.rb +0 -14
- data/spec/rr/expectations/boolean_spec.rb +0 -14
- data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +0 -71
- data/spec/rr/expectations/duck_type_spec.rb +0 -14
- data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +0 -51
- data/spec/rr/expectations/is_a_spec.rb +0 -14
- data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +0 -47
- data/spec/rr/expectations/numeric_spec.rb +0 -14
- data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +0 -59
- data/spec/rr/expectations/range_spec.rb +0 -10
- data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +0 -72
- data/spec/rr/expectations/regexp_spec.rb +0 -10
data/CHANGES
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
* 0.6.0
|
2
|
+
- Friendlier DoubleNotFound error message
|
3
|
+
- Implemented Double strategy creation methods (#mock, #stub, #proxy, #instance_of, and ! equivalents) on DoubleDefinition
|
4
|
+
- Implemented hash_including matcher (Patch by Matthew O'Conner)
|
5
|
+
- Implemented satisfy matcher (Patch by Matthew O'Conner)
|
6
|
+
- Implemented DoubleDefinitionCreator#mock!, #stub!, and #dont_allow!
|
7
|
+
- Modified api to method chain Doubles
|
8
|
+
- Fix conflict with Mocha overriding Object#verify
|
9
|
+
|
10
|
+
* 0.5.0
|
11
|
+
- Method chaining Doubles (Patch by Nick Kallen)
|
12
|
+
- Chained ordered expectations (Patch by Nick Kallen)
|
13
|
+
- Space#verify_doubles can take one or more objects with DoubleInjections to be verified
|
14
|
+
|
1
15
|
* 0.4.10
|
2
16
|
- DoubleDefinitionCreatorProxy does not undef #object_id
|
3
17
|
- Fixed rdoc pointer to README
|
data/README.rdoc
CHANGED
@@ -3,6 +3,15 @@
|
|
3
3
|
RR (Double Ruby) is a test double framework that features a rich
|
4
4
|
selection of double techniques and a terse syntax.
|
5
5
|
|
6
|
+
== More Information
|
7
|
+
=== Mailing Lists
|
8
|
+
* double-ruby-users@rubyforge.org
|
9
|
+
* double-ruby-devel@rubyforge.org
|
10
|
+
|
11
|
+
=== Websites
|
12
|
+
* http://rubyforge.org/projects/double-ruby
|
13
|
+
* http://github.com/btakita/rr
|
14
|
+
|
6
15
|
== What is a Test Double?
|
7
16
|
A Test Double is a generalization of something that replaces a real
|
8
17
|
object to make it easier to test another object. Its like a stunt
|
@@ -33,7 +42,7 @@ support spies.
|
|
33
42
|
== Syntax between RR and other double/mock frameworks
|
34
43
|
=== Terse Syntax
|
35
44
|
One of the goals of RR is to make doubles more scannable.
|
36
|
-
This is accomplished by
|
45
|
+
This is accomplished by making the double declaration look as much as the actual method invocation as possible.
|
37
46
|
Here is RR compared to other mock frameworks:
|
38
47
|
|
39
48
|
flexmock(User).should_receive(:find).with('42').and_return(jane) # Flexmock
|
@@ -42,10 +51,8 @@ Here is RR compared to other mock frameworks:
|
|
42
51
|
User.should_receive(:find).with('42') {jane} # Rspec using return value blocks
|
43
52
|
mock(User).find('42') {jane} # RR
|
44
53
|
|
45
|
-
===
|
46
|
-
RR
|
47
|
-
like other frameworks. Instead, RR utilizes a technique known as
|
48
|
-
"double injection".
|
54
|
+
=== Double Injections (a.k.a Partial Mocking)
|
55
|
+
RR utilizes a technique known as "double injection".
|
49
56
|
|
50
57
|
my_object = MyClass.new
|
51
58
|
mock(my_object).hello
|
@@ -54,10 +61,14 @@ Compare this with doing a mock in mocha:
|
|
54
61
|
my_mocked_object = mock()
|
55
62
|
my_mocked_object.expects(:hello)
|
56
63
|
|
64
|
+
== Pure Mock objects
|
57
65
|
If you wish to use objects for the sole purpose of being a mock, you can
|
58
66
|
do so by creating an empty object.
|
59
67
|
mock(my_mock_object = Object.new).hello
|
60
68
|
|
69
|
+
or by using mock!
|
70
|
+
my_mock_object = mock!.hello.subject # Mocks the #hello method and retrieves that object via the #subject method
|
71
|
+
|
61
72
|
=== No should_receive or expects method
|
62
73
|
RR uses method_missing to set your method expectation. This means you do not
|
63
74
|
need to use a method such as should_receive or expects.
|
@@ -70,7 +81,7 @@ Rspec mocks:
|
|
70
81
|
my_object.should_receive(:hello) # should_receive sets the hello method expectation
|
71
82
|
|
72
83
|
=== with method call is not necessary
|
73
|
-
Since RR uses method_missing, it also
|
84
|
+
Since RR uses method_missing, it also makes using the #with method unnecessary in most circumstances
|
74
85
|
to set the argument expectations.
|
75
86
|
|
76
87
|
mock(my_object).hello('bob', 'jane')
|
@@ -95,16 +106,19 @@ Rspec mocks:
|
|
95
106
|
|
96
107
|
== Using RR
|
97
108
|
To create a double on an object, you can use the following methods:
|
98
|
-
* mock
|
99
|
-
* stub
|
100
|
-
*
|
101
|
-
*
|
109
|
+
* mock or mock!
|
110
|
+
* stub or stub!
|
111
|
+
* dont_allow or dont_allow!
|
112
|
+
* proxy or proxy!
|
113
|
+
* instance_of or instance_of!
|
102
114
|
|
103
|
-
These methods are composable. mock and
|
115
|
+
These methods are composable. mock, stub, and dont_allow can be used by themselves and
|
104
116
|
are mutually exclusive.
|
105
|
-
proxy and instance_of must be chained with mock or stub. You can chain
|
117
|
+
proxy and instance_of must be chained with mock or stub. You can also chain
|
106
118
|
proxy and instance_of together.
|
107
119
|
|
120
|
+
The ! (bang) version of these methods causes the subject object of the Double to be instantiated.
|
121
|
+
|
108
122
|
=== mock
|
109
123
|
mock replaces the method on the object with an expectation and implementation.
|
110
124
|
The expectations are a mock will be called with certain arguments a certain
|
@@ -136,6 +150,12 @@ an exception is raised.
|
|
136
150
|
raise "Unexpected id #{id.inspect} passed to me"
|
137
151
|
end
|
138
152
|
|
153
|
+
=== dont_allow - aliased with do_not_allow, dont_call, and do_not_call
|
154
|
+
dont_allow sets an expectation on the Double that it will never be called.
|
155
|
+
If the Double is called, then a TimesCalledError is raised.
|
156
|
+
dont_allow(User).find('42')
|
157
|
+
User.find('42') # raises a TimesCalledError
|
158
|
+
|
139
159
|
=== mock.proxy
|
140
160
|
mock.proxy replaces the method on the object with an expectation, implementation, and
|
141
161
|
also invokes the actual method. mock.proxy also intercepts the return value and
|
@@ -190,6 +210,22 @@ Put double scenarios on instances of a Class.
|
|
190
210
|
m.system("rake baz") {true}
|
191
211
|
end
|
192
212
|
|
213
|
+
=== Double Graphs
|
214
|
+
RR has a method-chaining api support for Double graphs. For example,
|
215
|
+
lets say you want an object to receive a method call to #foo, and have
|
216
|
+
the return value receive a method call to #bar.
|
217
|
+
|
218
|
+
In RR, you would do:
|
219
|
+
stub(object).foo.stub!.bar {:baz}
|
220
|
+
object.foo.bar # :baz
|
221
|
+
# or
|
222
|
+
stub(object).foo {stub!.bar {:baz}}
|
223
|
+
object.foo.bar # :baz
|
224
|
+
# or
|
225
|
+
bar = stub!.bar {:baz}
|
226
|
+
stub(object).foo {bar}
|
227
|
+
object.foo.bar # :baz
|
228
|
+
|
193
229
|
=== Argument Wildcard matchers
|
194
230
|
==== anything
|
195
231
|
mock(object).foobar(1, anything)
|
@@ -214,6 +250,22 @@ Put double scenarios on instances of a Class.
|
|
214
250
|
def arg.talk; 'quack'; end
|
215
251
|
object.foobar(arg)
|
216
252
|
|
253
|
+
==== Ranges
|
254
|
+
mock(object).foobar(1..10)
|
255
|
+
object.foobar(5)
|
256
|
+
|
257
|
+
==== Regexps
|
258
|
+
mock(object).foobar(/on/)
|
259
|
+
object.foobar("ruby on rails")
|
260
|
+
|
261
|
+
==== hash_including
|
262
|
+
mock(object).foobar(hash_including(:red => "#FF0000", :blue => "#0000FF"))
|
263
|
+
object.foobar({:red => "#FF0000", :blue => "#0000FF", :green => "#00FF00"})
|
264
|
+
|
265
|
+
==== satisfy
|
266
|
+
mock(object).foobar(satisfy {|arg| arg.length == 2})
|
267
|
+
object.foobar("xy")
|
268
|
+
|
217
269
|
=== Invocation Amount Wildcard Matchers
|
218
270
|
==== any_times
|
219
271
|
mock(object).method_name(anything).times(any_times) {return_value}
|
@@ -222,10 +274,12 @@ Put double scenarios on instances of a Class.
|
|
222
274
|
With any development effort, there are countless people who have contributed
|
223
275
|
to making it possible. We all are standing on the shoulders of giants.
|
224
276
|
* Pivotal Labs for sponsoring RR development
|
277
|
+
* Nick Kallen for documentation suggestions, bug reports, and patches
|
278
|
+
* Matthew O'Conner for patches
|
279
|
+
* Nathan Sobo for various ideas and inspiration for cleaner and more expressive code
|
225
280
|
* Parker Thompson for pairing with me
|
226
281
|
* Felix Morio for pairing with me
|
227
282
|
* Jeff Whitmire for documentation suggestions
|
228
|
-
* Nick Kallen for documentation suggestion & bug reports
|
229
283
|
* David Chelimsky for encouragement to make the RR framework, for developing
|
230
284
|
the Rspec mock framework, and syntax ideas
|
231
285
|
* Gerard Meszaros for his excellent book "xUnit Test Patterns"
|
data/Rakefile
CHANGED
data/lib/rr.rb
CHANGED
@@ -10,13 +10,24 @@ require "#{dir}/rr/space"
|
|
10
10
|
require "#{dir}/rr/double_injection"
|
11
11
|
require "#{dir}/rr/hash_with_object_id_key"
|
12
12
|
|
13
|
-
require "#{dir}/rr/double_definition_creator_proxy"
|
14
|
-
|
15
|
-
require "#{dir}/rr/
|
13
|
+
require "#{dir}/rr/double_definitions/double_definition_creator_proxy"
|
14
|
+
require "#{dir}/rr/double_definitions/double_definition_creator"
|
15
|
+
require "#{dir}/rr/double_definitions/child_double_definition_creator"
|
16
|
+
require "#{dir}/rr/adapters/rr_methods"
|
16
17
|
|
17
18
|
require "#{dir}/rr/double"
|
18
|
-
require "#{dir}/rr/double_definition"
|
19
|
-
require "#{dir}/rr/
|
19
|
+
require "#{dir}/rr/double_definitions/double_definition"
|
20
|
+
require "#{dir}/rr/double_definitions/strategies/strategy"
|
21
|
+
require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
|
22
|
+
require "#{dir}/rr/double_definitions/strategies/verification/mock"
|
23
|
+
require "#{dir}/rr/double_definitions/strategies/verification/stub"
|
24
|
+
require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
|
25
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
|
26
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
|
27
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
|
28
|
+
require "#{dir}/rr/double_definitions/strategies/scope/scope_strategy"
|
29
|
+
require "#{dir}/rr/double_definitions/strategies/scope/instance"
|
30
|
+
require "#{dir}/rr/double_definitions/strategies/scope/instance_of_class"
|
20
31
|
require "#{dir}/rr/double_matches"
|
21
32
|
|
22
33
|
require "#{dir}/rr/expectations/argument_equality_expectation"
|
@@ -30,6 +41,8 @@ require "#{dir}/rr/wildcard_matchers/boolean"
|
|
30
41
|
require "#{dir}/rr/wildcard_matchers/duck_type"
|
31
42
|
require "#{dir}/rr/wildcard_matchers/regexp"
|
32
43
|
require "#{dir}/rr/wildcard_matchers/range"
|
44
|
+
require "#{dir}/rr/wildcard_matchers/satisfy"
|
45
|
+
require "#{dir}/rr/wildcard_matchers/hash_including"
|
33
46
|
|
34
47
|
require "#{dir}/rr/times_called_matchers/terminal"
|
35
48
|
require "#{dir}/rr/times_called_matchers/non_terminal"
|
@@ -41,15 +54,22 @@ require "#{dir}/rr/times_called_matchers/proc_matcher"
|
|
41
54
|
require "#{dir}/rr/times_called_matchers/at_least_matcher"
|
42
55
|
require "#{dir}/rr/times_called_matchers/at_most_matcher"
|
43
56
|
|
44
|
-
require "#{dir}/rr/adapters/rr_methods"
|
45
|
-
|
46
57
|
require "#{dir}/rr/adapters/rspec"
|
47
58
|
require "#{dir}/rr/adapters/test_unit"
|
48
59
|
|
49
60
|
module RR
|
50
61
|
class << self
|
62
|
+
(RR::Space.instance_methods - Object.instance_methods).each do |method_name|
|
63
|
+
returns_method = <<-METHOD
|
64
|
+
def #{method_name}(*args, &block)
|
65
|
+
RR::Space.instance.__send__(:#{method_name}, *args, &block)
|
66
|
+
end
|
67
|
+
METHOD
|
68
|
+
class_eval(returns_method, __FILE__, __LINE__ - 4)
|
69
|
+
end
|
70
|
+
|
51
71
|
def method_missing(method_name, *args, &block)
|
52
72
|
RR::Space.instance.__send__(method_name, *args, &block)
|
53
73
|
end
|
54
|
-
end
|
55
|
-
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,6 +1,24 @@
|
|
1
1
|
module RR
|
2
2
|
module Adapters
|
3
3
|
module RRMethods
|
4
|
+
class << self
|
5
|
+
def register_strategy_class(strategy_class, method_name)
|
6
|
+
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
7
|
+
def #{method_name}(subject=DoubleDefinitions::DoubleDefinitionCreator::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
8
|
+
creator = DoubleDefinitions::DoubleDefinitionCreator.new
|
9
|
+
creator.#{method_name}(subject, method_name, &definition_eval_block)
|
10
|
+
end
|
11
|
+
CLASS
|
12
|
+
|
13
|
+
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
14
|
+
def #{method_name}!(method_name=nil, &definition_eval_block)
|
15
|
+
creator = DoubleDefinitions::DoubleDefinitionCreator.new
|
16
|
+
creator.#{method_name}!(method_name, &definition_eval_block)
|
17
|
+
end
|
18
|
+
CLASS
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
# Verifies all the DoubleInjection objects have met their
|
5
23
|
# TimesCalledExpectations.
|
6
24
|
def verify
|
@@ -12,163 +30,6 @@ module RR
|
|
12
30
|
RR::Space.instance.reset
|
13
31
|
end
|
14
32
|
|
15
|
-
# This method sets the Double to have a mock strategy. A mock strategy
|
16
|
-
# sets the default state of the Double to expect the method call
|
17
|
-
# with arguments exactly one time. The Double's expectations can be
|
18
|
-
# changed.
|
19
|
-
#
|
20
|
-
# This method can be chained with proxy.
|
21
|
-
# mock.proxy(subject).method_name_1
|
22
|
-
# or
|
23
|
-
# proxy.mock(subject).method_name_1
|
24
|
-
#
|
25
|
-
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
26
|
-
# a method with arguments to the proxy will set up expectations that
|
27
|
-
# the a call to the subject's method with the arguments will happen,
|
28
|
-
# and return the prescribed value.
|
29
|
-
# mock(subject).method_name_1 {return_value_1}
|
30
|
-
# mock(subject).method_name_2(arg1, arg2) {return_value_2}
|
31
|
-
#
|
32
|
-
# When passed the subject and the method_name, this method returns
|
33
|
-
# a mock Double with the method already set.
|
34
|
-
#
|
35
|
-
# mock(subject, :method_name_1) {return_value_1}
|
36
|
-
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
37
|
-
#
|
38
|
-
# mock also takes a block for definitions.
|
39
|
-
# mock(subject) do
|
40
|
-
# method_name_1 {return_value_1}
|
41
|
-
# method_name_2(arg_1, arg_2) {return_value_2}
|
42
|
-
# end
|
43
|
-
def mock(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
44
|
-
creator = DoubleDefinitionCreator.new
|
45
|
-
creator.mock(subject, method_name, &definition)
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
# This method sets the Double to have a stub strategy. A stub strategy
|
50
|
-
# sets the default state of the Double to expect the method call
|
51
|
-
# with any arguments any number of times. The Double's
|
52
|
-
# expectations can be changed.
|
53
|
-
#
|
54
|
-
# This method can be chained with proxy.
|
55
|
-
# stub.proxy(subject).method_name_1
|
56
|
-
# or
|
57
|
-
# proxy.stub(subject).method_name_1
|
58
|
-
#
|
59
|
-
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
60
|
-
# a method with arguments to the proxy will set up expectations that
|
61
|
-
# the a call to the subject's method with the arguments will happen,
|
62
|
-
# and return the prescribed value.
|
63
|
-
# stub(subject).method_name_1 {return_value_1}
|
64
|
-
# stub(subject).method_name_2(arg_1, arg_2) {return_value_2}
|
65
|
-
#
|
66
|
-
# When passed the subject and the method_name, this method returns
|
67
|
-
# a stub Double with the method already set.
|
68
|
-
#
|
69
|
-
# mock(subject, :method_name_1) {return_value_1}
|
70
|
-
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
71
|
-
#
|
72
|
-
# stub also takes a block for definitions.
|
73
|
-
# stub(subject) do
|
74
|
-
# method_name_1 {return_value_1}
|
75
|
-
# method_name_2(arg_1, arg_2) {return_value_2}
|
76
|
-
# end
|
77
|
-
def stub(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
78
|
-
creator = DoubleDefinitionCreator.new
|
79
|
-
creator.stub(subject, method_name, &definition)
|
80
|
-
end
|
81
|
-
|
82
|
-
# This method add proxy capabilities to the Double. proxy can be called
|
83
|
-
# with mock or stub.
|
84
|
-
#
|
85
|
-
# mock.proxy(controller.template).render(:partial => "my/socks")
|
86
|
-
#
|
87
|
-
# stub.proxy(controller.template).render(:partial => "my/socks") do |html|
|
88
|
-
# html.should include("My socks are wet")
|
89
|
-
# html
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
93
|
-
# html.should include("My socks are wet")
|
94
|
-
# "My new return value"
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# mock.proxy also takes a block for definitions.
|
98
|
-
# mock.proxy(subject) do
|
99
|
-
# render(:partial => "my/socks")
|
100
|
-
#
|
101
|
-
# render(:partial => "my/socks") do |html|
|
102
|
-
# html.should include("My socks are wet")
|
103
|
-
# html
|
104
|
-
# end
|
105
|
-
#
|
106
|
-
# render(:partial => "my/socks") do |html|
|
107
|
-
# html.should include("My socks are wet")
|
108
|
-
# html
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# render(:partial => "my/socks") do |html|
|
112
|
-
# html.should include("My socks are wet")
|
113
|
-
# "My new return value"
|
114
|
-
# end
|
115
|
-
# end
|
116
|
-
#
|
117
|
-
# Passing a block to the Double (after the method name and arguments)
|
118
|
-
# allows you to intercept the return value.
|
119
|
-
# The return value can be modified, validated, and/or overridden by
|
120
|
-
# passing in a block. The return value of the block will replace
|
121
|
-
# the actual return value.
|
122
|
-
#
|
123
|
-
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
124
|
-
# html.should include("My socks are wet")
|
125
|
-
# "My new return value"
|
126
|
-
# end
|
127
|
-
def proxy(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
128
|
-
creator = DoubleDefinitionCreator.new
|
129
|
-
creator.proxy(subject, method_name, &definition)
|
130
|
-
end
|
131
|
-
|
132
|
-
# This method sets the Double to have a dont_allow strategy.
|
133
|
-
# A dont_allow strategy sets the default state of the Double
|
134
|
-
# to expect never to be called. The Double's expectations can be
|
135
|
-
# changed.
|
136
|
-
#
|
137
|
-
# The following example sets the expectation that subject.method_name
|
138
|
-
# will never be called with arg1 and arg2.
|
139
|
-
#
|
140
|
-
# do_not_allow(subject).method_name(arg1, arg2)
|
141
|
-
#
|
142
|
-
# dont_allow also supports a block sytnax.
|
143
|
-
# dont_allow(subject) do |m|
|
144
|
-
# m.method1 # Do not allow method1 with any arguments
|
145
|
-
# m.method2(arg1, arg2) # Do not allow method2 with arguments arg1 and arg2
|
146
|
-
# m.method3.with_no_args # Do not allow method3 with no arguments
|
147
|
-
# end
|
148
|
-
def dont_allow(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
149
|
-
creator = DoubleDefinitionCreator.new
|
150
|
-
creator.dont_allow(subject, method_name, &definition)
|
151
|
-
end
|
152
|
-
alias_method :do_not_allow, :dont_allow
|
153
|
-
alias_method :dont_call, :dont_allow
|
154
|
-
alias_method :do_not_call, :dont_allow
|
155
|
-
|
156
|
-
# Calling instance_of will cause all instances of the passed in Class
|
157
|
-
# to have the Double defined.
|
158
|
-
#
|
159
|
-
# The following example mocks all User's valid? method and return false.
|
160
|
-
# mock.instance_of(User).valid? {false}
|
161
|
-
#
|
162
|
-
# The following example mocks and proxies User#projects and returns the
|
163
|
-
# first 3 projects.
|
164
|
-
# mock.instance_of(User).projects do |projects|
|
165
|
-
# projects[0..2]
|
166
|
-
# end
|
167
|
-
def instance_of(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
168
|
-
creator = DoubleDefinitionCreator.new
|
169
|
-
creator.instance_of(subject, method_name, &definition)
|
170
|
-
end
|
171
|
-
|
172
33
|
# Returns a AnyTimesMatcher. This is meant to be passed in as an argument
|
173
34
|
# to Double#times.
|
174
35
|
#
|
@@ -210,7 +71,7 @@ module RR
|
|
210
71
|
end
|
211
72
|
|
212
73
|
# Sets up a DuckType wildcard ArgumentEqualityExpectation
|
213
|
-
# that succeeds when passed
|
74
|
+
# that succeeds when the passed argument implements the methods.
|
214
75
|
# arg = Object.new
|
215
76
|
# def arg.foo; end
|
216
77
|
# def arg.bar; end
|
@@ -219,6 +80,25 @@ module RR
|
|
219
80
|
def duck_type(*args)
|
220
81
|
RR::WildcardMatchers::DuckType.new(*args)
|
221
82
|
end
|
83
|
+
|
84
|
+
# Sets up a HashIncluding wildcard ArgumentEqualityExpectation
|
85
|
+
# that succeeds when the passed argument contains at least those keys
|
86
|
+
# and values of the expectation.
|
87
|
+
# mock(object).method_name(hash_including(:foo => 1)) {return_value}
|
88
|
+
# object.method_name({:foo => 1, :bar => 2) # passes
|
89
|
+
def hash_including(expected_hash)
|
90
|
+
RR::WildcardMatchers::HashIncluding.new(expected_hash)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Sets up a Satisfy wildcard ArgumentEqualityExpectation
|
94
|
+
# that succeeds when the passed argument causes the expectation's
|
95
|
+
# proc to return true.
|
96
|
+
# mock(object).method_name(satisfy {|arg| arg == :foo}) {return_value}
|
97
|
+
# object.method_name(:foo) # passes
|
98
|
+
def satisfy(expectation_proc=nil, &block)
|
99
|
+
expectation_proc ||= block
|
100
|
+
RR::WildcardMatchers::Satisfy.new(expectation_proc)
|
101
|
+
end
|
222
102
|
|
223
103
|
instance_methods.each do |name|
|
224
104
|
alias_method "rr_#{name}", name
|