rr 0.4.10 → 0.6.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.
- data/CHANGES +14 -0
- data/README.rdoc +67 -13
- data/Rakefile +1 -1
- data/lib/rr.rb +29 -9
- data/lib/rr/adapters/rr_methods.rb +38 -158
- data/lib/rr/double.rb +46 -41
- data/lib/rr/double_definitions/child_double_definition_creator.rb +23 -0
- data/lib/rr/double_definitions/double_definition.rb +212 -0
- data/lib/rr/double_definitions/double_definition_creator.rb +153 -0
- data/lib/rr/double_definitions/double_definition_creator_proxy.rb +25 -0
- data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
- data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
- data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
- data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +43 -0
- data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
- data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
- data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
- data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
- data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
- data/lib/rr/double_injection.rb +21 -15
- data/lib/rr/expectations/argument_equality_expectation.rb +2 -1
- data/lib/rr/space.rb +23 -22
- data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
- data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
- data/spec/high_level_spec.rb +111 -64
- data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +1 -1
- data/spec/rr/adapters/rr_methods_creator_spec.rb +99 -315
- data/spec/rr/adapters/rr_methods_space_spec.rb +90 -109
- data/spec/rr/adapters/rr_methods_spec_helper.rb +1 -1
- data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +1 -1
- data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +103 -0
- data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +83 -0
- data/spec/rr/double_definitions/double_definition_creator_spec.rb +495 -0
- data/spec/rr/double_definitions/double_definition_spec.rb +1116 -0
- data/spec/rr/double_injection/double_injection_bind_spec.rb +111 -0
- data/spec/rr/double_injection/double_injection_dispatching_spec.rb +245 -0
- data/spec/rr/{double → double_injection}/double_injection_has_original_method_spec.rb +9 -9
- data/spec/rr/double_injection/double_injection_reset_spec.rb +90 -0
- data/spec/rr/double_injection/double_injection_spec.rb +77 -0
- data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
- data/spec/rr/double_spec.rb +156 -136
- data/spec/rr/errors/rr_error_spec.rb +1 -1
- data/spec/rr/expectations/any_argument_expectation_spec.rb +1 -1
- data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +6 -30
- data/spec/rr/expectations/argument_equality_expectation_spec.rb +35 -18
- data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +22 -41
- data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
- data/spec/rr/expectations/hash_including_spec.rb +17 -0
- data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
- data/spec/rr/expectations/satisfy_spec.rb +14 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +30 -28
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +55 -54
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +49 -48
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +9 -7
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +77 -76
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +58 -57
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +59 -58
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +25 -24
- data/spec/rr/rspec/rspec_adapter_spec.rb +12 -11
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +10 -8
- data/spec/rr/rspec/rspec_usage_spec.rb +1 -1
- data/spec/rr/space/hash_with_object_id_key_spec.rb +1 -1
- data/spec/rr/space/space_spec.rb +330 -192
- data/spec/rr/test_unit/test_helper.rb +1 -2
- data/spec/rr/test_unit/test_unit_backtrace_test.rb +1 -2
- data/spec/rr/test_unit/test_unit_integration_test.rb +1 -2
- data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/integer_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/proc_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/range_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +1 -1
- data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
- data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
- data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
- data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
- data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
- data/spec/rr_spec.rb +28 -0
- data/spec/spec_helper.rb +84 -0
- metadata +43 -29
- data/lib/rr/double_creator.rb +0 -271
- data/lib/rr/double_definition.rb +0 -179
- data/lib/rr/double_definition_builder.rb +0 -44
- data/lib/rr/double_definition_creator.rb +0 -156
- data/lib/rr/double_definition_creator_proxy.rb +0 -20
- data/spec/rr/double/double_injection_bind_spec.rb +0 -105
- data/spec/rr/double/double_injection_dispatching_spec.rb +0 -228
- data/spec/rr/double/double_injection_reset_spec.rb +0 -86
- data/spec/rr/double/double_injection_spec.rb +0 -72
- data/spec/rr/double/double_injection_verify_spec.rb +0 -24
- data/spec/rr/double_definition_creator_proxy_spec.rb +0 -85
- data/spec/rr/double_definition_creator_spec.rb +0 -496
- data/spec/rr/double_definition_spec.rb +0 -815
- data/spec/rr/expectations/anything_spec.rb +0 -14
- data/spec/rr/expectations/boolean_spec.rb +0 -14
- data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +0 -71
- data/spec/rr/expectations/duck_type_spec.rb +0 -14
- data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +0 -51
- data/spec/rr/expectations/is_a_spec.rb +0 -14
- data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +0 -47
- data/spec/rr/expectations/numeric_spec.rb +0 -14
- data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +0 -59
- data/spec/rr/expectations/range_spec.rb +0 -10
- data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +0 -72
- data/spec/rr/expectations/regexp_spec.rb +0 -10
@@ -0,0 +1,25 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
class DoubleDefinitionCreatorProxy
|
4
|
+
def initialize(creator, &block) #:nodoc:
|
5
|
+
@creator = creator
|
6
|
+
class << self
|
7
|
+
instance_methods.each do |m|
|
8
|
+
unless m =~ /^_/ || m.to_s == 'object_id'
|
9
|
+
undef_method m
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method_name, *args, &block)
|
14
|
+
@creator.create(method_name, *args, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
yield(self) if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
def __creator__
|
21
|
+
@creator
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Implementation
|
5
|
+
class ImplementationStrategy < Strategy
|
6
|
+
class << self
|
7
|
+
def register_self_at_double_definition_creator(domain_name)
|
8
|
+
DoubleDefinitionCreator.register_implementation_strategy_class(self, domain_name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Implementation
|
5
|
+
# This method add proxy capabilities to the Double. proxy can be called
|
6
|
+
# with mock or stub.
|
7
|
+
#
|
8
|
+
# mock.proxy(controller.template).render(:partial => "my/socks")
|
9
|
+
#
|
10
|
+
# stub.proxy(controller.template).render(:partial => "my/socks") do |html|
|
11
|
+
# html.should include("My socks are wet")
|
12
|
+
# html
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
16
|
+
# html.should include("My socks are wet")
|
17
|
+
# "My new return value"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# mock.proxy also takes a block for definitions.
|
21
|
+
# mock.proxy(subject) do
|
22
|
+
# render(:partial => "my/socks")
|
23
|
+
#
|
24
|
+
# render(:partial => "my/socks") do |html|
|
25
|
+
# html.should include("My socks are wet")
|
26
|
+
# html
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# render(:partial => "my/socks") do |html|
|
30
|
+
# html.should include("My socks are wet")
|
31
|
+
# html
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# render(:partial => "my/socks") do |html|
|
35
|
+
# html.should include("My socks are wet")
|
36
|
+
# "My new return value"
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Passing a block to the Double (after the method name and arguments)
|
41
|
+
# allows you to intercept the return value.
|
42
|
+
# The return value can be modified, validated, and/or overridden by
|
43
|
+
# passing in a block. The return value of the block will replace
|
44
|
+
# the actual return value.
|
45
|
+
#
|
46
|
+
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
47
|
+
# html.should include("My socks are wet")
|
48
|
+
# "My new return value"
|
49
|
+
# end
|
50
|
+
class Proxy < ImplementationStrategy
|
51
|
+
register("proxy", :probe)
|
52
|
+
|
53
|
+
protected
|
54
|
+
def do_call
|
55
|
+
definition.implemented_by_original_method
|
56
|
+
definition.after_call(&handler) if handler
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Scope
|
5
|
+
class Instance < ScopeStrategy
|
6
|
+
protected
|
7
|
+
def do_call
|
8
|
+
double_injection = space.double_injection(subject, method_name)
|
9
|
+
Double.new(double_injection, definition)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Scope
|
5
|
+
# Calling instance_of will cause all instances of the passed in Class
|
6
|
+
# to have the Double defined.
|
7
|
+
#
|
8
|
+
# The following example mocks all User's valid? method and return false.
|
9
|
+
# mock.instance_of(User).valid? {false}
|
10
|
+
#
|
11
|
+
# The following example mocks and proxies User#projects and returns the
|
12
|
+
# first 3 projects.
|
13
|
+
# mock.instance_of(User).projects do |projects|
|
14
|
+
# projects[0..2]
|
15
|
+
# end
|
16
|
+
class InstanceOfClass < ScopeStrategy
|
17
|
+
register "instance_of"
|
18
|
+
|
19
|
+
def initialize(*args)
|
20
|
+
super
|
21
|
+
|
22
|
+
if !double_definition_creator.no_subject? && !double_definition_creator.subject.is_a?(Class)
|
23
|
+
raise ArgumentError, "instance_of only accepts class objects"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def do_call
|
29
|
+
class_handler = lambda do |return_value|
|
30
|
+
double_injection = space.double_injection(return_value, method_name)
|
31
|
+
Double.new(double_injection, definition)
|
32
|
+
return_value
|
33
|
+
end
|
34
|
+
|
35
|
+
instance_of_subject_creator = DoubleDefinitionCreator.new
|
36
|
+
instance_of_subject_creator.stub.proxy(subject)
|
37
|
+
instance_of_subject_creator.create(:new, &class_handler)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Scope
|
5
|
+
class ScopeStrategy < Strategy
|
6
|
+
class << self
|
7
|
+
def register_self_at_double_definition_creator(domain_name)
|
8
|
+
DoubleDefinitionCreator.register_scope_strategy_class(self, domain_name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
class Strategy
|
5
|
+
class << self
|
6
|
+
attr_reader :domain_name
|
7
|
+
def register(domain_name, *alias_method_names)
|
8
|
+
@domain_name = domain_name
|
9
|
+
register_self_at_double_definition_creator(domain_name)
|
10
|
+
DoubleDefinitionCreator.class_eval do
|
11
|
+
alias_method_names.each do |alias_method_name|
|
12
|
+
alias_method alias_method_name, domain_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
RR::Adapters::RRMethods.register_strategy_class(self, domain_name)
|
16
|
+
DoubleDefinition.register_strategy_class(self, domain_name)
|
17
|
+
RR::Adapters::RRMethods.class_eval do
|
18
|
+
alias_method_names.each do |alias_method_name|
|
19
|
+
alias_method alias_method_name, domain_name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_self_at_double_definition_creator
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :double_definition_creator, :definition, :method_name, :args, :handler
|
29
|
+
include Space::Reader
|
30
|
+
|
31
|
+
def initialize(double_definition_creator)
|
32
|
+
@double_definition_creator = double_definition_creator
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(definition, method_name, args, handler)
|
36
|
+
@definition, @method_name, @args, @handler = definition, method_name, args, handler
|
37
|
+
do_call
|
38
|
+
end
|
39
|
+
|
40
|
+
def name
|
41
|
+
self.class.domain_name
|
42
|
+
end
|
43
|
+
|
44
|
+
def verify_subject(subject)
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
def do_call
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
|
52
|
+
def permissive_argument
|
53
|
+
if args.empty?
|
54
|
+
definition.with_any_args
|
55
|
+
else
|
56
|
+
definition.with(*args)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def reimplementation
|
61
|
+
definition.returns(&handler)
|
62
|
+
end
|
63
|
+
|
64
|
+
def subject
|
65
|
+
definition.subject
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Verification
|
5
|
+
# This method sets the Double to have a dont_allow strategy.
|
6
|
+
# A dont_allow strategy sets the default state of the Double
|
7
|
+
# to expect never to be called. The Double's expectations can be
|
8
|
+
# changed.
|
9
|
+
#
|
10
|
+
# The following example sets the expectation that subject.method_name
|
11
|
+
# will never be called with arg1 and arg2.
|
12
|
+
#
|
13
|
+
# do_not_allow(subject).method_name(arg1, arg2)
|
14
|
+
#
|
15
|
+
# dont_allow also supports a block sytnax.
|
16
|
+
# dont_allow(subject) do |m|
|
17
|
+
# m.method1 # Do not allow method1 with any arguments
|
18
|
+
# m.method2(arg1, arg2) # Do not allow method2 with arguments arg1 and arg2
|
19
|
+
# m.method3.with_no_args # Do not allow method3 with no arguments
|
20
|
+
# end
|
21
|
+
class DontAllow < VerificationStrategy
|
22
|
+
register("dont_allow", :do_not_allow, :dont_call, :do_not_call)
|
23
|
+
|
24
|
+
protected
|
25
|
+
def do_call
|
26
|
+
definition.never
|
27
|
+
permissive_argument
|
28
|
+
reimplementation
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Verification
|
5
|
+
# This method sets the Double to have a mock strategy. A mock strategy
|
6
|
+
# sets the default state of the Double to expect the method call
|
7
|
+
# with arguments exactly one time. The Double's expectations can be
|
8
|
+
# changed.
|
9
|
+
#
|
10
|
+
# This method can be chained with proxy.
|
11
|
+
# mock.proxy(subject).method_name_1
|
12
|
+
# or
|
13
|
+
# proxy.mock(subject).method_name_1
|
14
|
+
#
|
15
|
+
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
16
|
+
# a method with arguments to the proxy will set up expectations that
|
17
|
+
# the a call to the subject's method with the arguments will happen,
|
18
|
+
# and return the prescribed value.
|
19
|
+
# mock(subject).method_name_1 {return_value_1}
|
20
|
+
# mock(subject).method_name_2(arg1, arg2) {return_value_2}
|
21
|
+
#
|
22
|
+
# When passed the subject and the method_name, this method returns
|
23
|
+
# a mock Double with the method already set.
|
24
|
+
#
|
25
|
+
# mock(subject, :method_name_1) {return_value_1}
|
26
|
+
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
27
|
+
#
|
28
|
+
# mock also takes a block for definitions.
|
29
|
+
# mock(subject) do
|
30
|
+
# method_name_1 {return_value_1}
|
31
|
+
# method_name_2(arg_1, arg_2) {return_value_2}
|
32
|
+
# end
|
33
|
+
class Mock < VerificationStrategy
|
34
|
+
register "mock"
|
35
|
+
|
36
|
+
protected
|
37
|
+
def do_call
|
38
|
+
definition.with(*args).once
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Verification
|
5
|
+
# This method sets the Double to have a stub strategy. A stub strategy
|
6
|
+
# sets the default state of the Double to expect the method call
|
7
|
+
# with any arguments any number of times. The Double's
|
8
|
+
# expectations can be changed.
|
9
|
+
#
|
10
|
+
# This method can be chained with proxy.
|
11
|
+
# stub.proxy(subject).method_name_1
|
12
|
+
# or
|
13
|
+
# proxy.stub(subject).method_name_1
|
14
|
+
#
|
15
|
+
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
16
|
+
# a method with arguments to the proxy will set up expectations that
|
17
|
+
# the a call to the subject's method with the arguments will happen,
|
18
|
+
# and return the prescribed value.
|
19
|
+
# stub(subject).method_name_1 {return_value_1}
|
20
|
+
# stub(subject).method_name_2(arg_1, arg_2) {return_value_2}
|
21
|
+
#
|
22
|
+
# When passed the subject and the method_name, this method returns
|
23
|
+
# a stub Double with the method already set.
|
24
|
+
#
|
25
|
+
# mock(subject, :method_name_1) {return_value_1}
|
26
|
+
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
27
|
+
#
|
28
|
+
# stub also takes a block for definitions.
|
29
|
+
# stub(subject) do
|
30
|
+
# method_name_1 {return_value_1}
|
31
|
+
# method_name_2(arg_1, arg_2) {return_value_2}
|
32
|
+
# end
|
33
|
+
class Stub < VerificationStrategy
|
34
|
+
register "stub"
|
35
|
+
|
36
|
+
protected
|
37
|
+
def do_call
|
38
|
+
definition.any_number_of_times
|
39
|
+
permissive_argument
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RR
|
2
|
+
module DoubleDefinitions
|
3
|
+
module Strategies
|
4
|
+
module Verification
|
5
|
+
class VerificationStrategy < Strategy
|
6
|
+
class << self
|
7
|
+
def register_self_at_double_definition_creator(domain_name)
|
8
|
+
DoubleDefinitionCreator.register_verification_strategy_class(self, domain_name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rr/double_injection.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
module RR
|
2
|
-
# RR::DoubleInjection is the binding of an
|
2
|
+
# RR::DoubleInjection is the binding of an subject and a method.
|
3
3
|
# A double_injection has 0 to many Double objects. Each Double
|
4
4
|
# has Argument Expectations and Times called Expectations.
|
5
5
|
class DoubleInjection
|
6
6
|
MethodArguments = Struct.new(:arguments, :block)
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :subject, :method_name, :doubles
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(subject, method_name)
|
10
|
+
@subject = subject
|
11
11
|
@method_name = method_name.to_sym
|
12
12
|
if object_has_method?(method_name)
|
13
|
-
|
13
|
+
begin
|
14
|
+
meta.__send__(:alias_method, original_method_name, method_name)
|
15
|
+
rescue NameError => e
|
16
|
+
subject.send(method_name)
|
17
|
+
meta.__send__(:alias_method, original_method_name, method_name)
|
18
|
+
end
|
14
19
|
end
|
15
20
|
@doubles = []
|
16
21
|
end
|
@@ -44,7 +49,7 @@ module RR
|
|
44
49
|
end
|
45
50
|
|
46
51
|
# RR::DoubleInjection#reset removes the injected dispatcher method.
|
47
|
-
# It binds the original method implementation on the
|
52
|
+
# It binds the original method implementation on the subject
|
48
53
|
# if one exists.
|
49
54
|
def reset
|
50
55
|
meta.__send__(:remove_method, placeholder_name)
|
@@ -57,7 +62,7 @@ module RR
|
|
57
62
|
end
|
58
63
|
|
59
64
|
def call_original_method(*args, &block)
|
60
|
-
@
|
65
|
+
@subject.__send__(original_method_name, *args, &block)
|
61
66
|
end
|
62
67
|
|
63
68
|
def object_has_original_method?
|
@@ -74,9 +79,10 @@ module RR
|
|
74
79
|
|
75
80
|
def call_method(args, block)
|
76
81
|
if double = find_double_to_attempt(args)
|
77
|
-
|
82
|
+
double.call(self, *args, &block)
|
83
|
+
else
|
84
|
+
double_not_found_error(*args)
|
78
85
|
end
|
79
|
-
double_not_found_error(*args)
|
80
86
|
end
|
81
87
|
|
82
88
|
def find_double_to_attempt(args)
|
@@ -99,17 +105,17 @@ module RR
|
|
99
105
|
end
|
100
106
|
|
101
107
|
unless matches.matching_doubles.empty?
|
102
|
-
# This will raise a TimesCalledError
|
103
|
-
return matches.matching_doubles.first
|
108
|
+
return matches.matching_doubles.first # This will raise a TimesCalledError
|
104
109
|
end
|
105
110
|
|
106
111
|
return nil
|
107
112
|
end
|
108
113
|
|
109
114
|
def double_not_found_error(*args)
|
110
|
-
message = "On
|
111
|
-
message << "unexpected method invocation
|
115
|
+
message = "On subject #{subject},\n"
|
116
|
+
message << "unexpected method invocation:\n"
|
112
117
|
message << " #{Double.formatted_name(@method_name, args)}\n"
|
118
|
+
message << "expected invocations:\n"
|
113
119
|
message << Double.list_message_part(@doubles)
|
114
120
|
raise Errors::DoubleNotFoundError, message
|
115
121
|
end
|
@@ -123,11 +129,11 @@ module RR
|
|
123
129
|
end
|
124
130
|
|
125
131
|
def object_has_method?(method_name)
|
126
|
-
@
|
132
|
+
@subject.methods.include?(method_name.to_s) || @subject.respond_to?(method_name)
|
127
133
|
end
|
128
134
|
|
129
135
|
def meta
|
130
|
-
(class << @
|
136
|
+
(class << @subject; self; end)
|
131
137
|
end
|
132
138
|
end
|
133
139
|
end
|