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,533 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../spec_helper")
2
+
3
+ module RR
4
+ module Injections
5
+ describe DoubleInjection do
6
+ attr_reader :method_name, :double_injection
7
+
8
+ macro("sets up subject and method_name") do
9
+ it "sets up subject and method_name" do
10
+ expect(double_injection.subject).to equal subject
11
+ expect(double_injection.method_name).to eq method_name.to_sym
12
+ end
13
+ end
14
+
15
+ subject { Object.new }
16
+
17
+ describe "mock/stub" do
18
+ context "when the subject responds to the injected method" do
19
+ before do
20
+ class << subject
21
+ attr_reader :original_foobar_called
22
+
23
+ def foobar
24
+ @original_foobar_called = true
25
+ :original_foobar
26
+ end
27
+ end
28
+
29
+ expect(subject).to respond_to(:foobar)
30
+ expect(!!subject.methods.detect {|method| method.to_sym == :foobar}).to be_true
31
+ stub(subject).foobar {:new_foobar}
32
+ end
33
+
34
+ describe "being bound" do
35
+ it "sets __rr__original_{method_name} to the original method" do
36
+ expect(subject.__rr__original_foobar).to eq :original_foobar
37
+ end
38
+
39
+ describe "being called" do
40
+ it "returns the return value of the block" do
41
+ expect(subject.foobar).to eq :new_foobar
42
+ end
43
+
44
+ it "does not call the original method" do
45
+ subject.foobar
46
+ expect(subject.original_foobar_called).to be_nil
47
+ end
48
+ end
49
+
50
+ describe "being reset" do
51
+ before do
52
+ RR::Space.reset_double(subject, :foobar)
53
+ end
54
+
55
+ it "rebinds the original method" do
56
+ expect(subject.foobar).to eq :original_foobar
57
+ end
58
+
59
+ it "removes __rr__original_{method_name}" do
60
+ subject.should_not respond_to(:__rr__original_foobar)
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ context "when the subject does not respond to the injected method" do
67
+ before do
68
+ subject.should_not respond_to(:foobar)
69
+ subject.methods.should_not include('foobar')
70
+ stub(subject).foobar {:new_foobar}
71
+ end
72
+
73
+ it "does not set __rr__original_{method_name} to the original method" do
74
+ subject.should_not respond_to(:__rr__original_foobar)
75
+ end
76
+
77
+ describe "being called" do
78
+ it "calls the newly defined method" do
79
+ expect(subject.foobar).to eq :new_foobar
80
+ end
81
+ end
82
+
83
+ describe "being reset" do
84
+ before do
85
+ RR::Space.reset_double(subject, :foobar)
86
+ end
87
+
88
+ it "unsets the foobar method" do
89
+ subject.should_not respond_to(:foobar)
90
+ subject.methods.should_not include('foobar')
91
+ end
92
+ end
93
+ end
94
+
95
+ context "when the subject redefines respond_to?" do
96
+ it "does not try to call the implementation" do
97
+ class << subject
98
+ def respond_to?(method_symbol, include_private = false)
99
+ method_symbol == :foobar
100
+ end
101
+ end
102
+ mock(subject).foobar
103
+ expect(subject.foobar).to eq nil
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "mock/stub + proxy" do
109
+ context "when the subject responds to the injected method" do
110
+ context "when the subject has the method defined" do
111
+ describe "being bound" do
112
+ before do
113
+ def subject.foobar
114
+ :original_foobar
115
+ end
116
+
117
+ expect(subject).to respond_to(:foobar)
118
+ expect(!!subject.methods.detect {|method| method.to_sym == :foobar}).to be_true
119
+ stub.proxy(subject).foobar {:new_foobar}
120
+ end
121
+
122
+ it "aliases the original method to __rr__original_{method_name}" do
123
+ expect(subject.__rr__original_foobar).to eq :original_foobar
124
+ end
125
+
126
+ it "replaces the original method with the new method" do
127
+ expect(subject.foobar).to eq :new_foobar
128
+ end
129
+
130
+ describe "being called" do
131
+ it "calls the original method first and sends it into the block" do
132
+ original_return_value = nil
133
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
134
+ expect(subject.foobar).to eq :new_foobar
135
+ expect(original_return_value).to eq :original_foobar
136
+ end
137
+ end
138
+
139
+ describe "being reset" do
140
+ before do
141
+ RR::Space.reset_double(subject, :foobar)
142
+ end
143
+
144
+ it "rebinds the original method" do
145
+ expect(subject.foobar).to eq :original_foobar
146
+ end
147
+
148
+ it "removes __rr__original_{method_name}" do
149
+ subject.should_not respond_to(:__rr__original_foobar)
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ context "when the subject does not have the method defined" do
156
+ describe "being bound" do
157
+ context "when the subject has not been previously bound to" do
158
+ before do
159
+ setup_subject
160
+
161
+ expect(subject).to respond_to(:foobar)
162
+ stub.proxy(subject).foobar {:new_foobar}
163
+ end
164
+
165
+ def setup_subject
166
+ def subject.respond_to?(method_name)
167
+ if method_name.to_sym == :foobar
168
+ true
169
+ else
170
+ super
171
+ end
172
+ end
173
+ end
174
+
175
+ it "does not define __rr__original_{method_name}" do
176
+ subject.methods.should_not include("__rr__original_foobar")
177
+ end
178
+
179
+ context "when method is defined after being bound and before being called" do
180
+ def setup_subject
181
+ super
182
+ def subject.foobar
183
+ :original_foobar
184
+ end
185
+ end
186
+
187
+ describe "being called" do
188
+ it "defines __rr__original_{method_name} to be the lazily created method" do
189
+ expect((!!subject.methods.detect {|method| method.to_sym == :__rr__original_foobar})).to be_true
190
+ expect(subject.__rr__original_foobar).to eq :original_foobar
191
+ end
192
+
193
+ it "calls the original method first and sends it into the block" do
194
+ original_return_value = nil
195
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
196
+ expect(subject.foobar).to eq :new_foobar
197
+ expect(original_return_value).to eq :original_foobar
198
+ end
199
+ end
200
+
201
+ describe "being reset" do
202
+ before do
203
+ RR::Space.reset_double(subject, :foobar)
204
+ end
205
+
206
+ it "rebinds the original method" do
207
+ expect(subject.foobar).to eq :original_foobar
208
+ end
209
+
210
+ it "removes __rr__original_{method_name}" do
211
+ subject.should_not respond_to(:__rr__original_foobar)
212
+ end
213
+ end
214
+ end
215
+
216
+ context "when method is still not defined" do
217
+ context "when the method is lazily created" do
218
+ def setup_subject
219
+ super
220
+ def subject.method_missing(method_name, *args, &block)
221
+ if method_name.to_sym == :foobar
222
+ def self.foobar
223
+ :original_foobar
224
+ end
225
+
226
+ foobar
227
+ else
228
+ super
229
+ end
230
+ end
231
+ end
232
+
233
+ describe "being called" do
234
+ it "calls the lazily created method and returns the injected method return value" do
235
+ original_return_value = nil
236
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
237
+ expect(subject.foobar).to eq :new_foobar
238
+ expect(original_return_value).to eq :original_foobar
239
+ end
240
+ end
241
+
242
+ describe "being reset" do
243
+ context "when reset before being called" do
244
+ before do
245
+ RR::Space.reset_double(subject, :foobar)
246
+ end
247
+
248
+ it "rebinds the original method" do
249
+ expect(subject.foobar).to eq :original_foobar
250
+ end
251
+
252
+ it "removes __rr__original_{method_name}" do
253
+ subject.should_not respond_to(:__rr__original_foobar)
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ context "when the method is not lazily created (handled in method_missing)" do
260
+ def setup_subject
261
+ super
262
+ def subject.method_missing(method_name, *args, &block)
263
+ if method_name.to_sym == :foobar
264
+ :original_foobar
265
+ else
266
+ super
267
+ end
268
+ end
269
+ end
270
+
271
+ describe "being called" do
272
+ it "does not define the __rr__original_{method_name}" do
273
+ subject.foobar
274
+ subject.methods.should_not include("__rr__original_foobar")
275
+ end
276
+
277
+ it "calls the lazily created method and returns the injected method return value" do
278
+ original_return_value = nil
279
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
280
+ expect(subject.foobar).to eq :new_foobar
281
+ expect(original_return_value).to eq :original_foobar
282
+ end
283
+ end
284
+
285
+ describe "being reset" do
286
+ before do
287
+ RR::Space.reset_double(subject, :foobar)
288
+ end
289
+
290
+ it "rebinds the original method" do
291
+ expect(subject.foobar).to eq :original_foobar
292
+ end
293
+
294
+ it "removes __rr__original_{method_name}" do
295
+ subject.should_not respond_to(:__rr__original_foobar)
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+ context "when the subject has been previously bound to" do
303
+ before do
304
+ setup_subject
305
+
306
+ expect(subject).to respond_to(:foobar)
307
+ stub.proxy(subject).baz {:new_baz}
308
+ stub.proxy(subject).foobar {:new_foobar}
309
+ end
310
+
311
+ def setup_subject
312
+ def subject.respond_to?(method_name)
313
+ if method_name.to_sym == :foobar || method_name.to_sym == :baz
314
+ true
315
+ else
316
+ super
317
+ end
318
+ end
319
+ end
320
+
321
+ it "does not define __rr__original_{method_name}" do
322
+ subject.methods.should_not include("__rr__original_foobar")
323
+ end
324
+
325
+ context "when method is defined after being bound and before being called" do
326
+ def setup_subject
327
+ super
328
+ def subject.foobar
329
+ :original_foobar
330
+ end
331
+ end
332
+
333
+ describe "being called" do
334
+ it "defines __rr__original_{method_name} to be the lazily created method" do
335
+ expect((!!subject.methods.detect {|method| method.to_sym == :__rr__original_foobar})).to be_true
336
+ expect(subject.__rr__original_foobar).to eq :original_foobar
337
+ end
338
+
339
+ it "calls the original method first and sends it into the block" do
340
+ original_return_value = nil
341
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
342
+ expect(subject.foobar).to eq :new_foobar
343
+ expect(original_return_value).to eq :original_foobar
344
+ end
345
+ end
346
+
347
+ describe "being reset" do
348
+ before do
349
+ RR::Space.reset_double(subject, :foobar)
350
+ end
351
+
352
+ it "rebinds the original method" do
353
+ expect(subject.foobar).to eq :original_foobar
354
+ end
355
+
356
+ it "removes __rr__original_{method_name}" do
357
+ subject.should_not respond_to(:__rr__original_foobar)
358
+ end
359
+ end
360
+ end
361
+
362
+ context "when method is still not defined" do
363
+ context "when the method is lazily created" do
364
+ def setup_subject
365
+ super
366
+ def subject.method_missing(method_name, *args, &block)
367
+ if method_name.to_sym == :foobar
368
+ def self.foobar
369
+ :original_foobar
370
+ end
371
+
372
+ foobar
373
+ else
374
+ super
375
+ end
376
+ end
377
+ end
378
+
379
+ describe "being called" do
380
+ it "calls the lazily created method and returns the injected method return value" do
381
+ original_return_value = nil
382
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
383
+ expect(subject.foobar).to eq :new_foobar
384
+ expect(original_return_value).to eq :original_foobar
385
+ end
386
+ end
387
+
388
+ describe "being reset" do
389
+ context "when reset before being called" do
390
+ before do
391
+ RR::Space.reset_double(subject, :foobar)
392
+ end
393
+
394
+ it "rebinds the original method" do
395
+ expect(subject.foobar).to eq :original_foobar
396
+ end
397
+
398
+ it "removes __rr__original_{method_name}" do
399
+ subject.should_not respond_to(:__rr__original_foobar)
400
+ end
401
+ end
402
+ end
403
+ end
404
+
405
+ context "when the method is not lazily created (handled in method_missing)" do
406
+ def setup_subject
407
+ super
408
+ def subject.method_missing(method_name, *args, &block)
409
+ if method_name.to_sym == :foobar
410
+ :original_foobar
411
+ else
412
+ super
413
+ end
414
+ end
415
+ end
416
+
417
+ describe "being called" do
418
+ it "does not define the __rr__original_{method_name}" do
419
+ subject.foobar
420
+ subject.methods.should_not include("__rr__original_foobar")
421
+ end
422
+
423
+ it "calls the lazily created method and returns the injected method return value" do
424
+ original_return_value = nil
425
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
426
+ expect(subject.foobar).to eq :new_foobar
427
+ expect(original_return_value).to eq :original_foobar
428
+ end
429
+ end
430
+
431
+ describe "being reset" do
432
+ before do
433
+ RR::Space.reset_double(subject, :foobar)
434
+ end
435
+
436
+ it "rebinds the original method" do
437
+ expect(subject.foobar).to eq :original_foobar
438
+ end
439
+
440
+ it "removes __rr__original_{method_name}" do
441
+ subject.should_not respond_to(:__rr__original_foobar)
442
+ end
443
+ end
444
+ end
445
+ end
446
+ end
447
+ end
448
+ end
449
+ end
450
+
451
+ context "when the subject does not respond to the injected method" do
452
+ context "when the subject responds to the method via method_missing" do
453
+ describe "being bound" do
454
+ before do
455
+ subject.should_not respond_to(:foobar)
456
+ subject.methods.should_not include('foobar')
457
+ class << subject
458
+ def method_missing(method_name, *args, &block)
459
+ if method_name == :foobar
460
+ :original_foobar
461
+ else
462
+ super
463
+ end
464
+ end
465
+ end
466
+ stub.proxy(subject).foobar {:new_foobar}
467
+ end
468
+
469
+ it "adds the method to the subject" do
470
+ expect(subject).to respond_to(:foobar)
471
+ expect((!!subject.methods.detect {|method| method.to_sym == :foobar})).to be_true
472
+ end
473
+
474
+ describe "being called" do
475
+ it "calls the original method first and sends it into the block" do
476
+ original_return_value = nil
477
+ stub.proxy(subject).foobar {|arg| original_return_value = arg; :new_foobar}
478
+ expect(subject.foobar).to eq :new_foobar
479
+ expect(original_return_value).to eq :original_foobar
480
+ end
481
+ end
482
+
483
+ describe "being reset" do
484
+ before do
485
+ RR::Space.reset_double(subject, :foobar)
486
+ end
487
+
488
+ it "unsets the foobar method" do
489
+ subject.should_not respond_to(:foobar)
490
+ subject.methods.should_not include('foobar')
491
+ end
492
+ end
493
+ end
494
+ end
495
+
496
+ context "when the subject would raise a NoMethodError when the method is called" do
497
+ describe "being bound" do
498
+ before do
499
+ subject.should_not respond_to(:foobar)
500
+ subject.methods.should_not include('foobar')
501
+ stub.proxy(subject).foobar {:new_foobar}
502
+ end
503
+
504
+ it "adds the method to the subject" do
505
+ expect(subject).to respond_to(:foobar)
506
+ expect((!!subject.methods.detect {|method| method.to_sym == :foobar})).to be_true
507
+ end
508
+
509
+ describe "being called" do
510
+ it "raises a NoMethodError" do
511
+ expect {
512
+ subject.foobar
513
+ }.to raise_error(NoMethodError)
514
+ end
515
+ end
516
+
517
+ describe "being reset" do
518
+ before do
519
+ RR::Space.reset_double(subject, :foobar)
520
+ end
521
+
522
+ it "unsets the foobar method" do
523
+ subject.should_not respond_to(:foobar)
524
+ subject.methods.should_not include('foobar')
525
+ end
526
+ end
527
+ end
528
+ end
529
+ end
530
+ end
531
+ end
532
+ end
533
+ end