muack 0.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 +7 -0
- data/.gitmodules +3 -0
- data/.travis.yml +11 -0
- data/CHANGES.md +5 -0
- data/Gemfile +7 -0
- data/LICENSE +201 -0
- data/README.md +494 -0
- data/Rakefile +18 -0
- data/lib/muack.rb +77 -0
- data/lib/muack/any_instance_of.rb +4 -0
- data/lib/muack/definition.rb +5 -0
- data/lib/muack/failure.rb +38 -0
- data/lib/muack/mock.rb +167 -0
- data/lib/muack/modifier.rb +29 -0
- data/lib/muack/proxy.rb +39 -0
- data/lib/muack/satisfy.rb +54 -0
- data/lib/muack/session.rb +12 -0
- data/lib/muack/stub.rb +22 -0
- data/lib/muack/test.rb +26 -0
- data/lib/muack/version.rb +4 -0
- data/muack.gemspec +53 -0
- data/task/.gitignore +1 -0
- data/task/gemgem.rb +268 -0
- data/test/test_any_instance_of.rb +30 -0
- data/test/test_mock.rb +170 -0
- data/test/test_proxy.rb +77 -0
- data/test/test_readme.rb +16 -0
- data/test/test_satisfy.rb +200 -0
- data/test/test_stub.rb +62 -0
- metadata +85 -0
data/lib/muack/stub.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require 'muack/mock'
|
3
|
+
|
4
|
+
module Muack
|
5
|
+
class Stub < Mock
|
6
|
+
# used for Muack::Session#verify
|
7
|
+
def __mock_verify; true; end
|
8
|
+
|
9
|
+
# used for mocked object to dispatch mocked method
|
10
|
+
def __mock_dispatch msg, actual_args, actual_block
|
11
|
+
defi = __mock_defis[msg].find{ |d|
|
12
|
+
__mock_check_args(d.args, actual_args)
|
13
|
+
}
|
14
|
+
if defi
|
15
|
+
__mock_block_call(defi, actual_args, actual_block)
|
16
|
+
else
|
17
|
+
Mock.__send__(:raise, # Wrong argument
|
18
|
+
Unexpected.new(object, __mock_defis[msg], msg, actual_args))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/muack/test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'bacon'
|
3
|
+
require 'muack'
|
4
|
+
|
5
|
+
Bacon.summary_on_exit
|
6
|
+
include Muack::API
|
7
|
+
|
8
|
+
Obj = Object.new
|
9
|
+
Str = 'Moo'
|
10
|
+
def Obj.inspect
|
11
|
+
'obj'
|
12
|
+
end
|
13
|
+
|
14
|
+
Muack::EnsureReset = lambda{
|
15
|
+
[Obj, Str].each do |o|
|
16
|
+
o.methods.select{ |m|
|
17
|
+
m.to_s.start_with?('__muack_mock') || m.to_s.start_with?('say')
|
18
|
+
}.should.empty
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
22
|
+
module Kernel
|
23
|
+
def eq? rhs
|
24
|
+
self == rhs
|
25
|
+
end
|
26
|
+
end
|
data/muack.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "muack"
|
5
|
+
s.version = "0.5.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Lin Jen-Shin (godfat)"]
|
9
|
+
s.date = "2013-06-24"
|
10
|
+
s.description = "Muack -- Yet another mocking library.\n\nBasically it's an [RR][] clone, but much faster under heavy use.\nIt's 32x times faster (750s vs 23s) for running [Rib][] tests.\n\n[RR]: https://github.com/rr/rr\n[Rib]: https://github.com/godfat/rib"
|
11
|
+
s.email = ["godfat (XD) godfat.org"]
|
12
|
+
s.files = [
|
13
|
+
".gitmodules",
|
14
|
+
".travis.yml",
|
15
|
+
"CHANGES.md",
|
16
|
+
"Gemfile",
|
17
|
+
"LICENSE",
|
18
|
+
"README.md",
|
19
|
+
"Rakefile",
|
20
|
+
"lib/muack.rb",
|
21
|
+
"lib/muack/any_instance_of.rb",
|
22
|
+
"lib/muack/definition.rb",
|
23
|
+
"lib/muack/failure.rb",
|
24
|
+
"lib/muack/mock.rb",
|
25
|
+
"lib/muack/modifier.rb",
|
26
|
+
"lib/muack/proxy.rb",
|
27
|
+
"lib/muack/satisfy.rb",
|
28
|
+
"lib/muack/session.rb",
|
29
|
+
"lib/muack/stub.rb",
|
30
|
+
"lib/muack/test.rb",
|
31
|
+
"lib/muack/version.rb",
|
32
|
+
"muack.gemspec",
|
33
|
+
"task/.gitignore",
|
34
|
+
"task/gemgem.rb",
|
35
|
+
"test/test_any_instance_of.rb",
|
36
|
+
"test/test_mock.rb",
|
37
|
+
"test/test_proxy.rb",
|
38
|
+
"test/test_readme.rb",
|
39
|
+
"test/test_satisfy.rb",
|
40
|
+
"test/test_stub.rb"]
|
41
|
+
s.homepage = "https://github.com/godfat/muack"
|
42
|
+
s.licenses = ["Apache License 2.0"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = "2.0.3"
|
45
|
+
s.summary = "Muack -- Yet another mocking library."
|
46
|
+
s.test_files = [
|
47
|
+
"test/test_any_instance_of.rb",
|
48
|
+
"test/test_mock.rb",
|
49
|
+
"test/test_proxy.rb",
|
50
|
+
"test/test_readme.rb",
|
51
|
+
"test/test_satisfy.rb",
|
52
|
+
"test/test_stub.rb"]
|
53
|
+
end
|
data/task/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.rbc
|
data/task/gemgem.rb
ADDED
@@ -0,0 +1,268 @@
|
|
1
|
+
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Gemgem
|
5
|
+
class << self
|
6
|
+
attr_accessor :dir, :spec
|
7
|
+
end
|
8
|
+
|
9
|
+
module_function
|
10
|
+
def create
|
11
|
+
yield(spec = Gem::Specification.new{ |s|
|
12
|
+
s.authors = ['Lin Jen-Shin (godfat)']
|
13
|
+
s.email = ['godfat (XD) godfat.org']
|
14
|
+
|
15
|
+
s.description = description.join
|
16
|
+
s.summary = description.first
|
17
|
+
s.license = readme['LICENSE'].sub(/.+\n\n/, '').lines.first.strip
|
18
|
+
|
19
|
+
s.rubygems_version = Gem::VERSION
|
20
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
21
|
+
s.files = gem_files
|
22
|
+
s.test_files = gem_files.grep(%r{^test/(.+?/)*test_.+?\.rb$})
|
23
|
+
s.executables = Dir['bin/*'].map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = %w[lib]
|
25
|
+
})
|
26
|
+
spec.homepage ||= "https://github.com/godfat/#{spec.name}"
|
27
|
+
spec
|
28
|
+
end
|
29
|
+
|
30
|
+
def readme
|
31
|
+
path = %w[README.md README].find{ |name|
|
32
|
+
File.exist?("#{Gemgem.dir}/#{name}")
|
33
|
+
}
|
34
|
+
@readme ||=
|
35
|
+
if path
|
36
|
+
ps = "##{File.read(path)}".
|
37
|
+
scan(/((#+)[^\n]+\n\n.+?(?=(\n\n\2[^#\n]+\n)|\Z))/m).map(&:first)
|
38
|
+
ps.inject('HEADER' => ps.first){ |r, s, i|
|
39
|
+
r[s[/\w+/]] = s
|
40
|
+
r
|
41
|
+
}
|
42
|
+
else
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def description
|
48
|
+
@description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines
|
49
|
+
end
|
50
|
+
|
51
|
+
def changes
|
52
|
+
path = %w[CHANGES.md CHANGES].find{ |name|
|
53
|
+
File.exist?("#{Gemgem.dir}/#{name}")
|
54
|
+
}
|
55
|
+
@changes ||=
|
56
|
+
if path
|
57
|
+
date = '\d+{4}\-\d+{2}\-\d{2}'
|
58
|
+
File.read(path).match(
|
59
|
+
/([^\n]+#{date}\n\n(.+?))(?=\n\n[^\n]+#{date}\n|\Z)/m)[1]
|
60
|
+
else
|
61
|
+
''
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def ann_md
|
66
|
+
"#{readme['HEADER'].sub(/([\w\-]+)/, "[\\1](#{spec.homepage})")}\n\n" \
|
67
|
+
"##{readme['DESCRIPTION'][/[^\n]+\n\n[^\n]+/]}\n\n" \
|
68
|
+
"### CHANGES:\n\n" \
|
69
|
+
"###{changes}\n\n" \
|
70
|
+
"##{readme['INSTALLATION']}\n\n" +
|
71
|
+
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS'][/[^\n]+\n\n[^\n]+/]}"
|
72
|
+
else '' end
|
73
|
+
end
|
74
|
+
|
75
|
+
def ann_html
|
76
|
+
gem 'nokogiri'
|
77
|
+
gem 'kramdown'
|
78
|
+
|
79
|
+
IO.popen('kramdown', 'r+') do |md|
|
80
|
+
md.puts Gemgem.ann_md
|
81
|
+
md.close_write
|
82
|
+
require 'nokogiri'
|
83
|
+
html = Nokogiri::XML.parse("<gemgem>#{md.read}</gemgem>")
|
84
|
+
html.css('*').each{ |n| n.delete('id') }
|
85
|
+
html.root.children.to_html
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def ann_email
|
90
|
+
"#{readme['HEADER'].sub(/([\w\-]+)/, "\\1 <#{spec.homepage}>")}\n\n" \
|
91
|
+
"#{readme['DESCRIPTION']}\n\n" \
|
92
|
+
"#{readme['INSTALLATION']}\n\n" +
|
93
|
+
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}\n\n" else '' end +
|
94
|
+
"## CHANGES:\n\n" \
|
95
|
+
"##{changes}\n\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
def gem_tag
|
99
|
+
"#{spec.name}-#{spec.version}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def write
|
103
|
+
File.open("#{dir}/#{spec.name}.gemspec", 'w'){ |f|
|
104
|
+
f << split_lines(spec.to_ruby) }
|
105
|
+
end
|
106
|
+
|
107
|
+
def split_lines ruby
|
108
|
+
ruby.gsub(/(.+?)\s*=\s*\[(.+?)\]/){ |s|
|
109
|
+
if $2.index(',')
|
110
|
+
"#{$1} = [\n #{$2.split(',').map(&:strip).join(",\n ")}]"
|
111
|
+
else
|
112
|
+
s
|
113
|
+
end
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def all_files
|
118
|
+
@all_files ||= find_files(Pathname.new(dir)).map{ |file|
|
119
|
+
if file.to_s =~ %r{\.git/|\.git$}
|
120
|
+
nil
|
121
|
+
else
|
122
|
+
file.to_s
|
123
|
+
end
|
124
|
+
}.compact.sort
|
125
|
+
end
|
126
|
+
|
127
|
+
def gem_files
|
128
|
+
@gem_files ||= all_files - ignored_files
|
129
|
+
end
|
130
|
+
|
131
|
+
def ignored_files
|
132
|
+
@ignored_file ||= all_files.select{ |path| ignore_patterns.find{ |ignore|
|
133
|
+
path =~ ignore && !git_files.include?(path)}}
|
134
|
+
end
|
135
|
+
|
136
|
+
def git_files
|
137
|
+
@git_files ||= if File.exist?("#{dir}/.git")
|
138
|
+
`git ls-files`.split("\n")
|
139
|
+
else
|
140
|
+
[]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# protected
|
145
|
+
def find_files path
|
146
|
+
path.children.select(&:file?).map{|file| file.to_s[(dir.size+1)..-1]} +
|
147
|
+
path.children.select(&:directory?).map{|dir| find_files(dir)}.flatten
|
148
|
+
end
|
149
|
+
|
150
|
+
def ignore_patterns
|
151
|
+
@ignore_files ||= expand_patterns(
|
152
|
+
gitignore.split("\n").reject{ |pattern|
|
153
|
+
pattern.strip == ''
|
154
|
+
}).map{ |pattern| %r{^([^/]+/)*?#{Regexp.escape(pattern)}(/[^/]+)*?$} }
|
155
|
+
end
|
156
|
+
|
157
|
+
def expand_patterns pathes
|
158
|
+
pathes.map{ |path|
|
159
|
+
if path !~ /\*/
|
160
|
+
path
|
161
|
+
else
|
162
|
+
expand_patterns(
|
163
|
+
Dir[path] +
|
164
|
+
Pathname.new(File.dirname(path)).children.select(&:directory?).
|
165
|
+
map{ |prefix| "#{prefix}/#{File.basename(path)}" })
|
166
|
+
end
|
167
|
+
}.flatten
|
168
|
+
end
|
169
|
+
|
170
|
+
def gitignore
|
171
|
+
if File.exist?(path = "#{dir}/.gitignore")
|
172
|
+
File.read(path)
|
173
|
+
else
|
174
|
+
''
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
namespace :gem do
|
180
|
+
|
181
|
+
desc 'Install gem'
|
182
|
+
task :install => [:build] do
|
183
|
+
sh("#{Gem.ruby} -S gem install pkg/#{Gemgem.gem_tag}.gem")
|
184
|
+
end
|
185
|
+
|
186
|
+
desc 'Build gem'
|
187
|
+
task :build => [:spec] do
|
188
|
+
sh("#{Gem.ruby} -S gem build #{Gemgem.spec.name}.gemspec")
|
189
|
+
sh("mkdir -p pkg")
|
190
|
+
sh("mv #{Gemgem.gem_tag}.gem pkg/")
|
191
|
+
end
|
192
|
+
|
193
|
+
desc 'Release gem'
|
194
|
+
task :release => [:spec, :check, :build] do
|
195
|
+
sh("git tag #{Gemgem.gem_tag}")
|
196
|
+
sh("git push")
|
197
|
+
sh("git push --tags")
|
198
|
+
sh("#{Gem.ruby} -S gem push pkg/#{Gemgem.gem_tag}.gem")
|
199
|
+
end
|
200
|
+
|
201
|
+
task :check do
|
202
|
+
ver = Gemgem.spec.version.to_s
|
203
|
+
|
204
|
+
if ENV['VERSION'].nil?
|
205
|
+
puts("\e[35mExpected " \
|
206
|
+
"\e[33mVERSION\e[35m=\e[33m#{ver}\e[0m")
|
207
|
+
exit(1)
|
208
|
+
|
209
|
+
elsif ENV['VERSION'] != ver
|
210
|
+
puts("\e[35mExpected \e[33mVERSION\e[35m=\e[33m#{ver} " \
|
211
|
+
"\e[35mbut got\n " \
|
212
|
+
"\e[33mVERSION\e[35m=\e[33m#{ENV['VERSION']}\e[0m")
|
213
|
+
exit(2)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end # of gem namespace
|
218
|
+
|
219
|
+
desc 'Run tests in memory'
|
220
|
+
task :test do
|
221
|
+
require 'bacon'
|
222
|
+
Bacon.extend(Bacon::TestUnitOutput)
|
223
|
+
Bacon.summary_on_exit
|
224
|
+
$LOAD_PATH.unshift('lib')
|
225
|
+
Dir['./test/**/test_*.rb'].each{ |file| require file[0..-4] }
|
226
|
+
end
|
227
|
+
|
228
|
+
desc 'Run tests with shell'
|
229
|
+
task 'test:shell', :RUBY_OPTS do |t, args|
|
230
|
+
files = Dir['test/**/test_*.rb'].join(' ')
|
231
|
+
|
232
|
+
cmd = [Gem.ruby, args[:RUBY_OPTS],
|
233
|
+
'-I', 'lib', '-S', 'bacon', '--quiet', files]
|
234
|
+
|
235
|
+
sh(cmd.compact.join(' '))
|
236
|
+
end
|
237
|
+
|
238
|
+
desc 'Generate ann markdown'
|
239
|
+
task 'ann:md' => ['gem:spec'] do
|
240
|
+
puts Gemgem.ann_md
|
241
|
+
end
|
242
|
+
|
243
|
+
desc 'Generate ann html'
|
244
|
+
task 'ann:html' => ['gem:spec'] do
|
245
|
+
puts Gemgem.ann_html
|
246
|
+
end
|
247
|
+
|
248
|
+
desc 'Generate ann email'
|
249
|
+
task 'ann:email' => ['gem:spec'] do
|
250
|
+
puts Gemgem.ann_email
|
251
|
+
end
|
252
|
+
|
253
|
+
desc 'Generate rdoc'
|
254
|
+
task :doc => ['gem:spec'] do
|
255
|
+
sh("yardoc -o rdoc --main README.md" \
|
256
|
+
" --files #{Gemgem.spec.extra_rdoc_files.join(',')}")
|
257
|
+
end
|
258
|
+
|
259
|
+
desc 'Remove ignored files'
|
260
|
+
task :clean => ['gem:spec'] do
|
261
|
+
trash = "~/.Trash/#{Gemgem.spec.name}/"
|
262
|
+
sh "mkdir -p #{trash}" unless File.exist?(File.expand_path(trash))
|
263
|
+
Gemgem.ignored_files.each{ |file| sh "mv #{file} #{trash}" }
|
264
|
+
end
|
265
|
+
|
266
|
+
task :default do
|
267
|
+
puts `#{Gem.ruby} -S #{$PROGRAM_NAME} -T`
|
268
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
require 'muack/test'
|
3
|
+
|
4
|
+
describe Muack::AnyInstanceOf do
|
5
|
+
should 'mock any_instance_of' do
|
6
|
+
klass = Class.new
|
7
|
+
any_instance_of(klass){ |instance| mock(instance).say{ true } }
|
8
|
+
obj = klass.new
|
9
|
+
obj.say .should.eq true
|
10
|
+
obj.respond_to?(:say).should.eq true
|
11
|
+
Muack.verify .should.eq true
|
12
|
+
obj.respond_to?(:say).should.eq false
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'proxy any_instance_of' do
|
16
|
+
klass = Class.new{ def f; true; end }
|
17
|
+
any_instance_of(klass){ |instance| mock_proxy(instance).f }
|
18
|
+
obj = klass.new
|
19
|
+
obj.f.should.eq true
|
20
|
+
Muack.verify.should.eq true
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'proxy any_instance_of with a block' do
|
24
|
+
klass = Class.new{ def f; 0; end }
|
25
|
+
any_instance_of(klass){ |instance| mock_proxy(instance).f{ |i| i+1 } }
|
26
|
+
obj = klass.new
|
27
|
+
obj.f.should.eq 1
|
28
|
+
Muack.verify.should.eq true
|
29
|
+
end
|
30
|
+
end
|
data/test/test_mock.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
|
2
|
+
require 'muack/test'
|
3
|
+
|
4
|
+
describe Muack::Mock do
|
5
|
+
describe 'Muack.verify==true' do
|
6
|
+
after do
|
7
|
+
Muack.verify.should.eq true
|
8
|
+
Muack::EnsureReset.call
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'mock with regular method' do
|
12
|
+
mock(Obj).say(true){ 'boo' }
|
13
|
+
Obj.say(true).should.eq 'boo'
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'mock existing method' do
|
17
|
+
mock(Obj).to_s{ 'zoo' }
|
18
|
+
Obj.to_s.should.eq 'zoo'
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'mock twice' do
|
22
|
+
mock(Obj).say(true){ Obj.saya }
|
23
|
+
mock(Obj).saya{ 'coo' }
|
24
|
+
Obj.say(true).should.eq 'coo'
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'also mock with with' do
|
28
|
+
mock(Str).method_missing(:say, 0){ 0 }
|
29
|
+
Str.say(0).should.eq 0
|
30
|
+
Muack.verify.should.eq true
|
31
|
+
mock(Str).method_missing(:say, 1){ 1 }
|
32
|
+
lambda{ Str.say(2) }.should.raise(Muack::Unexpected)
|
33
|
+
Muack.reset
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'mock multiple times' do
|
37
|
+
3.times{ |i| mock(Obj).say(i){ i } }
|
38
|
+
3.times{ |i| Obj.say(i).should.eq i }
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'mock multiple times with times(n) modifier' do
|
42
|
+
mock(Obj).say{ 0 }.times(3)
|
43
|
+
3.times{ |i| Obj.say.should.eq 0 }
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'mock 0 times with times(0) modifier' do
|
47
|
+
mock(Obj).say{ 0 }.times(0).should.kind_of Muack::Modifier
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'mix mock and stub' do
|
51
|
+
mock(Obj).say { 0 }
|
52
|
+
stub(Obj).saya{ 1 }
|
53
|
+
3.times{ Obj.saya.should.eq 1 }
|
54
|
+
Obj.say .should.eq 0
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'unnamed mock' do
|
58
|
+
mock.say{1}.object.say.should.eq 1
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'inspect' do
|
62
|
+
mock(Obj).inspect.should.eq "#<Muack::Mock object=obj>"
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'mock and call, mock and call' do
|
66
|
+
mock(Obj).say{0}
|
67
|
+
Obj.say.should.eq 0
|
68
|
+
mock(Obj).say{1}
|
69
|
+
Obj.say.should.eq 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'Muack.verify==false' do
|
74
|
+
after do
|
75
|
+
Muack.reset
|
76
|
+
Muack::EnsureReset.call
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'raise Muack::Unexpected error if passing unexpected argument' do
|
80
|
+
mock(Obj).say(true){ 'boo' }
|
81
|
+
begin
|
82
|
+
Obj.say(false)
|
83
|
+
'never'.should.eq 'reach'
|
84
|
+
rescue Muack::Unexpected => e
|
85
|
+
e.expected.should.eq 'obj.say(true)'
|
86
|
+
e.was .should.eq 'obj.say(false)'
|
87
|
+
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
should 'have correct message for multiple mocks with the same name' do
|
92
|
+
2.times{ mock(Obj).say }
|
93
|
+
begin
|
94
|
+
3.times{ Obj.say }
|
95
|
+
'never'.should.eq 'reach'
|
96
|
+
rescue Muack::Expected => e
|
97
|
+
e.expected.should.eq 'obj.say()'
|
98
|
+
e.expected_times.should.eq 2
|
99
|
+
e.actual_times .should.eq 3
|
100
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
101
|
+
"called 2 times\n but was 3 times."
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
should 'raise if a mock with times(0) gets called' do
|
106
|
+
mock(Obj).say.times(0)
|
107
|
+
begin
|
108
|
+
Obj.say
|
109
|
+
'never'.should.eq 'reach'
|
110
|
+
rescue Muack::Unexpected => e
|
111
|
+
e.expected.should.eq nil
|
112
|
+
e.was .should.eq 'obj.say()'
|
113
|
+
e.message .should.start_with "\nExpected: #{e.was}\n"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
should 'raise if a mock with times(0) gets called with diff sig' do
|
118
|
+
mock(Obj).say.times(0)
|
119
|
+
begin
|
120
|
+
Obj.say(true)
|
121
|
+
'never'.should.eq 'reach'
|
122
|
+
rescue Muack::Unexpected => e
|
123
|
+
e.expected.should.eq nil
|
124
|
+
e.was .should.eq 'obj.say(true)'
|
125
|
+
e.message .should.start_with "\nExpected: #{e.was}\n"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
should 'raise Muack::Unexpected when calling with diff sig' do
|
130
|
+
mock(Obj).say(true){1}
|
131
|
+
Obj.say(true).should.eq 1
|
132
|
+
begin
|
133
|
+
Obj.say
|
134
|
+
'never'.should.eq 'reach'
|
135
|
+
rescue Muack::Unexpected => e
|
136
|
+
e.expected.should.eq 'obj.say(true)'
|
137
|
+
e.was .should.eq 'obj.say()'
|
138
|
+
e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
should 'raise Muack::Expected error if mock methods not called' do
|
143
|
+
mock(Obj).say(true){ 'boo' }
|
144
|
+
begin
|
145
|
+
Muack.verify
|
146
|
+
rescue Muack::Expected => e
|
147
|
+
e.expected .should.eq 'obj.say(true)'
|
148
|
+
e.expected_times.should.eq 1
|
149
|
+
e.actual_times .should.eq 0
|
150
|
+
e.message .should.eq "\nExpected: obj.say(true)\n " \
|
151
|
+
"called 1 times\n but was 0 times."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
should 'show first not enough calls' do
|
156
|
+
mock(Obj).say{ 'boo' }.times(2)
|
157
|
+
mock(Obj).saya .times(2)
|
158
|
+
begin
|
159
|
+
Obj.say
|
160
|
+
Muack.verify
|
161
|
+
rescue Muack::Expected => e
|
162
|
+
e.expected .should.eq 'obj.say()'
|
163
|
+
e.expected_times.should.eq 2
|
164
|
+
e.actual_times .should.eq 1
|
165
|
+
e.message .should.eq "\nExpected: obj.say()\n " \
|
166
|
+
"called 2 times\n but was 1 times."
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|