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/command/env.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
module Command
|
10
|
+
Option = Struct.new(:name, :short, :long, :negated, :necessity, :type, :declaration, :description) do
|
11
|
+
def process!(argument)
|
12
|
+
argument = Command::Types[type][argument] if type
|
13
|
+
argument
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
module Command
|
10
|
+
class Parser
|
11
|
+
attr_reader :definition
|
12
|
+
attr_reader :command
|
13
|
+
attr_reader :options
|
14
|
+
attr_reader :argv
|
15
|
+
|
16
|
+
def initialize(definition, argv)
|
17
|
+
@definition = definition
|
18
|
+
@argv = argv
|
19
|
+
@affix = [] # arguments after '--'
|
20
|
+
if i = argv.index('--')
|
21
|
+
@affix = argv[(i+1)..-1]
|
22
|
+
@arguments = argv.first(i)
|
23
|
+
else
|
24
|
+
@arguments = @argv.dup
|
25
|
+
end
|
26
|
+
@options = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def argument(name)
|
30
|
+
position = @definition.argument_position[name]
|
31
|
+
raise ArgumentError, "No argument #{name.inspect} available" unless position
|
32
|
+
arguments[position]
|
33
|
+
end
|
34
|
+
|
35
|
+
def option(name)
|
36
|
+
@options[name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def arguments
|
40
|
+
@arguments+@affix
|
41
|
+
end
|
42
|
+
|
43
|
+
def command!
|
44
|
+
if @definition.commands_by_name.include?(@arguments.first)
|
45
|
+
@command = @arguments.shift
|
46
|
+
else
|
47
|
+
@command = @definition.default_command
|
48
|
+
end
|
49
|
+
|
50
|
+
@command
|
51
|
+
end
|
52
|
+
|
53
|
+
def normalize_arguments!
|
54
|
+
options = @definition[@command].options_by_flag
|
55
|
+
parse_argv = @arguments
|
56
|
+
@arguments = []
|
57
|
+
while arg = parse_argv.shift
|
58
|
+
if arg =~ /\A-([^-]{2,})/ then
|
59
|
+
flags = $1
|
60
|
+
until flags.empty?
|
61
|
+
flag = flags.slice!(0,1)
|
62
|
+
if opt = options["-#{flag}"] then
|
63
|
+
case opt.necessity
|
64
|
+
when :required
|
65
|
+
@arguments << "-#{flag}"
|
66
|
+
@arguments << flags unless flags.empty?
|
67
|
+
flags = ""
|
68
|
+
when :optional
|
69
|
+
raise "Invalid option - can't merge short options with optional arguments"
|
70
|
+
when :none
|
71
|
+
@arguments << "-#{flag}"
|
72
|
+
else
|
73
|
+
raise "Unknown necessity #{opt.necessity.inspect} for option #{opt}"
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@arguments << "-#{flag}#{flags}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
@arguments << arg
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def options!(*flags)
|
86
|
+
ignore_invalid_options = flags.delete(:ignore_invalid_options)
|
87
|
+
options = @definition[@command].options_by_flag # options available to this command
|
88
|
+
env = @definition[@command].env_by_variable # options available to this command
|
89
|
+
defaults = @definition[@command].default_options # options available to this command
|
90
|
+
|
91
|
+
normalize_arguments!
|
92
|
+
|
93
|
+
parse_argv = @arguments
|
94
|
+
@arguments = []
|
95
|
+
|
96
|
+
defaults.each do |key, default|
|
97
|
+
@options[key] = default unless @options.has_key?(key)
|
98
|
+
end
|
99
|
+
|
100
|
+
env.each do |key, definition|
|
101
|
+
if ENV.has_key?(key) && !@options.has_key?(key) then
|
102
|
+
mapped = options[definition.name]
|
103
|
+
value = mapped.process!(ENV[key])
|
104
|
+
@options[key] = value
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
while arg = parse_argv.shift
|
109
|
+
if option = options[arg] then
|
110
|
+
case option.necessity
|
111
|
+
when :required
|
112
|
+
value = option.process!(parse_argv.shift)
|
113
|
+
when :optional
|
114
|
+
if parse_argv.first && parse_argv.first !~ /\A-/ then
|
115
|
+
value = option.process!(parse_argv.shift)
|
116
|
+
else
|
117
|
+
value = true
|
118
|
+
end
|
119
|
+
when :none
|
120
|
+
value = true
|
121
|
+
end
|
122
|
+
@options[option.name] = (arg == option.negated) ? !value : value
|
123
|
+
elsif arg =~ /\A-/ then
|
124
|
+
raise "Invalid option #{arg}" unless ignore_invalid_options
|
125
|
+
@arguments << arg
|
126
|
+
else
|
127
|
+
@arguments << arg
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
@options
|
132
|
+
end
|
133
|
+
|
134
|
+
def result
|
135
|
+
Result.new(@command, @options, @arguments+@affix)
|
136
|
+
end
|
137
|
+
|
138
|
+
def parse(*flags)
|
139
|
+
command!
|
140
|
+
options!(*flags)
|
141
|
+
|
142
|
+
result
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
module Command
|
10
|
+
Types = {
|
11
|
+
:Virtual => nil,
|
12
|
+
:Boolean => proc { |v| v =~ /\A(?:true|y(?:es)?)\z/i },
|
13
|
+
:String => proc { |v| v },
|
14
|
+
:Integer => proc { |v| Integer(v) },
|
15
|
+
:Octal => proc { |v| Intever("0#{v}") },
|
16
|
+
:Hex => proc { |v| Integer("0x#{v}") },
|
17
|
+
:Float => proc { |v| Float(v) },
|
18
|
+
:File => proc { |v|
|
19
|
+
raise FileNotFoundError, "No such file or directory - #{v}" unless File.exist?(v)
|
20
|
+
raise NoFileError, "Not a file - #{v}" unless File.file?(v)
|
21
|
+
v
|
22
|
+
},
|
23
|
+
:Directory => proc { |v|
|
24
|
+
raise DirectoryNotFoundError, "No such file or directory - #{v}" unless File.exist?(v)
|
25
|
+
raise NoDirectoryError, "Not a directory - #{v}" unless File.directory?(v)
|
26
|
+
v
|
27
|
+
},
|
28
|
+
:Path => proc { |v|
|
29
|
+
require 'pathname'
|
30
|
+
Pathname.new(v)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
module Command
|
10
|
+
|
11
|
+
# The version of the 'command' library
|
12
|
+
module VERSION
|
13
|
+
|
14
|
+
# The major version number
|
15
|
+
MAJOR = 0
|
16
|
+
|
17
|
+
# The minor version number
|
18
|
+
MINOR = 0
|
19
|
+
|
20
|
+
# The tiny version number
|
21
|
+
TINY = 1
|
22
|
+
|
23
|
+
# The version as a string
|
24
|
+
def self.to_s
|
25
|
+
"#{MAJOR}.#{MINOR||0}.#{TINY||0}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/setup.rb
CHANGED
data/test/suite/lib/baretest.rb
CHANGED
@@ -33,26 +33,6 @@ BareTest.suite "BareTest" do
|
|
33
33
|
|
34
34
|
equal(suites_before+1, suites_after)
|
35
35
|
end
|
36
|
-
|
37
|
-
assert "Should be used by BareTest::run_if_mainfile" do
|
38
|
-
test = ::BareTest.clone # avoid interfering with the current run
|
39
|
-
test.init
|
40
|
-
suites_before = test.toplevel_suite.suites.size
|
41
|
-
test.run_if_mainfile "A new suite" do end
|
42
|
-
suites_after = test.toplevel_suite.suites.size
|
43
|
-
|
44
|
-
equal(suites_before+1, suites_after)
|
45
|
-
end
|
46
|
-
|
47
|
-
assert "Should be run by BareTest::run" do
|
48
|
-
this = self # needed because touch is called in the block of another assertion, so otherwise it'd be local to that assertion
|
49
|
-
test = ::BareTest.clone # avoid interfering with the current run
|
50
|
-
test.init
|
51
|
-
test.suite "A new suite" do assert do this.touch(:assertion_executed) end end
|
52
|
-
test.run
|
53
|
-
|
54
|
-
touched(:assertion_executed)
|
55
|
-
end
|
56
36
|
end
|
57
37
|
|
58
38
|
suite "::suite" do
|
@@ -66,162 +46,4 @@ BareTest.suite "BareTest" do
|
|
66
46
|
equal(suites_before+1, suites_after)
|
67
47
|
end
|
68
48
|
end
|
69
|
-
|
70
|
-
suite "::run_if_mainfile", :requires => ['rbconfig', 'shellwords'] do
|
71
|
-
setup do
|
72
|
-
ENV['FORMAT'] = 'minimal'
|
73
|
-
@ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
74
|
-
@test_path = Shellwords.escape(File.expand_path("#{__FILE__}/../../../external/bootstraptest.rb"))
|
75
|
-
@wrap_path = Shellwords.escape(File.expand_path("#{__FILE__}/../../../external/bootstrapwrap.rb"))
|
76
|
-
@inc_path = Shellwords.escape(File.dirname(BareTest.required_file))
|
77
|
-
end
|
78
|
-
|
79
|
-
suite "File is the program" do
|
80
|
-
assert "Should run the suite" do
|
81
|
-
IO.popen("#{@ruby} -I#{@inc_path} -rbaretest #{@test_path}") { |sio|
|
82
|
-
sio.read
|
83
|
-
} =~ /\ATests: 1\nSuccess: 1\nPending: 0\nFailures: 0\nErrors: 0\nTime: [^\n]+\nStatus: success\n\z/
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
suite "File is not the program" do
|
88
|
-
assert "Should not run the suite if the file is not the program" do
|
89
|
-
IO.popen("#{@ruby} -I#{@inc_path} -rbaretest #{@wrap_path}") { |sio|
|
90
|
-
sio.read
|
91
|
-
} =~ /\ADone\n\z/
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
suite "::run" do
|
97
|
-
assert "Should run BareTest's toplevel suite" do
|
98
|
-
this = self # needed because touch is called in the block of another assertion, so otherwise it'd be local to that assertion
|
99
|
-
test = ::BareTest.clone # avoid interfering with the current run
|
100
|
-
test.init
|
101
|
-
test.suite "A new suite" do assert do this.touch(:assertion_executed) end end
|
102
|
-
test.run
|
103
|
-
|
104
|
-
touched(:assertion_executed)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
suite "Skipped" do
|
109
|
-
suite "Suite" do
|
110
|
-
setup do
|
111
|
-
parent = ::BareTest::Suite.new
|
112
|
-
parent.setup do end
|
113
|
-
parent.teardown do end
|
114
|
-
@suite = ::BareTest::Skipped::Suite.new("None", parent)
|
115
|
-
@suite.setup do end
|
116
|
-
@suite.teardown do end
|
117
|
-
end
|
118
|
-
|
119
|
-
suite "#ancestry_setup" do
|
120
|
-
assert "Should always be an empty array." do
|
121
|
-
equal([], @suite.ancestry_setup)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
suite "#setup" do
|
126
|
-
assert "Should always be an empty array." do
|
127
|
-
equal([], @suite.setup)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
suite "#ancestry_teardown" do
|
132
|
-
assert "Should always be an empty array." do
|
133
|
-
equal([], @suite.ancestry_teardown)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
suite "#teardown" do
|
138
|
-
assert "Should always be an empty array." do
|
139
|
-
equal([], @suite.teardown)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
suite "#assert" do
|
144
|
-
assert "Should add new skipped assertions to a suite." do
|
145
|
-
equal(
|
146
|
-
:expected => 0,
|
147
|
-
:actual => @suite.assertions.size,
|
148
|
-
:message => "number of defined tests before adding any"
|
149
|
-
)
|
150
|
-
|
151
|
-
@suite.assert "a"
|
152
|
-
equal(
|
153
|
-
:expected => 1,
|
154
|
-
:actual => @suite.skipped.size,
|
155
|
-
:message => "number of defined tests after adding one"
|
156
|
-
)
|
157
|
-
|
158
|
-
@suite.assert "b"
|
159
|
-
equal(
|
160
|
-
:expected => 2,
|
161
|
-
:actual => @suite.skipped.size,
|
162
|
-
:message => "number of defined tests after adding two"
|
163
|
-
)
|
164
|
-
|
165
|
-
equal_unordered(
|
166
|
-
:expected => ['a', 'b'],
|
167
|
-
:actual => @suite.skipped.map { |child| child.description },
|
168
|
-
:message => "the descriptions"
|
169
|
-
)
|
170
|
-
|
171
|
-
@suite.skipped.all? { |test| kind_of(::BareTest::Skipped::Assertion, test) }
|
172
|
-
end
|
173
|
-
|
174
|
-
assert "Added tests should have the receiving suite as suite." do
|
175
|
-
@suite.assert "a"
|
176
|
-
assertion = @suite.skipped.first
|
177
|
-
|
178
|
-
same(
|
179
|
-
:expected => @suite,
|
180
|
-
:actual => assertion.suite,
|
181
|
-
:message => "the suite"
|
182
|
-
)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
suite "Assertion" do
|
188
|
-
suite "#execute" do
|
189
|
-
suite "Given a test that succeeds" do
|
190
|
-
assert "Should have status :skipped" do
|
191
|
-
assertion = ::BareTest::Skipped::Assertion.new(nil, "") do true end
|
192
|
-
assertion.execute
|
193
|
-
|
194
|
-
equal(:skipped, assertion.status)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
suite "Given a test that is pending" do
|
199
|
-
assert "Should have status :skipped" do
|
200
|
-
assertion = ::BareTest::Skipped::Assertion.new(nil, "")
|
201
|
-
assertion.execute
|
202
|
-
|
203
|
-
equal(:skipped, assertion.status)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
suite "Given a test that fails" do
|
208
|
-
assert "Should have status :skipped" do
|
209
|
-
assertion = ::BareTest::Skipped::Assertion.new(nil, "") do false end
|
210
|
-
assertion.execute
|
211
|
-
|
212
|
-
equal(:skipped, assertion.status)
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
suite "Given a test that errors" do
|
217
|
-
assert "Should have status :skipped" do
|
218
|
-
assertion = ::BareTest::Skipped::Assertion.new(nil, "") do raise end
|
219
|
-
assertion.execute
|
220
|
-
|
221
|
-
equal(:skipped, assertion.status)
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
49
|
end
|