muack 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +19 -9
- data/CHANGES.md +12 -0
- data/Gemfile +0 -4
- data/README.md +17 -16
- data/Rakefile +3 -4
- data/lib/muack/block.rb +4 -15
- data/lib/muack/block_26.rb +16 -0
- data/lib/muack/block_27.rb +16 -0
- data/lib/muack/coat.rb +1 -1
- data/lib/muack/definition.rb +4 -3
- data/lib/muack/failure.rb +5 -4
- data/lib/muack/mock.rb +123 -65
- data/lib/muack/spy.rb +3 -3
- data/lib/muack/stub.rb +7 -5
- data/lib/muack/test.rb +42 -11
- data/lib/muack/version.rb +1 -1
- data/muack.gemspec +65 -57
- data/task/README.md +8 -8
- data/task/gemgem.rb +29 -7
- data/test/test_any_instance_of.rb +16 -2
- data/test/test_from_readme.rb +5 -7
- data/test/test_keyargs.rb +111 -0
- data/test/test_modifier.rb +6 -6
- data/test/test_prepend.rb +121 -0
- data/test/test_proxy.rb +19 -4
- data/test/test_satisfying.rb +12 -12
- data/test/test_spy.rb +4 -4
- data/test/test_visibility.rb +120 -0
- metadata +15 -8
@@ -0,0 +1,111 @@
|
|
1
|
+
|
2
|
+
require 'muack/test'
|
3
|
+
|
4
|
+
describe Muack::Mock do
|
5
|
+
after do
|
6
|
+
Muack.verify.should.eq true
|
7
|
+
Muack::EnsureReset.call
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'passing single hash' do
|
11
|
+
would 'hash literal' do
|
12
|
+
mock(Obj).say({}, &:itself)
|
13
|
+
|
14
|
+
expect(Obj.say({})).eq({})
|
15
|
+
end
|
16
|
+
|
17
|
+
would 'hash literal with satisfying check' do
|
18
|
+
mock(Obj).say(is_a(Hash), &:itself)
|
19
|
+
|
20
|
+
expect(Obj.say({})).eq({})
|
21
|
+
end
|
22
|
+
|
23
|
+
would 'hash value' do
|
24
|
+
arg = {}
|
25
|
+
|
26
|
+
mock(Obj).say(arg, &:itself)
|
27
|
+
|
28
|
+
expect(Obj.say(arg)).eq(arg)
|
29
|
+
end
|
30
|
+
|
31
|
+
would 'non-empty hash' do
|
32
|
+
mock(Obj).say(a: 0, &:itself)
|
33
|
+
|
34
|
+
expect(Obj.say(a: 0)).eq(a: 0)
|
35
|
+
end
|
36
|
+
|
37
|
+
would 'non-empty hash with satisfying check' do
|
38
|
+
mock(Obj).say(where(a: 0), &:itself)
|
39
|
+
|
40
|
+
expect(Obj.say(a: 0)).eq(a: 0)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'keyargs mock' do
|
45
|
+
copy :tests do
|
46
|
+
would 'local block' do
|
47
|
+
mock(obj).say.with_any_args.returns{ |a:| a }
|
48
|
+
|
49
|
+
expect(instance.say(a: 0)).eq(0)
|
50
|
+
end
|
51
|
+
|
52
|
+
would 'instance method' do
|
53
|
+
mock(obj).bonjour(a: 0, b: 1)
|
54
|
+
|
55
|
+
expect(instance.bonjour(a: 0, b: 1)).eq([0, 1])
|
56
|
+
end
|
57
|
+
|
58
|
+
would 'prepended method' do
|
59
|
+
mock(obj).prepend_bonjour(a: 0, b: 1)
|
60
|
+
|
61
|
+
expect(instance.prepend_bonjour(a: 0, b: 1)).eq([0, 1])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'with direct mock' do
|
66
|
+
def obj
|
67
|
+
Obj
|
68
|
+
end
|
69
|
+
|
70
|
+
def instance
|
71
|
+
obj
|
72
|
+
end
|
73
|
+
|
74
|
+
paste :tests
|
75
|
+
|
76
|
+
would 'singleton method' do
|
77
|
+
mock(obj).single_bonjour(a: 0, b: 1)
|
78
|
+
|
79
|
+
expect(instance.single_bonjour(a: 0, b: 1)).eq([0, 1])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'with any_instance_of' do
|
84
|
+
def obj
|
85
|
+
any_instance_of(Cls)
|
86
|
+
end
|
87
|
+
|
88
|
+
def instance
|
89
|
+
@instance ||= Cls.new
|
90
|
+
end
|
91
|
+
|
92
|
+
paste :tests
|
93
|
+
end
|
94
|
+
|
95
|
+
would 'peek_args' do
|
96
|
+
mock(Obj).say.with_any_args.
|
97
|
+
peek_args{ |a:| [{a: a.succ}] }.
|
98
|
+
returns{ |a:| a.succ }
|
99
|
+
|
100
|
+
expect(Obj.say(a: 0)).eq(2)
|
101
|
+
end
|
102
|
+
|
103
|
+
would 'peek_args with instance_exec' do
|
104
|
+
mock(Obj).say.with_any_args.
|
105
|
+
peek_args(instance_exec: true){ |a:| [{a: object_id}] }.
|
106
|
+
returns{ |a:| a }
|
107
|
+
|
108
|
+
expect(Obj.say(a: 0)).eq(Obj.object_id)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/test/test_modifier.rb
CHANGED
@@ -37,19 +37,19 @@ describe Muack::Modifier do
|
|
37
37
|
|
38
38
|
describe 'peek_args' do
|
39
39
|
would 'with lexical scope' do
|
40
|
-
str = 'ff'
|
40
|
+
str = String.new('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
|
-
str = '16'
|
46
|
+
str = String.new('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
|
-
str = 'ff'
|
52
|
+
str = String.new('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
|
@@ -82,19 +82,19 @@ describe Muack::Modifier do
|
|
82
82
|
|
83
83
|
describe 'peek_return' do
|
84
84
|
would 'with lexical scope' do
|
85
|
-
str = 'ff'
|
85
|
+
str = String.new('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
|
-
str = '16'
|
91
|
+
str = String.new('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
|
-
str = 'ff'
|
97
|
+
str = String.new('ff')
|
98
98
|
stub(str).to_i(is_a(Integer)).peek_return{ |result| result * 2 }
|
99
99
|
str.to_i(16).should.eq 510
|
100
100
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
require 'muack/test'
|
3
|
+
|
4
|
+
describe 'mock with prepend' do
|
5
|
+
after do
|
6
|
+
verify
|
7
|
+
end
|
8
|
+
|
9
|
+
def verify
|
10
|
+
expect(Muack.verify).eq true
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
klass = Class.new do
|
15
|
+
def greet
|
16
|
+
'hi'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
mod = Module.new do
|
21
|
+
def greet
|
22
|
+
hello
|
23
|
+
end
|
24
|
+
|
25
|
+
def hello
|
26
|
+
'hello'
|
27
|
+
end
|
28
|
+
private :hello
|
29
|
+
end
|
30
|
+
|
31
|
+
perform(klass, mod)
|
32
|
+
end
|
33
|
+
|
34
|
+
copy :test do
|
35
|
+
would 'mock' do
|
36
|
+
obj = generate
|
37
|
+
|
38
|
+
mock(obj).hello{'mocked'}
|
39
|
+
|
40
|
+
expect(obj.greet).eq 'mocked'
|
41
|
+
verify
|
42
|
+
expect(obj.greet).eq 'hello'
|
43
|
+
expect(obj).not.respond_to? :hello
|
44
|
+
end
|
45
|
+
|
46
|
+
would 'mock proxy' do
|
47
|
+
obj = generate
|
48
|
+
|
49
|
+
mock(obj).hello
|
50
|
+
|
51
|
+
expect(obj.greet).eq 'hello'
|
52
|
+
verify
|
53
|
+
expect(obj.greet).eq 'hello'
|
54
|
+
expect(obj).not.respond_to? :hello
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'prepend on class mock with object' do
|
59
|
+
def perform(klass, mod)
|
60
|
+
klass.prepend(mod)
|
61
|
+
klass.new
|
62
|
+
end
|
63
|
+
|
64
|
+
paste :test
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'extend on object mock with object' do
|
68
|
+
def perform(klass, mod)
|
69
|
+
obj = klass.new
|
70
|
+
obj.extend(mod)
|
71
|
+
obj
|
72
|
+
end
|
73
|
+
|
74
|
+
paste :test
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'include on singleton_class mock with object' do
|
78
|
+
def perform(klass, mod)
|
79
|
+
obj = klass.new
|
80
|
+
obj.singleton_class.include(mod)
|
81
|
+
obj
|
82
|
+
end
|
83
|
+
|
84
|
+
paste :test
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'prepend on singleton_class mock with object' do
|
88
|
+
def perform(klass, mod)
|
89
|
+
obj = klass.new
|
90
|
+
obj.singleton_class.prepend(mod)
|
91
|
+
obj
|
92
|
+
end
|
93
|
+
|
94
|
+
paste :test
|
95
|
+
end
|
96
|
+
|
97
|
+
# Brought from rspec-mocks and it's currently failing on rspec-mocks
|
98
|
+
# See https://github.com/rspec/rspec-mocks/pull/1218
|
99
|
+
would "handle stubbing prepending methods that were only defined on the prepended module" do
|
100
|
+
to_be_prepended = Module.new do
|
101
|
+
def value
|
102
|
+
"#{super}_prepended".to_sym
|
103
|
+
end
|
104
|
+
|
105
|
+
def value_without_super
|
106
|
+
:prepended
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
object = Object.new
|
111
|
+
object.singleton_class.send(:prepend, to_be_prepended)
|
112
|
+
expect(object.value_without_super).eq :prepended
|
113
|
+
|
114
|
+
stub(object).value_without_super{ :stubbed }
|
115
|
+
|
116
|
+
expect(object.value_without_super).eq :stubbed
|
117
|
+
|
118
|
+
expect(Muack.verify)
|
119
|
+
expect(object.value_without_super).eq :prepended
|
120
|
+
end
|
121
|
+
end
|
data/test/test_proxy.rb
CHANGED
@@ -53,6 +53,21 @@ describe Muack::Mock do
|
|
53
53
|
Obj.aloha.should.eq [0, 1]
|
54
54
|
end
|
55
55
|
|
56
|
+
would 'proxy and call the original method for keyargs' do
|
57
|
+
mock(Obj).bonjour(a: :b, b: :a)
|
58
|
+
mock(Obj).bonjour
|
59
|
+
Obj.bonjour(a: :b, b: :a).should.eq %i[b a]
|
60
|
+
Obj.bonjour.should.eq [0, 1]
|
61
|
+
end
|
62
|
+
|
63
|
+
would 'proxy and call the original method for fake keyargs' do
|
64
|
+
args = {a: :b, b: :a}
|
65
|
+
mock(Obj).ciao(args)
|
66
|
+
mock(Obj).ciao
|
67
|
+
Obj.ciao(args).should.eq %i[b a]
|
68
|
+
Obj.ciao.should.eq [0, 1]
|
69
|
+
end
|
70
|
+
|
56
71
|
would 'proxy and call the block with super' do
|
57
72
|
mock(Str).class.peek_return{ |k| k.name.reverse }
|
58
73
|
Str.class.should.eq 'gnirtS'
|
@@ -60,9 +75,9 @@ describe Muack::Mock do
|
|
60
75
|
|
61
76
|
would 'mock proxy and call, mock proxy and call' do
|
62
77
|
mock(Obj).class.peek_return{ |k| k.name.reverse }
|
63
|
-
Obj.class.should.eq '
|
78
|
+
Obj.class.should.eq 'slC'
|
64
79
|
mock(Obj).class.peek_return{ |k| k.name.upcase }
|
65
|
-
Obj.class.should.eq '
|
80
|
+
Obj.class.should.eq 'CLS'
|
66
81
|
end
|
67
82
|
|
68
83
|
would 'stub proxy and call, stub proxy and call' do
|
@@ -74,12 +89,12 @@ describe Muack::Mock do
|
|
74
89
|
|
75
90
|
would 'stub proxy with any times' do
|
76
91
|
stub(Obj).class.peek_return{ |k| k.name.downcase }
|
77
|
-
3.times{ Obj.class.should.eq '
|
92
|
+
3.times{ Obj.class.should.eq 'cls' }
|
78
93
|
end
|
79
94
|
|
80
95
|
would 'stub proxy and spy' do
|
81
96
|
stub(Obj).class.peek_return{ |k| k.name.downcase }
|
82
|
-
Obj.class.should.eq '
|
97
|
+
Obj.class.should.eq 'cls'
|
83
98
|
spy(Obj).class
|
84
99
|
end
|
85
100
|
end
|
data/test/test_satisfying.rb
CHANGED
@@ -178,13 +178,13 @@ describe Muack::Satisfying do
|
|
178
178
|
end
|
179
179
|
|
180
180
|
would 'satisfy with satisfy' do
|
181
|
-
mock(Str).say(where(:b => is_a(
|
181
|
+
mock(Str).say(where(:b => is_a(Integer))){ |arg| arg[:b] }
|
182
182
|
Str.say(:b => 3).should.eq 3
|
183
183
|
Muack.verify.should.eq true
|
184
184
|
end
|
185
185
|
|
186
186
|
would 'satisfy with satisfy recursive' do
|
187
|
-
spec = where(:a => {:b => is_a(
|
187
|
+
spec = where(:a => {:b => is_a(Integer)})
|
188
188
|
mock(Str).say(spec){ |arg| arg[:a][:b] }
|
189
189
|
Str.say(:a => {:b => 1}).should.eq 1
|
190
190
|
Muack.verify.should.eq true
|
@@ -208,10 +208,10 @@ describe Muack::Satisfying do
|
|
208
208
|
end
|
209
209
|
|
210
210
|
would 'raise Unexpected error if passing unsatisfied argument' do
|
211
|
-
mock(Obj).say(where(:a => 0, :b => is_a(
|
211
|
+
mock(Obj).say(where(:a => 0, :b => is_a(Integer))){ 'boo' }
|
212
212
|
e = should.raise(Muack::Unexpected){Obj.say(:a => 0, :b => 1, :c => 2)}
|
213
213
|
e.expected.should.eq \
|
214
|
-
'obj.say(Muack::API.where({:a=>0, :b=>Muack::API.is_a(
|
214
|
+
'obj.say(Muack::API.where({:a=>0, :b=>Muack::API.is_a(Integer)}))'
|
215
215
|
e.was .should.eq 'obj.say({:a=>0, :b=>1, :c=>2})'
|
216
216
|
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
217
217
|
end
|
@@ -219,13 +219,13 @@ describe Muack::Satisfying do
|
|
219
219
|
would 'recurse' do
|
220
220
|
mock(Obj).say(where(:a =>
|
221
221
|
having(:b =>
|
222
|
-
allowing(:c => [is_a(
|
222
|
+
allowing(:c => [is_a(Integer)])))){ 'boo' }
|
223
223
|
e = should.raise(Muack::Unexpected){Obj.say(:a => 0)}
|
224
224
|
e.expected.should.eq \
|
225
225
|
'obj.say(Muack::API.where({:a=>' \
|
226
226
|
'Muack::API.having({:b=>' \
|
227
227
|
'Muack::API.allowing({:c=>' \
|
228
|
-
'[Muack::API.is_a(
|
228
|
+
'[Muack::API.is_a(Integer)]})})}))'
|
229
229
|
e.was .should.eq 'obj.say({:a=>0})'
|
230
230
|
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
231
231
|
end
|
@@ -251,13 +251,13 @@ describe Muack::Satisfying do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
would 'satisfy with satisfy' do
|
254
|
-
mock(Str).say(having(:b => is_a(
|
254
|
+
mock(Str).say(having(:b => is_a(Integer))){ |arg| arg[:b] }
|
255
255
|
Str.say(:a => 1, :b => 2).should.eq 2
|
256
256
|
Muack.verify.should.eq true
|
257
257
|
end
|
258
258
|
|
259
259
|
would 'satisfy with satisfy recursive' do
|
260
|
-
spec = having(:a => {:b => is_a(
|
260
|
+
spec = having(:a => {:b => is_a(Integer)})
|
261
261
|
mock(Str).say(spec){ |arg| arg[:a][:c] }
|
262
262
|
Str.say(:a => {:b => 1, :c => 2}, :d => 3).should.eq 2
|
263
263
|
Muack.verify.should.eq true
|
@@ -272,10 +272,10 @@ describe Muack::Satisfying do
|
|
272
272
|
end
|
273
273
|
|
274
274
|
would 'raise Unexpected error if passing unsatisfied argument' do
|
275
|
-
mock(Obj).say(having(:a => 0, :b => is_a(
|
275
|
+
mock(Obj).say(having(:a => 0, :b => is_a(Integer))){ 'boo' }
|
276
276
|
e = should.raise(Muack::Unexpected){ Obj.say(:b => 1) }
|
277
277
|
e.expected.should.eq \
|
278
|
-
'obj.say(Muack::API.having({:a=>0, :b=>Muack::API.is_a(
|
278
|
+
'obj.say(Muack::API.having({:a=>0, :b=>Muack::API.is_a(Integer)}))'
|
279
279
|
e.was .should.eq 'obj.say({:b=>1})'
|
280
280
|
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
281
281
|
end
|
@@ -301,13 +301,13 @@ describe Muack::Satisfying do
|
|
301
301
|
end
|
302
302
|
|
303
303
|
would 'satisfy with satisfy' do
|
304
|
-
mock(Str).say(allowing(:a => is_a(
|
304
|
+
mock(Str).say(allowing(:a => is_a(Integer), :b => 1)){ |arg| arg[:a] }
|
305
305
|
Str.say(:a => 0).should.eq 0
|
306
306
|
Muack.verify.should.eq true
|
307
307
|
end
|
308
308
|
|
309
309
|
would 'satisfy with satisfy recursive' do
|
310
|
-
spec = allowing(:a => {:b => is_a(
|
310
|
+
spec = allowing(:a => {:b => is_a(Integer), :c => 1}, :d => 2)
|
311
311
|
mock(Str).say(spec){ |arg| arg[:a][:b] }
|
312
312
|
Str.say(:a => {:b => 0}).should.eq 0
|
313
313
|
Muack.verify.should.eq true
|
data/test/test_spy.rb
CHANGED
@@ -59,7 +59,7 @@ describe Muack::Spy do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
would 'not care about the order' do
|
62
|
-
stub(Obj).say(is_a(
|
62
|
+
stub(Obj).say(is_a(Integer)){|i|i} # change to &:itself in the future
|
63
63
|
Obj .say(1).should.eq 1
|
64
64
|
Obj .say(2).should.eq 2
|
65
65
|
spy(Obj).say(2)
|
@@ -109,7 +109,7 @@ describe Muack::Spy do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
would 'raise Expected if arguments do not match' do
|
112
|
-
stub(Obj).say(is_a(
|
112
|
+
stub(Obj).say(is_a(Integer)){}
|
113
113
|
Obj .say(1)
|
114
114
|
spy(Obj).say(0)
|
115
115
|
e = should.raise(Muack::Unexpected){ Muack.verify }
|
@@ -119,7 +119,7 @@ describe Muack::Spy do
|
|
119
119
|
end
|
120
120
|
|
121
121
|
would 'raise Expected if arguments do not match, show original args' do
|
122
|
-
stub(Obj).say(is_a(
|
122
|
+
stub(Obj).say(is_a(Integer)){}
|
123
123
|
Obj .say(0)
|
124
124
|
Obj .say(1)
|
125
125
|
Obj .say(2)
|
@@ -133,7 +133,7 @@ describe Muack::Spy do
|
|
133
133
|
end
|
134
134
|
|
135
135
|
would 'raise Expected if arguments do not match, show original args' do
|
136
|
-
stub(Obj).say(is_a(
|
136
|
+
stub(Obj).say(is_a(Integer)){}
|
137
137
|
Obj .say(2)
|
138
138
|
Obj .say(0)
|
139
139
|
Obj .say(1)
|