rr 1.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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