caricature 0.7.2 → 0.7.5
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/README.rdoc +97 -97
- data/Rakefile +310 -310
- data/caricature.gemspec +110 -106
- data/lib/caricature.rb +3 -1
- data/lib/caricature/bacon.rb +2 -2
- data/lib/caricature/bacon/integration.rb +75 -55
- data/lib/caricature/clr.rb +4 -3
- data/lib/caricature/clr/aspnet_mvc.rb +3 -3
- data/lib/caricature/clr/descriptor.rb +106 -39
- data/lib/caricature/clr/event_verification.rb +57 -0
- data/lib/caricature/clr/expectation.rb +101 -0
- data/lib/caricature/clr/isolation.rb +49 -13
- data/lib/caricature/clr/isolator.rb +141 -5
- data/lib/caricature/clr/messenger.rb +6 -0
- data/lib/caricature/clr/method_call_recorder.rb +97 -0
- data/lib/caricature/core_ext.rb +11 -0
- data/lib/{core_ext → caricature/core_ext}/array.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/class.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/hash.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/module.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/object.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/string.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/system/string.rb +0 -0
- data/lib/{core_ext → caricature/core_ext}/system/type.rb +6 -0
- data/lib/caricature/expectation.rb +108 -66
- data/lib/caricature/isolator.rb +3 -3
- data/lib/caricature/method_call_recorder.rb +32 -4
- data/lib/caricature/rspec/integration.rb +118 -77
- data/lib/caricature/version.rb +5 -5
- data/spec/bacon/integration/callback_spec.rb +156 -156
- data/spec/bacon/integration/clr_to_clr_spec.rb +1 -2
- data/spec/bacon/integration/event_spec.rb +98 -0
- data/spec/bacon/integration/indexer_spec.rb +1 -1
- data/spec/bacon/spec_helper.rb +4 -4
- data/spec/bacon/unit/descriptor_spec.rb +95 -42
- data/spec/bacon/unit/expectation_spec.rb +2 -2
- data/spec/bacon/unit/interop_spec.rb +1 -14
- data/spec/bacon/unit/isolation_spec.rb +1 -1
- data/spec/bacon/unit/isolator_spec.rb +5 -5
- data/spec/bin/ClrModels.dll +0 -0
- data/spec/models/ClrModels.cs +32 -8
- data/spec/models/ruby_models.rb +150 -150
- data/spec/rspec/integration/callback_spec.rb +156 -156
- data/spec/rspec/integration/indexer_spec.rb +1 -1
- data/spec/rspec/spec_helper.rb +12 -6
- data/spec/rspec/unit/descriptor_spec.rb +93 -42
- data/spec/rspec/unit/event_spec.rb +17 -0
- data/spec/rspec/unit/interop_spec.rb +0 -13
- data/spec/spec_helper.rb +14 -14
- metadata +20 -22
- data/lib/core_ext/core_ext.rb +0 -8
- data/spec/bin/ClrModels.dll.mdb +0 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
module Caricature
|
2
|
+
|
3
|
+
# A recording that represents an event raise
|
4
|
+
# it contains argument variations that can be matched too
|
5
|
+
class EventRaiseRecording
|
6
|
+
|
7
|
+
# gets or sets the event name
|
8
|
+
attr_accessor :event_name
|
9
|
+
|
10
|
+
# gets or sets the amount of times the event was raised
|
11
|
+
attr_accessor :count
|
12
|
+
|
13
|
+
# gets or sets the arguments for this event raise
|
14
|
+
attr_accessor :args
|
15
|
+
|
16
|
+
# gets or sets the block for this event raise
|
17
|
+
attr_accessor :handler
|
18
|
+
|
19
|
+
# Initializes a new instance of a method call recording
|
20
|
+
# every time a method gets called in an isolated object
|
21
|
+
# this gets stored in the method call recorder
|
22
|
+
# It expects a +method_name+ at the very least.
|
23
|
+
def initialize(event_name, count=0)
|
24
|
+
@event_name = event_name
|
25
|
+
@count = count
|
26
|
+
@variations = []
|
27
|
+
end
|
28
|
+
|
29
|
+
# add args
|
30
|
+
def args
|
31
|
+
@variations
|
32
|
+
end
|
33
|
+
|
34
|
+
# indicates if it has an argument variation
|
35
|
+
def has_argument_variations?
|
36
|
+
@variations.size > 1
|
37
|
+
end
|
38
|
+
|
39
|
+
# add an argument variation
|
40
|
+
def add_argument_variation(args, block)
|
41
|
+
variation = find_argument_variations args
|
42
|
+
if variation.empty?
|
43
|
+
@variations << ArgumentRecording.new(args, @variations.size+1, block) if variation == []
|
44
|
+
else
|
45
|
+
variation.first.call_number += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# finds an argument variation that matches the provided +args+
|
50
|
+
def find_argument_variations(args)
|
51
|
+
return @variations if args.first.is_a?(Symbol) and args.last == :any
|
52
|
+
@variations.select { |ar| ar.args == args }
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
class MethodCallRecorder
|
58
|
+
|
59
|
+
def event_raises
|
60
|
+
@event_raises ||= {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def record_event_raise(event_name, mode, *args, &handler)
|
64
|
+
en_sym = event_name.to_sym
|
65
|
+
event_raises[mode] ||= {}
|
66
|
+
ev = (event_raises[mode][en_sym] ||= EventRaiseRecording.new(event_name))
|
67
|
+
ev.count += 1
|
68
|
+
ev.add_argument_variation args, handler
|
69
|
+
end
|
70
|
+
|
71
|
+
def event_error
|
72
|
+
@event_error
|
73
|
+
end
|
74
|
+
|
75
|
+
# returns whether the event was actually raised with the specified constraints
|
76
|
+
def event_raised?(event_name, mode = :instance, *args)
|
77
|
+
mc = event_raises[mode][event_name.to_s.to_sym]
|
78
|
+
if mc
|
79
|
+
vari = mc.find_argument_variations(args)
|
80
|
+
result = vari.any? { |agv| agv == args }
|
81
|
+
return result if result
|
82
|
+
if args.size == 1 and args.last.is_a?(Hash)
|
83
|
+
result = vari.any? do |agv|
|
84
|
+
agv.args.last.is_a?(Hash) and args.last.all? { |k, v| agv.args.last[k] == v }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
@event_error = "Event Arguments don't match for #{event_name}.\n\nYou expected:\n#{args.join(", ")}.\n\nI did find the following variations:\n#{mc.args.collect {|ar| ar.args.join(', ') }.join(' and ')}" unless result
|
88
|
+
result
|
89
|
+
else
|
90
|
+
@event_error = "Couldn't find an event with name #{event_name}"
|
91
|
+
return !!mc
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/core_ext/string'
|
2
|
+
require File.dirname(__FILE__) + '/core_ext/class'
|
3
|
+
require File.dirname(__FILE__) + '/core_ext/module'
|
4
|
+
require File.dirname(__FILE__) + '/core_ext/object'
|
5
|
+
require File.dirname(__FILE__) + '/core_ext/array'
|
6
|
+
require File.dirname(__FILE__) + '/core_ext/hash'
|
7
|
+
|
8
|
+
if defined? IRONRUBY_VERSION
|
9
|
+
require File.dirname(__FILE__) + '/core_ext/system/string'
|
10
|
+
require File.dirname(__FILE__) + '/core_ext/system/type'
|
11
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -16,6 +16,12 @@ module System
|
|
16
16
|
self.get_properties + iface_properties.flatten
|
17
17
|
end
|
18
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
|
+
|
19
25
|
end
|
20
26
|
|
21
27
|
end
|
@@ -35,58 +35,66 @@ module Caricature
|
|
35
35
|
# contains the syntax for building up an expectation
|
36
36
|
# This is shared between the +ExpecationBuilder+ and the +Expectation+
|
37
37
|
module ExpectationSyntax
|
38
|
+
|
38
39
|
# tell the expection which arguments it needs to respond to
|
39
40
|
# there is a magic argument here +any+ which configures
|
40
41
|
# the expectation to respond to any arguments
|
41
|
-
def with(*
|
42
|
-
|
43
|
-
|
44
|
-
|
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?
|
45
46
|
self
|
46
47
|
end
|
47
48
|
|
48
49
|
# tell the expectation it nees to return this value or the value returned by the block
|
49
50
|
# you provide to this method.
|
50
51
|
def return(value=nil, &b)
|
51
|
-
|
52
|
-
|
52
|
+
collected[:return_value] = value
|
53
|
+
collected[:return_callback] = b if b
|
53
54
|
self
|
54
55
|
end
|
55
56
|
|
56
57
|
# Sets up arguments for the block that is being passed into the isolated method call
|
57
|
-
def pass_block(*
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
def pass_block(*ags, &b)
|
59
|
+
collected[:any_block_args] = ags.first.is_a?(Symbol) and args.first == :any
|
60
|
+
collected[:block_args] = ags
|
61
|
+
collected[:block_callback] = b unless b.nil?
|
61
62
|
self
|
62
63
|
end
|
63
64
|
|
64
65
|
# tell the expectation it needs to raise an error with the specified arguments
|
65
66
|
alias_method :actual_raise, :raise
|
66
67
|
def raise(*args)
|
67
|
-
|
68
|
+
collected[:error_args] = args
|
68
69
|
self
|
69
70
|
end
|
70
|
-
|
71
|
+
|
71
72
|
# tell the expecation it needs to call the super before the expectation exectution
|
72
73
|
def super_before(&b)
|
73
|
-
|
74
|
-
|
74
|
+
collected[:super] = :before
|
75
|
+
collected[:block] = b if b
|
75
76
|
self
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
# tell the expectation it needs to call the super after the expecation execution
|
79
80
|
def super_after(&b)
|
80
|
-
|
81
|
-
|
81
|
+
collected[:super] = :after
|
82
|
+
collected[:block] = b if b
|
82
83
|
self
|
83
84
|
end
|
84
85
|
|
85
86
|
# indicates whether this expectation should match with any arguments
|
86
87
|
# or only for the specified arguments
|
87
88
|
def any_args?
|
88
|
-
|
89
|
+
collected[:any_args]
|
89
90
|
end
|
91
|
+
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def collected
|
96
|
+
@collected ||= {}
|
97
|
+
end
|
90
98
|
end
|
91
99
|
|
92
100
|
# A description of an expectation.
|
@@ -95,106 +103,140 @@ module Caricature
|
|
95
103
|
|
96
104
|
include ExpectationSyntax
|
97
105
|
|
98
|
-
# gets the method_name to which this expectation needs to listen to
|
99
|
-
attr_reader :method_name
|
100
|
-
|
101
|
-
# the arguments that this expectation needs to be constrained by
|
102
|
-
attr_reader :args
|
103
|
-
|
104
106
|
# the error_args that this expectation will raise an error with
|
105
|
-
|
107
|
+
def error_args
|
108
|
+
collected[:error_args]
|
109
|
+
end
|
106
110
|
|
107
111
|
# the value that this expecation will return when executed
|
108
|
-
|
112
|
+
def return_value
|
113
|
+
collected[:return_value]
|
114
|
+
end
|
109
115
|
|
110
116
|
# indicator for the mode to call the super +:before+, +:after+ and +nil+
|
111
|
-
|
112
|
-
|
117
|
+
def super
|
118
|
+
collected[:super]
|
119
|
+
end
|
120
|
+
|
113
121
|
# contains the callback if one is given
|
114
|
-
|
122
|
+
def callback
|
123
|
+
collected[:callback]
|
124
|
+
end
|
115
125
|
|
116
126
|
# contains the callback that is used to return the value when this expectation
|
117
127
|
# is executed
|
118
|
-
|
128
|
+
def return_callback
|
129
|
+
collected[:return_callback]
|
130
|
+
end
|
119
131
|
|
120
132
|
# contains the arguments that will be passed on to the block
|
121
|
-
|
133
|
+
def block_args
|
134
|
+
collected[:block_args]
|
135
|
+
end
|
122
136
|
|
123
137
|
# The block that will be used as value provider for the block in the method
|
124
|
-
|
138
|
+
def block_callback
|
139
|
+
collected[:block_callback]
|
140
|
+
end
|
125
141
|
|
126
142
|
# the block that will be used
|
127
|
-
|
128
|
-
|
129
|
-
|
143
|
+
def block
|
144
|
+
collected[:block]
|
145
|
+
end
|
146
|
+
|
147
|
+
# sets the block callback
|
148
|
+
def block=(val)
|
149
|
+
collected[:block] = val
|
150
|
+
end
|
151
|
+
|
152
|
+
# gets the method_name to which this expectation needs to listen to
|
153
|
+
def method_name
|
154
|
+
collected[:method_name]
|
155
|
+
end
|
156
|
+
|
157
|
+
# the arguments that this expectation needs to be constrained by
|
158
|
+
def args
|
159
|
+
collected[:args]
|
160
|
+
end
|
161
|
+
|
130
162
|
# Initializes a new instance of an expectation
|
131
|
-
def initialize(
|
132
|
-
|
133
|
-
|
134
|
-
@any_args = true
|
163
|
+
def initialize(options={})
|
164
|
+
collected[:any_args] = true
|
165
|
+
collected.merge!(options)
|
135
166
|
end
|
136
|
-
|
167
|
+
|
137
168
|
# indicates whether this expecation will raise an event.
|
138
169
|
def has_error_args?
|
139
|
-
|
170
|
+
!collected[:error_args].nil?
|
140
171
|
end
|
141
172
|
|
142
173
|
# indicates whether this expectation will return a value.
|
143
174
|
def has_return_value?
|
144
|
-
|
175
|
+
!collected[:return_value].nil?
|
145
176
|
end
|
146
177
|
|
147
178
|
# call the super before the expectation
|
148
179
|
def super_before?
|
149
|
-
|
180
|
+
collected[:super] == :before
|
150
181
|
end
|
151
182
|
|
152
183
|
# indicates whether super needs to be called somewhere
|
153
184
|
def call_super?
|
154
|
-
|
185
|
+
!collected[:super].nil?
|
155
186
|
end
|
156
187
|
|
157
188
|
# indicates whether this expecation has a callback it needs to execute
|
158
189
|
def has_callback?
|
159
|
-
|
190
|
+
!collected[:callback].nil?
|
160
191
|
end
|
161
|
-
|
192
|
+
|
162
193
|
# indicates whether this expectation has a block as value provider for the method call block
|
163
194
|
def has_block_callback?
|
164
|
-
|
195
|
+
!collected[:block_callback].nil?
|
165
196
|
end
|
166
197
|
|
167
198
|
# a flag to indicate it has a return value callback
|
168
199
|
def has_return_callback?
|
169
|
-
|
200
|
+
!collected[:return_callback].nil?
|
170
201
|
end
|
171
202
|
|
172
203
|
# executes this expectation with its configuration
|
173
204
|
def execute(*margs,&b)
|
174
|
-
ags = any_args? ? (margs.empty? ? :
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
if
|
179
|
-
if has_block_callback?
|
180
|
-
b.call(*@block_callback.call)
|
181
|
-
else
|
182
|
-
b.call(*@block_args)
|
183
|
-
end
|
184
|
-
end
|
205
|
+
ags = any_args? ? :any : (margs.empty? ? collected[:args] : margs)
|
206
|
+
do_raise_error
|
207
|
+
do_callback(ags)
|
208
|
+
do_block_callback(&b)
|
209
|
+
do_event_raise if respond_to?(:events)
|
185
210
|
|
186
|
-
return
|
211
|
+
return collected[:return_callback].call(*margs) if has_return_callback?
|
187
212
|
return return_value if has_return_value?
|
188
213
|
nil
|
189
214
|
end
|
190
215
|
|
191
|
-
def to_s
|
216
|
+
def to_s #:nodoc:
|
192
217
|
"<Caricature::Expecation, method_name: #{method_name}, args: #{args}, error args: #{error_args}>"
|
193
218
|
end
|
194
|
-
|
195
|
-
|
196
|
-
|
219
|
+
alias :inspect :to_s
|
220
|
+
|
221
|
+
|
222
|
+
private
|
223
|
+
|
224
|
+
def do_raise_error #:nodoc:
|
225
|
+
actual_raise *collected[:error_args] if has_error_args?
|
226
|
+
end
|
227
|
+
|
228
|
+
def do_callback(ags) #:nodoc:
|
229
|
+
callback.call(*ags) if has_callback?
|
197
230
|
end
|
231
|
+
|
232
|
+
def do_block_callback(&b) #:nodoc:
|
233
|
+
if b
|
234
|
+
ags = has_block_callback? ? collected[:block_callback].call : collected[:block_args]
|
235
|
+
b.call(*ags)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
|
198
240
|
end
|
199
241
|
|
200
242
|
# Constructs the expecation object.
|
@@ -207,14 +249,14 @@ module Caricature
|
|
207
249
|
# this builder is passed into the block to allow only certain
|
208
250
|
# operations in the block.
|
209
251
|
def initialize(method_name)
|
210
|
-
@
|
252
|
+
@collected = { :method_name => method_name, :args => [], :any_args => true }
|
211
253
|
end
|
212
254
|
|
213
255
|
|
214
256
|
|
215
257
|
# build up the expectation with the provided arguments
|
216
258
|
def build
|
217
|
-
Expectation.new
|
259
|
+
Expectation.new collected
|
218
260
|
end
|
219
261
|
|
220
262
|
end
|
data/lib/caricature/isolator.rb
CHANGED
@@ -214,6 +214,7 @@ module Caricature
|
|
214
214
|
pxy.instance_variable_set("@___context___", context)
|
215
215
|
pxy
|
216
216
|
end
|
217
|
+
|
217
218
|
|
218
219
|
class << self
|
219
220
|
|
@@ -280,17 +281,16 @@ module Caricature
|
|
280
281
|
def initialize(*args)
|
281
282
|
self
|
282
283
|
end
|
283
|
-
|
284
|
+
|
284
285
|
cmembers.each do |mn|
|
285
286
|
mn = mn.name.to_s.to_sym
|
286
287
|
define_cmethod mn do |*args|
|
288
|
+
return if mn.to_s =~ /$(singleton_)?method_added/ and args.first.to_s =~ /$(singleton_)?method_added/
|
287
289
|
b = nil
|
288
290
|
b = Proc.new { yield } if block_given?
|
289
291
|
isolation_context.send_class_message(mn, nil, *args, &b)
|
290
292
|
end
|
291
293
|
end
|
292
|
-
|
293
|
-
|
294
294
|
|
295
295
|
end
|
296
296
|
|