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.
Files changed (52) hide show
  1. data/README.rdoc +97 -97
  2. data/Rakefile +310 -310
  3. data/caricature.gemspec +110 -106
  4. data/lib/caricature.rb +3 -1
  5. data/lib/caricature/bacon.rb +2 -2
  6. data/lib/caricature/bacon/integration.rb +75 -55
  7. data/lib/caricature/clr.rb +4 -3
  8. data/lib/caricature/clr/aspnet_mvc.rb +3 -3
  9. data/lib/caricature/clr/descriptor.rb +106 -39
  10. data/lib/caricature/clr/event_verification.rb +57 -0
  11. data/lib/caricature/clr/expectation.rb +101 -0
  12. data/lib/caricature/clr/isolation.rb +49 -13
  13. data/lib/caricature/clr/isolator.rb +141 -5
  14. data/lib/caricature/clr/messenger.rb +6 -0
  15. data/lib/caricature/clr/method_call_recorder.rb +97 -0
  16. data/lib/caricature/core_ext.rb +11 -0
  17. data/lib/{core_ext → caricature/core_ext}/array.rb +0 -0
  18. data/lib/{core_ext → caricature/core_ext}/class.rb +0 -0
  19. data/lib/{core_ext → caricature/core_ext}/hash.rb +0 -0
  20. data/lib/{core_ext → caricature/core_ext}/module.rb +0 -0
  21. data/lib/{core_ext → caricature/core_ext}/object.rb +0 -0
  22. data/lib/{core_ext → caricature/core_ext}/string.rb +0 -0
  23. data/lib/{core_ext → caricature/core_ext}/system/string.rb +0 -0
  24. data/lib/{core_ext → caricature/core_ext}/system/type.rb +6 -0
  25. data/lib/caricature/expectation.rb +108 -66
  26. data/lib/caricature/isolator.rb +3 -3
  27. data/lib/caricature/method_call_recorder.rb +32 -4
  28. data/lib/caricature/rspec/integration.rb +118 -77
  29. data/lib/caricature/version.rb +5 -5
  30. data/spec/bacon/integration/callback_spec.rb +156 -156
  31. data/spec/bacon/integration/clr_to_clr_spec.rb +1 -2
  32. data/spec/bacon/integration/event_spec.rb +98 -0
  33. data/spec/bacon/integration/indexer_spec.rb +1 -1
  34. data/spec/bacon/spec_helper.rb +4 -4
  35. data/spec/bacon/unit/descriptor_spec.rb +95 -42
  36. data/spec/bacon/unit/expectation_spec.rb +2 -2
  37. data/spec/bacon/unit/interop_spec.rb +1 -14
  38. data/spec/bacon/unit/isolation_spec.rb +1 -1
  39. data/spec/bacon/unit/isolator_spec.rb +5 -5
  40. data/spec/bin/ClrModels.dll +0 -0
  41. data/spec/models/ClrModels.cs +32 -8
  42. data/spec/models/ruby_models.rb +150 -150
  43. data/spec/rspec/integration/callback_spec.rb +156 -156
  44. data/spec/rspec/integration/indexer_spec.rb +1 -1
  45. data/spec/rspec/spec_helper.rb +12 -6
  46. data/spec/rspec/unit/descriptor_spec.rb +93 -42
  47. data/spec/rspec/unit/event_spec.rb +17 -0
  48. data/spec/rspec/unit/interop_spec.rb +0 -13
  49. data/spec/spec_helper.rb +14 -14
  50. metadata +20 -22
  51. data/lib/core_ext/core_ext.rb +0 -8
  52. data/spec/bin/ClrModels.dll.mdb +0 -0
@@ -27,7 +27,6 @@ describe "CLR to CLR interactions" do
27
27
  @weapon.when_receiving(:attack).with(ClrModels::Ninja.new).return(5)
28
28
 
29
29
  @ninja.attack(ClrModels::Ninja.new, @weapon).should.equal 0
30
- #@ninja.attack(ClrModels::Ninja.new, ClrModels::Sword.new).should.equal 0
31
30
  end
32
31
 
33
32
  it "should work for expectations with an argument constraint and an assertion argument constraint" do
@@ -235,7 +234,7 @@ describe "CLR to CLR interactions" do
235
234
 
236
235
  result = @weapon.attack @ninja
237
236
  result.should.equal 5
238
- var = @ninja.did_receive?(:survive_attack_with).with(:any)
237
+ @ninja.did_receive?(:survive_attack_with).with(:any).should.be.successful
239
238
  @ninja.did_receive?(:survive_attack_with).with(@weapon).should.be.successful
240
239
  end
241
240
 
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ class DoNothingEventArgs < System::EventArgs
4
+
5
+
6
+ end
7
+
8
+ shared "an event publisher" do
9
+
10
+ it "should not raise an error when subscribing to an event" do
11
+ lambda { ClrModels::ExposedChangedSubscriber.new(@proxy) }.should.not.raise
12
+ end
13
+
14
+ it "should have 1 event subscription" do
15
+ @proxy.isolation_context.events.size.should == 1
16
+ end
17
+
18
+ it "should raise an event when no block is given" do
19
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed)
20
+ @proxy.explode
21
+ @subscriber.counter.should == 1
22
+ end
23
+
24
+ it "should raise an event with the provided parameters" do
25
+ sender = { :the => "sender" }
26
+ ags = DoNothingEventArgs.new
27
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed, sender, ags)
28
+ @proxy.explode
29
+ @subscriber.sender.should == sender
30
+ @subscriber.args.should == ags
31
+ end
32
+
33
+ it "should allow overriding the default event handler" do
34
+ sender = { :the => "sender" }
35
+ ags = DoNothingEventArgs.new
36
+ cnt, rsen, rar = 0, nil, nil
37
+ handler = lambda { |sen, ar| cnt +=1; rsen = sen; rar=ar }
38
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed, sender, ags, &handler)
39
+ @proxy.explode
40
+ rsen.should == sender
41
+ rar.should == ags
42
+ cnt.should == 1
43
+ @subscriber.counter.should == 0
44
+ end
45
+
46
+
47
+ it "should allow adding a block to the default event handler" do
48
+ sender = { :the => "sender" }
49
+ ags = DoNothingEventArgs.new
50
+ cnt = 0
51
+ handler = lambda { |sen, ar| cnt +=1 }
52
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed, sender, ags, &handler).raise_subscriptions
53
+ @proxy.explode
54
+ cnt.should == 1
55
+ @subscriber.counter.should == 1
56
+ end
57
+
58
+ it "should verify if an event was raised" do
59
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed)
60
+ @proxy.explode
61
+ @proxy.should.have_raised_event?(:on_is_exposed_changed)
62
+ end
63
+
64
+ it "should verify if an event was raised with specific parameters" do
65
+ sender = { :the => "sender" }
66
+ ags = DoNothingEventArgs.new
67
+ @proxy.when_receiving(:explode).return(nil).raise_event(:on_is_exposed_changed, sender, ags)
68
+ @proxy.explode
69
+ @proxy.should.have_raised_event?(:on_is_exposed_changed) { |ev| ev.with(sender, ags)}
70
+ end
71
+
72
+ end
73
+
74
+ describe "CLR event handling" do
75
+
76
+ describe "for CLR interfaces" do
77
+
78
+ before do
79
+ @proxy = isolate ClrModels::IExplodingWarrior
80
+ @subscriber = ClrModels::ExposedChangedSubscriber.new(@proxy)
81
+ end
82
+
83
+ behaves_like "an event publisher"
84
+
85
+ end
86
+
87
+ describe "for CLR classes" do
88
+
89
+ before do
90
+ @proxy = isolate ClrModels::ExposingWarrior
91
+ @subscriber = ClrModels::ExposedChangedSubscriber.new(@proxy)
92
+ end
93
+
94
+ behaves_like "an event publisher"
95
+
96
+ end
97
+
98
+ end
@@ -15,7 +15,7 @@ describe "CLR to CLR interactions" do
15
15
  end
16
16
 
17
17
  it "should work with an expectation" do
18
- @ind.when_receiving(:__getitem__).return("5")
18
+ @ind.when_receiving(:get_Item).return("5")
19
19
 
20
20
  @cons.call_index_on_class(@ind, "key1").should.equal "5"
21
21
  end
@@ -1,5 +1,5 @@
1
- require 'rubygems'
2
- # load the bacon library
3
- require 'bacon' unless defined? Bacon
4
-
1
+ require 'rubygems'
2
+ # load the bacon library
3
+ require 'bacon' unless defined? Bacon
4
+
5
5
  require File.dirname(__FILE__) + "/../spec_helper"
@@ -66,71 +66,124 @@ describe "Caricature::MemberDescriptor" do
66
66
 
67
67
  end
68
68
 
69
- describe "Caricature::ClrInterfaceDescriptor" do
69
+ describe Caricature::ClrEventDescriptor.to_s do
70
70
 
71
- before do
72
- @des = Caricature::ClrInterfaceDescriptor.new ClrModels::IWeapon
71
+ it "should have an event name" do
72
+ des = Caricature::ClrEventDescriptor.new "EventName"
73
+ des.event_name.should == "EventName"
73
74
  end
74
75
 
75
- it "should have 2 instance members" do
76
- @des.instance_members.size.should.equal 2
76
+ it "should correctly identify when it's not an instance member" do
77
+ des = Caricature::ClrEventDescriptor.new "EventName", false
78
+ des.should.not.be.instance_member
77
79
  end
78
80
 
79
- it "should contain only instance members" do
80
- result = true
81
- @des.instance_members.each do |mem|
82
- result = false unless mem.instance_member?
81
+ end
82
+
83
+ describe "Caricature::ClrInterfaceDescriptor" do
84
+
85
+ describe "when collecting methods" do
86
+
87
+ before do
88
+ @des = Caricature::ClrInterfaceDescriptor.new ClrModels::IWeapon
83
89
  end
84
90
 
85
- result.should.be.true
86
- end
91
+ it "should have 2 instance members" do
92
+ @des.instance_members.size.should.equal 2
93
+ end
87
94
 
88
- it "should have a damage instance member" do
89
- @des.instance_members.select { |mem| mem.name == "damage" }.should.not.be.empty
90
- end
95
+ it "should contain only instance members" do
96
+ result = true
97
+ @des.instance_members.each do |mem|
98
+ result = false unless mem.instance_member?
99
+ end
100
+
101
+ result.should.be.true
102
+ end
103
+
104
+ it "should have a damage instance member" do
105
+ @des.instance_members.select { |mem| mem.name == "damage" }.should.not.be.empty
106
+ end
107
+
108
+ it "should correctly identify indexers" do
109
+ des = Caricature::ClrInterfaceDescriptor.new ClrModels::IHaveAnIndexer
110
+ des.instance_members.select { |mem| mem.name == "get_Item" }.should.not.be.empty
111
+ end
91
112
 
92
- it "should correctly identify indexers" do
93
- des = Caricature::ClrInterfaceDescriptor.new ClrModels::IHaveAnIndexer
94
- des.instance_members.select { |mem| mem.name == "__getitem__" }.should.not.be.empty
113
+ it "should correctly identify indexers" do
114
+ des = Caricature::ClrInterfaceDescriptor.new ClrModels::IHaveAnIndexer
115
+ des.instance_members.select { |mem| mem.name == "set_Item" }.should.not.be.empty
116
+ end
95
117
  end
96
118
 
97
- it "should correctly identify indexers" do
98
- des = Caricature::ClrInterfaceDescriptor.new ClrModels::IHaveAnIndexer
99
- des.instance_members.select { |mem| mem.name == "__setitem__" }.should.not.be.empty
119
+ describe "when collecting events" do
120
+
121
+ before do
122
+ @des = Caricature::ClrInterfaceDescriptor.new ClrModels::IExplodingWarrior
123
+ end
124
+
125
+ it "should have collected 2 events" do
126
+ @des.events.size.should == 2
127
+ end
128
+
129
+ it "should have collected 2 instance events" do
130
+ @des.events.all? { |ev| ev.instance_member? }.should.be.true?
131
+ end
132
+
133
+
100
134
  end
101
-
135
+
102
136
  end
103
137
 
104
138
  describe "Caricature::ClrClassDescriptor" do
105
139
 
106
- before do
107
- @des = Caricature::ClrClassDescriptor.new ClrModels::SwordWithStatics
108
- end
140
+ describe "when collecting methods" do
109
141
 
110
- it "should have 11 instance members" do
111
- @des.instance_members.size.should.equal 11
112
- end
142
+ before do
143
+ @des = Caricature::ClrClassDescriptor.new ClrModels::SwordWithStatics
144
+ end
113
145
 
114
- it "should have 5 static members" do
115
- @des.class_members.size.should.equal 5
116
- end
146
+ it "should have 11 instance members" do
147
+ @des.instance_members.size.should.equal 11
148
+ end
117
149
 
118
- it "should have a damage instance member" do
119
- @des.instance_members.select { |mem| mem.name == "damage" }.should.not.be.empty
120
- end
150
+ it "should have 5 static members" do
151
+ @des.class_members.size.should.equal 5
152
+ end
121
153
 
122
- it "should have a another method instance member" do
123
- @des.instance_members.select { |mem| mem.name == "another_method" }.should.not.be.empty
124
- end
154
+ it "should have a damage instance member" do
155
+ @des.instance_members.select { |mem| mem.name == "damage" }.should.not.be.empty
156
+ end
157
+
158
+ it "should have a another method instance member" do
159
+ @des.instance_members.select { |mem| mem.name == "another_method" }.should.not.be.empty
160
+ end
125
161
 
126
- it "should correctly identify indexers" do
127
- des = Caricature::ClrClassDescriptor.new ClrModels::IndexerContained
128
- des.instance_members.select { |mem| mem.name == "__getitem__" }.should.not.be.empty
162
+ it "should correctly identify indexers" do
163
+ des = Caricature::ClrClassDescriptor.new ClrModels::IndexerContained
164
+ des.instance_members.select { |mem| mem.name == "get_Item" }.should.not.be.empty
165
+ end
166
+
167
+ it "should correctly identify indexers" do
168
+ des = Caricature::ClrClassDescriptor.new ClrModels::IndexerContained
169
+ des.instance_members.select { |mem| mem.name == "set_Item" }.should.not.be.empty
170
+ end
129
171
  end
130
172
 
131
- it "should correctly identify indexers" do
132
- des = Caricature::ClrClassDescriptor.new ClrModels::IndexerContained
133
- des.instance_members.select { |mem| mem.name == "__setitem__" }.should.not.be.empty
173
+ describe "when collecting events" do
174
+
175
+ before do
176
+ @des = Caricature::ClrClassDescriptor.new ClrModels::ExposingWarrior
177
+ end
178
+
179
+ it "should have 2 instance events" do
180
+ @des.events.size.should == 2
181
+ end
182
+
183
+ it "should should have 1 class event" do
184
+ @des.class_events.size.should == 1
185
+ end
186
+
134
187
  end
135
188
 
136
189
  end
@@ -208,9 +208,9 @@ describe "Caricature::ExpectationBuilder" do
208
208
  before do
209
209
  builder = Caricature::ExpectationBuilder.new :some_method
210
210
  @counter, @args = 0, []
211
- builder.with(5) do |*args|
211
+ builder.with(5) do |*ags|
212
212
  @counter += 1
213
- @args = args
213
+ @args = ags
214
214
  end
215
215
  @expectation = builder.build
216
216
  end
@@ -25,19 +25,6 @@ describe "Event handling" do
25
25
  subscriber.counter.should.equal 1
26
26
  end
27
27
 
28
- end
29
-
30
- describe "for an IR generated interface proxy" do
31
-
32
- before do
33
- @proxy = isolate ClrModels::IExposingWarrior
34
- end
35
-
36
- # apparently events don't work yet in IronRuby.. keeping this spec here to find out when it does
37
- # it "should not raise an error when subcribing to an event" do
38
- # lambda { ClrModels::ExposedChangedSubscriber.new(@proxy) }.should.not.raise
39
- # end
40
-
41
- end
28
+ end
42
29
 
43
30
  end
@@ -83,5 +83,5 @@ describe "Caricature::Isolation" do
83
83
  end
84
84
 
85
85
  end
86
-
86
+
87
87
  end
@@ -68,7 +68,7 @@ describe "Caricature::RubyIsolator" do
68
68
  end
69
69
  end
70
70
 
71
- describe "Caricature::RecordingClrProxy" do
71
+ describe "Caricature::ClrIsolator" do
72
72
 
73
73
  describe "for an instance of a CLR class" do
74
74
 
@@ -172,11 +172,11 @@ describe "Caricature::RecordingClrProxy" do
172
172
  end
173
173
 
174
174
  it "should create an add method for the event" do
175
- @proxy.should.respond_to?(:add_is_exposed_changed)
175
+ @proxy.should.respond_to?(:add_OnIsExposedChanged)
176
176
  end
177
177
 
178
178
  it "should create a remove method for the event" do
179
- @proxy.should.respond_to?(:remove_is_exposed_changed)
179
+ @proxy.should.respond_to?(:remove_OnIsExposedChanged)
180
180
  end
181
181
 
182
182
  end
@@ -201,11 +201,11 @@ describe "Caricature::RecordingClrProxy" do
201
201
  end
202
202
 
203
203
  it "should create an add method for an event defined on a composing interface" do
204
- @proxy.should.respond_to?(:add_is_exposed_changed)
204
+ @proxy.should.respond_to?(:add_OnIsExposedChanged)
205
205
  end
206
206
 
207
207
  it "should create a remove method for an event defined on a composing interface" do
208
- @proxy.should.respond_to?(:remove_is_exposed_changed)
208
+ @proxy.should.respond_to?(:remove_OnIsExposedChanged)
209
209
  end
210
210
 
211
211
  it "should create a getter for a property on the proxy" do
Binary file
@@ -18,7 +18,7 @@ namespace ClrModels{
18
18
  }
19
19
 
20
20
  public interface IExposing {
21
- event EventHandler<EventArgs> IsExposedChanged;
21
+ event EventHandler<EventArgs> OnIsExposedChanged;
22
22
  bool IsExposed {get; set; }
23
23
  }
24
24
 
@@ -30,6 +30,12 @@ namespace ClrModels{
30
30
  void OwnMethod();
31
31
  }
32
32
 
33
+ public interface IExplodingWarrior : IExposingBridge{
34
+ event EventHandler<EventArgs> OnExploding;
35
+ void Explode();
36
+
37
+ }
38
+
33
39
  public class ExposingWarrior : IExposingWarrior{
34
40
  private readonly int _id;
35
41
 
@@ -45,9 +51,23 @@ namespace ClrModels{
45
51
  return weapon.Damage() > 3;
46
52
  }
47
53
 
48
- public event EventHandler<EventArgs> IsExposedChanged;
54
+ public virtual event EventHandler<EventArgs> OnIsExposedChanged;
49
55
  public bool IsExposed {get; set; }
50
56
 
57
+
58
+ public event EventHandler<EventArgs> OnIsAliveChanged;
59
+
60
+ public void Die(){
61
+ OnIsAliveChanged(this, EventArgs.Empty);
62
+ }
63
+
64
+ public static event EventHandler<EventArgs> OnCountChanged;
65
+
66
+ public static void ChangeCount(){
67
+ OnCountChanged(null, EventArgs.Empty);
68
+ }
69
+
70
+
51
71
  public void SomeMethod(){}
52
72
  public void OwnMethod(){
53
73
 
@@ -58,30 +78,34 @@ namespace ClrModels{
58
78
  return _life - weapon.Damage();
59
79
  }
60
80
 
61
- public void ChangeIsExposed(){
81
+ public void Explode(){
62
82
  IsExposed = !IsExposed;
63
- var handler = IsExposedChanged;
83
+ var handler = OnIsExposedChanged;
64
84
  if(handler != null){
65
85
  handler(this, EventArgs.Empty);
66
86
  }
67
87
  }
68
88
 
69
- public bool HasEventSubscriptions{ get { return IsExposedChanged != null; } }
89
+ public bool HasEventSubscriptions{ get { return OnIsExposedChanged != null; } }
70
90
  }
71
91
 
72
92
  public class ExposedChangedSubscriber{
73
93
 
74
- private readonly IExposingWarrior _warrior;
94
+ private readonly IExposingBridge _warrior;
75
95
 
76
- public ExposedChangedSubscriber(IExposingWarrior warrior){
96
+ public ExposedChangedSubscriber(IExposingBridge warrior){
77
97
  _warrior = warrior;
78
- _warrior.IsExposedChanged += OnExposedChanged;
98
+ _warrior.OnIsExposedChanged += OnExposedChanged;
79
99
  }
80
100
 
81
101
  public int Counter { get; set; }
102
+ public object Sender {get; set; }
103
+ public EventArgs Args { get; set; }
82
104
 
83
105
  private void OnExposedChanged(object sender, EventArgs args){
84
106
  Counter++;
107
+ Sender = sender;
108
+ Args = args;
85
109
  }
86
110
 
87
111
  }