tap 0.7.9 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/History +28 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README +71 -43
  4. data/Rakefile +81 -64
  5. data/Tutorial +235 -0
  6. data/bin/tap +80 -44
  7. data/lib/tap.rb +41 -12
  8. data/lib/tap/app.rb +243 -246
  9. data/lib/tap/file_task.rb +357 -118
  10. data/lib/tap/generator.rb +88 -29
  11. data/lib/tap/generator/generators/config/config_generator.rb +4 -2
  12. data/lib/tap/generator/generators/config/templates/config.erb +1 -2
  13. data/lib/tap/generator/generators/file_task/file_task_generator.rb +3 -18
  14. data/lib/tap/generator/generators/file_task/templates/task.erb +22 -15
  15. data/lib/tap/generator/generators/file_task/templates/test.erb +13 -2
  16. data/{test/test/inference_methods/test_assert_files_exist/input/input_1.txt → lib/tap/generator/generators/generator/USAGE} +0 -0
  17. data/lib/tap/generator/generators/generator/generator_generator.rb +21 -0
  18. data/lib/tap/generator/generators/generator/templates/generator.erb +23 -0
  19. data/lib/tap/generator/generators/generator/templates/usage.erb +1 -0
  20. data/{test/test/inference_methods/test_assert_files_exist/input/input_2.txt → lib/tap/generator/generators/package/USAGE} +0 -0
  21. data/lib/tap/generator/generators/package/package_generator.rb +38 -0
  22. data/lib/tap/generator/generators/package/templates/package.erb +186 -0
  23. data/lib/tap/generator/generators/root/root_generator.rb +14 -9
  24. data/lib/tap/generator/generators/root/templates/Rakefile +20 -14
  25. data/{test/test/inference_methods/test_infer_glob/expected/file.yml → lib/tap/generator/generators/root/templates/ReadMe.txt} +0 -0
  26. data/lib/tap/generator/generators/root/templates/tap.yml +82 -0
  27. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -1
  28. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +2 -1
  29. data/{test/test/inference_methods/test_infer_glob/expected/file_1.txt → lib/tap/generator/generators/script/USAGE} +0 -0
  30. data/lib/tap/generator/generators/script/script_generator.rb +17 -0
  31. data/lib/tap/generator/generators/script/templates/script.erb +42 -0
  32. data/lib/tap/generator/generators/task/task_generator.rb +1 -1
  33. data/lib/tap/generator/generators/task/templates/task.erb +24 -16
  34. data/lib/tap/generator/generators/task/templates/test.erb +13 -17
  35. data/lib/tap/generator/generators/workflow/templates/task.erb +10 -10
  36. data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
  37. data/lib/tap/generator/generators/workflow/workflow_generator.rb +3 -18
  38. data/lib/tap/root.rb +108 -146
  39. data/lib/tap/script.rb +362 -0
  40. data/lib/tap/script/console.rb +28 -0
  41. data/lib/tap/script/destroy.rb +13 -1
  42. data/lib/tap/script/generate.rb +13 -1
  43. data/lib/tap/script/run.rb +100 -57
  44. data/lib/tap/support/batch_queue.rb +0 -3
  45. data/lib/tap/support/logger.rb +6 -3
  46. data/lib/tap/support/rake.rb +54 -0
  47. data/lib/tap/support/task_configuration.rb +169 -0
  48. data/lib/tap/support/tdoc.rb +198 -0
  49. data/lib/tap/support/tdoc/config_attr.rb +338 -0
  50. data/lib/tap/support/tdoc/tdoc_html_generator.rb +38 -0
  51. data/lib/tap/support/tdoc/tdoc_html_template.rb +42 -0
  52. data/lib/tap/support/versions.rb +33 -1
  53. data/lib/tap/task.rb +339 -227
  54. data/lib/tap/test.rb +86 -128
  55. data/lib/tap/test/env_vars.rb +16 -5
  56. data/lib/tap/test/file_methods.rb +373 -0
  57. data/lib/tap/test/subset_methods.rb +299 -180
  58. data/lib/tap/version.rb +2 -1
  59. data/lib/tap/workflow.rb +2 -0
  60. data/test/app/lib/app_test_task.rb +1 -0
  61. data/test/app_test.rb +327 -83
  62. data/test/check/binding_eval.rb +23 -0
  63. data/test/check/define_method_check.rb +22 -0
  64. data/test/check/dependencies_check.rb +175 -0
  65. data/test/check/inheritance_check.rb +22 -0
  66. data/test/file_task_test.rb +524 -291
  67. data/test/{test/inference_methods/test_infer_glob/expected/file_2.txt → root/glob/one.txt} +0 -0
  68. data/test/root/glob/two.txt +0 -0
  69. data/test/root_test.rb +330 -262
  70. data/test/script_test.rb +194 -0
  71. data/test/support/audit_test.rb +5 -2
  72. data/test/support/combinator_test.rb +10 -10
  73. data/test/support/rake_test.rb +35 -0
  74. data/test/support/task_configuration_test.rb +272 -0
  75. data/test/support/tdoc_test.rb +363 -0
  76. data/test/support/templater_test.rb +2 -2
  77. data/test/support/versions_test.rb +32 -0
  78. data/test/tap_test_helper.rb +39 -0
  79. data/test/task_base_test.rb +115 -0
  80. data/test/task_class_test.rb +56 -4
  81. data/test/task_execute_test.rb +29 -0
  82. data/test/task_test.rb +89 -70
  83. data/test/test/env_vars_test.rb +48 -0
  84. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/file.txt +0 -0
  85. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/folder/file.txt +0 -0
  86. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/file.txt +0 -0
  87. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/folder/file.txt +0 -0
  88. data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
  89. data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
  90. data/test/test/file_methods/test_assert_output_files_equal/expected/one.txt +1 -0
  91. data/test/test/file_methods/test_assert_output_files_equal/expected/two.txt +1 -0
  92. data/test/test/file_methods/test_assert_output_files_equal/input/one.txt +1 -0
  93. data/test/test/file_methods/test_assert_output_files_equal/input/two.txt +1 -0
  94. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_1.txt +0 -0
  95. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_2.txt +0 -0
  96. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_1.txt +0 -0
  97. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_2.txt +0 -0
  98. data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
  99. data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
  100. data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
  101. data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
  102. data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
  103. data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
  104. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_1.yml +0 -0
  105. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_2.yml +0 -0
  106. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_1.yml +0 -0
  107. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_2.yml +0 -0
  108. data/test/test/file_methods_test.rb +204 -0
  109. data/test/test/subset_methods_test.rb +93 -33
  110. data/test/test/test_assert_expected_result_files/expected/task/name/a.txt +1 -0
  111. data/test/test/test_assert_expected_result_files/expected/task/name/b.txt +1 -0
  112. data/test/test/test_assert_expected_result_files/input/a.txt +1 -0
  113. data/test/test/test_assert_expected_result_files/input/b.txt +1 -0
  114. data/test/test/test_file_task_test/expected/one.txt +1 -0
  115. data/test/test/test_file_task_test/expected/two.txt +1 -0
  116. data/test/test/test_file_task_test/input/one.txt +1 -0
  117. data/test/test/test_file_task_test/input/two.txt +1 -0
  118. data/test/test_test.rb +143 -3
  119. data/test/workflow_test.rb +2 -0
  120. data/vendor/rails_generator.rb +56 -0
  121. data/vendor/rails_generator/base.rb +263 -0
  122. data/vendor/rails_generator/commands.rb +581 -0
  123. data/vendor/rails_generator/generated_attribute.rb +42 -0
  124. data/vendor/rails_generator/lookup.rb +209 -0
  125. data/vendor/rails_generator/manifest.rb +53 -0
  126. data/vendor/rails_generator/options.rb +143 -0
  127. data/vendor/rails_generator/scripts.rb +83 -0
  128. data/vendor/rails_generator/scripts/destroy.rb +7 -0
  129. data/vendor/rails_generator/scripts/generate.rb +7 -0
  130. data/vendor/rails_generator/scripts/update.rb +12 -0
  131. data/vendor/rails_generator/simple_logger.rb +46 -0
  132. data/vendor/rails_generator/spec.rb +44 -0
  133. metadata +180 -196
  134. data/lib/tap/generator/generators/root/templates/app.yml +0 -19
  135. data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +0 -4
  136. data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +0 -26
  137. data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
  138. data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +0 -57
  139. data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +0 -108
  140. data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +0 -40
  141. data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +0 -21
  142. data/lib/tap/generator/generators/root/templates/server/config/environment.rb +0 -60
  143. data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +0 -5
  144. data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +0 -53
  145. data/lib/tap/script/server.rb +0 -12
  146. data/lib/tap/support/rap.rb +0 -38
  147. data/lib/tap/test/inference_methods.rb +0 -298
  148. data/test/task/config/task_with_config.yml +0 -1
  149. data/test/test/inference_methods_test.rb +0 -311
@@ -5,25 +5,106 @@ require 'tap/test/env_vars'
5
5
 
6
6
  module Test # :nodoc:
7
7
  module Unit # :nodoc:
8
- class TestCase
8
+ # Methods extending TestCase. See the TestTutorial for more information.
9
+ class TestCase
9
10
  class << self
11
+ include Tap::Test::EnvVars
12
+
13
+ # Passes conditions to subclass
14
+ def inherited(subclass) # :nodoc:
15
+ super
16
+ subclass_conditions = conditions.inject({}) do |memo, (key, value)|
17
+ memo.update(key => (value.dup rescue value))
18
+ end
19
+ subclass.instance_variable_set("@conditions", subclass_conditions)
20
+
21
+ # subclass_inputs = prompt_inputs.inject({}) do |memo, (key, value)|
22
+ # memo.update(key => (value.dup rescue value))
23
+ # end
24
+ # subclass.instance_variable_set("@prompt_inputs", subclass_inputs)
25
+ end
26
+
27
+ # Experimental -- The idea is to provide a way to prompt once for inputs
28
+ # that get used multiple times in a test. Perhaps create accessors
29
+ # automatically?
30
+
31
+ # def prompt_inputs
32
+ # @prompt_inputs ||= {}
33
+ # end
34
+
35
+ # def require_inputs(*keys, &block)
36
+ # if run_subset?("PROMPT")
37
+ # puts "\n#{name} requires inputs -- Enter values or 'skip'."
38
+
39
+ # argv = ARGV.dup
40
+ # begin
41
+ # ARGV.clear
42
+ # keys.collect do |key|
43
+ # print "#{key}: "
44
+ # value = gets.strip
45
+ # if value =~ /skip/i
46
+ # skip_test "missing inputs"
47
+ # break
48
+ # end
49
+ # prompt_inputs[key] = value
50
+ # end
51
+ # ensure
52
+ # ARGV.clear
53
+ # ARGV.concat(argv)
54
+ # end
55
+ # else
56
+ # skip_test "prompt test"
57
+ # end
58
+ # end
59
+
60
+ #
61
+ # conditions
62
+ #
10
63
 
11
- # Causes a whole test suite to require one of the listed platforms
12
- # in order to run. See match_platform? for details.
64
+ # A hash of defined conditions
65
+ def conditions
66
+ @conditions ||= {}
67
+ end
68
+
69
+ # Defines a condition block and associated message.
70
+ # Raises an error if no condition block is given.
71
+ def condition(name, msg=nil, &block)
72
+ raise "no condition block given" unless block_given?
73
+ conditions[name.to_sym] = [msg, block]
74
+ end
75
+
76
+ # Returns true if the all blocks for the named conditions return true.
13
77
  #
14
- # Simply declare like:
78
+ # condition(:is_true) { true }
79
+ # condition(:is_false) { false }
80
+ # satisfied?(:is_true) # => true
81
+ # satisfied?(:is_true, :is_false) # => false
15
82
  #
16
- # class Test::Unit::TestCase
17
- # require_platform 'mswin'
18
- # end
19
- def require_platform(*platforms, &block)
20
- @platforms = platforms
21
- yield if block_given? && match_platform?(*@platforms)
83
+ def satisfied?(*conditions)
84
+ unsatisfied_conditions(*conditions).empty?
22
85
  end
23
-
86
+
87
+ # Returns an array of the unsatified conditions. Raises
88
+ # an error if the named condition has not been defined.
89
+ #
90
+ # condition(:is_true) { true }
91
+ # condition(:is_false) { false }
92
+ # unsatisfied_conditions(:is_true, :is_false) # => [:is_false]
93
+ #
94
+ def unsatisfied_conditions(*conditions)
95
+ conditions = self.conditions.keys if conditions.empty?
96
+ unsatified = []
97
+ conditions.each do |condition|
98
+ raise "Unknown condition: #{condition}" unless self.conditions.has_key?(condition)
99
+ unsatified << condition unless (self.conditions[condition.to_sym].last.call() ? true : false)
100
+ end
101
+ unsatified
102
+ end
103
+
24
104
  # Returns true if RUBY_PLATFORM matches one of the specfied
25
- # platforms. Use the prefix 'non_' to specify any plaform but the
26
- # specified platform (ex: 'non_mswin')
105
+ # platforms. Use the prefix 'non_' to specify any plaform
106
+ # except the specified platform (ex: 'non_mswin'). Returns
107
+ # true if no platforms are specified.
27
108
  #
28
109
  # Some common platforms:
29
110
  # - mswin:: Windows
@@ -39,8 +120,44 @@ module Test # :nodoc:
39
120
 
40
121
  true
41
122
  end
123
+
124
+ # Returns true if the subset type or 'ALL' is specified in ENV
125
+ def run_subset?(type)
126
+ env_true?(type) || env_true?("ALL") ? true : false
127
+ end
128
+
129
+ #
130
+ # Methods for skipping a test suite
131
+ #
132
+ attr_accessor :run_test_suite
133
+
134
+ # Returns run_test_suite, or true if run_test_suite is not set.
135
+ def run_test_suite?
136
+ run_test_suite.nil? ? true : run_test_suite
137
+ end
138
+
139
+ # Causes a test suite to be skipped. If a message is given, it will
140
+ # print and notify the user the test suite has been skipped.
141
+ def skip_test(msg=nil)
142
+ @run_test_suite = false
143
+
144
+ # experimental -- perhaps use this so that a test can be skipped
145
+ # for multiple reasons?
146
+ (@skip_messages ||= []) << msg unless msg.nil?
147
+ end
42
148
 
43
149
  alias :original_suite :suite
150
+
151
+ # Modifies the default suite method to include/exclude tests based on platform.
152
+ def suite # :nodoc:
153
+ if run_test_suite?
154
+ original_suite
155
+ else
156
+ @skip_messages ||= []
157
+ puts "Skipping #{name}: #{@skip_messages.join(', ')}" unless @skip_messages.empty?
158
+ Test::Unit::TestSuite.new(name)
159
+ end
160
+ end
44
161
  end
45
162
  end
46
163
  end
@@ -48,196 +165,149 @@ end
48
165
 
49
166
  module Tap
50
167
  module Test
168
+
169
+ # Ideally you always run all of your tests and they all run and pass everywhere. In
170
+ # practice it's useful to suppress the execution of some tests -- long running tests,
171
+ # tests specific for a given platform, or tests that depend on some condition, such
172
+ # as the version of some third-party software your code interacts with.
173
+ #
174
+ # SubsetMethods extends TestCase with methods for defining conditions that can be
175
+ # used to conditionally perform some action, or skip a test suite entirely. When
176
+ # you include SubsetMethods within a specific TestCase, additional methods are
177
+ # made available for filtering tests.
178
+ #
179
+ # require 'tap/test/subset_methods'
180
+ # class Test::Unit::TestCase
181
+ # # only true if running on windows
182
+ # condition(:windows) { match_platform?('mswin') }
183
+ #
184
+ # # only true if running on anything but windows
185
+ # condition(:non_windows) { match_platform?('non_mswin') }
186
+ # end
187
+ #
188
+ # class AfterHoursTest < Test::Unit::TestCase
189
+ # # only true between 6pm and 6am
190
+ # # (maybe you're not allowed to tie up a computer until after hours)
191
+ # condition(:afterhours) { Time.now > 18 || Time.now < 6 }
192
+ #
193
+ # skip_test unless satisfied?(:windows, :afterhours)
194
+ # end
195
+ #
196
+ # AfterHoursTest will only run between the hours of 6pm and 6am, on a Windows platform.
197
+ # These conditions can be used in specific tests, when only some tests need to be skipped.
198
+ #
199
+ # class RunOnlyAFewTest < Test::Unit::TestCase
200
+ # include SubsetMethods
201
+ # include Benchmark
202
+ #
203
+ # def test_runs_all_the_time
204
+ # assert true
205
+ # end
206
+ #
207
+ # def test_runs_only_if_afterhours_condition_is_true
208
+ # condition_test(:afterhours) do
209
+ # ...
210
+ # end
211
+ # end
212
+ #
213
+ # def test_runs_only_when_EXTENDED_is_true
214
+ # extended_test do
215
+ # ...
216
+ # end
217
+ # end
218
+ #
219
+ # def test_runs_only_when_BENCHMARK_is_true
220
+ # benchmark_test do |x|
221
+ # x.report("init speed") { 10000.times { Object.new } }
222
+ # end
223
+ # end
224
+ # end
225
+ #
226
+ # In the example, EXTENDED and BENCHMARK refer to environment (ENV) variables.
227
+ # ENV variables can be set from the command line like so:
228
+ #
229
+ # % tap run test extended=true
230
+ # % tap run test BENCHMARK=true
231
+ #
232
+ # In so far as SubsetMethods is concerned, the environment variables are case-insensitive.
233
+ # To run all tests that get switched using an environment variable, set ALL=true.
234
+ #
235
+ # == Class Methods
236
+ #
237
+ # See Test::Unit::TestCase for documentation of the class methods added by SubsetMethods
51
238
  module SubsetMethods
52
239
  include Tap::Test::EnvVars
240
+
241
+ def satisfied?(*conditions)
242
+ self.class.satisfied?(*conditions)
243
+ end
53
244
 
54
- def self.suite
55
- if match_platform?(*@platforms)
56
- original_suite
57
- else
58
- # if platforms are specfied for the tests and the platform does NOT
59
- # match, remake the suite to skip all tests.
60
- method_names = public_instance_methods(true)
61
- suite = Test::Unit::TestSuite.new(name)
62
- method_names.each do |method_name|
63
- catch(:invalid_test) do
64
- suite << new('on_test_skipped') if method_name =~ /^test/
65
- end
66
- end
67
- suite
68
- end
245
+ # Returns true if the subset type or 'ALL' is specified in ENV
246
+ def run_subset?(type)
247
+ self.class.run_subset?(type)
69
248
  end
70
249
 
71
- # Platform-specific test. Useful for specifying test that should only be run on,
72
- # for instance, windows. See match_platform? for details.
73
- def platform_test(*platforms, &block)
74
- if self.class.match_platform?(*platforms)
75
- yield
76
- else
77
- print ' '
78
- end
79
- end
80
-
81
- # Subset test declaration for extended tests -- type: EXTENDED
82
- # Prints 'x' unless run.
83
- def extended_test(&block)
84
- subset_test("EXTENDED", "x", &block)
85
- end
86
-
87
- # Subset test declaration for benchmark tests -- type: BENCHMARK
88
- # Prints 'b' unless run.
89
- def benchmark_test(length=10, &block)
90
- subset_test("BENCHMARK") do
91
- puts
92
- puts calling_method
93
- bm(length) do |x|
94
- yield(x)
95
- end
96
- end
250
+ # Returns true if the pretty-print string for obj matches the regexp specified in env_var(type).
251
+ # Returns the default value if 'ALL' is specified in ENV or type is not specified in ENV.
252
+ def match_regexp?(type, obj, default=true)
253
+ return true if env_true?("ALL")
254
+ return default unless env(type)
255
+
256
+ PP.singleline_pp(obj, '') =~ Regexp.new(env(type)) ? true : false
97
257
  end
98
258
 
99
- # Case tests take a hash of testcases and expected values. Each pair in the hash will
100
- # be passed to the block if type CASE_TEST is specified. Individual cases tests can be
101
- # specified by providing a regexp in CASE; the testcase will run if the pretty-print of
102
- # the testcase matches the provided regexp. Example:
259
+ # Platform-specific test. Useful for specifying test that should only
260
+ # be run on a subset of platforms. Prints ' ' if the test is not run.
103
261
  #
104
- # case_test(
105
- # [1,2,3] => 'an array testcase',
106
- # '[1, 2, 3]' => 'the pretty print of the array',
107
- # 'another testcase' => 'some third testcase'
108
- # ).do |testcase, expected|
109
- # ...your test code...
262
+ # def test_only_on_windows
263
+ # platform_test('mswin') { ... }
110
264
  # end
111
265
  #
112
- # ENV['CASE_TEST']=true => all tests run
113
- # ENV['CASE']='1, 2, 3' => first two tests run
114
- # ENV['CASE']='another' => only last test runs
115
- def case_test(hash, &block)
116
- if match_regexp?("CASE_TEST", calling_method)
117
- hash.each_pair do |testcase, expected|
118
- yield(testcase, expected) if match_regexp?("CASE", testcase)
119
- end
266
+ # See TestCase#match_platform? for matching details.
267
+ def platform_test(*platforms)
268
+ if self.class.match_platform?(*platforms)
269
+ yield
270
+ else
271
+ print ' '
120
272
  end
121
273
  end
122
-
123
- # Acase tests take an array of testcases. Each testcase in the array will
124
- # be passed to the block if type CASE_TEST is specified. Individual cases tests can be
125
- # specified by providing a regexp in CASE; the testcase will run if the pretty-print of
126
- # the testcase matches the provided regexp. Example:
274
+
275
+ # Conditonal test. Only runs if the named conditions are satisfied.
276
+ # If no conditons are explicitly set, only runs if all conditions
277
+ # are satisfied.
278
+ #
279
+ # condition(:is_true) { true }
280
+ # condition(:is_false) { false }
127
281
  #
128
- # case_test(
129
- # [1,2,3] ,
130
- # '[1, 2, 3]',
131
- # 'another testcase'
132
- # ).do |testcase|
133
- # ...your test code...
282
+ # def test_only_if_true_is_satisfied
283
+ # condition_test(:is_true) { # runs }
134
284
  # end
135
285
  #
136
- # ENV['CASE_TEST']=true => all tests run
137
- # ENV['CASE']='1, 2, 3' => first two tests run
138
- # ENV['CASE']='another' => only last test runs
139
- def acase_test(*array)
140
- if match_regexp?("CASE_TEST", calling_method)
141
- array.each do |testcase|
142
- yield(testcase) if match_regexp?("CASE", testcase)
143
- end
144
- end
145
- end
146
-
147
-
148
- # Subset test declaration for prompt tests -- type: PROMPT
149
- # Prints 'p' unless run.
150
- #
151
- # Useful for tests that require user input. If run, then this test will
152
- # prompt the user for an input for each item in the array. The results
153
- # are collected in a hash and passed to the block.
154
- #
155
- # Example:
156
- #
157
- # def test_something_important
158
- # prompt_test(:a, :b, :c).do |config|
159
- # ...your test code...
160
- # end
286
+ # def test_only_if_all_conditions_are_satisfied
287
+ # condition_test { # does not run }
161
288
  # end
162
289
  #
163
- # (if run, prompts print to $stdout the following:)
164
- # test_something_important: Enter values or 'skip'
165
- # a: # => enter 'avalue'
166
- # b: # => enter 'bvalue'
167
- # c: # => enter 'cvalue'
168
- #
169
- # # config => {:a => 'avalue', :b => 'bvalue', :c => 'cvalue'}
170
- def prompt_test(*array, &block)
171
- subset_test("PROMPT", "p") do
172
- puts "\n#{calling_method} -- Enter values or 'skip'."
173
-
174
- config = {}
175
- array.each do |key|
176
- print "#{key}: "
177
- value = gets.strip
178
- flunk "skipped test" if value =~ /skip/i
179
-
180
- config[key] = value
181
- end
182
-
183
- yield(config)
290
+ # See TestCase#condition for more details.
291
+ def condition_test(*conditions)
292
+ unsatisfied_conditions = self.class.unsatisfied_conditions(*conditions)
293
+ if unsatisfied_conditions.empty?
294
+ yield
295
+ else
296
+ print ' '
184
297
  end
185
298
  end
186
-
187
- protected
188
-
189
- # Formats the input by using singleline_pp
190
- def spp(input, str='')
191
- PP.singleline_pp(input, str)
192
- end
193
-
194
- # Required for platform tests
195
- def on_test_skipped
196
- print ' '
197
- end
198
-
199
- # Returns true if the env_var(var) is set and matches /^true%/i
200
- def env_true?(var)
201
- env(var) && env(var) =~ /^true$/i
202
- end
203
-
204
- # Returns true if the subset type or 'ALL' is specified in ENV
205
- def run_subset?(type)
206
- env_true?(type) || env_true?("ALL") ? true : false
207
- end
208
-
209
- # Returns true if the pretty-print string for obj matches the regexp specified in env_var(type).
210
- # Returns the default value if 'ALL' is specified in ENV or type is not specified in ENV.
211
- def match_regexp?(type, obj, default=true)
212
- return true if env_true?("ALL")
213
- return default unless env(type)
214
-
215
- spp(obj) =~ Regexp.new(env(type)) ? true : false
216
- end
217
-
218
- # Calling method iterates over the call stack, and returns the first calling
219
- # method name that matches the input pattern (by default /^test/)
220
- def calling_method(pattern=/^test/)
221
- 0.upto(caller.length) do |i|
222
- caller[i] =~ /:in `(.*)'$/
223
- method_name = $1
224
- return method_name if method_name =~ pattern
225
- end
226
299
 
227
- ''
228
- end
229
-
230
300
  # Basic method for a subset test. The provided block will run if:
231
301
  # - The subset type or 'ALL' is specified in ENV
232
302
  # - The calling method matches the regexp provided in the "TYPE_TEST" ENV variable
233
303
  #
234
304
  # Otherwise the block will be skipped and +skip+ will be printed. By default skip
235
305
  # is the first letter of +type+.
236
- def subset_test(type, skip=type[0..0].downcase, &block)
306
+ def subset_test(type, skip=type[0..0].downcase)
237
307
  type = type.upcase
238
308
  type_test = "#{type}_TEST"
239
309
  if run_subset?(type) || env(type_test)
240
- if match_regexp?(type_test, calling_method)
310
+ if match_regexp?(type_test, method_name)
241
311
  yield
242
312
  else
243
313
  print skip
@@ -247,12 +317,61 @@ module Tap
247
317
  end
248
318
  end
249
319
 
250
- # Runs only if the first argument causes an 'if' statement to return true.
251
- def switch_test(run_test, skip="!", &block)
252
- if run_test
253
- yield
254
- else
255
- print skip
320
+ # Declares a subset_test for the ENV variable 'EXTENDED'.
321
+ # Prints 'x' if the test is not run.
322
+ #
323
+ # def test_some_long_process
324
+ # extended_test { ... }
325
+ # end
326
+ def extended_test(&block)
327
+ subset_test("EXTENDED", "x", &block)
328
+ end
329
+
330
+ # Declares a subset_test for the ENV variable 'BENCHMARK'. If run,
331
+ # benchmark_test sets up benchmarking using the bm method using the
332
+ # input length and block. As a result you MUST 'include Benchmark'
333
+ # in the test class. Prints 'b' if the test is not run.
334
+ #
335
+ # include Benchmark
336
+ # def test_speed
337
+ # benchmark_test(10) {|x| ... }
338
+ # end
339
+ def benchmark_test(length=10, &block)
340
+ subset_test("BENCHMARK") do
341
+ puts
342
+ puts method_name
343
+ bm(length, &block)
344
+ end
345
+ end
346
+
347
+ # Declares a subset_test for the ENV variable 'PROMPT'. When run, prompts
348
+ # the user for each input specified in array. Inputs will then be passed
349
+ # as a hash to the block. Prints 'p' unless run.
350
+ #
351
+ # def test_requiring_inputs
352
+ # prompt_test(:a, :b, :c) {|a, b, c| ... }
353
+ # end
354
+ #
355
+ # If run, the command line prompt will be like the following:
356
+ #
357
+ # test_requiring_inputs: Enter values or 'skip'
358
+ # a: avalue
359
+ # b: bvalue
360
+ # c: cvalue
361
+ #
362
+ # The block recieves ['avalue', 'bvalue', 'cvalue'].
363
+ def prompt_test(*keys, &block)
364
+ subset_test("PROMPT", "p") do
365
+ puts "\n#{method_name} -- Enter values or 'skip'."
366
+
367
+ values = keys.collect do |key|
368
+ print "#{key}: "
369
+ value = gets.strip
370
+ flunk "skipped test" if value =~ /skip/i
371
+ value
372
+ end
373
+
374
+ yield(*values)
256
375
  end
257
376
  end
258
377
  end