baretest 0.1.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +52 -0
- data/MANIFEST.txt +50 -31
- data/README.rdoc +260 -0
- data/bin/baretest +82 -24
- data/doc/baretest.rdoc +98 -0
- data/doc/mocking_stubbing_test_doubles.rdoc +5 -0
- data/doc/quickref.rdoc +261 -0
- data/doc/writing_tests.rdoc +148 -0
- data/examples/test.rake +58 -30
- data/examples/tests/irb_mode/failures.rb +26 -0
- data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
- data/examples/tests/mock_developer/test/setup.rb +57 -0
- data/examples/tests/mock_developer/test/suite/mock_demo.rb +19 -0
- data/examples/tests/overview/test.rb +89 -0
- data/examples/tests/variations/variations_01.rb +14 -0
- data/examples/tests/variations/variations_02.rb +19 -0
- data/examples/tests/variations/variations_03.rb +19 -0
- data/lib/baretest/assertion/context.rb +20 -0
- data/lib/baretest/assertion/failure.rb +22 -0
- data/lib/baretest/assertion/skip.rb +21 -0
- data/lib/{test → baretest}/assertion/support.rb +174 -39
- data/lib/baretest/assertion.rb +182 -0
- data/lib/baretest/irb_mode.rb +263 -0
- data/lib/{test/assertion/failure.rb → baretest/layout.rb} +6 -5
- data/lib/baretest/mocha.rb +18 -0
- data/lib/baretest/run/cli.rb +104 -0
- data/lib/{test → baretest}/run/errors.rb +12 -7
- data/lib/{test → baretest}/run/minimal.rb +8 -3
- data/lib/baretest/run/profile.rb +151 -0
- data/lib/{test → baretest}/run/spec.rb +10 -4
- data/lib/baretest/run/tap.rb +44 -0
- data/lib/baretest/run/xml.rb +80 -0
- data/lib/{test → baretest}/run.rb +31 -18
- data/lib/baretest/setup.rb +15 -0
- data/lib/baretest/skipped/assertion.rb +20 -0
- data/lib/baretest/skipped/suite.rb +49 -0
- data/lib/baretest/skipped.rb +15 -0
- data/lib/baretest/suite.rb +234 -0
- data/lib/baretest/utilities.rb +43 -0
- data/lib/{test → baretest}/version.rb +12 -3
- data/lib/baretest.rb +112 -0
- data/test/external/bootstraptest.rb +1 -1
- data/test/setup.rb +1 -1
- data/test/{lib/test → suite/lib/baretest}/assertion/support.rb +78 -24
- data/test/suite/lib/baretest/assertion.rb +192 -0
- data/test/{lib/test → suite/lib/baretest}/irb_mode.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/cli.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/errors.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/interactive.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/spec.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/tap.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/xml.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run.rb +63 -61
- data/test/{lib/test → suite/lib/baretest}/suite.rb +77 -54
- data/test/{lib/test.rb → suite/lib/baretest.rb} +37 -37
- metadata +61 -40
- data/README.markdown +0 -229
- data/examples/test.rb +0 -93
- data/lib/test/assertion.rb +0 -117
- data/lib/test/debug.rb +0 -34
- data/lib/test/irb_mode.rb +0 -104
- data/lib/test/run/cli.rb +0 -79
- data/lib/test/run/interactive.rb +0 -60
- data/lib/test/run/tap.rb +0 -32
- data/lib/test/run/xml.rb +0 -56
- data/lib/test/suite.rb +0 -95
- data/lib/test.rb +0 -118
- data/test/lib/test/assertion.rb +0 -142
- data/test/lib/test/debug.rb +0 -63
data/lib/test/assertion.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'test/assertion/failure'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
module Test
|
14
|
-
|
15
|
-
# Defines an assertion
|
16
|
-
# An assertion belongs to a suite and consists of a description and a block.
|
17
|
-
# The verify the assertion, the suite's (and its ancestors) setup blocks are
|
18
|
-
# executed, then the assertions block is executed and after that, the suite's
|
19
|
-
# (and ancestors) teardown blocks are invoked.
|
20
|
-
#
|
21
|
-
# An assertion has 5 possible states, see Assertion#status for a list of them.
|
22
|
-
#
|
23
|
-
# There are various helper methods in lib/test/support.rb which help you
|
24
|
-
# defining nicer diagnostics or just easier ways to test common scenarios.
|
25
|
-
# The following are test helpers:
|
26
|
-
# * Kernel#raises(exception_class=StandardError)
|
27
|
-
# * Kernel#within_delta(a, b, delta)
|
28
|
-
# * Kernel#equal_unordered(a,b)
|
29
|
-
# * Enumerable#equal_unordered(other)
|
30
|
-
class Assertion
|
31
|
-
|
32
|
-
# An assertion has 5 possible states:
|
33
|
-
# :success
|
34
|
-
# : The assertion passed. This means the block returned a trueish value.
|
35
|
-
# :failure
|
36
|
-
# : The assertion failed. This means the block returned a falsish value.
|
37
|
-
# Alternatively it raised a Test::Failure (NOT YET IMPLEMENTED).
|
38
|
-
# The latter has the advantage that it can provide nicer diagnostics.
|
39
|
-
# :pending
|
40
|
-
# : No block given to the assertion to be run
|
41
|
-
# :skipped
|
42
|
-
# : If one of the parent suites is missing a dependency, its assertions
|
43
|
-
# will be skipped
|
44
|
-
# :error
|
45
|
-
# : The assertion errored out. This means the block raised an exception
|
46
|
-
attr_reader :status
|
47
|
-
|
48
|
-
# If an exception occured in Assertion#execute, this will contain the
|
49
|
-
# Exception object raised.
|
50
|
-
attr_reader :exception
|
51
|
-
|
52
|
-
# The description of this assertion.
|
53
|
-
attr_reader :description
|
54
|
-
|
55
|
-
# The failure reason.
|
56
|
-
attr_reader :failure_reason
|
57
|
-
|
58
|
-
# The suite this assertion belongs to
|
59
|
-
attr_reader :suite
|
60
|
-
|
61
|
-
# The block specifying the assertion
|
62
|
-
attr_reader :block
|
63
|
-
|
64
|
-
# suite
|
65
|
-
# : The suite the Assertion belongs to
|
66
|
-
# description
|
67
|
-
# : A descriptive string about what this Assertion tests.
|
68
|
-
# &block
|
69
|
-
# : The block definition. Without one, the Assertion will have a :pending
|
70
|
-
# status.
|
71
|
-
def initialize(suite, description, &block)
|
72
|
-
@suite = suite
|
73
|
-
@status = nil
|
74
|
-
@failure_reason = nil
|
75
|
-
@exception = nil
|
76
|
-
@description = description || "No description given"
|
77
|
-
@block = block
|
78
|
-
end
|
79
|
-
|
80
|
-
# Run all setups in the order of their nesting (outermost first, innermost last)
|
81
|
-
def setup
|
82
|
-
@suite.ancestry_setup.each { |setup| instance_eval(&setup) } if @suite
|
83
|
-
end
|
84
|
-
|
85
|
-
# Run all teardowns in the order of their nesting (innermost first, outermost last)
|
86
|
-
def teardown
|
87
|
-
@suite.ancestry_teardown.each { |setup| instance_eval(&setup) } if @suite
|
88
|
-
end
|
89
|
-
|
90
|
-
# Runs the assertion and sets the status and exception
|
91
|
-
def execute
|
92
|
-
@exception = nil
|
93
|
-
if @block then
|
94
|
-
setup
|
95
|
-
# run the assertion
|
96
|
-
begin
|
97
|
-
@status = instance_eval(&@block) ? :success : :failure
|
98
|
-
rescue ::Test::Assertion::Failure => failure
|
99
|
-
@status = :failure
|
100
|
-
@failure_reason = failure
|
101
|
-
rescue => exception
|
102
|
-
@failure_reason = "An error occurred"
|
103
|
-
@exception = exception
|
104
|
-
@status = :error
|
105
|
-
end
|
106
|
-
teardown
|
107
|
-
else
|
108
|
-
@status = :pending
|
109
|
-
end
|
110
|
-
self
|
111
|
-
end
|
112
|
-
|
113
|
-
def clean_copy(use_class=nil)
|
114
|
-
(use_class || self.class).new(@suite, @description, &@block)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
data/lib/test/debug.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'pp'
|
10
|
-
require 'yaml'
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
module Test
|
15
|
-
class Suite
|
16
|
-
def to_s
|
17
|
-
sprintf "%s %s", self.class, @description
|
18
|
-
end
|
19
|
-
|
20
|
-
def inspect
|
21
|
-
sprintf "#<%s:%08x %p>", self.class, object_id>>1, @description
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class Assertion
|
26
|
-
def to_s
|
27
|
-
sprintf "%s %s", self.class, @description
|
28
|
-
end
|
29
|
-
|
30
|
-
def inspect
|
31
|
-
sprintf "#<%s:%08x @suite=%p %p>", self.class, object_id>>1, @suite, @description
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/lib/test/irb_mode.rb
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'test/debug'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
module Test
|
14
|
-
module IRBMode
|
15
|
-
module AssertionExtensions
|
16
|
-
end
|
17
|
-
|
18
|
-
class AssertionContext < ::Test::Assertion
|
19
|
-
attr_accessor :original_assertion
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
"Assertion"
|
23
|
-
end
|
24
|
-
|
25
|
-
def e!
|
26
|
-
em!
|
27
|
-
bt!
|
28
|
-
end
|
29
|
-
|
30
|
-
def em!
|
31
|
-
puts @original_assertion.exception
|
32
|
-
end
|
33
|
-
|
34
|
-
def bt!
|
35
|
-
size = caller.size+3
|
36
|
-
puts @original_assertion.exception.backtrace[0..-size]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.extended(by)
|
41
|
-
by.init do
|
42
|
-
require 'irb'
|
43
|
-
require 'test/debug'
|
44
|
-
IRB.setup(nil) # must only be called once
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Formatter callback.
|
49
|
-
# Invoked once for every assertion.
|
50
|
-
# Gets the assertion to run as single argument.
|
51
|
-
def run_test(assertion)
|
52
|
-
rv = super
|
53
|
-
# drop into irb if assertion failed
|
54
|
-
if [:failure, :error].include?(rv.status) then
|
55
|
-
start_irb_mode(assertion)
|
56
|
-
irb_mode_for_assertion(assertion)
|
57
|
-
stop_irb_mode(assertion)
|
58
|
-
end
|
59
|
-
|
60
|
-
@count[:test] += 1
|
61
|
-
@count[assertion.status] += 1
|
62
|
-
rv
|
63
|
-
end
|
64
|
-
|
65
|
-
def start_irb_mode(assertion)
|
66
|
-
ancestry = assertion.suite.ancestors.reverse.map { |suite| suite.name }
|
67
|
-
|
68
|
-
puts
|
69
|
-
puts "#{assertion.status.to_s.capitalize} in #{ancestry.join(' > ')}"
|
70
|
-
puts " #{assertion.description}"
|
71
|
-
puts "#{assertion.exception} - #{assertion.exception.backtrace.first}"
|
72
|
-
super
|
73
|
-
rescue NoMethodError # HAX, not happy about that. necessary due to order of extend
|
74
|
-
end
|
75
|
-
|
76
|
-
# This method is highlevel hax, try to add necessary API to
|
77
|
-
# Test::Assertion
|
78
|
-
def irb_mode_for_assertion(assertion)
|
79
|
-
irb_context = assertion.clean_copy(AssertionContext)
|
80
|
-
irb_context.original_assertion = assertion
|
81
|
-
irb_context.setup
|
82
|
-
@irb = IRB::Irb.new(IRB::WorkSpace.new(irb_context.send(:binding)))
|
83
|
-
irb = @irb # for closure
|
84
|
-
|
85
|
-
# HAX - cargo cult, taken from irb.rb, not yet really understood.
|
86
|
-
IRB.conf[:IRB_RC].call(irb.context) if IRB.conf[:IRB_RC] # loads the irbrc?
|
87
|
-
IRB.conf[:MAIN_CONTEXT] = irb.context # why would the main context be set here?
|
88
|
-
# /HAX
|
89
|
-
|
90
|
-
trap("SIGINT") do
|
91
|
-
irb.signal_handle
|
92
|
-
end
|
93
|
-
catch(:IRB_EXIT) do irb.eval_input end
|
94
|
-
|
95
|
-
irb_context.teardown
|
96
|
-
end
|
97
|
-
|
98
|
-
def stop_irb_mode(assertion)
|
99
|
-
puts
|
100
|
-
super
|
101
|
-
rescue NoMethodError # HAX, not happy about that. necessary due to order of extend
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
data/lib/test/run/cli.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module Test
|
10
|
-
class Run
|
11
|
-
module CLI
|
12
|
-
Formats = {
|
13
|
-
:pending => "\e[43m%9s\e[0m %s%s\n",
|
14
|
-
:skipped => "\e[43m%9s\e[0m %s%s\n",
|
15
|
-
:success => "\e[42m%9s\e[0m %s%s\n",
|
16
|
-
:failure => "\e[41m%9s\e[0m %s%s\n",
|
17
|
-
:error => "\e[37;40;1m%9s\e[0m %s%s\n" # ]]]]]]]] - bbedit hates open brackets...
|
18
|
-
}
|
19
|
-
|
20
|
-
FooterFormats = {
|
21
|
-
:incomplete => "\e[43m%9s\e[0m\n",
|
22
|
-
:success => "\e[42m%9s\e[0m\n",
|
23
|
-
:failure => "\e[41m%9s\e[0m\n",
|
24
|
-
:error => "\e[37;40;1m%9s\e[0m\n" # ]]]]]]]] - bbedit hates open brackets...
|
25
|
-
}
|
26
|
-
|
27
|
-
def run_all(*args)
|
28
|
-
@depth = 0
|
29
|
-
puts "Running all tests\n"
|
30
|
-
start = Time.now
|
31
|
-
super # run all suites
|
32
|
-
status = global_status
|
33
|
-
printf "\n%2$d tests run in %1$.1fs\n%3$d successful, %4$d pending, %5$d failures, %6$d errors\n",
|
34
|
-
Time.now-start, *@count.values_at(:test, :success, :pending, :failure, :error)
|
35
|
-
print "Final status: "
|
36
|
-
printf FooterFormats[status], status_label(status)
|
37
|
-
end
|
38
|
-
|
39
|
-
def run_suite(suite)
|
40
|
-
return super unless suite.description
|
41
|
-
#label, size = ' '*@depth+suite.description, suite.tests.size.to_s
|
42
|
-
#printf "\n\e[1m%-*s\e[0m (%d tests)\n", 71-size.length, label, size
|
43
|
-
case size = suite.tests.size
|
44
|
-
when 0
|
45
|
-
puts "\n \e[1m#{' '*@depth+suite.description}\e[0m"
|
46
|
-
when 1
|
47
|
-
puts "\n \e[1m#{' '*@depth+suite.description}\e[0m (1 test)"
|
48
|
-
else
|
49
|
-
puts "\n \e[1m#{' '*@depth+suite.description}\e[0m (#{size} tests)"
|
50
|
-
end
|
51
|
-
@depth += 1
|
52
|
-
super # run the suite
|
53
|
-
@depth -= 1
|
54
|
-
end
|
55
|
-
|
56
|
-
def run_test(assertion)
|
57
|
-
rv = super # run the assertion
|
58
|
-
printf(Formats[rv.status], status_label(rv.status), ' '*@depth, rv.description)
|
59
|
-
if rv.status == :error then
|
60
|
-
indent = ' '+' '*@depth
|
61
|
-
print(indent, rv.exception.message, "\n", indent, rv.exception.backtrace.first, "\n")
|
62
|
-
elsif rv.status == :failure && rv.failure_reason then
|
63
|
-
print(' ', ' '*@depth, rv.failure_reason, "\n")
|
64
|
-
end
|
65
|
-
rv
|
66
|
-
end
|
67
|
-
|
68
|
-
def word_wrap(string, cols)
|
69
|
-
str.scan(/[^ ]+ /)
|
70
|
-
end
|
71
|
-
|
72
|
-
def status_label(status)
|
73
|
-
status.to_s.capitalize.center(9)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
@format["test/run/cli"] = Run::CLI # register the extender
|
79
|
-
end
|
data/lib/test/run/interactive.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module Test
|
10
|
-
class Run
|
11
|
-
module Interactive
|
12
|
-
def self.extended(obj)
|
13
|
-
obj.init do
|
14
|
-
require "test/irb_mode"
|
15
|
-
extend(Test::IRBMode)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def run_all
|
20
|
-
count = proc { |acc,csuite| acc+csuite.tests.size+csuite.suites.inject(0, &count) }
|
21
|
-
@counted = count[0, suite] # count the number of tests to run
|
22
|
-
@depth = 0
|
23
|
-
@width = (Math.log(@counted)/Math.log(10)).floor+1
|
24
|
-
|
25
|
-
puts "Running all tests in interactive mode\n"
|
26
|
-
$stdout.sync = true
|
27
|
-
print_count
|
28
|
-
|
29
|
-
super
|
30
|
-
|
31
|
-
puts "\n\nDone"
|
32
|
-
$stdout.sync = false
|
33
|
-
$stdout.flush
|
34
|
-
end
|
35
|
-
|
36
|
-
def run_suite(suite)
|
37
|
-
return super unless suite.description
|
38
|
-
@depth += 1
|
39
|
-
super
|
40
|
-
@depth -= 1
|
41
|
-
end
|
42
|
-
|
43
|
-
def run_test(assertion)
|
44
|
-
rv = super
|
45
|
-
print_count
|
46
|
-
rv
|
47
|
-
end
|
48
|
-
|
49
|
-
def print_count
|
50
|
-
printf "\rRan %*d of %*d assertions", @width, @count[:test], @width, @counted
|
51
|
-
end
|
52
|
-
|
53
|
-
def stop_irb_mode(assertion)
|
54
|
-
puts "\n\n"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
@format["test/run/interactive"] = Run::Interactive # register the extender
|
60
|
-
end
|
data/lib/test/run/tap.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module Test
|
10
|
-
class Run
|
11
|
-
module TAP
|
12
|
-
def run_all
|
13
|
-
puts "TAP version 13"
|
14
|
-
count = proc { |acc,csuite| acc+csuite.tests.size+csuite.suites.inject(0, &count) }
|
15
|
-
puts "1..#{count[0, suite]}"
|
16
|
-
@current = 0
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def run_test(assertion)
|
21
|
-
rv = super
|
22
|
-
printf "%sok %d - %s%s\n",
|
23
|
-
rv.status == :success ? '' : 'not ',
|
24
|
-
@current+=1,
|
25
|
-
rv.description,
|
26
|
-
rv.status == :success ? '' : " # #{rv.status}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
@format["test/run/tap"] = Run::TAP
|
32
|
-
end
|
data/lib/test/run/xml.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module Test
|
10
|
-
class Run
|
11
|
-
module XML
|
12
|
-
def run_all
|
13
|
-
@depth = 1
|
14
|
-
|
15
|
-
puts '<?xml version="1.0" encoding="utf-8"?>'
|
16
|
-
puts '<tests>'
|
17
|
-
start = Time.now
|
18
|
-
super
|
19
|
-
stop = Time.now
|
20
|
-
status = case
|
21
|
-
when @count[:error] > 0 then 'error'
|
22
|
-
when @count[:failure] > 0 then 'failure'
|
23
|
-
when @count[:pending] > 0 then 'incomplete'
|
24
|
-
when @count[:skipped] > 0 then 'incomplete'
|
25
|
-
else 'success'
|
26
|
-
end
|
27
|
-
puts %{</tests>}
|
28
|
-
puts %{<report>}
|
29
|
-
puts %{\t<duration>#{stop-start}</duration>}
|
30
|
-
@count.each { |key, value|
|
31
|
-
puts %{\t<count type="#{key}">#{value}</count>}
|
32
|
-
}
|
33
|
-
puts %{</report>}
|
34
|
-
puts %{<status>#{status}</status>}
|
35
|
-
end
|
36
|
-
|
37
|
-
def run_suite(suite)
|
38
|
-
puts %{#{"\t"*@depth}<suite description="#{suite.description}">}
|
39
|
-
@depth += 1
|
40
|
-
super
|
41
|
-
@depth -= 1
|
42
|
-
puts %{#{"\t"*@depth}</suite>}
|
43
|
-
end
|
44
|
-
|
45
|
-
def run_test(assertion)
|
46
|
-
rv = super
|
47
|
-
puts %{#{"\t"*@depth}<test>}
|
48
|
-
puts %{#{"\t"*@depth}\t<status>#{rv.status}</status>}
|
49
|
-
puts %{#{"\t"*@depth}\t<description>#{rv.description}</description>}
|
50
|
-
puts %{#{"\t"*@depth}</test>}
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
@format["test/run/xml"] = Run::XML
|
56
|
-
end
|
data/lib/test/suite.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
module Test
|
10
|
-
|
11
|
-
# A Suite is a container for multiple assertions.
|
12
|
-
# You can give a suite a description, also a suite can contain
|
13
|
-
# setup and teardown blocks that are executed before (setup) and after
|
14
|
-
# (teardown) every assertion.
|
15
|
-
# Suites can also be nested. Nested suites will inherit setup and teardown.
|
16
|
-
class Suite
|
17
|
-
|
18
|
-
# Nested suites
|
19
|
-
attr_reader :suites
|
20
|
-
|
21
|
-
# All assertions in this suite
|
22
|
-
attr_reader :tests
|
23
|
-
|
24
|
-
# This suites description. Toplevel suites usually don't have a description.
|
25
|
-
attr_reader :description
|
26
|
-
|
27
|
-
# This suites direct parent. Nil if toplevel suite.
|
28
|
-
attr_reader :parent
|
29
|
-
|
30
|
-
# An Array containing the suite itself (first element), then its direct
|
31
|
-
# parent suite, then that suite's parent and so on
|
32
|
-
attr_reader :ancestors
|
33
|
-
|
34
|
-
def self.create(description=nil, parent=nil, opts={}, &block)
|
35
|
-
Array(opts[:requires]).each { |file| require file } if opts[:requires]
|
36
|
-
rescue LoadError
|
37
|
-
# A suite is skipped if requirements are not met
|
38
|
-
Skipped::Suite.new(description, parent, &block)
|
39
|
-
else
|
40
|
-
# All suites within Skipped::Suite are Skipped::Suite
|
41
|
-
(block ? self : Skipped::Suite).new(description, parent, &block)
|
42
|
-
end
|
43
|
-
|
44
|
-
def initialize(description=nil, parent=nil, &block)
|
45
|
-
@description = description
|
46
|
-
@parent = parent
|
47
|
-
@suites = []
|
48
|
-
@tests = []
|
49
|
-
@setup = []
|
50
|
-
@teardown = []
|
51
|
-
@ancestors = [self] + (@parent ? @parent.ancestors : [])
|
52
|
-
instance_eval(&block) if block
|
53
|
-
end
|
54
|
-
|
55
|
-
# Define a nested suite.
|
56
|
-
# Nested suites inherit setup & teardown methods.
|
57
|
-
# Also if an outer suite is skipped, all inner suites are skipped too.
|
58
|
-
# Valid values for opts:
|
59
|
-
# requires
|
60
|
-
# : A list of files to require, if one of the requires fails, the suite
|
61
|
-
# will be skipped. Accepts a String or an Array
|
62
|
-
def suite(description=nil, opts={}, &block)
|
63
|
-
@suites << self.class.create(description, self, opts, &block)
|
64
|
-
end
|
65
|
-
|
66
|
-
# All setups in the order of their nesting (outermost first, innermost last)
|
67
|
-
def ancestry_setup
|
68
|
-
ancestors.map { |suite| suite.setup }.flatten.reverse
|
69
|
-
end
|
70
|
-
|
71
|
-
# All teardowns in the order of their nesting (innermost first, outermost last)
|
72
|
-
def ancestry_teardown
|
73
|
-
ancestors.map { |suite| suite.teardown }.flatten
|
74
|
-
end
|
75
|
-
|
76
|
-
# Define a setup block for this suite. The block will be ran before every
|
77
|
-
# assertion once, even for nested suites.
|
78
|
-
def setup(&block)
|
79
|
-
block ? @setup << block : @setup
|
80
|
-
end
|
81
|
-
|
82
|
-
# Define a teardown block for this suite. The block will be ran after every
|
83
|
-
# assertion once, even for nested suites.
|
84
|
-
def teardown(&block)
|
85
|
-
block ? @teardown << block : @teardown
|
86
|
-
end
|
87
|
-
|
88
|
-
# Define an assertion. The block is supposed to return a trueish value
|
89
|
-
# (anything but nil or false).
|
90
|
-
# See Assertion for more info.
|
91
|
-
def assert(description=nil, &block)
|
92
|
-
@tests << Assertion.new(self, description, &block)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
data/lib/test.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2009 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'test/irb_mode'
|
10
|
-
require 'test/run'
|
11
|
-
require 'test/suite'
|
12
|
-
require 'test/assertion'
|
13
|
-
# See bottom for more requires
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
module Test
|
18
|
-
class <<self
|
19
|
-
# A hash of formatters (require-string => module) to be used with Test::Run.
|
20
|
-
attr_reader :format
|
21
|
-
|
22
|
-
# For mock integration and others, append modules that should extend the Test::Run instance.
|
23
|
-
attr_reader :extender
|
24
|
-
|
25
|
-
# The toplevel suite. That's the one run_if_mainfile and define add suites
|
26
|
-
# and assertions to.
|
27
|
-
attr_reader :toplevel_suite
|
28
|
-
|
29
|
-
# The full path to this file
|
30
|
-
attr_reader :required_file
|
31
|
-
end
|
32
|
-
|
33
|
-
# For bootstrapped selftest
|
34
|
-
def self.init
|
35
|
-
@format = {}
|
36
|
-
@extender = []
|
37
|
-
@toplevel_suite = Suite.new
|
38
|
-
@required_file = ["", *$LOAD_PATH].map { |path|
|
39
|
-
File.expand_path(File.join(path, __FILE__))
|
40
|
-
}.find { |full| File.exist?(full) }
|
41
|
-
end
|
42
|
-
init
|
43
|
-
|
44
|
-
# Adds the contained assertions and suites to the toplevel suite
|
45
|
-
def self.define(name=nil, opts={}, &block)
|
46
|
-
if name then
|
47
|
-
@toplevel_suite.suite(name, opts, &block)
|
48
|
-
elsif opts && !opts.empty?
|
49
|
-
raise ArgumentError, "Suites with options must have names"
|
50
|
-
else
|
51
|
-
@toplevel_suite.instance_eval(&block)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Creates a Test::Run instance, adds the assertions and suites defined in its
|
56
|
-
# own block to that Test::Run instance's toplevel suite and if $PROGRAM_NAME
|
57
|
-
# (aka $0) is equal to __FILE__ (means the current file is the file directly
|
58
|
-
# executed by ruby, and not just required/loaded/evaled by another file),
|
59
|
-
# subsequently also runs that suite.
|
60
|
-
def self.run_if_mainfile(name=nil, opts={}, &block)
|
61
|
-
define(name, opts, &block)
|
62
|
-
if caller.first[/^[^:]*/] == $0 then # if is mainfile
|
63
|
-
run(:format => ENV['FORMAT'], :interactive => ENV['INTERACTIVE'])
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.run(opts=nil)
|
68
|
-
Run.new(@toplevel_suite, opts).run_all
|
69
|
-
end
|
70
|
-
|
71
|
-
# Skipped contains variants of Suite and Assertion.
|
72
|
-
# See Skipped::Suite and Skipped::Assertion
|
73
|
-
module Skipped
|
74
|
-
# Like Test::Suite, but all Assertions are defined as Skipped::Assertion
|
75
|
-
class Suite < ::Test::Suite
|
76
|
-
# :nodoc:
|
77
|
-
# All Assertions use Skipped::Assertion instead of Test::Assertion.
|
78
|
-
def assert(description=nil, &block)
|
79
|
-
@tests << Skipped::Assertion.new(self, description, &block)
|
80
|
-
end
|
81
|
-
|
82
|
-
# :nodoc:
|
83
|
-
# All setup blocks are disabled
|
84
|
-
def ancestry_setup
|
85
|
-
[]
|
86
|
-
end
|
87
|
-
|
88
|
-
# :nodoc:
|
89
|
-
# All teardown blocks are disabled
|
90
|
-
def ancestry_teardown
|
91
|
-
[]
|
92
|
-
end
|
93
|
-
|
94
|
-
# :nodoc:
|
95
|
-
# All setup blocks are disabled
|
96
|
-
def setup(&block)
|
97
|
-
[]
|
98
|
-
end
|
99
|
-
|
100
|
-
# :nodoc:
|
101
|
-
# All teardown blocks are disabled
|
102
|
-
def teardown(&block)
|
103
|
-
[]
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Like Test::Assertion, but fakes execution and sets status always to
|
108
|
-
# skipped.
|
109
|
-
class Assertion < ::Test::Assertion
|
110
|
-
def execute() @status = :skipped and self end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# At bottom due to dependencies
|
118
|
-
require 'test/assertion/support' # Needs Test.extender to be defined
|