test-spec 0.2 → 0.3.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.
- data/{README.txt → README} +85 -2
- data/ROADMAP +1 -0
- data/Rakefile +105 -91
- data/TODO +2 -0
- data/bin/specrb +104 -0
- data/examples/stack.rb +38 -0
- data/examples/stack_spec.rb +119 -0
- data/lib/{test-spec/test → test}/spec.rb +167 -45
- data/lib/{test-spec/test → test}/spec/dox.rb +16 -8
- data/lib/{test-spec/test → test}/spec/rdox.rb +1 -2
- data/lib/{test-spec/test → test}/spec/should-output.rb +3 -2
- data/test/spec_dox.rb +39 -0
- data/test/spec_flexmock.rb +210 -0
- data/test/spec_mocha.rb +118 -0
- data/test/spec_nestedcontexts.rb +26 -0
- data/test/spec_should-output.rb +26 -0
- data/test/spec_testspec.rb +522 -0
- data/test/spec_testspec_order.rb +26 -0
- data/test/test_testunit.rb +21 -0
- metadata +35 -20
- data/History.txt +0 -0
- data/Manifest.txt +0 -11
- data/lib/test-spec.rb +0 -2
- data/lib/test-spec/version.rb +0 -9
- data/setup.rb +0 -1585
data/examples/stack.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copied without code changes from RSpec.
|
2
|
+
|
3
|
+
class StackUnderflowError < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
class StackOverflowError < RuntimeError
|
7
|
+
end
|
8
|
+
|
9
|
+
class Stack
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@items = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def push object
|
16
|
+
raise StackOverflowError if @items.length == 10
|
17
|
+
@items.push object
|
18
|
+
end
|
19
|
+
|
20
|
+
def pop
|
21
|
+
raise StackUnderflowError if @items.empty?
|
22
|
+
@items.delete @items.last
|
23
|
+
end
|
24
|
+
|
25
|
+
def peek
|
26
|
+
raise StackUnderflowError if @items.empty?
|
27
|
+
@items.last
|
28
|
+
end
|
29
|
+
|
30
|
+
def empty?
|
31
|
+
@items.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def full?
|
35
|
+
@items.length == 10
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Copied with minor code changes (should_xxx -> should.xxx) from RSpec.
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/test/spec'
|
4
|
+
require File.dirname(__FILE__) + "/stack"
|
5
|
+
|
6
|
+
context "A stack (in general)" do
|
7
|
+
setup do
|
8
|
+
@stack = Stack.new
|
9
|
+
["a","b","c"].each { |x| @stack.push x }
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "should add to the top when sent 'push'" do
|
13
|
+
@stack.push "d"
|
14
|
+
@stack.peek.should.equal "d"
|
15
|
+
end
|
16
|
+
|
17
|
+
specify "should return the top item when sent 'peek'" do
|
18
|
+
@stack.peek.should.equal "c"
|
19
|
+
end
|
20
|
+
|
21
|
+
specify "should NOT remove the top item when sent 'peek'" do
|
22
|
+
@stack.peek.should.equal "c"
|
23
|
+
@stack.peek.should.equal "c"
|
24
|
+
end
|
25
|
+
|
26
|
+
specify "should return the top item when sent 'pop'" do
|
27
|
+
@stack.pop.should.equal "c"
|
28
|
+
end
|
29
|
+
|
30
|
+
specify "should remove the top item when sent 'pop'" do
|
31
|
+
@stack.pop.should.equal "c"
|
32
|
+
@stack.pop.should.equal "b"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "An empty stack" do
|
37
|
+
setup do
|
38
|
+
@stack = Stack.new
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "should be empty" do
|
42
|
+
@stack.should.be.empty
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "should no longer be empty after 'push'" do
|
46
|
+
@stack.push "anything"
|
47
|
+
@stack.should.not.be.empty
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should complain when sent 'peek'" do
|
51
|
+
lambda { @stack.peek }.should.raise StackUnderflowError
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "should complain when sent 'pop'" do
|
55
|
+
lambda { @stack.pop }.should.raise StackUnderflowError
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "An almost empty stack (with one item)" do
|
60
|
+
setup do
|
61
|
+
@stack = Stack.new
|
62
|
+
@stack.push 3
|
63
|
+
end
|
64
|
+
|
65
|
+
specify "should not be empty" do
|
66
|
+
@stack.should.not.be.empty
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "should remain not empty after 'peek'" do
|
70
|
+
@stack.peek
|
71
|
+
@stack.should.not.be.empty
|
72
|
+
end
|
73
|
+
|
74
|
+
specify "should become empty after 'pop'" do
|
75
|
+
@stack.pop
|
76
|
+
@stack.should.be.empty
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "An almost full stack (with one item less than capacity)" do
|
81
|
+
setup do
|
82
|
+
@stack = Stack.new
|
83
|
+
(1..9).each { |i| @stack.push i }
|
84
|
+
end
|
85
|
+
|
86
|
+
specify "should not be full" do
|
87
|
+
@stack.should.not.be.full
|
88
|
+
end
|
89
|
+
|
90
|
+
specify "should become full when sent 'push'" do
|
91
|
+
@stack.push Object.new
|
92
|
+
@stack.should.be.full
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "A full stack" do
|
97
|
+
setup do
|
98
|
+
@stack = Stack.new
|
99
|
+
(1..10).each { |i| @stack.push i }
|
100
|
+
end
|
101
|
+
|
102
|
+
specify "should be full" do
|
103
|
+
@stack.should.be.full
|
104
|
+
end
|
105
|
+
|
106
|
+
specify "should remain full after 'peek'" do
|
107
|
+
@stack.peek
|
108
|
+
@stack.should.be.full
|
109
|
+
end
|
110
|
+
|
111
|
+
specify "should no longer be full after 'pop'" do
|
112
|
+
@stack.pop
|
113
|
+
@stack.should.not.be.full
|
114
|
+
end
|
115
|
+
|
116
|
+
specify "should complain on 'push'" do
|
117
|
+
lambda { @stack.push Object.new }.should.raise StackOverflowError
|
118
|
+
end
|
119
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# test/spec -- a BDD interface for Test::Unit
|
3
3
|
#
|
4
|
-
# Copyright (C) 2006 Christian Neukirchen <mailto:chneukirchen@gmail.com>
|
4
|
+
# Copyright (C) 2006, 2007 Christian Neukirchen <mailto:chneukirchen@gmail.com>
|
5
5
|
#
|
6
6
|
# This work is licensed under the same terms as Ruby itself.
|
7
7
|
#
|
@@ -24,9 +24,9 @@ module Test # :nodoc:
|
|
24
24
|
end
|
25
25
|
|
26
26
|
module Test::Spec
|
27
|
-
VERSION = "0.
|
27
|
+
VERSION = "0.3"
|
28
28
|
|
29
|
-
CONTEXTS = {}
|
29
|
+
CONTEXTS = {} # :nodoc:
|
30
30
|
|
31
31
|
class DefinitionError < StandardError
|
32
32
|
end
|
@@ -34,8 +34,16 @@ module Test::Spec
|
|
34
34
|
class Should
|
35
35
|
include Test::Unit::Assertions
|
36
36
|
|
37
|
-
def
|
37
|
+
def self.deprecated_alias(to, from) # :nodoc:
|
38
|
+
define_method(to) { |*args|
|
39
|
+
warn "Test::Spec::Should##{to} is deprecated and will be removed in future versions."
|
40
|
+
__send__ from, *args
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(object, message=nil)
|
38
45
|
@object = object
|
46
|
+
@message = message
|
39
47
|
end
|
40
48
|
|
41
49
|
$TEST_SPEC_TESTCASE = nil
|
@@ -52,96 +60,121 @@ module Test::Spec
|
|
52
60
|
self
|
53
61
|
end
|
54
62
|
|
55
|
-
def not
|
56
|
-
|
63
|
+
def not(*args)
|
64
|
+
case args.size
|
65
|
+
when 0
|
66
|
+
ShouldNot.new(@object, @message)
|
67
|
+
when 1
|
68
|
+
ShouldNot.new(@object, @message).pass(args.first)
|
69
|
+
else
|
70
|
+
raise ArgumentError, "#not takes zero or one argument(s)."
|
71
|
+
end
|
57
72
|
end
|
58
73
|
|
74
|
+
def messaging(message)
|
75
|
+
@message = message.to_s
|
76
|
+
self
|
77
|
+
end
|
78
|
+
alias blaming messaging
|
59
79
|
|
60
80
|
def satisfy(&block)
|
61
|
-
assert_block("satisfy block failed.") {
|
81
|
+
assert_block(@message || "satisfy block failed.") {
|
62
82
|
yield @object
|
63
83
|
}
|
64
84
|
end
|
65
85
|
|
66
86
|
def equal(value)
|
67
|
-
assert_equal value, @object
|
87
|
+
assert_equal value, @object, @message
|
68
88
|
end
|
69
89
|
alias == equal
|
70
90
|
|
71
91
|
def close(value, delta)
|
72
|
-
assert_in_delta value, @object, delta
|
92
|
+
assert_in_delta value, @object, delta, @message
|
73
93
|
end
|
74
|
-
|
94
|
+
deprecated_alias :be_close, :close
|
75
95
|
|
76
96
|
def be(*value)
|
77
97
|
case value.size
|
78
98
|
when 0
|
79
99
|
self
|
80
100
|
when 1
|
81
|
-
|
101
|
+
if CustomShould === value.first
|
102
|
+
pass value.first
|
103
|
+
else
|
104
|
+
assert_same value.first, @object, @message
|
105
|
+
end
|
82
106
|
else
|
83
107
|
raise ArgumentError, "should.be needs zero or one argument"
|
84
108
|
end
|
85
109
|
end
|
86
110
|
|
87
111
|
def match(value)
|
88
|
-
assert_match value, @object
|
112
|
+
assert_match value, @object, @message
|
89
113
|
end
|
90
114
|
alias =~ match
|
91
115
|
|
92
116
|
def instance_of(klass)
|
93
|
-
assert_instance_of klass, @object
|
117
|
+
assert_instance_of klass, @object, @message
|
94
118
|
end
|
95
|
-
|
119
|
+
deprecated_alias :be_an_instance_of, :instance_of
|
96
120
|
|
97
121
|
def kind_of(klass)
|
98
|
-
assert_kind_of klass, @object
|
122
|
+
assert_kind_of klass, @object, @message
|
99
123
|
end
|
100
|
-
|
124
|
+
deprecated_alias :be_a_kind_of, :kind_of
|
101
125
|
|
102
126
|
def respond_to(method)
|
103
|
-
assert_respond_to @object, method
|
127
|
+
assert_respond_to @object, method, @message
|
104
128
|
end
|
105
129
|
|
106
130
|
def _raise(*args)
|
107
131
|
args = [RuntimeError] if args.empty?
|
108
|
-
assert_raise(*args, &@object)
|
132
|
+
assert_raise(*(args + [@message]), &@object)
|
109
133
|
end
|
110
134
|
|
111
135
|
def throw(*args)
|
112
|
-
assert_throws(*args, &@object)
|
136
|
+
assert_throws(*(args + [@message]), &@object)
|
113
137
|
end
|
114
138
|
|
115
139
|
def nil
|
116
|
-
assert_nil @object
|
140
|
+
assert_nil @object, @message
|
117
141
|
end
|
118
|
-
|
142
|
+
deprecated_alias :be_nil, :nil
|
119
143
|
|
120
144
|
|
121
145
|
def include(value)
|
122
|
-
msg = build_message(
|
146
|
+
msg = build_message(@message, "<?> expected to include ?, but it didn't.",
|
123
147
|
@object, value)
|
124
148
|
assert_block(msg) { @object.include?(value) }
|
125
149
|
end
|
126
150
|
|
127
151
|
def >(value)
|
128
|
-
assert_operator @object, :>, value
|
152
|
+
assert_operator @object, :>, value, @message
|
129
153
|
end
|
130
154
|
|
131
155
|
def >=(value)
|
132
|
-
assert_operator @object, :>=, value
|
156
|
+
assert_operator @object, :>=, value, @message
|
133
157
|
end
|
134
158
|
|
135
159
|
def <(value)
|
136
|
-
assert_operator @object, :<, value
|
160
|
+
assert_operator @object, :<, value, @message
|
137
161
|
end
|
138
162
|
|
139
163
|
def <=(value)
|
140
|
-
assert_operator @object, :<=, value
|
164
|
+
assert_operator @object, :<=, value, @message
|
141
165
|
end
|
142
166
|
|
143
167
|
def ===(value)
|
144
|
-
assert_operator @object, :===, value
|
168
|
+
assert_operator @object, :===, value, @message
|
169
|
+
end
|
170
|
+
|
171
|
+
def pass(custom)
|
172
|
+
_wrap_assertion {
|
173
|
+
assert_nothing_raised(Test::Unit::AssertionFailedError,
|
174
|
+
@message || custom.failure_message) {
|
175
|
+
assert custom.matches?(@object), @message || custom.failure_message
|
176
|
+
}
|
177
|
+
}
|
145
178
|
end
|
146
179
|
|
147
180
|
def method_missing(name, *args)
|
@@ -150,7 +183,7 @@ module Test::Spec
|
|
150
183
|
|
151
184
|
if @object.respond_to?("#{name}?")
|
152
185
|
assert @object.__send__("#{name}?", *args),
|
153
|
-
|
186
|
+
"#{name}? expected to be true. #{@message}"
|
154
187
|
else
|
155
188
|
super
|
156
189
|
end
|
@@ -160,12 +193,19 @@ module Test::Spec
|
|
160
193
|
class ShouldNot
|
161
194
|
include Test::Unit::Assertions
|
162
195
|
|
163
|
-
def initialize(object)
|
196
|
+
def initialize(object, message=nil)
|
164
197
|
@object = object
|
198
|
+
@message = message
|
199
|
+
end
|
200
|
+
|
201
|
+
def satisfy(&block)
|
202
|
+
assert_block(@message || "not.satisfy block succeded.") {
|
203
|
+
not yield @object
|
204
|
+
}
|
165
205
|
end
|
166
206
|
|
167
207
|
def equal(value)
|
168
|
-
assert_not_equal value, @object
|
208
|
+
assert_not_equal value, @object, @message
|
169
209
|
end
|
170
210
|
alias == equal
|
171
211
|
|
@@ -174,7 +214,11 @@ module Test::Spec
|
|
174
214
|
when 0
|
175
215
|
self
|
176
216
|
when 1
|
177
|
-
|
217
|
+
if CustomShould === value.first
|
218
|
+
pass value.first
|
219
|
+
else
|
220
|
+
assert_not_same value.first, @object, @message
|
221
|
+
end
|
178
222
|
else
|
179
223
|
Kernel.raise ArgumentError, "should.be needs zero or one argument"
|
180
224
|
end
|
@@ -182,42 +226,80 @@ module Test::Spec
|
|
182
226
|
|
183
227
|
def match(value)
|
184
228
|
# Icky Regexp check
|
185
|
-
assert_no_match value, @object
|
229
|
+
assert_no_match value, @object, @message
|
186
230
|
end
|
187
231
|
alias =~ match
|
188
232
|
|
189
233
|
def _raise(*args)
|
190
|
-
assert_nothing_raised(*args, &@object)
|
234
|
+
assert_nothing_raised(*(args+[@message]), &@object)
|
191
235
|
end
|
192
236
|
|
193
237
|
def throw
|
194
|
-
assert_nothing_thrown(&@object)
|
238
|
+
assert_nothing_thrown(@message, &@object)
|
195
239
|
end
|
196
240
|
|
197
241
|
def nil
|
198
|
-
assert_not_nil @object
|
242
|
+
assert_not_nil @object, @message
|
199
243
|
end
|
200
|
-
alias be_nil nil
|
201
244
|
|
245
|
+
def be_nil
|
246
|
+
warn "Test::Spec::ShouldNot#be_nil is deprecated and will be removed in future versions."
|
247
|
+
self.nil
|
248
|
+
end
|
202
249
|
|
203
|
-
def not
|
204
|
-
|
250
|
+
def not(*args)
|
251
|
+
case args.size
|
252
|
+
when 0
|
253
|
+
Should.new(@object, @message)
|
254
|
+
when 1
|
255
|
+
Should.new(@object, @message).pass(args.first)
|
256
|
+
else
|
257
|
+
raise ArgumentError, "#not takes zero or one argument(s)."
|
258
|
+
end
|
205
259
|
end
|
206
260
|
|
261
|
+
def pass(custom)
|
262
|
+
_wrap_assertion {
|
263
|
+
begin
|
264
|
+
assert !custom.matches?(@object), @message || custom.failure_message
|
265
|
+
end
|
266
|
+
}
|
267
|
+
end
|
207
268
|
|
208
269
|
def method_missing(name, *args)
|
209
270
|
# This will make raise call Kernel.raise, and self.raise call _raise.
|
210
271
|
return _raise(*args) if name == :raise
|
211
272
|
|
212
273
|
if @object.respond_to?("#{name}?")
|
213
|
-
assert_block("#{name}? expected to be false.") {
|
274
|
+
assert_block("#{name}? expected to be false. #{@message}") {
|
214
275
|
not @object.__send__("#{name}?", *args)
|
215
276
|
}
|
216
277
|
else
|
217
278
|
super
|
218
279
|
end
|
219
280
|
end
|
281
|
+
|
282
|
+
end
|
220
283
|
|
284
|
+
class CustomShould
|
285
|
+
attr_accessor :object
|
286
|
+
|
287
|
+
def initialize(obj)
|
288
|
+
self.object = obj
|
289
|
+
end
|
290
|
+
|
291
|
+
def failure_message
|
292
|
+
"#{self.class.name} failed"
|
293
|
+
end
|
294
|
+
|
295
|
+
def matches?(*args, &block)
|
296
|
+
assumptions(*args, &block)
|
297
|
+
true
|
298
|
+
end
|
299
|
+
|
300
|
+
def assumptions(*args, &block)
|
301
|
+
raise NotImplementedError, "you need to supply a #{self.class}#matches? method"
|
302
|
+
end
|
221
303
|
end
|
222
304
|
end
|
223
305
|
|
@@ -275,10 +357,16 @@ class Test::Spec::TestCase
|
|
275
357
|
|
276
358
|
self.count += 1 # Let them run in order of definition
|
277
359
|
|
278
|
-
# TODO Changed by Jean-Michel
|
279
|
-
# define_method("test_%03d: %s" % [count, specname], &block)
|
280
360
|
define_method("test_spec {%s} %03d [%s]" % [name, count, specname], &block)
|
281
361
|
end
|
362
|
+
|
363
|
+
def xspecify(specname, &block)
|
364
|
+
raise ArgumentError, "xspecify needs a block" if block.nil?
|
365
|
+
|
366
|
+
specify specname do
|
367
|
+
@_result.add_disabled(specname)
|
368
|
+
end
|
369
|
+
end
|
282
370
|
|
283
371
|
def setup(&block)
|
284
372
|
setups << block
|
@@ -324,6 +412,24 @@ class Test::Spec::TestCase
|
|
324
412
|
end
|
325
413
|
end
|
326
414
|
|
415
|
+
class Test::Spec::Disabled < Test::Unit::Failure # :nodoc:
|
416
|
+
def initialize(name)
|
417
|
+
@name = name
|
418
|
+
end
|
419
|
+
|
420
|
+
def single_character_display
|
421
|
+
"D"
|
422
|
+
end
|
423
|
+
|
424
|
+
def short_display
|
425
|
+
@name
|
426
|
+
end
|
427
|
+
|
428
|
+
def long_display
|
429
|
+
@name + " is disabled"
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
327
433
|
|
328
434
|
# Monkey-patch test/unit to run tests in an optionally specified order.
|
329
435
|
module Test::Unit # :nodoc:
|
@@ -348,19 +454,35 @@ module Test::Unit # :nodoc:
|
|
348
454
|
@tests.first.respond_to?(:position) ? @tests.first.position : 0
|
349
455
|
end
|
350
456
|
end
|
457
|
+
|
458
|
+
class TestResult # :nodoc:
|
459
|
+
# Records a disabled test.
|
460
|
+
def add_disabled(name)
|
461
|
+
notify_listeners(FAULT, Test::Spec::Disabled.new(name))
|
462
|
+
notify_listeners(CHANGED, self)
|
463
|
+
end
|
464
|
+
end
|
351
465
|
end
|
352
466
|
|
353
467
|
|
354
|
-
|
468
|
+
|
469
|
+
#-- Global helpers
|
355
470
|
|
356
471
|
class Object
|
357
|
-
def should
|
358
|
-
|
472
|
+
def should(*args)
|
473
|
+
case args.size
|
474
|
+
when 0
|
475
|
+
Test::Spec::Should.new(self)
|
476
|
+
when 1
|
477
|
+
Test::Spec::Should.new(self).pass(args.first)
|
478
|
+
else
|
479
|
+
raise ArgumentError, "Object#should takes zero or one argument(s)."
|
480
|
+
end
|
359
481
|
end
|
360
482
|
end
|
361
483
|
|
362
484
|
module Kernel
|
363
|
-
def context(name, &block)
|
485
|
+
def context(name, &block) # :doc:
|
364
486
|
(Test::Spec::CONTEXTS[name] ||= Test::Spec::TestCase.new(name)).add(&block)
|
365
487
|
end
|
366
488
|
|