baretest 0.2.4 → 0.4.0.pre1
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/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
data/lib/baretest/run/xml.rb
CHANGED
@@ -31,47 +31,49 @@ module BareTest
|
|
31
31
|
# <status>The final status, one of: success, incomplete, failure, error</status>
|
32
32
|
#
|
33
33
|
module XML # :nodoc:
|
34
|
+
extend Formatter
|
35
|
+
option_defaults :indent => "\t"
|
36
|
+
text "Options for 'XML' formatter:\n"
|
37
|
+
option :indent, '--indent STRING', :String, 'String to use for indenting'
|
38
|
+
text "\nEnvironment variables for 'XML' formatter:\n"
|
39
|
+
env_option :indent, 'INDENT'
|
40
|
+
|
34
41
|
def run_all
|
35
|
-
@depth
|
42
|
+
@depth = 1
|
43
|
+
@indent = @options[:indent]
|
36
44
|
|
37
45
|
puts '<?xml version="1.0" encoding="utf-8"?>',
|
38
46
|
'<tests>'
|
39
47
|
start = Time.now
|
40
48
|
super
|
41
49
|
stop = Time.now
|
42
|
-
status = case
|
43
|
-
when @count[:error] > 0 then 'error'
|
44
|
-
when @count[:failure] > 0 then 'failure'
|
45
|
-
when @count[:pending] > 0 then 'incomplete'
|
46
|
-
when @count[:skipped] > 0 then 'incomplete'
|
47
|
-
else 'success'
|
48
|
-
end
|
49
50
|
puts %{</tests>},
|
50
51
|
%{<report>},
|
51
|
-
%{
|
52
|
+
%{#{@indent}<duration>#{stop-start}</duration>}
|
52
53
|
@count.each { |key, value|
|
53
|
-
puts %{
|
54
|
+
puts %{#{@indent}<count type="#{key}">#{value}</count>}
|
54
55
|
}
|
55
56
|
puts %{</report>},
|
56
|
-
%{<status>#{
|
57
|
+
%{<status>#{global_status}</status>}
|
57
58
|
end
|
58
59
|
|
59
60
|
def run_suite(suite)
|
60
|
-
puts %{#{
|
61
|
+
puts %{#{@indent*@depth}<suite description="#{suite.description}">}
|
61
62
|
@depth += 1
|
62
63
|
super
|
63
64
|
@depth -= 1
|
64
|
-
puts %{#{
|
65
|
+
puts %{#{@indent*@depth}</suite>}
|
65
66
|
end
|
66
67
|
|
67
68
|
def run_test(assertion, setup)
|
68
69
|
rv = super
|
69
|
-
puts %{#{
|
70
|
-
%{#{
|
71
|
-
%{#{
|
72
|
-
%{#{
|
73
|
-
%{#{
|
74
|
-
%{#{
|
70
|
+
puts %{#{@indent*@depth}<test>},
|
71
|
+
%{#{@indent*@depth}#{@indent}<file>#{assertion.file}</file>},
|
72
|
+
%{#{@indent*@depth}#{@indent}<line>#{assertion.line}</line>},
|
73
|
+
%{#{@indent*@depth}#{@indent}<status>#{rv.status}</status>},
|
74
|
+
%{#{@indent*@depth}#{@indent}<description>#{assertion.description}</description>},
|
75
|
+
%{#{@indent*@depth}</test>}
|
76
|
+
rv
|
75
77
|
end
|
76
78
|
end
|
77
79
|
end
|
data/lib/baretest/setup.rb
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
module BareTest
|
10
|
+
# Encapsulates a single setup block and associated information.
|
11
|
+
# Relevant for setup variants.
|
10
12
|
Setup = Struct.new(:component, :substitute, :value, :block) do
|
11
13
|
def inspect
|
12
14
|
sprintf "#<Setup component=%s substitute=%p value=%p>", component, substitute, value
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009-2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
module BareTest
|
10
|
+
|
11
|
+
# The status of an Assertion or Suite, including failure- and skipreasons,
|
12
|
+
# or in case of exceptions, the exception itself and in what phase it occurred
|
13
|
+
# An assertion or suite has 9 possible states:
|
14
|
+
# :success:: The assertion passed. This means the block returned a trueish value.
|
15
|
+
# :failure:: The assertion failed. This means the block returned a falsish value.
|
16
|
+
# Alternatively it raised an Assertion::Failure.
|
17
|
+
# The latter has the advantage that it can provide nicer diagnostics.
|
18
|
+
# :pending:: No block given to the assertion to be run
|
19
|
+
# :skipped:: If one of the parent suites is missing a dependency, its assertions
|
20
|
+
# will be skipped
|
21
|
+
# Alternatively it raised an Assertion::Skip.
|
22
|
+
# :error:: The assertion errored out. This means the block raised an exception
|
23
|
+
class Status
|
24
|
+
|
25
|
+
# The assertion or suite this status belongs to. Assertion or Suite.
|
26
|
+
attr_reader :entity
|
27
|
+
|
28
|
+
# The assertions execute context.
|
29
|
+
attr_reader :context
|
30
|
+
|
31
|
+
# The status identifier, see BareTest::Status. Symbol.
|
32
|
+
attr_reader :status
|
33
|
+
|
34
|
+
# Detailed reason for skipping. Array or nil.
|
35
|
+
attr_reader :skip_reason
|
36
|
+
|
37
|
+
# Detailed reason for failing. Array or nil.
|
38
|
+
attr_reader :failure_reason
|
39
|
+
|
40
|
+
# If an exception occured in Assertion#execute, this will contain the
|
41
|
+
# Exception object raised.
|
42
|
+
attr_reader :exception
|
43
|
+
|
44
|
+
# entity:: The suite or Assertion this Status belongs to
|
45
|
+
# status:: The status identifier
|
46
|
+
# skip_reason:: Why the Assertion or Suite failed.
|
47
|
+
# Array, String or nil.
|
48
|
+
# failure_reason:: Why the Assertion or Suite was skipped.
|
49
|
+
# Array, String or nil.
|
50
|
+
def initialize(entity, status, context=nil, skip_reason=nil, failure_reason=nil, exception=nil)
|
51
|
+
@entity = entity
|
52
|
+
@status = status
|
53
|
+
@context = context
|
54
|
+
@skip_reason = skip_reason
|
55
|
+
@failure_reason = failure_reason
|
56
|
+
@exception = exception
|
57
|
+
end
|
58
|
+
|
59
|
+
# The failure/error/skipping/pending reason.
|
60
|
+
# Returns nil if there's no reason, a string otherwise
|
61
|
+
# Options:
|
62
|
+
# :default:: Reason to return if no reason is present
|
63
|
+
# :separator:: String used to separate multiple reasons
|
64
|
+
# :indent:: A String, the indentation to use. Prefixes every line.
|
65
|
+
# :first_indent: A String, used to indent the first line only (replaces indent).
|
66
|
+
def reason(opt=nil)
|
67
|
+
if opt then
|
68
|
+
default, separator, indent, first_indent =
|
69
|
+
*opt.values_at(:default, :separator, :indent, :first_indent)
|
70
|
+
reason = @skip_reason || @failure_reason || default
|
71
|
+
return nil unless reason
|
72
|
+
reason = Array(reason)
|
73
|
+
reason = reason.join(separator || "\n")
|
74
|
+
reason = reason.gsub(/^/, indent) if indent
|
75
|
+
reason = reason.gsub(/^#{Regexp.escape(indent)}/, first_indent) if first_indent
|
76
|
+
reason
|
77
|
+
else
|
78
|
+
@reason.empty? ? nil : @reason.join("\n")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def inspect # :nodoc:
|
83
|
+
sprintf "#<%s:0x%08x status=%p exception=%p skip_reason=%p failure_reason=%p entity=%p>",
|
84
|
+
self.class,
|
85
|
+
object_id>>1,
|
86
|
+
@status,
|
87
|
+
@exception,
|
88
|
+
@skip_reason,
|
89
|
+
@failure_reason,
|
90
|
+
@entity
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/baretest/suite.rb
CHANGED
@@ -21,76 +21,181 @@ module BareTest
|
|
21
21
|
class Suite
|
22
22
|
|
23
23
|
# Nested suites, in the order of definition
|
24
|
-
attr_reader
|
24
|
+
attr_reader :suites
|
25
25
|
|
26
26
|
# All assertions in this suite
|
27
|
-
attr_reader
|
27
|
+
attr_reader :assertions
|
28
28
|
|
29
|
-
#
|
30
|
-
|
29
|
+
# Whether this suite has been manually skipped (either via
|
30
|
+
# Suite.new(..., :skip => reason) or via Suite#skip)
|
31
|
+
attr_reader :skipped
|
31
32
|
|
32
33
|
# This suites description. Toplevel suites usually don't have a description.
|
33
|
-
attr_reader
|
34
|
+
attr_reader :description
|
34
35
|
|
35
36
|
# This suites direct parent. Nil if toplevel suite.
|
36
|
-
attr_reader
|
37
|
+
attr_reader :parent
|
37
38
|
|
38
39
|
# An Array containing the suite itself (first element), then its direct
|
39
40
|
# parent suite, then that suite's parent and so on
|
40
|
-
attr_reader
|
41
|
+
attr_reader :ancestors
|
42
|
+
|
43
|
+
# All things this suite depends on, see Suite::new for more information
|
44
|
+
attr_reader :depends_on
|
45
|
+
|
46
|
+
# All things this suite provides, see Suite::new for more information
|
47
|
+
attr_reader :provides
|
48
|
+
|
49
|
+
# All things this suite is tagged with, see Suite::new for more information
|
50
|
+
attr_reader :tags
|
51
|
+
|
52
|
+
# A list of valid options Suite::new accepts
|
53
|
+
ValidOptions = [:skip, :requires, :use, :provides, :depends_on, :tags]
|
41
54
|
|
42
55
|
# Create a new suite.
|
43
56
|
#
|
44
|
-
#
|
45
|
-
#
|
57
|
+
# Arguments:
|
58
|
+
# description:: A string with a human readable description of this suite,
|
59
|
+
# preferably less than 60 characters and without newlines
|
60
|
+
# parent:: The suite that nests this suite. Ancestry plays a role in
|
61
|
+
# execution of setup and teardown blocks (all ancestors setups
|
62
|
+
# and teardowns are executed too).
|
63
|
+
# opts:: An additional options hash.
|
46
64
|
#
|
47
65
|
# Keys the options hash accepts:
|
48
|
-
# :
|
49
|
-
#
|
50
|
-
#
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
#
|
66
|
+
# :skip:: Skips the suite if true or a String is passed. If a String
|
67
|
+
# is passed, it is used as the reason.
|
68
|
+
# :requires:: A string or array of strings with requires that have to be
|
69
|
+
# done in order to run this suite. If a require fails, the
|
70
|
+
# assertions will all be skipped with reason "Missing
|
71
|
+
# dependency".
|
72
|
+
# :use:: A symbol or array of symbols with components this suite
|
73
|
+
# should load prior to running.
|
74
|
+
# :provides:: A symbol or array of symbols with dependencies this suite
|
75
|
+
# resolves, see 'depends_on'.
|
76
|
+
# :depends_on:: A symbol or array of symbols with dependencies of this
|
77
|
+
# suite, see 'provides'.
|
78
|
+
# :tags:: A symbol or array of symbols, useful to run only suites
|
79
|
+
# having/not having specific tags
|
62
80
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
# and teardown blocks (all ancestors setups and teardowns are executed too).
|
68
|
-
# &block:: The given block is instance evaled.
|
69
|
-
def initialize(description=nil, parent=nil, &block)
|
81
|
+
# &block:: The given block is instance evaled and can contain further
|
82
|
+
# definition of this assertion. See Suite#suite and
|
83
|
+
# Suite#assert.
|
84
|
+
def initialize(description=nil, parent=nil, opts=nil, &block)
|
70
85
|
@description = description
|
71
86
|
@parent = parent
|
72
87
|
@suites = [] # [["description", subsuite, skipped], ["description2", ...], ...] - see Array#assoc
|
73
88
|
@assertions = []
|
74
|
-
@skipped =
|
89
|
+
@skipped = false
|
75
90
|
@setup = {nil => []}
|
76
91
|
@components = []
|
77
92
|
@teardown = []
|
78
|
-
|
93
|
+
if @parent then
|
94
|
+
@ancestors = [self, *@parent.ancestors]
|
95
|
+
@depends_on = @parent.depends_on
|
96
|
+
@tags = @parent.tags
|
97
|
+
else
|
98
|
+
@ancestors = [self]
|
99
|
+
@depends_on = []
|
100
|
+
@tags = []
|
101
|
+
end
|
102
|
+
@provides = []
|
103
|
+
@reason = [] # skip reason
|
104
|
+
if opts then
|
105
|
+
raise ArgumentError, "Invalid option(s): #{(opts.keys - ValidOptions).inspect}" unless (opts.keys - ValidOptions).empty?
|
106
|
+
skip, requires, use, provides, depends_on, tags = opts.values_at(*ValidOptions)
|
107
|
+
skip(skip == true ? nil : skip) if skip
|
108
|
+
use(*use) if use
|
109
|
+
requires(*requires) if requires
|
110
|
+
@depends_on |= Array(depends_on) if depends_on
|
111
|
+
@provides |= Array(provides) if provides
|
112
|
+
@tags |= Array(tags) if tags
|
113
|
+
end
|
79
114
|
instance_eval(&block) if block
|
80
115
|
end
|
81
116
|
|
117
|
+
# An ID, usable for persistence
|
118
|
+
def id
|
119
|
+
@id ||= ancestors.map { |suite| suite.description }.join("\f")
|
120
|
+
end
|
121
|
+
|
122
|
+
# Instruct this suite to use the given components.
|
123
|
+
# The suite is skipped if a component is not available.
|
124
|
+
def use(*components)
|
125
|
+
components.each do |name|
|
126
|
+
component = BareTest.component(name)
|
127
|
+
if component then
|
128
|
+
instance_eval(&component)
|
129
|
+
else
|
130
|
+
skip("Missing component: #{name.inspect}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Instruct this suite to require the given files.
|
136
|
+
# The suite is skipped if a file can't be loaded.
|
137
|
+
def requires(*paths)
|
138
|
+
paths.each do |file|
|
139
|
+
begin
|
140
|
+
require file
|
141
|
+
rescue LoadError => e
|
142
|
+
skip("Missing source file: #{file} (#{e})")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns whether this suite has all the passed tags
|
148
|
+
def tagged?(tags)
|
149
|
+
(@tags-tags).empty?
|
150
|
+
end
|
151
|
+
|
152
|
+
# Marks this suite as manually skipped.
|
153
|
+
def skip(reason=nil)
|
154
|
+
@skipped = true
|
155
|
+
@reason |= reason ? Array(reason) : ['Manually skipped']
|
156
|
+
true
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns whether this assertion has been marked as manually skipped.
|
160
|
+
def skipped?
|
161
|
+
@skipped
|
162
|
+
end
|
163
|
+
|
164
|
+
# The failure/error/skipping/pending reason.
|
165
|
+
# Returns nil if there's no reason, a string otherwise
|
166
|
+
# Options:
|
167
|
+
# :default:: Reason to return if no reason is present
|
168
|
+
# :separator:: String used to separate multiple reasons
|
169
|
+
# :indent:: A String, the indentation to use. Prefixes every line.
|
170
|
+
# :first_indent: A String, used to indent the first line only (replaces indent).
|
171
|
+
def reason(opt=nil)
|
172
|
+
if opt then
|
173
|
+
default, separator, indent, first_indent =
|
174
|
+
*opt.values_at(:default, :separator, :indent, :first_indent)
|
175
|
+
reason = @reason
|
176
|
+
reason = Array(default) if reason.empty? && default
|
177
|
+
return nil if reason.empty?
|
178
|
+
reason = reason.join(separator || "\n")
|
179
|
+
reason = reason.gsub(/^/, indent) if indent
|
180
|
+
reason = reason.gsub(/^#{Regexp.escape(indent)}/, first_indent) if first_indent
|
181
|
+
reason
|
182
|
+
else
|
183
|
+
@reason.empty? ? nil : @reason.join("\n")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
82
187
|
# Define a nested suite.
|
83
188
|
#
|
84
189
|
# Nested suites inherit setup & teardown methods.
|
85
190
|
# Also if an outer suite is skipped, all inner suites are skipped too.
|
86
191
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
if
|
93
|
-
|
192
|
+
# See Suite::new - all arguments are passed to it verbatim, and self is
|
193
|
+
# added as parent.
|
194
|
+
def suite(description=nil, *args, &block)
|
195
|
+
suite = self.class.new(description, self, *args, &block)
|
196
|
+
existing_suite = @suites.assoc(description)
|
197
|
+
if existing_suite then
|
198
|
+
existing_suite.last.update(suite)
|
94
199
|
else
|
95
200
|
@suites << [description, suite]
|
96
201
|
end
|
@@ -101,20 +206,23 @@ module BareTest
|
|
101
206
|
#
|
102
207
|
# Used to merge suites with the same description.
|
103
208
|
def update(with_suite)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
209
|
+
assertions, setup, teardown, provides, depends_on, skipped, reason, suites =
|
210
|
+
*with_suite.merge_attributes
|
211
|
+
@assertions.concat(assertions)
|
212
|
+
@setup.update(setup) do |k,v1,v2| v1+v2 end
|
213
|
+
@teardown.concat(teardown)
|
214
|
+
@provides |= provides
|
215
|
+
@depends_on |= depends_on
|
216
|
+
@skipped ||= skipped
|
217
|
+
@reason.concat(reason)
|
218
|
+
suites.each { |description, suite|
|
219
|
+
if append_to = @suites.assoc(description) then
|
220
|
+
append_to.last.update(suite)
|
221
|
+
else
|
222
|
+
@suites << [description, suite]
|
223
|
+
end
|
224
|
+
}
|
225
|
+
|
118
226
|
self
|
119
227
|
end
|
120
228
|
|
@@ -173,6 +281,13 @@ module BareTest
|
|
173
281
|
block ? @teardown << block : @teardown
|
174
282
|
end
|
175
283
|
|
284
|
+
# Returns the number of possible setup variations.
|
285
|
+
# See #each_component_variant
|
286
|
+
def component_variant_count
|
287
|
+
ancestry_setup.values_at(*ancestry_components).inject(1) { |r,f| r*f.size }
|
288
|
+
end
|
289
|
+
|
290
|
+
# Yields all possible permutations of setup components.
|
176
291
|
def each_component_variant
|
177
292
|
setups = ancestry_setup
|
178
293
|
components = ancestry_components
|
@@ -196,6 +311,7 @@ module BareTest
|
|
196
311
|
self
|
197
312
|
end
|
198
313
|
|
314
|
+
# Return only the first of all possible setup variation permutations.
|
199
315
|
def first_component_variant
|
200
316
|
setups, *comps = ancestry_setup.values_at(nil, *ancestry_components)
|
201
317
|
setups = setups+comps.map { |comp| comp.first }
|
@@ -208,8 +324,8 @@ module BareTest
|
|
208
324
|
# (anything but nil or false).
|
209
325
|
#
|
210
326
|
# See Assertion for more info.
|
211
|
-
def assert(description=nil, &block)
|
212
|
-
assertion = Assertion.new(self, description, &block)
|
327
|
+
def assert(description=nil, opts=nil, &block)
|
328
|
+
assertion = Assertion.new(self, description, opts, &block)
|
213
329
|
if match = caller.first.match(/^(.*):(\d+)(?::.+)?$/) then
|
214
330
|
file, line = match.captures
|
215
331
|
file = File.expand_path(file)
|
@@ -220,6 +336,7 @@ module BareTest
|
|
220
336
|
end
|
221
337
|
@assertions << assertion
|
222
338
|
end
|
339
|
+
alias guard assert # TODO: This is temporary, guards should become first class citizens
|
223
340
|
|
224
341
|
def to_s #:nodoc:
|
225
342
|
sprintf "%s %s", self.class, @description
|
@@ -228,9 +345,18 @@ module BareTest
|
|
228
345
|
def inspect #:nodoc:
|
229
346
|
sprintf "#<%s:%08x %p>", self.class, object_id>>1, @description
|
230
347
|
end
|
348
|
+
|
349
|
+
protected
|
350
|
+
# All attributes that are required when merging two suites
|
351
|
+
def merge_attributes
|
352
|
+
return @assertions,
|
353
|
+
@setup,
|
354
|
+
@teardown,
|
355
|
+
@provides,
|
356
|
+
@depends_on,
|
357
|
+
@skipped,
|
358
|
+
@reason,
|
359
|
+
@suites
|
360
|
+
end
|
231
361
|
end
|
232
362
|
end
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
require 'baretest/skipped/suite' # TODO: determine why this require is on the bottom and document it.
|