aidmock 0.1.0

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.
@@ -0,0 +1,237 @@
1
+ # Copyright (c) 2011 Wilker Lúcio
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ describe Aidmock::Matchers do
22
+ m = ::Aidmock::Matchers
23
+
24
+ trueMatch = Class.new do
25
+ def match?(obj)
26
+ true
27
+ end
28
+ end.new
29
+
30
+ falseMatch = Class.new do
31
+ def match?(obj)
32
+ false
33
+ end
34
+ end.new
35
+
36
+ context "create matcher by value" do
37
+ it "use the matcher if one is sent" do
38
+ m.create(trueMatch).should == trueMatch
39
+ end
40
+
41
+ it "use an AnyMatcher if an array is sent" do
42
+ m.create([trueMatch, falseMatch]).should be_an_instance_of(m::AnyMatcher)
43
+ end
44
+
45
+ it "use KindOfMatcher if a class is sent" do
46
+ m.create(String).should be_an_instance_of(m::KindOfMatcher)
47
+ end
48
+
49
+ it "use AnythingMatcher if nil is sent" do
50
+ m.create(nil).should be_an_instance_of(m::AnythingMatcher)
51
+ end
52
+
53
+ it "use DuckTypeMatcher if receive a symbol" do
54
+ m.create(:to_s).should be_an_instance_of(m::DuckTypeMatcher)
55
+ end
56
+
57
+ it "use HashMatcher if receive a hash" do
58
+ m.create(:name => nil).should be_an_instance_of(m::HashMatcher)
59
+ end
60
+
61
+ it "raise error if can't figure a matcher" do
62
+ expect { m.create("") }.to raise_error
63
+ end
64
+ end
65
+
66
+ context "matchers" do
67
+ context "AnyMatcher" do
68
+ it "pass if any of matchers matches" do
69
+ matcher = m::AnyMatcher.new(falseMatch, trueMatch)
70
+ matcher.should matches("obj")
71
+ end
72
+
73
+ it "fails if no matcher can match" do
74
+ matcher = m::AnyMatcher.new(falseMatch, falseMatch)
75
+ matcher.should_not matches("obj")
76
+ end
77
+ end
78
+
79
+ context "AnythingMatcher" do
80
+ it "always pass" do
81
+ matcher = m::AnythingMatcher.new
82
+ matcher.should matches("something")
83
+ end
84
+
85
+ it "should pass with nil" do
86
+ matcher = m::AnythingMatcher.new
87
+ matcher.should matches(nil)
88
+ end
89
+ end
90
+
91
+ context "DuckTypeMatcher" do
92
+ it "pass if object respond to all methods" do
93
+ matcher = m::DuckTypeMatcher.new(:to_s, :gsub)
94
+ matcher.should matches("string")
95
+ end
96
+
97
+ it "pass if object is nil" do
98
+ matcher = m::DuckTypeMatcher.new(:to_s, :gsub)
99
+ matcher.should matches(nil)
100
+ end
101
+
102
+ it "fail if object don't respond to any of methods" do
103
+ matcher = m::DuckTypeMatcher.new(:to_s, :gsub, :i_fail_things)
104
+ matcher.should_not matches("string")
105
+ end
106
+ end
107
+
108
+ context "InstanceOfMatcher" do
109
+ it "pass if the object is an instance of given" do
110
+ matcher = m::InstanceOfMatcher.new(String)
111
+ matcher.should matches("string")
112
+ end
113
+
114
+ it "pass if the object is nil" do
115
+ matcher = m::InstanceOfMatcher.new(String)
116
+ matcher.should matches(nil)
117
+ end
118
+
119
+ it "fail if object is not an instance of given" do
120
+ matcher = m::InstanceOfMatcher.new(Numeric)
121
+ matcher.should_not matches(4)
122
+ end
123
+ end
124
+
125
+ context "KindOfMatcher" do
126
+ it "pass if the object is an instance of given" do
127
+ matcher = m::KindOfMatcher.new(String)
128
+ matcher.should matches("string")
129
+ end
130
+
131
+ it "pass if the object is an kind of given" do
132
+ matcher = m::KindOfMatcher.new(Numeric)
133
+ matcher.should matches(4)
134
+ end
135
+
136
+ it "pass if the object is nil" do
137
+ matcher = m::KindOfMatcher.new(String)
138
+ matcher.should matches(nil)
139
+ end
140
+
141
+ it "fail if object is not an instance of given" do
142
+ matcher = m::KindOfMatcher.new(String)
143
+ matcher.should_not matches(4)
144
+ end
145
+ end
146
+
147
+ context "HashMatcher" do
148
+ context "flexible mode" do
149
+ it "pass if hash contains only valid keys" do
150
+ matcher = m::HashMatcher.new(:name => trueMatch, :email => falseMatch)
151
+ matcher.should matches(:name => "hi")
152
+ end
153
+
154
+ it "pass if the object is nil" do
155
+ matcher = m::HashMatcher.new(:name => trueMatch, :email => falseMatch)
156
+ matcher.should matches(nil)
157
+ end
158
+
159
+ it "fails if send an invalid key to hash" do
160
+ matcher = m::HashMatcher.new(:name => trueMatch, :email => trueMatch)
161
+ matcher.should_not matches(:other => "hi")
162
+ end
163
+
164
+ it "fails if send a valid key with invalid value" do
165
+ matcher = m::HashMatcher.new(:name => falseMatch, :email => trueMatch)
166
+ matcher.should_not matches(:name => "bar")
167
+ end
168
+ end
169
+
170
+ context "strict mode" do
171
+ it "pass if hash contains all valid keys" do
172
+ matcher = m::HashMatcher.new({:name => trueMatch, :email => trueMatch}, true)
173
+ matcher.should matches(:name => "hi", :email => "ho")
174
+ end
175
+
176
+ it "fails if any key is missing" do
177
+ matcher = m::HashMatcher.new({:name => trueMatch, :email => trueMatch}, true)
178
+ matcher.should_not matches(:name => "hi")
179
+ end
180
+
181
+ it "fails if has extra keys" do
182
+ matcher = m::HashMatcher.new({:name => trueMatch, :email => trueMatch}, true)
183
+ matcher.should_not matches(:name => "hi", :email => "ho", :other => "hu")
184
+ end
185
+ end
186
+ end
187
+
188
+ context "NotNilArgMatcher" do
189
+ it "pass if internal matcher pass" do
190
+ matcher = m::NotNilArgMatcher.new(trueMatch)
191
+ matcher.should matches("hi")
192
+ end
193
+
194
+ it "fails if internal matcher fails" do
195
+ matcher = m::NotNilArgMatcher.new(falseMatch)
196
+ matcher.should_not matches("hi")
197
+ end
198
+
199
+ it "fails if object is nil" do
200
+ matcher = m::NotNilArgMatcher.new(trueMatch)
201
+ matcher.should_not matches(nil)
202
+ end
203
+ end
204
+
205
+ context "OptionalArgMatcher" do
206
+ it "just call match at given matcher" do
207
+ matcher = m::OptionalArgMatcher.new(trueMatch)
208
+ matcher.should matches("thing")
209
+ end
210
+ end
211
+
212
+ context "SplatArgMatcher" do
213
+ it "use anything matcher by default" do
214
+ matcher = m::SplatArgMatcher.new
215
+ matcher.should matches([true])
216
+ end
217
+
218
+ it "should try to match every given value at splat" do
219
+ matcher = m::SplatArgMatcher.new(trueMatch)
220
+ trueMatch.should_receive(:match?).with(1) { true }
221
+ trueMatch.should_receive(:match?).with(2) { true }
222
+ trueMatch.should_receive(:match?).with(3) { true }
223
+
224
+ matcher.should matches([1, 2, 3])
225
+ end
226
+
227
+ it "fail if any of args don't respect matcher" do
228
+ matcher = m::SplatArgMatcher.new(trueMatch)
229
+ trueMatch.stub(:match?).with(1) { true }
230
+ trueMatch.stub(:match?).with(2) { false }
231
+ trueMatch.stub(:match?).with(3) { true }
232
+
233
+ matcher.should_not matches([1, 2, 3])
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,205 @@
1
+ # Copyright (c) 2011 Wilker Lúcio
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ describe Aidmock::MethodDescriptor do
22
+ mock_descriptor = Aidmock::Frameworks::MockDescriptor
23
+ md = Aidmock::MethodDescriptor
24
+ m = Aidmock::Matchers
25
+
26
+ trueMatch = Class.new do
27
+ def match?(obj)
28
+ true
29
+ end
30
+ end.new
31
+
32
+ falseMatch = Class.new do
33
+ def match?(obj)
34
+ false
35
+ end
36
+ end.new
37
+
38
+ def mock_return(val)
39
+ Aidmock::Frameworks::MockDescriptor.new(nil, :some, val)
40
+ end
41
+
42
+ def mock_args(args)
43
+ Aidmock::Frameworks::MockDescriptor.new(nil, :some, nil, args)
44
+ end
45
+
46
+ it "verify the arguments and return value" do
47
+ double = mock_descriptor.new(nil, :method, :result, [:args])
48
+ desc = md.new(:some, nil)
49
+ desc.should_receive(:verify_arguments).with(double)
50
+ desc.should_receive(:verify_return).with(double)
51
+ desc.verify(double)
52
+ end
53
+
54
+ context "verifying return value" do
55
+ it "raise error if return value don't match" do
56
+ desc = md.new(:some, falseMatch)
57
+
58
+ expect { desc.verify_return(mock_return([nil])) }.to raise_error(Aidmock::MethodInterfaceReturnNotMatchError)
59
+ end
60
+
61
+ it "not raise error if return value match" do
62
+ desc = md.new(:some, trueMatch)
63
+
64
+ expect { desc.verify_return(mock_return([nil])) }.to_not raise_error
65
+ end
66
+
67
+ it "send double value to matcher" do
68
+ desc = md.new(:some, trueMatch)
69
+ trueMatch.should_receive(:match?).with("hi").and_return(true)
70
+ trueMatch.should_receive(:match?).with("ho").and_return(true)
71
+
72
+ desc.verify_return(mock_return(["hi", "ho"]))
73
+ end
74
+ end
75
+
76
+ context "verifying arguments" do
77
+ context "testing arguments arity" do
78
+ context "on fixed arguments length" do
79
+ it "raise error if user send less arguments than method expects" do
80
+ desc = md.new(:some, nil, trueMatch, trueMatch)
81
+
82
+ expect { desc.verify_arguments(mock_args([5]))}.to raise_error(Aidmock::MethodInterfaceArgumentsNotMatchError, "error on mock method :some, expected 2 arguments, 1 sent")
83
+ end
84
+
85
+ it "raise error if user send more arguments than method expects" do
86
+ desc = md.new(:some, nil, trueMatch, trueMatch)
87
+
88
+ expect { desc.verify_arguments(mock_args([5, 6, 7]))}.to raise_error(Aidmock::MethodInterfaceArgumentsNotMatchError, "error on mock method :some, expected 2 arguments, 3 sent")
89
+ end
90
+
91
+ it "not raise error if they are in correct arity" do
92
+ desc = md.new(:some, nil, trueMatch, trueMatch)
93
+
94
+ expect { desc.verify_arguments(mock_args([5, 6]))}.to_not raise_error
95
+ end
96
+ end
97
+
98
+ context "on variable arguments length" do
99
+ it "raise error if number of arguments is less than required ones" do
100
+ desc = md.new(:some, nil, trueMatch, Aidmock::Matchers::OptionalArgMatcher.new(trueMatch))
101
+
102
+ expect { desc.verify_arguments(mock_args([])) }.to raise_error(Aidmock::MethodInterfaceArgumentsNotMatchError, "error on mock method :some, expected at least 1, 0 sent")
103
+ end
104
+
105
+ it "raise error if it has more args than possible (after optional ones)" do
106
+ desc = md.new(:some, nil, trueMatch, Aidmock::Matchers::OptionalArgMatcher.new(trueMatch))
107
+
108
+ expect { desc.verify_arguments(mock_args([1, 2, 3])) }.to raise_error(Aidmock::MethodInterfaceArgumentsNotMatchError, "error on mock method :some, expected at most 2, 3 sent")
109
+ end
110
+
111
+ it "dont raise error if fits on argument length" do
112
+ desc = md.new(:some, nil, trueMatch, Aidmock::Matchers::OptionalArgMatcher.new(trueMatch))
113
+
114
+ expect { desc.verify_arguments(mock_args([1])) }.to_not raise_error
115
+ expect { desc.verify_arguments(mock_args([1, 2])) }.to_not raise_error
116
+ end
117
+
118
+ it "dont raise error if has more arguments than max, but has a splat" do
119
+ desc = md.new(:some, nil, trueMatch, Aidmock::Matchers::SplatArgMatcher.new(trueMatch))
120
+
121
+ expect { desc.verify_arguments(mock_args([1, 2, 3])) }.to_not raise_error
122
+ end
123
+ end
124
+ end
125
+
126
+ context "checking arguments" do
127
+ it "try each argument on respective matcher" do
128
+ m1 = mock
129
+ m2 = mock
130
+
131
+ m1.should_receive(:match?).with(1).and_return(true)
132
+ m2.should_receive(:match?).with(2).and_return(true)
133
+
134
+ desc = md.new(:some, nil, m1, m2)
135
+ desc.verify_arguments(mock_args([1, 2]))
136
+ end
137
+
138
+ it "raise error if any matcher fail" do
139
+ desc = md.new(:some, nil, falseMatch, trueMatch)
140
+
141
+ expect { desc.verify_arguments(mock_args([1, 2])) }.to raise_error(Aidmock::MethodInterfaceArgumentsNotMatchError)
142
+ end
143
+
144
+ it "send an array with others if has a splat" do
145
+ matcher = mock
146
+ matcher.should_receive(:match?).with(2).and_return(true)
147
+ matcher.should_receive(:match?).with(3).and_return(true)
148
+
149
+ desc = md.new(:some, nil, trueMatch, Aidmock::Matchers::SplatArgMatcher.new(matcher))
150
+ desc.verify_arguments(mock_args([1, 2, 3]))
151
+ end
152
+ end
153
+ end
154
+
155
+ context "#arity" do
156
+ it "return 0 if no arguments are given" do
157
+ md.new(:some, nil).arity.should == 0
158
+ end
159
+
160
+ it "return positive number of arguments if they are regular ones" do
161
+ md.new(:some, nil, nil, nil).arity.should == 2
162
+ end
163
+
164
+ it "return -1 if start with optional argument" do
165
+ md.new(:some, nil, m::OptionalArgMatcher.new(nil)).arity.should == -1
166
+ end
167
+
168
+ it "return -1 if start with splat argument" do
169
+ md.new(:some, nil, m::SplatArgMatcher.new(nil)).arity.should == -1
170
+ end
171
+
172
+ it "return negative value when has both optional and required args" do
173
+ md.new(:some, nil, nil, m::OptionalArgMatcher.new(nil)).arity.should == -2
174
+ end
175
+
176
+ it "return negative value when has both splt and required args" do
177
+ md.new(:some, nil, nil, m::SplatArgMatcher.new(nil)).arity.should == -2
178
+ end
179
+
180
+ it "return negative when have optional, required and splt args" do
181
+ md.new(:some, nil, nil, m::OptionalArgMatcher.new(nil), m::SplatArgMatcher.new(nil)).arity.should == -2
182
+ end
183
+ end
184
+
185
+ context "#required_arity" do
186
+ before :each do
187
+ @m = md.new(:some, nil)
188
+ end
189
+
190
+ it "return arity if its positive" do
191
+ @m.stub(:arity).and_return(1)
192
+ @m.required_arity.should == 1
193
+ end
194
+
195
+ it "return 0 if arity is 0" do
196
+ @m.stub(:arity).and_return(0)
197
+ @m.required_arity.should == 0
198
+ end
199
+
200
+ it "return arity positive less 1 if it's negative" do
201
+ @m.stub(:arity).and_return(-2)
202
+ @m.required_arity.should == 1
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,119 @@
1
+ # Copyright (c) 2011 Wilker Lúcio
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ describe Aidmock::Sanity do
22
+ context ".sanitize_interfaces" do
23
+ it "check each defined interface" do
24
+ m1 = mock
25
+ m2 = mock
26
+
27
+ Aidmock.stub!(:interfaces).and_return({:a => m1, :b => m2})
28
+ Aidmock::Sanity.should_receive(:sanitize_interface).with(m1)
29
+ Aidmock::Sanity.should_receive(:sanitize_interface).with(m2)
30
+
31
+ Aidmock::Sanity.sanitize_interfaces
32
+ end
33
+ end
34
+
35
+ context ".sanitize_interface" do
36
+ it "check each method defined on interface" do
37
+ m1 = mock
38
+ m2 = mock
39
+ m3 = mock
40
+ m4 = mock
41
+ ca = mock
42
+
43
+ interface = Aidmock::Interface.allocate
44
+ interface.stub(:methods).and_return([m1, m2])
45
+ interface.stub(:class_methods).and_return([m3, m4])
46
+ interface.stub(:klass).and_return(ca)
47
+
48
+ Aidmock::Sanity.should_receive(:sanitize_method).with(ca, m1)
49
+ Aidmock::Sanity.should_receive(:sanitize_method).with(ca, m2)
50
+ Aidmock::Sanity.should_receive(:sanitize_method).with(ca, m3)
51
+ Aidmock::Sanity.should_receive(:sanitize_method).with(ca, m4)
52
+
53
+ Aidmock::Sanity.sanitize_interface(interface)
54
+ end
55
+ end
56
+
57
+ context ".sanitize_method" do
58
+ before :each do
59
+ @ca = mock(:allocate => Object)
60
+ @me = mock(:name => :to_s, :arity => 0, :class_method? => false)
61
+ end
62
+
63
+ it "verify if method is defined" do
64
+ Aidmock::Sanity.should_receive(:verify_method_defined).with(@ca, @me)
65
+ Aidmock::Sanity.sanitize_method(@ca, @me)
66
+ end
67
+
68
+ it "verify if method arity" do
69
+ Aidmock::Sanity.should_receive(:verify_method_arity).with(@ca, @me)
70
+ Aidmock::Sanity.sanitize_method(@ca, @me)
71
+ end
72
+ end
73
+
74
+ context ".verify_method_defined" do
75
+ it "raise error if object don't have the method defined" do
76
+ klass = Object
77
+ method = Aidmock::MethodDescriptor.new(:foo_isnt_here, nil)
78
+
79
+ expect { Aidmock::Sanity.verify_method_defined(klass, method) }.to raise_error("Aidmock Sanity: method 'foo_isnt_here' is not defined for Object")
80
+ end
81
+
82
+ it "don't raise error if object has the method" do
83
+ klass = Object
84
+ method = Aidmock::MethodDescriptor.new(:to_s, nil)
85
+
86
+ expect { Aidmock::Sanity.verify_method_defined(klass, method) }.to_not raise_error
87
+ end
88
+
89
+ it "don't check for regexp methods" do
90
+ klass = String
91
+ method = Aidmock::MethodDescriptor.new(/concat_.*/, nil, [String, Fixnum])
92
+
93
+ expect { Aidmock::Sanity.verify_method_arity(klass, method) }.to_not raise_error
94
+ end
95
+ end
96
+
97
+ context ".verify_method_arity" do
98
+ it "raise error if arity is different" do
99
+ klass = String
100
+ method = Aidmock::MethodDescriptor.new(:gsub, nil)
101
+
102
+ expect { Aidmock::Sanity.verify_method_arity(klass, method) }.to raise_error("Aidmock Sanity: method 'gsub' of String mismatch interface arity, -1 for 0")
103
+ end
104
+
105
+ it "not raise error if arity is same" do
106
+ klass = String
107
+ method = Aidmock::MethodDescriptor.new(:concat, nil, [String, Fixnum])
108
+
109
+ expect { Aidmock::Sanity.verify_method_arity(klass, method) }.to_not raise_error
110
+ end
111
+
112
+ it "don't check for regexp methods" do
113
+ klass = String
114
+ method = Aidmock::MethodDescriptor.new(/concat_.*/, nil, [String, Fixnum])
115
+
116
+ expect { Aidmock::Sanity.verify_method_arity(klass, method) }.to_not raise_error
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2011 Wilker Lúcio
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ describe Aidmock do
22
+ context ".interface" do
23
+ end
24
+
25
+ context ".stub" do
26
+ end
27
+
28
+ context ".verify" do
29
+ it "do verify double on each double returned by framework" do
30
+ m1 = mock; m2 = mock; m3 = mock
31
+ framework = stub(:mocks => [m1, m2, m3])
32
+ Aidmock.stub!(:framework) { framework }
33
+
34
+ Aidmock.should_receive(:verify_double).with(m1) { nil }
35
+ Aidmock.should_receive(:verify_double).with(m2) { nil }
36
+ Aidmock.should_receive(:verify_double).with(m3) { nil }
37
+
38
+ Aidmock.verify
39
+ end
40
+ end
41
+
42
+ context ".verify_double" do
43
+ it "call to verify chain if the chain has any element" do
44
+ double = Aidmock::Frameworks::MockDescriptor.new("object", :to_s, nil, [])
45
+
46
+ Aidmock.stub!(:chain_for).with(String) { [String] }
47
+ Aidmock.should_receive(:verify_double_on_chain).with(double, [String])
48
+
49
+ Aidmock.send :verify_double, double
50
+ end
51
+ end
52
+
53
+ context ".verify_double_on_chain" do
54
+ it "call verify on method descriptor if method exists" do
55
+ double = mock
56
+ chain = mock
57
+ method = mock
58
+ method.should_receive(:verify).with(double)
59
+
60
+ Aidmock.stub!(:find_method_on_chain).with(double, chain).and_return(method)
61
+
62
+ Aidmock.send(:verify_double_on_chain, double, chain)
63
+ end
64
+
65
+ it "raise error if method can't be found" do
66
+ double = stub(:method => nil, :object => nil)
67
+ chain = mock
68
+
69
+ Aidmock.stub!(:find_method_on_chain).with(double, chain).and_return(nil)
70
+
71
+ expect { Aidmock.send(:verify_double_on_chain, double, chain) }.to raise_error(Aidmock::MethodInterfaceNotDefinedError)
72
+ end
73
+ end
74
+
75
+ context ".find_method_on_chain" do
76
+ it "get method if the interface has it" do
77
+ double = stub(:method => :some)
78
+ interface = stub
79
+ interface.stub(:find_method).with(double).and_return(true)
80
+
81
+ Aidmock.send(:find_method_on_chain, double, [interface]).should == true
82
+ end
83
+
84
+ it "return nil if no interface has the method" do
85
+ double = stub(:method => :some)
86
+ interface = stub
87
+ interface.stub(:find_method).with(double) { nil }
88
+
89
+ Aidmock.send(:find_method_on_chain, double, [interface]).should == nil
90
+ end
91
+
92
+ it "use first occurence if more than one on chain can respond to method" do
93
+ m1 = mock, m2 = mock
94
+ double = stub(:method => :some)
95
+ interface = stub
96
+ interface.stub(:find_method).with(double) { nil }
97
+ interface2 = stub
98
+ interface2.stub(:find_method).with(double) { m1 }
99
+ interface3 = stub
100
+ interface3.stub(:find_method).with(double) { m2 }
101
+
102
+ Aidmock.send(:find_method_on_chain, double, [interface, interface2, interface3]).should == m1
103
+ end
104
+ end
105
+
106
+ context ".class_chain" do
107
+ it "get chain of defined interfaces on a class" do
108
+ m1 = mock
109
+ m2 = mock
110
+ Aidmock.stub!(:interfaces).and_return({String => m1, Object => m2, Fixnum => true})
111
+ Aidmock.send(:chain_for, String).should == [m1, m2]
112
+ end
113
+ end
114
+
115
+ context ".extract_class" do
116
+ it "return the object class if it's an instance" do
117
+ Aidmock.send(:extract_class, "string").should == String
118
+ end
119
+
120
+ it "return the object if it's an class" do
121
+ Aidmock.send(:extract_class, String).should == String
122
+ end
123
+ end
124
+ end