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