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
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
|