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.
@@ -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.1"
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 initialize(object)
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
- ShouldNot.new(@object)
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
- alias be_close close
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
- assert_same value.first, @object
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
- alias be_an_instance_of instance_of
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
- alias be_a_kind_of kind_of
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
- alias be_nil nil
142
+ deprecated_alias :be_nil, :nil
119
143
 
120
144
 
121
145
  def include(value)
122
- msg = build_message(nil, "<?> expected to include ?, but it didn't.",
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
- "#{name}? expected to be true."
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
- assert_not_same value.first, @object
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
- Should.new(@object)
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
- # Global helpers
468
+
469
+ #-- Global helpers
355
470
 
356
471
  class Object
357
- def should
358
- Test::Spec::Should.new(self)
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