muack 1.1.1 → 1.1.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGES.md +10 -0
- data/Gemfile +1 -1
- data/README.md +43 -9
- data/lib/muack.rb +5 -0
- data/lib/muack/any_instance_of.rb +4 -0
- data/lib/muack/coat.rb +16 -0
- data/lib/muack/failure.rb +1 -1
- data/lib/muack/mock.rb +13 -11
- data/lib/muack/session.rb +16 -10
- data/lib/muack/test.rb +3 -10
- data/lib/muack/version.rb +1 -1
- data/muack.gemspec +7 -4
- data/task/gemgem.rb +1 -5
- data/test/test_any_instance_of.rb +25 -27
- data/test/test_coat.rb +48 -0
- data/test/test_from_readme.rb +3 -3
- data/test/test_mock.rb +64 -90
- data/test/test_modifier.rb +17 -17
- data/test/test_proxy.rb +20 -24
- data/test/test_satisfy.rb +97 -179
- data/test/test_stub.rb +50 -74
- metadata +6 -3
data/test/test_coat.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require 'muack/test'
|
3
|
+
|
4
|
+
describe Muack::Coat do
|
5
|
+
after do
|
6
|
+
Muack.verify.should.eq true
|
7
|
+
Muack::EnsureReset.call
|
8
|
+
end
|
9
|
+
|
10
|
+
would 'wear out' do
|
11
|
+
coat(Str).to_s{ 'Coat' }
|
12
|
+
Str.to_s.should.eq 'Coat'
|
13
|
+
Str.to_s.should.eq 'Moo'
|
14
|
+
end
|
15
|
+
|
16
|
+
would 'wear out 2 times' do
|
17
|
+
coat(Str).to_s{ 'Coat' }.times(2)
|
18
|
+
2.times{ Str.to_s.should.eq 'Coat' }
|
19
|
+
Str.to_s.should.eq 'Moo'
|
20
|
+
end
|
21
|
+
|
22
|
+
would 'call the original method' do
|
23
|
+
coat(Str).to_s{ Str.to_s.reverse }
|
24
|
+
Str.to_s.should.eq 'ooM'
|
25
|
+
Str.to_s.should.eq 'Moo'
|
26
|
+
end
|
27
|
+
|
28
|
+
would 'raise Expected error if coated method is not called' do
|
29
|
+
coat(Obj).say{ 'nnf' }
|
30
|
+
e = should.raise(Muack::Expected){ Muack.verify }
|
31
|
+
e.expected .should.eq 'obj.say()'
|
32
|
+
e.expected_times.should.eq 1
|
33
|
+
e.actual_times .should.eq 0
|
34
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
35
|
+
"called 1 times\n but was 0 times."
|
36
|
+
end
|
37
|
+
|
38
|
+
would 'raise Expected error if coated method is not called' do
|
39
|
+
coat(Obj).say{ 'nnf' }.times(2)
|
40
|
+
Obj.say.should.eq 'nnf'
|
41
|
+
e = should.raise(Muack::Expected){ Muack.verify }
|
42
|
+
e.expected .should.eq 'obj.say()'
|
43
|
+
e.expected_times.should.eq 2
|
44
|
+
e.actual_times .should.eq 1
|
45
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
46
|
+
"called 2 times\n but was 1 times."
|
47
|
+
end
|
48
|
+
end
|
data/test/test_from_readme.rb
CHANGED
@@ -9,7 +9,7 @@ describe 'from README.md' do
|
|
9
9
|
after{ Muack.reset }
|
10
10
|
|
11
11
|
Context = Module.new{
|
12
|
-
include Muack::API
|
12
|
+
include Pork::API, Muack::API
|
13
13
|
|
14
14
|
def results; @results ||= []; end
|
15
15
|
def p res ; results << res ; end
|
@@ -19,7 +19,7 @@ describe 'from README.md' do
|
|
19
19
|
results.zip(expects).each do |(res, exp)|
|
20
20
|
next if exp == 'ok'
|
21
21
|
if exp.start_with?('raise')
|
22
|
-
res.should.kind_of eval(exp.sub('raise', ''))
|
22
|
+
res.should.kind_of? eval(exp.sub('raise', ''))
|
23
23
|
else
|
24
24
|
res.should.eq eval(exp)
|
25
25
|
end
|
@@ -28,7 +28,7 @@ describe 'from README.md' do
|
|
28
28
|
}
|
29
29
|
|
30
30
|
codes.each.with_index do |code, index|
|
31
|
-
|
31
|
+
would 'pass from README.md #%02d' % index do
|
32
32
|
context = Module.new{extend Context}
|
33
33
|
begin
|
34
34
|
context.instance_eval(code, 'README.md', 0)
|
data/test/test_mock.rb
CHANGED
@@ -8,31 +8,31 @@ describe Muack::Mock do
|
|
8
8
|
Muack::EnsureReset.call
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
would 'inspect' do
|
12
12
|
mock(Obj).inspect.should.eq "Muack::API.mock(obj)"
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
would 'mock with regular method' do
|
16
16
|
mock(Obj).say(true){ 'boo' }
|
17
17
|
Obj.say(true).should.eq 'boo'
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
would 'mock existing method' do
|
21
21
|
mock(Obj).to_s{ 'zoo' }
|
22
22
|
Obj.to_s.should.eq 'zoo'
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
would 'pass the actual block' do
|
26
26
|
mock(Obj).say{ |&block| block.call('Hi') }
|
27
27
|
Obj.say{ |msg| msg }.should.eq 'Hi'
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
would 'pass multiple arguments' do
|
31
31
|
mock(Obj).say{ |*args| args.reverse }.with_any_args
|
32
32
|
Obj.say(0, 1).should.eq [1, 0]
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
would 'mock private method and preserve privacy' do
|
36
36
|
mock(Obj).private{ 'sai' }
|
37
37
|
Obj.respond_to?(:private ).should.eq false
|
38
38
|
Obj.respond_to?(:private, true).should.eq true
|
@@ -42,13 +42,13 @@ describe Muack::Mock do
|
|
42
42
|
Obj.__send__(:private).should.eq 'pri'
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
would 'mock twice' do
|
46
46
|
mock(Obj).say(true){ Obj.saya }
|
47
47
|
mock(Obj).saya{ 'coo' }
|
48
48
|
Obj.say(true).should.eq 'coo'
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
would 'also mock with with' do
|
52
52
|
mock(Str).method_missing(:say, 0){ 0 }
|
53
53
|
Str.say(0).should.eq 0
|
54
54
|
Muack.verify.should.eq true
|
@@ -57,45 +57,45 @@ describe Muack::Mock do
|
|
57
57
|
Muack.reset
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
would 'mix mock and stub' do
|
61
61
|
mock(Obj).say { 0 }
|
62
62
|
stub(Obj).saya{ 1 }
|
63
63
|
3.times{ Obj.saya.should.eq 1 }
|
64
64
|
Obj.say .should.eq 0
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
would 'mix mock and stub with conflicting method, latter wins' do
|
68
68
|
stub(Obj).say{0}
|
69
69
|
mock(Obj).say{1}
|
70
70
|
Obj.say.should.eq 1
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
would 'mix mock and stub with conflicting method, try to hit stub' do
|
74
74
|
stub(Obj).say{0}
|
75
75
|
mock(Obj).say{1}
|
76
76
|
Obj.say.should.eq 1
|
77
77
|
lambda{ Obj.say }.should.raise(Muack::Expected)
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
would 'mix mock and stub with conflicting method, mock never called' do
|
81
81
|
mock(Obj).say{0}
|
82
82
|
stub(Obj).say{1}
|
83
83
|
Obj.say.should.eq 1
|
84
84
|
lambda{ Muack.verify }.should.raise(Muack::Expected)
|
85
85
|
end
|
86
86
|
|
87
|
-
|
87
|
+
would 'unnamed mock' do
|
88
88
|
mock.say{1}.object.say.should.eq 1
|
89
89
|
end
|
90
90
|
|
91
|
-
|
91
|
+
would 'mock and call, mock and call' do
|
92
92
|
mock(Obj).say{0}
|
93
93
|
Obj.say.should.eq 0
|
94
94
|
mock(Obj).say{1}
|
95
95
|
Obj.say.should.eq 1
|
96
96
|
end
|
97
97
|
|
98
|
-
|
98
|
+
would 'not remove original singleton method' do
|
99
99
|
obj = Class.new{ def self.f; 0; end }
|
100
100
|
2.times{ mock(obj).f{ 1 } }
|
101
101
|
2.times{ obj.f.should.eq 1 }
|
@@ -110,111 +110,85 @@ describe Muack::Mock do
|
|
110
110
|
Muack::EnsureReset.call
|
111
111
|
end
|
112
112
|
|
113
|
-
|
113
|
+
would 'raise Unexpected error if passing unexpected argument' do
|
114
114
|
mock(Obj).say(true){ 'boo' }
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
e.expected.should.eq 'obj.say(true)'
|
120
|
-
e.was .should.eq 'obj.say(false)'
|
121
|
-
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
122
|
-
end
|
115
|
+
e = should.raise(Muack::Unexpected){ Obj.say(false) }
|
116
|
+
e.expected.should.eq 'obj.say(true)'
|
117
|
+
e.was .should.eq 'obj.say(false)'
|
118
|
+
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
123
119
|
end
|
124
120
|
|
125
|
-
|
121
|
+
would 'have correct message for multiple mocks with the same name' do
|
126
122
|
2.times{ mock(Obj).say{} }
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
e.actual_times .should.eq 3
|
134
|
-
e.message .should.eq "\nExpected: obj.say()\n " \
|
135
|
-
"called 2 times\n but was 3 times."
|
136
|
-
end
|
123
|
+
e = should.raise(Muack::Expected){ 3.times{ Obj.say } }
|
124
|
+
e.expected.should.eq 'obj.say()'
|
125
|
+
e.expected_times.should.eq 2
|
126
|
+
e.actual_times .should.eq 3
|
127
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
128
|
+
"called 2 times\n but was 3 times."
|
137
129
|
end
|
138
130
|
|
139
|
-
|
131
|
+
would 'have correct message for mocks with special satisfier' do
|
140
132
|
mock(Obj).say(anything){}
|
141
|
-
|
133
|
+
e = should.raise(Muack::Expected) do
|
142
134
|
Obj.say(1)
|
143
135
|
Obj.say(2)
|
144
|
-
'never'.should.eq 'reach'
|
145
|
-
rescue Muack::Expected => e
|
146
|
-
expected = 'obj.say(Muack::API.anything())'
|
147
|
-
e.expected.should.eq expected
|
148
|
-
e.expected_times.should.eq 1
|
149
|
-
e.actual_times .should.eq 2
|
150
|
-
e.message .should.eq "\nExpected: #{expected}\n " \
|
151
|
-
"called 1 times\n but was 2 times."
|
152
136
|
end
|
137
|
+
expected = 'obj.say(Muack::API.anything())'
|
138
|
+
e.expected.should.eq expected
|
139
|
+
e.expected_times.should.eq 1
|
140
|
+
e.actual_times .should.eq 2
|
141
|
+
e.message .should.eq "\nExpected: #{expected}\n " \
|
142
|
+
"called 1 times\n but was 2 times."
|
153
143
|
end
|
154
144
|
|
155
|
-
|
145
|
+
would 'raise if a mock with times(0) gets called' do
|
156
146
|
mock(Obj).say.times(0)
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
e.expected.should.eq nil
|
162
|
-
e.was .should.eq 'obj.say()'
|
163
|
-
e.message .should.eq "\nUnexpected call: #{e.was}"
|
164
|
-
end
|
147
|
+
e = should.raise(Muack::Unexpected){ Obj.say }
|
148
|
+
e.expected.should.eq nil
|
149
|
+
e.was .should.eq 'obj.say()'
|
150
|
+
e.message .should.eq "\nUnexpected call: #{e.was}"
|
165
151
|
end
|
166
152
|
|
167
|
-
|
153
|
+
would 'raise if a mock with times(0) gets called with diff sig' do
|
168
154
|
mock(Obj).say.times(0)
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
e.expected.should.eq nil
|
174
|
-
e.was .should.eq 'obj.say(true)'
|
175
|
-
e.message .should.eq "\nUnexpected call: #{e.was}"
|
176
|
-
end
|
155
|
+
e = should.raise(Muack::Unexpected){ Obj.say(true) }
|
156
|
+
e.expected.should.eq nil
|
157
|
+
e.was .should.eq 'obj.say(true)'
|
158
|
+
e.message .should.eq "\nUnexpected call: #{e.was}"
|
177
159
|
end
|
178
160
|
|
179
|
-
|
161
|
+
would 'raise Unexpected when calling with diff sig' do
|
180
162
|
mock(Obj).say(true){1}
|
181
163
|
Obj.say(true).should.eq 1
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
e.expected.should.eq 'obj.say(true)'
|
187
|
-
e.was .should.eq 'obj.say()'
|
188
|
-
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
189
|
-
end
|
164
|
+
e = should.raise(Muack::Unexpected){ Obj.say }
|
165
|
+
e.expected.should.eq 'obj.say(true)'
|
166
|
+
e.was .should.eq 'obj.say()'
|
167
|
+
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
190
168
|
end
|
191
169
|
|
192
|
-
|
170
|
+
would 'raise Expected error if mock methods not called' do
|
193
171
|
mock(Obj).say(true){ 'boo' }
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
e.message .should.eq "\nExpected: obj.say(true)\n " \
|
201
|
-
"called 1 times\n but was 0 times."
|
202
|
-
end
|
172
|
+
e = should.raise(Muack::Expected){ Muack.verify }
|
173
|
+
e.expected .should.eq 'obj.say(true)'
|
174
|
+
e.expected_times.should.eq 1
|
175
|
+
e.actual_times .should.eq 0
|
176
|
+
e.message .should.eq "\nExpected: obj.say(true)\n " \
|
177
|
+
"called 1 times\n but was 0 times."
|
203
178
|
end
|
204
179
|
|
205
|
-
|
180
|
+
would 'show first not enough calls' do
|
206
181
|
mock(Obj).say{ 'boo' }.times(2)
|
207
182
|
mock(Obj).saya{} .times(2)
|
208
|
-
|
183
|
+
e = should.raise(Muack::Expected) do
|
209
184
|
Obj.say
|
210
185
|
Muack.verify
|
211
|
-
rescue Muack::Expected => e
|
212
|
-
e.expected .should.eq 'obj.say()'
|
213
|
-
e.expected_times.should.eq 2
|
214
|
-
e.actual_times .should.eq 1
|
215
|
-
e.message .should.eq "\nExpected: obj.say()\n " \
|
216
|
-
"called 2 times\n but was 1 times."
|
217
186
|
end
|
187
|
+
e.expected .should.eq 'obj.say()'
|
188
|
+
e.expected_times.should.eq 2
|
189
|
+
e.actual_times .should.eq 1
|
190
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
191
|
+
"called 2 times\n but was 1 times."
|
218
192
|
end
|
219
193
|
end
|
220
194
|
end
|
data/test/test_modifier.rb
CHANGED
@@ -8,92 +8,92 @@ describe Muack::Modifier do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe 'times' do
|
11
|
-
|
11
|
+
would 'mock multiple times' do
|
12
12
|
3.times{ |i| mock(Obj).say(i){ i } }
|
13
13
|
3.times{ |i| Obj.say(i).should.eq i }
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
would 'mock multiple times with times(n) modifier' do
|
17
17
|
mock(Obj).say{ 0 }.times(3)
|
18
18
|
3.times{ |i| Obj.say.should.eq 0 }
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
mock(Obj).say{ 0 }.times(0).should.kind_of Muack::Modifier
|
21
|
+
would 'mock 0 times with times(0) modifier' do
|
22
|
+
mock(Obj).say{ 0 }.times(0).should.kind_of? Muack::Modifier
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'returns' do
|
27
|
-
|
27
|
+
would 'return with lexical scope' do
|
28
28
|
mock(Obj).say.returns{0}
|
29
29
|
Obj.say.should.eq 0
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
would 'return with dynamic scope' do
|
33
33
|
mock(Obj).say.returns(:instance_exec => true){object_id}
|
34
34
|
Obj.say.should.eq Obj.object_id
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
describe 'peek_args' do
|
39
|
-
|
39
|
+
would 'with lexical scope' do
|
40
40
|
str = 'ff'
|
41
41
|
stub(str).to_i.peek_args{16}
|
42
42
|
str.to_i.should.eq 255
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
would 'with dynamic scope' do
|
46
46
|
str = '16'
|
47
47
|
stub(str).to_i.peek_args(:instance_exec => true){Integer(self)}
|
48
48
|
str.to_i.should.eq 22
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
would 'modify' do
|
52
52
|
str = 'ff'
|
53
53
|
stub(str).to_i(is_a(Integer)).peek_args{ |radix| radix * 2 }
|
54
54
|
str.to_i(8).should.eq 255
|
55
55
|
end
|
56
56
|
|
57
|
-
|
57
|
+
would 'preserve args' do
|
58
58
|
stub(Obj).say{|*a|a}.with_any_args.peek_args{|*a|a}
|
59
59
|
Obj.say(0,1).should.eq [0,1]
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
would 'pass first args' do
|
63
63
|
stub(Obj).say{|*a|a}.with_any_args.peek_args{|a|a}
|
64
64
|
Obj.say(0,1).should.eq [0]
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
would 'pass nothing with nil' do
|
68
68
|
stub(Obj).say{|*a|a}.with_any_args.peek_args{}
|
69
69
|
Obj.say(0,1).should.eq []
|
70
70
|
end
|
71
71
|
|
72
|
-
|
72
|
+
would 'pass nothing with empty array' do
|
73
73
|
stub(Obj).say{|*a|a}.with_any_args.peek_args{[]}
|
74
74
|
Obj.say(0,1).should.eq []
|
75
75
|
end
|
76
76
|
|
77
|
-
|
77
|
+
would 'pass an empty array with [[]]' do
|
78
78
|
stub(Obj).say{|*a|a}.with_any_args.peek_args{[[]]}
|
79
79
|
Obj.say(0,1).should.eq [[]]
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
83
|
describe 'peek_return' do
|
84
|
-
|
84
|
+
would 'with lexical scope' do
|
85
85
|
str = 'ff'
|
86
86
|
stub(str).to_i.peek_return{16}
|
87
87
|
str.to_i.should.eq 16
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
would 'with dynamic scope' do
|
91
91
|
str = '16'
|
92
92
|
stub(str).to_i.peek_return(:instance_exec => true){Integer(self)+1}
|
93
93
|
str.to_i.should.eq 17
|
94
94
|
end
|
95
95
|
|
96
|
-
|
96
|
+
would 'modify' do
|
97
97
|
str = 'ff'
|
98
98
|
stub(str).to_i(is_a(Integer)).peek_return{ |result| result * 2 }
|
99
99
|
str.to_i(16).should.eq 510
|