jordi-xml_struct 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,148 @@
1
+ require 'test/unit/ui/console/testrunner'
2
+
3
+ module Test::Unit::UI # :nodoc:
4
+ module SpecDox # :nodoc:
5
+ class TestRunner < Test::Unit::UI::Console::TestRunner
6
+ protected
7
+ def setup_mediator
8
+ @mediator = create_mediator(@suite)
9
+ end
10
+
11
+ def add_fault(fault)
12
+ if fault.kind_of? Test::Spec::Disabled
13
+ @disabled += 1
14
+ output_no_nl " (disabled)"
15
+ elsif fault.kind_of? Test::Spec::Empty
16
+ @empty += 1
17
+ output_no_nl " (empty)"
18
+ else
19
+ @faults << fault
20
+ word = fault.class.name[/(.*::)?(.*)/, 2].upcase
21
+ output_no_nl " (#{word} - #{@faults.size})"
22
+ end
23
+ end
24
+
25
+ def started(result)
26
+ @result = result
27
+ @context = nil
28
+ @contexts = []
29
+ @disabled = 0
30
+ @empty = 0
31
+ indent 0
32
+ end
33
+
34
+ def finished(elapsed_time)
35
+ nl
36
+ output "Finished in #{elapsed_time} seconds."
37
+ @faults.each_with_index do |fault, index|
38
+ nl
39
+ output("%3d) %s" % [index + 1, fault.long_display])
40
+ end
41
+ nl
42
+ output_result
43
+ end
44
+
45
+ def output_result
46
+ if @disabled > 0
47
+ disabled = ", #{@disabled} disabled"
48
+ else
49
+ disabled = ""
50
+ end
51
+
52
+ if @empty > 0
53
+ empty = ", #{@empty} empty"
54
+ else
55
+ empty = ""
56
+ end
57
+
58
+ r = ("%d specifications#{disabled}#{empty} " +
59
+ "(%d requirements), %d failures") % [
60
+ @result.run_count, @result.assertion_count, @result.failure_count]
61
+ r << ", #{@result.error_count} errors" if @result.error_count > 0
62
+ output r
63
+ end
64
+
65
+ def test_started(name)
66
+ return if special_test? name
67
+
68
+ contextname, @specname = unmangle name
69
+ return if contextname.nil? || @specname.nil?
70
+
71
+ if @context != contextname
72
+ @context = contextname
73
+
74
+ @old_contexts = @contexts
75
+ @contexts = @context.split("\t")
76
+
77
+ common = 0
78
+ @contexts.zip(@old_contexts) { |a, b|
79
+ break if a != b
80
+ common += 1
81
+ }
82
+
83
+ nl if common == 0
84
+
85
+ @contexts[common..-1].each_with_index { |head, i|
86
+ indent common + i
87
+ output_heading head
88
+ }
89
+ end
90
+
91
+ @assertions = @result.assertion_count
92
+ @prevdisabled = @disabled
93
+ output_item @specname
94
+ end
95
+
96
+ def test_finished(name)
97
+ return if special_test? name
98
+
99
+ # Did any assertion run?
100
+ if @assertions == @result.assertion_count && @prevdisabled == @disabled
101
+ add_fault Test::Spec::Empty.new(@specname)
102
+ end
103
+
104
+ # Don't let empty contexts clutter up the output.
105
+ nl unless name =~ /\Adefault_test\(/
106
+ end
107
+
108
+ def output_no_nl(something, level=NORMAL)
109
+ @io.write(something) if (output?(level))
110
+ @io.flush
111
+ end
112
+
113
+ def output_item(item)
114
+ output_no_nl "#{@prefix}- #{item}"
115
+ end
116
+
117
+ def output_heading(heading)
118
+ output "#{@prefix}#{heading}"
119
+ end
120
+
121
+ def unmangle(name)
122
+ if name =~ /\Atest_spec \{(.*?)\} \d+ \[(.*)\]/
123
+ contextname = $1
124
+ specname = $2
125
+ elsif name =~ /test_(.*?)\((.*)\)$/
126
+ specname = $1
127
+ contextname = $2
128
+
129
+ contextname.gsub!(/^Test\B|\BTest$/, '')
130
+ specname.gsub!(/_/, ' ')
131
+ else
132
+ contextname = specname = nil
133
+ end
134
+
135
+ [contextname, specname]
136
+ end
137
+
138
+ def indent(depth)
139
+ @indent = depth
140
+ @prefix = " " * depth
141
+ end
142
+
143
+ def special_test?(name)
144
+ name =~ /\Atest_spec \{.*?\} (-1 BEFORE|AFTER) ALL\(/
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,25 @@
1
+ require 'test/spec/dox'
2
+
3
+ module Test::Unit::UI # :nodoc:
4
+ module RDox # :nodoc:
5
+ class TestRunner < Test::Unit::UI::SpecDox::TestRunner
6
+ def output_heading(heading)
7
+ output "#{@headprefix} #{heading}"
8
+ end
9
+
10
+ def output_item(item)
11
+ output_no_nl "* #{item}"
12
+ end
13
+
14
+ def finished(elapsed_time)
15
+ nl
16
+ output_result
17
+ end
18
+
19
+ def indent(depth)
20
+ @prefix = ""
21
+ @headprefix = "==" + "=" * depth
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ # Code adapted from rs, written by Eero Saynatkari.
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ class Test::Spec::Should
6
+ # Captures output from the IO given as
7
+ # the second argument (STDIN by default)
8
+ # and matches it against a String or
9
+ # Regexp given as the first argument.
10
+ def output(expected, to = STDOUT)
11
+ # Store the old stream
12
+ old_to = to.dup
13
+
14
+ # Obtain a filehandle to replace (works with Readline)
15
+ to.reopen File.open(File.join(Dir.tmpdir, "should_output_#{$$}"), "w+")
16
+
17
+ # Execute
18
+ @object.call
19
+
20
+ # Restore
21
+ out = to.dup
22
+ to.reopen old_to
23
+
24
+ # Grab the data
25
+ out.rewind
26
+ output = out.read
27
+
28
+ # Match up
29
+ case expected
30
+ when Regexp
31
+ output.should.match expected
32
+ else
33
+ output.should.equal expected
34
+ end # case expected
35
+
36
+ # Clean up
37
+ ensure
38
+ out.close
39
+
40
+ # STDIO redirection will break else
41
+ begin
42
+ to.seek 0, IO::SEEK_END
43
+ rescue Errno::ESPIPE
44
+ rescue Errno::EPIPE
45
+ end
46
+
47
+ FileUtils.rm_f out.path
48
+ end # output
49
+ end # Test::Spec::Should
@@ -0,0 +1,8 @@
1
+ # To load it externally, without activating Test::Unit.
2
+
3
+ module Test
4
+ module Spec
5
+ VERSION = "0.9"
6
+ end
7
+ end
8
+
@@ -0,0 +1,660 @@
1
+ #
2
+ # test/spec -- a BDD interface for Test::Unit
3
+ #
4
+ # Copyright (C) 2006, 2007, 2008 Christian Neukirchen <mailto:chneukirchen@gmail.com>
5
+ #
6
+ # This work is licensed under the same terms as Ruby itself.
7
+ #
8
+
9
+ require 'test/unit'
10
+
11
+ class Test::Unit::AutoRunner # :nodoc:
12
+ RUNNERS[:specdox] = lambda {
13
+ require 'test/spec/dox'
14
+ Test::Unit::UI::SpecDox::TestRunner
15
+ }
16
+
17
+ RUNNERS[:rdox] = lambda {
18
+ require 'test/spec/rdox'
19
+ Test::Unit::UI::RDox::TestRunner
20
+ }
21
+ end
22
+
23
+ module Test # :nodoc:
24
+ end
25
+
26
+ module Test::Spec
27
+ require 'test/spec/version'
28
+
29
+ CONTEXTS = {} # :nodoc:
30
+ SHARED_CONTEXTS = Hash.new { |h,k| h[k] = [] } # :nodoc:
31
+
32
+ class DefinitionError < StandardError
33
+ end
34
+
35
+ class Should
36
+ include Test::Unit::Assertions
37
+
38
+ def self.deprecated_alias(to, from) # :nodoc:
39
+ define_method(to) { |*args|
40
+ warn "Test::Spec::Should##{to} is deprecated and will be removed in future versions."
41
+ __send__ from, *args
42
+ }
43
+ end
44
+
45
+ def initialize(object, message=nil)
46
+ @object = object
47
+ @message = message
48
+ end
49
+
50
+ $TEST_SPEC_TESTCASE = nil
51
+ def add_assertion
52
+ $TEST_SPEC_TESTCASE && $TEST_SPEC_TESTCASE.__send__(:add_assertion)
53
+ end
54
+
55
+
56
+ def an
57
+ self
58
+ end
59
+
60
+ def a
61
+ self
62
+ end
63
+
64
+ def not(*args)
65
+ case args.size
66
+ when 0
67
+ ShouldNot.new(@object, @message)
68
+ when 1
69
+ ShouldNot.new(@object, @message).pass(args.first)
70
+ else
71
+ raise ArgumentError, "#not takes zero or one argument(s)."
72
+ end
73
+ end
74
+
75
+ def messaging(message)
76
+ @message = message.to_s
77
+ self
78
+ end
79
+ alias blaming messaging
80
+
81
+ def satisfy(&block)
82
+ assert_block(@message || "satisfy block failed.") {
83
+ yield @object
84
+ }
85
+ end
86
+
87
+ def equal(value)
88
+ assert_equal value, @object, @message
89
+ end
90
+ alias == equal
91
+
92
+ def close(value, delta)
93
+ assert_in_delta value, @object, delta, @message
94
+ end
95
+ deprecated_alias :be_close, :close
96
+
97
+ def be(*value)
98
+ case value.size
99
+ when 0
100
+ self
101
+ when 1
102
+ if CustomShould === value.first
103
+ pass value.first
104
+ else
105
+ assert_same value.first, @object, @message
106
+ end
107
+ else
108
+ raise ArgumentError, "should.be needs zero or one argument"
109
+ end
110
+ end
111
+
112
+ def match(value)
113
+ assert_match value, @object, @message
114
+ end
115
+ alias =~ match
116
+
117
+ def instance_of(klass)
118
+ assert_instance_of klass, @object, @message
119
+ end
120
+ deprecated_alias :be_an_instance_of, :instance_of
121
+
122
+ def kind_of(klass)
123
+ assert_kind_of klass, @object, @message
124
+ end
125
+ deprecated_alias :be_a_kind_of, :kind_of
126
+
127
+ def respond_to(method)
128
+ assert_respond_to @object, method, @message
129
+ end
130
+
131
+ def _raise(*args, &block)
132
+ args = [RuntimeError] if args.empty?
133
+ block ||= @object
134
+ assert_raise(*(args + [@message]), &block)
135
+ end
136
+
137
+ def throw(*args)
138
+ assert_throws(*(args + [@message]), &@object)
139
+ end
140
+
141
+ def nil
142
+ assert_nil @object, @message
143
+ end
144
+ deprecated_alias :be_nil, :nil
145
+
146
+
147
+ def include(value)
148
+ msg = build_message(@message, "<?> expected to include ?, but it didn't.",
149
+ @object, value)
150
+ assert_block(msg) { @object.include?(value) }
151
+ end
152
+
153
+ def >(value)
154
+ assert_operator @object, :>, value, @message
155
+ end
156
+
157
+ def >=(value)
158
+ assert_operator @object, :>=, value, @message
159
+ end
160
+
161
+ def <(value)
162
+ assert_operator @object, :<, value, @message
163
+ end
164
+
165
+ def <=(value)
166
+ assert_operator @object, :<=, value, @message
167
+ end
168
+
169
+ def ===(value)
170
+ assert_operator @object, :===, value, @message
171
+ end
172
+
173
+ def pass(custom)
174
+ _wrap_assertion {
175
+ assert_nothing_raised(Test::Unit::AssertionFailedError,
176
+ @message || custom.failure_message) {
177
+ assert custom.matches?(@object), @message || custom.failure_message
178
+ }
179
+ }
180
+ end
181
+
182
+ def method_missing(name, *args, &block)
183
+ # This will make raise call Kernel.raise, and self.raise call _raise.
184
+ return _raise(*args, &block) if name == :raise
185
+
186
+ if @object.respond_to?("#{name}?")
187
+ assert @object.__send__("#{name}?", *args),
188
+ "#{name}? expected to be true. #{@message}"
189
+ else
190
+ if @object.respond_to?(name)
191
+ assert @object.__send__(name, *args),
192
+ "#{name} expected to be true. #{@message}"
193
+ else
194
+ super
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ class ShouldNot
201
+ include Test::Unit::Assertions
202
+
203
+ def initialize(object, message=nil)
204
+ @object = object
205
+ @message = message
206
+ end
207
+
208
+ def add_assertion
209
+ $TEST_SPEC_TESTCASE && $TEST_SPEC_TESTCASE.__send__(:add_assertion)
210
+ end
211
+
212
+
213
+ def satisfy(&block)
214
+ assert_block(@message || "not.satisfy block succeded.") {
215
+ not yield @object
216
+ }
217
+ end
218
+
219
+ def equal(value)
220
+ assert_not_equal value, @object, @message
221
+ end
222
+ alias == equal
223
+
224
+ def be(*value)
225
+ case value.size
226
+ when 0
227
+ self
228
+ when 1
229
+ if CustomShould === value.first
230
+ pass value.first
231
+ else
232
+ assert_not_same value.first, @object, @message
233
+ end
234
+ else
235
+ Kernel.raise ArgumentError, "should.be needs zero or one argument"
236
+ end
237
+ end
238
+
239
+ def match(value)
240
+ # Icky Regexp check
241
+ assert_no_match value, @object, @message
242
+ end
243
+ alias =~ match
244
+
245
+ def _raise(*args, &block)
246
+ block ||= @object
247
+ assert_nothing_raised(*(args+[@message]), &block)
248
+ end
249
+
250
+ def throw
251
+ assert_nothing_thrown(@message, &@object)
252
+ end
253
+
254
+ def nil
255
+ assert_not_nil @object, @message
256
+ end
257
+
258
+ def be_nil
259
+ warn "Test::Spec::ShouldNot#be_nil is deprecated and will be removed in future versions."
260
+ self.nil
261
+ end
262
+
263
+ def not(*args)
264
+ case args.size
265
+ when 0
266
+ Should.new(@object, @message)
267
+ when 1
268
+ Should.new(@object, @message).pass(args.first)
269
+ else
270
+ raise ArgumentError, "#not takes zero or one argument(s)."
271
+ end
272
+ end
273
+
274
+ def pass(custom)
275
+ _wrap_assertion {
276
+ begin
277
+ assert !custom.matches?(@object), @message || custom.failure_message
278
+ end
279
+ }
280
+ end
281
+
282
+ def method_missing(name, *args, &block)
283
+ # This will make raise call Kernel.raise, and self.raise call _raise.
284
+ return _raise(*args, &block) if name == :raise
285
+
286
+ if @object.respond_to?("#{name}?")
287
+ assert_block("#{name}? expected to be false. #{@message}") {
288
+ not @object.__send__("#{name}?", *args)
289
+ }
290
+ else
291
+ if @object.respond_to?(name)
292
+ assert_block("#{name} expected to be false. #{@message}") {
293
+ not @object.__send__("#{name}", *args)
294
+ }
295
+ else
296
+ super
297
+ end
298
+ end
299
+ end
300
+
301
+ end
302
+
303
+ class CustomShould
304
+ attr_accessor :object
305
+
306
+ def initialize(obj)
307
+ self.object = obj
308
+ end
309
+
310
+ def failure_message
311
+ "#{self.class.name} failed"
312
+ end
313
+
314
+ def matches?(*args, &block)
315
+ assumptions(*args, &block)
316
+ true
317
+ end
318
+
319
+ def assumptions(*args, &block)
320
+ raise NotImplementedError, "you need to supply a #{self.class}#matches? method"
321
+ end
322
+ end
323
+ end
324
+
325
+ class Test::Spec::TestCase
326
+ attr_reader :testcase
327
+ attr_reader :name
328
+ attr_reader :position
329
+
330
+ module InstanceMethods
331
+ def setup # :nodoc:
332
+ $TEST_SPEC_TESTCASE = self
333
+ super
334
+ call_methods_including_parents(:setups)
335
+ end
336
+
337
+ def teardown # :nodoc:
338
+ super
339
+ call_methods_including_parents(:teardowns, :reverse)
340
+ end
341
+
342
+ def before_all
343
+ call_methods_including_parents(:before_all)
344
+ end
345
+
346
+ def after_all
347
+ call_methods_including_parents(:after_all, :reverse)
348
+ end
349
+
350
+ def initialize(name)
351
+ super name
352
+
353
+ # Don't let the default_test clutter up the results and don't
354
+ # flunk if no tests given, either.
355
+ throw :invalid_test if name.to_s == "default_test"
356
+ end
357
+
358
+ def position
359
+ self.class.position
360
+ end
361
+
362
+ def context(*args)
363
+ raise Test::Spec::DefinitionError,
364
+ "context definition is not allowed inside a specify-block"
365
+ end
366
+
367
+ alias :describe :context
368
+
369
+ private
370
+
371
+ def call_methods_including_parents(method, reverse=false, klass=self.class)
372
+ return unless klass
373
+
374
+ if reverse
375
+ klass.send(method).each { |s| instance_eval(&s) }
376
+ call_methods_including_parents(method, reverse, klass.parent)
377
+ else
378
+ call_methods_including_parents(method, reverse, klass.parent)
379
+ klass.send(method).each { |s| instance_eval(&s) }
380
+ end
381
+ end
382
+ end
383
+
384
+ module ClassMethods
385
+ attr_accessor :count
386
+ attr_accessor :name
387
+ attr_accessor :position
388
+ attr_accessor :parent
389
+
390
+ attr_accessor :setups
391
+ attr_accessor :teardowns
392
+
393
+ attr_accessor :before_all
394
+ attr_accessor :after_all
395
+
396
+ # old-style (RSpec <1.0):
397
+
398
+ def context(name, superclass=Test::Unit::TestCase, klass=Test::Spec::TestCase, &block)
399
+ (Test::Spec::CONTEXTS[self.name + "\t" + name] ||= klass.new(name, self, superclass)).add(&block)
400
+ end
401
+
402
+ def xcontext(name, superclass=Test::Unit::TestCase, &block)
403
+ context(name, superclass, Test::Spec::DisabledTestCase, &block)
404
+ end
405
+
406
+ def specify(specname, &block)
407
+ raise ArgumentError, "specify needs a block" if block.nil?
408
+
409
+ self.count += 1 # Let them run in order of definition
410
+
411
+ define_method("test_spec {%s} %03d [%s]" % [name, count, specname], &block)
412
+ end
413
+
414
+ def xspecify(specname, &block)
415
+ specify specname do
416
+ @_result.add_disabled(specname)
417
+ end
418
+ end
419
+
420
+ def setup(&block)
421
+ setups << block
422
+ end
423
+
424
+ def teardown(&block)
425
+ teardowns << block
426
+ end
427
+
428
+ def shared_context(name, &block)
429
+ Test::Spec::SHARED_CONTEXTS[self.name + "\t" + name] << block
430
+ end
431
+
432
+ def behaves_like(shared_context)
433
+ if Test::Spec::SHARED_CONTEXTS.include?(shared_context)
434
+ Test::Spec::SHARED_CONTEXTS[shared_context].each { |block|
435
+ instance_eval(&block)
436
+ }
437
+ elsif Test::Spec::SHARED_CONTEXTS.include?(self.name + "\t" + shared_context)
438
+ Test::Spec::SHARED_CONTEXTS[self.name + "\t" + shared_context].each { |block|
439
+ instance_eval(&block)
440
+ }
441
+ else
442
+ raise NameError, "Shared context #{shared_context} not found."
443
+ end
444
+ end
445
+ alias :it_should_behave_like :behaves_like
446
+
447
+ # new-style (RSpec 1.0+):
448
+
449
+ alias :describe :context
450
+ alias :describe_shared :shared_context
451
+ alias :it :specify
452
+ alias :xit :xspecify
453
+
454
+ def before(kind=:each, &block)
455
+ case kind
456
+ when :each
457
+ setup(&block)
458
+ when :all
459
+ before_all << block
460
+ else
461
+ raise ArgumentError, "invalid argument: before(#{kind.inspect})"
462
+ end
463
+ end
464
+
465
+ def after(kind=:each, &block)
466
+ case kind
467
+ when :each
468
+ teardown(&block)
469
+ when :all
470
+ after_all << block
471
+ else
472
+ raise ArgumentError, "invalid argument: after(#{kind.inspect})"
473
+ end
474
+ end
475
+
476
+
477
+ def init(name, position, parent)
478
+ self.position = position
479
+ self.parent = parent
480
+
481
+ if parent
482
+ self.name = parent.name + "\t" + name
483
+ else
484
+ self.name = name
485
+ end
486
+
487
+ self.count = 0
488
+ self.setups = []
489
+ self.teardowns = []
490
+
491
+ self.before_all = []
492
+ self.after_all = []
493
+ end
494
+ end
495
+
496
+ @@POSITION = 0
497
+
498
+ def initialize(name, parent=nil, superclass=Test::Unit::TestCase)
499
+ @testcase = Class.new(superclass) {
500
+ include InstanceMethods
501
+ extend ClassMethods
502
+ }
503
+
504
+ @@POSITION = @@POSITION + 1
505
+ @testcase.init(name, @@POSITION, parent)
506
+ end
507
+
508
+ def add(&block)
509
+ raise ArgumentError, "context needs a block" if block.nil?
510
+
511
+ @testcase.class_eval(&block)
512
+ self
513
+ end
514
+ end
515
+
516
+ (Test::Spec::DisabledTestCase = Test::Spec::TestCase.dup).class_eval do
517
+ alias :test_case_initialize :initialize
518
+
519
+ def initialize(*args, &block)
520
+ test_case_initialize(*args, &block)
521
+ @testcase.instance_eval do
522
+ alias :test_case_specify :specify
523
+
524
+ def specify(specname, &block)
525
+ test_case_specify(specname) { @_result.add_disabled(specname) }
526
+ end
527
+ alias :it :specify
528
+ end
529
+ end
530
+ end
531
+
532
+ class Test::Spec::Disabled < Test::Unit::Failure # :nodoc:
533
+ def initialize(name)
534
+ @name = name
535
+ end
536
+
537
+ def single_character_display
538
+ "D"
539
+ end
540
+
541
+ def short_display
542
+ @name
543
+ end
544
+
545
+ def long_display
546
+ @name + " is disabled"
547
+ end
548
+ end
549
+
550
+ class Test::Spec::Empty < Test::Unit::Failure # :nodoc:
551
+ def initialize(name)
552
+ @name = name
553
+ end
554
+
555
+ def single_character_display
556
+ ""
557
+ end
558
+
559
+ def short_display
560
+ @name
561
+ end
562
+
563
+ def long_display
564
+ @name + " is empty"
565
+ end
566
+ end
567
+
568
+
569
+ # Monkey-patch test/unit to run tests in an optionally specified order.
570
+ module Test::Unit # :nodoc:
571
+ class TestSuite # :nodoc:
572
+ undef run
573
+ def run(result, &progress_block)
574
+ sort!
575
+ yield(STARTED, name)
576
+ @tests.first.before_all if @tests.first.respond_to? :before_all
577
+ @tests.each do |test|
578
+ test.run(result, &progress_block)
579
+ end
580
+ @tests.last.after_all if @tests.last.respond_to? :after_all
581
+ yield(FINISHED, name)
582
+ end
583
+
584
+ def sort!
585
+ @tests = @tests.sort_by { |test|
586
+ test.respond_to?(:position) ? test.position : 0
587
+ }
588
+ end
589
+
590
+ def position
591
+ @tests.first.respond_to?(:position) ? @tests.first.position : 0
592
+ end
593
+ end
594
+
595
+ class TestResult # :nodoc:
596
+ # Records a disabled test.
597
+ def add_disabled(name)
598
+ notify_listeners(FAULT, Test::Spec::Disabled.new(name))
599
+ notify_listeners(CHANGED, self)
600
+ end
601
+ end
602
+ end
603
+
604
+
605
+ # Hide Test::Spec interna in backtraces.
606
+ module Test::Unit::Util::BacktraceFilter # :nodoc:
607
+ TESTSPEC_PREFIX = __FILE__.gsub(/spec\.rb\Z/, '')
608
+
609
+ # Vendor plugins like to be loaded several times, don't recurse
610
+ # infinitely then.
611
+ unless method_defined? "testspec_filter_backtrace"
612
+ alias :testspec_filter_backtrace :filter_backtrace
613
+ end
614
+
615
+ def filter_backtrace(backtrace, prefix=nil)
616
+ if prefix.nil?
617
+ testspec_filter_backtrace(testspec_filter_backtrace(backtrace),
618
+ TESTSPEC_PREFIX)
619
+ else
620
+ testspec_filter_backtrace(backtrace, prefix)
621
+ end
622
+ end
623
+ end
624
+
625
+
626
+ #-- Global helpers
627
+
628
+ class Object
629
+ def should(*args)
630
+ case args.size
631
+ when 0
632
+ Test::Spec::Should.new(self)
633
+ when 1
634
+ Test::Spec::Should.new(self).pass(args.first)
635
+ else
636
+ raise ArgumentError, "Object#should takes zero or one argument(s)."
637
+ end
638
+ end
639
+ end
640
+
641
+ module Kernel
642
+ def context(name, superclass=Test::Unit::TestCase, klass=Test::Spec::TestCase, &block) # :doc:
643
+ (Test::Spec::CONTEXTS[name] ||= klass.new(name, nil, superclass)).add(&block)
644
+ end
645
+
646
+ def xcontext(name, superclass=Test::Unit::TestCase, &block) # :doc:
647
+ context(name, superclass, Test::Spec::DisabledTestCase, &block)
648
+ end
649
+
650
+ def shared_context(name, &block)
651
+ Test::Spec::SHARED_CONTEXTS[name] << block
652
+ end
653
+
654
+ alias :describe :context
655
+ alias :xdescribe :xcontext
656
+ alias :describe_shared :shared_context
657
+
658
+ private :context, :xcontext, :shared_context
659
+ private :describe, :xdescribe, :describe_shared
660
+ end