tap 0.12.4 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/History +34 -0
  2. data/README +62 -41
  3. data/bin/tap +36 -40
  4. data/cmd/console.rb +14 -6
  5. data/cmd/manifest.rb +62 -58
  6. data/cmd/run.rb +49 -31
  7. data/doc/API +84 -0
  8. data/doc/Class Reference +83 -115
  9. data/doc/Examples/Command Line +36 -0
  10. data/doc/Examples/Workflow +40 -0
  11. data/lib/tap/app.rb +293 -214
  12. data/lib/tap/app/node.rb +43 -0
  13. data/lib/tap/app/queue.rb +77 -0
  14. data/lib/tap/app/stack.rb +16 -0
  15. data/lib/tap/app/state.rb +22 -0
  16. data/lib/tap/constants.rb +2 -2
  17. data/lib/tap/env.rb +400 -314
  18. data/lib/tap/env/constant.rb +227 -0
  19. data/lib/tap/env/gems.rb +63 -0
  20. data/lib/tap/env/manifest.rb +89 -0
  21. data/lib/tap/env/minimap.rb +292 -0
  22. data/lib/tap/{support → env}/string_ext.rb +2 -2
  23. data/lib/tap/exe.rb +113 -125
  24. data/lib/tap/join.rb +175 -0
  25. data/lib/tap/joins.rb +9 -0
  26. data/lib/tap/joins/switch.rb +44 -0
  27. data/lib/tap/joins/sync.rb +99 -0
  28. data/lib/tap/root.rb +100 -491
  29. data/lib/tap/root/utils.rb +220 -0
  30. data/lib/tap/{support → root}/versions.rb +31 -29
  31. data/lib/tap/schema.rb +248 -0
  32. data/lib/tap/schema/parser.rb +413 -0
  33. data/lib/tap/schema/utils.rb +82 -0
  34. data/lib/tap/support/intern.rb +19 -6
  35. data/lib/tap/support/templater.rb +8 -3
  36. data/lib/tap/task.rb +175 -171
  37. data/lib/tap/tasks/dump.rb +58 -0
  38. data/lib/tap/tasks/load.rb +62 -0
  39. metadata +30 -73
  40. data/cmd/destroy.rb +0 -27
  41. data/cmd/generate.rb +0 -27
  42. data/doc/Command Reference +0 -105
  43. data/doc/Syntax Reference +0 -234
  44. data/doc/Tutorial +0 -348
  45. data/lib/tap/dump.rb +0 -142
  46. data/lib/tap/file_task.rb +0 -384
  47. data/lib/tap/generator/arguments.rb +0 -13
  48. data/lib/tap/generator/base.rb +0 -176
  49. data/lib/tap/generator/destroy.rb +0 -60
  50. data/lib/tap/generator/generate.rb +0 -93
  51. data/lib/tap/generator/generators/command/command_generator.rb +0 -21
  52. data/lib/tap/generator/generators/command/templates/command.erb +0 -32
  53. data/lib/tap/generator/generators/config/config_generator.rb +0 -98
  54. data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
  55. data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
  56. data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
  57. data/lib/tap/generator/generators/root/root_generator.rb +0 -84
  58. data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
  59. data/lib/tap/generator/generators/root/templates/README +0 -14
  60. data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
  61. data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
  62. data/lib/tap/generator/generators/root/templates/gemspec +0 -27
  63. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
  64. data/lib/tap/generator/generators/task/task_generator.rb +0 -25
  65. data/lib/tap/generator/generators/task/templates/task.erb +0 -14
  66. data/lib/tap/generator/generators/task/templates/test.erb +0 -19
  67. data/lib/tap/generator/manifest.rb +0 -20
  68. data/lib/tap/generator/preview.rb +0 -69
  69. data/lib/tap/load.rb +0 -64
  70. data/lib/tap/spec.rb +0 -41
  71. data/lib/tap/support/aggregator.rb +0 -65
  72. data/lib/tap/support/audit.rb +0 -333
  73. data/lib/tap/support/constant.rb +0 -143
  74. data/lib/tap/support/constant_manifest.rb +0 -126
  75. data/lib/tap/support/dependencies.rb +0 -54
  76. data/lib/tap/support/dependency.rb +0 -44
  77. data/lib/tap/support/executable.rb +0 -198
  78. data/lib/tap/support/executable_queue.rb +0 -125
  79. data/lib/tap/support/gems.rb +0 -43
  80. data/lib/tap/support/join.rb +0 -144
  81. data/lib/tap/support/joins.rb +0 -12
  82. data/lib/tap/support/joins/switch.rb +0 -27
  83. data/lib/tap/support/joins/sync_merge.rb +0 -38
  84. data/lib/tap/support/manifest.rb +0 -171
  85. data/lib/tap/support/minimap.rb +0 -90
  86. data/lib/tap/support/node.rb +0 -176
  87. data/lib/tap/support/parser.rb +0 -450
  88. data/lib/tap/support/schema.rb +0 -385
  89. data/lib/tap/support/shell_utils.rb +0 -67
  90. data/lib/tap/test.rb +0 -77
  91. data/lib/tap/test/assertions.rb +0 -38
  92. data/lib/tap/test/env_vars.rb +0 -29
  93. data/lib/tap/test/extensions.rb +0 -73
  94. data/lib/tap/test/file_test.rb +0 -362
  95. data/lib/tap/test/file_test_class.rb +0 -15
  96. data/lib/tap/test/regexp_escape.rb +0 -87
  97. data/lib/tap/test/script_test.rb +0 -46
  98. data/lib/tap/test/script_tester.rb +0 -115
  99. data/lib/tap/test/subset_test.rb +0 -260
  100. data/lib/tap/test/subset_test_class.rb +0 -99
  101. data/lib/tap/test/tap_test.rb +0 -109
  102. data/lib/tap/test/utils.rb +0 -231
@@ -1,15 +0,0 @@
1
- module Tap
2
- module Test
3
-
4
- # Class methods extending tests which include FileTest.
5
- module FileTestClass
6
-
7
- # The class-level test root (a Tap::Root)
8
- attr_accessor :class_test_root
9
-
10
- # An array of directories to be cleaned up by cleanup
11
- attr_accessor :cleanup_dirs
12
-
13
- end
14
- end
15
- end
@@ -1,87 +0,0 @@
1
- require 'tap/test/utils'
2
-
3
- module Tap
4
- module Test
5
-
6
- # RegexpEscape is a subclass of regexp that escapes all but the text in a
7
- # special escape sequence. This allows the creation of complex regexps
8
- # to match, for instance, console output.
9
- #
10
- # The RegexpEscape.escape (or equivalently the quote) method does the
11
- # work; all regexp-active characters are escaped except for characters
12
- # enclosed by ':.' and '.:' delimiters.
13
- #
14
- # RegexpEscape.escape('reg[exp]+ chars. are(quoted)') # => 'reg\[exp\]\+\ chars\.\ are\(quoted\)'
15
- # RegexpEscape.escape('these are not: :.a(b*)c.:') # => 'these\ are\ not:\ a(b*)c'
16
- #
17
- # In addition, all-period regexps are automatically upgraded to '.*?';
18
- # use the '.{n}' notation to specify n arbitrary characters.
19
- #
20
- # RegexpEscape.escape('_:..:_:...:_:....:') # => '_.*?_.*?_.*?'
21
- # RegexpEscape.escape(':..{1}.:') # => '.{1}'
22
- #
23
- # RegexpEscape instances are initialized using the escaped input string
24
- # and return the original string upon to_s.
25
- #
26
- # str = %q{
27
- # a multiline
28
- # :...:
29
- # example}
30
- # r = RegexpEscape.new(str)
31
- #
32
- # r =~ %q{
33
- # a multiline
34
- # matching
35
- # example} # => true
36
- #
37
- # r !~ %q{
38
- # a failing multiline
39
- # example} # => true
40
- #
41
- # r.to_s # => str
42
- #
43
- class RegexpEscape < Regexp
44
-
45
- # matches the escape sequence
46
- ESCAPE_SEQUENCE = /:\..*?\.:/
47
-
48
- class << self
49
-
50
- # Escapes regexp-active characters in str, except for character
51
- # delimited by ':.' and '.:'. See the class description for
52
- # details.
53
- def escape(str)
54
- substituents = []
55
- str.scan(ESCAPE_SEQUENCE) do
56
- regexp_str = $&[2...-2]
57
- regexp_str = ".*?" if regexp_str =~ /^\.*$/
58
- substituents << regexp_str
59
- end
60
- substituents << ""
61
-
62
- splits = str.split(ESCAPE_SEQUENCE).collect do |split|
63
- super(split)
64
- end
65
- splits << "" if splits.empty?
66
-
67
- splits.zip(substituents).to_a.flatten.join
68
- end
69
-
70
- # Same as escape.
71
- def quote(str)
72
- escape(str)
73
- end
74
- end
75
-
76
- def initialize(str, *options)
77
- super(RegexpEscape.escape(str), *options)
78
- @original_str = str
79
- end
80
-
81
- # Returns the original string for self
82
- def to_s
83
- @original_str
84
- end
85
- end
86
- end
87
- end
@@ -1,46 +0,0 @@
1
- require 'tap/test/assertions'
2
- require 'tap/test/script_tester'
3
- require 'tap/test/subset_test'
4
-
5
- module Tap
6
- module Test
7
- module ScriptTest
8
-
9
- def self.included(base)
10
- super
11
- base.send(:include, Tap::Test::SubsetTest)
12
- base.send(:include, Tap::Test::Assertions)
13
- end
14
-
15
- def default_command_path
16
- nil
17
- end
18
-
19
- def script_test(test_dir=method_root.root)
20
- subset_test("SCRIPT", "s") do
21
- Tap::Root.chdir(test_dir, true) do
22
- Utils.with_argv do
23
- puts "\n# == #{name}"
24
-
25
- cmd = ScriptTester.new(default_command_path, env_var('stepwise')) do |expected, result, msg|
26
- case expected
27
- when String
28
- assert_output_equal(expected, result, msg)
29
- when Regexp
30
- assert_alike(expected, result, msg)
31
- end
32
- end
33
-
34
- yield(cmd)
35
- end
36
- end
37
- end
38
- end
39
-
40
- end
41
- end
42
- end
43
-
44
-
45
-
46
-
@@ -1,115 +0,0 @@
1
- require 'tap/support/shell_utils'
2
- require 'tap/test/regexp_escape'
3
-
4
- module Tap
5
- module Test
6
-
7
- class ScriptTester
8
- include Tap::Support::ShellUtils
9
-
10
- # The command path for self, returned by to_s
11
- attr_accessor :command_path
12
-
13
- # An array of (command, message, expected, validation)
14
- # entries, representing the accumulated test commands.
15
- attr_reader :commands
16
-
17
- attr_reader :stepwise, :run_block
18
-
19
- NIL_VALIDATION = lambda {|*args|}
20
-
21
- def initialize(command_path=nil, stepwise=false, &run_block)
22
- @command_path = command_path
23
- @commands = []
24
- @stepwise = stepwise
25
- @run_block = run_block
26
- end
27
-
28
- # Splits the input string, collecting single-line commands
29
- # and expected results. Nil will be used as the expected
30
- # result if the result is whitespace, or not present.
31
- #
32
- # cmd = ScriptTest.new
33
- # cmd.split %Q{
34
- # % command one
35
- # expected text for command one
36
- # % command two
37
- # % command three
38
- # expected text for command three
39
- # }
40
- # # => [
41
- # # ["command one", "expected text for command one\n"],
42
- # # ["command two", nil],
43
- # # ["command three", "expected text for command three\n"]]
44
- #
45
- def split(str)
46
- str.split(/^%\s*/).collect do |s|
47
- next(nil) if s.strip.empty?
48
- command, expected = s.split(/\n/, 2)
49
- expected = nil if expected && expected.strip.empty?
50
- [command.strip, expected]
51
- end.compact
52
- end
53
-
54
- def time(msg, command)
55
- run([command, msg, nil, NIL_VALIDATION])
56
- end
57
-
58
- def check(msg, command, use_regexp_escapes=true, &validation)
59
- new_commands = split(command)
60
- commands = new_commands.collect do |cmd, expected|
61
- expected = RegexpEscape.new(expected) if expected && use_regexp_escapes
62
- [cmd, msg, expected, validation]
63
- end
64
-
65
- run(*commands)
66
- end
67
-
68
- def match(msg, command, regexp=nil, &validation)
69
- new_commands = split(command)
70
- commands = new_commands.collect do |cmd, expected|
71
- raise "expected text specified in match command" unless expected == nil
72
- [cmd, msg, regexp, validation]
73
- end
74
-
75
- run(*commands)
76
- end
77
-
78
- def run(*commands)
79
- commands.each_with_index do |(cmd, msg, expected, validation), i|
80
- unless expected || validation
81
- raise ArgumentError, "no expectation or validation set for: #{cmd}"
82
- end
83
-
84
- start = Time.now
85
- result = capture_sh(cmd) {|ok, status, tempfile_path| }
86
- elapsed = Time.now - start
87
-
88
- cmd_msg = commands.length > 1 ? "#{msg} (#{i})" : msg
89
- run_block.call(expected, result, %Q{#{cmd_msg}\n% #{cmd}}) if expected
90
- validation.call(result) if validation
91
-
92
- if stepwise
93
- print %Q{
94
- ------------------------------------
95
- %s
96
- > %s
97
- %s
98
- Time Elapsed: %.3fs} % [cmd_msg, cmd, result, elapsed]
99
-
100
- print "\nContinue? (y/n): "
101
- break if gets.strip =~ /^no?$/i
102
- else
103
- puts "%.3fs : %s" % [elapsed, cmd_msg]
104
- end
105
- end
106
- end
107
-
108
- # Returns the command path.
109
- def to_s
110
- command_path
111
- end
112
-
113
- end
114
- end
115
- end
@@ -1,260 +0,0 @@
1
- require 'benchmark'
2
- require 'tap/test/subset_test_class'
3
-
4
- module Tap
5
- module Test
6
-
7
- # SubsetTest provides methods to conditionally run tests, or to skip a
8
- # test suite entirely.
9
- #
10
- # require 'tap/test'
11
- #
12
- # class Test::Unit::TestCase
13
- # # only true if running on windows
14
- # condition(:windows) { match_platform?('mswin') }
15
- #
16
- # # only true if running on anything but windows
17
- # condition(:non_windows) { match_platform?('non_mswin') }
18
- # end
19
- #
20
- # class WindowsOnlyTest < Test::Unit::TestCase
21
- # skip_test unless satisfied?(:windows)
22
- # end
23
- #
24
- # Here the WindowsOnlyTest will only run on a Windows platform. Conditions
25
- # like these may be targeted at specific tests when only some tests need
26
- # to be skipped.
27
- #
28
- # class RunOnlyAFewTest < Test::Unit::TestCase
29
- # include SubsetTest
30
- #
31
- # def test_runs_all_the_time
32
- # assert true
33
- # end
34
- #
35
- # def test_runs_only_if_non_windows_condition_is_true
36
- # condition_test(:non_windows) { assert true }
37
- # end
38
- # end
39
- #
40
- # def test_runs_only_when_ENV_variable_EXTENDED_is_true
41
- # extended_test { assert true }
42
- # end
43
- #
44
- # def test_runs_only_when_ENV_variable_BENCHMARK_is_true
45
- # benchmark_test do |x|
46
- # x.report("init speed") { 10000.times { Object.new } }
47
- # end
48
- # end
49
- #
50
- # def test_runs_only_when_ENV_variable_CUSTOM_is_true
51
- # subset_test('CUSTOM') { assert true }
52
- # end
53
- # end
54
- #
55
- # In the example, the ENV variables EXTENDED, BENCHMARK, and CUSTOM act as
56
- # flags to run specific tests. If you're running your test using Rake, ENV
57
- # variables can be set from the command line like so:
58
- #
59
- # % rake test EXTENDED=true
60
- # % rake test BENCHMARK=true
61
- #
62
- # Since tap and rap can run rake tasks as well, these are equivalent:
63
- #
64
- # % tap run test EXTENDED=true
65
- # % rap test BENCHMARK=true
66
- #
67
- # In so far as SubsetTest is concerned, the environment variables are
68
- # case-insensitive. As in the example, additional ENV-based tests can be
69
- # defined using the subset_test method. To run all tests that get switched
70
- # using an ENV variable, set ALL=true.
71
- #
72
- # # also runs benchmark tests
73
- # % rap test BenchMark=true
74
- #
75
- # # runs all tests
76
- # % rap test all=true
77
- #
78
- # See {Test::Unit::TestCase}[link:classes/Test/Unit/TestCase.html] and
79
- # SubsetTestClass for more information.
80
- module SubsetTest
81
- include Tap::Test::EnvVars
82
-
83
- def self.included(base)
84
- super
85
- base.extend SubsetTestClass
86
- end
87
-
88
- # Returns true if the specified conditions are satisfied.
89
- def satisfied?(*condition_names)
90
- self.class.satisfied?(*condition_names)
91
- end
92
-
93
- # Returns true if the subset type (ex 'BENCHMARK') or 'ALL' is
94
- # specified in ENV.
95
- def run_subset?(type)
96
- self.class.run_subset?(type)
97
- end
98
-
99
- # Returns true if the input string matches the regexp specified in
100
- # env_var(type). Returns the default value if 'ALL' is specified in
101
- # ENV or type is not specified in ENV.
102
- def match_regexp?(type, str, default=true)
103
- return true if env_true?("ALL")
104
- return default unless env_var(type)
105
-
106
- str =~ Regexp.new(env_var(type)) ? true : false
107
- end
108
-
109
- # Platform-specific test. Useful for specifying test that should only
110
- # be run on a subset of platforms. Prints ' ' if the test is not run.
111
- #
112
- # def test_only_on_windows
113
- # platform_test('mswin') { ... }
114
- # end
115
- #
116
- # See SubsetTestClass#match_platform? for matching details.
117
- def platform_test(*platforms)
118
- if self.class.match_platform?(*platforms)
119
- yield
120
- else
121
- print ' '
122
- end
123
- end
124
-
125
- # Conditonal test. Only runs if the specified conditions are satisfied.
126
- # If no conditons are explicitly set, condition_test only runs if ALL
127
- # conditions for the test are satisfied.
128
- #
129
- # condition(:is_true) { true }
130
- # condition(:is_false) { false }
131
- #
132
- # def test_only_if_true_is_satisfied
133
- # condition_test(:is_true) { # runs }
134
- # end
135
- #
136
- # def test_only_if_all_conditions_are_satisfied
137
- # condition_test { # does not run }
138
- # end
139
- #
140
- # See SubsetTestClass#condition for more details.
141
- def condition_test(*condition_names)
142
- if self.class.unsatisfied_conditions(*condition_names).empty?
143
- yield
144
- else
145
- print ' '
146
- end
147
- end
148
-
149
- # Defines a subset test. The provided block will only run if:
150
- # - the subset type is specified in ENV
151
- # - the subset 'ALL' is specified in ENV
152
- # - the test method name matches the regexp provided in the
153
- # <TYPE>_TEST ENV variable
154
- #
155
- # Otherwise the block will be skipped and +skip+ will be printed in the
156
- # test output. By default skip is the first letter of +type+.
157
- #
158
- # For example, with these methods:
159
- #
160
- # def test_one
161
- # subset_test('CUSTOM') { assert true }
162
- # end
163
- #
164
- # def test_two
165
- # subset_test('CUSTOM') { assert true }
166
- # end
167
- #
168
- # Condition Tests that get run
169
- # ENV['ALL']=true test_one, test_two
170
- # ENV['CUSTOM']=true test_one, test_two
171
- # ENV['CUSTOM_TEST']=test_ test_one, test_two
172
- # ENV['CUSTOM_TEST']=test_one test_one
173
- # ENV['CUSTOM']=nil no tests get run
174
- #
175
- # If you're running your tests with rake (or rap), ENV variables may be
176
- # set from the command line.
177
- #
178
- # # all tests
179
- # % rap test all=true
180
- #
181
- # # custom subset tests
182
- # % rap test custom=true
183
- #
184
- # # just test_one (it is the only test
185
- # # matching the '.est_on.' pattern)
186
- # % rap test custom_test=.est_on.
187
- #
188
- def subset_test(type, skip=type[0..0].downcase)
189
- type = type.upcase
190
- type_test = "#{type}_TEST"
191
- if run_subset?(type) || env_var(type_test)
192
- if match_regexp?(type_test, name.to_s)
193
- yield
194
- else
195
- print skip
196
- end
197
- else
198
- print skip
199
- end
200
- end
201
-
202
- # Declares a subset_test for the ENV variable 'EXTENDED'.
203
- # Prints 'x' if the test is not run.
204
- #
205
- # def test_some_long_process
206
- # extended_test { ... }
207
- # end
208
- def extended_test(&block)
209
- subset_test("EXTENDED", "x", &block)
210
- end
211
-
212
- # Declares a subset_test for the ENV variable 'BENCHMARK'. If run,
213
- # benchmark_test sets up benchmarking using the Benchmark.bm method
214
- # using the input length and block. Prints 'b' if the test is not run.
215
- #
216
- # include Benchmark
217
- # def test_speed
218
- # benchmark_test(10) {|x| ... }
219
- # end
220
- def benchmark_test(length=10, &block)
221
- subset_test("BENCHMARK") do
222
- puts
223
- puts name
224
- Benchmark.bm(length, &block)
225
- end
226
- end
227
-
228
- # Declares a subset_test for the ENV variable 'PROMPT'. When run, prompts
229
- # the user for each input specified in array. Inputs will then be passed
230
- # as a hash to the block. Prints 'p' unless run.
231
- #
232
- # def test_requiring_inputs
233
- # prompt_test(:a, :b, :c) {|a, b, c| ... }
234
- # end
235
- #
236
- # If run, the command line prompt will be like the following:
237
- #
238
- # test_requiring_inputs: Enter values or 'skip'
239
- # a: avalue
240
- # b: bvalue
241
- # c: cvalue
242
- #
243
- # The block recieves ['avalue', 'bvalue', 'cvalue'].
244
- def prompt_test(*keys, &block)
245
- subset_test("PROMPT", "p") do
246
- puts "\n#{name} -- Enter values or 'skip'."
247
-
248
- values = keys.collect do |key|
249
- print "#{key}: "
250
- value = gets.strip
251
- flunk "skipped test" if value =~ /skip/i
252
- value
253
- end
254
-
255
- yield(*values)
256
- end
257
- end
258
- end
259
- end
260
- end