rr 0.10.11 → 1.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 (57) hide show
  1. data/CHANGES +5 -0
  2. data/Gemfile +6 -0
  3. data/README.rdoc +28 -2
  4. data/VERSION.yml +3 -3
  5. data/lib/rr.rb +23 -17
  6. data/lib/rr/adapters/rr_methods.rb +43 -17
  7. data/lib/rr/blank_slate.rb +2 -2
  8. data/lib/rr/class_instance_method_defined.rb +9 -0
  9. data/lib/rr/double.rb +2 -2
  10. data/lib/rr/double_definitions/double_definition.rb +29 -16
  11. data/lib/rr/double_definitions/double_definition_create.rb +52 -86
  12. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +28 -0
  13. data/lib/rr/double_definitions/double_injections/instance.rb +16 -0
  14. data/lib/rr/double_definitions/double_injections/new_instance_of.rb +53 -0
  15. data/lib/rr/double_definitions/strategies/double_injection/any_instance_of.rb +31 -0
  16. data/lib/rr/double_definitions/strategies/double_injection/double_injection_strategy.rb +10 -0
  17. data/lib/rr/double_definitions/strategies/double_injection/instance.rb +17 -0
  18. data/lib/rr/double_definitions/strategies/double_injection/new_instance_of.rb +37 -0
  19. data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +0 -5
  20. data/lib/rr/double_definitions/strategies/implementation/proxy.rb +0 -2
  21. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +0 -2
  22. data/lib/rr/double_definitions/strategies/strategy.rb +0 -27
  23. data/lib/rr/double_definitions/strategies/strategy_methods.rb +53 -0
  24. data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +0 -2
  25. data/lib/rr/double_definitions/strategies/verification/mock.rb +0 -2
  26. data/lib/rr/double_definitions/strategies/verification/stub.rb +0 -2
  27. data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +0 -5
  28. data/lib/rr/hash_with_object_id_key.rb +4 -0
  29. data/lib/rr/injections/double_injection.rb +94 -71
  30. data/lib/rr/injections/injection.rb +8 -10
  31. data/lib/rr/injections/method_missing_injection.rb +13 -20
  32. data/lib/rr/injections/singleton_method_added_injection.rb +19 -17
  33. data/lib/rr/method_dispatches/base_method_dispatch.rb +1 -1
  34. data/lib/rr/method_dispatches/method_dispatch.rb +4 -4
  35. data/lib/rr/method_dispatches/method_missing_dispatch.rb +17 -14
  36. data/lib/rr/recorded_calls.rb +1 -1
  37. data/lib/rr/space.rb +6 -6
  38. data/lib/rr/times_called_matchers/times_called_matcher.rb +2 -2
  39. data/scratch.rb +118 -0
  40. data/spec/api/any_instance_of/all_instances_of_spec.rb +14 -0
  41. data/spec/api/any_instance_of/any_instance_of_spec.rb +47 -0
  42. data/spec/api/mock/mock_spec.rb +2 -2
  43. data/spec/api/new_instance_of/instance_of_spec.rb +15 -0
  44. data/spec/api/new_instance_of/new_instance_of_spec.rb +61 -0
  45. data/spec/environment_fixture_setup.rb +3 -2
  46. data/spec/rr/adapters/rr_methods_space_spec.rb +8 -10
  47. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +1 -1
  48. data/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb +6 -2
  49. data/spec/rr/double_definitions/double_definition_create_spec.rb +1 -52
  50. data/spec/rr/double_injection/double_injection_verify_spec.rb +1 -1
  51. data/spec/rr/rspec/rspec_adapter_spec.rb +5 -5
  52. data/spec/rr/space/space_spec.rb +58 -67
  53. data/spec/spec_helper.rb +2 -2
  54. metadata +33 -9
  55. data/lib/rr/double_definitions/strategies/scope/instance.rb +0 -15
  56. data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +0 -50
  57. data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +0 -15
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 1.0.0
2
+ - Added any_instance_of (aliased by all_instances_of), which binds methods directly to the class (instead of the eigenclass).
3
+ - Subclasses of a injected class do not have their methods overridden.
4
+ - any_instance_of and new_instance_of now have a block syntax
5
+
1
6
  0.10.11
2
7
  - Added RR.blank_slate_whitelist
3
8
  - Fixed class_eval method redefinition warning in jruby
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ group :test do
2
+ gem "rspec", "1.3.0"
3
+ gem "session", "2.4.0"
4
+ gem "diff-lcs", "1.1.2"
5
+ gem "ruby-debug", "0.10.3"
6
+ end
@@ -213,9 +213,33 @@ renders the partial.
213
213
  html
214
214
  end
215
215
 
216
- === instance_of
217
- Put double scenarios on instances of a Class.
216
+ === any_instance_of
217
+ Allows stubs to be added to all instances of a class. It works by binding to methods from the class itself, rather than the eigenclass.
218
+ This allows all instances (excluding instances with the method redefined in the eigenclass) to get the change.
218
219
 
220
+ Due to Ruby runtime limitations, mocks will not work as expected. It's not obviously feasible (without an ObjectSpace lookup) to support all of RR's methods (such as mocking).
221
+ ObjectSpace is not readily supported in jRuby, since it causes general slowness in the intreperter.
222
+ I'm of the opinion that test speed is more important than having mocks on all instances of a class.
223
+ If there is another solution, I'd be willing to add it.
224
+
225
+ any_instance_of(User) do |u|
226
+ stub(u).valid? {false}
227
+ end
228
+ # or
229
+ any_instance_of(User, :valid? => false)
230
+ # or
231
+ any_instance_of(User, :valid? => lambda {false})
232
+
233
+ === new_instance_of
234
+ Stubs the new method of the class and allows doubles to be bound to new instances.
235
+
236
+ Mocks can be used, because new instances are deterministically bound.
237
+
238
+ new_instance_of(User) do |u|
239
+ mock(u).valid? {false}
240
+ end
241
+
242
+ # Deprecated syntax
219
243
  mock.instance_of(User).valid? {false}
220
244
 
221
245
  === Spies
@@ -338,7 +362,9 @@ If you have directly contributed to RR and I missed you in this list, please let
338
362
  * Dave Myron for a bug report
339
363
  * David Chelimsky for encouragement to make the RR framework, for developing the Rspec mock framework, syntax ideas, and patches
340
364
  * Daniel Sudol for identifing performance issues with RR
365
+ * Dmitry Ratnikov for patches
341
366
  * Felix Morio for pairing with me
367
+ * Gabriel Horner for patches
342
368
  * Gerard Meszaros for his excellent book "xUnit Test Patterns"
343
369
  * James Mead for developing Mocha
344
370
  * Jeff Whitmire for documentation suggestions
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :build:
3
- :minor: 10
4
- :patch: 11
5
- :major: 0
3
+ :minor: 0
4
+ :patch: 0
5
+ :major: 1
data/lib/rr.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  dir = File.dirname(__FILE__)
2
- require 'rubygems'
3
2
  require 'forwardable'
4
3
 
5
4
  require "#{dir}/rr/blank_slate"
@@ -17,6 +16,27 @@ require "#{dir}/rr/errors/spy_verification_errors/double_injection_not_found_err
17
16
  require "#{dir}/rr/errors/spy_verification_errors/invocation_count_error"
18
17
 
19
18
  require "#{dir}/rr/space"
19
+
20
+ require "#{dir}/rr/double_definitions/strategies/strategy"
21
+ require "#{dir}/rr/double_definitions/strategies/strategy_methods"
22
+ require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
23
+ require "#{dir}/rr/double_definitions/strategies/verification/mock"
24
+ require "#{dir}/rr/double_definitions/strategies/verification/stub"
25
+ require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
26
+ require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
27
+ require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
28
+ require "#{dir}/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation"
29
+ require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
30
+ require "#{dir}/rr/double_definitions/strategies/double_injection/double_injection_strategy"
31
+ require "#{dir}/rr/double_definitions/strategies/double_injection/instance"
32
+ require "#{dir}/rr/double_definitions/strategies/double_injection/any_instance_of"
33
+ require "#{dir}/rr/double_definitions/strategies/double_injection/new_instance_of"
34
+ require "#{dir}/rr/adapters/rr_methods"
35
+ require "#{dir}/rr/double_definitions/double_injections/instance"
36
+ require "#{dir}/rr/double_definitions/double_injections/any_instance_of"
37
+ require "#{dir}/rr/double_definitions/double_injections/new_instance_of"
38
+ require "#{dir}/rr/double_definitions/double_definition"
39
+
20
40
  require "#{dir}/rr/injections/injection"
21
41
  require "#{dir}/rr/injections/double_injection"
22
42
  require "#{dir}/rr/injections/method_missing_injection"
@@ -27,26 +47,13 @@ require "#{dir}/rr/method_dispatches/method_missing_dispatch"
27
47
  require "#{dir}/rr/hash_with_object_id_key"
28
48
  require "#{dir}/rr/recorded_calls"
29
49
  require "#{dir}/rr/proc_from_block"
50
+ require "#{dir}/rr/class_instance_method_defined"
30
51
 
31
52
  require "#{dir}/rr/double_definitions/double_definition_create_blank_slate"
32
53
  require "#{dir}/rr/double_definitions/double_definition_create"
33
54
  require "#{dir}/rr/double_definitions/child_double_definition_create"
34
- require "#{dir}/rr/adapters/rr_methods"
35
55
 
36
56
  require "#{dir}/rr/double"
37
- require "#{dir}/rr/double_definitions/double_definition"
38
- require "#{dir}/rr/double_definitions/strategies/strategy"
39
- require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
40
- require "#{dir}/rr/double_definitions/strategies/verification/mock"
41
- require "#{dir}/rr/double_definitions/strategies/verification/stub"
42
- require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
43
- require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
44
- require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
45
- require "#{dir}/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation"
46
- require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
47
- require "#{dir}/rr/double_definitions/strategies/scope/scope_strategy"
48
- require "#{dir}/rr/double_definitions/strategies/scope/instance"
49
- require "#{dir}/rr/double_definitions/strategies/scope/instance_of_class"
50
57
  require "#{dir}/rr/double_matches"
51
58
 
52
59
  require "#{dir}/rr/expectations/argument_equality_expectation"
@@ -84,12 +91,11 @@ module RR
84
91
  class << self
85
92
  include Adapters::RRMethods
86
93
  (RR::Space.instance_methods - Object.instance_methods).each do |method_name|
87
- returns_method = <<-METHOD
94
+ class_eval((<<-METHOD), __FILE__, __LINE__ + 1)
88
95
  def #{method_name}(*args, &block)
89
96
  RR::Space.instance.__send__(:#{method_name}, *args, &block)
90
97
  end
91
98
  METHOD
92
- class_eval(returns_method, __FILE__, __LINE__ - 4)
93
99
  end
94
100
  end
95
101
  end
@@ -1,22 +1,40 @@
1
1
  module RR
2
2
  module Adapters
3
3
  module RRMethods
4
- class << self
5
- def register_strategy_class(strategy_class, method_name)
6
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
7
- def #{method_name}(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
8
- double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
9
- double_definition_create.#{method_name}(subject, method_name, &definition_eval_block)
10
- end
11
- CLASS
12
-
13
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
14
- def #{method_name}!(method_name=nil, &definition_eval_block)
15
- double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
16
- double_definition_create.#{method_name}!(method_name, &definition_eval_block)
17
- end
18
- CLASS
19
- end
4
+ include ::RR::DoubleDefinitions::Strategies::StrategyMethods
5
+ def mock(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
6
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
7
+ double_definition_create.mock(subject, method_name, &definition_eval_block)
8
+ end
9
+
10
+ def stub(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
11
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
12
+ double_definition_create.stub(subject, method_name, &definition_eval_block)
13
+ end
14
+
15
+ def dont_allow(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
16
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
17
+ double_definition_create.dont_allow(subject, method_name, &definition_eval_block)
18
+ end
19
+
20
+ def proxy(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
21
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
22
+ double_definition_create.proxy(subject, method_name, &definition_eval_block)
23
+ end
24
+
25
+ def strong(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
26
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
27
+ double_definition_create.strong(subject, method_name, &definition_eval_block)
28
+ end
29
+
30
+ def any_instance_of(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
31
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
32
+ double_definition_create.any_instance_of(subject, method_name, &definition_eval_block)
33
+ end
34
+
35
+ def instance_of(subject=DoubleDefinitions::DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
36
+ double_definition_create = DoubleDefinitions::DoubleDefinitionCreate.new
37
+ double_definition_create.instance_of(subject, method_name, &definition_eval_block)
20
38
  end
21
39
 
22
40
  # Verifies all the DoubleInjection objects have met their
@@ -102,7 +120,7 @@ module RR
102
120
 
103
121
  def spy(subject)
104
122
  methods_to_stub = subject.public_methods.map {|method_name| method_name.to_sym} -
105
- [:methods, :==, :__send__, :__id__, :object_id]
123
+ [:methods, :==, :__send__, :__id__, :object_id, :class]
106
124
  methods_to_stub.each do |method|
107
125
  stub.proxy(subject, method)
108
126
  end
@@ -112,6 +130,14 @@ module RR
112
130
  RR::SpyVerificationProxy.new(subject)
113
131
  end
114
132
 
133
+ def new_instance_of(*args, &block)
134
+ RR::DoubleDefinitions::DoubleInjections::NewInstanceOf.call(*args, &block)
135
+ end
136
+
137
+ def any_instance_of(*args, &block)
138
+ RR::DoubleDefinitions::DoubleInjections::AnyInstanceOf.call(*args, &block)
139
+ end
140
+
115
141
  instance_methods.each do |name|
116
142
  alias_method "rr_#{name}", name
117
143
  end
@@ -1,6 +1,6 @@
1
1
  module RR
2
2
  module BlankSlate
3
- class << self
3
+ extend(Module.new do
4
4
  def call(klass)
5
5
  klass.instance_eval do
6
6
  instance_methods.each do |unformatted_method_name|
@@ -12,6 +12,6 @@ module RR
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end)
16
16
  end
17
17
  end
@@ -0,0 +1,9 @@
1
+ module RR
2
+ module ClassInstanceMethodDefined
3
+ def self.call(klass, instance_method, include_super=true)
4
+ klass.instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym} ||
5
+ klass.protected_instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym} ||
6
+ klass.private_instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym}
7
+ end
8
+ end
9
+ end
@@ -3,7 +3,7 @@ module RR
3
3
  # It has the ArgumentEqualityExpectation, TimesCalledExpectation,
4
4
  # and the implementation.
5
5
  class Double
6
- class << self
6
+ extend(Module.new do
7
7
  def formatted_name(method_name, args)
8
8
  formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
9
9
  "#{method_name}(#{formatted_errors})"
@@ -14,7 +14,7 @@ module RR
14
14
  "- #{formatted_name(double.method_name, double.expected_arguments)}"
15
15
  end.join("\n")
16
16
  end
17
- end
17
+ end)
18
18
 
19
19
  attr_reader :times_called, :double_injection, :definition, :times_called_expectation
20
20
  include Space::Reader
@@ -1,22 +1,6 @@
1
1
  module RR
2
2
  module DoubleDefinitions
3
3
  class DoubleDefinition #:nodoc:
4
- class << self
5
- def register_strategy_class(strategy_class, method_name)
6
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
7
- def #{method_name}(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
8
- ChildDoubleDefinitionCreate.new(self).#{method_name}(subject, method_name, &definition_eval_block)
9
- end
10
- CLASS
11
-
12
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
13
- def #{method_name}!(method_name=nil, &definition_eval_block)
14
- ChildDoubleDefinitionCreate.new(self).#{method_name}!(method_name, &definition_eval_block)
15
- end
16
- CLASS
17
- end
18
- end
19
-
20
4
  ORIGINAL_METHOD = Object.new
21
5
  attr_accessor(
22
6
  :argument_expectation,
@@ -349,6 +333,35 @@ module RR
349
333
  end
350
334
  end
351
335
  include StateQueryMethods
336
+ include ::RR::DoubleDefinitions::Strategies::StrategyMethods
337
+
338
+ def mock(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
339
+ ChildDoubleDefinitionCreate.new(self).mock(subject, method_name, &definition_eval_block)
340
+ end
341
+
342
+ def stub(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
343
+ ChildDoubleDefinitionCreate.new(self).stub(subject, method_name, &definition_eval_block)
344
+ end
345
+
346
+ def dont_allow(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
347
+ ChildDoubleDefinitionCreate.new(self).dont_allow(subject, method_name, &definition_eval_block)
348
+ end
349
+
350
+ def proxy(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
351
+ ChildDoubleDefinitionCreate.new(self).proxy(subject, method_name, &definition_eval_block)
352
+ end
353
+
354
+ def strong(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
355
+ ChildDoubleDefinitionCreate.new(self).strong(subject, method_name, &definition_eval_block)
356
+ end
357
+
358
+ def any_instance_of(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
359
+ ChildDoubleDefinitionCreate.new(self).any_instance_of(subject, method_name, &definition_eval_block)
360
+ end
361
+
362
+ def instance_of(subject=DoubleDefinitionCreate::NO_SUBJECT, method_name=nil, &definition_eval_block)
363
+ ChildDoubleDefinitionCreate.new(self).instance_of(subject, method_name, &definition_eval_block)
364
+ end
352
365
  end
353
366
  end
354
367
  end
@@ -1,82 +1,51 @@
1
1
  module RR
2
2
  module DoubleDefinitions
3
3
  class DoubleDefinitionCreate # :nodoc
4
- class << self
5
- def register_verification_strategy_class(strategy_class, strategy_method_name)
6
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
7
- def #{strategy_method_name}(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
8
- self.add_verification_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
4
+ extend(Module.new do
5
+ def default_double_injection_strategy
6
+ @default_double_injection_strategy ||= lambda do |double_injection_create|
7
+ Strategies::DoubleInjection::Instance.new(double_injection_create)
9
8
  end
10
- CLASS
11
-
12
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
13
- def #{strategy_method_name}!(method_name=nil, &definition_eval_block)
14
- #{strategy_method_name}(Object.new, method_name, &definition_eval_block)
15
- end
16
- CLASS
17
9
  end
18
-
19
- def register_implementation_strategy_class(strategy_class, strategy_method_name)
20
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
21
- def #{strategy_method_name}(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
22
- self.add_implementation_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
23
- end
24
- CLASS
25
10
 
26
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
27
- def #{strategy_method_name}!(method_name=nil, &definition_eval_block)
28
- #{strategy_method_name}(Object.new, method_name, &definition_eval_block)
11
+ def set_default_double_injection_strategy(strategy_lambda)
12
+ original_strategy_lambda = default_double_injection_strategy
13
+ begin
14
+ @default_double_injection_strategy = strategy_lambda
15
+ yield
16
+ ensure
17
+ @default_double_injection_strategy = original_strategy_lambda
29
18
  end
30
- CLASS
31
19
  end
20
+ end)
32
21
 
33
- def register_scope_strategy_class(strategy_class, strategy_method_name)
34
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
35
- def #{strategy_method_name}(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
36
- self.add_scope_strategy(#{strategy_class.name}, subject, method_name, &definition_eval_block)
37
- end
38
- CLASS
39
-
40
- class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
41
- def #{strategy_method_name}!(method_name=nil, &definition_eval_block)
42
- #{strategy_method_name}(Object.new, method_name, &definition_eval_block)
43
- end
44
- CLASS
45
- end
46
- end
47
-
48
- attr_reader :subject,
49
- :verification_strategy,
50
- :implementation_strategy,
51
- :scope_strategy
22
+ attr_reader :subject, :verification_strategy, :implementation_strategy, :double_injection_strategy
52
23
  NO_SUBJECT = Object.new
53
24
 
54
25
  include Space::Reader
55
26
 
56
27
  def initialize
57
- @verification_strategy = nil
28
+ @verification_strategy = Strategies::Verification::Stub.new(self)
58
29
  @implementation_strategy = Strategies::Implementation::Reimplementation.new(self)
59
- @scope_strategy = Strategies::Scope::Instance.new(self)
30
+ @double_injection_strategy = self.class.default_double_injection_strategy.call(self)
60
31
  end
61
32
 
62
33
  def call(method_name, *args, &handler)
63
- raise DoubleDefinitionCreateError if no_subject?
64
34
  definition = DoubleDefinition.new(self)
65
- verification_strategy || no_strategy_error
66
35
  verification_strategy.call(definition, method_name, args, handler)
67
36
  implementation_strategy.call(definition, method_name, args, handler)
68
- scope_strategy.call(definition, method_name, args, handler)
37
+ double_injection_strategy.call(definition, method_name, args, handler)
69
38
  definition
70
39
  end
71
-
40
+
72
41
  def root_subject
73
42
  subject
74
43
  end
75
-
44
+
76
45
  def method_name
77
46
  @verification_strategy.method_name
78
47
  end
79
-
48
+
80
49
  module StrategySetupMethods
81
50
  def no_subject?
82
51
  subject.__id__ === NO_SUBJECT.__id__
@@ -95,9 +64,9 @@ module RR
95
64
  end
96
65
  end
97
66
 
98
- def add_scope_strategy(scope_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
67
+ def add_double_injection_strategy(double_injection_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
99
68
  add_strategy(subject, method_name, definition_eval_block) do
100
- self.scope_strategy = scope_strategy_class.new(self)
69
+ self.double_injection_strategy = double_injection_strategy_class.new(self)
101
70
  end
102
71
  end
103
72
 
@@ -119,56 +88,53 @@ module RR
119
88
  end
120
89
 
121
90
  def verification_strategy=(verification_strategy)
122
- verify_no_verification_strategy
123
- verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
124
91
  @verification_strategy = verification_strategy
125
92
  verification_strategy
126
93
  end
127
94
 
128
95
  def implementation_strategy=(implementation_strategy)
129
- verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
130
96
  @implementation_strategy = implementation_strategy
131
97
  end
132
98
 
133
- def scope_strategy=(scope_strategy)
134
- verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
135
- @scope_strategy = scope_strategy
99
+ def double_injection_strategy=(double_injection_strategy)
100
+ @double_injection_strategy = double_injection_strategy
136
101
  end
102
+ end
103
+ include StrategySetupMethods
137
104
 
138
- def verify_no_verification_strategy
139
- strategy_already_defined_error if verification_strategy
140
- end
105
+ class DoubleDefinitionCreateError < Errors::RRError
106
+ end
141
107
 
142
- def strategy_already_defined_error
143
- raise(
144
- Errors::DoubleDefinitionError,
145
- "This Double already has a #{verification_strategy.name} strategy"
146
- )
147
- end
108
+ # Verification Strategies
109
+ include ::RR::DoubleDefinitions::Strategies::StrategyMethods
110
+ def mock(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
111
+ self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Mock, subject, method_name, &definition_eval_block)
112
+ end
148
113
 
149
- def verify_not_proxy_and_dont_allow(verification_strategy, implementation_strategy)
150
- proxy_when_dont_allow_error if
151
- verification_strategy.is_a?(Strategies::Verification::DontAllow) &&
152
- implementation_strategy.is_a?(Strategies::Implementation::Proxy)
153
- end
114
+ def stub(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
115
+ self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Stub, subject, method_name, &definition_eval_block)
116
+ end
154
117
 
155
- def proxy_when_dont_allow_error
156
- raise(
157
- Errors::DoubleDefinitionError,
158
- "Doubles cannot be proxied when using dont_allow strategy"
159
- )
160
- end
118
+ def dont_allow(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
119
+ self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::DontAllow, subject, method_name, &definition_eval_block)
120
+ end
161
121
 
162
- def no_strategy_error
163
- raise(
164
- Errors::DoubleDefinitionError,
165
- "This Double has no strategy"
166
- )
167
- end
122
+ # Implementation Strategies
123
+ def proxy(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
124
+ self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::Proxy, subject, method_name, &definition_eval_block)
168
125
  end
169
- include StrategySetupMethods
170
126
 
171
- class DoubleDefinitionCreateError < Errors::RRError
127
+ def strong(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
128
+ self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::StronglyTypedReimplementation, subject, method_name, &definition_eval_block)
129
+ end
130
+
131
+ # DoubleInjection Strategies
132
+ def any_instance_of(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
133
+ self.add_double_injection_strategy(::RR::DoubleDefinitions::Strategies::DoubleInjection::AnyInstanceOf, subject, method_name, &definition_eval_block)
134
+ end
135
+
136
+ def instance_of(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
137
+ self.add_double_injection_strategy(::RR::DoubleDefinitions::Strategies::DoubleInjection::NewInstanceOf, subject, method_name, &definition_eval_block)
172
138
  end
173
139
  end
174
140
  end