rr 1.1.2 → 3.0.2

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 (157) hide show
  1. checksums.yaml +5 -5
  2. data/Appraisals +3 -43
  3. data/CHANGES.md +93 -0
  4. data/CREDITS.md +5 -0
  5. data/Gemfile +1 -17
  6. data/README.md +29 -32
  7. data/Rakefile +42 -40
  8. data/doc/02_syntax_comparison.md +1 -0
  9. data/lib/rr/class_instance_method_defined.rb +1 -1
  10. data/lib/rr/core_ext/array.rb +2 -0
  11. data/lib/rr/core_ext/hash.rb +2 -0
  12. data/lib/rr/deprecations.rb +97 -0
  13. data/lib/rr/double.rb +28 -10
  14. data/lib/rr/double_definitions/double_definition.rb +39 -16
  15. data/lib/rr/double_definitions/double_definition_create.rb +5 -5
  16. data/lib/rr/double_definitions/double_definition_create_blank_slate.rb +10 -4
  17. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +1 -1
  18. data/lib/rr/double_definitions/double_injections/instance.rb +2 -2
  19. data/lib/rr/double_definitions/strategies/strategy.rb +27 -8
  20. data/lib/rr/double_definitions/strategies/verification/mock.rb +8 -2
  21. data/lib/rr/double_matches.rb +4 -3
  22. data/lib/rr/dsl.rb +152 -0
  23. data/lib/rr/expectations/any_argument_expectation.rb +4 -4
  24. data/lib/rr/expectations/argument_equality_expectation.rb +43 -5
  25. data/lib/rr/injections/double_injection.rb +85 -26
  26. data/lib/rr/injections/method_missing_injection.rb +37 -6
  27. data/lib/rr/integrations/minitest_4.rb +1 -1
  28. data/lib/rr/integrations/minitest_4_active_support.rb +1 -1
  29. data/lib/rr/integrations/rspec/invocation_matcher.rb +0 -8
  30. data/lib/rr/integrations/rspec_2.rb +20 -2
  31. data/lib/rr/keyword_arguments.rb +15 -0
  32. data/lib/rr/method_dispatches/base_method_dispatch.rb +22 -5
  33. data/lib/rr/method_dispatches/method_dispatch.rb +21 -10
  34. data/lib/rr/method_dispatches/method_missing_dispatch.rb +14 -5
  35. data/lib/rr/recorded_call.rb +35 -0
  36. data/lib/rr/recorded_calls.rb +23 -9
  37. data/lib/rr/space.rb +15 -5
  38. data/lib/rr/spy_verification.rb +13 -5
  39. data/lib/rr/version.rb +1 -1
  40. data/lib/rr/wildcard_matchers.rb +10 -10
  41. data/lib/rr/without_autohook.rb +7 -14
  42. data/rr.gemspec +8 -3
  43. data/spec/defines_spec_suite_tasks.rb +12 -0
  44. data/spec/global_helper.rb +5 -0
  45. data/spec/spec_suite_configuration.rb +1 -7
  46. data/spec/suites.yml +0 -14
  47. data/spec/suites/rspec_2/functional/any_instance_of_spec.rb +133 -33
  48. data/spec/suites/rspec_2/functional/dont_allow_spec.rb +13 -8
  49. data/spec/suites/rspec_2/functional/mock_bang_spec.rb +20 -0
  50. data/spec/suites/rspec_2/functional/mock_instance_of_spec.rb +14 -0
  51. data/spec/suites/rspec_2/functional/mock_instance_of_strong_spec.rb +15 -0
  52. data/spec/suites/rspec_2/functional/mock_proxy_instance_of_spec.rb +15 -0
  53. data/spec/suites/rspec_2/functional/mock_proxy_spec.rb +14 -0
  54. data/spec/suites/rspec_2/functional/mock_spec.rb +8 -232
  55. data/spec/suites/rspec_2/functional/mock_strong_spec.rb +14 -0
  56. data/spec/suites/rspec_2/functional/received_spec.rb +16 -0
  57. data/spec/suites/rspec_2/functional/spy_spec.rb +89 -28
  58. data/spec/suites/rspec_2/functional/stub_bang_spec.rb +20 -0
  59. data/spec/suites/rspec_2/functional/stub_instance_of_spec.rb +15 -0
  60. data/spec/suites/rspec_2/functional/stub_instance_of_strong_spec.rb +15 -0
  61. data/spec/suites/rspec_2/functional/stub_proxy_instance_of_spec.rb +16 -0
  62. data/spec/suites/rspec_2/functional/stub_proxy_spec.rb +45 -0
  63. data/spec/suites/rspec_2/functional/stub_spec.rb +42 -161
  64. data/spec/suites/rspec_2/functional/stub_strong_spec.rb +15 -0
  65. data/spec/suites/rspec_2/helper.rb +2 -2
  66. data/spec/suites/rspec_2/support/mixins/double_definition_creator_helpers.rb +173 -0
  67. data/spec/suites/rspec_2/support/mixins/mock_definition_creator_helpers.rb +45 -0
  68. data/spec/suites/rspec_2/support/mixins/proxy_definition_creator_helpers.rb +33 -0
  69. data/spec/suites/rspec_2/support/mixins/stub_creator_helpers.rb +43 -0
  70. data/spec/suites/rspec_2/support/mixins/stub_definition_creator_helpers.rb +45 -0
  71. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_never_called_qualifier.rb +39 -0
  72. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_times_called_qualifier.rb +50 -0
  73. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_without_qualifiers.rb +131 -0
  74. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/dont_allow.rb +148 -0
  75. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of.rb +26 -0
  76. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of_strong.rb +28 -0
  77. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_proxy.rb +11 -0
  78. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_strong.rb +37 -0
  79. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mocking.rb +107 -0
  80. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of.rb +32 -0
  81. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of_strong.rb +39 -0
  82. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_proxy.rb +11 -0
  83. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_strong.rb +37 -0
  84. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stubbing.rb +57 -0
  85. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/array_flatten_bug.rb +35 -0
  86. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/block_form.rb +31 -0
  87. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/comparing_arity.rb +63 -0
  88. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/object_is_proxy.rb +43 -0
  89. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/sequential_invocations.rb +26 -0
  90. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/setting_implementation.rb +51 -0
  91. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/yields.rb +81 -0
  92. data/spec/suites/rspec_2/unit/core_ext/enumerable_spec.rb +0 -28
  93. data/spec/suites/rspec_2/unit/deprecations_spec.rb +27 -0
  94. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_spec.rb +18 -18
  95. data/spec/suites/rspec_2/unit/dsl/double_creators_spec.rb +133 -0
  96. data/spec/suites/rspec_2/unit/dsl/space_spec.rb +99 -0
  97. data/spec/suites/rspec_2/unit/dsl/wildcard_matchers_spec.rb +67 -0
  98. data/spec/suites/rspec_2/unit/expectations/any_argument_expectation_spec.rb +9 -9
  99. data/spec/suites/rspec_2/unit/expectations/argument_equality_expectation_spec.rb +21 -21
  100. data/spec/suites/rspec_2/unit/expectations/boolean_argument_equality_expectation_spec.rb +4 -4
  101. data/spec/suites/rspec_2/unit/expectations/hash_including_argument_equality_expectation_spec.rb +31 -21
  102. data/spec/suites/rspec_2/unit/injections/double_injection/double_injection_spec.rb +0 -12
  103. data/spec/suites/rspec_2/unit/integrations/rspec_spec.rb +4 -19
  104. data/spec/suites/rspec_2/unit/space_spec.rb +7 -4
  105. data/spec/suites/rspec_2/unit/spy_verification_spec.rb +1 -1
  106. data/spec/support/adapter.rb +1 -1
  107. data/spec/support/adapter_tests/rspec.rb +19 -15
  108. data/spec/support/project/generator.rb +0 -4
  109. metadata +112 -57
  110. data/gemfiles/ruby_18_rspec_1.gemfile +0 -14
  111. data/gemfiles/ruby_18_rspec_1.gemfile.lock +0 -38
  112. data/gemfiles/ruby_18_rspec_1_rails_2.gemfile +0 -18
  113. data/gemfiles/ruby_18_rspec_1_rails_2.gemfile.lock +0 -64
  114. data/gemfiles/ruby_19_rspec_2_rails_3.gemfile +0 -15
  115. data/gemfiles/ruby_19_rspec_2_rails_3.gemfile.lock +0 -123
  116. data/lib/rr/adapters.rb +0 -34
  117. data/lib/rr/adapters/rr_methods.rb +0 -142
  118. data/lib/rr/integrations/rspec_1.rb +0 -46
  119. data/lib/rr/integrations/test_unit_1.rb +0 -63
  120. data/lib/rr/integrations/test_unit_2.rb +0 -17
  121. data/lib/rr/integrations/test_unit_200.rb +0 -27
  122. data/lib/rr/integrations/test_unit_200_active_support.rb +0 -25
  123. data/lib/rr/integrations/test_unit_2_active_support.rb +0 -38
  124. data/lib/rr/proc_from_block.rb +0 -11
  125. data/spec/suites/rspec_1/helper.rb +0 -24
  126. data/spec/suites/rspec_1/integration/rspec_1_spec.rb +0 -93
  127. data/spec/suites/rspec_1/integration/test_unit_1_spec.rb +0 -102
  128. data/spec/suites/rspec_1/integration/test_unit_2_spec.rb +0 -109
  129. data/spec/suites/rspec_1/spec_helper.rb +0 -3
  130. data/spec/suites/rspec_1_rails_2/integration/astc_rails_2_spec.rb +0 -141
  131. data/spec/suites/rspec_1_rails_2/integration/rspec_1_rails_2_spec.rb +0 -132
  132. data/spec/suites/rspec_1_rails_2/integration/test_unit_1_rails_2_spec.rb +0 -141
  133. data/spec/suites/rspec_1_rails_2/integration/test_unit_2_rails_2_spec.rb +0 -148
  134. data/spec/suites/rspec_1_rails_2/spec_helper.rb +0 -3
  135. data/spec/suites/rspec_2/functional/dsl_spec.rb +0 -13
  136. data/spec/suites/rspec_2/functional/instance_of_spec.rb +0 -14
  137. data/spec/suites/rspec_2/functional/proxy_spec.rb +0 -136
  138. data/spec/suites/rspec_2/functional/strong_spec.rb +0 -79
  139. data/spec/suites/rspec_2/integration/rspec_2_spec.rb +0 -133
  140. data/spec/suites/rspec_2/integration/test_unit_200_spec.rb +0 -102
  141. data/spec/suites/rspec_2/integration/test_unit_2_spec.rb +0 -109
  142. data/spec/suites/rspec_2/unit/adapters/rr_methods/double_creators_spec.rb +0 -135
  143. data/spec/suites/rspec_2/unit/adapters/rr_methods/space_spec.rb +0 -101
  144. data/spec/suites/rspec_2/unit/adapters/rr_methods/wildcard_matchers_spec.rb +0 -69
  145. data/spec/suites/rspec_2/unit/proc_from_block_spec.rb +0 -14
  146. data/spec/suites/rspec_2_rails_3/integration/astc_rails_3_spec.rb +0 -141
  147. data/spec/suites/rspec_2_rails_3/integration/minitest_4_rails_3_spec.rb +0 -148
  148. data/spec/suites/rspec_2_rails_3/integration/rspec_2_rails_3_spec.rb +0 -172
  149. data/spec/suites/rspec_2_rails_3/integration/test_unit_200_rails_3_spec.rb +0 -141
  150. data/spec/suites/rspec_2_rails_3/integration/test_unit_2_rails_3_spec.rb +0 -148
  151. data/spec/suites/rspec_2_rails_3/spec_helper.rb +0 -3
  152. data/spec/suites/rspec_2_rails_4/integration/astc_rails_4_spec.rb +0 -142
  153. data/spec/suites/rspec_2_rails_4/integration/minitest_4_rails_4_spec.rb +0 -149
  154. data/spec/suites/rspec_2_rails_4/integration/rspec_2_rails_4_spec.rb +0 -173
  155. data/spec/suites/rspec_2_rails_4/integration/test_unit_200_rails_4_spec.rb +0 -142
  156. data/spec/suites/rspec_2_rails_4/integration/test_unit_2_rails_4_spec.rb +0 -149
  157. data/spec/suites/rspec_2_rails_4/spec_helper.rb +0 -3
@@ -2,14 +2,14 @@ module RR
2
2
  module Expectations
3
3
  class AnyArgumentExpectation < ArgumentEqualityExpectation #:nodoc:
4
4
  def initialize
5
- super
5
+ super([], {})
6
6
  end
7
7
 
8
- def exact_match?(*arguments)
8
+ def exact_match?(arguments, keyword_arguments)
9
9
  false
10
10
  end
11
11
 
12
- def wildcard_match?(*arguments)
12
+ def wildcard_match?(arguments, keyword_arguments)
13
13
  true
14
14
  end
15
15
 
@@ -18,4 +18,4 @@ module RR
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -10,20 +10,37 @@ module RR
10
10
  end
11
11
 
12
12
  attr_reader :expected_arguments
13
+ attr_reader :expected_keyword_arguments
13
14
 
14
- def initialize(*expected_arguments)
15
+ def initialize(expected_arguments,
16
+ expected_keyword_arguments)
15
17
  @expected_arguments = expected_arguments
18
+ @expected_keyword_arguments = expected_keyword_arguments
16
19
  end
17
20
 
18
- def exact_match?(*arguments)
21
+ def exact_match?(arguments, keyword_arguments)
19
22
  return false unless arguments.length == expected_arguments.length
20
23
  arguments.each_with_index do |arg, index|
21
- return false unless self.class.recursive_safe_eq(expected_arguments[index], arg)
24
+ expected_arg = expected_arguments[index]
25
+ return false unless self.class.recursive_safe_eq(expected_arg, arg)
26
+ end
27
+ keywords = keyword_arguments.keys
28
+ expected_keywords = expected_keyword_arguments.keys
29
+ unless keywords.length == expected_keywords.length
30
+ return false
31
+ end
32
+ keywords.each do |keyword|
33
+ keyword_argument = keyword_arguments[keyword]
34
+ expected_keyword_argument = expected_keyword_arguments[keyword]
35
+ unless self.class.recursive_safe_eq(expected_keyword_argument,
36
+ keyword_argument)
37
+ return false
38
+ end
22
39
  end
23
40
  true
24
41
  end
25
42
 
26
- def wildcard_match?(*arguments)
43
+ def wildcard_match?(arguments, keyword_arguments)
27
44
  return false unless arguments.length == expected_arguments.length
28
45
  arguments.each_with_index do |arg, index|
29
46
  expected_argument = expected_arguments[index]
@@ -33,11 +50,32 @@ module RR
33
50
  return false unless self.class.recursive_safe_eq(expected_argument, arg)
34
51
  end
35
52
  end
53
+ keywords = keyword_arguments.keys
54
+ expected_keywords = expected_keyword_arguments.keys
55
+ unless keywords.length == expected_keywords.length
56
+ return false
57
+ end
58
+ keywords.each do |keyword|
59
+ keyword_argument = keyword_arguments[keyword]
60
+ expected_keyword_argument = expected_keyword_arguments[keyword]
61
+ if expected_keyword_argument.respond_to?(:wildcard_match?)
62
+ unless expected_keyword_argument.wildcard_match?(keyword_argument)
63
+ return false
64
+ end
65
+ else
66
+ unless self.class.recursive_safe_eq(expected_keyword_argument,
67
+ keyword_argument)
68
+ return false
69
+ end
70
+ end
71
+ end
36
72
  true
37
73
  end
38
74
 
39
75
  def ==(other)
40
- expected_arguments == other.expected_arguments
76
+ other.is_a?(self.class) and
77
+ expected_arguments == other.expected_arguments and
78
+ expected_keyword_arguments == other.expected_keyword_arguments
41
79
  end
42
80
  end
43
81
  end
@@ -31,15 +31,20 @@ module RR
31
31
  exists?((class << subject; self; end), method_name)
32
32
  end
33
33
 
34
- def dispatch_method(subject, subject_class, method_name, arguments, block)
34
+ def dispatch_method(subject,
35
+ subject_class,
36
+ method_name,
37
+ arguments,
38
+ keyword_arguments,
39
+ block)
35
40
  subject_eigenclass = (class << subject; self; end)
36
41
  if (
37
42
  exists?(subject_class, method_name) &&
38
- (subject_class == subject_eigenclass) || !subject.is_a?(Class)
43
+ ((subject_class == subject_eigenclass) || !subject.is_a?(Class))
39
44
  )
40
- find(subject_class, method_name.to_sym).dispatch_method(subject, arguments, block)
45
+ find(subject_class, method_name.to_sym).dispatch_method(subject, arguments, keyword_arguments, block)
41
46
  else
42
- new(subject_class, method_name.to_sym).dispatch_original_method(subject, arguments, block)
47
+ new(subject_class, method_name.to_sym).dispatch_original_method(subject, arguments, keyword_arguments, block)
43
48
  end
44
49
  end
45
50
 
@@ -91,7 +96,9 @@ module RR
91
96
 
92
97
  attr_reader :subject_class, :method_name, :doubles
93
98
 
94
- MethodArguments = Struct.new(:arguments, :block)
99
+ MethodArguments = Struct.new(:arguments,
100
+ :keyword_arguments,
101
+ :block)
95
102
 
96
103
  def initialize(subject_class, method_name)
97
104
  @subject_class = subject_class
@@ -111,7 +118,11 @@ module RR
111
118
  # is called.
112
119
  def bind
113
120
  if subject_has_method_defined?(method_name)
114
- bind_method_with_alias
121
+ if subject_has_original_method?
122
+ bind_method
123
+ else
124
+ bind_method_with_alias
125
+ end
115
126
  else
116
127
  Injections::MethodMissingInjection.find_or_create(subject_class)
117
128
  Injections::SingletonMethodAddedInjection.find_or_create(subject_class)
@@ -126,14 +137,25 @@ module RR
126
137
  id = BoundObjects.size
127
138
  BoundObjects[id] = subject_class
128
139
 
129
- subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
130
- def #{method_name}(*args, &block)
131
- ::RR::Injections::DoubleInjection::BoundObjects[#{id}].class_eval do
132
- remove_method(:#{method_name})
140
+ if KeywordArguments.fully_supported?
141
+ subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
142
+ def #{method_name}(*args, **kwargs, &block)
143
+ ::RR::Injections::DoubleInjection::BoundObjects[#{id}].class_eval do
144
+ remove_method(:#{method_name})
145
+ end
146
+ method_missing(:#{method_name}, *args, **kwargs, &block)
133
147
  end
134
- method_missing(:#{method_name}, *args, &block)
135
- end
136
- RUBY
148
+ RUBY
149
+ else
150
+ subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
151
+ def #{method_name}(*args, &block)
152
+ ::RR::Injections::DoubleInjection::BoundObjects[#{id}].class_eval do
153
+ remove_method(:#{method_name})
154
+ end
155
+ method_missing(:#{method_name}, *args, &block)
156
+ end
157
+ RUBY
158
+ end
137
159
  self
138
160
  end
139
161
 
@@ -141,13 +163,37 @@ module RR
141
163
  id = BoundObjects.size
142
164
  BoundObjects[id] = subject_class
143
165
 
144
- subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
145
- def #{method_name}(*args, &block)
146
- arguments = MethodArguments.new(args, block)
147
- obj = ::RR::Injections::DoubleInjection::BoundObjects[#{id}]
148
- ::RR::Injections::DoubleInjection.dispatch_method(self, obj, :#{method_name}, arguments.arguments, arguments.block)
149
- end
150
- RUBY
166
+ if KeywordArguments.fully_supported?
167
+ subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
168
+ def #{method_name}(*args, **kwargs, &block)
169
+ arguments = MethodArguments.new(args, kwargs, block)
170
+ obj = ::RR::Injections::DoubleInjection::BoundObjects[#{id}]
171
+ ::RR::Injections::DoubleInjection.dispatch_method(
172
+ self,
173
+ obj,
174
+ :#{method_name},
175
+ arguments.arguments,
176
+ arguments.keyword_arguments,
177
+ arguments.block
178
+ )
179
+ end
180
+ RUBY
181
+ else
182
+ subject_class.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
183
+ def #{method_name}(*args, &block)
184
+ arguments = MethodArguments.new(args, {}, block)
185
+ obj = ::RR::Injections::DoubleInjection::BoundObjects[#{id}]
186
+ ::RR::Injections::DoubleInjection.dispatch_method(
187
+ self,
188
+ obj,
189
+ :#{method_name},
190
+ arguments.arguments,
191
+ arguments.keyword_arguments,
192
+ arguments.block
193
+ )
194
+ end
195
+ RUBY
196
+ end
151
197
  self
152
198
  end
153
199
 
@@ -175,17 +221,29 @@ module RR
175
221
  end
176
222
  end
177
223
 
178
- def dispatch_method(subject, args, block)
224
+ def dispatch_method(subject, args, kwargs, block)
179
225
  if @dispatch_method_delegates_to_dispatch_original_method
180
- dispatch_original_method(subject, args, block)
226
+ dispatch_original_method(subject, args, kwargs, block)
181
227
  else
182
- dispatch = MethodDispatches::MethodDispatch.new(self, subject, args, block)
228
+ dispatch = MethodDispatches::MethodDispatch.new(
229
+ self,
230
+ subject,
231
+ args,
232
+ kwargs,
233
+ block
234
+ )
183
235
  dispatch.call
184
236
  end
185
237
  end
186
238
 
187
- def dispatch_original_method(subject, args, block)
188
- dispatch = MethodDispatches::MethodDispatch.new(self, subject, args, block)
239
+ def dispatch_original_method(subject, args, kwargs, block)
240
+ dispatch = MethodDispatches::MethodDispatch.new(
241
+ self,
242
+ subject,
243
+ args,
244
+ kwargs,
245
+ block
246
+ )
189
247
  dispatch.call_original_method
190
248
  end
191
249
 
@@ -206,7 +264,8 @@ module RR
206
264
 
207
265
  protected
208
266
  def deferred_bind_method
209
- unless subject_has_method_defined?(original_method_alias_name)
267
+ if respond_to?(method_name) and
268
+ not subject_has_method_defined?(original_method_alias_name)
210
269
  bind_method_with_alias
211
270
  end
212
271
  @performed_deferred_bind = true
@@ -71,12 +71,43 @@ module RR
71
71
  id = BoundObjects.size
72
72
  BoundObjects[id] = subject_class
73
73
 
74
- subject_class.class_eval((<<-METHOD), __FILE__, __LINE__ + 1)
75
- def method_missing(method_name, *args, &block)
76
- obj = ::RR::Injections::MethodMissingInjection::BoundObjects[#{id}]
77
- MethodDispatches::MethodMissingDispatch.new(self, obj, method_name, args, block).call
78
- end
79
- METHOD
74
+ if KeywordArguments.fully_supported?
75
+ subject_class.class_eval((<<-METHOD), __FILE__, __LINE__ + 1)
76
+ def method_missing(method_name, *args, **kwargs, &block)
77
+ if respond_to_missing?(method_name, true)
78
+ super(method_name, *args, **kwargs, &block)
79
+ else
80
+ obj = ::RR::Injections::MethodMissingInjection::BoundObjects[#{id}]
81
+ MethodDispatches::MethodMissingDispatch.new(
82
+ self,
83
+ obj,
84
+ method_name,
85
+ args,
86
+ kwargs,
87
+ block
88
+ ).call
89
+ end
90
+ end
91
+ METHOD
92
+ else
93
+ subject_class.class_eval((<<-METHOD), __FILE__, __LINE__ + 1)
94
+ def method_missing(method_name, *args, &block)
95
+ if respond_to_missing?(method_name, true)
96
+ super(method_name, *args, &block)
97
+ else
98
+ obj = ::RR::Injections::MethodMissingInjection::BoundObjects[#{id}]
99
+ MethodDispatches::MethodMissingDispatch.new(
100
+ self,
101
+ obj,
102
+ method_name,
103
+ args,
104
+ {},
105
+ block
106
+ ).call
107
+ end
108
+ end
109
+ METHOD
110
+ end
80
111
  end
81
112
 
82
113
  def original_method_alias_name
@@ -36,7 +36,7 @@ module RR
36
36
  def hook
37
37
  assertion_error_class = self.assertion_error_class
38
38
  test_case_class.class_eval do
39
- include RR::Adapters::RRMethods
39
+ include RR::DSL
40
40
  include Mixin
41
41
 
42
42
  unless instance_methods.any? { |method_name| method_name.to_sym == :setup_with_rr }
@@ -20,7 +20,7 @@ module RR
20
20
  def hook
21
21
  parent_adapter_class = self.parent_adapter_class
22
22
  ::ActiveSupport::TestCase.class_eval do
23
- include RR::Adapters::RRMethods
23
+ include RR::DSL
24
24
  include parent_adapter_class::Mixin
25
25
 
26
26
  setup do
@@ -37,11 +37,3 @@ module RR
37
37
  end
38
38
  end
39
39
  end
40
-
41
- module RR
42
- module Adapters
43
- module Rspec
44
- InvocationMatcher = RR::Integrations::RSpec::InvocationMatcher
45
- end
46
- end
47
- end
@@ -1,6 +1,24 @@
1
1
  module RR
2
2
  module Integrations
3
- class RSpec2 < RSpec1
3
+ class RSpec2
4
+ module Mixin
5
+ def setup_mocks_for_rspec
6
+ RR.reset
7
+ end
8
+
9
+ def verify_mocks_for_rspec
10
+ RR.verify
11
+ end
12
+
13
+ def teardown_mocks_for_rspec
14
+ RR.reset
15
+ end
16
+
17
+ def have_received(method = nil)
18
+ RSpec::InvocationMatcher.new(method)
19
+ end
20
+ end
21
+
4
22
  def name
5
23
  'RSpec 2'
6
24
  end
@@ -14,7 +32,7 @@ module RR
14
32
  def hook
15
33
  ::RSpec.configure do |config|
16
34
  config.mock_with Mixin
17
- config.include RR::Adapters::RRMethods
35
+ config.include RR::DSL
18
36
  end
19
37
 
20
38
  patterns =
@@ -0,0 +1,15 @@
1
+ module RR
2
+ module KeywordArguments
3
+ class << self
4
+ if (RUBY_VERSION <=> "2.7.0") >= 0
5
+ def fully_supported?
6
+ true
7
+ end
8
+ else
9
+ def fully_supported?
10
+ false
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,7 +4,7 @@ module RR
4
4
  extend Forwardable
5
5
  include Space::Reader
6
6
 
7
- attr_reader :args, :block, :double
7
+ attr_reader :args, :kwargs, :block, :double
8
8
 
9
9
  def call
10
10
  raise NotImplementedError
@@ -12,7 +12,7 @@ module RR
12
12
 
13
13
  protected
14
14
  def find_double_to_attempt
15
- matches = DoubleMatches.new(doubles).find_all_matches(args)
15
+ matches = DoubleMatches.new(doubles).find_all_matches(args, kwargs)
16
16
 
17
17
  unless matches.exact_terminal_doubles_to_attempt.empty?
18
18
  return matches.exact_terminal_doubles_to_attempt.first
@@ -47,8 +47,25 @@ module RR
47
47
  end
48
48
  end
49
49
 
50
- def call_original_method_missing
51
- subject.__send__(MethodMissingDispatch.original_method_missing_alias_name, method_name, *args, &block)
50
+ if KeywordArguments.fully_supported?
51
+ def call_original_method_missing
52
+ subject.__send__(
53
+ MethodMissingDispatch.original_method_missing_alias_name,
54
+ method_name,
55
+ *args,
56
+ **kwargs,
57
+ &block
58
+ )
59
+ end
60
+ else
61
+ def call_original_method_missing
62
+ subject.__send__(
63
+ MethodMissingDispatch.original_method_missing_alias_name,
64
+ method_name,
65
+ *args,
66
+ &block
67
+ )
68
+ end
52
69
  end
53
70
 
54
71
  def implementation_is_original_method?
@@ -70,7 +87,7 @@ module RR
70
87
  message =
71
88
  "On subject #{subject},\n" <<
72
89
  "unexpected method invocation:\n" <<
73
- " #{Double.formatted_name(method_name, args)}\n" <<
90
+ " #{Double.formatted_name(method_name, args, kwargs)}\n" <<
74
91
  "expected invocations:\n" <<
75
92
  Double.list_message_part(doubles)
76
93
  raise RR::Errors.build_error(:DoubleNotFoundError, message)