rr 1.0.5 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +6 -14
  2. data/CHANGES.md +24 -0
  3. data/LICENSE +2 -2
  4. data/README.md +124 -741
  5. data/VERSION +1 -1
  6. data/lib/rr.rb +2 -103
  7. data/lib/rr/adapters/minitest.rb +21 -13
  8. data/lib/rr/adapters/minitest_active_support.rb +34 -0
  9. data/lib/rr/adapters/none.rb +17 -0
  10. data/lib/rr/adapters/{rspec.rb → rspec/invocation_matcher.rb} +2 -27
  11. data/lib/rr/adapters/rspec_1.rb +42 -0
  12. data/lib/rr/adapters/rspec_2.rb +24 -0
  13. data/lib/rr/adapters/test_unit_1.rb +54 -0
  14. data/lib/rr/adapters/test_unit_2.rb +13 -0
  15. data/lib/rr/adapters/test_unit_2_active_support.rb +35 -0
  16. data/lib/rr/autohook.rb +43 -0
  17. data/lib/rr/core_ext/array.rb +12 -0
  18. data/lib/rr/core_ext/enumerable.rb +16 -0
  19. data/lib/rr/core_ext/hash.rb +20 -0
  20. data/lib/rr/core_ext/range.rb +8 -0
  21. data/lib/rr/core_ext/regexp.rb +8 -0
  22. data/lib/rr/double.rb +4 -4
  23. data/lib/rr/double_definitions/double_definition.rb +9 -3
  24. data/lib/rr/errors.rb +21 -0
  25. data/lib/rr/expectations/argument_equality_expectation.rb +10 -7
  26. data/lib/rr/expectations/times_called_expectation.rb +2 -8
  27. data/lib/rr/injections/double_injection.rb +1 -1
  28. data/lib/rr/method_dispatches/base_method_dispatch.rb +1 -1
  29. data/lib/rr/recorded_calls.rb +12 -12
  30. data/lib/rr/space.rb +5 -3
  31. data/lib/rr/times_called_matchers/never_matcher.rb +2 -2
  32. data/lib/rr/wildcard_matchers/anything.rb +2 -2
  33. data/lib/rr/wildcard_matchers/boolean.rb +3 -7
  34. data/lib/rr/wildcard_matchers/duck_type.rb +11 -15
  35. data/lib/rr/wildcard_matchers/hash_including.rb +14 -13
  36. data/lib/rr/wildcard_matchers/is_a.rb +6 -7
  37. data/lib/rr/wildcard_matchers/satisfy.rb +8 -8
  38. data/lib/rr/without_autohook.rb +112 -0
  39. data/rr.gemspec +28 -0
  40. data/spec/global_helper.rb +12 -0
  41. data/spec/suite.rb +93 -0
  42. data/spec/suites/common/adapter_tests.rb +37 -0
  43. data/spec/suites/common/rails_integration_test.rb +175 -0
  44. data/spec/suites/common/test_unit_tests.rb +25 -0
  45. data/spec/suites/minitest/integration/minitest_test.rb +13 -0
  46. data/spec/suites/minitest/test_helper.rb +3 -0
  47. data/spec/suites/rspec_1/integration/rspec_1_spec.rb +20 -0
  48. data/spec/suites/rspec_1/integration/test_unit_1_rails_spec.rb +19 -0
  49. data/spec/suites/rspec_1/integration/test_unit_2_rails_spec.rb +18 -0
  50. data/spec/suites/rspec_1/spec_helper.rb +24 -0
  51. data/spec/suites/rspec_2/functional/any_instance_of_spec.rb +47 -0
  52. data/spec/suites/rspec_2/functional/dont_allow_spec.rb +12 -0
  53. data/spec/suites/rspec_2/functional/dsl_spec.rb +13 -0
  54. data/spec/suites/rspec_2/functional/instance_of_spec.rb +14 -0
  55. data/spec/suites/rspec_2/functional/mock_spec.rb +241 -0
  56. data/spec/suites/rspec_2/functional/proxy_spec.rb +136 -0
  57. data/spec/suites/rspec_2/functional/spy_spec.rb +41 -0
  58. data/spec/suites/rspec_2/functional/strong_spec.rb +79 -0
  59. data/spec/suites/rspec_2/functional/stub_spec.rb +190 -0
  60. data/spec/suites/rspec_2/functional/wildcard_matchers_spec.rb +128 -0
  61. data/spec/suites/rspec_2/integration/minitest_rails_spec.rb +15 -0
  62. data/spec/suites/rspec_2/integration/rspec_2_spec.rb +20 -0
  63. data/spec/suites/rspec_2/integration/test_unit_rails_spec.rb +14 -0
  64. data/spec/suites/rspec_2/spec_helper.rb +27 -0
  65. data/spec/suites/rspec_2/support/matchers/wildcard_matcher_matchers.rb +32 -0
  66. data/spec/suites/rspec_2/support/shared_examples/space.rb +13 -0
  67. data/spec/suites/rspec_2/support/shared_examples/times_called_expectation.rb +9 -0
  68. data/spec/suites/rspec_2/unit/adapters/rr_methods/double_creators_spec.rb +135 -0
  69. data/spec/suites/rspec_2/unit/adapters/rr_methods/space_spec.rb +101 -0
  70. data/spec/suites/rspec_2/unit/adapters/rr_methods/wildcard_matchers_spec.rb +69 -0
  71. data/spec/suites/rspec_2/unit/adapters/rspec/invocation_matcher_spec.rb +297 -0
  72. data/spec/suites/rspec_2/unit/adapters/rspec_spec.rb +85 -0
  73. data/spec/suites/rspec_2/unit/core_ext/array_spec.rb +39 -0
  74. data/spec/suites/rspec_2/unit/core_ext/enumerable_spec.rb +81 -0
  75. data/spec/suites/rspec_2/unit/core_ext/hash_spec.rb +55 -0
  76. data/spec/suites/rspec_2/unit/core_ext/range_spec.rb +41 -0
  77. data/spec/suites/rspec_2/unit/core_ext/regexp_spec.rb +41 -0
  78. data/spec/suites/rspec_2/unit/double_definitions/child_double_definition_create_spec.rb +114 -0
  79. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_blank_slate_spec.rb +93 -0
  80. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_spec.rb +446 -0
  81. data/spec/suites/rspec_2/unit/errors/rr_error_spec.rb +67 -0
  82. data/spec/suites/rspec_2/unit/expectations/any_argument_expectation_spec.rb +48 -0
  83. data/spec/suites/rspec_2/unit/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  84. data/spec/suites/rspec_2/unit/expectations/argument_equality_expectation_spec.rb +135 -0
  85. data/spec/suites/rspec_2/unit/expectations/boolean_argument_equality_expectation_spec.rb +30 -0
  86. data/spec/suites/rspec_2/unit/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
  87. data/spec/suites/rspec_2/unit/expectations/satisfy_argument_equality_expectation_spec.rb +61 -0
  88. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/any_times_matcher_spec.rb +22 -0
  89. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/at_least_matcher_spec.rb +37 -0
  90. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/at_most_matcher_spec.rb +43 -0
  91. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/integer_matcher_spec.rb +58 -0
  92. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/proc_matcher_spec.rb +35 -0
  93. data/spec/suites/rspec_2/unit/expectations/times_called_expectation/range_matcher_spec.rb +39 -0
  94. data/spec/suites/rspec_2/unit/hash_with_object_id_key_spec.rb +88 -0
  95. data/spec/suites/rspec_2/unit/injections/double_injection/double_injection_spec.rb +545 -0
  96. data/spec/suites/rspec_2/unit/injections/double_injection/double_injection_verify_spec.rb +32 -0
  97. data/spec/suites/rspec_2/unit/proc_from_block_spec.rb +14 -0
  98. data/spec/suites/rspec_2/unit/rr_spec.rb +28 -0
  99. data/spec/suites/rspec_2/unit/space_spec.rb +595 -0
  100. data/spec/suites/rspec_2/unit/spy_verification_spec.rb +133 -0
  101. data/spec/suites/rspec_2/unit/times_called_matchers/any_times_matcher_spec.rb +46 -0
  102. data/spec/suites/rspec_2/unit/times_called_matchers/at_least_matcher_spec.rb +54 -0
  103. data/spec/suites/rspec_2/unit/times_called_matchers/at_most_matcher_spec.rb +69 -0
  104. data/spec/suites/rspec_2/unit/times_called_matchers/integer_matcher_spec.rb +69 -0
  105. data/spec/suites/rspec_2/unit/times_called_matchers/proc_matcher_spec.rb +54 -0
  106. data/spec/suites/rspec_2/unit/times_called_matchers/range_matcher_spec.rb +75 -0
  107. data/spec/suites/rspec_2/unit/times_called_matchers/times_called_matcher_spec.rb +117 -0
  108. data/spec/suites/rspec_2/unit/wildcard_matchers/anything_spec.rb +33 -0
  109. data/spec/suites/rspec_2/unit/wildcard_matchers/boolean_spec.rb +45 -0
  110. data/spec/suites/rspec_2/unit/wildcard_matchers/duck_type_spec.rb +64 -0
  111. data/spec/suites/rspec_2/unit/wildcard_matchers/hash_including_spec.rb +64 -0
  112. data/spec/suites/rspec_2/unit/wildcard_matchers/is_a_spec.rb +55 -0
  113. data/spec/suites/rspec_2/unit/wildcard_matchers/numeric_spec.rb +46 -0
  114. data/spec/suites/rspec_2/unit/wildcard_matchers/satisfy_spec.rb +57 -0
  115. data/spec/suites/test_unit_1/integration/test_unit_1_test.rb +6 -0
  116. data/spec/suites/test_unit_1/test_helper.rb +7 -0
  117. data/spec/suites/test_unit_2/integration/test_unit_2_test.rb +6 -0
  118. data/spec/suites/test_unit_2/test_helper.rb +3 -0
  119. metadata +183 -19
  120. data/Gemfile +0 -9
  121. data/Rakefile +0 -34
  122. data/lib/rr/adapters/rspec2.rb +0 -30
  123. data/lib/rr/adapters/test_unit.rb +0 -33
  124. data/lib/rr/errors/argument_equality_error.rb +0 -6
  125. data/lib/rr/wildcard_matchers/range.rb +0 -7
  126. data/lib/rr/wildcard_matchers/regexp.rb +0 -7
  127. data/spec/runner.rb +0 -41
@@ -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,14 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ module RR
4
+ describe ProcFromBlock do
5
+ describe "#==" do
6
+ it "acts the same as #== on a Proc" do
7
+ original_proc = lambda {}
8
+ expect(Proc.new(&original_proc)).to eq original_proc
9
+
10
+ expect(ProcFromBlock.new(&original_proc)).to eq original_proc
11
+ end
12
+ end
13
+ end
14
+ 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,595 @@
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
+ block = lambda {}
15
+ space.record_call(object, :to_s, [], block)
16
+ expect(space.recorded_calls).to eq RR::RecordedCalls.new([[object, :to_s, [], block]])
17
+ end
18
+ end
19
+
20
+ describe "#double_injection" do
21
+ context "when existing subject == but not === with the same method name" do
22
+ it "creates a new DoubleInjection" do
23
+ subject_1 = []
24
+ subject_2 = []
25
+ expect((subject_1 === subject_2)).to be_true
26
+ expect(subject_1.__id__).to_not eq subject_2.__id__
27
+
28
+ injection_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, :foobar)
29
+ injection_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, :foobar)
30
+
31
+ expect(injection_1).to_not eq injection_2
32
+ end
33
+ end
34
+
35
+ context "when a DoubleInjection is not registered for the subject and method_name" do
36
+ before do
37
+ def subject.foobar(*args)
38
+ :original_foobar
39
+ end
40
+
41
+ @method_name = :foobar
42
+ end
43
+
44
+ context "when method_name is a symbol" do
45
+ it "returns double_injection and adds double_injection to double_injection list" do
46
+ double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
47
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)).to equal double_injection
48
+ expect(double_injection.subject_class).to eq(class << subject; self; end)
49
+ expect(double_injection.method_name).to equal method_name
50
+ end
51
+ end
52
+
53
+ context "when method_name is a string" do
54
+ it "returns double_injection and adds double_injection to double_injection list" do
55
+ double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')
56
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)).to equal double_injection
57
+ expect(double_injection.subject_class).to eq(class << subject; self; end)
58
+ expect(double_injection.method_name).to equal method_name
59
+ end
60
+ end
61
+
62
+ it "overrides the method when passing a block" do
63
+ original_method = subject.method(:foobar)
64
+ Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
65
+ expect(subject.method(:foobar)).to_not eq original_method
66
+ end
67
+ end
68
+
69
+ context "when double_injection exists" do
70
+ before do
71
+ def subject.foobar(*args)
72
+ :original_foobar
73
+ end
74
+
75
+ @method_name = :foobar
76
+ end
77
+
78
+ context "when a DoubleInjection is registered for the subject and method_name" do
79
+ it "returns the existing DoubleInjection" do
80
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')
81
+
82
+ expect(double_injection.subject_has_original_method?).to be_true
83
+
84
+ expect(Injections::DoubleInjection.find_or_create_by_subject(subject, 'foobar')).to equal double_injection
85
+
86
+ double_injection.reset
87
+ expect(subject.foobar).to eq :original_foobar
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#method_missing_injection" do
94
+ context "when existing subject == but not === with the same method name" do
95
+ it "creates a new DoubleInjection" do
96
+ subject_1 = []
97
+ subject_2 = []
98
+ expect((subject_1 === subject_2)).to be_true
99
+ expect(subject_1.__id__).to_not eq subject_2.__id__
100
+
101
+ injection_1 = Injections::MethodMissingInjection.find_or_create(class << subject_1; self; end)
102
+ injection_2 = Injections::MethodMissingInjection.find_or_create(class << subject_2; self; end)
103
+
104
+ expect(injection_1).to_not eq injection_2
105
+ end
106
+ end
107
+
108
+ context "when a MethodMissingInjection is not registered for the subject and method_name" do
109
+ before do
110
+ def subject.method_missing(method_name, *args, &block)
111
+ :original_method_missing
112
+ end
113
+ end
114
+
115
+ it "overrides the method when passing a block" do
116
+ original_method = subject.method(:method_missing)
117
+ Injections::MethodMissingInjection.find_or_create(class << subject; self; end)
118
+ expect(subject.method(:method_missing)).to_not eq original_method
119
+ end
120
+ end
121
+
122
+ context "when a MethodMissingInjection is registered for the subject and method_name" do
123
+ before do
124
+ def subject.method_missing(method_name, *args, &block)
125
+ :original_method_missing
126
+ end
127
+ end
128
+
129
+ context "when a DoubleInjection is registered for the subject and method_name" do
130
+ it "returns the existing DoubleInjection" do
131
+ injection = Injections::MethodMissingInjection.find_or_create(class << subject; self; end)
132
+ expect(injection.subject_has_original_method?).to be_true
133
+
134
+ expect(Injections::MethodMissingInjection.find_or_create(class << subject; self; end)).to equal injection
135
+
136
+ injection.reset
137
+ expect(subject.method_missing(:foobar)).to eq :original_method_missing
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ describe "#singleton_method_added_injection" do
144
+ context "when existing subject == but not === with the same method name" do
145
+ it "creates a new DoubleInjection" do
146
+ subject_1 = []
147
+ subject_2 = []
148
+ expect((subject_1 === subject_2)).to be_true
149
+ expect(subject_1.__id__).to_not eq subject_2.__id__
150
+
151
+ injection_1 = Injections::SingletonMethodAddedInjection.find_or_create(class << subject_1; self; end)
152
+ injection_2 = Injections::SingletonMethodAddedInjection.find_or_create(class << subject_2; self; end)
153
+
154
+ expect(injection_1).to_not eq injection_2
155
+ end
156
+ end
157
+
158
+ context "when a SingletonMethodAddedInjection is not registered for the subject and method_name" do
159
+ before do
160
+ def subject.singleton_method_added(method_name)
161
+ :original_singleton_method_added
162
+ end
163
+ end
164
+
165
+ it "overrides the method when passing a block" do
166
+ original_method = subject.method(:singleton_method_added)
167
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)
168
+ expect(subject.method(:singleton_method_added)).to_not eq original_method
169
+ end
170
+ end
171
+
172
+ context "when a SingletonMethodAddedInjection is registered for the subject and method_name" do
173
+ before do
174
+ def subject.singleton_method_added(method_name)
175
+ :original_singleton_method_added
176
+ end
177
+ end
178
+
179
+ context "when a DoubleInjection is registered for the subject and method_name" do
180
+ it "returns the existing DoubleInjection" do
181
+ injection = Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)
182
+ expect(injection.subject_has_original_method?).to be_true
183
+
184
+ expect(Injections::SingletonMethodAddedInjection.find_or_create(class << subject; self; end)).to equal injection
185
+
186
+ injection.reset
187
+ expect(subject.singleton_method_added(:foobar)).to eq :original_singleton_method_added
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "#reset" do
194
+ attr_reader :subject_1, :subject_2
195
+ before do
196
+ @subject_1 = Object.new
197
+ @subject_2 = Object.new
198
+ @method_name = :foobar
199
+ end
200
+
201
+ it "should clear the #recorded_calls" do
202
+ object = Object.new
203
+ space.record_call(object, :to_s, [], nil)
204
+
205
+ space.reset
206
+ expect(space.recorded_calls).to eq RR::RecordedCalls.new([])
207
+ end
208
+
209
+ it "removes the ordered doubles" do
210
+ mock(subject_1).foobar1.ordered
211
+ mock(subject_2).foobar2.ordered
212
+
213
+ space.ordered_doubles.should_not be_empty
214
+
215
+ space.reset
216
+ expect(space.ordered_doubles).to be_empty
217
+ end
218
+
219
+ it "resets all double_injections" do
220
+ expect(subject_1.respond_to?(method_name)).to be_false
221
+ expect(subject_2.respond_to?(method_name)).to be_false
222
+
223
+ Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
224
+ expect(Injections::DoubleInjection.exists_by_subject?(subject_1, method_name)).to be_true
225
+ expect(subject_1.respond_to?(method_name)).to be_true
226
+
227
+ Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
228
+ expect(Injections::DoubleInjection.exists_by_subject?(subject_2, method_name)).to be_true
229
+ expect(subject_2.respond_to?(method_name)).to be_true
230
+
231
+ space.reset
232
+
233
+ expect(subject_1.respond_to?(method_name)).to be_false
234
+ expect(Injections::DoubleInjection.exists?(subject_1, method_name)).to be_false
235
+
236
+ expect(subject_2.respond_to?(method_name)).to be_false
237
+ expect(Injections::DoubleInjection.exists?(subject_2, method_name)).to be_false
238
+ end
239
+
240
+ it "resets all method_missing_injections" do
241
+ expect(subject_1.respond_to?(:method_missing)).to be_false
242
+ expect(subject_2.respond_to?(:method_missing)).to be_false
243
+
244
+ Injections::MethodMissingInjection.find_or_create(class << subject_1; self; end)
245
+ expect(Injections::MethodMissingInjection.exists?(class << subject_1; self; end)).to be_true
246
+ expect(subject_1.respond_to?(:method_missing)).to be_true
247
+
248
+ Injections::MethodMissingInjection.find_or_create(class << subject_2; self; end)
249
+ expect(Injections::MethodMissingInjection.exists?(class << subject_2; self; end)).to be_true
250
+ expect(subject_2.respond_to?(:method_missing)).to be_true
251
+
252
+ space.reset
253
+
254
+ expect(subject_1.respond_to?(:method_missing)).to be_false
255
+ expect(Injections::MethodMissingInjection.exists?(subject_1)).to be_false
256
+
257
+ expect(subject_2.respond_to?(:method_missing)).to be_false
258
+ expect(Injections::MethodMissingInjection.exists?(subject_2)).to be_false
259
+ end
260
+
261
+ it "resets all singleton_method_added_injections" do
262
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_false
263
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_false
264
+
265
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject_1; self; end)
266
+ expect(Injections::SingletonMethodAddedInjection.exists?(class << subject_1; self; end)).to be_true
267
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_true
268
+
269
+ Injections::SingletonMethodAddedInjection.find_or_create(class << subject_2; self; end)
270
+ expect(Injections::SingletonMethodAddedInjection.exists?(class << subject_2; self; end)).to be_true
271
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_true
272
+
273
+ space.reset
274
+
275
+ expect(subject_1.respond_to?(:singleton_method_added)).to be_false
276
+ expect(Injections::SingletonMethodAddedInjection.exists?(subject_1)).to be_false
277
+
278
+ expect(subject_2.respond_to?(:singleton_method_added)).to be_false
279
+ expect(Injections::SingletonMethodAddedInjection.exists?(subject_2)).to be_false
280
+ end
281
+
282
+ it "clears RR::Injections::DoubleInjection::BoundObjects" do
283
+ stub(subject).foobar
284
+ RR::Injections::DoubleInjection::BoundObjects.should_not be_empty
285
+ space.reset
286
+ pending "Clearing BoundObjects" do
287
+ expect(RR::Injections::DoubleInjection::BoundObjects).to be_empty
288
+ end
289
+ end
290
+ end
291
+
292
+ describe "#reset_double" do
293
+ before do
294
+ @method_name = :foobar
295
+
296
+ def subject.foobar
297
+ end
298
+ end
299
+
300
+ it "resets the double_injections and restores the original method" do
301
+ original_method = subject.method(method_name)
302
+
303
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
304
+ expect(Injections::DoubleInjection.instances.keys).to include(class << subject; self; end)
305
+ Injections::DoubleInjection.find_by_subject(subject, method_name).should_not be_nil
306
+ expect(subject.method(method_name)).to_not eq original_method
307
+
308
+ space.reset_double(subject, method_name)
309
+ Injections::DoubleInjection.instances.keys.should_not include(subject)
310
+ expect(subject.method(method_name)).to eq original_method
311
+ end
312
+
313
+ context "when it has no double_injections" do
314
+ it "removes the subject from the double_injections map" do
315
+ Injections::DoubleInjection.find_or_create_by_subject(subject, :foobar1)
316
+ Injections::DoubleInjection.find_or_create_by_subject(subject, :foobar2)
317
+
318
+ expect(Injections::DoubleInjection.instances.include?(class << subject; self; end)).to eq true
319
+ Injections::DoubleInjection.find_by_subject(subject, :foobar1).should_not be_nil
320
+ Injections::DoubleInjection.find_by_subject(subject, :foobar2).should_not be_nil
321
+
322
+ space.reset_double(subject, :foobar1)
323
+ expect(Injections::DoubleInjection.instances.include?(class << subject; self; end)).to eq true
324
+ expect(Injections::DoubleInjection.find_by_subject(subject, :foobar1)).to be_nil
325
+ Injections::DoubleInjection.find_by_subject(subject, :foobar2).should_not be_nil
326
+
327
+ space.reset_double(subject, :foobar2)
328
+ expect(Injections::DoubleInjection.instances.include?(subject)).to eq false
329
+ end
330
+ end
331
+ end
332
+
333
+ describe "#DoubleInjection.reset" do
334
+ attr_reader :subject_1, :subject_2
335
+ before do
336
+ @subject_1 = Object.new
337
+ @subject_2 = Object.new
338
+ @method_name = :foobar
339
+ end
340
+
341
+ it "resets the double_injection and removes it from the double_injections list" do
342
+ double_injection_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
343
+ double_1_reset_call_count = 0
344
+ ( class << double_injection_1; self; end).class_eval do
345
+ define_method(:reset) do
346
+ double_1_reset_call_count += 1
347
+ end
348
+ end
349
+ double_injection_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
350
+ double_2_reset_call_count = 0
351
+ ( class << double_injection_2; self; end).class_eval do
352
+ define_method(:reset) do
353
+ double_2_reset_call_count += 1
354
+ end
355
+ end
356
+
357
+ Injections::DoubleInjection.reset
358
+ expect(double_1_reset_call_count).to eq 1
359
+ expect(double_2_reset_call_count).to eq 1
360
+ end
361
+ end
362
+
363
+ describe "#verify_doubles" do
364
+ attr_reader :subject_1, :subject_2, :subject3, :double_1, :double_2, :double3
365
+ before do
366
+ @subject_1 = Object.new
367
+ @subject_2 = Object.new
368
+ @subject3 = Object.new
369
+ @method_name = :foobar
370
+ @double_1 = Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
371
+ @double_2 = Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
372
+ @double3 = Injections::DoubleInjection.find_or_create_by_subject(subject3, method_name)
373
+ end
374
+
375
+ context "when passed no arguments" do
376
+ it "verifies and deletes the double_injections" do
377
+ double_1_verify_call_count = 0
378
+ double_1_reset_call_count = 0
379
+ (
380
+ class << double_1;
381
+ self;
382
+ end).class_eval do
383
+ define_method(:verify) do
384
+ double_1_verify_call_count += 1
385
+ end
386
+ define_method(:reset) do
387
+ double_1_reset_call_count += 1
388
+ end
389
+ end
390
+
391
+ double_2_verify_call_count = 0
392
+ double_2_reset_call_count = 0
393
+ (
394
+ class << double_2;
395
+ self;
396
+ end).class_eval do
397
+ define_method(:verify) do
398
+ double_2_verify_call_count += 1
399
+ end
400
+ define_method(:reset) do
401
+ double_2_reset_call_count += 1
402
+ end
403
+ end
404
+
405
+ space.verify_doubles
406
+ expect(double_1_verify_call_count).to eq 1
407
+ expect(double_2_verify_call_count).to eq 1
408
+ expect(double_1_reset_call_count).to eq 1
409
+ expect(double_1_reset_call_count).to eq 1
410
+ end
411
+ end
412
+
413
+ context "when passed an Object that has at least one DoubleInjection" do
414
+ it "verifies all Doubles injected into the Object" do
415
+ double_1_verify_call_count = 0
416
+ double_1_reset_call_count = 0
417
+ (
418
+ class << double_1;
419
+ self;
420
+ end).class_eval do
421
+ define_method(:verify) do
422
+ double_1_verify_call_count += 1
423
+ end
424
+ define_method(:reset) do
425
+ double_1_reset_call_count += 1
426
+ end
427
+ end
428
+
429
+ double_2_verify_call_count = 0
430
+ double_2_reset_call_count = 0
431
+ (
432
+ class << double_2;
433
+ self;
434
+ end).class_eval do
435
+ define_method(:verify) do
436
+ double_2_verify_call_count += 1
437
+ end
438
+ define_method(:reset) do
439
+ double_2_reset_call_count += 1
440
+ end
441
+ end
442
+
443
+ space.verify_doubles(subject_1)
444
+
445
+ expect(double_1_verify_call_count).to eq 1
446
+ expect(double_1_reset_call_count).to eq 1
447
+ expect(double_2_verify_call_count).to eq 0
448
+ expect(double_2_reset_call_count).to eq 0
449
+ end
450
+ end
451
+
452
+ context "when passed multiple Objects with at least one DoubleInjection" do
453
+ it "verifies the Doubles injected into all of the Objects" do
454
+ double_1_verify_call_count = 0
455
+ double_1_reset_call_count = 0
456
+ ( class << double_1; self; end).class_eval do
457
+ define_method(:verify) do
458
+ double_1_verify_call_count += 1
459
+ end
460
+ define_method(:reset) do
461
+ double_1_reset_call_count += 1
462
+ end
463
+ end
464
+
465
+ double_2_verify_call_count = 0
466
+ double_2_reset_call_count = 0
467
+ ( class << double_2; self; end).class_eval do
468
+ define_method(:verify) do
469
+ double_2_verify_call_count += 1
470
+ end
471
+ define_method(:reset) do
472
+ double_2_reset_call_count += 1
473
+ end
474
+ end
475
+
476
+ double3_verify_call_count = 0
477
+ double3_reset_call_count = 0
478
+ ( class << double3; self; end).class_eval do
479
+ define_method(:verify) do
480
+ double3_verify_call_count += 1
481
+ end
482
+ define_method(:reset) do
483
+ double3_reset_call_count += 1
484
+ end
485
+ end
486
+
487
+ space.verify_doubles(subject_1, subject_2)
488
+
489
+ expect(double_1_verify_call_count).to eq 1
490
+ expect(double_1_reset_call_count).to eq 1
491
+ expect(double_2_verify_call_count).to eq 1
492
+ expect(double_2_reset_call_count).to eq 1
493
+ expect(double3_verify_call_count).to eq 0
494
+ expect(double3_reset_call_count).to eq 0
495
+ end
496
+ end
497
+
498
+ context "when passed an subject that does not have a DoubleInjection" do
499
+ it "does not raise an error" do
500
+ double_1_verify_call_count = 0
501
+ double_1_reset_call_count = 0
502
+ ( class << double_1; self; end).class_eval do
503
+ define_method(:verify) do
504
+ double_1_verify_call_count += 1
505
+ end
506
+ define_method(:reset) do
507
+ double_1_reset_call_count += 1
508
+ end
509
+ end
510
+
511
+ double_2_verify_call_count = 0
512
+ double_2_reset_call_count = 0
513
+ ( class << double_2; self; end).class_eval do
514
+ define_method(:verify) do
515
+ double_2_verify_call_count += 1
516
+ end
517
+ define_method(:reset) do
518
+ double_2_reset_call_count += 1
519
+ end
520
+ end
521
+
522
+ double3_verify_call_count = 0
523
+ double3_reset_call_count = 0
524
+ ( class << double3; self; end).class_eval do
525
+ define_method(:verify) do
526
+ double3_verify_call_count += 1
527
+ end
528
+ define_method(:reset) do
529
+ double3_reset_call_count += 1
530
+ end
531
+ end
532
+
533
+ no_double_injection_object = Object.new
534
+ space.verify_doubles(no_double_injection_object)
535
+
536
+ expect(double_1_verify_call_count).to eq 0
537
+ expect(double_1_reset_call_count).to eq 0
538
+ expect(double_2_verify_call_count).to eq 0
539
+ expect(double_2_reset_call_count).to eq 0
540
+ expect(double3_verify_call_count).to eq 0
541
+ expect(double3_reset_call_count).to eq 0
542
+ end
543
+ end
544
+ end
545
+
546
+ describe "#verify_double" do
547
+ before do
548
+ @method_name = :foobar
549
+
550
+ def subject.foobar
551
+ end
552
+ end
553
+
554
+ it "verifies and deletes the double_injection" do
555
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
556
+ expect(Injections::DoubleInjection.find_by_subject(subject, method_name)).to equal double_injection
557
+
558
+ verify_call_count = 0
559
+ ( class << double_injection; self; end).class_eval do
560
+ define_method(:verify) do
561
+ verify_call_count += 1
562
+ end
563
+ end
564
+ space.verify_double(subject, method_name)
565
+ expect(verify_call_count).to eq 1
566
+
567
+ expect(Injections::DoubleInjection.find(subject, method_name)).to be_nil
568
+ end
569
+
570
+ context "when verifying the double_injection raises an error" do
571
+ it "deletes the double_injection and restores the original method" do
572
+ original_method = subject.method(method_name)
573
+
574
+ @double_injection = Injections::DoubleInjection.find_or_create_by_subject(subject, method_name)
575
+ expect(subject.method(method_name)).to_not eq original_method
576
+
577
+ expect(Injections::DoubleInjection.find_by_subject(subject, method_name)).to equal double_injection
578
+
579
+ verify_called = true
580
+ ( class << double_injection; self; end).class_eval do
581
+ define_method(:verify) do
582
+ verify_called = true
583
+ raise "An Error"
584
+ end
585
+ end
586
+ expect { space.verify_double(subject, method_name) }.to raise_error
587
+ expect(verify_called).to be_true
588
+
589
+ expect(Injections::DoubleInjection.find(subject, method_name)).to be_nil
590
+ expect(subject.method(method_name)).to eq original_method
591
+ end
592
+ end
593
+ end
594
+ end
595
+ end