muack 1.4.0 → 1.5.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.
- 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)
|