baretest 0.2.4 → 0.4.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +6 -6
- data/MANIFEST.txt +40 -18
- data/README.rdoc +8 -1
- data/bin/baretest +126 -118
- data/doc/baretest.rdoc +1 -1
- data/doc/mocking_stubbing_test_doubles.rdoc +31 -3
- data/doc/news/news-0.3.0.rdoc +7 -0
- data/doc/quickref.rdoc +74 -28
- data/doc/whats_going_on.rdoc +5 -0
- data/doc/writing_tests.rdoc +25 -13
- data/examples/components/rack-test.rb +17 -0
- data/examples/{tests/irb_mode → irb_mode}/failures.rb +0 -0
- data/examples/rake/test.rake +40 -0
- data/examples/tests/01_basics_I.rb +34 -0
- data/examples/tests/02_basics_II_helpers.rb +25 -0
- data/examples/tests/03_basics_III_setup_and_teardown.rb +53 -0
- data/examples/tests/04_advanced_I_dependencies.rb +31 -0
- data/examples/tests/05_advanced_II_tags.rb +12 -0
- data/examples/tests/06_advanced_III_requires.rb +21 -0
- data/examples/tests/07_advanced_IV_components.rb +48 -0
- data/examples/tests/08_expert_I_setup_variants.rb +46 -0
- data/lib/baretest.rb +142 -21
- data/lib/baretest/assertion.rb +83 -92
- data/lib/baretest/assertion/context.rb +9 -0
- data/lib/baretest/assertion/support.rb +88 -61
- data/lib/baretest/commandline.rb +268 -0
- data/lib/baretest/formatter.rb +58 -0
- data/lib/baretest/invalidselectors.rb +24 -0
- data/lib/baretest/irb_mode.rb +100 -58
- data/lib/baretest/persistence.rb +94 -0
- data/lib/baretest/run.rb +138 -37
- data/lib/baretest/run/cli.rb +97 -43
- data/lib/baretest/run/minimal.rb +2 -1
- data/lib/baretest/run/none.rb +21 -0
- data/lib/baretest/run/xml.rb +21 -19
- data/lib/baretest/setup.rb +2 -0
- data/lib/baretest/status.rb +93 -0
- data/lib/baretest/suite.rb +185 -59
- data/lib/baretest/uid.rb +51 -0
- data/lib/baretest/use/mocha.rb +24 -0
- data/lib/baretest/use/rack_test.rb +9 -0
- data/lib/baretest/use/rr.rb +17 -0
- data/lib/baretest/version.rb +18 -4
- data/lib/command.rb +36 -0
- data/lib/command/argument.rb +11 -0
- data/lib/command/decoratinghash.rb +31 -0
- data/lib/command/definition.rb +294 -0
- data/lib/command/directorynotfounderror.rb +11 -0
- data/lib/command/env.rb +11 -0
- data/lib/command/filenotfounderror.rb +11 -0
- data/lib/command/kernel.rb +14 -0
- data/lib/command/nodirectoryerror.rb +11 -0
- data/lib/command/nofileerror.rb +11 -0
- data/lib/command/option.rb +16 -0
- data/lib/command/parser.rb +145 -0
- data/lib/command/result.rb +11 -0
- data/lib/command/types.rb +33 -0
- data/lib/command/version.rb +28 -0
- data/test/setup.rb +3 -0
- data/test/suite/lib/baretest.rb +0 -178
- data/test/suite/lib/baretest/assertion.rb +133 -112
- data/test/suite/lib/baretest/assertion/context.rb +40 -0
- data/test/suite/lib/baretest/assertion/failure.rb +19 -0
- data/test/suite/lib/baretest/assertion/skip.rb +19 -0
- data/test/suite/lib/baretest/assertion/support.rb +366 -84
- data/test/suite/lib/baretest/run.rb +114 -15
- data/test/suite/lib/baretest/suite.rb +70 -29
- metadata +46 -24
- data/examples/test.rake +0 -65
- data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
- data/examples/tests/mock_developer/test/setup.rb +0 -57
- data/examples/tests/mock_developer/test/suite/mock_demo.rb +0 -19
- data/examples/tests/overview/test.rb +0 -89
- data/examples/tests/variations/variations_01.rb +0 -14
- data/examples/tests/variations/variations_02.rb +0 -19
- data/examples/tests/variations/variations_03.rb +0 -19
- data/lib/baretest/mocha.rb +0 -18
- data/lib/baretest/rr.rb +0 -16
- data/lib/baretest/run/errors.rb +0 -49
- data/lib/baretest/skipped.rb +0 -15
- data/lib/baretest/skipped/assertion.rb +0 -20
- data/lib/baretest/skipped/suite.rb +0 -49
- data/test/external/bootstraptest.rb +0 -5
- data/test/external/bootstrapwrap.rb +0 -2
- data/test/helper/mocks.rb +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
# pretend the lib 'baretest/demo/06_advanced_requires' was already loaded
|
2
|
+
$LOADED_FEATURES << 'baretest/demo/06_advanced_requires'
|
3
|
+
|
4
|
+
|
5
|
+
# You can baretest tell that a suite depends on an external lib using the
|
6
|
+
# :requires option, it accepts either a String or an Array of strings.
|
7
|
+
BareTest.suite do
|
8
|
+
# Baretest will load all libraries mentioned in :requires via a standard
|
9
|
+
# Kernel.require upon suite definition
|
10
|
+
suite "Depends on an existing lib", :requires => 'baretest/demo/06_advanced_requires' do
|
11
|
+
assert "Succeeds because library-dependency is met" do
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
suite "Depends on a missing lib", :requires => 'baretest/demo/06_advanced_requires_missing' do
|
17
|
+
assert "Skipped because library-dependency is NOT met" do
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# This code should be in 'baretest/use/demo_component', somewhere in rubys
|
2
|
+
# $LOAD_PATH.
|
3
|
+
module DemoComponent
|
4
|
+
module DemoMethods
|
5
|
+
def demo
|
6
|
+
demo_component = @demo_component
|
7
|
+
@demo_component = :executed
|
8
|
+
same(:setup, demo_component)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
BareTest.new_component :demo_component do
|
14
|
+
# Make our components' assertion helpers available in assertions
|
15
|
+
BareTest::Assertion::Context.send :include, DemoComponent::DemoMethods
|
16
|
+
|
17
|
+
setup do
|
18
|
+
@demo_component = :setup
|
19
|
+
end
|
20
|
+
|
21
|
+
teardown do
|
22
|
+
same(:executed, @demo_component, "@demo_component after the assertion")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
BareTest.suite do
|
28
|
+
suite "Using DemoComponent", :use => :demo_component do
|
29
|
+
assert "Successful assertions must use the 'demo' method" do
|
30
|
+
demo
|
31
|
+
end
|
32
|
+
|
33
|
+
assert "Fails if 'demo' is not invoked, even if otherwise successful" do
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
assert "Fails if @demo_component was changed prior to calling 'demo'" do
|
38
|
+
@demo_component = :unexpected
|
39
|
+
demo
|
40
|
+
end
|
41
|
+
|
42
|
+
assert "Fails if @demo_component was changed after to calling 'demo'" do
|
43
|
+
demo
|
44
|
+
@demo_component = :unexpected
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# The thing we want to test
|
2
|
+
class String
|
3
|
+
def numeric?
|
4
|
+
self =~ /[+-]?(?:[1-9]\d*|0)(?:\.\d+)?(?:[eE][+-]?\d+)?/
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
BareTest.suite do
|
9
|
+
suite "Variations - Notation I" do
|
10
|
+
setup :number, '123' do |number|
|
11
|
+
@number = '123'
|
12
|
+
end
|
13
|
+
|
14
|
+
setup :number, '-123' do |number|
|
15
|
+
@number = '-123'
|
16
|
+
end
|
17
|
+
|
18
|
+
setup :number, '1.23' do |number|
|
19
|
+
@number = '1.23'
|
20
|
+
end
|
21
|
+
|
22
|
+
assert ":number should be a numeric" do
|
23
|
+
@number.numeric?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
suite "Variations - Notation II" do
|
28
|
+
setup :number, %w[123 -123 1.23 -1.23 1e3 -1e3 1e-3 -1e-3] do |number|
|
29
|
+
@number = number
|
30
|
+
end
|
31
|
+
|
32
|
+
assert ":number should be a numeric" do
|
33
|
+
@number.numeric?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
suite "Variations - Notation III" do
|
38
|
+
setup :number, {'"123"' => "123", '"1.23"' => "1.23", '"1e3"' => "1e3"} do |number|
|
39
|
+
@number = number
|
40
|
+
end
|
41
|
+
|
42
|
+
assert ":number should be a numeric" do
|
43
|
+
@number.numeric?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/baretest.rb
CHANGED
@@ -7,6 +7,9 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
require 'baretest/assertion'
|
10
|
+
require 'baretest/commandline'
|
11
|
+
require 'baretest/formatter'
|
12
|
+
require 'baretest/invalidselectors'
|
10
13
|
require 'baretest/irb_mode'
|
11
14
|
require 'baretest/run'
|
12
15
|
require 'baretest/suite'
|
@@ -17,7 +20,45 @@ require 'ruby/kernel'
|
|
17
20
|
|
18
21
|
|
19
22
|
module BareTest
|
23
|
+
# A lookup table to test which of two states is more important
|
24
|
+
# (MoreImportantStatus[[a,b]] # => a or b)
|
25
|
+
MoreImportantStatus = {}
|
26
|
+
|
27
|
+
# All states in the order of relevance, more relevant states first
|
28
|
+
StatusOrder = :error,
|
29
|
+
:failure,
|
30
|
+
:pending,
|
31
|
+
:manually_skipped,
|
32
|
+
:dependency_missing,
|
33
|
+
:library_missing,
|
34
|
+
:component_missing,
|
35
|
+
:ignored,
|
36
|
+
:success
|
37
|
+
|
38
|
+
StatusOrder.combination(2) do |x,y|
|
39
|
+
more_important = StatusOrder.index(x) < StatusOrder.index(y) ? x : y
|
40
|
+
MoreImportantStatus[[x,y]] = more_important
|
41
|
+
MoreImportantStatus[[y,x]] = more_important
|
42
|
+
end
|
43
|
+
StatusOrder.each do |status|
|
44
|
+
MoreImportantStatus[[status,status]] = status
|
45
|
+
MoreImportantStatus[[nil,status]] = status
|
46
|
+
MoreImportantStatus[[status,nil]] = status
|
47
|
+
end
|
48
|
+
|
49
|
+
# The standard glob used by baretest to load test files
|
50
|
+
# :nodoc:
|
51
|
+
DefaultInitialPositiveGlob = 'test/{suite,unit,isolation,integration,system}/**/*.rb'
|
52
|
+
|
53
|
+
# Selectors that are valid to be passed into process_selectors
|
54
|
+
# :nodoc:
|
55
|
+
ValidStateSelectors = [:new, :success, :failure, :error, :skipped, :pending]
|
56
|
+
|
20
57
|
class << self
|
58
|
+
# A hash of components - available via BareTest::use(name) and
|
59
|
+
# Suite#suite :use => name
|
60
|
+
attr_reader :components
|
61
|
+
|
21
62
|
# A hash of formatters (require-string => module) to be used with Test::Run.
|
22
63
|
attr_reader :format
|
23
64
|
|
@@ -33,6 +74,21 @@ module BareTest
|
|
33
74
|
attr_reader :required_file # :nodoc:
|
34
75
|
end
|
35
76
|
|
77
|
+
# Enure that the suite is run wiht a minimal version of baretest
|
78
|
+
def self.require_baretest(version)
|
79
|
+
if (version.split(".").map { |s| s.to_i } <=> BareTest::VERSION.to_a) == 0 then
|
80
|
+
abort "Requires baretest version #{version}, you have #{BareTest::VERSION}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Ensure that the suite is run with a minimal version of ruby
|
85
|
+
def self.require_ruby(version)
|
86
|
+
if (version.split(".").map { |s| s.to_i } <=> RUBY_VERSION.split(".").map { |s| s.to_i }) == 1 then
|
87
|
+
abort "Requires ruby version #{version}, you have #{RUBY_VERSION}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
36
92
|
# Loads all files in a test directory in order to load the suites and
|
37
93
|
# assertions. Used by the 'baretest' executable and the standard rake task.
|
38
94
|
#
|
@@ -44,16 +100,20 @@ module BareTest
|
|
44
100
|
def self.load_standard_test_files(opts={})
|
45
101
|
verbose = opts.delete(:verbose)
|
46
102
|
setup_path = opts.delete(:setup_path) || 'test/setup.rb'
|
103
|
+
lib_path = opts.delete(:lib_path) || 'test/lib'
|
47
104
|
chdir = opts.delete(:chdir) || '.'
|
48
|
-
files = opts.delete(:files)
|
105
|
+
files = opts.delete(:files)
|
106
|
+
files = [DefaultInitialPositiveGlob] if (files.nil? || files.empty?)
|
49
107
|
Dir.chdir(chdir) do
|
108
|
+
$LOAD_PATH.unshift(File.expand_path(lib_path)) if File.exist?(lib_path)
|
50
109
|
load(setup_path) if File.exist?(setup_path)
|
51
110
|
files.each do |glob|
|
52
111
|
glob = "#{glob}/**/*.rb" if File.directory?(glob)
|
53
112
|
Dir.glob(glob) { |path|
|
54
113
|
helper_path = path.sub(%r{^test/(suite|unit|integration|system)/}, 'test/helper/\1/')
|
55
|
-
|
56
|
-
|
114
|
+
exists = (helper_path != path && File.exist?(helper_path))
|
115
|
+
puts(exists ? "Loading helper file #{helper_path}" : "No helper file #{helper_path} to load") if verbose
|
116
|
+
load(helper_path) if exists
|
57
117
|
puts "Loading test file #{path}" if verbose
|
58
118
|
load(path)
|
59
119
|
}
|
@@ -61,10 +121,70 @@ module BareTest
|
|
61
121
|
end
|
62
122
|
end
|
63
123
|
|
124
|
+
# Determine which of the named states is the most important one (see
|
125
|
+
# StatusOrder)
|
126
|
+
def self.most_important_status(states)
|
127
|
+
(StatusOrder & states).first # requires Array#& to be stable (keep order of first operand)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Convert an array of selectors into a hash with those selectors preprocessed
|
131
|
+
# as far as possible.
|
132
|
+
# Example:
|
133
|
+
# BareTest.process_selectors %w[-some/**/glob/*.rb %failure :tag1 -:tag2]
|
134
|
+
# # => {
|
135
|
+
# # :files => ...an array with paths...,
|
136
|
+
# # :include_tags => [:tag1],
|
137
|
+
# # :exclude_tags => [:tag2],
|
138
|
+
# # :include_states => [:failure]
|
139
|
+
# # :exclude_states => nil,
|
140
|
+
# # }
|
141
|
+
def self.process_selectors(selectors, base_directory=".", default_initial_positive_glob=nil)
|
142
|
+
files = []
|
143
|
+
include_tags = []
|
144
|
+
exclude_tags = []
|
145
|
+
include_states = []
|
146
|
+
exclude_states = []
|
147
|
+
|
148
|
+
default_initial_positive_glob ||= DefaultInitialPositiveGlob
|
149
|
+
Dir.chdir(base_directory) do
|
150
|
+
selectors.each do |selector|
|
151
|
+
case selector
|
152
|
+
when /\A-%(.*)/ then exclude_states << $1.to_sym
|
153
|
+
when /\A-:(.*)/ then exclude_tags << $1.to_sym
|
154
|
+
when /\A\+?%(.*)/ then include_states << $1.to_sym
|
155
|
+
when /\A\+?:(.*)/ then include_tags << $1.to_sym
|
156
|
+
when /\A-(.*)/ then
|
157
|
+
files = Dir[default_initial_positive_glob] if files.empty? && default_initial_positive_glob
|
158
|
+
glob = File.directory?($1) ? "#{$1}/**/*.rb" : $1
|
159
|
+
files -= Dir[glob]
|
160
|
+
when /\A\+?(.*)/ then
|
161
|
+
glob = File.directory?(selector) ? "#{selector}/**/*.rb" : selector
|
162
|
+
files |= Dir[glob]
|
163
|
+
else
|
164
|
+
raise "Should never reach else - selector: #{selector.inspect}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
files = Dir[default_initial_positive_glob] if files.empty? && default_initial_positive_glob
|
168
|
+
files.map! do |path| File.expand_path(path) end
|
169
|
+
end
|
170
|
+
|
171
|
+
invalid_states = (include_states|exclude_states)-ValidStateSelectors
|
172
|
+
raise InvalidSelectors.new(invalid_states) unless invalid_states.empty?
|
173
|
+
|
174
|
+
return {
|
175
|
+
:files => files,
|
176
|
+
:include_tags => include_tags,
|
177
|
+
:exclude_tags => exclude_tags,
|
178
|
+
:include_states => include_states.empty? ? nil : include_states,
|
179
|
+
:exclude_states => exclude_states.empty? ? nil : exclude_states
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
64
183
|
# Initializes BareTest, is automatically called
|
65
184
|
#
|
66
185
|
# Needed for bootstrapped selftest
|
67
186
|
def self.init # :nodoc:
|
187
|
+
@components = {}
|
68
188
|
@format = {}
|
69
189
|
@extender = []
|
70
190
|
@toplevel_suite = BareTest::Suite.new
|
@@ -74,6 +194,17 @@ module BareTest
|
|
74
194
|
end
|
75
195
|
init
|
76
196
|
|
197
|
+
def self.component(name)
|
198
|
+
component = @components[name]
|
199
|
+
begin
|
200
|
+
require "baretest/use/#{name}"
|
201
|
+
rescue LoadError
|
202
|
+
else
|
203
|
+
component = @components[name]
|
204
|
+
end
|
205
|
+
component
|
206
|
+
end
|
207
|
+
|
77
208
|
# If no description was given, it adds the contained assertions and suites to the toplevel suite,
|
78
209
|
# if a description was given, a suite with the given description is created, added to the toplevel
|
79
210
|
# suite, and all the contained assertions and suites are added to the created suite.
|
@@ -87,26 +218,16 @@ module BareTest
|
|
87
218
|
end
|
88
219
|
end
|
89
220
|
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
def self.run_if_mainfile(description=nil, opts={}, &block)
|
96
|
-
suite(description, opts, &block)
|
97
|
-
if caller.first[/^[^:]*/] == $0 then # if is mainfile
|
98
|
-
run(:format => ENV['FORMAT'], :interactive => ENV['INTERACTIVE'])
|
99
|
-
end
|
221
|
+
# Create a new component for Suite's :use option (see BareTest::Suite::new)
|
222
|
+
def self.new_component(name, &block)
|
223
|
+
name = name.to_sym
|
224
|
+
raise ArgumentError, "Component named #{name.inspect} already exists" if @components.has_key?(name)
|
225
|
+
@components[name] = block
|
100
226
|
end
|
101
227
|
|
102
|
-
#
|
103
|
-
|
104
|
-
|
105
|
-
# Returns the Run instance.
|
106
|
-
def self.run(opts=nil)
|
107
|
-
runner = BareTest::Run.new(@toplevel_suite, opts)
|
108
|
-
runner.run_all
|
109
|
-
runner
|
228
|
+
# Shortcut for toplevel_suite.use. Preferably use the :use option instead.
|
229
|
+
def self.use(component)
|
230
|
+
@toplevel_suite.use(component)
|
110
231
|
end
|
111
232
|
end
|
112
233
|
|
data/lib/baretest/assertion.rb
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
require 'baretest/assertion/context'
|
10
10
|
require 'baretest/assertion/failure'
|
11
11
|
require 'baretest/assertion/skip'
|
12
|
+
require 'baretest/status'
|
12
13
|
|
13
14
|
|
14
15
|
|
@@ -30,42 +31,16 @@ module BareTest
|
|
30
31
|
# * Kernel#equal_unordered(a,b)
|
31
32
|
# * Enumerable#equal_unordered(other)
|
32
33
|
class Assertion
|
33
|
-
|
34
34
|
# The exceptions baretest will not rescue (NoMemoryError, SignalException, Interrupt
|
35
35
|
# and SystemExit)
|
36
36
|
PassthroughExceptions = [NoMemoryError, SignalException, Interrupt, SystemExit]
|
37
37
|
|
38
|
-
# An assertion has 5 possible states:
|
39
|
-
# :success:: The assertion passed. This means the block returned a trueish value.
|
40
|
-
# :failure:: The assertion failed. This means the block returned a falsish value.
|
41
|
-
# Alternatively it raised a Test::Failure (NOT YET IMPLEMENTED).
|
42
|
-
# The latter has the advantage that it can provide nicer diagnostics.
|
43
|
-
# :pending:: No block given to the assertion to be run
|
44
|
-
# :skipped:: If one of the parent suites is missing a dependency, its assertions
|
45
|
-
# will be skipped
|
46
|
-
# :error:: The assertion errored out. This means the block raised an exception
|
47
|
-
attr_reader :status
|
48
|
-
|
49
|
-
# If an exception occured in Assertion#execute, this will contain the
|
50
|
-
# Exception object raised.
|
51
|
-
attr_reader :exception
|
52
|
-
|
53
38
|
# The description of this assertion.
|
54
39
|
attr_reader :description
|
55
40
|
|
56
|
-
# The failure/error/skipping/pending reason.
|
57
|
-
attr_reader :reason
|
58
|
-
|
59
41
|
# The suite this assertion belongs to
|
60
42
|
attr_reader :suite
|
61
43
|
|
62
|
-
# The Context-instance the assertions setup, assert and teardown are run
|
63
|
-
attr_reader :context
|
64
|
-
|
65
|
-
# The Setup instances whose #block is to be executed before this assertion
|
66
|
-
# is ran
|
67
|
-
attr_accessor :setups
|
68
|
-
|
69
44
|
# The block specifying the assertion
|
70
45
|
attr_reader :block
|
71
46
|
|
@@ -85,90 +60,106 @@ module BareTest
|
|
85
60
|
# description:: A descriptive string about what this Assertion tests.
|
86
61
|
# &block:: The block definition. Without one, the Assertion will have a
|
87
62
|
# :pending status.
|
88
|
-
def initialize(suite, description, &block)
|
89
|
-
@suite
|
90
|
-
@description
|
91
|
-
@
|
92
|
-
@
|
93
|
-
|
63
|
+
def initialize(suite, description, opt=nil, &block)
|
64
|
+
@suite = suite
|
65
|
+
@description = (description || "No description given")
|
66
|
+
@block = block
|
67
|
+
@skipped = false
|
68
|
+
if opt then
|
69
|
+
skip_reason = opt[:skip]
|
70
|
+
skip(skip_reason == true ? "Tagged as skipped" : skip_reason) if skip_reason
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# An ID, usable for persistence
|
75
|
+
def id
|
76
|
+
@id ||= [
|
77
|
+
@description,
|
78
|
+
*(@suite && @suite.ancestors.map { |suite| suite.description })
|
79
|
+
].compact.join("\f")
|
94
80
|
end
|
95
81
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
@exception = nil
|
100
|
-
@context = ::BareTest::Assertion::Context.new(self)
|
82
|
+
# Returns whether this assertion has been marked as manually skipped.
|
83
|
+
def skipped?
|
84
|
+
!!@skipped
|
101
85
|
end
|
102
86
|
|
103
|
-
|
104
|
-
|
105
|
-
|
87
|
+
# Marks this assertion as manually skipped.
|
88
|
+
def skip(reason=nil)
|
89
|
+
@skipped ||= []
|
90
|
+
@skipped |= reason ? Array(reason) : ['Manually skipped']
|
91
|
+
end
|
92
|
+
|
93
|
+
# The description allows substitutes in the form ":identifier" and
|
94
|
+
# ":{identifier}" (the latter in case of ajanced characters that don't
|
95
|
+
# belong to the identifier, like ":{identifier}stuff").
|
96
|
+
# This method will interploate those substitutes.
|
97
|
+
# This is relevant with regards to setup variants.
|
98
|
+
def interpolated_description(substitutes)
|
99
|
+
if substitutes.empty? then
|
106
100
|
@description
|
107
101
|
else
|
108
|
-
substitutes = {}
|
109
|
-
setups.each do |setup| substitutes[setup.component] = setup.substitute end
|
110
102
|
@description.gsub(/:(?:#{substitutes.keys.join('|')})\b/) { |m|
|
111
103
|
substitutes[m[1..-1].to_sym]
|
112
104
|
}
|
113
105
|
end
|
114
106
|
end
|
115
107
|
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
108
|
+
# Returns a Status
|
109
|
+
# Executes with_setup, then the assertions defining block, and in the end
|
110
|
+
# and_teardown. Usually with_setup and and_teardown are supplied by the
|
111
|
+
# containing suite.
|
112
|
+
def execute(with_setup=nil, and_teardown=nil)
|
113
|
+
if @skipped then
|
114
|
+
status = Status.new(self, :manually_skipped)
|
115
|
+
elsif !@block
|
116
|
+
status = Status.new(self, :pending)
|
117
|
+
else
|
118
|
+
context = ::BareTest::Assertion::Context.new(self)
|
119
|
+
status = execute_phase(:setup, context, with_setup) if with_setup
|
120
|
+
status = execute_phase(:exercise, context, @block) unless status
|
121
|
+
status = execute_phase(:teardown, context, and_teardown) unless (status || !and_teardown)
|
122
|
+
status ||= Status.new(self, :success, context)
|
123
|
+
end
|
129
124
|
|
130
|
-
|
131
|
-
def teardown
|
132
|
-
@suite.ancestry_teardown.each do |teardown|
|
133
|
-
@context.instance_eval(&teardown)
|
134
|
-
end if @suite
|
135
|
-
rescue *PassthroughExceptions
|
136
|
-
raise # pass through exceptions must be passed through
|
137
|
-
rescue Exception => exception
|
138
|
-
@reason = "An error occurred during setup"
|
139
|
-
@exception = exception
|
140
|
-
@status = :error
|
125
|
+
status
|
141
126
|
end
|
142
127
|
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
rescue Exception => exception
|
162
|
-
@reason = "An error occurred during execution"
|
163
|
-
@exception = exception
|
164
|
-
@status = :error
|
128
|
+
# A phase can result in either success, skip, failure or error
|
129
|
+
# Execute_phase will simply return nil upon success, all other cases
|
130
|
+
# will generate a full Status instance.
|
131
|
+
# This is for practical reasons - it means you can go through several
|
132
|
+
# phases, looking for the first non-nil one.
|
133
|
+
def execute_phase(name, context, code)
|
134
|
+
status = nil
|
135
|
+
skip_reason = nil
|
136
|
+
failure_reason = nil
|
137
|
+
exception = nil
|
138
|
+
|
139
|
+
begin
|
140
|
+
if code.is_a?(Array) then
|
141
|
+
code.each do |block| context.instance_eval(&block) end
|
142
|
+
else
|
143
|
+
unless context.instance_eval(&code)
|
144
|
+
failure_reason = "Assertion failed"
|
145
|
+
status = :failure
|
165
146
|
end
|
166
147
|
end
|
167
|
-
|
168
|
-
|
169
|
-
|
148
|
+
rescue *PassthroughExceptions
|
149
|
+
raise # passthrough-exceptions must be passed through
|
150
|
+
rescue ::BareTest::Assertion::Failure => failure
|
151
|
+
status = :failure
|
152
|
+
failure_reason = failure.message
|
153
|
+
rescue ::BareTest::Assertion::Skip => skip
|
154
|
+
status = :manually_skipped
|
155
|
+
skip_reason = skip.message
|
156
|
+
rescue Exception => exception
|
157
|
+
status = :error
|
158
|
+
failure_reason = "An error occurred during #{name}: #{exception}"
|
159
|
+
exception = exception
|
170
160
|
end
|
171
|
-
|
161
|
+
|
162
|
+
status && Status.new(self, status, context, skip_reason, failure_reason, exception)
|
172
163
|
end
|
173
164
|
|
174
165
|
def to_s # :nodoc:
|