rr 1.1.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +5 -5
  2. data/Appraisals +6 -0
  3. data/CHANGES.md +102 -1
  4. data/CREDITS.md +5 -0
  5. data/Gemfile +3 -0
  6. data/README.md +91 -110
  7. data/Rakefile +43 -0
  8. data/doc/02_syntax_comparison.md +1 -0
  9. data/gemfiles/ruby_19_rspec_2.gemfile +14 -0
  10. data/gemfiles/ruby_19_rspec_2.gemfile.lock +49 -0
  11. data/gemfiles/ruby_19_rspec_2_rails_4.gemfile +15 -0
  12. data/gemfiles/ruby_19_rspec_2_rails_4.gemfile.lock +119 -0
  13. data/lib/rr/class_instance_method_defined.rb +1 -1
  14. data/lib/rr/core_ext/array.rb +2 -0
  15. data/lib/rr/core_ext/hash.rb +2 -0
  16. data/lib/rr/deprecations.rb +97 -0
  17. data/lib/rr/double.rb +28 -10
  18. data/lib/rr/double_definitions/double_definition.rb +39 -16
  19. data/lib/rr/double_definitions/double_definition_create.rb +5 -5
  20. data/lib/rr/double_definitions/double_definition_create_blank_slate.rb +10 -4
  21. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +1 -1
  22. data/lib/rr/double_definitions/double_injections/instance.rb +2 -2
  23. data/lib/rr/double_definitions/strategies/strategy.rb +27 -8
  24. data/lib/rr/double_definitions/strategies/verification/mock.rb +8 -2
  25. data/lib/rr/double_matches.rb +4 -3
  26. data/lib/rr/dsl.rb +152 -0
  27. data/lib/rr/expectations/any_argument_expectation.rb +4 -4
  28. data/lib/rr/expectations/argument_equality_expectation.rb +43 -5
  29. data/lib/rr/injections/double_injection.rb +67 -19
  30. data/lib/rr/injections/method_missing_injection.rb +37 -6
  31. data/lib/rr/integrations.rb +13 -12
  32. data/lib/rr/integrations/decorator.rb +4 -1
  33. data/lib/rr/integrations/minitest_4.rb +1 -1
  34. data/lib/rr/integrations/minitest_4_active_support.rb +1 -1
  35. data/lib/rr/integrations/rspec/invocation_matcher.rb +0 -8
  36. data/lib/rr/integrations/rspec_2.rb +28 -3
  37. data/lib/rr/keyword_arguments.rb +15 -0
  38. data/lib/rr/method_dispatches/base_method_dispatch.rb +22 -5
  39. data/lib/rr/method_dispatches/method_dispatch.rb +21 -10
  40. data/lib/rr/method_dispatches/method_missing_dispatch.rb +14 -5
  41. data/lib/rr/recorded_call.rb +35 -0
  42. data/lib/rr/recorded_calls.rb +23 -9
  43. data/lib/rr/space.rb +15 -5
  44. data/lib/rr/spy_verification.rb +13 -5
  45. data/lib/rr/version.rb +1 -2
  46. data/lib/rr/wildcard_matchers.rb +10 -10
  47. data/lib/rr/without_autohook.rb +7 -14
  48. data/rr.gemspec +14 -5
  49. data/spec/custom_formatter_for_rspec.rb +18 -0
  50. data/spec/custom_formatter_for_rspec_2.rb +40 -0
  51. data/spec/defines_spec_suite_tasks.rb +57 -0
  52. data/spec/fixtures/rubygems_patch_for_187.rb +598 -0
  53. data/spec/global_helper.rb +38 -0
  54. data/spec/spec.opts +3 -0
  55. data/spec/spec_suite_configuration.rb +126 -0
  56. data/spec/spec_suite_runner.rb +47 -0
  57. data/spec/suites.yml +10 -0
  58. data/spec/suites/rspec_2/functional/any_instance_of_spec.rb +147 -0
  59. data/spec/suites/rspec_2/functional/dont_allow_spec.rb +17 -0
  60. data/spec/suites/rspec_2/functional/mock_bang_spec.rb +20 -0
  61. data/spec/suites/rspec_2/functional/mock_instance_of_spec.rb +14 -0
  62. data/spec/suites/rspec_2/functional/mock_instance_of_strong_spec.rb +15 -0
  63. data/spec/suites/rspec_2/functional/mock_proxy_instance_of_spec.rb +15 -0
  64. data/spec/suites/rspec_2/functional/mock_proxy_spec.rb +14 -0
  65. data/spec/suites/rspec_2/functional/mock_spec.rb +17 -0
  66. data/spec/suites/rspec_2/functional/mock_strong_spec.rb +14 -0
  67. data/spec/suites/rspec_2/functional/received_spec.rb +16 -0
  68. data/spec/suites/rspec_2/functional/spy_spec.rb +102 -0
  69. data/spec/suites/rspec_2/functional/stub_bang_spec.rb +20 -0
  70. data/spec/suites/rspec_2/functional/stub_instance_of_spec.rb +15 -0
  71. data/spec/suites/rspec_2/functional/stub_instance_of_strong_spec.rb +15 -0
  72. data/spec/suites/rspec_2/functional/stub_proxy_instance_of_spec.rb +16 -0
  73. data/spec/suites/rspec_2/functional/stub_proxy_spec.rb +45 -0
  74. data/spec/suites/rspec_2/functional/stub_spec.rb +71 -0
  75. data/spec/suites/rspec_2/functional/stub_strong_spec.rb +15 -0
  76. data/spec/suites/rspec_2/functional/wildcard_matchers_spec.rb +128 -0
  77. data/spec/suites/rspec_2/helper.rb +28 -0
  78. data/spec/suites/rspec_2/integration/minitest_4_spec.rb +109 -0
  79. data/spec/suites/rspec_2/integration/minitest_spec.rb +109 -0
  80. data/spec/suites/rspec_2/spec_helper.rb +3 -0
  81. data/spec/suites/rspec_2/support/matchers/wildcard_matcher_matchers.rb +32 -0
  82. data/spec/suites/rspec_2/support/mixins/double_definition_creator_helpers.rb +173 -0
  83. data/spec/suites/rspec_2/support/mixins/mock_definition_creator_helpers.rb +45 -0
  84. data/spec/suites/rspec_2/support/mixins/proxy_definition_creator_helpers.rb +33 -0
  85. data/spec/suites/rspec_2/support/mixins/stub_creator_helpers.rb +43 -0
  86. data/spec/suites/rspec_2/support/mixins/stub_definition_creator_helpers.rb +45 -0
  87. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_never_called_qualifier.rb +39 -0
  88. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_times_called_qualifier.rb +50 -0
  89. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_without_qualifiers.rb +131 -0
  90. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/dont_allow.rb +148 -0
  91. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of.rb +26 -0
  92. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of_strong.rb +28 -0
  93. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_proxy.rb +11 -0
  94. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_strong.rb +37 -0
  95. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mocking.rb +107 -0
  96. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of.rb +32 -0
  97. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of_strong.rb +39 -0
  98. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_proxy.rb +11 -0
  99. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_strong.rb +37 -0
  100. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stubbing.rb +57 -0
  101. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/array_flatten_bug.rb +35 -0
  102. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/block_form.rb +31 -0
  103. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/comparing_arity.rb +63 -0
  104. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/object_is_proxy.rb +43 -0
  105. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/sequential_invocations.rb +26 -0
  106. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/setting_implementation.rb +51 -0
  107. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/yields.rb +81 -0
  108. data/spec/suites/rspec_2/support/shared_examples/space.rb +13 -0
  109. data/spec/suites/rspec_2/support/shared_examples/times_called_expectation.rb +9 -0
  110. data/spec/suites/rspec_2/unit/core_ext/array_spec.rb +39 -0
  111. data/spec/suites/rspec_2/unit/core_ext/enumerable_spec.rb +53 -0
  112. data/spec/suites/rspec_2/unit/core_ext/hash_spec.rb +55 -0
  113. data/spec/suites/rspec_2/unit/core_ext/range_spec.rb +41 -0
  114. data/spec/suites/rspec_2/unit/core_ext/regexp_spec.rb +41 -0
  115. data/spec/suites/rspec_2/unit/deprecations_spec.rb +27 -0
  116. data/spec/suites/rspec_2/unit/double_definitions/child_double_definition_create_spec.rb +114 -0
  117. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_blank_slate_spec.rb +93 -0
  118. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_spec.rb +446 -0
  119. data/spec/suites/rspec_2/unit/dsl/double_creators_spec.rb +133 -0
  120. data/spec/suites/rspec_2/unit/dsl/space_spec.rb +99 -0
  121. data/spec/suites/rspec_2/unit/dsl/wildcard_matchers_spec.rb +67 -0
  122. data/spec/suites/rspec_2/unit/errors/rr_error_spec.rb +67 -0
  123. data/spec/suites/rspec_2/unit/expectations/any_argument_expectation_spec.rb +48 -0
  124. data/spec/suites/rspec_2/unit/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  125. data/spec/suites/rspec_2/unit/expectations/argument_equality_expectation_spec.rb +135 -0
  126. data/spec/suites/rspec_2/unit/expectations/boolean_argument_equality_expectation_spec.rb +30 -0
  127. data/spec/suites/rspec_2/unit/expectations/hash_including_argument_equality_expectation_spec.rb +92 -0
  128. data/spec/suites/rspec_2/unit/expectations/satisfy_argument_equality_expectation_spec.rb +61 -0
  129. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/any_times_matcher_spec.rb +22 -0
  130. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/at_least_matcher_spec.rb +37 -0
  131. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/at_most_matcher_spec.rb +43 -0
  132. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/integer_matcher_spec.rb +58 -0
  133. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/proc_matcher_spec.rb +35 -0
  134. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/range_matcher_spec.rb +39 -0
  135. data/spec/suites/rspec_2/unit/hash_with_object_id_key_spec.rb +88 -0
  136. data/spec/suites/rspec_2/unit/injections/double_injection/double_injection_spec.rb +533 -0
  137. data/spec/suites/rspec_2/unit/injections/double_injection/double_injection_verify_spec.rb +32 -0
  138. data/spec/suites/rspec_2/unit/integrations/rspec/invocation_matcher_spec.rb +297 -0
  139. data/spec/suites/rspec_2/unit/integrations/rspec_spec.rb +70 -0
  140. data/spec/suites/rspec_2/unit/rr_spec.rb +28 -0
  141. data/spec/suites/rspec_2/unit/space_spec.rb +598 -0
  142. data/spec/suites/rspec_2/unit/spy_verification_spec.rb +133 -0
  143. data/spec/suites/rspec_2/unit/times_called_matchers/any_times_matcher_spec.rb +46 -0
  144. data/spec/suites/rspec_2/unit/times_called_matchers/at_least_matcher_spec.rb +54 -0
  145. data/spec/suites/rspec_2/unit/times_called_matchers/at_most_matcher_spec.rb +69 -0
  146. data/spec/suites/rspec_2/unit/times_called_matchers/integer_matcher_spec.rb +69 -0
  147. data/spec/suites/rspec_2/unit/times_called_matchers/proc_matcher_spec.rb +54 -0
  148. data/spec/suites/rspec_2/unit/times_called_matchers/range_matcher_spec.rb +75 -0
  149. data/spec/suites/rspec_2/unit/times_called_matchers/times_called_matcher_spec.rb +117 -0
  150. data/spec/suites/rspec_2/unit/wildcard_matchers/anything_spec.rb +33 -0
  151. data/spec/suites/rspec_2/unit/wildcard_matchers/boolean_spec.rb +45 -0
  152. data/spec/suites/rspec_2/unit/wildcard_matchers/duck_type_spec.rb +64 -0
  153. data/spec/suites/rspec_2/unit/wildcard_matchers/hash_including_spec.rb +64 -0
  154. data/spec/suites/rspec_2/unit/wildcard_matchers/is_a_spec.rb +55 -0
  155. data/spec/suites/rspec_2/unit/wildcard_matchers/numeric_spec.rb +46 -0
  156. data/spec/suites/rspec_2/unit/wildcard_matchers/satisfy_spec.rb +57 -0
  157. data/spec/support/adapter.rb +22 -0
  158. data/spec/support/adapter_tests/base.rb +45 -0
  159. data/spec/support/adapter_tests/minitest.rb +7 -0
  160. data/spec/support/adapter_tests/rspec.rb +70 -0
  161. data/spec/support/adapter_tests/test_unit.rb +47 -0
  162. data/spec/support/command_runner.rb +105 -0
  163. data/spec/support/generator.rb +56 -0
  164. data/spec/support/integration_tests/base.rb +64 -0
  165. data/spec/support/integration_tests/rails.rb +60 -0
  166. data/spec/support/integration_tests/rails_minitest.rb +13 -0
  167. data/spec/support/integration_tests/rails_rspec.rb +13 -0
  168. data/spec/support/integration_tests/rails_test_unit.rb +13 -0
  169. data/spec/support/integration_tests/rails_test_unit_like.rb +13 -0
  170. data/spec/support/integration_tests/ruby.rb +7 -0
  171. data/spec/support/integration_tests/ruby_minitest.rb +13 -0
  172. data/spec/support/integration_tests/ruby_rspec.rb +13 -0
  173. data/spec/support/integration_tests/ruby_test_unit.rb +13 -0
  174. data/spec/support/matchers/be_a_subset_of_matcher.rb +24 -0
  175. data/spec/support/project/cucumber.rb +50 -0
  176. data/spec/support/project/generator.rb +348 -0
  177. data/spec/support/project/minitest.rb +39 -0
  178. data/spec/support/project/rails.rb +199 -0
  179. data/spec/support/project/rails_minitest.rb +17 -0
  180. data/spec/support/project/rails_rspec.rb +50 -0
  181. data/spec/support/project/rails_test_unit.rb +17 -0
  182. data/spec/support/project/rails_test_unit_like.rb +17 -0
  183. data/spec/support/project/rspec.rb +69 -0
  184. data/spec/support/project/ruby.rb +34 -0
  185. data/spec/support/project/ruby_minitest.rb +11 -0
  186. data/spec/support/project/ruby_rspec.rb +29 -0
  187. data/spec/support/project/ruby_test_unit.rb +11 -0
  188. data/spec/support/project/ruby_test_unit_like.rb +21 -0
  189. data/spec/support/project/test_unit.rb +29 -0
  190. data/spec/support/project/test_unit_like.rb +7 -0
  191. data/spec/support/project/tests_runner.rb +22 -0
  192. data/spec/support/test.sqlite3 +0 -0
  193. data/spec/support/test_case/generator.rb +53 -0
  194. data/spec/support/test_case/minitest.rb +13 -0
  195. data/spec/support/test_case/rspec.rb +19 -0
  196. data/spec/support/test_case/test_unit.rb +21 -0
  197. data/spec/support/test_file/generator.rb +120 -0
  198. data/spec/support/test_file/minitest.rb +19 -0
  199. data/spec/support/test_file/rails_minitest.rb +7 -0
  200. data/spec/support/test_file/rails_rspec.rb +12 -0
  201. data/spec/support/test_file/rails_test_unit.rb +25 -0
  202. data/spec/support/test_file/rspec.rb +33 -0
  203. data/spec/support/test_file/test_unit.rb +36 -0
  204. data/spec/support/test_helper/generator.rb +27 -0
  205. data/spec/support/test_helper/minitest.rb +7 -0
  206. data/spec/support/test_helper/rails.rb +31 -0
  207. data/spec/support/test_helper/rails_minitest.rb +7 -0
  208. data/spec/support/test_helper/rails_rspec.rb +25 -0
  209. data/spec/support/test_helper/rails_test_unit.rb +23 -0
  210. data/spec/support/test_helper/rspec.rb +7 -0
  211. data/spec/support/test_helper/ruby.rb +31 -0
  212. data/spec/support/test_helper/test_unit.rb +7 -0
  213. metadata +240 -19
  214. data/VERSION +0 -1
  215. data/lib/rr/adapters.rb +0 -44
  216. data/lib/rr/adapters/rr_methods.rb +0 -142
  217. data/lib/rr/integrations/rspec_1.rb +0 -46
  218. data/lib/rr/integrations/test_unit_1.rb +0 -63
  219. data/lib/rr/integrations/test_unit_2.rb +0 -15
  220. data/lib/rr/integrations/test_unit_200.rb +0 -27
  221. data/lib/rr/integrations/test_unit_200_active_support.rb +0 -25
  222. data/lib/rr/integrations/test_unit_2_active_support.rb +0 -38
  223. data/lib/rr/proc_from_block.rb +0 -11
@@ -0,0 +1,32 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../spec_helper")
2
+
3
+ module RR
4
+ module Injections
5
+ describe DoubleInjection, "#verify" do
6
+ subject { Object.new }
7
+
8
+ include_examples "Swapped Space"
9
+
10
+ attr_reader :method_name, :double_injection
11
+
12
+ before do
13
+ @method_name = :foobar
14
+ subject.methods.should_not include(method_name.to_s)
15
+ @double_injection = ::RR::Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
16
+ end
17
+
18
+ it "verifies each double was met" do
19
+ double = RR::Double.new(
20
+ double_injection,
21
+ RR::DoubleDefinitions::DoubleDefinition.new(RR::DoubleDefinitions::DoubleDefinitionCreate.new)
22
+ )
23
+ double_injection.register_double double
24
+
25
+ double.definition.with(1).once.returns {nil}
26
+ expect { double_injection.verify }.to raise_error(RR::Errors::TimesCalledError)
27
+ subject.foobar(1)
28
+ expect { double_injection.verify }.to_not raise_error
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,297 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../spec_helper")
2
+
3
+ module RR
4
+ module Integrations
5
+ module RSpec
6
+ describe InvocationMatcher do
7
+ describe "matching against a method with no doubles" do
8
+ before do
9
+ @matcher = InvocationMatcher.new(:foobar)
10
+ @result = @matcher.matches?(Object.new)
11
+ end
12
+
13
+ it "does not match" do
14
+ @result.should_not be
15
+ end
16
+ end
17
+
18
+ describe "defining an expectation using a method invocation" do
19
+ subject { Object.new }
20
+
21
+ before do
22
+ stub(subject).foobar
23
+ subject.foobar(:args)
24
+ @result = InvocationMatcher.new.foobar(:args).matches?(subject)
25
+ end
26
+
27
+ it "uses the invoked method as the expected method" do
28
+ expect(@result).to be
29
+ end
30
+ end
31
+
32
+ describe "matching against a stubbed method that was never called" do
33
+ subject { Object.new }
34
+
35
+ before do
36
+ stub(subject).foobar
37
+ @matcher = InvocationMatcher.new(:foobar)
38
+ @result = @matcher.matches?(subject)
39
+ end
40
+
41
+ it "does not match" do
42
+ @result.should_not be
43
+ end
44
+ end
45
+
46
+ describe "matching against a stubbed method that was called once" do
47
+ subject { Object.new }
48
+
49
+ before do
50
+ stub(subject).foobar
51
+ subject.foobar
52
+ @result = InvocationMatcher.new(:foobar).matches?(subject)
53
+ end
54
+
55
+ it "does match" do
56
+ expect(@result).to be
57
+ end
58
+ end
59
+
60
+ describe "matching against a stubbed method that was called with unexpected arguments" do
61
+ subject { Object.new }
62
+
63
+ before do
64
+ @args = %w(one two)
65
+ stub(subject).foobar
66
+ subject.foobar(:other)
67
+ @result = InvocationMatcher.new(:foobar).with(*@args).matches?(subject)
68
+ end
69
+
70
+ it "does not match" do
71
+ @result.should_not be
72
+ end
73
+ end
74
+
75
+ describe "matching against a stubbed method that was called with expected arguments" do
76
+ subject { Object.new }
77
+
78
+ before do
79
+ @args = %w(one two)
80
+ stub(subject).foobar
81
+ subject.foobar(*@args)
82
+ @result = InvocationMatcher.new(:foobar).with(*@args).matches?(subject)
83
+ end
84
+
85
+ it "does match" do
86
+ expect(@result).to be
87
+ end
88
+ end
89
+
90
+ describe "defining a fulfilled argument expectation using a method invocation" do
91
+ subject { Object.new }
92
+
93
+ before do
94
+ @args = %w(one two)
95
+ stub(subject).foobar
96
+ subject.foobar(*@args)
97
+ @result = InvocationMatcher.new.foobar(*@args).matches?(subject)
98
+ end
99
+
100
+ it "does match" do
101
+ expect(@result).to be
102
+ end
103
+ end
104
+
105
+ describe "defining an unfulfilled argument expectation using a method invocation" do
106
+ subject { Object.new }
107
+
108
+ before do
109
+ @args = %w(one two)
110
+ stub(subject).foobar
111
+ subject.foobar(:other)
112
+ @result = InvocationMatcher.new.foobar(*@args).matches?(subject)
113
+ end
114
+
115
+ it "does not match" do
116
+ @result.should_not be
117
+ end
118
+ end
119
+
120
+ describe "matching against a stubbed method that was called more than once" do
121
+ subject { Object.new }
122
+
123
+ before do
124
+ stub(subject).foobar
125
+ 2.times { subject.foobar }
126
+ @result = InvocationMatcher.new(:foobar).twice.matches?(subject)
127
+ end
128
+
129
+ it "does match" do
130
+ expect(@result).to be
131
+ end
132
+ end
133
+
134
+ describe "matching a stubbed method with any arguments" do
135
+ subject { Object.new }
136
+
137
+ before do
138
+ stub(subject).foobar
139
+ subject.foobar(:args)
140
+ @result = InvocationMatcher.new(:foobar).with_any_args.matches?(subject)
141
+ end
142
+
143
+ it "does match" do
144
+ expect(@result).to be
145
+ end
146
+ end
147
+
148
+ describe "matching a stubbed method with no arguments when arguments are not provided" do
149
+ subject { Object.new }
150
+
151
+ before do
152
+ stub(subject).foobar
153
+ subject.foobar
154
+ @result = InvocationMatcher.new(:foobar).with_no_args.matches?(subject)
155
+ end
156
+
157
+ it "does match" do
158
+ expect(@result).to be
159
+ end
160
+ end
161
+
162
+ describe "matching a stubbed method with no arguments when arguments are provided" do
163
+ subject { Object.new }
164
+
165
+ before do
166
+ stub(subject).foobar
167
+ subject.foobar(:args)
168
+ @result = InvocationMatcher.new(:foobar).with_no_args.matches?(subject)
169
+ end
170
+
171
+ it "does not match" do
172
+ @result.should_not be
173
+ end
174
+ end
175
+
176
+ describe "matching a method that was called twice when expected once" do
177
+ subject { Object.new }
178
+
179
+ before do
180
+ stub(subject).foobar
181
+ 2.times { subject.foobar }
182
+ @matcher = InvocationMatcher.new(:foobar).times(1)
183
+ @result = @matcher.matches?(subject)
184
+ end
185
+
186
+ it "does not match" do
187
+ @result.should_not be
188
+ end
189
+ end
190
+
191
+ describe "matching a method that was called twice when expected twice" do
192
+ subject { Object.new }
193
+
194
+ before do
195
+ stub(subject).foobar
196
+ 2.times { subject.foobar }
197
+ @result = InvocationMatcher.new(:foobar).times(2).matches?(subject)
198
+ end
199
+
200
+ it "does match" do
201
+ expect(@result).to be
202
+ end
203
+ end
204
+
205
+ describe "matching a method that was called twice when any number of times" do
206
+ subject { Object.new }
207
+
208
+ before do
209
+ stub(subject).foobar
210
+ 2.times { subject.foobar }
211
+ @result = InvocationMatcher.new(:foobar).any_number_of_times.matches?(subject)
212
+ end
213
+
214
+ it "does match" do
215
+ expect(@result).to be
216
+ end
217
+ end
218
+
219
+ describe "matching a method that was called three times when expected at most twice" do
220
+ subject { Object.new }
221
+
222
+ before do
223
+ stub(subject).foobar
224
+ 3.times { subject.foobar }
225
+ @result = InvocationMatcher.new(:foobar).at_most(2).matches?(subject)
226
+ end
227
+
228
+ it "does not match" do
229
+ @result.should_not be
230
+ end
231
+ end
232
+
233
+ describe "matching a method that was called once when expected at most twice" do
234
+ subject { Object.new }
235
+
236
+ before do
237
+ stub(subject).foobar
238
+ subject.foobar
239
+ @result = InvocationMatcher.new(:foobar).at_most(2).matches?(subject)
240
+ end
241
+
242
+ it "does match" do
243
+ expect(@result).to be
244
+ end
245
+ end
246
+
247
+ describe "matching a method that was called once when expected at least twice" do
248
+ subject { Object.new }
249
+
250
+ before do
251
+ stub(subject).foobar
252
+ subject.foobar
253
+ @result = InvocationMatcher.new(:foobar).at_least(2).matches?(subject)
254
+ end
255
+
256
+ it "does not match" do
257
+ @result.should_not be
258
+ end
259
+ end
260
+
261
+ describe "matching a method that was called three times when expected at least twice" do
262
+ subject { Object.new }
263
+
264
+ before do
265
+ stub(subject).foobar
266
+ 3.times { subject.foobar }
267
+ @result = InvocationMatcher.new(:foobar).at_least(2).matches?(subject)
268
+ end
269
+
270
+ it "does match" do
271
+ expect(@result).to be
272
+ end
273
+ end
274
+
275
+ describe "that does not match" do
276
+ before do
277
+ @error = Object.new
278
+ @message = 'Verification error message'
279
+ stub(RR::Space.instance.recorded_calls).match_error { @error }
280
+ stub(@error).message { @message }
281
+
282
+ @matcher = InvocationMatcher.new(:foobar)
283
+ @result = @matcher.matches?(Object.new)
284
+ end
285
+
286
+ it "returns false when matching" do
287
+ @result.should_not be
288
+ end
289
+
290
+ it "returns a failure messsage" do
291
+ expect(@matcher.failure_message).to eq @message
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module Integrations
5
+ describe RSpec2 do
6
+ attr_reader :fixture, :method_name
7
+
8
+ describe "#setup_mocks_for_rspec" do
9
+ subject { Object.new }
10
+
11
+ before do
12
+ @fixture = Object.new
13
+ fixture.extend RSpec2::Mixin
14
+ @method_name = :foobar
15
+ end
16
+
17
+ it "resets the double_injections" do
18
+ stub(subject).foobar
19
+ ::RR::Injections::DoubleInjection.instances.should_not be_empty
20
+
21
+ fixture.setup_mocks_for_rspec
22
+ expect(::RR::Injections::DoubleInjection.instances).to be_empty
23
+ end
24
+ end
25
+
26
+ describe "#verify_mocks_for_rspec" do
27
+ subject { Object.new }
28
+
29
+ before do
30
+ @fixture = Object.new
31
+ fixture.extend RSpec2::Mixin
32
+ @method_name = :foobar
33
+ end
34
+
35
+ it "verifies the double_injections" do
36
+ mock(subject).foobar
37
+
38
+ expect {
39
+ fixture.verify_mocks_for_rspec
40
+ }.to raise_error(::RR::Errors::TimesCalledError)
41
+ expect(::RR::Injections::DoubleInjection.instances).to be_empty
42
+ end
43
+ end
44
+
45
+ describe "#teardown_mocks_for_rspec" do
46
+ subject { Object.new }
47
+
48
+ before do
49
+ @fixture = Object.new
50
+ fixture.extend RSpec2::Mixin
51
+ @method_name = :foobar
52
+ end
53
+
54
+ it "resets the double_injections" do
55
+ stub(subject).foobar
56
+ ::RR::Injections::DoubleInjection.instances.should_not be_empty
57
+
58
+ fixture.teardown_mocks_for_rspec
59
+ expect(::RR::Injections::DoubleInjection.instances).to be_empty
60
+ end
61
+ end
62
+
63
+ describe "#trim_backtrace" do
64
+ it "does not set trim_backtrace" do
65
+ expect(RR.trim_backtrace).to eq false
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ describe "RR" do
4
+ before do
5
+ Object.class_eval do
6
+ def verify
7
+ raise "Dont call me"
8
+ end
9
+ end
10
+ end
11
+
12
+ after do
13
+ Object.class_eval do
14
+ remove_method :verify
15
+ end
16
+ end
17
+
18
+ it "has proxy methods for each method defined directly on Space" do
19
+ space_instance_methods = RR::Space.instance_methods(false)
20
+ space_instance_methods.should_not be_empty
21
+
22
+ rr_instance_methods = RR.methods(false)
23
+ space_instance_methods.each do |space_instance_method|
24
+ expect(rr_instance_methods).to include(space_instance_method)
25
+ end
26
+ RR.verify
27
+ end
28
+ end
@@ -0,0 +1,598 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ module RR
4
+ describe Space do
5
+ include_examples "Swapped Space"
6
+
7
+ attr_reader :method_name, :double_injection
8
+
9
+ subject { Object.new }
10
+
11
+ describe "#record_call" do
12
+ it "should add a call to the list" do
13
+ object = Object.new
14
+ method_name = :to_s
15
+ arguments = []
16
+ keyword_arguments = {}
17
+ space.record_call(object, method_name, arguments, keyword_arguments, lambda {})
18
+ expect(space.recorded_calls[0]).to eq \
19
+ RR::RecordedCall.new(object, method_name, arguments, keyword_arguments, lambda {})
20
+ end
21
+ end
22
+
23
+ describe "#double_injection" do
24
+ context "when existing subject == but not === with the same method name" do
25
+ it "creates a new DoubleInjection" do
26
+ subject_1 = []
27
+ subject_2 = []
28
+ expect((subject_1 === subject_2)).to be_true
29
+ expect(subject_1.__id__).to_not eq subject_2.__id__
30
+
31
+ injection_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, :foobar)
32
+ injection_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, :foobar)
33
+
34
+ expect(injection_1).to_not eq injection_2
35
+ end
36
+ end
37
+
38
+ context "when a DoubleInjection is not registered for the subject and method_name" do
39
+ before do
40
+ def subject.foobar(*args)
41
+ :original_foobar
42
+ end
43
+
44
+ @method_name = :foobar
45
+ end
46
+
47
+ context "when method_name is a symbol" do
48
+ it "returns double_injection and adds double_injection to double_injection list" do
49
+ double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
50
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)).to equal double_injection
51
+ expect(double_injection.subject_class).to eq(class << subject; self; end)
52
+ expect(double_injection.method_name).to equal method_name
53
+ end
54
+ end
55
+
56
+ context "when method_name is a string" do
57
+ it "returns double_injection and adds double_injection to double_injection list" do
58
+ double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')
59
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)).to equal double_injection
60
+ expect(double_injection.subject_class).to eq(class << subject; self; end)
61
+ expect(double_injection.method_name).to equal method_name
62
+ end
63
+ end
64
+
65
+ it "overrides the method when passing a block" do
66
+ original_method = subject.method(:foobar)
67
+ Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
68
+ expect(subject.method(:foobar)).to_not eq original_method
69
+ end
70
+ end
71
+
72
+ context "when double_injection exists" do
73
+ before do
74
+ def subject.foobar(*args)
75
+ :original_foobar
76
+ end
77
+
78
+ @method_name = :foobar
79
+ end
80
+
81
+ context "when a DoubleInjection is registered for the subject and method_name" do
82
+ it "returns the existing DoubleInjection" do
83
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')
84
+
85
+ expect(double_injection.subject_has_original_method?).to be_true
86
+
87
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')).to equal double_injection
88
+
89
+ double_injection.reset
90
+ expect(subject.foobar).to eq :original_foobar
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "#method_missing_injection" do
97
+ context "when existing subject == but not === with the same method name" do
98
+ it "creates a new DoubleInjection" do
99
+ subject_1 = []
100
+ subject_2 = []
101
+ expect((subject_1 === subject_2)).to be_true
102
+ expect(subject_1.__id__).to_not eq subject_2.__id__
103
+
104
+ injection_1 = Injections::MethodMissingInjection.find_or_create(class << subject_1; self; end)
105
+ injection_2 = Injections::MethodMissingInjection.find_or_create(class << subject_2; self; end)
106
+
107
+ expect(injection_1).to_not eq injection_2
108
+ end
109
+ end
110
+
111
+ context "when a MethodMissingInjection is not registered for the subject and method_name" do
112
+ before do
113
+ def subject.method_missing(method_name, *args, &block)
114
+ :original_method_missing
115
+ end
116
+ end
117
+
118
+ it "overrides the method when passing a block" do
119
+ original_method = subject.method(:method_missing)
120
+ Injections::MethodMissingInjection.find_or_create(class << subject; self; end)
121
+ expect(subject.method(:method_missing)).to_not eq original_method
122
+ end
123
+ end
124
+
125
+ context "when a MethodMissingInjection is registered for the subject and method_name" do
126
+ before do
127
+ def subject.method_missing(method_name, *args, &block)
128
+ :original_method_missing
129
+ end
130
+ end
131
+
132
+ context "when a DoubleInjection is registered for the subject and method_name" do
133
+ it "returns the existing DoubleInjection" do
134
+ injection = Injections::MethodMissingInjection.find_or_create(class << subject; self; end)
135
+ expect(injection.subject_has_original_method?).to be_true
136
+
137
+ expect(Injections::MethodMissingInjection.find_or_create(class << subject; self; end)).to equal injection
138
+
139
+ injection.reset
140
+ expect(subject.method_missing(:foobar)).to eq :original_method_missing
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ describe "#singleton_method_added_injection" do
147
+ context "when existing subject == but not === with the same method name" do
148
+ it "creates a new DoubleInjection" do
149
+ subject_1 = []
150
+ subject_2 = []
151
+ expect((subject_1 === subject_2)).to be_true
152
+ expect(subject_1.__id__).to_not eq subject_2.__id__
153
+
154
+ injection_1 = Injections::SingletonMethodAddedInjection.find_or_create(class << subject_1; self; end)
155
+ injection_2 = Injections::SingletonMethodAddedInjection.find_or_create(class << subject_2; self; end)
156
+
157
+ expect(injection_1).to_not eq injection_2
158
+ end
159
+ end
160
+
161
+ context "when a SingletonMethodAddedInjection is not registered for the subject and method_name" do
162
+ before do
163
+ def subject.singleton_method_added(method_name)
164
+ :original_singleton_method_added
165
+ end
166
+ end
167
+
168
+ it "overrides the method when passing a block" do
169
+ original_method = subject.method(:singleton_method_added)
170
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)
171
+ expect(subject.method(:singleton_method_added)).to_not eq original_method
172
+ end
173
+ end
174
+
175
+ context "when a SingletonMethodAddedInjection is registered for the subject and method_name" do
176
+ before do
177
+ def subject.singleton_method_added(method_name)
178
+ :original_singleton_method_added
179
+ end
180
+ end
181
+
182
+ context "when a DoubleInjection is registered for the subject and method_name" do
183
+ it "returns the existing DoubleInjection" do
184
+ injection = Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)
185
+ expect(injection.subject_has_original_method?).to be_true
186
+
187
+ expect(Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)).to equal injection
188
+
189
+ injection.reset
190
+ expect(subject.singleton_method_added(:foobar)).to eq :original_singleton_method_added
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "#reset" do
197
+ attr_reader :subject_1, :subject_2
198
+ before do
199
+ @subject_1 = Object.new
200
+ @subject_2 = Object.new
201
+ @method_name = :foobar
202
+ end
203
+
204
+ it "should clear the #recorded_calls" do
205
+ object = Object.new
206
+ space.record_call(object, :to_s, [], {}, nil)
207
+
208
+ space.reset
209
+ expect(space.recorded_calls).to eq RR::RecordedCalls.new([])
210
+ end
211
+
212
+ it "removes the ordered doubles" do
213
+ mock(subject_1).foobar1.ordered
214
+ mock(subject_2).foobar2.ordered
215
+
216
+ space.ordered_doubles.should_not be_empty
217
+
218
+ space.reset
219
+ expect(space.ordered_doubles).to be_empty
220
+ end
221
+
222
+ it "resets all double_injections" do
223
+ expect(subject_1.respond_to?(method_name)).to be_false
224
+ expect(subject_2.respond_to?(method_name)).to be_false
225
+
226
+ Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
227
+ expect(Injections::DoubleInjection.exists_by_subject?(subject_1, method_name)).to be_true
228
+ expect(subject_1.respond_to?(method_name)).to be_true
229
+
230
+ Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
231
+ expect(Injections::DoubleInjection.exists_by_subject?(subject_2, method_name)).to be_true
232
+ expect(subject_2.respond_to?(method_name)).to be_true
233
+
234
+ space.reset
235
+
236
+ expect(subject_1.respond_to?(method_name)).to be_false
237
+ expect(Injections::DoubleInjection.exists?(subject_1, method_name)).to be_false
238
+
239
+ expect(subject_2.respond_to?(method_name)).to be_false
240
+ expect(Injections::DoubleInjection.exists?(subject_2, method_name)).to be_false
241
+ end
242
+
243
+ it "resets all method_missing_injections" do
244
+ expect(subject_1.respond_to?(:method_missing)).to be_false
245
+ expect(subject_2.respond_to?(:method_missing)).to be_false
246
+
247
+ Injections::MethodMissingInjection.find_or_create(class << subject_1; self; end)
248
+ expect(Injections::MethodMissingInjection.exists?(class << subject_1; self; end)).to be_true
249
+ expect(subject_1.respond_to?(:method_missing)).to be_true
250
+
251
+ Injections::MethodMissingInjection.find_or_create(class << subject_2; self; end)
252
+ expect(Injections::MethodMissingInjection.exists?(class << subject_2; self; end)).to be_true
253
+ expect(subject_2.respond_to?(:method_missing)).to be_true
254
+
255
+ space.reset
256
+
257
+ expect(subject_1.respond_to?(:method_missing)).to be_false
258
+ expect(Injections::MethodMissingInjection.exists?(subject_1)).to be_false
259
+
260
+ expect(subject_2.respond_to?(:method_missing)).to be_false
261
+ expect(Injections::MethodMissingInjection.exists?(subject_2)).to be_false
262
+ end
263
+
264
+ it "resets all singleton_method_added_injections" do
265
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_false
266
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_false
267
+
268
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject_1; self; end)
269
+ expect(Injections::SingletonMethodAddedInjection.exists?(class << subject_1; self; end)).to be_true
270
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_true
271
+
272
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject_2; self; end)
273
+ expect(Injections::SingletonMethodAddedInjection.exists?(class << subject_2; self; end)).to be_true
274
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_true
275
+
276
+ space.reset
277
+
278
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_false
279
+ expect(Injections::SingletonMethodAddedInjection.exists?(subject_1)).to be_false
280
+
281
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_false
282
+ expect(Injections::SingletonMethodAddedInjection.exists?(subject_2)).to be_false
283
+ end
284
+
285
+ it "clears RR::Injections::DoubleInjection::BoundObjects" do
286
+ stub(subject).foobar
287
+ RR::Injections::DoubleInjection::BoundObjects.should_not be_empty
288
+ space.reset
289
+ pending "Clearing BoundObjects" do
290
+ expect(RR::Injections::DoubleInjection::BoundObjects).to be_empty
291
+ end
292
+ end
293
+ end
294
+
295
+ describe "#reset_double" do
296
+ before do
297
+ @method_name = :foobar
298
+
299
+ def subject.foobar
300
+ end
301
+ end
302
+
303
+ it "resets the double_injections and restores the original method" do
304
+ original_method = subject.method(method_name)
305
+
306
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
307
+ expect(Injections::DoubleInjection.instances.keys).to include(class << subject; self; end)
308
+ Injections::DoubleInjection.find_by_subject(subject, method_name).should_not be_nil
309
+ expect(subject.method(method_name)).to_not eq original_method
310
+
311
+ space.reset_double(subject, method_name)
312
+ Injections::DoubleInjection.instances.keys.should_not include(subject)
313
+ expect(subject.method(method_name)).to eq original_method
314
+ end
315
+
316
+ context "when it has no double_injections" do
317
+ it "removes the subject from the double_injections map" do
318
+ Injections::DoubleInjection.find_or_create_by_subject(subject, :foobar1)
319
+ Injections::DoubleInjection.find_or_create_by_subject(subject, :foobar2)
320
+
321
+ expect(Injections::DoubleInjection.instances.include?(class << subject; self; end)).to eq true
322
+ Injections::DoubleInjection.find_by_subject(subject, :foobar1).should_not be_nil
323
+ Injections::DoubleInjection.find_by_subject(subject, :foobar2).should_not be_nil
324
+
325
+ space.reset_double(subject, :foobar1)
326
+ expect(Injections::DoubleInjection.instances.include?(class << subject; self; end)).to eq true
327
+ expect(Injections::DoubleInjection.find_by_subject(subject, :foobar1)).to be_nil
328
+ Injections::DoubleInjection.find_by_subject(subject, :foobar2).should_not be_nil
329
+
330
+ space.reset_double(subject, :foobar2)
331
+ expect(Injections::DoubleInjection.instances.include?(subject)).to eq false
332
+ end
333
+ end
334
+ end
335
+
336
+ describe "#DoubleInjection.reset" do
337
+ attr_reader :subject_1, :subject_2
338
+ before do
339
+ @subject_1 = Object.new
340
+ @subject_2 = Object.new
341
+ @method_name = :foobar
342
+ end
343
+
344
+ it "resets the double_injection and removes it from the double_injections list" do
345
+ double_injection_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
346
+ double_1_reset_call_count = 0
347
+ ( class << double_injection_1; self; end).class_eval do
348
+ define_method(:reset) do
349
+ double_1_reset_call_count += 1
350
+ end
351
+ end
352
+ double_injection_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
353
+ double_2_reset_call_count = 0
354
+ ( class << double_injection_2; self; end).class_eval do
355
+ define_method(:reset) do
356
+ double_2_reset_call_count += 1
357
+ end
358
+ end
359
+
360
+ Injections::DoubleInjection.reset
361
+ expect(double_1_reset_call_count).to eq 1
362
+ expect(double_2_reset_call_count).to eq 1
363
+ end
364
+ end
365
+
366
+ describe "#verify_doubles" do
367
+ attr_reader :subject_1, :subject_2, :subject3, :double_1, :double_2, :double3
368
+ before do
369
+ @subject_1 = Object.new
370
+ @subject_2 = Object.new
371
+ @subject3 = Object.new
372
+ @method_name = :foobar
373
+ @double_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
374
+ @double_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
375
+ @double3 = Injections::DoubleInjection.find_or_create_by_subject(subject3, method_name)
376
+ end
377
+
378
+ context "when passed no arguments" do
379
+ it "verifies and deletes the double_injections" do
380
+ double_1_verify_call_count = 0
381
+ double_1_reset_call_count = 0
382
+ (
383
+ class << double_1;
384
+ self;
385
+ end).class_eval do
386
+ define_method(:verify) do
387
+ double_1_verify_call_count += 1
388
+ end
389
+ define_method(:reset) do
390
+ double_1_reset_call_count += 1
391
+ end
392
+ end
393
+
394
+ double_2_verify_call_count = 0
395
+ double_2_reset_call_count = 0
396
+ (
397
+ class << double_2;
398
+ self;
399
+ end).class_eval do
400
+ define_method(:verify) do
401
+ double_2_verify_call_count += 1
402
+ end
403
+ define_method(:reset) do
404
+ double_2_reset_call_count += 1
405
+ end
406
+ end
407
+
408
+ space.verify_doubles
409
+ expect(double_1_verify_call_count).to eq 1
410
+ expect(double_2_verify_call_count).to eq 1
411
+ expect(double_1_reset_call_count).to eq 1
412
+ expect(double_1_reset_call_count).to eq 1
413
+ end
414
+ end
415
+
416
+ context "when passed an Object that has at least one DoubleInjection" do
417
+ it "verifies all Doubles injected into the Object" do
418
+ double_1_verify_call_count = 0
419
+ double_1_reset_call_count = 0
420
+ (
421
+ class << double_1;
422
+ self;
423
+ end).class_eval do
424
+ define_method(:verify) do
425
+ double_1_verify_call_count += 1
426
+ end
427
+ define_method(:reset) do
428
+ double_1_reset_call_count += 1
429
+ end
430
+ end
431
+
432
+ double_2_verify_call_count = 0
433
+ double_2_reset_call_count = 0
434
+ (
435
+ class << double_2;
436
+ self;
437
+ end).class_eval do
438
+ define_method(:verify) do
439
+ double_2_verify_call_count += 1
440
+ end
441
+ define_method(:reset) do
442
+ double_2_reset_call_count += 1
443
+ end
444
+ end
445
+
446
+ space.verify_doubles(subject_1)
447
+
448
+ expect(double_1_verify_call_count).to eq 1
449
+ expect(double_1_reset_call_count).to eq 1
450
+ expect(double_2_verify_call_count).to eq 0
451
+ expect(double_2_reset_call_count).to eq 0
452
+ end
453
+ end
454
+
455
+ context "when passed multiple Objects with at least one DoubleInjection" do
456
+ it "verifies the Doubles injected into all of the Objects" do
457
+ double_1_verify_call_count = 0
458
+ double_1_reset_call_count = 0
459
+ ( class << double_1; self; end).class_eval do
460
+ define_method(:verify) do
461
+ double_1_verify_call_count += 1
462
+ end
463
+ define_method(:reset) do
464
+ double_1_reset_call_count += 1
465
+ end
466
+ end
467
+
468
+ double_2_verify_call_count = 0
469
+ double_2_reset_call_count = 0
470
+ ( class << double_2; self; end).class_eval do
471
+ define_method(:verify) do
472
+ double_2_verify_call_count += 1
473
+ end
474
+ define_method(:reset) do
475
+ double_2_reset_call_count += 1
476
+ end
477
+ end
478
+
479
+ double3_verify_call_count = 0
480
+ double3_reset_call_count = 0
481
+ ( class << double3; self; end).class_eval do
482
+ define_method(:verify) do
483
+ double3_verify_call_count += 1
484
+ end
485
+ define_method(:reset) do
486
+ double3_reset_call_count += 1
487
+ end
488
+ end
489
+
490
+ space.verify_doubles(subject_1, subject_2)
491
+
492
+ expect(double_1_verify_call_count).to eq 1
493
+ expect(double_1_reset_call_count).to eq 1
494
+ expect(double_2_verify_call_count).to eq 1
495
+ expect(double_2_reset_call_count).to eq 1
496
+ expect(double3_verify_call_count).to eq 0
497
+ expect(double3_reset_call_count).to eq 0
498
+ end
499
+ end
500
+
501
+ context "when passed an subject that does not have a DoubleInjection" do
502
+ it "does not raise an error" do
503
+ double_1_verify_call_count = 0
504
+ double_1_reset_call_count = 0
505
+ ( class << double_1; self; end).class_eval do
506
+ define_method(:verify) do
507
+ double_1_verify_call_count += 1
508
+ end
509
+ define_method(:reset) do
510
+ double_1_reset_call_count += 1
511
+ end
512
+ end
513
+
514
+ double_2_verify_call_count = 0
515
+ double_2_reset_call_count = 0
516
+ ( class << double_2; self; end).class_eval do
517
+ define_method(:verify) do
518
+ double_2_verify_call_count += 1
519
+ end
520
+ define_method(:reset) do
521
+ double_2_reset_call_count += 1
522
+ end
523
+ end
524
+
525
+ double3_verify_call_count = 0
526
+ double3_reset_call_count = 0
527
+ ( class << double3; self; end).class_eval do
528
+ define_method(:verify) do
529
+ double3_verify_call_count += 1
530
+ end
531
+ define_method(:reset) do
532
+ double3_reset_call_count += 1
533
+ end
534
+ end
535
+
536
+ no_double_injection_object = Object.new
537
+ space.verify_doubles(no_double_injection_object)
538
+
539
+ expect(double_1_verify_call_count).to eq 0
540
+ expect(double_1_reset_call_count).to eq 0
541
+ expect(double_2_verify_call_count).to eq 0
542
+ expect(double_2_reset_call_count).to eq 0
543
+ expect(double3_verify_call_count).to eq 0
544
+ expect(double3_reset_call_count).to eq 0
545
+ end
546
+ end
547
+ end
548
+
549
+ describe "#verify_double" do
550
+ before do
551
+ @method_name = :foobar
552
+
553
+ def subject.foobar
554
+ end
555
+ end
556
+
557
+ it "verifies and deletes the double_injection" do
558
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
559
+ expect(Injections::DoubleInjection.find_by_subject(subject, method_name)).to equal double_injection
560
+
561
+ verify_call_count = 0
562
+ ( class << double_injection; self; end).class_eval do
563
+ define_method(:verify) do
564
+ verify_call_count += 1
565
+ end
566
+ end
567
+ space.verify_double(subject, method_name)
568
+ expect(verify_call_count).to eq 1
569
+
570
+ expect(Injections::DoubleInjection.find(subject, method_name)).to be_nil
571
+ end
572
+
573
+ context "when verifying the double_injection raises an error" do
574
+ it "deletes the double_injection and restores the original method" do
575
+ original_method = subject.method(method_name)
576
+
577
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
578
+ expect(subject.method(method_name)).to_not eq original_method
579
+
580
+ expect(Injections::DoubleInjection.find_by_subject(subject, method_name)).to equal double_injection
581
+
582
+ verify_called = true
583
+ ( class << double_injection; self; end).class_eval do
584
+ define_method(:verify) do
585
+ verify_called = true
586
+ raise "An Error"
587
+ end
588
+ end
589
+ expect { space.verify_double(subject, method_name) }.to raise_error
590
+ expect(verify_called).to be_true
591
+
592
+ expect(Injections::DoubleInjection.find(subject, method_name)).to be_nil
593
+ expect(subject.method(method_name)).to eq original_method
594
+ end
595
+ end
596
+ end
597
+ end
598
+ end