caricature 0.7.6 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/caricature.gemspec +3 -3
  2. data/lib/bin/Workarounds.dll.mdb +0 -0
  3. data/lib/caricature.rb +25 -25
  4. data/lib/caricature/clr.rb +6 -6
  5. data/lib/caricature/clr/aspnet_mvc.rb +54 -54
  6. data/lib/caricature/core_ext.rb +10 -10
  7. data/lib/caricature/core_ext/array.rb +9 -9
  8. data/lib/caricature/core_ext/class.rb +31 -14
  9. data/lib/caricature/core_ext/hash.rb +12 -12
  10. data/lib/caricature/core_ext/module.rb +14 -14
  11. data/lib/caricature/core_ext/object.rb +76 -18
  12. data/lib/caricature/core_ext/string.rb +16 -16
  13. data/lib/caricature/core_ext/system/string.rb +20 -20
  14. data/lib/caricature/core_ext/system/type.rb +26 -26
  15. data/lib/caricature/descriptor.rb +73 -73
  16. data/lib/caricature/expectation.rb +264 -263
  17. data/lib/caricature/isolation.rb +143 -143
  18. data/lib/caricature/isolator.rb +302 -302
  19. data/lib/caricature/messenger.rb +67 -67
  20. data/lib/caricature/method_call_recorder.rb +228 -228
  21. data/lib/caricature/verification.rb +60 -60
  22. data/lib/caricature/version.rb +1 -1
  23. data/spec/bacon/integration/clr_to_clr_spec.rb +4 -4
  24. data/spec/bacon/integration/clr_to_ruby_spec.rb +227 -227
  25. data/spec/bacon/integration/event_spec.rb +2 -2
  26. data/spec/bacon/integration/ruby_to_ruby_spec.rb +270 -270
  27. data/spec/bacon/integration/syntax_spec.rb +43 -0
  28. data/spec/bacon/unit/core_ext_spec.rb +87 -87
  29. data/spec/bacon/unit/expectation_spec.rb +300 -300
  30. data/spec/bacon/unit/interop_spec.rb +29 -29
  31. data/spec/bacon/unit/isolation_spec.rb +86 -86
  32. data/spec/bacon/unit/isolator_spec.rb +219 -219
  33. data/spec/bacon/unit/messaging_spec.rb +310 -310
  34. data/spec/bacon/unit/method_call_spec.rb +342 -342
  35. data/spec/bin/ClrModels.dll.mdb +0 -0
  36. data/spec/rspec/unit/event_spec.rb +1 -1
  37. metadata +31 -11
  38. data/spec/models.notused/ClrModels.cs +0 -241
  39. data/spec/models.notused/ruby_models.rb +0 -151
@@ -1,68 +1,68 @@
1
- module Caricature
2
-
3
- # A base class to encapsulate method invocation
4
- class Messenger
5
-
6
- # contains the recorder for recording method calls
7
- attr_accessor :recorder
8
-
9
- # the real instance of the isolated subject
10
- # used to forward calls in partial mocks
11
- attr_reader :instance
12
-
13
- # the expecations that have been set for the isolation
14
- attr_reader :expectations
15
-
16
- # creates a new instance of this messaging strategy
17
- def initialize(expectations, instance=nil)
18
- @instance, @expectations = instance, expectations
19
- end
20
-
21
- # deliver the message to the receiving isolation
22
- def deliver(method_name, return_type, *args, &b)
23
-
24
- internal_deliver(:instance, method_name, return_type, *args, &b)
25
- end
26
-
27
- # deliver the message to class of the receiving isolation
28
- def deliver_to_class(method_name, return_type, *args, &b)
29
- internal_deliver(:class, method_name, return_type, *args, &b)
30
- end
31
-
32
- protected
33
-
34
- # template method for looking up the expectation and/or returning a value
35
- def internal_deliver(mode, method_name, return_type, *args, &b)
36
- raise NotImplementedError.new("Override in an implementing class")
37
- end
38
-
39
- private
40
- def record_call(method_name, mode, expectation, *args, &b)
41
- recorder.record_call method_name, mode, expectation, *args, &b if recorder
42
- end
43
-
44
- end
45
-
46
- # Encapsulates sending messages to Ruby isolations
47
- class RubyMessenger < Messenger
48
-
49
- protected
50
-
51
- # implementation of the template method for looking up the expectation and/or returning a value
52
- def internal_deliver(mode, method_name, return_type, *args, &b)
53
- exp = expectations.find(method_name, mode, *args)
54
- bl = record_call(method_name, mode, exp, *args, &b)
55
- if exp
56
- block = exp.block || b
57
- res = instance.__send__(method_name, *args, &block) if exp.super_before?
58
- res = exp.execute *args, &bl
59
- res = instance.__send__(method_name, *args, &block) if !exp.super_before? and exp.call_super?
60
- res
61
- else
62
- nil
63
- end
64
- end
65
-
66
- end
67
-
1
+ module Caricature
2
+
3
+ # A base class to encapsulate method invocation
4
+ class Messenger
5
+
6
+ # contains the recorder for recording method calls
7
+ attr_accessor :recorder
8
+
9
+ # the real instance of the isolated subject
10
+ # used to forward calls in partial mocks
11
+ attr_reader :instance
12
+
13
+ # the expecations that have been set for the isolation
14
+ attr_reader :expectations
15
+
16
+ # creates a new instance of this messaging strategy
17
+ def initialize(expectations, instance=nil)
18
+ @instance, @expectations = instance, expectations
19
+ end
20
+
21
+ # deliver the message to the receiving isolation
22
+ def deliver(method_name, return_type, *args, &b)
23
+
24
+ internal_deliver(:instance, method_name, return_type, *args, &b)
25
+ end
26
+
27
+ # deliver the message to class of the receiving isolation
28
+ def deliver_to_class(method_name, return_type, *args, &b)
29
+ internal_deliver(:class, method_name, return_type, *args, &b)
30
+ end
31
+
32
+ protected
33
+
34
+ # template method for looking up the expectation and/or returning a value
35
+ def internal_deliver(mode, method_name, return_type, *args, &b)
36
+ raise NotImplementedError.new("Override in an implementing class")
37
+ end
38
+
39
+ private
40
+ def record_call(method_name, mode, expectation, *args, &b)
41
+ recorder.record_call method_name, mode, expectation, *args, &b if recorder
42
+ end
43
+
44
+ end
45
+
46
+ # Encapsulates sending messages to Ruby isolations
47
+ class RubyMessenger < Messenger
48
+
49
+ protected
50
+
51
+ # implementation of the template method for looking up the expectation and/or returning a value
52
+ def internal_deliver(mode, method_name, return_type, *args, &b)
53
+ exp = expectations.find(method_name, mode, *args)
54
+ bl = record_call(method_name, mode, exp, *args, &b)
55
+ if exp
56
+ block = exp.block || b
57
+ res = instance.__send__(method_name, *args, &block) if exp.super_before?
58
+ res = exp.execute *args, &bl
59
+ res = instance.__send__(method_name, *args, &block) if !exp.super_before? and exp.call_super?
60
+ res
61
+ else
62
+ nil
63
+ end
64
+ end
65
+
66
+ end
67
+
68
68
  end
@@ -1,229 +1,229 @@
1
- module Caricature
2
-
3
- class BlockCallRecording
4
- attr_accessor :call_number
5
- attr_reader :args
6
-
7
- def initialize(*args)
8
- @call_number = 1
9
- @args = args
10
- end
11
-
12
- # compares one block variation to another.
13
- # Also takes an array as an argument
14
- def ==(other)
15
- other = self.class.new(other) if other.respond_to?(:each)
16
- return true if other.args.first.is_a?(Symbol) and other.args.first == :any
17
- other.args == args
18
- end
19
-
20
- end
21
-
22
- # A recording of an argument variation.
23
- # Every time a method is called with different arguments
24
- # the method call recorder will create an ArgumentVariation
25
- # these variations are used later in the assertion
26
- # to verify against specific argument values
27
- class ArgumentRecording
28
-
29
- # contains the arguments of the recorded parameters
30
- attr_accessor :args
31
-
32
- # contains the block for the recorded parameters
33
- attr_accessor :block
34
-
35
- # the number of the call that has the following parameters
36
- attr_accessor :call_number
37
-
38
- # the collection of block calls variations on this argument variation
39
- attr_reader :blocks
40
-
41
- # initializes a new instance of an argument recording.
42
- # configures it with 1 call count and the args as an +Array+
43
- def initialize(args=[], call_number=1, block=nil)
44
- @args = args
45
- @block = block
46
- @blocks = []
47
- @call_number = call_number
48
- end
49
-
50
- def add_block_variation(*args)
51
- bv = find_block_variation(*args)
52
- if bv.empty?
53
- blocks << BlockCallRecording.new(*args)
54
- else
55
- bv.first.call_number += 1
56
- end
57
- end
58
-
59
- def find_block_variation(*args)
60
- return @blocks if args.last.is_a?(Symbol) and args.last == :any
61
- @blocks.select { |bv| bv.args == args }
62
- end
63
-
64
- # compares one argument variation to another.
65
- # Also takes an array as an argument
66
- def ==(other)
67
- other = self.class.new(other) if other.respond_to?(:each)
68
- return true if other.args.first.is_a?(Symbol) and other.args.first == :any
69
- other.args == args
70
- end
71
-
72
- def to_s
73
- "<ArgumentRecording @args=#{args}, @block= #{block}, @call_number=#{call_number}"
74
- end
75
- alias_method :inspect, :to_s
76
- end
77
-
78
- # A recording that represents a method call
79
- # it contains argument variations that can be matched too
80
- class MethodCallRecording
81
-
82
- # gets or sets the method name
83
- attr_accessor :method_name
84
-
85
- # gets or sets the amount of times the method was called
86
- attr_accessor :count
87
-
88
- # gets or sets the arguments for this method call
89
- attr_accessor :args
90
-
91
- # gets or sets the block for this method call
92
- attr_accessor :block
93
-
94
- # Initializes a new instance of a method call recording
95
- # every time a method gets called in an isolated object
96
- # this gets stored in the method call recorder
97
- # It expects a +method_name+ at the very least.
98
- def initialize(method_name, count=0)
99
- @method_name = method_name
100
- @count = count
101
- @variations = []
102
- end
103
-
104
- # add args
105
- def args
106
- @variations
107
- end
108
-
109
- # indicates if it has an argument variation
110
- def has_argument_variations?
111
- @variations.size > 1
112
- end
113
-
114
- # add an argument variation
115
- def add_argument_variation(args, block)
116
- variation = find_argument_variations args, nil
117
- if variation.empty?
118
- @variations << ArgumentRecording.new(args, @variations.size+1, block) if variation == []
119
- else
120
- variation.first.call_number += 1
121
- end
122
- end
123
-
124
- # finds an argument variation that matches the provided +args+
125
- def find_argument_variations(args, block_args)
126
- return @variations if args.first.is_a?(Symbol) and args.last == :any
127
- return match_hash(args, block_args) if args.size == 1 and args.last.is_a?(Hash)
128
- return @variations.select { |ar| ar.args == args } if block_args.nil?
129
- return @variations.select { |ar| ar.args == args and ar.block } if block_args.last == :any
130
- return @variations.select do |ar|
131
- av = ar.args == args
132
- # idx = 0
133
- # ags = ar.args
134
- # av = args.all? do |ag|
135
- # rag = ags[idx]
136
- # res = if ag.is_a?(Hash) and rag.is_a?(Hash)
137
- # ag.all? { |k, v| ar.args[idx][k] == v }
138
- # else
139
- # ag == rag
140
- # end
141
- # idx += 1
142
- # res
143
- # end
144
- av and not ar.find_block_variation(*block_args).empty?
145
- end
146
- end
147
-
148
- def match_hash(args, block_args)
149
- @variations.select do |ar|
150
- ags = ar.args.last
151
- args.last.all? { |k, v| ags[k] == v }
152
- end
153
- end
154
- end
155
-
156
- # The recorder that will collect method calls and provides an interface for finding those recordings
157
- class MethodCallRecorder
158
-
159
- # gets the collection of method calls. This is a hash with the method name as key
160
- attr_reader :method_calls
161
-
162
-
163
- # Initializes a new instance of a method call recorder
164
- # every time a method gets called in an isolated object
165
- # this gets stored in the method call recorder
166
- def initialize
167
- @method_calls = {:instance => {}, :class => {} }
168
- end
169
-
170
- # records a method call or increments the count of how many times this method was called.
171
- def record_call(method_name, mode=:instance, expectation=nil, *args, &block)
172
- mn_sym = method_name.to_s.underscore.to_sym
173
- method_calls[mode][mn_sym] ||= MethodCallRecording.new mn_sym.to_s
174
- mc = method_calls[mode][mn_sym]
175
- mc.count += 1
176
- agc = mc.add_argument_variation args, block
177
- b = (expectation && expectation.block) ? (expectation.block||block) : block
178
- expectation.block = lambda do |*ags|
179
- res = nil
180
- res = b.call *ags if b
181
- agc.first.add_block_variation *ags
182
- res
183
- end if expectation
184
- block.nil? ? nil : (lambda { |*ags|
185
- res = nil
186
- res = block.call *ags if block
187
- agc.first.add_block_variation *ags
188
- res
189
- })
190
- end
191
-
192
-
193
- def error
194
- @error
195
- end
196
-
197
- # returns whether the method was actually called with the specified constraints
198
- def was_called?(method_name, block_args, mode=:instance, *args)
199
- mc = method_calls[mode][method_name.to_s.underscore.to_sym]
200
- if mc
201
- vari = mc.find_argument_variations(args, block_args)
202
- result = vari.any? { |agv| agv == args }
203
- return result if result
204
- if args.size == 1 and args.last.is_a?(Hash)
205
- result = vari.any? do |agv|
206
- agv.args.last.is_a?(Hash) and args.last.all? { |k, v| agv.args.last[k] == v }
207
- end
208
- end
209
- @error = "Arguments don't match.\nYou expected:\n#{args.join(", ")}.\nI did find the following variations:\n#{mc.args.collect {|ar| ar.args.join(', ') }.join("\nand\n")}" unless result
210
- result
211
- else
212
- @error = "Couldn't find a method with name #{method_name}"
213
- return !!mc
214
- end
215
- end
216
-
217
- # # indexer that gives you access to the recorded method by method name
218
- # def [](method_name)
219
- # method_calls[:instance][method_name.to_s.to_sym]
220
- # end
221
-
222
- # returns the number of different methods that has been recorderd
223
- def size
224
- @method_calls.size
225
- end
226
- end
227
-
228
-
1
+ module Caricature
2
+
3
+ class BlockCallRecording
4
+ attr_accessor :call_number
5
+ attr_reader :args
6
+
7
+ def initialize(*args)
8
+ @call_number = 1
9
+ @args = args
10
+ end
11
+
12
+ # compares one block variation to another.
13
+ # Also takes an array as an argument
14
+ def ==(other)
15
+ other = self.class.new(other) if other.respond_to?(:each)
16
+ return true if other.args.first.is_a?(Symbol) and other.args.first == :any
17
+ other.args == args
18
+ end
19
+
20
+ end
21
+
22
+ # A recording of an argument variation.
23
+ # Every time a method is called with different arguments
24
+ # the method call recorder will create an ArgumentVariation
25
+ # these variations are used later in the assertion
26
+ # to verify against specific argument values
27
+ class ArgumentRecording
28
+
29
+ # contains the arguments of the recorded parameters
30
+ attr_accessor :args
31
+
32
+ # contains the block for the recorded parameters
33
+ attr_accessor :block
34
+
35
+ # the number of the call that has the following parameters
36
+ attr_accessor :call_number
37
+
38
+ # the collection of block calls variations on this argument variation
39
+ attr_reader :blocks
40
+
41
+ # initializes a new instance of an argument recording.
42
+ # configures it with 1 call count and the args as an +Array+
43
+ def initialize(args=[], call_number=1, block=nil)
44
+ @args = args
45
+ @block = block
46
+ @blocks = []
47
+ @call_number = call_number
48
+ end
49
+
50
+ def add_block_variation(*args)
51
+ bv = find_block_variation(*args)
52
+ if bv.empty?
53
+ blocks << BlockCallRecording.new(*args)
54
+ else
55
+ bv.first.call_number += 1
56
+ end
57
+ end
58
+
59
+ def find_block_variation(*args)
60
+ return @blocks if args.last.is_a?(Symbol) and args.last == :any
61
+ @blocks.select { |bv| bv.args == args }
62
+ end
63
+
64
+ # compares one argument variation to another.
65
+ # Also takes an array as an argument
66
+ def ==(other)
67
+ other = self.class.new(other) if other.respond_to?(:each)
68
+ return true if other.args.first.is_a?(Symbol) and other.args.first == :any
69
+ other.args == args
70
+ end
71
+
72
+ def to_s
73
+ "<ArgumentRecording @args=#{args}, @block= #{block}, @call_number=#{call_number}"
74
+ end
75
+ alias_method :inspect, :to_s
76
+ end
77
+
78
+ # A recording that represents a method call
79
+ # it contains argument variations that can be matched too
80
+ class MethodCallRecording
81
+
82
+ # gets or sets the method name
83
+ attr_accessor :method_name
84
+
85
+ # gets or sets the amount of times the method was called
86
+ attr_accessor :count
87
+
88
+ # gets or sets the arguments for this method call
89
+ attr_accessor :args
90
+
91
+ # gets or sets the block for this method call
92
+ attr_accessor :block
93
+
94
+ # Initializes a new instance of a method call recording
95
+ # every time a method gets called in an isolated object
96
+ # this gets stored in the method call recorder
97
+ # It expects a +method_name+ at the very least.
98
+ def initialize(method_name, count=0)
99
+ @method_name = method_name
100
+ @count = count
101
+ @variations = []
102
+ end
103
+
104
+ # add args
105
+ def args
106
+ @variations
107
+ end
108
+
109
+ # indicates if it has an argument variation
110
+ def has_argument_variations?
111
+ @variations.size > 1
112
+ end
113
+
114
+ # add an argument variation
115
+ def add_argument_variation(args, block)
116
+ variation = find_argument_variations args, nil
117
+ if variation.empty?
118
+ @variations << ArgumentRecording.new(args, @variations.size+1, block) if variation == []
119
+ else
120
+ variation.first.call_number += 1
121
+ end
122
+ end
123
+
124
+ # finds an argument variation that matches the provided +args+
125
+ def find_argument_variations(args, block_args)
126
+ return @variations if args.first.is_a?(Symbol) and args.last == :any
127
+ return match_hash(args, block_args) if args.size == 1 and args.last.is_a?(Hash)
128
+ return @variations.select { |ar| ar.args == args } if block_args.nil?
129
+ return @variations.select { |ar| ar.args == args and ar.block } if block_args.last == :any
130
+ return @variations.select do |ar|
131
+ av = ar.args == args
132
+ # idx = 0
133
+ # ags = ar.args
134
+ # av = args.all? do |ag|
135
+ # rag = ags[idx]
136
+ # res = if ag.is_a?(Hash) and rag.is_a?(Hash)
137
+ # ag.all? { |k, v| ar.args[idx][k] == v }
138
+ # else
139
+ # ag == rag
140
+ # end
141
+ # idx += 1
142
+ # res
143
+ # end
144
+ av and not ar.find_block_variation(*block_args).empty?
145
+ end
146
+ end
147
+
148
+ def match_hash(args, block_args)
149
+ @variations.select do |ar|
150
+ ags = ar.args.last
151
+ args.last.all? { |k, v| ags[k] == v }
152
+ end
153
+ end
154
+ end
155
+
156
+ # The recorder that will collect method calls and provides an interface for finding those recordings
157
+ class MethodCallRecorder
158
+
159
+ # gets the collection of method calls. This is a hash with the method name as key
160
+ attr_reader :method_calls
161
+
162
+
163
+ # Initializes a new instance of a method call recorder
164
+ # every time a method gets called in an isolated object
165
+ # this gets stored in the method call recorder
166
+ def initialize
167
+ @method_calls = {:instance => {}, :class => {} }
168
+ end
169
+
170
+ # records a method call or increments the count of how many times this method was called.
171
+ def record_call(method_name, mode=:instance, expectation=nil, *args, &block)
172
+ mn_sym = method_name.to_s.underscore.to_sym
173
+ method_calls[mode][mn_sym] ||= MethodCallRecording.new mn_sym.to_s
174
+ mc = method_calls[mode][mn_sym]
175
+ mc.count += 1
176
+ agc = mc.add_argument_variation args, block
177
+ b = (expectation && expectation.block) ? (expectation.block||block) : block
178
+ expectation.block = lambda do |*ags|
179
+ res = nil
180
+ res = b.call *ags if b
181
+ agc.first.add_block_variation *ags
182
+ res
183
+ end if expectation
184
+ block.nil? ? nil : (lambda { |*ags|
185
+ res = nil
186
+ res = block.call *ags if block
187
+ agc.first.add_block_variation *ags
188
+ res
189
+ })
190
+ end
191
+
192
+
193
+ def error
194
+ @error
195
+ end
196
+
197
+ # returns whether the method was actually called with the specified constraints
198
+ def was_called?(method_name, block_args, mode=:instance, *args)
199
+ mc = method_calls[mode][method_name.to_s.underscore.to_sym]
200
+ if mc
201
+ vari = mc.find_argument_variations(args, block_args)
202
+ result = vari.any? { |agv| agv == args }
203
+ return result if result
204
+ if args.size == 1 and args.last.is_a?(Hash)
205
+ result = vari.any? do |agv|
206
+ agv.args.last.is_a?(Hash) and args.last.all? { |k, v| agv.args.last[k] == v }
207
+ end
208
+ end
209
+ @error = "Arguments don't match.\nYou expected:\n#{args.join(", ")}.\nI did find the following variations:\n#{mc.args.collect {|ar| ar.args.join(', ') }.join("\nand\n")}" unless result
210
+ result
211
+ else
212
+ @error = "Couldn't find a method with name #{method_name}"
213
+ return !!mc
214
+ end
215
+ end
216
+
217
+ # # indexer that gives you access to the recorded method by method name
218
+ # def [](method_name)
219
+ # method_calls[:instance][method_name.to_s.to_sym]
220
+ # end
221
+
222
+ # returns the number of different methods that has been recorderd
223
+ def size
224
+ @method_calls.size
225
+ end
226
+ end
227
+
228
+
229
229
  end