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.
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