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
data/lib/rr/double.rb CHANGED
@@ -4,14 +4,20 @@ module RR
4
4
  # and the implementation.
5
5
  class Double
6
6
  extend(Module.new do
7
- def formatted_name(method_name, args)
8
- formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
7
+ def formatted_name(method_name, args, kwargs)
8
+ formatted_arguments =
9
+ args.collect {|arg| arg.inspect} +
10
+ kwargs.collect {|keyword, value| "#{keyword}: #{value.inspect}"}
11
+ formatted_errors = formatted_arguments.join(', ')
9
12
  "#{method_name}(#{formatted_errors})"
10
13
  end
11
14
 
12
15
  def list_message_part(doubles)
13
16
  doubles.collect do |double|
14
- "- #{formatted_name(double.method_name, double.expected_arguments)}"
17
+ name = formatted_name(double.method_name,
18
+ double.expected_arguments,
19
+ double.expected_keyword_arguments)
20
+ "- #{name}"
15
21
  end.join("\n")
16
22
  end
17
23
  end)
@@ -32,14 +38,14 @@ module RR
32
38
 
33
39
  # Double#exact_match? returns true when the passed in arguments
34
40
  # exactly match the ArgumentEqualityExpectation arguments.
35
- def exact_match?(*arguments)
36
- definition.exact_match?(*arguments)
41
+ def exact_match?(arguments, keyword_arguments)
42
+ definition.exact_match?(arguments, keyword_arguments)
37
43
  end
38
44
 
39
45
  # Double#wildcard_match? returns true when the passed in arguments
40
46
  # wildcard match the ArgumentEqualityExpectation arguments.
41
- def wildcard_match?(*arguments)
42
- definition.wildcard_match?(*arguments)
47
+ def wildcard_match?(arguments, keyword_arguments)
48
+ definition.wildcard_match?(arguments, keyword_arguments)
43
49
  end
44
50
 
45
51
  # Double#attempt? returns true when the
@@ -74,18 +80,26 @@ module RR
74
80
  argument_expectation.expected_arguments
75
81
  end
76
82
 
83
+ # The keyword arguments that this Double expects
84
+ def expected_keyword_arguments
85
+ verify_argument_expectation_is_set
86
+ argument_expectation.expected_keyword_arguments
87
+ end
88
+
77
89
  # The TimesCalledMatcher for the TimesCalledExpectation
78
90
  def times_matcher
79
91
  definition.times_matcher
80
92
  end
81
93
 
82
94
  def formatted_name
83
- self.class.formatted_name(method_name, expected_arguments)
95
+ self.class.formatted_name(method_name,
96
+ expected_arguments,
97
+ expected_keyword_arguments)
84
98
  end
85
99
 
86
- def method_call(args)
100
+ def method_call(args, kwargs)
87
101
  if verbose?
88
- puts Double.formatted_name(method_name, args)
102
+ puts Double.formatted_name(method_name, args, kwargs)
89
103
  end
90
104
  times_called_expectation.attempt if definition.times_matcher
91
105
  space.verify_ordered_double(self) if ordered?
@@ -148,6 +162,10 @@ module RR
148
162
  definition.argument_expectation.expected_arguments
149
163
  end
150
164
 
165
+ def kwargs
166
+ definition.argument_expectation.expected_keyword_arguments
167
+ end
168
+
151
169
  def argument_expectation
152
170
  definition.argument_expectation
153
171
  end
@@ -36,16 +36,26 @@ module RR
36
36
  end
37
37
 
38
38
  module ArgumentDefinitionConstructionMethods
39
- # Double#with sets the expectation that the Double will receive
40
- # the passed in arguments.
41
- #
42
- # Passing in a block sets the return value.
43
- #
44
- # mock(subject).method_name.with(1, 2) {:return_value}
45
- def with(*args, &return_value_block)
46
- @argument_expectation = Expectations::ArgumentEqualityExpectation.new(*args)
47
- install_method_callback return_value_block
48
- self
39
+ if KeywordArguments.fully_supported?
40
+ # Double#with sets the expectation that the Double will receive
41
+ # the passed in arguments.
42
+ #
43
+ # Passing in a block sets the return value.
44
+ #
45
+ # mock(subject).method_name.with(1, 2) {:return_value}
46
+ def with(*args, **kwargs, &return_value_block)
47
+ @argument_expectation =
48
+ Expectations::ArgumentEqualityExpectation.new(args, kwargs)
49
+ install_method_callback return_value_block
50
+ self
51
+ end
52
+ else
53
+ def with(*args, &return_value_block)
54
+ @argument_expectation =
55
+ Expectations::ArgumentEqualityExpectation.new(args, {})
56
+ install_method_callback return_value_block
57
+ self
58
+ end
49
59
  end
50
60
 
51
61
  # Double#with_any_args sets the expectation that the Double can receive
@@ -67,7 +77,8 @@ module RR
67
77
  #
68
78
  # mock(subject).method_name.with_no_args {:return_value}
69
79
  def with_no_args(&return_value_block)
70
- @argument_expectation = Expectations::ArgumentEqualityExpectation.new()
80
+ @argument_expectation =
81
+ Expectations::ArgumentEqualityExpectation.new([], {})
71
82
  install_method_callback return_value_block
72
83
  self
73
84
  end
@@ -298,18 +309,18 @@ module RR
298
309
  @verbose ? true : false
299
310
  end
300
311
 
301
- def exact_match?(*arguments)
312
+ def exact_match?(arguments, keyword_arguments)
302
313
  unless @argument_expectation
303
314
  raise RR::Errors.build_error(:DoubleDefinitionError, "#argument_expectation must be defined on #{inspect}")
304
315
  end
305
- @argument_expectation.exact_match?(*arguments)
316
+ @argument_expectation.exact_match?(arguments, keyword_arguments)
306
317
  end
307
318
 
308
- def wildcard_match?(*arguments)
319
+ def wildcard_match?(arguments, keyword_arguments)
309
320
  unless @argument_expectation
310
321
  raise RR::Errors.build_error(:DoubleDefinitionError, "#argument_expectation must be defined on #{inspect}")
311
322
  end
312
- @argument_expectation.wildcard_match?(*arguments)
323
+ @argument_expectation.wildcard_match?(arguments, keyword_arguments)
313
324
  end
314
325
 
315
326
  def terminal?
@@ -320,7 +331,19 @@ module RR
320
331
  end
321
332
 
322
333
  def expected_arguments
323
- argument_expectation ? argument_expectation.expected_arguments : []
334
+ if argument_expectation
335
+ argument_expectation.expected_arguments
336
+ else
337
+ []
338
+ end
339
+ end
340
+
341
+ def expected_keyword_arguments
342
+ if argument_expectation
343
+ argument_expectation.expected_keyword_arguments
344
+ else
345
+ {}
346
+ end
324
347
  end
325
348
 
326
349
  def implementation_is_original_method?
@@ -30,11 +30,11 @@ module RR
30
30
  @double_injection_strategy = self.class.default_double_injection_strategy.call(self)
31
31
  end
32
32
 
33
- def call(method_name, *args, &handler)
33
+ def call(method_name, args, kwargs, &handler)
34
34
  definition = DoubleDefinition.new(self)
35
- verification_strategy.call(definition, method_name, args, handler)
36
- implementation_strategy.call(definition, method_name, args, handler)
37
- double_injection_strategy.call(definition, method_name, args, handler)
35
+ verification_strategy.call(definition, method_name, args, kwargs, handler)
36
+ implementation_strategy.call(definition, method_name, args, kwargs, handler)
37
+ double_injection_strategy.call(definition, method_name, args, kwargs, handler)
38
38
  definition
39
39
  end
40
40
 
@@ -81,7 +81,7 @@ module RR
81
81
  self
82
82
  elsif method_name
83
83
  # TODO: Pass in arguments.
84
- call(method_name)
84
+ call(method_name, [], {})
85
85
  else
86
86
  DoubleDefinitionCreateBlankSlate.new(self, &definition_eval_block)
87
87
  end
@@ -14,13 +14,19 @@ module RR
14
14
  end
15
15
  end
16
16
 
17
- def method_missing(method_name, *args, &block)
18
- @double_definition_create.call(method_name, *args, &block)
17
+ if KeywordArguments.fully_supported?
18
+ def method_missing(method_name, *args, **kwargs, &block)
19
+ @double_definition_create.call(method_name, args, kwargs, &block)
20
+ end
21
+ else
22
+ def method_missing(method_name, *args, &block)
23
+ @double_definition_create.call(method_name, args, {}, &block)
24
+ end
19
25
  end
20
26
 
21
27
  def __double_definition_create__
22
28
  @double_definition_create
23
29
  end
24
- end
30
+ end
25
31
  end
26
- end
32
+ end
@@ -3,7 +3,7 @@ module RR
3
3
  module DoubleInjections
4
4
  class AnyInstanceOf
5
5
  extend(Module.new do
6
- include RR::Adapters::RRMethods
6
+ include RR::DSL
7
7
 
8
8
  def call(subject_class, stubbed_methods=nil, &block)
9
9
  strategy_lambda = lambda do |double_definition_create|
@@ -3,7 +3,7 @@ module RR
3
3
  module DoubleInjections
4
4
  class Instance
5
5
  extend(Module.new do
6
- include ::RR::Adapters::RRMethods
6
+ include ::RR::DSL
7
7
 
8
8
  def call(double_method_name, *args, &definition_eval_block)
9
9
  double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
@@ -13,4 +13,4 @@ module RR
13
13
  end
14
14
  end
15
15
  end
16
- end
16
+ end
@@ -2,7 +2,12 @@ module RR
2
2
  module DoubleDefinitions
3
3
  module Strategies
4
4
  class Strategy
5
- attr_reader :double_definition_create, :definition, :method_name, :args, :handler
5
+ attr_reader :double_definition_create
6
+ attr_reader :definition
7
+ attr_reader :method_name
8
+ attr_reader :args
9
+ attr_reader :kwargs
10
+ attr_reader :handler
6
11
 
7
12
  include Space::Reader
8
13
 
@@ -10,8 +15,12 @@ module RR
10
15
  @double_definition_create = double_definition_create
11
16
  end
12
17
 
13
- def call(definition, method_name, args, handler)
14
- @definition, @method_name, @args, @handler = definition, method_name, args, handler
18
+ def call(definition, method_name, args, kwargs, handler)
19
+ @definition = definition
20
+ @method_name = method_name
21
+ @args = args
22
+ @kwargs = kwargs
23
+ @handler = handler
15
24
  do_call
16
25
  end
17
26
 
@@ -23,11 +32,21 @@ module RR
23
32
  raise NotImplementedError
24
33
  end
25
34
 
26
- def permissive_argument
27
- if args.empty?
28
- definition.with_any_args
29
- else
30
- definition.with(*args)
35
+ if KeywordArguments.fully_supported?
36
+ def permissive_argument
37
+ if args.empty? and kwargs.empty?
38
+ definition.with_any_args
39
+ else
40
+ definition.with(*args, **kwargs)
41
+ end
42
+ end
43
+ else
44
+ def permissive_argument
45
+ if args.empty?
46
+ definition.with_any_args
47
+ else
48
+ definition.with(*args)
49
+ end
31
50
  end
32
51
  end
33
52
 
@@ -32,8 +32,14 @@ module RR
32
32
  # end
33
33
  class Mock < VerificationStrategy
34
34
  protected
35
- def do_call
36
- definition.with(*args).once
35
+ if KeywordArguments.fully_supported?
36
+ def do_call
37
+ definition.with(*args, **kwargs).once
38
+ end
39
+ else
40
+ def do_call
41
+ definition.with(*args).once
42
+ end
37
43
  end
38
44
  end
39
45
  end
@@ -15,9 +15,10 @@ module RR
15
15
  @wildcard_non_terminal_doubles_to_attempt = []
16
16
  end
17
17
 
18
- def find_all_matches(args)
18
+ def find_all_matches(args, kwargs)
19
+ kwargs ||= {}
19
20
  @doubles.each do |double|
20
- if double.exact_match?(*args)
21
+ if double.exact_match?(args, kwargs)
21
22
  matching_doubles << double
22
23
  if double.attempt?
23
24
  if double.terminal?
@@ -26,7 +27,7 @@ module RR
26
27
  exact_non_terminal_doubles_to_attempt << double
27
28
  end
28
29
  end
29
- elsif double.wildcard_match?(*args)
30
+ elsif double.wildcard_match?(args, kwargs)
30
31
  matching_doubles << double
31
32
  if double.attempt?
32
33
  if double.terminal?
data/lib/rr/dsl.rb ADDED
@@ -0,0 +1,152 @@
1
+ module RR
2
+ module DSL
3
+ METHODS_TO_EXCLUDE_FROM_SPYING = [
4
+ :methods,
5
+ :==,
6
+ :__send__,
7
+ :__id__,
8
+ :object_id,
9
+ :class,
10
+ :respond_to?,
11
+ :inspect,
12
+ :to_s,
13
+ :respond_to_missing?,
14
+ :instance_eval,
15
+ :instance_exec
16
+ ]
17
+
18
+ include DoubleDefinitions::Strategies::StrategyMethods
19
+
20
+ def mock(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
21
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
22
+ double_definition_create.mock(subject, method_name, &definition_eval_block)
23
+ end
24
+
25
+ def stub(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
26
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
27
+ double_definition_create.stub(subject, method_name, &definition_eval_block)
28
+ end
29
+
30
+ def dont_allow(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
31
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
32
+ double_definition_create.dont_allow(subject, method_name, &definition_eval_block)
33
+ end
34
+
35
+ def proxy(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
36
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
37
+ double_definition_create.proxy(subject, method_name, &definition_eval_block)
38
+ end
39
+
40
+ def strong(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
41
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
42
+ double_definition_create.strong(subject, method_name, &definition_eval_block)
43
+ end
44
+
45
+ def instance_of(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
46
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
47
+ double_definition_create.instance_of(subject, method_name, &definition_eval_block)
48
+ end
49
+
50
+ def any_instance_of(*args, &block)
51
+ RR::DoubleDefinitions::DoubleInjections::AnyInstanceOf.call(*args, &block)
52
+ end
53
+
54
+ # Verifies all the DoubleInjection objects have met their
55
+ # TimesCalledExpectations.
56
+ def verify
57
+ RR::Space.instance.verify_doubles
58
+ end
59
+
60
+ # Resets the registered Doubles and ordered Doubles
61
+ def reset
62
+ RR::Space.instance.reset
63
+ end
64
+
65
+ # Returns a AnyTimesMatcher. This is meant to be passed in as an argument
66
+ # to Double#times.
67
+ #
68
+ # mock(object).method_name(anything).times(any_times) {return_value}
69
+ def any_times
70
+ TimesCalledMatchers::AnyTimesMatcher.new
71
+ end
72
+
73
+ # Sets up an Anything wildcard ArgumentEqualityExpectation
74
+ # that succeeds when passed any argument.
75
+ # mock(object).method_name(anything) {return_value}
76
+ # object.method_name("an arbitrary value") # passes
77
+ def anything
78
+ RR::WildcardMatchers::Anything.new
79
+ end
80
+
81
+ # Sets up an IsA wildcard ArgumentEqualityExpectation
82
+ # that succeeds when passed an argument of a certain type.
83
+ # mock(object).method_name(is_a(String)) {return_value}
84
+ # object.method_name("A String") # passes
85
+ def is_a(klass)
86
+ RR::WildcardMatchers::IsA.new(klass)
87
+ end
88
+
89
+ # Sets up an Numeric wildcard ArgumentEqualityExpectation
90
+ # that succeeds when passed an argument that is ::Numeric.
91
+ # mock(object).method_name(numeric) {return_value}
92
+ # object.method_name(99) # passes
93
+ def numeric
94
+ RR::WildcardMatchers::Numeric.new
95
+ end
96
+
97
+ # Sets up an Boolean wildcard ArgumentEqualityExpectation
98
+ # that succeeds when passed an argument that is a ::Boolean.
99
+ # mock(object).method_name(boolean) {return_value}
100
+ # object.method_name(false) # passes
101
+ def boolean
102
+ RR::WildcardMatchers::Boolean.new
103
+ end
104
+
105
+ # Sets up a DuckType wildcard ArgumentEqualityExpectation
106
+ # that succeeds when the passed argument implements the methods.
107
+ # arg = Object.new
108
+ # def arg.foo; end
109
+ # def arg.bar; end
110
+ # mock(object).method_name(duck_type(:foo, :bar)) {return_value}
111
+ # object.method_name(arg) # passes
112
+ def duck_type(*args)
113
+ RR::WildcardMatchers::DuckType.new(*args)
114
+ end
115
+
116
+ # Sets up a HashIncluding wildcard ArgumentEqualityExpectation
117
+ # that succeeds when the passed argument contains at least those keys
118
+ # and values of the expectation.
119
+ # mock(object).method_name(hash_including(:foo => 1)) {return_value}
120
+ # object.method_name({:foo => 1, :bar => 2) # passes
121
+ def hash_including(expected_hash)
122
+ RR::WildcardMatchers::HashIncluding.new(expected_hash)
123
+ end
124
+
125
+ # Sets up a Satisfy wildcard ArgumentEqualityExpectation
126
+ # that succeeds when the passed argument causes the expectation's
127
+ # proc to return true.
128
+ # mock(object).method_name(satisfy {|arg| arg == :foo}) {return_value}
129
+ # object.method_name(:foo) # passes
130
+ def satisfy(expectation_proc=nil, &block)
131
+ expectation_proc ||= block
132
+ RR::WildcardMatchers::Satisfy.new(expectation_proc)
133
+ end
134
+
135
+ def spy(subject)
136
+ subject_methods = subject.public_methods.map {|method_name| method_name.to_sym }
137
+ methods_to_stub = subject_methods - METHODS_TO_EXCLUDE_FROM_SPYING
138
+
139
+ methods_to_stub.each do |method|
140
+ stub.proxy(subject, method)
141
+ end
142
+ end
143
+
144
+ def received(subject)
145
+ RR::SpyVerificationProxy.new(subject)
146
+ end
147
+
148
+ instance_methods.each do |name|
149
+ alias_method "rr_#{name}", name
150
+ end
151
+ end
152
+ end