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