-
Notifications
You must be signed in to change notification settings - Fork 58
/
double_definition_create.rb
139 lines (117 loc) · 5.45 KB
/
double_definition_create.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
module RR
module DoubleDefinitions
class DoubleDefinitionCreate # :nodoc
extend(Module.new do
def default_double_injection_strategy
@default_double_injection_strategy ||= lambda do |double_injection_create|
Strategies::DoubleInjection::Instance.new(double_injection_create)
end
end
def set_default_double_injection_strategy(strategy_lambda)
original_strategy_lambda = default_double_injection_strategy
begin
@default_double_injection_strategy = strategy_lambda
yield
ensure
@default_double_injection_strategy = original_strategy_lambda
end
end
end)
attr_reader :subject, :verification_strategy, :implementation_strategy, :double_injection_strategy
NO_SUBJECT = Object.new
include Space::Reader
def initialize
@verification_strategy = Strategies::Verification::Stub.new(self)
@implementation_strategy = Strategies::Implementation::Reimplementation.new(self)
@double_injection_strategy = self.class.default_double_injection_strategy.call(self)
end
def call(method_name, *args, &handler)
definition = DoubleDefinition.new(self)
verification_strategy.call(definition, method_name, args, handler)
implementation_strategy.call(definition, method_name, args, handler)
double_injection_strategy.call(definition, method_name, args, handler)
definition
end
def root_subject
subject
end
def method_name
@verification_strategy.method_name
end
module StrategySetupMethods
def no_subject?
subject.__id__ === NO_SUBJECT.__id__
end
protected
def add_verification_strategy(verification_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
add_strategy(subject, method_name, definition_eval_block) do
self.verification_strategy = verification_strategy_class.new(self)
end
end
def add_implementation_strategy(implementation_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
add_strategy(subject, method_name, definition_eval_block) do
self.implementation_strategy = implementation_strategy_class.new(self)
end
end
def add_double_injection_strategy(double_injection_strategy_class, subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
add_strategy(subject, method_name, definition_eval_block) do
self.double_injection_strategy = double_injection_strategy_class.new(self)
end
end
def add_strategy(subject, method_name, definition_eval_block)
if method_name && definition_eval_block
raise ArgumentError, "Cannot pass in a method name and a block"
end
@subject = subject
yield
# TODO: Allow hash argument to simulate a Struct.
if no_subject?
self
elsif method_name
# TODO: Pass in arguments.
call(method_name)
else
DoubleDefinitionCreateBlankSlate.new(self, &definition_eval_block)
end
end
def verification_strategy=(verification_strategy)
@verification_strategy = verification_strategy
verification_strategy
end
def implementation_strategy=(implementation_strategy)
@implementation_strategy = implementation_strategy
end
def double_injection_strategy=(double_injection_strategy)
@double_injection_strategy = double_injection_strategy
end
end
include StrategySetupMethods
class DoubleDefinitionCreateError < Errors::RRError
end
# Verification Strategies
include ::RR::DoubleDefinitions::Strategies::StrategyMethods
def mock(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Mock, subject, method_name, &definition_eval_block)
end
def stub(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::Stub, subject, method_name, &definition_eval_block)
end
def dont_allow(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_verification_strategy(::RR::DoubleDefinitions::Strategies::Verification::DontAllow, subject, method_name, &definition_eval_block)
end
# Implementation Strategies
def proxy(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::Proxy, subject, method_name, &definition_eval_block)
end
def strong(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_implementation_strategy(::RR::DoubleDefinitions::Strategies::Implementation::StronglyTypedReimplementation, subject, method_name, &definition_eval_block)
end
# DoubleInjection Strategies
def instance_of(subject=NO_SUBJECT, method_name=nil, &definition_eval_block)
self.add_double_injection_strategy(::RR::DoubleDefinitions::Strategies::DoubleInjection::AnyInstanceOf, subject, method_name, &definition_eval_block)
end
alias_method :any_instance_of, :instance_of
alias_method :all_instances_of, :instance_of
end
end
end