caricature 0.6.1 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -15,13 +15,14 @@ namespace :spec do
15
15
 
16
16
  desc "runs the specifications for the different classes"
17
17
  task :unit do
18
- specs = Dir.glob('spec/**/*_spec.rb').reject { |file| File..basename(file) == "integration_spec.rb" }
18
+ specs = Dir.glob('spec/unit/**/*_spec.rb')
19
19
  system "ibacon #{specs.join(' ')}"
20
20
  end
21
21
 
22
22
  desc "runs the integration tests"
23
23
  task :integration do
24
- system "ibacon spec/integration_spec.rb"
24
+ specs = Dir.glob('spec/integration/**/*_spec.rb')
25
+ system "ibacon #{specs.join(' ')}"
25
26
  end
26
27
  end
27
28
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.6.3
data/caricature.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{caricature}
5
- s.version = "0.6.1"
5
+ s.version = "0.6.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ivan Porto Carrero"]
9
- s.date = %q{2009-05-21}
9
+ s.date = %q{2009-07-10}
10
10
  s.description = %q{This project aims to make interop between IronRuby objects and .NET objects easier. The idea is that it integrates nicely with bacon and later rspec and that it transparently lets you mock ironruby ojbects as well as CLR objects/interfaces. Caricature handles interfaces, interface inheritance, CLR objects, CLR object instances, Ruby classes and instances of Ruby classes.}
11
11
  s.email = %q{ivan@flanders.co.nz}
12
12
  s.extra_rdoc_files = [
@@ -136,18 +136,21 @@ Gem::Specification.new do |s|
136
136
  "pkg/caricature-0.6.0.gem",
137
137
  "spec/bacon_helper.rb",
138
138
  "spec/bin/.gitignore",
139
- "spec/core_ext_spec.rb",
140
- "spec/descriptor_spec.rb",
141
- "spec/expectation_spec.rb",
142
- "spec/integration_spec.rb",
143
- "spec/interop_spec.rb",
144
- "spec/isolation_spec.rb",
145
- "spec/isolator_spec.rb",
146
- "spec/messaging_spec.rb",
147
- "spec/method_call_spec.rb",
139
+ "spec/integration/clr_to_clr_spec.rb",
140
+ "spec/integration/clr_to_ruby_spec.rb",
141
+ "spec/integration/indexer_spec.rb",
142
+ "spec/integration/ruby_to_ruby_spec.rb",
148
143
  "spec/models/ClrModels.cs",
149
- "spec/sword_spec.rb",
150
- "spec/verification_spec.rb",
144
+ "spec/unit/core_ext_spec.rb",
145
+ "spec/unit/descriptor_spec.rb",
146
+ "spec/unit/expectation_spec.rb",
147
+ "spec/unit/interop_spec.rb",
148
+ "spec/unit/isolation_spec.rb",
149
+ "spec/unit/isolator_spec.rb",
150
+ "spec/unit/messaging_spec.rb",
151
+ "spec/unit/method_call_spec.rb",
152
+ "spec/unit/sword_spec.rb",
153
+ "spec/unit/verification_spec.rb",
151
154
  "workarounds/ReflectionHelper.cs"
152
155
  ]
153
156
  s.has_rdoc = true
@@ -159,17 +162,20 @@ Gem::Specification.new do |s|
159
162
  s.summary = %q{Caricature - Bringing simple mocking to the DLR}
160
163
  s.test_files = [
161
164
  "spec/bacon_helper.rb",
162
- "spec/core_ext_spec.rb",
163
- "spec/descriptor_spec.rb",
164
- "spec/expectation_spec.rb",
165
- "spec/integration_spec.rb",
166
- "spec/interop_spec.rb",
167
- "spec/isolation_spec.rb",
168
- "spec/isolator_spec.rb",
169
- "spec/messaging_spec.rb",
170
- "spec/method_call_spec.rb",
171
- "spec/sword_spec.rb",
172
- "spec/verification_spec.rb"
165
+ "spec/integration/clr_to_clr_spec.rb",
166
+ "spec/integration/clr_to_ruby_spec.rb",
167
+ "spec/integration/indexer_spec.rb",
168
+ "spec/integration/ruby_to_ruby_spec.rb",
169
+ "spec/unit/core_ext_spec.rb",
170
+ "spec/unit/descriptor_spec.rb",
171
+ "spec/unit/expectation_spec.rb",
172
+ "spec/unit/interop_spec.rb",
173
+ "spec/unit/isolation_spec.rb",
174
+ "spec/unit/isolator_spec.rb",
175
+ "spec/unit/messaging_spec.rb",
176
+ "spec/unit/method_call_spec.rb",
177
+ "spec/unit/sword_spec.rb",
178
+ "spec/unit/verification_spec.rb"
173
179
  ]
174
180
 
175
181
  if s.respond_to? :specification_version then
@@ -2,6 +2,10 @@ load_assembly 'System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyTo
2
2
  load_assembly 'System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
3
3
  load_assembly 'System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
4
4
 
5
+ include System::Web
6
+ include System::Web::Routing
7
+ include System::Web::Mvc
8
+
5
9
  class String
6
10
 
7
11
  def to_url_filename
@@ -1,9 +1,41 @@
1
1
  module Caricature
2
2
 
3
+ # Contains the logic to collect members from a CLR type
4
+ module ClrMemberCollector
5
+
6
+ private
7
+ # collects the instance members for a CLR type.
8
+ # makes sure it can handle indexers for properties etc.
9
+ def collect_members_from(meths, properties, instance_member=true)
10
+
11
+ mem = []
12
+ mem += meths.collect do |mi|
13
+ MemberDescriptor.new(mi.name.underscore, mi.return_type, instance_member)
14
+ end
15
+ properties.each do |pi|
16
+ prop_name = property_name_from(pi)
17
+ mem << MemberDescriptor.new(prop_name, pi.property_type, instance_member)
18
+ mem << MemberDescriptor.new("__setitem__", nil, instance_member) if prop_name == "__getitem__"
19
+ mem << MemberDescriptor.new("#{prop_name}=", nil, instance_member) if pi.can_write and prop_name != "__getitem__"
20
+ end
21
+ mem
22
+ end
23
+
24
+ # gets the property name from the +PropertyInfo+
25
+ # when the property is an indexer it will return +[]+
26
+ def property_name_from(property_info)
27
+ return property_info.name.underscore if property_info.get_index_parameters.empty?
28
+ "__getitem__"
29
+ end
30
+
31
+ end
32
+
3
33
  # describes clr interfaces.
4
34
  # Because CLR interfaces can't have static members this descriptor does not collect any class members
5
35
  class ClrInterfaceDescriptor < TypeDescriptor
6
36
 
37
+ include ClrMemberCollector
38
+
7
39
  # collects instance members on this interface
8
40
  # it will collect properties, methods and property setters
9
41
  def initialize_instance_members_for(klass)
@@ -12,9 +44,7 @@ module Caricature
12
44
  properties = clr_type.collect_interface_properties
13
45
  methods = clr_type.collect_interface_methods
14
46
 
15
- @instance_members += methods.collect { |mi| MemberDescriptor.new(mi.name.underscore, mi.return_type) }
16
- @instance_members += properties.collect { |pi| MemberDescriptor.new(pi.name.underscore, pi.property_type) }
17
- @instance_members += properties.select { |pi| pi.can_write }.collect { |pi| MemberDescriptor.new("#{pi.name.underscore}=", nil) }
47
+ @instance_members = collect_members_from methods, properties
18
48
  end
19
49
 
20
50
  # this method is empty because an interface can't have static members
@@ -26,6 +56,8 @@ module Caricature
26
56
  # Describes a CLR class type. it collects the properties and methods on an instance as well as on a static level
27
57
  class ClrClassDescriptor < TypeDescriptor
28
58
 
59
+ include ClrMemberCollector
60
+
29
61
  # collects all the instance members of the provided CLR class type
30
62
  def initialize_instance_members_for(klass)
31
63
  clr_type = klass.to_clr_type
@@ -33,9 +65,7 @@ module Caricature
33
65
  methods = Workarounds::ReflectionHelper.get_instance_methods(clr_type)
34
66
  properties = Workarounds::ReflectionHelper.get_instance_properties(clr_type)
35
67
 
36
- @instance_members += methods.collect { |mi| MemberDescriptor.new(mi.name.underscore, mi.return_type) }
37
- @instance_members += properties.collect { |pi| MemberDescriptor.new(pi.name.underscore, pi.property_type) }
38
- @instance_members += properties.select{|pi| pi.can_write }.collect { |pi| MemberDescriptor.new("#{pi.name.underscore}=", nil) }
68
+ @instance_members = collect_members_from methods, properties
39
69
  end
40
70
 
41
71
  # collects all the static members of the provided CLR class type
@@ -45,9 +75,7 @@ module Caricature
45
75
  methods = Workarounds::ReflectionHelper.get_class_methods(clr_type)
46
76
  properties = Workarounds::ReflectionHelper.get_class_properties(clr_type)
47
77
 
48
- @class_members += methods.collect { |mi| MemberDescriptor.new(mi.name.underscore, mi.return_type, false) }
49
- @class_members += properties.collect { |pi| MemberDescriptor.new(pi.name.underscore, pi.property_type, false) }
50
- @class_members += properties.select{|pi| pi.can_write }.collect { |pi| MemberDescriptor.new("#{pi.name.underscore}=", nil, false) }
78
+ @class_members = collect_members_from methods, properties, false
51
79
  end
52
80
 
53
81
  end
@@ -23,19 +23,11 @@ module Caricature
23
23
  # to the method name. It will then also return the first result it can find.
24
24
  def find(method_name, mode=:instance, *args)
25
25
  expectations = mode == :class ? @class_expectations : @instance_expectations
26
+
26
27
  candidates = expectations.select { |exp| exp.method_name.to_s.to_sym == method_name.to_s.to_sym }
27
- is_single = (args.first.is_a?(Symbol) and args.first == :any)
28
- return candidates.first if is_single
29
-
30
- second_pass = candidates.select do |exp|
31
- result = false
32
- exp.args.each_with_index do |item, idx|
33
- result = true if args[idx] == item
34
- end
35
- result
36
- end
37
- return second_pass.first unless second_pass.empty?
38
- candidates.select { |exp| exp.any_args? }.first
28
+ with_arguments_candidates = candidates.select { |exp| exp.args == args }
29
+
30
+ with_arguments_candidates.first || candidates.select { |exp| exp.any_args? }.first
39
31
  end
40
32
 
41
33
  end
@@ -91,7 +91,6 @@ module Caricature
91
91
 
92
92
  # builds up an expectation for a class method, allows for overriding the result returned by the class method
93
93
  def create_class_override(method_name, &block)
94
- puts "creating override"
95
94
  internal_create_override method_name, :class, &block
96
95
  end
97
96
 
@@ -0,0 +1,254 @@
1
+ require File.dirname(__FILE__) + "/../bacon_helper"
2
+
3
+ describe "CLR to CLR interactions" do
4
+
5
+ describe "when isolating CLR interfaces" do
6
+ before do
7
+ @ninja = ClrModels::Ninja.new
8
+ @weapon = Caricature::Isolation.for(ClrModels::IWeapon)
9
+ end
10
+
11
+ it "should work without expectations" do
12
+ @ninja.attack ClrModels::Ninja.new, @weapon
13
+
14
+ @weapon.did_receive?(:attack).should.be.successful
15
+ end
16
+
17
+ it "should work for expectations with an argument constraint" do
18
+ ninja = ClrModels::Ninja.new
19
+ @weapon.when_receiving(:attack).with(ninja).return(5)
20
+
21
+ @ninja.attack(ninja, @weapon).should.equal 5
22
+
23
+ @weapon.did_receive?(:attack).with(:any).should.be.successful
24
+ end
25
+
26
+ it "should work for expectations with an argument constraint when a wrong argument is passed in" do
27
+ @weapon.when_receiving(:attack).with(ClrModels::Ninja.new).return(5)
28
+
29
+ @ninja.attack(ClrModels::Ninja.new, @weapon).should.equal 0
30
+ end
31
+
32
+ it "should work for expectations with an argument constraint and an assertion argument constraint" do
33
+ ninja = ClrModels::Ninja.new
34
+ @weapon.when_receiving(:attack).with(ninja).return(5)
35
+
36
+ @ninja.attack(ninja, @weapon).should.equal 5
37
+
38
+ @weapon.did_receive?(:attack).with(ninja).should.be.successful
39
+ end
40
+
41
+ it "should fail for expectations with an argument constraint and an assertion argument constraint" do
42
+ ninja = ClrModels::Ninja.new
43
+ @weapon.when_receiving(:attack).with(ninja).return(5)
44
+
45
+ @ninja.attack(ninja, @weapon).should.equal 5
46
+
47
+ @weapon.did_receive?(:attack).with(ClrModels::Ninja.new).should.not.be.successful
48
+ end
49
+
50
+ it "should work with an expectation with any arguments" do
51
+ @weapon.when_receiving(:damage).return(5)
52
+
53
+ @ninja.is_killed_by(@weapon).should.be.true?
54
+ @weapon.did_receive?(:damage).should.be.successful
55
+ end
56
+
57
+ it "should work with an expectation getting different method call result" do
58
+ @weapon.when_receiving(:damage).return(2)
59
+
60
+ @ninja.is_killed_by(@weapon).should.be.false?
61
+ @weapon.did_receive?(:damage).should.be.successful
62
+ end
63
+
64
+ it "should work for an assertion on a specific argument" do
65
+ @weapon.when_receiving(:damage).return(2)
66
+
67
+ @ninja.is_killed_by(@weapon).should.be.false?
68
+ @weapon.did_receive?(:damage).should.be.successful
69
+ end
70
+
71
+ end
72
+
73
+ describe "when isolating CLR classes" do
74
+
75
+ describe "plain vanilla CLR classes" do
76
+ before do
77
+ @weapon = ClrModels::Sword.new
78
+ @ninja = Caricature::Isolation.for(ClrModels::Ninja)
79
+ end
80
+
81
+ it "should work without expectations" do
82
+ result = @weapon.attack @ninja
83
+ result.should.equal 0
84
+
85
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
86
+ end
87
+
88
+ it "should work for expectations with an argument constraint" do
89
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
90
+
91
+ @weapon.attack(@ninja).should.equal 5
92
+
93
+ @ninja.did_receive?(:survive_attack_with).with(:any).should.be.successful
94
+ end
95
+
96
+ it "should work for expectations with an argument constraint when a wrong argument is passed in" do
97
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
98
+
99
+ @weapon.attack(ClrModels::Ninja.new).should.equal 6
100
+
101
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.not.be.successful
102
+ end
103
+
104
+ it "should work for expectations with an argument constraint and an assertion argument constraint" do
105
+ ninja = ClrModels::Ninja.new
106
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
107
+
108
+ @weapon.attack(@ninja).should.equal 5
109
+
110
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
111
+ end
112
+
113
+ it "should fail for expectations with an argument constraint and an assertion argument constraint" do
114
+ ninja = ClrModels::Ninja.new
115
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
116
+
117
+ @weapon.attack(@ninja).should.equal 5
118
+
119
+ @ninja.did_receive?(:survive_attack_with).with(ClrModels::Sword.new).should.not.be.successful
120
+ end
121
+
122
+ it "should work with an expectation for any arguments" do
123
+ @ninja.when_receiving(:survive_attack_with).return(5)
124
+
125
+ result = @weapon.attack @ninja
126
+ result.should.equal 5
127
+
128
+ @ninja.did_receive?(:survive_attack_with).with(:any).should.be.successful
129
+ end
130
+
131
+ it "should work with an assertion for specific arguments" do
132
+ @ninja.when_receiving(:survive_attack_with) do |method_should|
133
+ method_should.return(5)
134
+ end
135
+
136
+ result = @weapon.attack @ninja
137
+ result.should.equal 5
138
+
139
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
140
+ end
141
+
142
+ it "should fail for an assertion with wrong arguments" do
143
+ @ninja.when_receiving(:survive_attack_with) do |method_should|
144
+ method_should.return(5)
145
+ end
146
+
147
+ result = @weapon.attack @ninja
148
+ result.should.equal 5
149
+
150
+ @ninja.
151
+ did_receive?(:survive_attack_with).
152
+ with(Caricature::Isolation.for(ClrModels::IWeapon)).
153
+ should.not.be.successful
154
+ end
155
+
156
+ end
157
+
158
+ describe "that have an indexer" do
159
+ before do
160
+ @cons = ClrModels::IndexerCaller.new
161
+ @ind = Caricature::Isolation.for(ClrModels::IndexerContained)
162
+ end
163
+
164
+ it "should work without expectations" do
165
+ @cons.call_index_on_class(@ind, "key1").should.be.nil
166
+ end
167
+
168
+
169
+ end
170
+
171
+ end
172
+
173
+ describe "when isolating CLR instances" do
174
+
175
+ before do
176
+ @weapon = ClrModels::Sword.new
177
+ @ninja = Caricature::Isolation.for(ClrModels::Ninja.new)
178
+ end
179
+
180
+ it "should work without expectations" do
181
+ result = @weapon.attack @ninja
182
+ result.should.equal 0
183
+
184
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
185
+ end
186
+
187
+ it "should work for expectations with an argument constraint" do
188
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
189
+
190
+ @weapon.attack(@ninja).should.equal 5
191
+
192
+ @ninja.did_receive?(:survive_attack_with).with(:any).should.be.successful
193
+ end
194
+
195
+ it "should work for expectations with an argument constraint when a wrong argument is passed in" do
196
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
197
+
198
+ @weapon.attack(ClrModels::Ninja.new).should.equal 6
199
+
200
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.not.be.successful
201
+ end
202
+
203
+ it "should work for expectations with an argument constraint and an assertion argument constraint" do
204
+ ninja = ClrModels::Ninja.new
205
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
206
+
207
+ @weapon.attack(@ninja).should.equal 5
208
+
209
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
210
+ end
211
+
212
+ it "should fail for expectations with an argument constraint and an assertion argument constraint" do
213
+ ninja = ClrModels::Ninja.new
214
+ @ninja.when_receiving(:survive_attack_with).with(@weapon).return(5)
215
+
216
+ @weapon.attack(@ninja).should.equal 5
217
+
218
+ @ninja.did_receive?(:survive_attack_with).with(ClrModels::Sword.new).should.not.be.successful
219
+ end
220
+
221
+ it "should work with an expectation for any arguments" do
222
+ @ninja.when_receiving(:survive_attack_with).return(5)
223
+
224
+ result = @weapon.attack @ninja
225
+ result.should.equal 5
226
+
227
+ @ninja.did_receive?(:survive_attack_with).with(:any).should.be.successful
228
+ end
229
+
230
+ it "should fail for an assertion for specific arguments" do
231
+ @ninja.when_receiving(:survive_attack_with) do |method_should|
232
+ method_should.return(5)
233
+ end
234
+
235
+ result = @weapon.attack @ninja
236
+ result.should.equal 5
237
+ var = @ninja.did_receive?(:survive_attack_with).with(:any)
238
+ @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
239
+ end
240
+
241
+ it "should allow to delegate the method call to the real instance (partial mock)" do
242
+ @ninja.when_receiving(:survive_attack_with).super_after
243
+
244
+ result = @weapon.attack @ninja
245
+ result.should.equal 6
246
+
247
+ @ninja.did_receive?(:survive_attack_with).should.be.successful
248
+ end
249
+
250
+
251
+
252
+ end
253
+
254
+ end