rr 0.3.11 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/CHANGES +8 -3
  2. data/README +130 -39
  3. data/Rakefile +6 -5
  4. data/lib/rr.rb +8 -8
  5. data/lib/rr/adapters/rr_methods.rb +228 -0
  6. data/lib/rr/adapters/rspec.rb +1 -1
  7. data/lib/rr/adapters/test_unit.rb +1 -1
  8. data/lib/rr/double.rb +294 -89
  9. data/lib/rr/{scenario_creator.rb → double_creator.rb} +65 -66
  10. data/lib/rr/{scenario_definition.rb → double_definition.rb} +36 -36
  11. data/lib/rr/{scenario_definition_builder.rb → double_definition_builder.rb} +3 -3
  12. data/lib/rr/double_insertion.rb +132 -0
  13. data/lib/rr/{scenario_matches.rb → double_matches.rb} +2 -2
  14. data/lib/rr/{scenario_method_proxy.rb → double_method_proxy.rb} +2 -2
  15. data/lib/rr/errors/argument_equality_error.rb +3 -3
  16. data/lib/rr/errors/rr_error.rb +13 -13
  17. data/lib/rr/errors/scenario_definition_error.rb +3 -3
  18. data/lib/rr/errors/scenario_not_found_error.rb +3 -3
  19. data/lib/rr/errors/scenario_order_error.rb +3 -3
  20. data/lib/rr/errors/times_called_error.rb +3 -3
  21. data/lib/rr/expectations/any_argument_expectation.rb +1 -1
  22. data/lib/rr/expectations/argument_equality_expectation.rb +1 -1
  23. data/lib/rr/expectations/times_called_expectation.rb +1 -1
  24. data/lib/rr/hash_with_object_id_key.rb +1 -1
  25. data/lib/rr/space.rb +40 -40
  26. data/lib/rr/times_called_matchers/any_times_matcher.rb +13 -13
  27. data/lib/rr/times_called_matchers/at_least_matcher.rb +11 -11
  28. data/lib/rr/times_called_matchers/at_most_matcher.rb +16 -16
  29. data/lib/rr/times_called_matchers/integer_matcher.rb +13 -13
  30. data/lib/rr/times_called_matchers/non_terminal.rb +21 -21
  31. data/lib/rr/times_called_matchers/proc_matcher.rb +7 -7
  32. data/lib/rr/times_called_matchers/range_matcher.rb +14 -14
  33. data/lib/rr/times_called_matchers/terminal.rb +16 -16
  34. data/lib/rr/times_called_matchers/times_called_matcher.rb +32 -32
  35. data/spec/core_spec_suite.rb +18 -0
  36. data/{examples → spec}/environment_fixture_setup.rb +0 -1
  37. data/{examples/high_level_example.rb → spec/high_level_spec.rb} +11 -11
  38. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  39. data/spec/rr/adapters/rr_methods_creator_spec.rb +365 -0
  40. data/spec/rr/adapters/rr_methods_space_spec.rb +134 -0
  41. data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
  42. data/{examples/rr/extensions/instance_methods_times_matcher_example.rb → spec/rr/adapters/rr_methods_times_matcher_spec.rb} +4 -4
  43. data/spec/rr/double/double_insertion_bind_spec.rb +78 -0
  44. data/spec/rr/double/double_insertion_dispatching_spec.rb +221 -0
  45. data/spec/rr/double/double_insertion_has_original_method_spec.rb +56 -0
  46. data/spec/rr/double/double_insertion_register_scenario_spec.rb +24 -0
  47. data/spec/rr/double/double_insertion_reset_spec.rb +89 -0
  48. data/spec/rr/double/double_insertion_spec.rb +66 -0
  49. data/spec/rr/double/double_insertion_verify_spec.rb +23 -0
  50. data/spec/rr/double_creator_spec.rb +454 -0
  51. data/{examples/rr/scenario_definition_example.rb → spec/rr/double_definition_spec.rb} +143 -143
  52. data/spec/rr/double_method_proxy_spec.rb +71 -0
  53. data/spec/rr/double_spec.rb +654 -0
  54. data/spec/rr/errors/rr_error_spec.rb +65 -0
  55. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  56. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +38 -0
  57. data/spec/rr/expectations/argument_equality_expectation_spec.rb +58 -0
  58. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +53 -0
  59. data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +71 -0
  60. data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +51 -0
  61. data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +47 -0
  62. data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +59 -0
  63. data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +72 -0
  64. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +43 -0
  65. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +67 -0
  66. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
  67. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +21 -0
  68. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +103 -0
  69. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +79 -0
  70. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +81 -0
  71. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +40 -0
  72. data/spec/rr/rspec/rspec_adapter_spec.rb +65 -0
  73. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +52 -0
  74. data/spec/rr/rspec/rspec_usage_spec.rb +67 -0
  75. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  76. data/spec/rr/space/space_create_spec.rb +278 -0
  77. data/spec/rr/space/space_helper.rb +7 -0
  78. data/spec/rr/space/space_register_spec.rb +32 -0
  79. data/spec/rr/space/space_reset_spec.rb +131 -0
  80. data/spec/rr/space/space_spec.rb +32 -0
  81. data/spec/rr/space/space_verify_spec.rb +181 -0
  82. data/{examples → spec}/rr/test_unit/test_helper.rb +1 -1
  83. data/{examples → spec}/rr/test_unit/test_unit_backtrace_test.rb +0 -0
  84. data/{examples → spec}/rr/test_unit/test_unit_integration_test.rb +4 -4
  85. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  86. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  87. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  88. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  89. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  90. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  91. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  92. data/spec/rspec_spec_suite.rb +16 -0
  93. data/spec/spec_helper.rb +9 -0
  94. data/{examples/example_suite.rb → spec/spec_suite.rb} +3 -3
  95. data/{examples/test_unit_example_suite.rb → spec/test_unit_spec_suite.rb} +0 -0
  96. metadata +93 -93
  97. data/examples/core_example_suite.rb +0 -31
  98. data/examples/example_helper.rb +0 -9
  99. data/examples/rr/double/double_bind_example.rb +0 -70
  100. data/examples/rr/double/double_dispatching_example.rb +0 -236
  101. data/examples/rr/double/double_example.rb +0 -66
  102. data/examples/rr/double/double_has_original_method_example.rb +0 -56
  103. data/examples/rr/double/double_register_scenario_example.rb +0 -24
  104. data/examples/rr/double/double_reset_example.rb +0 -89
  105. data/examples/rr/double/double_verify_example.rb +0 -23
  106. data/examples/rr/errors/rr_error_example.rb +0 -65
  107. data/examples/rr/expectations/any_argument_expectation_example.rb +0 -52
  108. data/examples/rr/expectations/anything_argument_equality_expectation_example.rb +0 -38
  109. data/examples/rr/expectations/argument_equality_expectation_example.rb +0 -62
  110. data/examples/rr/expectations/boolean_argument_equality_expectation_example.rb +0 -48
  111. data/examples/rr/expectations/duck_type_argument_equality_expectation_example.rb +0 -67
  112. data/examples/rr/expectations/is_a_argument_equality_expectation_example.rb +0 -50
  113. data/examples/rr/expectations/numeric_argument_equality_expectation_example.rb +0 -46
  114. data/examples/rr/expectations/range_argument_equality_expectation_example.rb +0 -59
  115. data/examples/rr/expectations/regexp_argument_equality_expectation_example.rb +0 -67
  116. data/examples/rr/expectations/times_called_expectation/times_called_expectation_any_times_example.rb +0 -50
  117. data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_least_example.rb +0 -73
  118. data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_most_example.rb +0 -77
  119. data/examples/rr/expectations/times_called_expectation/times_called_expectation_example.rb +0 -42
  120. data/examples/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +0 -20
  121. data/examples/rr/expectations/times_called_expectation/times_called_expectation_integer_example.rb +0 -111
  122. data/examples/rr/expectations/times_called_expectation/times_called_expectation_proc_example.rb +0 -88
  123. data/examples/rr/expectations/times_called_expectation/times_called_expectation_range_example.rb +0 -90
  124. data/examples/rr/extensions/instance_methods_argument_matcher_example.rb +0 -65
  125. data/examples/rr/extensions/instance_methods_creator_example.rb +0 -363
  126. data/examples/rr/extensions/instance_methods_example_helper.rb +0 -11
  127. data/examples/rr/extensions/instance_methods_space_example.rb +0 -122
  128. data/examples/rr/rspec/rspec_adapter_example.rb +0 -63
  129. data/examples/rr/rspec/rspec_backtrace_tweaking_example.rb +0 -36
  130. data/examples/rr/rspec/rspec_usage_example.rb +0 -65
  131. data/examples/rr/scenario_creator_example.rb +0 -459
  132. data/examples/rr/scenario_example.rb +0 -701
  133. data/examples/rr/scenario_method_proxy_example.rb +0 -71
  134. data/examples/rr/space/hash_with_object_id_key_example.rb +0 -86
  135. data/examples/rr/space/space_create_example.rb +0 -278
  136. data/examples/rr/space/space_example.rb +0 -29
  137. data/examples/rr/space/space_helper.rb +0 -7
  138. data/examples/rr/space/space_register_example.rb +0 -32
  139. data/examples/rr/space/space_reset_example.rb +0 -120
  140. data/examples/rr/space/space_verify_example.rb +0 -169
  141. data/examples/rr/times_called_matchers/any_times_matcher_example.rb +0 -63
  142. data/examples/rr/times_called_matchers/at_least_matcher_example.rb +0 -70
  143. data/examples/rr/times_called_matchers/at_most_matcher_example.rb +0 -85
  144. data/examples/rr/times_called_matchers/integer_matcher_example.rb +0 -91
  145. data/examples/rr/times_called_matchers/proc_matcher_example.rb +0 -77
  146. data/examples/rr/times_called_matchers/range_matcher_example.rb +0 -97
  147. data/examples/rr/times_called_matchers/times_called_matcher_example.rb +0 -53
  148. data/examples/rspec_example_suite.rb +0 -25
  149. data/lib/rr/extensions/instance_methods.rb +0 -228
  150. data/lib/rr/scenario.rb +0 -337
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ * 0.4.0
2
+ - Documentation improvements
3
+ - Renamed Double to DoubleInsertion
4
+ - Renamed Scenario to Double
5
+
1
6
  * 0.3.11
2
7
  - Fixed [#13724] Mock Proxy on Active Record Association proxies causes error
3
8
 
@@ -50,7 +55,7 @@
50
55
  - Fixed [#12402] Stubbing return value of probes fails after calling the stubbed method two times
51
56
 
52
57
  * 0.2.3
53
- - Added InstanceMethods#rr_verify and InstanceMethods#rr_reset
58
+ - Added RRMethods#rr_verify and RRMethods#rr_reset
54
59
 
55
60
  * 0.2.2
56
61
  - Fixed "singleton method bound for a different object"
@@ -62,8 +67,8 @@
62
67
  - Probe returns the return value of the passed in block, instead of ignoring its return value
63
68
  - Scenario#after_call returns the return value of the passed in block
64
69
  - Not using method aliasing to store original method
65
- - Renamed DoubleMethods to InstanceMethods
66
- - Added InstanceMethods#mock_probe
70
+ - Renamed DoubleMethods to RRMethods
71
+ - Added RRMethods#mock_probe
67
72
 
68
73
  * 0.1.15
69
74
  - Fixed [#12333] Rebinding original_methods causes blocks not to work
data/README CHANGED
@@ -1,32 +1,134 @@
1
1
  = RR
2
2
 
3
- RR (Double Ruby) is a double framework that features a rich
3
+ RR (Double Ruby) is a test double framework that features a rich
4
4
  selection of double techniques and a terse syntax.
5
+
6
+ == What is a Test Double?
7
+ A Test Double is a generalization of something that replaces a real
8
+ object to make it easier to test another object. Its like a stunt
9
+ double for tests. The following are test doubles:
10
+ * Mocks
11
+ * Stubs
12
+ * Fakes
13
+ * Spies
14
+ * Proxies
5
15
  http://xunitpatterns.com/Test%20Double.html
6
16
 
7
- Currently RR implements mocks, stubs, and probes. It is a goal of
8
- RR to support a wide range of double techniques and patterns.
17
+ Currently RR implements mocks, stubs, and proxies. In the future, RR will
18
+ support spies.
19
+
20
+ == Syntax between RR and other double/mock frameworks
21
+ === Terse Syntax
22
+ One of the goals of RR is to make doubles more scannable.
23
+ This is accomplished by removing words from a double declaration.
24
+ Here is RR compared to other mock frameworks:
25
+
26
+ flexmock(User).should_receive(:find).with('42').and_return(jane) # Flexmock
27
+ User.should_receive(:find).with('42').and_return(jane) # Rspec
28
+ User.expects(:find).with('42').returns {jane} # Mocha
29
+ User.should_receive(:find).with('42') {jane} # Rspec using return value blocks
30
+ mock(User).find('42') {jane} # RR
31
+
32
+ === No mock objects
33
+ RR is an opinionated framework. RR does not create a mock object for you,
34
+ like other frameworks. Instead, RR utilizes a technique known as
35
+ "partial mocking".
36
+
37
+ my_object = MyClass.new
38
+ mock(my_object).hello
39
+
40
+ Compare this with doing a mock in mocha:
41
+ my_mocked_object = mock()
42
+ my_mocked_object.expects(:hello)
43
+
44
+ === No should_receive or expects method
45
+ RR uses method_missing to set your method expectation. This means you do not
46
+ need to use a method such as should_receive or expects.
47
+
48
+ mock(my_object).hello # The hello method on my_object is mocked
49
+
50
+ Mocha:
51
+ my_object.expects(:hello) # expects sets the hello method expectation
52
+ Rspec mocks:
53
+ my_object.should_receive(:hello) # should_receive sets the hello method expectation
54
+
55
+ === with method call is not necessary
56
+ Since RR uses method_missing, it also make using the with method unnecessary
57
+ to set the argument expectations.
58
+
59
+ mock(my_object).hello('bob', 'jane')
60
+
61
+ Mocha:
62
+ my_object.expects(:hello).with('bob', 'jane')
63
+ Rspec mocks:
64
+ my_object.should_receive(:hello).with('bob', 'jane')
65
+
66
+ === using a block to set the return value
67
+ RR supports using a block to set the return value. RR also has the #returns method.
68
+ Both of the examples are equivalent.
69
+
70
+ mock(my_object).hello('bob', 'jane') {'Hello Bob and Jane'}
71
+ mock(my_object).hello('bob', 'jane').returns('Hello Bob and Jane')
9
72
 
10
- == Mocks
11
- http://xunitpatterns.com/Mock%20Object.html
73
+ Mocha:
74
+ my_object.expects(:hello).with('bob', 'jane').returns('Hello Bob and Jane')
75
+ Rspec mocks:
76
+ my_object.should_receive(:hello).with('bob', 'jane').and_return('Hello Bob and Jane')
77
+ my_object.should_receive(:hello).with('bob', 'jane') {'Hello Bob and Jane'} #rspec also supports blocks for the return value
78
+
79
+ == Using RR
80
+ To create a double on an object, you can use the following methods:
81
+ * mock
82
+ * stub
83
+ * proxy
84
+ * instance_of
85
+
86
+ These methods are composable. mock and stub can be used by themselves and
87
+ are mutually exclusive.
88
+ proxy and instance_of must be chained with mock or stub. You can chain
89
+ proxy and instance_of together.
90
+
91
+ === mock
92
+ mock replaces the method on the object with an expectation and implementation.
93
+ The expectations are a mock will be called with certain arguments a certain
94
+ number of times (the default is once). You can also set the return value
95
+ of the method invocation.
96
+
97
+ See http://xunitpatterns.com/Mock%20Object.html
98
+
99
+ The following example sets an expectation that the view will receive a method
100
+ call to #render with the arguments {:partial => "user_info"} once.
101
+ When the method is called "Information" is returned.
12
102
  view = controller.template
13
103
  mock(view).render(:partial => "user_info") {"Information"}
14
104
 
15
- # or
16
- mock(view) do
17
- render(:partial => "user_info") {"Information"}
18
- end
105
+ === stub
106
+ stub replaces the method on the object with only an implementation. You
107
+ can still use arguments to differentiate which stub gets invoked.
19
108
 
20
- == Stubs
21
- http://xunitpatterns.com/Test%20Stub.html
109
+ See http://xunitpatterns.com/Test%20Stub.html
110
+
111
+ The following example makes the User.find method return jane when passed
112
+ '42' and returns bob when passed '99'. If another id is passed to User.find,
113
+ an exception is raised.
22
114
  jane = User.new
115
+ bob = User.new
23
116
  stub(User).find('42') {jane}
117
+ stub(User).find('99') {bob}
118
+ stub(User).find do |id|
119
+ raise "Unexpected id #{id.inspect} passed to me"
120
+ end
24
121
 
25
- == Mock Proxies/Probes
26
- Add verifications that a method was called while actually calling it.
27
- The following example verifies render partial will be called and
28
- renders the partial.
122
+ === mock.proxy
123
+ mock.proxy replaces the method on the object with an expectation, implementation, and
124
+ also invokes the actual method. mock.proxy also intercepts the return value and
125
+ passes it into the return value block.
29
126
 
127
+ The following example makes sets an expectation that view.render({:partial => "right_navigation"})
128
+ gets called once and return the actual content of the rendered partial template.
129
+ A call to view.render({:partial => "user_info"}) will render the user_info
130
+ partial template and send the content into the block and is represented by the html variable.
131
+ An assertion is done on the html and "Different html" is returned.
30
132
  view = controller.template
31
133
  mock.proxy(view).render(:partial => "right_navigation")
32
134
  mock.proxy(view).render(:partial => "user_info") do |html|
@@ -34,21 +136,20 @@ renders the partial.
34
136
  "Different html"
35
137
  end
36
138
 
37
- Probes support after_call callbacks. This is useful for Stubbing out
38
- a class method and getting its return value. You can also change the return value.
39
- This technique is also useful for verifying that you are mocking exists and
40
- functions proberly, thereby testing you interface.
41
- For example, using ActiveRecord:
42
-
43
- mock.proxy(User).find('5') do |user|
44
- mock.proxy(user).projects do |projects|
139
+ You can also use mock.proxy to set expectations on the returned value. In
140
+ the following example, a call to User.find('5') does the normal ActiveRecord
141
+ implementation and passes the actual value, represented by the variable bob,
142
+ into the block. bob is then set with a mock.proxy for projects to return
143
+ only the first 3 projects. bob is also mocked with valid? to return false.
144
+ mock.proxy(User).find('5') do |bob|
145
+ mock.proxy(bob).projects do |projects|
45
146
  projects[0..3]
46
147
  end
47
- mock(user).valid? {false}
48
- user
148
+ mock(bob).valid? {false}
149
+ bob
49
150
  end
50
151
 
51
- == Stub Proxy/Probes
152
+ === stub.proxy
52
153
  Intercept the return value of a method call.
53
154
  The following example verifies render partial will be called and
54
155
  renders the partial.
@@ -59,12 +160,12 @@ renders the partial.
59
160
  html
60
161
  end
61
162
 
62
- == Instance of Doubles
163
+ === instance_of
63
164
  Put double scenarios on instances of a Class.
64
165
 
65
166
  mock.instance_of(User).valid? {false}
66
167
 
67
- == Block Syntax
168
+ === Block Syntax
68
169
  script = MyScript.new
69
170
  mock(script) do |m|
70
171
  m.system("cd #{RAILS_ENV}") {true}
@@ -72,23 +173,13 @@ Put double scenarios on instances of a Class.
72
173
  m.system("rake baz") {true}
73
174
  end
74
175
 
75
- == Terse Syntax
76
- One of the goals of RR is to make doubles more scannable.
77
- This is accomplished by removing words from a double declaration.
78
- Here is RR compared to other mock frameworks:
79
-
80
- flexmock(User).should_receive(:find).with('42').and_return(jane) # Flexmock
81
- User.should_receive(:find).with('42').and_return(jane) # Rspec
82
- User.expects(:find).with('42').returns {jane} # Mocha
83
- User.should_receive(:find).with('42') {jane} # Rspec using return value blocks
84
- mock(User).find('42') {jane} # RR
85
-
86
176
  == Special Thanks To
87
177
  With any development effort, there are countless people who have contributed
88
178
  to making it possible. We all are standing on the shoulders of giants.
89
179
  * Pivotal Labs for sponsoring RR development
90
180
  * Parker Thompson for pairing with me
91
181
  * Felix Morio for pairing with me
182
+ * Jeff Whitmire for documentation suggestions
92
183
  * David Chelimsky for encouragement to make the RR framework, for developing
93
184
  the Rspec mock framework, and syntax ideas
94
185
  * Gerald Meszaros for his excellent book "xUnit Test Patterns"
data/Rakefile CHANGED
@@ -22,16 +22,16 @@ end
22
22
 
23
23
  def run_suite
24
24
  dir = File.dirname(__FILE__)
25
- system("ruby #{dir}/examples/example_suite.rb") || raise("Example Suite failed")
25
+ system("ruby #{dir}/spec/spec_suite.rb") || raise("Spec Suite failed")
26
26
  end
27
27
 
28
28
  PKG_NAME = "rr"
29
- PKG_VERSION = "0.3.11"
29
+ PKG_VERSION = "0.4.0"
30
30
  PKG_FILES = FileList[
31
31
  '[A-Z]*',
32
32
  '*.rb',
33
33
  'lib/**/*.rb',
34
- 'examples/**/*.rb'
34
+ 'spec/**/*.rb'
35
35
  ]
36
36
 
37
37
  spec = Gem::Specification.new do |s|
@@ -40,7 +40,7 @@ spec = Gem::Specification.new do |s|
40
40
  s.summary = "RR (Double Ruby) is a double framework that features a rich " <<
41
41
  "selection of double techniques and a terse syntax. " <<
42
42
  "http://xunitpatterns.com/Test%20Double.html"
43
- s.test_files = "examples/example_suite.rb"
43
+ s.test_files = "spec/spec_suite.rb"
44
44
  s.description = s.summary
45
45
 
46
46
  s.files = PKG_FILES.to_a
@@ -66,5 +66,6 @@ end
66
66
 
67
67
  def tag_release
68
68
  dashed_version = PKG_VERSION.gsub('.', '-')
69
- `svn cp svn+ssh://rubyforge.org/var/svn/pivotalrb/rr/trunk svn+ssh://rubyforge.org/var/svn/pivotalrb/rr/tags/REL-#{dashed_version} -m 'Version #{PKG_VERSION}'`
69
+ svn_user = "#{ENV["SVN_USER"]}@" || ""
70
+ `svn cp svn+ssh://#{svn_user}rubyforge.org/var/svn/pivotalrb/rr/trunk svn+ssh://#{svn_user}rubyforge.org/var/svn/pivotalrb/rr/tags/REL-#{dashed_version} -m 'Version #{PKG_VERSION}'`
70
71
  end
data/lib/rr.rb CHANGED
@@ -7,17 +7,17 @@ require "#{dir}/rr/errors/argument_equality_error"
7
7
  require "#{dir}/rr/errors/times_called_error"
8
8
 
9
9
  require "#{dir}/rr/space"
10
- require "#{dir}/rr/double"
10
+ require "#{dir}/rr/double_insertion"
11
11
  require "#{dir}/rr/hash_with_object_id_key"
12
12
 
13
- require "#{dir}/rr/scenario_method_proxy"
13
+ require "#{dir}/rr/double_method_proxy"
14
14
 
15
- require "#{dir}/rr/scenario_creator"
15
+ require "#{dir}/rr/double_creator"
16
16
 
17
- require "#{dir}/rr/scenario"
18
- require "#{dir}/rr/scenario_definition"
19
- require "#{dir}/rr/scenario_definition_builder"
20
- require "#{dir}/rr/scenario_matches"
17
+ require "#{dir}/rr/double"
18
+ require "#{dir}/rr/double_definition"
19
+ require "#{dir}/rr/double_definition_builder"
20
+ require "#{dir}/rr/double_matches"
21
21
 
22
22
  require "#{dir}/rr/expectations/argument_equality_expectation"
23
23
  require "#{dir}/rr/expectations/any_argument_expectation"
@@ -41,7 +41,7 @@ require "#{dir}/rr/times_called_matchers/proc_matcher"
41
41
  require "#{dir}/rr/times_called_matchers/at_least_matcher"
42
42
  require "#{dir}/rr/times_called_matchers/at_most_matcher"
43
43
 
44
- require "#{dir}/rr/extensions/instance_methods"
44
+ require "#{dir}/rr/adapters/rr_methods"
45
45
 
46
46
  require "#{dir}/rr/adapters/rspec"
47
47
  require "#{dir}/rr/adapters/test_unit"
@@ -0,0 +1,228 @@
1
+ module RR
2
+ module Adapters
3
+ module RRMethods
4
+ # Verifies all the DoubleInsertion objects have met their
5
+ # TimesCalledExpectations.
6
+ def verify
7
+ RR::Space.instance.verify_double_insertions
8
+ end
9
+
10
+ # Resets the registered Doubles and ordered Doubles
11
+ def reset
12
+ RR::Space.instance.reset
13
+ end
14
+
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 DoubleMethodProxy 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=DoubleCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
44
+ creator = RR::Space.scenario_creator
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 DoubleMethodProxy 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=DoubleCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
78
+ creator = RR::Space.scenario_creator
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=DoubleCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
128
+ creator = RR::Space.scenario_creator
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=DoubleCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
149
+ creator = RR::Space.scenario_creator
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=DoubleCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
168
+ creator = RR::Space.scenario_creator
169
+ creator.instance_of(subject, method_name, &definition)
170
+ end
171
+
172
+ # Returns a AnyTimesMatcher. This is meant to be passed in as an argument
173
+ # to Double#times.
174
+ #
175
+ # mock(object).method_name(anything).times(any_times) {return_value}
176
+ def any_times
177
+ TimesCalledMatchers::AnyTimesMatcher.new
178
+ end
179
+
180
+ # Sets up an Anything wildcard ArgumentEqualityExpectation
181
+ # that succeeds when passed any argument.
182
+ # mock(object).method_name(anything) {return_value}
183
+ # object.method_name("an arbitrary value") # passes
184
+ def anything
185
+ RR::WildcardMatchers::Anything.new
186
+ end
187
+
188
+ # Sets up an IsA wildcard ArgumentEqualityExpectation
189
+ # that succeeds when passed an argument of a certain type.
190
+ # mock(object).method_name(is_a(String)) {return_value}
191
+ # object.method_name("A String") # passes
192
+ def is_a(klass)
193
+ RR::WildcardMatchers::IsA.new(klass)
194
+ end
195
+
196
+ # Sets up an Numeric wildcard ArgumentEqualityExpectation
197
+ # that succeeds when passed an argument that is ::Numeric.
198
+ # mock(object).method_name(numeric) {return_value}
199
+ # object.method_name(99) # passes
200
+ def numeric
201
+ RR::WildcardMatchers::Numeric.new
202
+ end
203
+
204
+ # Sets up an Boolean wildcard ArgumentEqualityExpectation
205
+ # that succeeds when passed an argument that is a ::Boolean.
206
+ # mock(object).method_name(boolean) {return_value}
207
+ # object.method_name(false) # passes
208
+ def boolean
209
+ RR::WildcardMatchers::Boolean.new
210
+ end
211
+
212
+ # Sets up a DuckType wildcard ArgumentEqualityExpectation
213
+ # that succeeds when passed the argument implements the methods.
214
+ # arg = Object.new
215
+ # def arg.foo; end
216
+ # def arg.bar; end
217
+ # mock(object).method_name(duck_type(:foo, :bar)) {return_value}
218
+ # object.method_name(arg) # passes
219
+ def duck_type(*args)
220
+ RR::WildcardMatchers::DuckType.new(*args)
221
+ end
222
+
223
+ instance_methods.each do |name|
224
+ alias_method "rr_#{name}", name
225
+ end
226
+ end
227
+ end
228
+ end