test 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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