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.
Files changed (85) hide show
  1. data/LICENSE.txt +6 -6
  2. data/MANIFEST.txt +40 -18
  3. data/README.rdoc +8 -1
  4. data/bin/baretest +126 -118
  5. data/doc/baretest.rdoc +1 -1
  6. data/doc/mocking_stubbing_test_doubles.rdoc +31 -3
  7. data/doc/news/news-0.3.0.rdoc +7 -0
  8. data/doc/quickref.rdoc +74 -28
  9. data/doc/whats_going_on.rdoc +5 -0
  10. data/doc/writing_tests.rdoc +25 -13
  11. data/examples/components/rack-test.rb +17 -0
  12. data/examples/{tests/irb_mode → irb_mode}/failures.rb +0 -0
  13. data/examples/rake/test.rake +40 -0
  14. data/examples/tests/01_basics_I.rb +34 -0
  15. data/examples/tests/02_basics_II_helpers.rb +25 -0
  16. data/examples/tests/03_basics_III_setup_and_teardown.rb +53 -0
  17. data/examples/tests/04_advanced_I_dependencies.rb +31 -0
  18. data/examples/tests/05_advanced_II_tags.rb +12 -0
  19. data/examples/tests/06_advanced_III_requires.rb +21 -0
  20. data/examples/tests/07_advanced_IV_components.rb +48 -0
  21. data/examples/tests/08_expert_I_setup_variants.rb +46 -0
  22. data/lib/baretest.rb +142 -21
  23. data/lib/baretest/assertion.rb +83 -92
  24. data/lib/baretest/assertion/context.rb +9 -0
  25. data/lib/baretest/assertion/support.rb +88 -61
  26. data/lib/baretest/commandline.rb +268 -0
  27. data/lib/baretest/formatter.rb +58 -0
  28. data/lib/baretest/invalidselectors.rb +24 -0
  29. data/lib/baretest/irb_mode.rb +100 -58
  30. data/lib/baretest/persistence.rb +94 -0
  31. data/lib/baretest/run.rb +138 -37
  32. data/lib/baretest/run/cli.rb +97 -43
  33. data/lib/baretest/run/minimal.rb +2 -1
  34. data/lib/baretest/run/none.rb +21 -0
  35. data/lib/baretest/run/xml.rb +21 -19
  36. data/lib/baretest/setup.rb +2 -0
  37. data/lib/baretest/status.rb +93 -0
  38. data/lib/baretest/suite.rb +185 -59
  39. data/lib/baretest/uid.rb +51 -0
  40. data/lib/baretest/use/mocha.rb +24 -0
  41. data/lib/baretest/use/rack_test.rb +9 -0
  42. data/lib/baretest/use/rr.rb +17 -0
  43. data/lib/baretest/version.rb +18 -4
  44. data/lib/command.rb +36 -0
  45. data/lib/command/argument.rb +11 -0
  46. data/lib/command/decoratinghash.rb +31 -0
  47. data/lib/command/definition.rb +294 -0
  48. data/lib/command/directorynotfounderror.rb +11 -0
  49. data/lib/command/env.rb +11 -0
  50. data/lib/command/filenotfounderror.rb +11 -0
  51. data/lib/command/kernel.rb +14 -0
  52. data/lib/command/nodirectoryerror.rb +11 -0
  53. data/lib/command/nofileerror.rb +11 -0
  54. data/lib/command/option.rb +16 -0
  55. data/lib/command/parser.rb +145 -0
  56. data/lib/command/result.rb +11 -0
  57. data/lib/command/types.rb +33 -0
  58. data/lib/command/version.rb +28 -0
  59. data/test/setup.rb +3 -0
  60. data/test/suite/lib/baretest.rb +0 -178
  61. data/test/suite/lib/baretest/assertion.rb +133 -112
  62. data/test/suite/lib/baretest/assertion/context.rb +40 -0
  63. data/test/suite/lib/baretest/assertion/failure.rb +19 -0
  64. data/test/suite/lib/baretest/assertion/skip.rb +19 -0
  65. data/test/suite/lib/baretest/assertion/support.rb +366 -84
  66. data/test/suite/lib/baretest/run.rb +114 -15
  67. data/test/suite/lib/baretest/suite.rb +70 -29
  68. metadata +46 -24
  69. data/examples/test.rake +0 -65
  70. data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
  71. data/examples/tests/mock_developer/test/setup.rb +0 -57
  72. data/examples/tests/mock_developer/test/suite/mock_demo.rb +0 -19
  73. data/examples/tests/overview/test.rb +0 -89
  74. data/examples/tests/variations/variations_01.rb +0 -14
  75. data/examples/tests/variations/variations_02.rb +0 -19
  76. data/examples/tests/variations/variations_03.rb +0 -19
  77. data/lib/baretest/mocha.rb +0 -18
  78. data/lib/baretest/rr.rb +0 -16
  79. data/lib/baretest/run/errors.rb +0 -49
  80. data/lib/baretest/skipped.rb +0 -15
  81. data/lib/baretest/skipped/assertion.rb +0 -20
  82. data/lib/baretest/skipped/suite.rb +0 -49
  83. data/test/external/bootstraptest.rb +0 -5
  84. data/test/external/bootstrapwrap.rb +0 -2
  85. data/test/helper/mocks.rb +0 -0
@@ -0,0 +1,11 @@
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 DirectoryNotFoundError < NoDirectoryError; end
11
+ end
@@ -0,0 +1,11 @@
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
+ Env = Struct.new(:name, :variable)
11
+ end
@@ -0,0 +1,11 @@
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 FileNotFoundError < NoFileError; end
11
+ end
@@ -0,0 +1,14 @@
1
+ #--
2
+ # Copyright 2010 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ module Kernel
10
+ private
11
+ def Command(*args, &block)
12
+ $command = Command.define(nil, *args, &block)
13
+ end
14
+ end
@@ -0,0 +1,11 @@
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 NoDirectoryError < ArgumentError; end
11
+ end
@@ -0,0 +1,11 @@
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 NoFileError < ArgumentError; end
11
+ end
@@ -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,11 @@
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
+ Result = Struct.new(:command, :options, :arguments)
11
+ 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
@@ -1,2 +1,5 @@
1
+ BareTest.require_baretest "0.4"
2
+ BareTest.require_ruby "1.8.6"
3
+
1
4
  $LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib"))
2
5
  require 'baretest'
@@ -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