caricature 0.7.6 → 0.7.7
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/caricature.gemspec +3 -3
- data/lib/bin/Workarounds.dll.mdb +0 -0
- data/lib/caricature.rb +25 -25
- data/lib/caricature/clr.rb +6 -6
- data/lib/caricature/clr/aspnet_mvc.rb +54 -54
- data/lib/caricature/core_ext.rb +10 -10
- data/lib/caricature/core_ext/array.rb +9 -9
- data/lib/caricature/core_ext/class.rb +31 -14
- data/lib/caricature/core_ext/hash.rb +12 -12
- data/lib/caricature/core_ext/module.rb +14 -14
- data/lib/caricature/core_ext/object.rb +76 -18
- data/lib/caricature/core_ext/string.rb +16 -16
- data/lib/caricature/core_ext/system/string.rb +20 -20
- data/lib/caricature/core_ext/system/type.rb +26 -26
- data/lib/caricature/descriptor.rb +73 -73
- data/lib/caricature/expectation.rb +264 -263
- data/lib/caricature/isolation.rb +143 -143
- data/lib/caricature/isolator.rb +302 -302
- data/lib/caricature/messenger.rb +67 -67
- data/lib/caricature/method_call_recorder.rb +228 -228
- data/lib/caricature/verification.rb +60 -60
- data/lib/caricature/version.rb +1 -1
- data/spec/bacon/integration/clr_to_clr_spec.rb +4 -4
- data/spec/bacon/integration/clr_to_ruby_spec.rb +227 -227
- data/spec/bacon/integration/event_spec.rb +2 -2
- data/spec/bacon/integration/ruby_to_ruby_spec.rb +270 -270
- data/spec/bacon/integration/syntax_spec.rb +43 -0
- data/spec/bacon/unit/core_ext_spec.rb +87 -87
- data/spec/bacon/unit/expectation_spec.rb +300 -300
- data/spec/bacon/unit/interop_spec.rb +29 -29
- data/spec/bacon/unit/isolation_spec.rb +86 -86
- data/spec/bacon/unit/isolator_spec.rb +219 -219
- data/spec/bacon/unit/messaging_spec.rb +310 -310
- data/spec/bacon/unit/method_call_spec.rb +342 -342
- data/spec/bin/ClrModels.dll.mdb +0 -0
- data/spec/rspec/unit/event_spec.rb +1 -1
- metadata +31 -11
- data/spec/models.notused/ClrModels.cs +0 -241
- data/spec/models.notused/ruby_models.rb +0 -151
@@ -1,17 +1,17 @@
|
|
1
|
-
class String
|
2
|
-
|
3
|
-
# converts a camel cased word to an underscored word
|
4
|
-
def underscore
|
5
|
-
self.gsub(/::/, '/').
|
6
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
7
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
8
|
-
tr("-", "_").
|
9
|
-
downcase
|
10
|
-
end
|
11
|
-
|
12
|
-
# Gets the constant when it is defined that corresponds to this string
|
13
|
-
def classify
|
14
|
-
Object.const_get self
|
15
|
-
end
|
16
|
-
|
1
|
+
class String
|
2
|
+
|
3
|
+
# converts a camel cased word to an underscored word
|
4
|
+
def underscore
|
5
|
+
self.gsub(/::/, '/').
|
6
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
7
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
8
|
+
tr("-", "_").
|
9
|
+
downcase
|
10
|
+
end
|
11
|
+
|
12
|
+
# Gets the constant when it is defined that corresponds to this string
|
13
|
+
def classify
|
14
|
+
Object.const_get self
|
15
|
+
end
|
16
|
+
|
17
17
|
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
module System
|
2
|
-
|
3
|
-
class String
|
4
|
-
|
5
|
-
# converts a camel cased word to an underscored word
|
6
|
-
def underscore
|
7
|
-
self.gsub(/::/, '/').
|
8
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
9
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
-
tr("-", "_").
|
11
|
-
downcase
|
12
|
-
end
|
13
|
-
|
14
|
-
# Gets the constant when it is defined that corresponds to this string
|
15
|
-
def classify
|
16
|
-
Object.const_get self
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
1
|
+
module System
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# converts a camel cased word to an underscored word
|
6
|
+
def underscore
|
7
|
+
self.gsub(/::/, '/').
|
8
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
9
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
+
tr("-", "_").
|
11
|
+
downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
# Gets the constant when it is defined that corresponds to this string
|
15
|
+
def classify
|
16
|
+
Object.const_get self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
21
|
end
|
@@ -1,27 +1,27 @@
|
|
1
|
-
module System
|
2
|
-
|
3
|
-
class Type
|
4
|
-
|
5
|
-
# collects all the methods defined on an interface and its parents
|
6
|
-
def collect_interface_methods
|
7
|
-
iface_methods = []
|
8
|
-
iface_methods += self.get_interfaces.collect { |t| t.collect_interface_methods }
|
9
|
-
self.get_methods + iface_methods.flatten
|
10
|
-
end
|
11
|
-
|
12
|
-
# collects the properties defined on an interface an its parents
|
13
|
-
def collect_interface_properties
|
14
|
-
iface_properties = []
|
15
|
-
iface_properties += self.get_interfaces.collect { |t| t.collect_interface_properties }
|
16
|
-
self.get_properties + iface_properties.flatten
|
17
|
-
end
|
18
|
-
|
19
|
-
def collect_interface_events
|
20
|
-
iface_events = []
|
21
|
-
iface_events += self.get_interfaces.collect { |t| t.collect_interface_events }
|
22
|
-
self.get_events + iface_events.flatten.uniq
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
1
|
+
module System
|
2
|
+
|
3
|
+
class Type
|
4
|
+
|
5
|
+
# collects all the methods defined on an interface and its parents
|
6
|
+
def collect_interface_methods
|
7
|
+
iface_methods = []
|
8
|
+
iface_methods += self.get_interfaces.collect { |t| t.collect_interface_methods }
|
9
|
+
self.get_methods + iface_methods.flatten
|
10
|
+
end
|
11
|
+
|
12
|
+
# collects the properties defined on an interface an its parents
|
13
|
+
def collect_interface_properties
|
14
|
+
iface_properties = []
|
15
|
+
iface_properties += self.get_interfaces.collect { |t| t.collect_interface_properties }
|
16
|
+
self.get_properties + iface_properties.flatten
|
17
|
+
end
|
18
|
+
|
19
|
+
def collect_interface_events
|
20
|
+
iface_events = []
|
21
|
+
iface_events += self.get_interfaces.collect { |t| t.collect_interface_events }
|
22
|
+
self.get_events + iface_events.flatten.uniq
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
27
|
end
|
@@ -1,74 +1,74 @@
|
|
1
|
-
module Caricature
|
2
|
-
|
3
|
-
# Describes a class/type so it can be proxied more easily
|
4
|
-
# This is the base class from which other more specialised descriptors can be
|
5
|
-
# used to provide the metadata need to generate the proxy classes
|
6
|
-
class TypeDescriptor
|
7
|
-
|
8
|
-
# Gets the instance members of the described type/class
|
9
|
-
attr_reader :instance_members
|
10
|
-
|
11
|
-
# Gets the class members for the described type/class
|
12
|
-
attr_reader :class_members
|
13
|
-
|
14
|
-
# initializes a new instance of a type descriptor
|
15
|
-
def initialize(klass)
|
16
|
-
@instance_members = []
|
17
|
-
@class_members = []
|
18
|
-
|
19
|
-
unless klass == :in_unit_test_for_class
|
20
|
-
initialize_instance_members_for klass
|
21
|
-
initialize_class_members_for klass
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# collects the instance members of the provided type
|
26
|
-
def initialize_instance_members_for(klass)
|
27
|
-
raise NotImplementedError.new("Override in implementing class")
|
28
|
-
end
|
29
|
-
|
30
|
-
# collects the class members of the provided type
|
31
|
-
def initialize_class_members_for(klass)
|
32
|
-
raise NotImplementedError.new("Override in implementing class")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Describes a member of a class
|
37
|
-
# this contains the metadata needed to generate the member
|
38
|
-
# and perhaps a default value for the property type if necessary
|
39
|
-
class MemberDescriptor
|
40
|
-
|
41
|
-
# the return type of this member
|
42
|
-
attr_reader :return_type
|
43
|
-
|
44
|
-
# the name of this member
|
45
|
-
attr_reader :name
|
46
|
-
|
47
|
-
# initializes a nem instance of member descriptor
|
48
|
-
def initialize(name, return_type=nil, is_instance_member=true)
|
49
|
-
@name, @return_type, @instance_member = name, return_type, is_instance_member
|
50
|
-
end
|
51
|
-
|
52
|
-
# indicates whether this member is a class member or an instance member
|
53
|
-
def instance_member?
|
54
|
-
@instance_member
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
# Describes a ruby object.
|
60
|
-
class RubyObjectDescriptor < TypeDescriptor
|
61
|
-
|
62
|
-
# collects all the members that are defined by this class
|
63
|
-
def initialize_instance_members_for(klass)
|
64
|
-
@instance_members += (klass.instance_methods - Object.instance_methods).collect { |mn| MemberDescriptor.new(mn) }
|
65
|
-
end
|
66
|
-
|
67
|
-
# collects all the members that aren't a member of Object.singleton_methods
|
68
|
-
def initialize_class_members_for(klass)
|
69
|
-
@class_members += klass.methods(false).collect { |mn| MemberDescriptor.new(mn) }
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
|
1
|
+
module Caricature
|
2
|
+
|
3
|
+
# Describes a class/type so it can be proxied more easily
|
4
|
+
# This is the base class from which other more specialised descriptors can be
|
5
|
+
# used to provide the metadata need to generate the proxy classes
|
6
|
+
class TypeDescriptor
|
7
|
+
|
8
|
+
# Gets the instance members of the described type/class
|
9
|
+
attr_reader :instance_members
|
10
|
+
|
11
|
+
# Gets the class members for the described type/class
|
12
|
+
attr_reader :class_members
|
13
|
+
|
14
|
+
# initializes a new instance of a type descriptor
|
15
|
+
def initialize(klass)
|
16
|
+
@instance_members = []
|
17
|
+
@class_members = []
|
18
|
+
|
19
|
+
unless klass == :in_unit_test_for_class
|
20
|
+
initialize_instance_members_for klass
|
21
|
+
initialize_class_members_for klass
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# collects the instance members of the provided type
|
26
|
+
def initialize_instance_members_for(klass)
|
27
|
+
raise NotImplementedError.new("Override in implementing class")
|
28
|
+
end
|
29
|
+
|
30
|
+
# collects the class members of the provided type
|
31
|
+
def initialize_class_members_for(klass)
|
32
|
+
raise NotImplementedError.new("Override in implementing class")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Describes a member of a class
|
37
|
+
# this contains the metadata needed to generate the member
|
38
|
+
# and perhaps a default value for the property type if necessary
|
39
|
+
class MemberDescriptor
|
40
|
+
|
41
|
+
# the return type of this member
|
42
|
+
attr_reader :return_type
|
43
|
+
|
44
|
+
# the name of this member
|
45
|
+
attr_reader :name
|
46
|
+
|
47
|
+
# initializes a nem instance of member descriptor
|
48
|
+
def initialize(name, return_type=nil, is_instance_member=true)
|
49
|
+
@name, @return_type, @instance_member = name, return_type, is_instance_member
|
50
|
+
end
|
51
|
+
|
52
|
+
# indicates whether this member is a class member or an instance member
|
53
|
+
def instance_member?
|
54
|
+
@instance_member
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# Describes a ruby object.
|
60
|
+
class RubyObjectDescriptor < TypeDescriptor
|
61
|
+
|
62
|
+
# collects all the members that are defined by this class
|
63
|
+
def initialize_instance_members_for(klass)
|
64
|
+
@instance_members += (klass.instance_methods - Object.instance_methods).collect { |mn| MemberDescriptor.new(mn) }
|
65
|
+
end
|
66
|
+
|
67
|
+
# collects all the members that aren't a member of Object.singleton_methods
|
68
|
+
def initialize_class_members_for(klass)
|
69
|
+
@class_members += klass.methods(false).collect { |mn| MemberDescriptor.new(mn) }
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
74
|
end
|
@@ -1,264 +1,265 @@
|
|
1
|
-
module Caricature
|
2
|
-
|
3
|
-
# A collection of expectations with some methods to make it easier to work with them.
|
4
|
-
# It allows you to add and find expectations based on certain criteria.
|
5
|
-
class Expectations
|
6
|
-
|
7
|
-
#initializes a new empty instance of the +Expectation+ collection
|
8
|
-
def initialize
|
9
|
-
@instance_expectations = []
|
10
|
-
@class_expectations = []
|
11
|
-
end
|
12
|
-
|
13
|
-
# Adds an expectation to this collection. From then on it can be found in the collection.
|
14
|
-
def add_expectation(expectation, mode=:instance)
|
15
|
-
@instance_expectations << expectation unless mode == :class
|
16
|
-
@class_expectations << expectation if mode == :class
|
17
|
-
end
|
18
|
-
|
19
|
-
# Finds an expectation in the collection. It matches by +method_name+ first.
|
20
|
-
# Then it tries to figure out if you care about the arguments. You can say you don't care by providing
|
21
|
-
# the symbol +:any+ as first argument to this method. When you don't care the first match is being returned
|
22
|
-
# When you specify arguments other than +:any+ it will try to match the specified arguments in addition
|
23
|
-
# to the method name. It will then also return the first result it can find.
|
24
|
-
def find(method_name, mode=:instance, *args)
|
25
|
-
expectations = mode == :class ? @class_expectations : @instance_expectations
|
26
|
-
|
27
|
-
candidates = expectations.select { |exp| exp.method_name.to_s.underscore =~ /#{method_name}|#{method_name.to_s.underscore}/ }
|
28
|
-
with_arguments_candidates = candidates.select { |exp| exp.args == args }
|
29
|
-
|
30
|
-
with_arguments_candidates.first || candidates.select { |exp| exp.any_args? }.first
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# contains the syntax for building up an expectation
|
36
|
-
# This is shared between the +ExpecationBuilder+ and the +Expectation+
|
37
|
-
module ExpectationSyntax
|
38
|
-
|
39
|
-
# tell the expection which arguments it needs to respond to
|
40
|
-
# there is a magic argument here +any+ which configures
|
41
|
-
# the expectation to respond to any arguments
|
42
|
-
def with(*ags, &b)
|
43
|
-
collected[:any_args] = ags.first.is_a?(Symbol) and ags.first == :any
|
44
|
-
collected[:args] = ags
|
45
|
-
collected[:callback] = b unless b.nil?
|
46
|
-
self
|
47
|
-
end
|
48
|
-
|
49
|
-
# tell the expectation it nees to return this value or the value returned by the block
|
50
|
-
# you provide to this method.
|
51
|
-
def return(value=nil, &b)
|
52
|
-
collected[:return_value] = value
|
53
|
-
collected[:return_callback] = b if b
|
54
|
-
self
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
collected[:
|
61
|
-
collected[:
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
collected[:
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
collected[:
|
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
|
-
# is
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
collected
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
return
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
#
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
#
|
250
|
-
#
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
1
|
+
module Caricature
|
2
|
+
|
3
|
+
# A collection of expectations with some methods to make it easier to work with them.
|
4
|
+
# It allows you to add and find expectations based on certain criteria.
|
5
|
+
class Expectations
|
6
|
+
|
7
|
+
#initializes a new empty instance of the +Expectation+ collection
|
8
|
+
def initialize
|
9
|
+
@instance_expectations = []
|
10
|
+
@class_expectations = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Adds an expectation to this collection. From then on it can be found in the collection.
|
14
|
+
def add_expectation(expectation, mode=:instance)
|
15
|
+
@instance_expectations << expectation unless mode == :class
|
16
|
+
@class_expectations << expectation if mode == :class
|
17
|
+
end
|
18
|
+
|
19
|
+
# Finds an expectation in the collection. It matches by +method_name+ first.
|
20
|
+
# Then it tries to figure out if you care about the arguments. You can say you don't care by providing
|
21
|
+
# the symbol +:any+ as first argument to this method. When you don't care the first match is being returned
|
22
|
+
# When you specify arguments other than +:any+ it will try to match the specified arguments in addition
|
23
|
+
# to the method name. It will then also return the first result it can find.
|
24
|
+
def find(method_name, mode=:instance, *args)
|
25
|
+
expectations = mode == :class ? @class_expectations : @instance_expectations
|
26
|
+
|
27
|
+
candidates = expectations.select { |exp| exp.method_name.to_s.underscore =~ /#{method_name}|#{method_name.to_s.underscore}/ }
|
28
|
+
with_arguments_candidates = candidates.select { |exp| exp.args == args }
|
29
|
+
|
30
|
+
with_arguments_candidates.first || candidates.select { |exp| exp.any_args? }.first
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# contains the syntax for building up an expectation
|
36
|
+
# This is shared between the +ExpecationBuilder+ and the +Expectation+
|
37
|
+
module ExpectationSyntax
|
38
|
+
|
39
|
+
# tell the expection which arguments it needs to respond to
|
40
|
+
# there is a magic argument here +any+ which configures
|
41
|
+
# the expectation to respond to any arguments
|
42
|
+
def with(*ags, &b)
|
43
|
+
collected[:any_args] = ags.first.is_a?(Symbol) and ags.first == :any
|
44
|
+
collected[:args] = ags
|
45
|
+
collected[:callback] = b unless b.nil?
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# tell the expectation it nees to return this value or the value returned by the block
|
50
|
+
# you provide to this method.
|
51
|
+
def return(value=nil, &b)
|
52
|
+
collected[:return_value] = value
|
53
|
+
collected[:return_callback] = b if b
|
54
|
+
self
|
55
|
+
end
|
56
|
+
alias_method :returns, :return
|
57
|
+
|
58
|
+
# Sets up arguments for the block that is being passed into the isolated method call
|
59
|
+
def pass_block(*ags, &b)
|
60
|
+
collected[:any_block_args] = ags.first.is_a?(Symbol) and args.first == :any
|
61
|
+
collected[:block_args] = ags
|
62
|
+
collected[:block_callback] = b unless b.nil?
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# tell the expectation it needs to raise an error with the specified arguments
|
67
|
+
alias_method :actual_raise, :raise
|
68
|
+
def raise(*args)
|
69
|
+
collected[:error_args] = args
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
# tell the expecation it needs to call the super before the expectation exectution
|
74
|
+
def super_before(&b)
|
75
|
+
collected[:super] = :before
|
76
|
+
collected[:block] = b if b
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# tell the expectation it needs to call the super after the expecation execution
|
81
|
+
def super_after(&b)
|
82
|
+
collected[:super] = :after
|
83
|
+
collected[:block] = b if b
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
# indicates whether this expectation should match with any arguments
|
88
|
+
# or only for the specified arguments
|
89
|
+
def any_args?
|
90
|
+
collected[:any_args]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def collected
|
97
|
+
@collected ||= {}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# A description of an expectation.
|
102
|
+
# An expectation has the power to call the proxy method or completely ignore it
|
103
|
+
class Expectation
|
104
|
+
|
105
|
+
include ExpectationSyntax
|
106
|
+
|
107
|
+
# the error_args that this expectation will raise an error with
|
108
|
+
def error_args
|
109
|
+
collected[:error_args]
|
110
|
+
end
|
111
|
+
|
112
|
+
# the value that this expecation will return when executed
|
113
|
+
def return_value
|
114
|
+
collected[:return_value]
|
115
|
+
end
|
116
|
+
|
117
|
+
# indicator for the mode to call the super +:before+, +:after+ and +nil+
|
118
|
+
def super
|
119
|
+
collected[:super]
|
120
|
+
end
|
121
|
+
|
122
|
+
# contains the callback if one is given
|
123
|
+
def callback
|
124
|
+
collected[:callback]
|
125
|
+
end
|
126
|
+
|
127
|
+
# contains the callback that is used to return the value when this expectation
|
128
|
+
# is executed
|
129
|
+
def return_callback
|
130
|
+
collected[:return_callback]
|
131
|
+
end
|
132
|
+
|
133
|
+
# contains the arguments that will be passed on to the block
|
134
|
+
def block_args
|
135
|
+
collected[:block_args]
|
136
|
+
end
|
137
|
+
|
138
|
+
# The block that will be used as value provider for the block in the method
|
139
|
+
def block_callback
|
140
|
+
collected[:block_callback]
|
141
|
+
end
|
142
|
+
|
143
|
+
# the block that will be used
|
144
|
+
def block
|
145
|
+
collected[:block]
|
146
|
+
end
|
147
|
+
|
148
|
+
# sets the block callback
|
149
|
+
def block=(val)
|
150
|
+
collected[:block] = val
|
151
|
+
end
|
152
|
+
|
153
|
+
# gets the method_name to which this expectation needs to listen to
|
154
|
+
def method_name
|
155
|
+
collected[:method_name]
|
156
|
+
end
|
157
|
+
|
158
|
+
# the arguments that this expectation needs to be constrained by
|
159
|
+
def args
|
160
|
+
collected[:args]
|
161
|
+
end
|
162
|
+
|
163
|
+
# Initializes a new instance of an expectation
|
164
|
+
def initialize(options={})
|
165
|
+
collected[:any_args] = true
|
166
|
+
collected.merge!(options)
|
167
|
+
end
|
168
|
+
|
169
|
+
# indicates whether this expecation will raise an event.
|
170
|
+
def has_error_args?
|
171
|
+
!collected[:error_args].nil?
|
172
|
+
end
|
173
|
+
|
174
|
+
# indicates whether this expectation will return a value.
|
175
|
+
def has_return_value?
|
176
|
+
!collected[:return_value].nil?
|
177
|
+
end
|
178
|
+
|
179
|
+
# call the super before the expectation
|
180
|
+
def super_before?
|
181
|
+
collected[:super] == :before
|
182
|
+
end
|
183
|
+
|
184
|
+
# indicates whether super needs to be called somewhere
|
185
|
+
def call_super?
|
186
|
+
!collected[:super].nil?
|
187
|
+
end
|
188
|
+
|
189
|
+
# indicates whether this expecation has a callback it needs to execute
|
190
|
+
def has_callback?
|
191
|
+
!collected[:callback].nil?
|
192
|
+
end
|
193
|
+
|
194
|
+
# indicates whether this expectation has a block as value provider for the method call block
|
195
|
+
def has_block_callback?
|
196
|
+
!collected[:block_callback].nil?
|
197
|
+
end
|
198
|
+
|
199
|
+
# a flag to indicate it has a return value callback
|
200
|
+
def has_return_callback?
|
201
|
+
!collected[:return_callback].nil?
|
202
|
+
end
|
203
|
+
|
204
|
+
# executes this expectation with its configuration
|
205
|
+
def execute(*margs,&b)
|
206
|
+
ags = any_args? ? :any : (margs.empty? ? collected[:args] : margs)
|
207
|
+
do_raise_error
|
208
|
+
do_callback(ags)
|
209
|
+
do_block_callback(&b)
|
210
|
+
do_event_raise if respond_to?(:events)
|
211
|
+
|
212
|
+
return collected[:return_callback].call(*margs) if has_return_callback?
|
213
|
+
return return_value if has_return_value?
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_s #:nodoc:
|
218
|
+
"<Caricature::Expecation, method_name: #{method_name}, args: #{args}, error args: #{error_args}>"
|
219
|
+
end
|
220
|
+
alias :inspect :to_s
|
221
|
+
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
def do_raise_error #:nodoc:
|
226
|
+
actual_raise *collected[:error_args] if has_error_args?
|
227
|
+
end
|
228
|
+
|
229
|
+
def do_callback(ags) #:nodoc:
|
230
|
+
callback.call(*ags) if has_callback?
|
231
|
+
end
|
232
|
+
|
233
|
+
def do_block_callback(&b) #:nodoc:
|
234
|
+
if b
|
235
|
+
ags = has_block_callback? ? collected[:block_callback].call : collected[:block_args]
|
236
|
+
b.call(*ags)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
# Constructs the expecation object.
|
244
|
+
# Used as a boundary between the definition and usage of the expectation
|
245
|
+
class ExpectationBuilder
|
246
|
+
|
247
|
+
include ExpectationSyntax
|
248
|
+
|
249
|
+
# initialises a new instance of the expectation builder
|
250
|
+
# this builder is passed into the block to allow only certain
|
251
|
+
# operations in the block.
|
252
|
+
def initialize(method_name)
|
253
|
+
@collected = { :method_name => method_name, :args => [], :any_args => true }
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
# build up the expectation with the provided arguments
|
259
|
+
def build
|
260
|
+
Expectation.new collected
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
264
265
|
end
|