undees-bacon 1.1.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.
- data/COPYING +18 -0
- data/README +290 -0
- data/Rakefile +138 -0
- data/bin/bacon +117 -0
- data/lib/autotest/bacon.rb +36 -0
- data/lib/autotest/bacon_rspec.rb +2 -0
- data/lib/autotest/discover.rb +9 -0
- data/lib/bacon.rb +354 -0
- data/test/spec_bacon.rb +374 -0
- data/test/spec_nontrue.rb +14 -0
- data/test/spec_should.rb +32 -0
- metadata +66 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
Autotest.add_hook :initialize do |att|
|
2
|
+
att.clear_mappings
|
3
|
+
|
4
|
+
att.add_mapping(%r%^(test|spec)/.*\.rb$%) do |filename, _|
|
5
|
+
filename
|
6
|
+
end
|
7
|
+
|
8
|
+
att.add_mapping(%r%^lib/(.*)\.rb$%) do |filename, m|
|
9
|
+
lib_path = m[1]
|
10
|
+
spec = File.basename(lib_path)
|
11
|
+
path = File.dirname(lib_path)
|
12
|
+
[
|
13
|
+
"test/#{path}/test_#{spec}.rb",
|
14
|
+
"test/#{path}/spec_#{spec}.rb",
|
15
|
+
"spec/#{path}/spec_#{spec}.rb",
|
16
|
+
# TODO : decide if the follow 'rspec style' name should be allowed?
|
17
|
+
# "spec/#{path}/#{spec}_spec.rb"
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
class Autotest::Bacon < Autotest
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
self.libs = %w[. lib test spec].join(File::PATH_SEPARATOR)
|
28
|
+
end
|
29
|
+
|
30
|
+
def make_test_cmd(files_to_test)
|
31
|
+
args = files_to_test.keys.flatten.join(' ')
|
32
|
+
args = '-a' if args.empty?
|
33
|
+
# TODO : make regex to pass to -n using values
|
34
|
+
"#{ruby} -S bacon -o TestUnit #{args}"
|
35
|
+
end
|
36
|
+
end
|
data/lib/bacon.rb
ADDED
@@ -0,0 +1,354 @@
|
|
1
|
+
# Bacon -- small RSpec clone.
|
2
|
+
#
|
3
|
+
# "Truth will sooner come out from error than from confusion." ---Francis Bacon
|
4
|
+
|
5
|
+
# Copyright (C) 2007, 2008 Christian Neukirchen <purl.org/net/chneukirchen>
|
6
|
+
#
|
7
|
+
# Bacon is freely distributable under the terms of an MIT-style license.
|
8
|
+
# See COPYING or http://www.opensource.org/licenses/mit-license.php.
|
9
|
+
|
10
|
+
module Bacon
|
11
|
+
VERSION = "1.1"
|
12
|
+
|
13
|
+
Counter = Hash.new(0)
|
14
|
+
ErrorLog = ""
|
15
|
+
Shared = Hash.new { |_, name|
|
16
|
+
raise NameError, "no such context: #{name.inspect}"
|
17
|
+
}
|
18
|
+
|
19
|
+
RestrictName = // unless defined? RestrictName
|
20
|
+
RestrictContext = // unless defined? RestrictContext
|
21
|
+
|
22
|
+
Backtraces = true unless defined? Backtraces
|
23
|
+
|
24
|
+
def self.summary_on_exit
|
25
|
+
return if Counter[:installed_summary] > 0
|
26
|
+
at_exit {
|
27
|
+
handle_summary
|
28
|
+
if $!
|
29
|
+
raise $!
|
30
|
+
elsif Counter[:errors] + Counter[:failed] > 0
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
}
|
34
|
+
Counter[:installed_summary] += 1
|
35
|
+
end
|
36
|
+
class <<self; alias summary_at_exit summary_on_exit; end
|
37
|
+
|
38
|
+
module SpecDoxOutput
|
39
|
+
def handle_specification(name)
|
40
|
+
puts name
|
41
|
+
yield
|
42
|
+
puts
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_requirement(description)
|
46
|
+
print "- #{description}"
|
47
|
+
error = yield
|
48
|
+
puts error.empty? ? "" : " [#{error}]"
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_summary
|
52
|
+
print ErrorLog if Backtraces
|
53
|
+
puts "%d specifications (%d requirements), %d failures, %d errors" %
|
54
|
+
Counter.values_at(:specifications, :requirements, :failed, :errors)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module TestUnitOutput
|
59
|
+
def handle_specification(name) yield end
|
60
|
+
|
61
|
+
def handle_requirement(description)
|
62
|
+
error = yield
|
63
|
+
if error.empty?
|
64
|
+
print "."
|
65
|
+
else
|
66
|
+
print error[0..0]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_summary
|
71
|
+
puts
|
72
|
+
puts ErrorLog if Backtraces
|
73
|
+
puts "%d tests, %d assertions, %d failures, %d errors" %
|
74
|
+
Counter.values_at(:specifications, :requirements, :failed, :errors)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module TapOutput
|
79
|
+
def handle_specification(name) yield end
|
80
|
+
|
81
|
+
def handle_requirement(description)
|
82
|
+
ErrorLog.replace ""
|
83
|
+
error = yield
|
84
|
+
if error.empty?
|
85
|
+
puts "ok %-3d - %s" % [Counter[:specifications], description]
|
86
|
+
else
|
87
|
+
puts "not ok %d - %s: %s" %
|
88
|
+
[Counter[:specifications], description, error]
|
89
|
+
puts ErrorLog.strip.gsub(/^/, '# ') if Backtraces
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def handle_summary
|
94
|
+
puts "1..#{Counter[:specifications]}"
|
95
|
+
puts "# %d tests, %d assertions, %d failures, %d errors" %
|
96
|
+
Counter.values_at(:specifications, :requirements, :failed, :errors)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module KnockOutput
|
101
|
+
def handle_specification(name) yield end
|
102
|
+
|
103
|
+
def handle_requirement(description)
|
104
|
+
ErrorLog.replace ""
|
105
|
+
error = yield
|
106
|
+
if error.empty?
|
107
|
+
puts "ok - %s" % [description]
|
108
|
+
else
|
109
|
+
puts "not ok - %s: %s" % [description, error]
|
110
|
+
puts ErrorLog.strip.gsub(/^/, '# ') if Backtraces
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def handle_summary; end
|
115
|
+
end
|
116
|
+
|
117
|
+
extend SpecDoxOutput # default
|
118
|
+
|
119
|
+
class Error < RuntimeError
|
120
|
+
attr_accessor :count_as
|
121
|
+
|
122
|
+
def initialize(count_as, message)
|
123
|
+
@count_as = count_as
|
124
|
+
super message
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class Context
|
129
|
+
attr_reader :name, :block
|
130
|
+
|
131
|
+
def initialize(name, &block)
|
132
|
+
@name = name
|
133
|
+
@before, @after = [], []
|
134
|
+
@block = block
|
135
|
+
end
|
136
|
+
|
137
|
+
def run
|
138
|
+
return unless name =~ RestrictContext
|
139
|
+
Bacon.handle_specification(name) { instance_eval(&block) }
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
def before(&block); @before << block; end
|
144
|
+
def after(&block); @after << block; end
|
145
|
+
|
146
|
+
def behaves_like(*names)
|
147
|
+
names.each { |name| instance_eval(&Shared[name]) }
|
148
|
+
end
|
149
|
+
|
150
|
+
def it(description, &block)
|
151
|
+
return unless description =~ RestrictName
|
152
|
+
block ||= lambda { should.flunk "not implemented" }
|
153
|
+
Counter[:specifications] += 1
|
154
|
+
run_requirement description, block
|
155
|
+
end
|
156
|
+
|
157
|
+
def should(*args, &block)
|
158
|
+
if Counter[:depth]==0
|
159
|
+
it('should '+args.first,&block)
|
160
|
+
else
|
161
|
+
super(*args,&block)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def run_requirement(description, spec)
|
166
|
+
Bacon.handle_requirement description do
|
167
|
+
begin
|
168
|
+
Counter[:depth] += 1
|
169
|
+
rescued = false
|
170
|
+
begin
|
171
|
+
@before.each { |block| instance_eval(&block) }
|
172
|
+
prev_req = Counter[:requirements]
|
173
|
+
instance_eval(&spec)
|
174
|
+
rescue Object => e
|
175
|
+
rescued = true
|
176
|
+
raise e
|
177
|
+
ensure
|
178
|
+
if Counter[:requirements] == prev_req and not rescued
|
179
|
+
raise Error.new(:missing,
|
180
|
+
"empty specification: #{@name} #{description}")
|
181
|
+
end
|
182
|
+
begin
|
183
|
+
@after.each { |block| instance_eval(&block) }
|
184
|
+
rescue Object => e
|
185
|
+
raise e unless rescued
|
186
|
+
end
|
187
|
+
end
|
188
|
+
rescue Object => e
|
189
|
+
ErrorLog << "#{e.class}: #{e.message}\n"
|
190
|
+
e.backtrace.find_all { |line| line !~ /bin\/bacon|\/bacon\.rb:\d+/ }.
|
191
|
+
each_with_index { |line, i|
|
192
|
+
ErrorLog << "\t#{line}#{i==0 ? ": #@name - #{description}" : ""}\n"
|
193
|
+
}
|
194
|
+
ErrorLog << "\n"
|
195
|
+
|
196
|
+
if e.kind_of? Error
|
197
|
+
Counter[e.count_as] += 1
|
198
|
+
e.count_as.to_s.upcase
|
199
|
+
else
|
200
|
+
Counter[:errors] += 1
|
201
|
+
"ERROR: #{e.class}"
|
202
|
+
end
|
203
|
+
else
|
204
|
+
""
|
205
|
+
ensure
|
206
|
+
Counter[:depth] -= 1
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def describe(*args, &block)
|
212
|
+
context = Bacon::Context.new(args.join(' '), &block)
|
213
|
+
@before.each { |b| context.before(&b) }
|
214
|
+
@after.each { |b| context.after(&b) }
|
215
|
+
context.run
|
216
|
+
end
|
217
|
+
|
218
|
+
def raise?(*args, &block); block.raise?(*args); end
|
219
|
+
def throw?(*args, &block); block.throw?(*args); end
|
220
|
+
def change?(*args, &block); block.change?(*args); end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
class Object
|
226
|
+
def true?; false; end
|
227
|
+
def false?; false; end
|
228
|
+
end
|
229
|
+
|
230
|
+
class TrueClass
|
231
|
+
def true?; true; end
|
232
|
+
end
|
233
|
+
|
234
|
+
class FalseClass
|
235
|
+
def false?; true; end
|
236
|
+
end
|
237
|
+
|
238
|
+
class Proc
|
239
|
+
def raise?(*exceptions)
|
240
|
+
exceptions = [RuntimeError] if exceptions.empty?
|
241
|
+
call
|
242
|
+
|
243
|
+
# Only to work in 1.9.0, rescue with splat doesn't work there right now
|
244
|
+
rescue Object => e
|
245
|
+
case e
|
246
|
+
when *exceptions
|
247
|
+
e
|
248
|
+
else
|
249
|
+
raise e
|
250
|
+
end
|
251
|
+
else
|
252
|
+
false
|
253
|
+
end
|
254
|
+
|
255
|
+
def throw?(sym)
|
256
|
+
catch(sym) {
|
257
|
+
call
|
258
|
+
return false
|
259
|
+
}
|
260
|
+
return true
|
261
|
+
end
|
262
|
+
|
263
|
+
def change?
|
264
|
+
pre_result = yield
|
265
|
+
called = call
|
266
|
+
post_result = yield
|
267
|
+
pre_result != post_result
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class Numeric
|
272
|
+
def close?(to, delta)
|
273
|
+
(to.to_f - self).abs <= delta.to_f rescue false
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
class Object
|
279
|
+
def should(*args, &block) Should.new(self).be(*args, &block) end
|
280
|
+
end
|
281
|
+
|
282
|
+
module Kernel
|
283
|
+
private
|
284
|
+
def describe(*args, &block) Bacon::Context.new(args.join(' '), &block).run end
|
285
|
+
def shared(name, &block) Bacon::Shared[name] = block end
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
class Should
|
290
|
+
# Kills ==, ===, =~, eql?, equal?, frozen?, instance_of?, is_a?,
|
291
|
+
# kind_of?, nil?, respond_to?, tainted?
|
292
|
+
instance_methods.each { |name| undef_method name if name =~ /\?|^\W+$/ }
|
293
|
+
|
294
|
+
def initialize(object)
|
295
|
+
@object = object
|
296
|
+
@negated = false
|
297
|
+
end
|
298
|
+
|
299
|
+
def not(*args, &block)
|
300
|
+
@negated = !@negated
|
301
|
+
|
302
|
+
if args.empty?
|
303
|
+
self
|
304
|
+
else
|
305
|
+
be(*args, &block)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def be(*args, &block)
|
310
|
+
if args.empty?
|
311
|
+
self
|
312
|
+
else
|
313
|
+
block = args.shift unless block_given?
|
314
|
+
satisfy(*args, &block)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
alias a be
|
319
|
+
alias an be
|
320
|
+
|
321
|
+
def satisfy(*args, &block)
|
322
|
+
if args.size == 1 && String === args.first
|
323
|
+
description = args.shift
|
324
|
+
else
|
325
|
+
description = ""
|
326
|
+
end
|
327
|
+
|
328
|
+
r = yield(@object, *args)
|
329
|
+
if Bacon::Counter[:depth] > 0
|
330
|
+
Bacon::Counter[:requirements] += 1
|
331
|
+
raise Bacon::Error.new(:failed, description) unless @negated ^ r
|
332
|
+
end
|
333
|
+
(@negated ^ r) ? (r || true) : false
|
334
|
+
end
|
335
|
+
|
336
|
+
def method_missing(name, *args, &block)
|
337
|
+
name = "#{name}?" if name.to_s =~ /\w[^?]\z/
|
338
|
+
|
339
|
+
desc = @negated ? "not " : ""
|
340
|
+
desc << @object.inspect << "." << name.to_s
|
341
|
+
desc << "(" << args.map{|x|x.inspect}.join(", ") << ") failed"
|
342
|
+
|
343
|
+
satisfy(desc) { |x| x.__send__(name, *args, &block) }
|
344
|
+
end
|
345
|
+
|
346
|
+
def equal(value) self == value end
|
347
|
+
def match(value) self =~ value end
|
348
|
+
def identical_to(value) self.equal? value end
|
349
|
+
alias same_as identical_to
|
350
|
+
|
351
|
+
def flunk(reason="Flunked")
|
352
|
+
raise Bacon::Error.new(:failed, reason)
|
353
|
+
end
|
354
|
+
end
|
data/test/spec_bacon.rb
ADDED
@@ -0,0 +1,374 @@
|
|
1
|
+
$-w,w = nil, $-w
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/bacon')
|
3
|
+
$-w = w
|
4
|
+
|
5
|
+
# Hooray for meta-testing.
|
6
|
+
module MetaTests
|
7
|
+
def succeed
|
8
|
+
lambda { |block|
|
9
|
+
block.should.not.raise Bacon::Error
|
10
|
+
true
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def fail
|
15
|
+
lambda { |block|
|
16
|
+
block.should.raise Bacon::Error
|
17
|
+
true
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def equal_string(x)
|
22
|
+
lambda { |s|
|
23
|
+
x == s.to_s
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "Bacon" do
|
29
|
+
extend MetaTests
|
30
|
+
|
31
|
+
it "should have should.satisfy" do
|
32
|
+
lambda { should.satisfy { 1 == 1 } }.should succeed
|
33
|
+
lambda { should.satisfy { 1 } }.should succeed
|
34
|
+
|
35
|
+
lambda { should.satisfy { 1 != 1 } }.should fail
|
36
|
+
lambda { should.satisfy { false } }.should fail
|
37
|
+
lambda { should.satisfy { false } }.should fail
|
38
|
+
|
39
|
+
lambda { 1.should.satisfy { |n| n % 2 == 0 } }.should fail
|
40
|
+
lambda { 2.should.satisfy { |n| n % 2 == 0 } }.should succeed
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have should.equal" do
|
44
|
+
lambda { "string1".should == "string1" }.should succeed
|
45
|
+
lambda { "string1".should == "string2" }.should fail
|
46
|
+
lambda { "1".should == 1 }.should fail
|
47
|
+
|
48
|
+
lambda { "string1".should.equal "string1" }.should succeed
|
49
|
+
lambda { "string1".should.equal "string2" }.should fail
|
50
|
+
lambda { "1".should.equal 1 }.should fail
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have should.raise" do
|
54
|
+
lambda { lambda { raise "Error" }.should.raise }.should succeed
|
55
|
+
lambda { lambda { raise "Error" }.should.raise RuntimeError }.should succeed
|
56
|
+
lambda { lambda { raise "Error" }.should.not.raise }.should fail
|
57
|
+
lambda { lambda { raise "Error" }.should.not.raise(RuntimeError) }.should fail
|
58
|
+
|
59
|
+
lambda { lambda { 1 + 1 }.should.raise }.should fail
|
60
|
+
lambda {
|
61
|
+
lambda { raise "Error" }.should.raise(Interrupt)
|
62
|
+
}.should.raise
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have should.raise with a block" do
|
66
|
+
lambda { should.raise { raise "Error" } }.should succeed
|
67
|
+
lambda { should.raise(RuntimeError) { raise "Error" } }.should succeed
|
68
|
+
lambda { should.not.raise { raise "Error" } }.should fail
|
69
|
+
lambda { should.not.raise(RuntimeError) { raise "Error" } }.should fail
|
70
|
+
|
71
|
+
lambda { should.raise { 1 + 1 } }.should fail
|
72
|
+
lambda {
|
73
|
+
should.raise(Interrupt) { raise "Error" }
|
74
|
+
}.should.raise
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have a should.raise should return the exception" do
|
78
|
+
ex = lambda { raise "foo!" }.should.raise
|
79
|
+
ex.should.be.kind_of RuntimeError
|
80
|
+
ex.message.should =~ /foo/
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have should.be.an.instance_of" do
|
84
|
+
lambda { "string".should.be.instance_of String }.should succeed
|
85
|
+
lambda { "string".should.be.instance_of Hash }.should fail
|
86
|
+
|
87
|
+
lambda { "string".should.be.an.instance_of String }.should succeed
|
88
|
+
lambda { "string".should.be.an.instance_of Hash }.should fail
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have should.be.nil" do
|
92
|
+
lambda { nil.should.be.nil }.should succeed
|
93
|
+
lambda { nil.should.not.be.nil }.should fail
|
94
|
+
lambda { "foo".should.be.nil }.should fail
|
95
|
+
lambda { "foo".should.not.be.nil }.should succeed
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should have should.include" do
|
99
|
+
lambda { [1,2,3].should.include 2 }.should succeed
|
100
|
+
lambda { [1,2,3].should.include 4 }.should fail
|
101
|
+
|
102
|
+
lambda { {1=>2, 3=>4}.should.include 1 }.should succeed
|
103
|
+
lambda { {1=>2, 3=>4}.should.include 2 }.should fail
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should have should.be.a.kind_of" do
|
107
|
+
lambda { Array.should.be.kind_of Module }.should succeed
|
108
|
+
lambda { "string".should.be.kind_of Object }.should succeed
|
109
|
+
lambda { 1.should.be.kind_of Comparable }.should succeed
|
110
|
+
|
111
|
+
lambda { Array.should.be.a.kind_of Module }.should succeed
|
112
|
+
|
113
|
+
lambda { "string".should.be.a.kind_of Class }.should fail
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should have should.match" do
|
117
|
+
lambda { "string".should.match(/strin./) }.should succeed
|
118
|
+
lambda { "string".should =~ /strin./ }.should succeed
|
119
|
+
|
120
|
+
lambda { "string".should.match(/slin./) }.should fail
|
121
|
+
lambda { "string".should =~ /slin./ }.should fail
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should have should.not.raise" do
|
125
|
+
lambda { lambda { 1 + 1 }.should.not.raise }.should succeed
|
126
|
+
lambda { lambda { 1 + 1 }.should.not.raise(Interrupt) }.should succeed
|
127
|
+
|
128
|
+
lambda {
|
129
|
+
lambda {
|
130
|
+
lambda {
|
131
|
+
Kernel.raise ZeroDivisionError.new("ArgumentError")
|
132
|
+
}.should.not.raise(RuntimeError, Comparable)
|
133
|
+
}.should.raise ZeroDivisionError
|
134
|
+
}.should succeed
|
135
|
+
|
136
|
+
lambda { lambda { raise "Error" }.should.not.raise }.should fail
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should have should.throw" do
|
140
|
+
lambda { lambda { throw :foo }.should.throw(:foo) }.should succeed
|
141
|
+
lambda { lambda { :foo }.should.throw(:foo) }.should fail
|
142
|
+
|
143
|
+
should.throw(:foo) { throw :foo }
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should have should.not.satisfy" do
|
147
|
+
lambda { should.not.satisfy { 1 == 2 } }.should succeed
|
148
|
+
lambda { should.not.satisfy { 1 == 1 } }.should fail
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should have should.not.equal" do
|
152
|
+
lambda { "string1".should.not == "string2" }.should succeed
|
153
|
+
lambda { "string1".should.not == "string1" }.should fail
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should have should.not.match" do
|
157
|
+
lambda { "string".should.not.match(/sling/) }.should succeed
|
158
|
+
lambda { "string".should.not.match(/string/) }.should fail
|
159
|
+
# lambda { "string".should.not.match("strin") }.should fail
|
160
|
+
|
161
|
+
lambda { "string".should.not =~ /sling/ }.should succeed
|
162
|
+
lambda { "string".should.not =~ /string/ }.should fail
|
163
|
+
# lambda { "string".should.not =~ "strin" }.should fail
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should have should.be.identical_to/same_as" do
|
167
|
+
lambda { s = "string"; s.should.be.identical_to s }.should succeed
|
168
|
+
lambda { "string".should.be.identical_to "string" }.should fail
|
169
|
+
|
170
|
+
lambda { s = "string"; s.should.be.same_as s }.should succeed
|
171
|
+
lambda { "string".should.be.same_as "string" }.should fail
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should have should.respond_to" do
|
175
|
+
lambda { "foo".should.respond_to :to_s }.should succeed
|
176
|
+
lambda { 5.should.respond_to :to_str }.should fail
|
177
|
+
lambda { :foo.should.respond_to :nx }.should fail
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should have should.be.close" do
|
181
|
+
lambda { 1.4.should.be.close 1.4, 0 }.should succeed
|
182
|
+
lambda { 0.4.should.be.close 0.5, 0.1 }.should succeed
|
183
|
+
|
184
|
+
lambda { 0.4.should.be.close 0.5, 0.05 }.should fail
|
185
|
+
lambda { 0.4.should.be.close Object.new, 0.1 }.should fail
|
186
|
+
lambda { 0.4.should.be.close 0.5, -0.1 }.should fail
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should support multiple negation" do
|
190
|
+
lambda { 1.should.equal 1 }.should succeed
|
191
|
+
lambda { 1.should.not.equal 1 }.should fail
|
192
|
+
lambda { 1.should.not.not.equal 1 }.should succeed
|
193
|
+
lambda { 1.should.not.not.not.equal 1 }.should fail
|
194
|
+
|
195
|
+
lambda { 1.should.equal 2 }.should fail
|
196
|
+
lambda { 1.should.not.equal 2 }.should succeed
|
197
|
+
lambda { 1.should.not.not.equal 2 }.should fail
|
198
|
+
lambda { 1.should.not.not.not.equal 2 }.should succeed
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should have should.<predicate>" do
|
202
|
+
lambda { [].should.be.empty }.should succeed
|
203
|
+
lambda { [1,2,3].should.not.be.empty }.should succeed
|
204
|
+
|
205
|
+
lambda { [].should.not.be.empty }.should fail
|
206
|
+
lambda { [1,2,3].should.be.empty }.should fail
|
207
|
+
|
208
|
+
lambda { {1=>2, 3=>4}.should.has_key 1 }.should succeed
|
209
|
+
lambda { {1=>2, 3=>4}.should.not.has_key 2 }.should succeed
|
210
|
+
|
211
|
+
lambda { nil.should.bla }.should.raise(NoMethodError)
|
212
|
+
lambda { nil.should.not.bla }.should.raise(NoMethodError)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should have should <operator> (>, >=, <, <=, ===)" do
|
216
|
+
lambda { 2.should.be > 1 }.should succeed
|
217
|
+
lambda { 1.should.be > 2 }.should fail
|
218
|
+
|
219
|
+
lambda { 1.should.be < 2 }.should succeed
|
220
|
+
lambda { 2.should.be < 1 }.should fail
|
221
|
+
|
222
|
+
lambda { 2.should.be >= 1 }.should succeed
|
223
|
+
lambda { 2.should.be >= 2 }.should succeed
|
224
|
+
lambda { 2.should.be >= 2.1 }.should fail
|
225
|
+
|
226
|
+
lambda { 2.should.be <= 1 }.should fail
|
227
|
+
lambda { 2.should.be <= 2 }.should succeed
|
228
|
+
lambda { 2.should.be <= 2.1 }.should succeed
|
229
|
+
|
230
|
+
lambda { Array.should === [1,2,3] }.should succeed
|
231
|
+
lambda { Integer.should === [1,2,3] }.should fail
|
232
|
+
|
233
|
+
lambda { /foo/.should === "foobar" }.should succeed
|
234
|
+
lambda { "foobar".should === /foo/ }.should fail
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should allow for custom shoulds" do
|
238
|
+
lambda { (1+1).should equal_string("2") }.should succeed
|
239
|
+
lambda { (1+2).should equal_string("2") }.should fail
|
240
|
+
|
241
|
+
lambda { (1+1).should.be equal_string("2") }.should succeed
|
242
|
+
lambda { (1+2).should.be equal_string("2") }.should fail
|
243
|
+
|
244
|
+
lambda { (1+1).should.not equal_string("2") }.should fail
|
245
|
+
lambda { (1+2).should.not equal_string("2") }.should succeed
|
246
|
+
lambda { (1+2).should.not.not equal_string("2") }.should fail
|
247
|
+
|
248
|
+
lambda { (1+1).should.not.be equal_string("2") }.should fail
|
249
|
+
lambda { (1+2).should.not.be equal_string("2") }.should succeed
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should have should.flunk" do
|
253
|
+
lambda { should.flunk }.should fail
|
254
|
+
lambda { should.flunk "yikes" }.should fail
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "before/after" do
|
259
|
+
before do
|
260
|
+
@a = 1
|
261
|
+
@b = 2
|
262
|
+
end
|
263
|
+
|
264
|
+
before do
|
265
|
+
@a = 2
|
266
|
+
end
|
267
|
+
|
268
|
+
after do
|
269
|
+
@a.should.equal 2
|
270
|
+
@a = 3
|
271
|
+
end
|
272
|
+
|
273
|
+
after do
|
274
|
+
@a.should.equal 3
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should run in the right order" do
|
278
|
+
@a.should.equal 2
|
279
|
+
@b.should.equal 2
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "when nested" do
|
283
|
+
before do
|
284
|
+
@c = 5
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should run from higher level" do
|
288
|
+
@a.should.equal 2
|
289
|
+
@b.should.equal 2
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should run at the nested level" do
|
293
|
+
@c.should.equal 5
|
294
|
+
end
|
295
|
+
|
296
|
+
before do
|
297
|
+
@a = 5
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should run in the right order" do
|
301
|
+
@a.should.equal 5
|
302
|
+
@a = 2
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should not run from lower level" do
|
307
|
+
@c.should.be.nil
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "when nested at a sibling level" do
|
311
|
+
it "should not run from sibling level" do
|
312
|
+
@c.should.be.nil
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
shared "a shared context" do
|
318
|
+
it "gets called where it is included" do
|
319
|
+
true.should.be.true
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
shared "another shared context" do
|
324
|
+
it "can access data" do
|
325
|
+
@magic.should.be.equal 42
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
describe "shared/behaves_like" do
|
330
|
+
behaves_like "a shared context"
|
331
|
+
|
332
|
+
ctx = self
|
333
|
+
it "raises NameError when the context is not found" do
|
334
|
+
lambda {
|
335
|
+
ctx.behaves_like "whoops"
|
336
|
+
}.should.raise NameError
|
337
|
+
end
|
338
|
+
|
339
|
+
behaves_like "a shared context"
|
340
|
+
|
341
|
+
before {
|
342
|
+
@magic = 42
|
343
|
+
}
|
344
|
+
behaves_like "another shared context"
|
345
|
+
end
|
346
|
+
|
347
|
+
describe 'describe arguments' do
|
348
|
+
|
349
|
+
def check(ctx,name)
|
350
|
+
ctx.should.be.an.instance_of Bacon::Context
|
351
|
+
ctx.instance_variable_get('@name').should == name
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should work with string' do
|
355
|
+
check(describe('string') {},'string')
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'should work with symbols' do
|
359
|
+
check(describe(:behaviour) {},'behaviour')
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'should work with modules' do
|
363
|
+
check(describe(Bacon) {},'Bacon')
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'should work with namespaced modules' do
|
367
|
+
check(describe(Bacon::Context) {},'Bacon::Context')
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'should work with multiple arguments' do
|
371
|
+
check(describe(Bacon::Context, :empty) {},'Bacon::Context empty')
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|