muack 1.3.0 → 1.5.1
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 +39 -0
- data/Gemfile +0 -4
- data/README.md +33 -24
- 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 +139 -67
- data/lib/muack/satisfying.rb +20 -11
- data/lib/muack/spy.rb +18 -4
- data/lib/muack/stub.rb +7 -6
- data/lib/muack/test.rb +42 -11
- data/lib/muack/version.rb +1 -1
- data/muack.gemspec +65 -55
- data/task/README.md +8 -8
- data/task/gemgem.rb +34 -7
- data/test/test_any_instance_of.rb +16 -2
- data/test/test_from_readme.rb +5 -7
- data/test/test_keyargs.rb +160 -0
- data/test/test_mock.rb +24 -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 +39 -10
- data/test/test_spy.rb +149 -0
- data/test/test_stub.rb +0 -95
- data/test/test_visibility.rb +120 -0
- metadata +17 -8
@@ -57,8 +57,8 @@ describe Muack::AnyInstanceOf do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
would 'mock with multiple any_instance_of call' do
|
60
|
-
any_instance_of(klass){ |inst| mock(inst).f(is_a(
|
61
|
-
any_instance_of(klass){ |inst| mock(inst).f(is_a(
|
60
|
+
any_instance_of(klass){ |inst| mock(inst).f(is_a(Integer)){ |i| i+1 } }
|
61
|
+
any_instance_of(klass){ |inst| mock(inst).f(is_a(Integer)){ |i| i+2 } }
|
62
62
|
obj = klass.new
|
63
63
|
obj.f(2).should.eq 3
|
64
64
|
obj.f(2).should.eq 4
|
@@ -112,4 +112,18 @@ describe Muack::AnyInstanceOf do
|
|
112
112
|
|
113
113
|
obj.f.should.eq 0
|
114
114
|
end
|
115
|
+
|
116
|
+
# Brought from rspec-mocks and it's currently failing on rspec-mocks
|
117
|
+
would 'stub any_instance_of on module extending it self' do
|
118
|
+
mod = Module.new {
|
119
|
+
extend self
|
120
|
+
def hello; :hello; end
|
121
|
+
}
|
122
|
+
|
123
|
+
any_instance_of(mod){ |inst| stub(inst).hello{ :stub } }
|
124
|
+
|
125
|
+
expect(mod.hello).eq(:stub)
|
126
|
+
expect(Muack.verify)
|
127
|
+
expect(mod.hello).eq(:hello)
|
128
|
+
end
|
115
129
|
end
|
data/test/test_from_readme.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
require 'muack/test'
|
3
3
|
|
4
4
|
describe 'from README.md' do
|
5
|
-
readme = File.read(
|
6
|
-
"#{File.dirname(File.expand_path(__FILE__))}/../README.md")
|
5
|
+
readme = File.read("#{__dir__}/../README.md")
|
7
6
|
codes = readme.scan(/``` ruby(.+?)```/m).map(&:first)
|
8
7
|
|
9
8
|
after{ Muack.reset }
|
@@ -12,15 +11,14 @@ describe 'from README.md' do
|
|
12
11
|
include Muack::API
|
13
12
|
|
14
13
|
def describe desc, &block
|
15
|
-
@
|
16
|
-
|
14
|
+
@suite.describe(desc, &block)
|
15
|
+
Pork::Executor.execute(:stat => @stat, :suite => @suite)
|
17
16
|
end
|
18
17
|
|
19
18
|
def results; @results ||= []; end
|
20
19
|
def p res ; results << res ; end
|
21
20
|
|
22
21
|
def verify expects
|
23
|
-
return if results.empty?
|
24
22
|
results.zip(expects).each do |(res, exp)|
|
25
23
|
next if exp == 'ok'
|
26
24
|
if exp.start_with?('raise')
|
@@ -34,10 +32,10 @@ describe 'from README.md' do
|
|
34
32
|
|
35
33
|
codes.each.with_index do |code, index|
|
36
34
|
would 'pass from README.md #%02d' % index do
|
37
|
-
|
35
|
+
suite, stat = Class.new(self.class){ init }, pork_stat
|
38
36
|
context = Module.new do
|
39
37
|
extend Context
|
40
|
-
@
|
38
|
+
@suite, @stat = suite, stat
|
41
39
|
end
|
42
40
|
begin
|
43
41
|
context.instance_eval(code, 'README.md', 0)
|
@@ -0,0 +1,160 @@
|
|
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
|
+
|
112
|
+
describe 'proxy new' do
|
113
|
+
would 'handle initialize via ordinal new' do
|
114
|
+
kargs_initialize = Class.new do
|
115
|
+
def initialize a:
|
116
|
+
@a = a
|
117
|
+
end
|
118
|
+
attr_reader :a
|
119
|
+
end
|
120
|
+
|
121
|
+
mock(kargs_initialize).new(a: 0)
|
122
|
+
|
123
|
+
expect(kargs_initialize.new(a: 0).a).eq(0)
|
124
|
+
end
|
125
|
+
|
126
|
+
would 'handle overridden new without keyword arguments' do
|
127
|
+
kargs_initialize = Class.new do
|
128
|
+
def initialize a:
|
129
|
+
@a = a
|
130
|
+
end
|
131
|
+
attr_reader :a
|
132
|
+
|
133
|
+
def self.new a
|
134
|
+
super(a: a)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
mock(kargs_initialize).new(0)
|
139
|
+
|
140
|
+
expect(kargs_initialize.new(0).a).eq(0)
|
141
|
+
end
|
142
|
+
|
143
|
+
would 'handle overridden new with keyword arguments' do
|
144
|
+
kargs_initialize = Class.new do
|
145
|
+
def initialize a
|
146
|
+
@a = a
|
147
|
+
end
|
148
|
+
attr_reader :a
|
149
|
+
|
150
|
+
def self.new a:
|
151
|
+
super(a)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
mock(kargs_initialize).new(a: 0)
|
156
|
+
|
157
|
+
expect(kargs_initialize.new(a: 0).a).eq(0)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/test/test_mock.rb
CHANGED
@@ -102,6 +102,30 @@ describe Muack::Mock do
|
|
102
102
|
Muack.verify.should.eq true
|
103
103
|
obj.f .should.eq 0
|
104
104
|
end
|
105
|
+
|
106
|
+
describe 'not affect the original module' do
|
107
|
+
would 'with include' do
|
108
|
+
m = Module.new{ def f; :f; end }
|
109
|
+
c0 = Class.new{ include m }.new
|
110
|
+
c1 = Class.new{ include m }.new
|
111
|
+
|
112
|
+
mock(c0).f{:g}
|
113
|
+
|
114
|
+
expect(c0.f).eq :g
|
115
|
+
expect(c1.f).eq :f
|
116
|
+
end
|
117
|
+
|
118
|
+
would 'with prepend' do
|
119
|
+
m = Module.new{ def f; :f; end }
|
120
|
+
c0 = Class.new{ prepend m }.new
|
121
|
+
c1 = Class.new{ prepend m }.new
|
122
|
+
|
123
|
+
mock(c0).f{:g}
|
124
|
+
|
125
|
+
expect(c0.f).eq :g
|
126
|
+
expect(c1.f).eq :f
|
127
|
+
end
|
128
|
+
end
|
105
129
|
end
|
106
130
|
|
107
131
|
describe 'Muack.verify==false' do
|
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
|