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