rr 0.10.11 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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