test 0.2.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.
@@ -0,0 +1,53 @@
1
+ require 'test/reporters/abstract_hash'
2
+
3
+ module Test::Reporters
4
+
5
+ # TAP-Y Reporter
6
+ #
7
+ class Tapy < AbstractHash
8
+
9
+ #
10
+ def initialize(runner)
11
+ require 'json'
12
+ super(runner)
13
+ end
14
+
15
+ #
16
+ def begin_suite(suite)
17
+ puts super(suite).to_yaml
18
+ end
19
+
20
+ #
21
+ def begin_case(test_case)
22
+ puts super(test_case).to_yaml
23
+ end
24
+
25
+ #
26
+ def pass(test) #, backtrace=nil)
27
+ puts super(test).to_yaml
28
+ end
29
+
30
+ #
31
+ def fail(test, exception)
32
+ puts super(test, exception).to_yaml
33
+ end
34
+
35
+ #
36
+ def error(test, exception)
37
+ puts super(test, exception).to_yaml
38
+ end
39
+
40
+ #
41
+ def todo(test, exception)
42
+ puts super(test, exception).to_yaml
43
+ end
44
+
45
+ #
46
+ def end_suite(suite)
47
+ puts super(suite).to_yaml
48
+ puts "..."
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,51 @@
1
+ require 'test/reporters/abstract_hash'
2
+
3
+ module Test::Reporters
4
+
5
+ # Test Reporter is used to test Ruby Test itself.
6
+ #
7
+ class Test < AbstractHash
8
+
9
+ #
10
+ def initialize(runner)
11
+ super(runner)
12
+ end
13
+
14
+ #
15
+ def begin_suite(suite)
16
+ super(suite)
17
+ end
18
+
19
+ #
20
+ def begin_case(test_case)
21
+ super(test_case)
22
+ end
23
+
24
+ #
25
+ def pass(test) #, backtrace=nil)
26
+ super(test)
27
+ end
28
+
29
+ #
30
+ def fail(test, exception)
31
+ super(test, exception)
32
+ end
33
+
34
+ #
35
+ def error(test, exception)
36
+ super(test, exception)
37
+ end
38
+
39
+ #
40
+ def todo(test, exception)
41
+ super(test, exception)
42
+ end
43
+
44
+ #
45
+ def end_suite(suite)
46
+ super(suite)
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,342 @@
1
+ module Test
2
+
3
+ # Runner will need the Recorder and Pending classes.
4
+ if RUBY_VERSION < '1.9'
5
+ require 'test/recorder'
6
+ require 'test/core_ext'
7
+ else
8
+ require_relative 'recorder'
9
+ require_relative 'core_ext'
10
+ end
11
+
12
+ $TEST_SUITE = [] unless defined?($TEST_SUITE)
13
+
14
+ # The Test::Runner class handles the execution of tests.
15
+ #
16
+ class Runner
17
+
18
+ # Default report is in the old "dot-progress" format.
19
+ DEFAULT_FORMAT = 'dotprogress'
20
+
21
+ # Exceptions that are not caught by test runner.
22
+ OPEN_ERRORS = [NoMemoryError, SignalException, Interrupt, SystemExit]
23
+
24
+ # / / / D E F A U L T S / / /
25
+
26
+ # Default test suite ($TEST_SUITE).
27
+ def self.suite
28
+ $TEST_SUITE
29
+ end
30
+
31
+ # Default list of test files to load.
32
+ def self.files
33
+ @files ||= []
34
+ end
35
+
36
+ #
37
+ def self.format
38
+ @format || DEFAULT_FORMAT
39
+ end
40
+
41
+ #
42
+ def self.format=(format)
43
+ @format = format
44
+ end
45
+
46
+ #
47
+ def self.verbose
48
+ @verbose
49
+ end
50
+
51
+ #
52
+ def self.verbose=(boolean)
53
+ @verbose = !!boolean
54
+ end
55
+
56
+ # Default description match for filtering tests.
57
+ def self.match
58
+ @match ||= []
59
+ end
60
+
61
+ # Default selection of tags for filtering tests.
62
+ def self.tags
63
+ @tags ||= []
64
+ end
65
+
66
+ # Default selection of units for filtering tests.
67
+ def self.units
68
+ @unit ||= []
69
+ end
70
+
71
+ #
72
+ def self.hard
73
+ @hard
74
+ end
75
+
76
+ #
77
+ def self.hard=(boolean)
78
+ @hard = !!boolean
79
+ end
80
+
81
+ # / / / A T T R I B U T E S / / /
82
+
83
+ # Test suite to run. This is a list of compliant test units and test cases.
84
+ attr :suite
85
+
86
+ # Test files to load.
87
+ attr :files
88
+
89
+ # Reporter format name, or name fragment, used to look up reporter class.
90
+ attr :format
91
+
92
+ #
93
+ def format=(name)
94
+ @format = name.to_s
95
+ end
96
+
97
+ # Matching text used to filter which tests are run.
98
+ attr :match
99
+
100
+ # Selected tags used to filter which tests are run.
101
+ attr :tags
102
+
103
+ # List of units with which to filter tests. It is an array of strings
104
+ # which are matched against module, class and method names.
105
+ attr :units
106
+
107
+ # Show extra details in reports.
108
+ def verbose?
109
+ @verbose
110
+ end
111
+
112
+ #
113
+ def verbose=(boolean)
114
+ @verbose = !!boolean
115
+ end
116
+
117
+ # Use "hard" test mode?
118
+ def hard?
119
+ @hard
120
+ end
121
+
122
+ #
123
+ def hard=(boolean)
124
+ @hard = !!boolean
125
+ end
126
+
127
+ # New Runner.
128
+ #
129
+ # @param [Array] suite
130
+ # A list of compliant tests/testcases.
131
+ #
132
+ def initialize(options={}, &block)
133
+ @suite = options[:suite] || self.class.suite
134
+ @files = options[:files] || self.class.files
135
+ @format = options[:format] || self.class.format
136
+ @tags = options[:tags] || self.class.tags
137
+ @units = options[:units] || self.class.units
138
+ @match = options[:match] || self.class.match
139
+ @verbose = options[:verbose] || self.class.verbose
140
+ @hard = options[:hard] || self.class.hard
141
+
142
+ block.call(self) if block
143
+ end
144
+
145
+ # The reporter to use for ouput.
146
+ attr :reporter
147
+
148
+ # Record pass, fail, error, pending and omitted tests.
149
+ attr :recorder
150
+
151
+ # Array of observers, typically this just contains the recorder and
152
+ # reporter instances.
153
+ attr :observers
154
+
155
+ # Run test suite.
156
+ #
157
+ # @return [Boolean]
158
+ # That the tests ran without error or failure.
159
+ #
160
+ def run
161
+ files_resolved.each do |file|
162
+ require file
163
+ end
164
+
165
+ @reporter = reporter_load(format)
166
+ @recorder = Recorder.new
167
+ @observers = [@reporter, @recorder]
168
+
169
+ #cd_tmp do
170
+ observers.each{ |o| o.begin_suite(suite) }
171
+ run_thru(suite)
172
+ observers.each{ |o| o.end_suite(suite) }
173
+ #end
174
+
175
+ recorder.success?
176
+ end
177
+
178
+ private
179
+
180
+ #
181
+ def run_thru(list)
182
+ list.each do |t|
183
+ if t.respond_to?(:each)
184
+ run_case(t)
185
+ elsif t.respond_to?(:call)
186
+ run_test(t)
187
+ else
188
+ #run_note(t) ?
189
+ end
190
+ end
191
+ end
192
+
193
+ # Run a test case.
194
+ #
195
+ def run_case(tcase)
196
+ if tcase.respond_to?(:skip?) && tcase.skip?
197
+ return observers.each{ |o| o.skip_case(tcase) }
198
+ end
199
+
200
+ observers.each{ |o| o.begin_case(tcase) }
201
+
202
+ if tcase.respond_to?(:call)
203
+ tcase.call do
204
+ run_thru( select(tcase) )
205
+ end
206
+ else
207
+ run_thru( select(tcase) )
208
+ end
209
+
210
+ observers.each{ |o| o.end_case(tcase) }
211
+ end
212
+
213
+ # Run a test.
214
+ #
215
+ # @param [Object] test
216
+ # The test to run, must repsond to #call.
217
+ #
218
+ def run_test(test)
219
+ if test.respond_to?(:skip?) && test.skip?
220
+ return observers.each{ |o| o.skip_test(test) }
221
+ end
222
+
223
+ observers.each{ |o| o.begin_test(test) }
224
+ begin
225
+ success = test.call
226
+ if hard? && !success # TODO: separate run_test method to speed things up?
227
+ raise Assertion, "failure of #{test}"
228
+ else
229
+ observers.each{ |o| o.pass(test) }
230
+ end
231
+ rescue *OPEN_ERRORS => exception
232
+ raise exception
233
+ rescue NotImplementedError => exception
234
+ if exception.assertion?
235
+ observers.each{ |o| o.omit(test, exception) }
236
+ else
237
+ observers.each{ |o| o.todo(test, exception) }
238
+ end
239
+ rescue Exception => exception
240
+ if exception.assertion?
241
+ observers.each{ |o| o.fail(test, exception) }
242
+ else
243
+ observers.each{ |o| o.error(test, exception) }
244
+ end
245
+ end
246
+ observers.each{ |o| o.end_test(test) }
247
+ end
248
+
249
+ # TODO: Make sure this filtering code is correct for the complex
250
+ # condition that that ordered testcases can't have their tests
251
+ # filtered individually (since they may depend on one another).
252
+
253
+ # Filter cases based on selection criteria.
254
+ #
255
+ # @return [Array] selected test cases
256
+ def select(cases)
257
+ selected = []
258
+ if cases.respond_to?(:ordered?) && cases.ordered?
259
+ cases.each do |tc|
260
+ selected << tc
261
+ end
262
+ else
263
+ cases.each do |tc|
264
+ next if tc.respond_to?(:skip?) && tc.skip?
265
+ next if !match.empty? && !match.any?{ |m| m =~ tc.to_s }
266
+
267
+ if !units.empty?
268
+ next unless tc.respond_to?(:unit)
269
+ next unless units.find{ |u| tc.unit.start_with?(u) }
270
+ end
271
+
272
+ if !tags.empty?
273
+ next unless tc.respond_to?(:tags)
274
+ tc_tags = [tc.tags].flatten.map{ |t| t.to_s }
275
+ next if (tags & tc_tags).empty?
276
+ end
277
+
278
+ selected << tc
279
+ end
280
+ end
281
+ selected
282
+ end
283
+
284
+ # Get a reporter instance be name fragment.
285
+ #
286
+ # @return [Reporter::Abstract]
287
+ # The test reporter instance.
288
+ #
289
+ def reporter_load(format)
290
+ format = DEFAULT_REPORT_FORMAT unless format
291
+ format = format.to_s.downcase
292
+ name = reporter_list.find{ |r| /^#{format}/ =~ r }
293
+
294
+ raise "unsupported report format" unless format
295
+
296
+ require "test/reporters/#{name}"
297
+ reporter = Test::Reporters.const_get(name.capitalize)
298
+ reporter.new(self)
299
+ end
300
+
301
+ # Returns a list of available report types.
302
+ #
303
+ # @return [Array<String>]
304
+ # The names of available reporters.
305
+ #
306
+ def reporter_list
307
+ list = Dir[File.dirname(__FILE__) + '/reporters/*.rb']
308
+ list = list.map{ |r| File.basename(r).chomp('.rb') }
309
+ list = list.reject{ |r| /^abstract/ =~ r }
310
+ list.sort
311
+ end
312
+
313
+ # Files can be globs and directories which need to be
314
+ # resolved to a list of files.
315
+ #
316
+ def files_resolved
317
+ list = files.flatten
318
+ list = list.map{ |f| Dir[f] }.flatten
319
+ list = list.map{ |f| File.directory?(f) ? Dir[File.join(f, '**/*.rb')] : f }
320
+ list = list.flatten.uniq
321
+ list = list.map{ |f| File.expand_path(f) }
322
+ list
323
+ end
324
+
325
+ =begin
326
+ # TODO ?
327
+ def cd_tmp(&block)
328
+ dir = Test::Config.root + '/tmp'
329
+ if Directory.exist?(dir)
330
+ dir = File.join(dir, 'test')
331
+ FileUtils.mkdir(dir) unless File.exist?(dir)
332
+ else
333
+ dir = File.join(Dir.tmpdir)
334
+ end
335
+
336
+ Dir.chdir(dir, &block)
337
+ end
338
+ =end
339
+
340
+ end
341
+
342
+ end
Binary file