tap 0.12.4 → 0.17.0

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