muack 0.7.3 → 1.0.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.
@@ -2,10 +2,10 @@
2
2
  require 'muack/test'
3
3
 
4
4
  describe Muack::AnyInstanceOf do
5
- klass = Class.new{ def f; 0; end }
5
+ klass = Class.new{ def f; 0; end; private; def g; 1; end }
6
6
 
7
7
  should 'mock any_instance_of' do
8
- any_instance_of(klass){ |instance| mock(instance).say{ true } }
8
+ any_instance_of(klass){ |inst| mock(inst).say{ true } }
9
9
  obj = klass.new
10
10
  obj.say .should.eq true
11
11
  obj.respond_to?(:say).should.eq true
@@ -13,16 +13,33 @@ describe Muack::AnyInstanceOf do
13
13
  obj.respond_to?(:say).should.eq false
14
14
  end
15
15
 
16
+ should 'mock any_instance_of with instance_exec' do
17
+ any_instance_of(klass){ |inst|
18
+ mock(inst).say.returns(:instance_exec => true){ f } }
19
+ obj = klass.new
20
+ obj.say .should.eq obj.f
21
+ Muack.verify .should.eq true
22
+ obj.respond_to?(:say).should.eq false
23
+ end
24
+
16
25
  should 'proxy any_instance_of' do
17
- any_instance_of(klass){ |instance| mock(instance).f.proxy }
26
+ any_instance_of(klass){ |inst| mock(inst).f }
18
27
  obj = klass.new
19
28
  obj.f .should.eq 0
20
29
  Muack.verify.should.eq true
21
30
  obj.f .should.eq 0
22
31
  end
23
32
 
24
- should 'proxy any_instance_of with a block' do
25
- any_instance_of(klass){ |instance| mock(instance).f{ |i| i+1 }.proxy }
33
+ should 'proxy any_instance_of for private methods' do
34
+ any_instance_of(klass){ |inst| mock(inst).g.peek_return{|i|i+1} }
35
+ obj = klass.new
36
+ obj.__send__(:g).should.eq 2
37
+ Muack.verify .should.eq true
38
+ obj.__send__(:g).should.eq 1
39
+ end
40
+
41
+ should 'proxy any_instance_of with peek_return' do
42
+ any_instance_of(klass){ |inst| mock(inst).f.peek_return{|i|i+1} }
26
43
  obj = klass.new
27
44
  obj.f .should.eq 1
28
45
  Muack.verify.should.eq true
@@ -30,8 +47,8 @@ describe Muack::AnyInstanceOf do
30
47
  end
31
48
 
32
49
  should 'proxy with multiple any_instance_of call' do
33
- any_instance_of(klass){ |instance| mock(instance).f{ |i| i+1 }.proxy }
34
- any_instance_of(klass){ |instance| mock(instance).f{ |i| i+2 }.proxy }
50
+ any_instance_of(klass){ |inst| mock(inst).f.peek_return{ |i| i+1 } }
51
+ any_instance_of(klass){ |inst| mock(inst).f.peek_return{ |i| i+2 } }
35
52
  obj = klass.new
36
53
  obj.f.should.eq 1
37
54
  obj.f.should.eq 2
@@ -49,8 +66,15 @@ describe Muack::AnyInstanceOf do
49
66
  obj.f.should.eq 0
50
67
  end
51
68
 
69
+ should 'share the same counts for different instances' do
70
+ times = 2
71
+ any_instance_of(klass){ |inst| mock(inst).f{0}.times(times) }
72
+ times.times{ klass.new.f.should.eq 0 }
73
+ Muack.verify.should.eq true
74
+ end
75
+
52
76
  should 'stub proxy with any_instance_of and spy' do
53
- any_instance_of(klass){ |inst| stub(inst).f{ |i| i+3 }.proxy }
77
+ any_instance_of(klass){ |inst| stub(inst).f.peek_return{ |i| i+3 } }
54
78
  obj = klass.new
55
79
  obj.f.should.eq 3
56
80
  obj.f.should.eq 3
@@ -0,0 +1,40 @@
1
+
2
+ require 'muack/test'
3
+
4
+ describe 'from README.md' do
5
+ readme = File.read(
6
+ "#{File.dirname(File.expand_path(__FILE__))}/../README.md")
7
+ codes = readme.scan(/``` ruby(.+?)```/m).map(&:first)
8
+
9
+ after{ Muack.reset }
10
+
11
+ Context = Module.new{
12
+ def p res
13
+ (@results ||= []) << res
14
+ end
15
+
16
+ def verify expects
17
+ return unless @results
18
+ @results.zip(expects).each do |(res, exp)|
19
+ next if exp == 'ok'
20
+ if exp.start_with?('raise')
21
+ res.should.kind_of eval(exp.sub('raise', ''))
22
+ else
23
+ res.should.eq eval(exp)
24
+ end
25
+ end
26
+ end
27
+ }
28
+
29
+ codes.each.with_index do |code, index|
30
+ should 'pass from README.md #%02d' % index do
31
+ context = Module.new{extend Context}
32
+ begin
33
+ context.instance_eval(code, 'README.md', 0)
34
+ rescue Muack::Failure => e
35
+ context.p e
36
+ end
37
+ context.verify(code.scan(/# (.+)/).map(&:first))
38
+ end
39
+ end
40
+ end
data/test/test_mock.rb CHANGED
@@ -22,6 +22,21 @@ describe Muack::Mock do
22
22
  Obj.to_s.should.eq 'zoo'
23
23
  end
24
24
 
25
+ should 'pass the actual block' do
26
+ mock(Obj).say{ |&block| block.call('Hi') }
27
+ Obj.say{ |msg| msg }.should.eq 'Hi'
28
+ end
29
+
30
+ should 'mock private method and preserve privacy' do
31
+ mock(Obj).private{ 'sai' }
32
+ Obj.respond_to?(:private ).should.eq false
33
+ Obj.respond_to?(:private, true).should.eq true
34
+ Obj.__send__(:private).should.eq 'sai'
35
+ Muack.verify.should.eq true
36
+ Obj.respond_to?(:private ).should.eq false
37
+ Obj.__send__(:private).should.eq 'pri'
38
+ end
39
+
25
40
  should 'mock twice' do
26
41
  mock(Obj).say(true){ Obj.saya }
27
42
  mock(Obj).saya{ 'coo' }
@@ -37,25 +52,31 @@ describe Muack::Mock do
37
52
  Muack.reset
38
53
  end
39
54
 
40
- should 'mock multiple times' do
41
- 3.times{ |i| mock(Obj).say(i){ i } }
42
- 3.times{ |i| Obj.say(i).should.eq i }
55
+ should 'mix mock and stub' do
56
+ mock(Obj).say { 0 }
57
+ stub(Obj).saya{ 1 }
58
+ 3.times{ Obj.saya.should.eq 1 }
59
+ Obj.say .should.eq 0
43
60
  end
44
61
 
45
- should 'mock multiple times with times(n) modifier' do
46
- mock(Obj).say{ 0 }.times(3)
47
- 3.times{ |i| Obj.say.should.eq 0 }
62
+ should 'mix mock and stub with conflicting method, latter wins' do
63
+ stub(Obj).say{0}
64
+ mock(Obj).say{1}
65
+ Obj.say.should.eq 1
48
66
  end
49
67
 
50
- should 'mock 0 times with times(0) modifier' do
51
- mock(Obj).say{ 0 }.times(0).should.kind_of Muack::Modifier
68
+ should 'mix mock and stub with conflicting method, try to hit stub' do
69
+ stub(Obj).say{0}
70
+ mock(Obj).say{1}
71
+ Obj.say.should.eq 1
72
+ lambda{ Obj.say }.should.raise(Muack::Expected)
52
73
  end
53
74
 
54
- should 'mix mock and stub' do
55
- mock(Obj).say { 0 }
56
- stub(Obj).saya{ 1 }
57
- 3.times{ Obj.saya.should.eq 1 }
58
- Obj.say .should.eq 0
75
+ should 'mix mock and stub with conflicting method, mock never called' do
76
+ mock(Obj).say{0}
77
+ stub(Obj).say{1}
78
+ Obj.say.should.eq 1
79
+ lambda{ Muack.verify }.should.raise(Muack::Expected)
59
80
  end
60
81
 
61
82
  should 'unnamed mock' do
@@ -76,16 +97,6 @@ describe Muack::Mock do
76
97
  Muack.verify.should.eq true
77
98
  obj.f .should.eq 0
78
99
  end
79
-
80
- should 'return values with returns with a value' do
81
- mock(Obj).say.returns(0)
82
- Obj.say.should.eq 0
83
- end
84
-
85
- should 'return values with returns with a block' do
86
- mock(Obj).say.returns{0}
87
- Obj.say.should.eq 0
88
- end
89
100
  end
90
101
 
91
102
  describe 'Muack.verify==false' do
@@ -107,7 +118,7 @@ describe Muack::Mock do
107
118
  end
108
119
 
109
120
  should 'have correct message for multiple mocks with the same name' do
110
- 2.times{ mock(Obj).say }
121
+ 2.times{ mock(Obj).say{} }
111
122
  begin
112
123
  3.times{ Obj.say }
113
124
  'never'.should.eq 'reach'
@@ -121,7 +132,7 @@ describe Muack::Mock do
121
132
  end
122
133
 
123
134
  should 'have correct message for mocks with special satisfier' do
124
- mock(Obj).say(anything)
135
+ mock(Obj).say(anything){}
125
136
  begin
126
137
  Obj.say(1)
127
138
  Obj.say(2)
@@ -188,7 +199,7 @@ describe Muack::Mock do
188
199
 
189
200
  should 'show first not enough calls' do
190
201
  mock(Obj).say{ 'boo' }.times(2)
191
- mock(Obj).saya .times(2)
202
+ mock(Obj).saya{} .times(2)
192
203
  begin
193
204
  Obj.say
194
205
  Muack.verify
@@ -0,0 +1,102 @@
1
+
2
+ require 'muack/test'
3
+
4
+ describe Muack::Modifier do
5
+ after do
6
+ Muack.verify.should.eq true
7
+ Muack::EnsureReset.call
8
+ end
9
+
10
+ describe 'times' do
11
+ should 'mock multiple times' do
12
+ 3.times{ |i| mock(Obj).say(i){ i } }
13
+ 3.times{ |i| Obj.say(i).should.eq i }
14
+ end
15
+
16
+ should 'mock multiple times with times(n) modifier' do
17
+ mock(Obj).say{ 0 }.times(3)
18
+ 3.times{ |i| Obj.say.should.eq 0 }
19
+ end
20
+
21
+ should 'mock 0 times with times(0) modifier' do
22
+ mock(Obj).say{ 0 }.times(0).should.kind_of Muack::Modifier
23
+ end
24
+ end
25
+
26
+ describe 'returns' do
27
+ should 'return with lexical scope' do
28
+ mock(Obj).say.returns{0}
29
+ Obj.say.should.eq 0
30
+ end
31
+
32
+ should 'return with dynamic scope' do
33
+ mock(Obj).say.returns(:instance_exec => true){object_id}
34
+ Obj.say.should.eq Obj.object_id
35
+ end
36
+ end
37
+
38
+ describe 'peek_args' do
39
+ should 'with lexical scope' do
40
+ str = 'ff'
41
+ stub(str).to_i.peek_args{16}
42
+ str.to_i.should.eq 255
43
+ end
44
+
45
+ should 'with dynamic scope' do
46
+ str = '16'
47
+ stub(str).to_i.peek_args(:instance_exec => true){Integer(self)}
48
+ str.to_i.should.eq 22
49
+ end
50
+
51
+ should 'modify' do
52
+ str = 'ff'
53
+ stub(str).to_i(is_a(Integer)).peek_args{ |radix| radix * 2 }
54
+ str.to_i(8).should.eq 255
55
+ end
56
+
57
+ should 'preserve args' do
58
+ stub(Obj).say{|*a|a}.with_any_args.peek_args{|*a|a}
59
+ Obj.say(0,1).should.eq [0,1]
60
+ end
61
+
62
+ should 'pass first args' do
63
+ stub(Obj).say{|*a|a}.with_any_args.peek_args{|a|a}
64
+ Obj.say(0,1).should.eq [0]
65
+ end
66
+
67
+ should 'pass nothing with nil' do
68
+ stub(Obj).say{|*a|a}.with_any_args.peek_args{}
69
+ Obj.say(0,1).should.eq []
70
+ end
71
+
72
+ should 'pass nothing with empty array' do
73
+ stub(Obj).say{|*a|a}.with_any_args.peek_args{[]}
74
+ Obj.say(0,1).should.eq []
75
+ end
76
+
77
+ should 'pass an empty array with [[]]' do
78
+ stub(Obj).say{|*a|a}.with_any_args.peek_args{[[]]}
79
+ Obj.say(0,1).should.eq [[]]
80
+ end
81
+ end
82
+
83
+ describe 'peek_return' do
84
+ should 'with lexical scope' do
85
+ str = 'ff'
86
+ stub(str).to_i.peek_return{16}
87
+ str.to_i.should.eq 16
88
+ end
89
+
90
+ should 'with dynamic scope' do
91
+ str = '16'
92
+ stub(str).to_i.peek_return(:instance_exec => true){Integer(self)+1}
93
+ str.to_i.should.eq 17
94
+ end
95
+
96
+ should 'modify' do
97
+ str = 'ff'
98
+ stub(str).to_i(is_a(Integer)).peek_return{ |result| result * 2 }
99
+ str.to_i(16).should.eq 510
100
+ end
101
+ end
102
+ end
data/test/test_proxy.rb CHANGED
@@ -9,57 +9,62 @@ describe Muack::Mock do
9
9
  end
10
10
 
11
11
  should 'proxy with regular method' do
12
- mock(Str).reverse.proxy
12
+ mock(Str).reverse
13
13
  Str.reverse.should.eq 'ooM'
14
14
  end
15
15
 
16
+ should 'proxy with private method' do
17
+ mock(Obj).private.peek_return(&:reverse)
18
+ Obj.__send__(:private).should.eq 'irp'
19
+ end
20
+
16
21
  should 'proxy multiple times' do
17
- 2.times{ mock(Str).reverse.proxy }
22
+ 2.times{ mock(Str).reverse }
18
23
  2.times{ Str.reverse.should.eq 'ooM' }
19
24
  end
20
25
 
21
26
  should 'proxy multiple times with super method' do
22
- 2.times{ mock(Str).class.proxy }
27
+ 2.times{ mock(Str).class }
23
28
  2.times{ Str.class.should.eq String }
24
29
  end
25
30
 
26
31
  should 'return modifier itself for any modifier methods' do
27
- mock(Str).to_s.proxy.returns{ |s| s.reverse }.times(2).
32
+ mock(Str).to_s.peek_return{ |s| s.reverse }.times(2).
28
33
  with_any_args.with_any_args
29
34
  2.times{ Str.to_s.should.eq 'ooM' }
30
35
  end
31
36
 
32
37
  should 'proxy and call the block' do
33
- mock(Obj).method_missing(:inspect){ |str| str.reverse }.proxy
38
+ mock(Obj).method_missing(:inspect).peek_return{ |str| str.reverse }
34
39
  Obj.inspect.should.eq 'jbo'
35
40
  end
36
41
 
37
42
  should 'proxy and call the block with super' do
38
- mock(Str).class{ |k| k.name.reverse }.proxy
43
+ mock(Str).class.peek_return{ |k| k.name.reverse }
39
44
  Str.class.should.eq 'gnirtS'
40
45
  end
41
46
 
42
47
  should 'mock proxy and call, mock proxy and call' do
43
- mock(Obj).class{ |k| k.name.reverse }.proxy
48
+ mock(Obj).class.peek_return{ |k| k.name.reverse }
44
49
  Obj.class.should.eq 'tcejbO'
45
- mock(Obj).class{ |k| k.name.upcase }.proxy
50
+ mock(Obj).class.peek_return{ |k| k.name.upcase }
46
51
  Obj.class.should.eq 'OBJECT'
47
52
  end
48
53
 
49
54
  should 'stub proxy and call, stub proxy and call' do
50
- stub(Obj).kind_of?(Object){ |b| !b }.proxy
55
+ stub(Obj).kind_of?(Object).peek_return{ |b| !b }
51
56
  Obj.kind_of?(Object).should.eq false
52
- stub(Obj).kind_of?(String){ |b| b.to_s }.proxy
57
+ stub(Obj).kind_of?(String).peek_return{ |b| b.to_s }
53
58
  Obj.kind_of?(String).should.eq 'false'
54
59
  end
55
60
 
56
61
  should 'stub proxy with any times' do
57
- stub(Obj).class{ |k| k.name.downcase }.proxy
62
+ stub(Obj).class.peek_return{ |k| k.name.downcase }
58
63
  3.times{ Obj.class.should.eq 'object' }
59
64
  end
60
65
 
61
66
  should 'stub proxy and spy' do
62
- stub(Obj).class{ |k| k.name.downcase }.proxy
67
+ stub(Obj).class.peek_return{ |k| k.name.downcase }
63
68
  Obj.class.should.eq 'object'
64
69
  spy(Obj).class
65
70
  end
@@ -72,7 +77,7 @@ describe Muack::Mock do
72
77
  end
73
78
 
74
79
  should 'raise Expected error if passing unexpected argument' do
75
- mock(Str).reverse.proxy
80
+ mock(Str).reverse
76
81
  Str.reverse.should.eq 'ooM'
77
82
  begin
78
83
  Str.reverse
data/test/test_satisfy.rb CHANGED
@@ -247,6 +247,11 @@ describe Muack::Satisfy do
247
247
  matcher.inspect.should.start_with expected
248
248
  end
249
249
 
250
+ should 'not crash for top-level subclass' do
251
+ Class.new(Muack::Satisfy){ def self.name; 'TopLevel'; end }.new.
252
+ api_name.should.eq 'top_level'
253
+ end
254
+
250
255
  should 'satisfy' do
251
256
  mock(Str).say(satisfy{ |arg| arg % 2 == 0 }){ |arg| arg + 1 }
252
257
  Str.say(14).should.eq 15
@@ -270,7 +275,7 @@ describe Muack::Satisfy do
270
275
  end
271
276
  end
272
277
 
273
- describe Muack::Satisfy::Union do
278
+ describe Muack::Satisfy::Disj do
274
279
  should 'have human readable to_s and inspect' do
275
280
  matcher = is_a(TrueClass) | is_a(FalseClass)
276
281
  expected = 'Muack::API.is_a(TrueClass) | Muack::API.is_a(FalseClass)'
@@ -303,7 +308,7 @@ describe Muack::Satisfy do
303
308
  end
304
309
  end
305
310
 
306
- describe Muack::Satisfy::Inter do
311
+ describe Muack::Satisfy::Conj do
307
312
  should 'have human readable to_s and inspect' do
308
313
  matcher = respond_to(:ancestors) & is_a(Class)
309
314
  expected = 'Muack::API.respond_to(:ancestors) & Muack::API.is_a(Class)'
data/test/test_stub.rb CHANGED
@@ -33,6 +33,11 @@ describe Muack::Stub do
33
33
  Str.say(' ').should.eq 'Hoo'
34
34
  end
35
35
 
36
+ should 'pass the actual block' do
37
+ stub(Obj).say{ |&block| block.call('Hi') }
38
+ Obj.say{ |msg| msg }.should.eq 'Hi'
39
+ end
40
+
36
41
  should 'accept block form' do
37
42
  stub(Obj){ |o| o.say{0}; o.saya{1} }
38
43
  Obj.saya.should.eq 1
@@ -46,13 +51,13 @@ describe Muack::Stub do
46
51
  end
47
52
 
48
53
  should 'work with spy twice' do
49
- stub(Obj).say
54
+ stub(Obj).say{}
50
55
  2.times{ Obj.say.should.eq nil }
51
56
  spy(Obj).say.times(2)
52
57
  end
53
58
 
54
59
  should 'work with spy spy' do
55
- stub(Obj).say
60
+ stub(Obj).say{}
56
61
  2.times{ Obj.say.should.eq nil }
57
62
  2.times{ spy(Obj).say }
58
63
  end
@@ -90,7 +95,7 @@ describe Muack::Stub do
90
95
  end
91
96
 
92
97
  should 'raise Expected if the spy is not satisfied' do
93
- stub(Obj).say
98
+ stub(Obj).say{}
94
99
  spy( Obj).say
95
100
  begin
96
101
  Muack.verify
@@ -105,7 +110,7 @@ describe Muack::Stub do
105
110
  end
106
111
 
107
112
  should 'raise Expected if the spy is not satisfied enough' do
108
- stub(Obj).say
113
+ stub(Obj).say{}
109
114
  Obj.say
110
115
  spy( Obj).say(0)
111
116
  begin
@@ -119,7 +124,7 @@ describe Muack::Stub do
119
124
  end
120
125
 
121
126
  should 'show correct times for under satisfaction' do
122
- stub(Obj).say
127
+ stub(Obj).say{}
123
128
  2.times{ Obj.say }
124
129
  spy( Obj).say.times(3)
125
130
  begin
@@ -135,7 +140,7 @@ describe Muack::Stub do
135
140
  end
136
141
 
137
142
  should 'show correct times for over satisfaction' do
138
- stub(Obj).say
143
+ stub(Obj).say{}
139
144
  2.times{ Obj.say }
140
145
  spy( Obj).say
141
146
  begin