spec 5.0.14

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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +34 -0
  3. data/.gitignore +3 -0
  4. data/History.txt +911 -0
  5. data/Manifest.txt +26 -0
  6. data/README.txt +497 -0
  7. data/Rakefile +214 -0
  8. data/design_rationale.rb +52 -0
  9. data/lib/hoe/minitest.rb +26 -0
  10. data/lib/minitest/assertions.rb +649 -0
  11. data/lib/minitest/autorun.rb +12 -0
  12. data/lib/minitest/benchmark.rb +423 -0
  13. data/lib/minitest/expectations.rb +268 -0
  14. data/lib/minitest/hell.rb +11 -0
  15. data/lib/minitest/mock.rb +220 -0
  16. data/lib/minitest/parallel_each.rb +120 -0
  17. data/lib/minitest/pride.rb +4 -0
  18. data/lib/minitest/pride_plugin.rb +143 -0
  19. data/lib/minitest/spec.rb +292 -0
  20. data/lib/minitest/test.rb +272 -0
  21. data/lib/minitest/unit.rb +45 -0
  22. data/lib/minitest.rb +839 -0
  23. data/lib/spec.rb +3 -0
  24. data/readme.md +7 -0
  25. data/release_notes.md +49 -0
  26. data/spec.gemspec +36 -0
  27. data/test/manual/appium.rb +14 -0
  28. data/test/manual/appium_after_last.rb +24 -0
  29. data/test/manual/appium_before_first.rb +23 -0
  30. data/test/manual/assert.rb +61 -0
  31. data/test/manual/before_first_0.rb +27 -0
  32. data/test/manual/before_first_1.rb +29 -0
  33. data/test/manual/debug.rb +37 -0
  34. data/test/manual/do_end.rb +31 -0
  35. data/test/manual/raise.rb +61 -0
  36. data/test/manual/run2.rb +74 -0
  37. data/test/manual/run3.rb +91 -0
  38. data/test/manual/setup.rb +13 -0
  39. data/test/manual/simple.rb +19 -0
  40. data/test/manual/simple2.rb +20 -0
  41. data/test/manual/t.rb +11 -0
  42. data/test/manual/trace.rb +19 -0
  43. data/test/manual/trace2.rb +15 -0
  44. data/test/minitest/metametameta.rb +78 -0
  45. data/test/minitest/test_helper.rb +20 -0
  46. data/test/minitest/test_minitest_benchmark.rb +131 -0
  47. data/test/minitest/test_minitest_mock.rb +490 -0
  48. data/test/minitest/test_minitest_reporter.rb +270 -0
  49. data/test/minitest/test_minitest_spec.rb +794 -0
  50. data/test/minitest/test_minitest_unit.rb +1846 -0
  51. metadata +147 -0
data/lib/minitest.rb ADDED
@@ -0,0 +1,839 @@
1
+ require "optparse"
2
+ require 'chronic_duration'
3
+
4
+ ##
5
+ # :include: README.txt
6
+
7
+ module Minitest
8
+ VERSION = '5.0.14' # :nodoc:
9
+ DATE = '2013-08-07' # :nodoc:
10
+
11
+ @@installed_at_exit ||= false
12
+ @@after_run = []
13
+ @extensions = []
14
+
15
+ mc = (class << self; self; end)
16
+
17
+ ##
18
+ # Filter object for backtraces.
19
+
20
+ mc.send :attr_accessor, :backtrace_filter
21
+
22
+ ##
23
+ # Reporter object to be used for all runs.
24
+ #
25
+ # NOTE: This accessor is only available during setup, not during runs.
26
+
27
+ mc.send :attr_accessor, :reporter
28
+
29
+ ##
30
+ # Names of known extension plugins.
31
+
32
+ mc.send :attr_accessor, :extensions
33
+
34
+ @@trace_set = false
35
+ mc.send :attr_accessor, :trace_set
36
+
37
+ ##
38
+ # Registers Minitest to run at process exit
39
+
40
+ def self.autorun
41
+ at_exit {
42
+ next if $! and not $!.kind_of? SystemExit
43
+
44
+ exit_code = nil
45
+
46
+ at_exit {
47
+ @@after_run.reverse_each(&:call)
48
+ exit exit_code || false
49
+ }
50
+
51
+ exit_code = Minitest.run ARGV
52
+ } unless @@installed_at_exit
53
+ @@installed_at_exit = true
54
+ end
55
+
56
+ ##
57
+ # A simple hook allowing you to run a block of code after everything
58
+ # is done running. Eg:
59
+ #
60
+ # Minitest.after_run { p $debugging_info }
61
+
62
+ def self.after_run &block
63
+ @@after_run << block
64
+ end
65
+
66
+ def self.init_plugins options # :nodoc:
67
+ self.extensions.each do |name|
68
+ msg = "plugin_#{name}_init"
69
+ send msg, options if self.respond_to? msg
70
+ end
71
+ end
72
+
73
+ def self.load_plugins # :nodoc:
74
+ return unless self.extensions.empty?
75
+
76
+ seen = {}
77
+
78
+ Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
79
+ name = File.basename plugin_path, "_plugin.rb"
80
+
81
+ next if seen[name]
82
+ seen[name] = true
83
+
84
+ require plugin_path
85
+ self.extensions << name
86
+ end
87
+ end
88
+
89
+ ##
90
+ # This is the top-level run method. Everything starts from here. It
91
+ # tells each Runnable sub-class to run, and each of those are
92
+ # responsible for doing whatever they do.
93
+ #
94
+ # The overall structure of a run looks like this:
95
+ #
96
+ # Minitest.autorun
97
+ # Minitest.run(args)
98
+ # __run(reporter, options)
99
+ # Runnable.runnables.each
100
+ # runnable.run(reporter, options)
101
+ # self.runnable_methods.each
102
+ # self.new(runnable_method).run
103
+
104
+ def self.run args = []
105
+ self.load_plugins
106
+
107
+ options = process_args args
108
+
109
+ reporter = CompositeReporter.new
110
+ reporter << ProgressReporter.new(options[:io], options)
111
+ reporter << SummaryReporter.new(options[:io], options)
112
+
113
+ self.reporter = reporter # this makes it available to plugins
114
+ self.init_plugins options
115
+ self.reporter = nil # runnables shouldn't depend on the reporter, ever
116
+
117
+ reporter.start
118
+ __run reporter, options
119
+ reporter.report
120
+
121
+ reporter.passed?
122
+ end
123
+
124
+ ##
125
+ # Internal run method. Responsible for telling all Runnable
126
+ # sub-classes to run.
127
+ #
128
+ # NOTE: this method is redefined in parallel_each.rb, which is
129
+ # loaded if a Runnable calls parallelize_me!.
130
+
131
+ def self.__run reporter, options
132
+ Runnable.runnables.each do |runnable|
133
+ runnable.run reporter, options
134
+ end
135
+ end
136
+
137
+ ##
138
+ # Trace file source to :io (default $stdout)
139
+ #
140
+ # spec_opts = {}
141
+ #
142
+ # @param :trace [Array<String>] the files to trace
143
+ # @param :io [IO] io to print to
144
+ def self.trace_specs spec_opts
145
+ # ensure trace is set once
146
+ return if trace_set
147
+ self.trace_set = true
148
+
149
+ targets = []
150
+ files = {}
151
+ last_file = ''
152
+ last_line = -1
153
+
154
+ files_to_trace = spec_opts.fetch(:trace, []);
155
+ io = spec_opts.fetch(:io, $stdout)
156
+ color = spec_opts.fetch(:color, "\e[32m") # ANSI.green default
157
+ # target only existing readable files
158
+ files_to_trace.each { |f| targets.push(f) if File.exists?(f) && File
159
+ .readable?(f) }
160
+ return if targets.empty?
161
+
162
+ set_trace_func(lambda do |event, file, line, id, binding, classname|
163
+ return unless targets.include? file
164
+
165
+ # never repeat a line
166
+ return if file == last_file && line == last_line
167
+
168
+ file_sym = file.intern
169
+ files[file_sym] = IO.readlines(file) if files[file_sym].nil?
170
+ lines = files[file_sym]
171
+
172
+ # arrays are 0 indexed and line numbers start at one.
173
+ io.print color if color # ANSI code
174
+ io.puts lines[ line - 1]
175
+ io.print "\e[0m" if color # ANSI.clear
176
+
177
+ last_file = file
178
+ last_line = line
179
+
180
+ end)
181
+ end
182
+
183
+ ##
184
+ # Run specs. Does not print dots (ProgressReporter)
185
+ #
186
+ # spec_opts
187
+ # @param :io [Array<String>] defaults to $stdout
188
+ # @param :trace [Array<String>] files to trace
189
+
190
+ def self.run_specs spec_opts={}
191
+ options = { :io => spec_opts.fetch(:io, $stdout) }
192
+ reporter = Minitest::CompositeReporter.new
193
+ reporter << Minitest::SummaryReporter.new(options[:io], options)
194
+ reporter.start
195
+
196
+ trace_specs spec_opts
197
+
198
+ begin
199
+ Minitest.__run reporter, options
200
+ reporter.reporters.each { |r| r.report }
201
+ rescue Minitest::Runnable::ExitAfterFirstFail
202
+ # Minitest calls .report on exception
203
+ end
204
+ end
205
+
206
+ def self.process_args args = [] # :nodoc:
207
+ options = { :io => $stdout }
208
+ orig_args = args.dup
209
+
210
+ OptionParser.new do |opts|
211
+ opts.banner = "minitest options:"
212
+ opts.version = Minitest::VERSION
213
+
214
+ opts.on "-h", "--help", "Display this help." do
215
+ puts opts
216
+ exit
217
+ end
218
+
219
+ opts.on "-s", "--seed SEED", Integer, "Sets random seed" do |m|
220
+ options[:seed] = m.to_i
221
+ end
222
+
223
+ opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
224
+ options[:verbose] = true
225
+ end
226
+
227
+ opts.on "-n", "--name PATTERN","Filter run on /pattern/ or string." do |a|
228
+ options[:filter] = a
229
+ end
230
+
231
+ unless extensions.empty?
232
+ opts.separator ""
233
+ opts.separator "Known extensions: #{extensions.join(', ')}"
234
+
235
+ extensions.each do |meth|
236
+ msg = "plugin_#{meth}_options"
237
+ send msg, opts, options if self.respond_to?(msg)
238
+ end
239
+ end
240
+
241
+ begin
242
+ opts.parse! args
243
+ rescue OptionParser::InvalidOption => e
244
+ puts
245
+ puts e
246
+ puts
247
+ puts opts
248
+ exit 1
249
+ end
250
+
251
+ orig_args -= args
252
+ end
253
+
254
+ unless options[:seed] then
255
+ srand
256
+ options[:seed] = srand % 0xFFFF
257
+ orig_args << "--seed" << options[:seed].to_s
258
+ end
259
+
260
+ srand options[:seed]
261
+
262
+ options[:args] = orig_args.map { |s|
263
+ s =~ /[\s|&<>$()]/ ? s.inspect : s
264
+ }.join " "
265
+
266
+ options
267
+ end
268
+
269
+ def self.filter_backtrace bt # :nodoc:
270
+ backtrace_filter.filter bt
271
+ end
272
+
273
+ ##
274
+ # Represents anything "runnable", like Test, Spec, Benchmark, or
275
+ # whatever you can dream up.
276
+ #
277
+ # Subclasses of this are automatically registered and available in
278
+ # Runnable.runnables.
279
+
280
+ class Runnable
281
+ ##
282
+ # Number of assertions executed in this run.
283
+
284
+ attr_accessor :assertions
285
+
286
+ ##
287
+ # An assertion raised during the run, if any.
288
+
289
+ attr_accessor :failures
290
+
291
+ ##
292
+ # Name of the run.
293
+
294
+ def name
295
+ @NAME
296
+ end
297
+
298
+ ##
299
+ # Set the name of the run.
300
+
301
+ def name= o
302
+ @NAME = o
303
+ end
304
+
305
+ def self.inherited klass # :nodoc:
306
+ self.runnables << klass
307
+ super
308
+ end
309
+
310
+ ##
311
+ # Returns all instance methods matching the pattern +re+.
312
+
313
+ def self.methods_matching re
314
+ public_instance_methods(true).grep(re).map(&:to_s)
315
+ end
316
+
317
+ def self.reset # :nodoc:
318
+ @@runnables = []
319
+ end
320
+
321
+ reset
322
+
323
+ class ExitAfterFirstFail < RuntimeError; end
324
+
325
+ def self.check_failures result, reporter
326
+ if !result.failures.empty?
327
+ begin
328
+ reporter.reporters.each { |r| r.report }
329
+ ensure
330
+ raise ExitAfterFirstFail
331
+ end
332
+ end
333
+ end
334
+
335
+ ##
336
+ # Responsible for running all runnable methods in a given class,
337
+ # each in its own instance. Each instance is passed to the
338
+ # reporter to record.
339
+
340
+ def self.run reporter, options = {}
341
+ filter = options[:filter] || '/./'
342
+ filter = Regexp.new $1 if filter =~ /\/(.*)\//
343
+
344
+ filtered_methods = self.runnable_methods.find_all { |m|
345
+ filter === m || filter === "#{self}##{m}"
346
+ }
347
+
348
+ begin
349
+ # before_first
350
+ method1 = self.new(filtered_methods.first)
351
+ # run method and capture exceptions.
352
+ method1.capture_exceptions do
353
+ method1.before_first_method
354
+ end
355
+ # save exceptions to reporter and check for failures
356
+ with_info_handler reporter do
357
+ # only record if failures not empty, otherwise
358
+ # the count (runs) are messed up. each call to .record
359
+ # increases count by one.
360
+ if !method1.failures.empty?
361
+ reporter.record method1
362
+ check_failures method1, reporter
363
+ end
364
+
365
+ # run the other methods
366
+ filtered_methods.each do |method_name|
367
+ result = self.new(method_name).run
368
+ raise "#{self}#run _must_ return self" unless self === result
369
+ reporter.record result
370
+ check_failures result, reporter
371
+ end
372
+ end
373
+ ensure # ensure after last runs
374
+ # after_last
375
+ # init method1 again
376
+ method1 = self.new(filtered_methods.first)
377
+ method1.capture_exceptions do
378
+ method1.after_last_method
379
+ end
380
+ with_info_handler reporter do
381
+ if !method1.failures.empty?
382
+ reporter.record method1
383
+ check_failures method1, reporter
384
+ end
385
+ end
386
+ end
387
+ end
388
+
389
+ def before_first_method; end
390
+ def after_last_method; end
391
+
392
+ def self.with_info_handler reporter, &block # :nodoc:
393
+ handler = lambda do
394
+ unless reporter.passed? then
395
+ warn "Current results:"
396
+ warn ""
397
+ warn reporter.reporters.first
398
+ warn ""
399
+ end
400
+ end
401
+
402
+ on_signal "INFO", handler, &block
403
+ end
404
+
405
+ def self.on_signal name, action # :nodoc:
406
+ supported = Signal.list[name]
407
+
408
+ old_trap = trap name do
409
+ old_trap.call if old_trap.respond_to? :call
410
+ action.call
411
+ end if supported
412
+
413
+ yield
414
+ ensure
415
+ trap name, old_trap if supported
416
+ end
417
+
418
+ ##
419
+ # Each subclass of Runnable is responsible for overriding this
420
+ # method to return all runnable methods. See #methods_matching.
421
+
422
+ def self.runnable_methods
423
+ raise NotImplementedError, "subclass responsibility"
424
+ end
425
+
426
+ ##
427
+ # Returns all subclasses of Runnable.
428
+
429
+ def self.runnables
430
+ @@runnables
431
+ end
432
+
433
+ def marshal_dump # :nodoc:
434
+ [self.name, self.failures, self.assertions]
435
+ end
436
+
437
+ def marshal_load ary # :nodoc:
438
+ self.name, self.failures, self.assertions = ary
439
+ end
440
+
441
+ def failure # :nodoc:
442
+ self.failures.first
443
+ end
444
+
445
+ def initialize name # :nodoc:
446
+ self.name = name
447
+ self.failures = []
448
+ self.assertions = 0
449
+ end
450
+
451
+ ##
452
+ # Runs a single method. Needs to return self.
453
+
454
+ def run
455
+ raise NotImplementedError, "subclass responsibility"
456
+ end
457
+
458
+ ##
459
+ # Did this run pass?
460
+ #
461
+ # Note: skipped runs are not considered passing, but they don't
462
+ # cause the process to exit non-zero.
463
+
464
+ def passed?
465
+ raise NotImplementedError, "subclass responsibility"
466
+ end
467
+
468
+ ##
469
+ # Returns a single character string to print based on the result
470
+ # of the run. Eg ".", "F", or "E".
471
+
472
+ def result_code
473
+ raise NotImplementedError, "subclass responsibility"
474
+ end
475
+
476
+ ##
477
+ # Was this run skipped? See #passed? for more information.
478
+
479
+ def skipped?
480
+ raise NotImplementedError, "subclass responsibility"
481
+ end
482
+ end
483
+
484
+ ##
485
+ # Defines the API for Reporters. Subclass this and override whatever
486
+ # you want. Go nuts.
487
+
488
+ class AbstractReporter
489
+ ##
490
+ # Starts reporting on the run.
491
+
492
+ def start
493
+ end
494
+
495
+ ##
496
+ # Record a result and output the Runnable#result_code. Stores the
497
+ # result of the run if the run did not pass.
498
+
499
+ def record result
500
+ end
501
+
502
+ ##
503
+ # Outputs the summary of the run.
504
+
505
+ def report
506
+ end
507
+
508
+ ##
509
+ # Did this run pass?
510
+
511
+ def passed?
512
+ true
513
+ end
514
+ end
515
+
516
+ class Reporter < AbstractReporter # :nodoc:
517
+ ##
518
+ # The IO used to report.
519
+
520
+ attr_accessor :io
521
+
522
+ ##
523
+ # Command-line options for this run.
524
+
525
+ attr_accessor :options
526
+
527
+ def initialize io = $stdout, options = {} # :nodoc:
528
+ self.io = io
529
+ self.options = options
530
+ end
531
+ end
532
+
533
+ ##
534
+ # A very simple reporter that prints the "dots" during the run.
535
+ #
536
+ # This is added to the top-level CompositeReporter at the start of
537
+ # the run. If you want to change the output of minitest via a
538
+ # plugin, pull this out of the composite and replace it with your
539
+ # own.
540
+
541
+ class ProgressReporter < Reporter
542
+ def record result # :nodoc:
543
+ io.print "%s#%s = %.2f s = " % [result.class, result.name, result.time] if
544
+ options[:verbose]
545
+ io.print result.result_code
546
+ io.puts if options[:verbose]
547
+ end
548
+ end
549
+
550
+ ##
551
+ # A reporter that gathers statistics about a test run. Does not do
552
+ # any IO because meant to be used as a parent class for a reporter
553
+ # that does.
554
+ #
555
+ # If you want to create an entirely different type of output (eg,
556
+ # CI, HTML, etc), this is the place to start.
557
+
558
+ class StatisticsReporter < Reporter
559
+ # :stopdoc:
560
+ attr_accessor :assertions
561
+ attr_accessor :count
562
+ attr_accessor :results
563
+ attr_accessor :start_time
564
+ attr_accessor :total_time
565
+ attr_accessor :failures
566
+ attr_accessor :errors
567
+ attr_accessor :skips
568
+ # :startdoc:
569
+
570
+ def initialize io = $stdout, options = {} # :nodoc:
571
+ super
572
+
573
+ self.assertions = 0
574
+ self.count = 0
575
+ self.results = []
576
+ self.start_time = nil
577
+ self.total_time = nil
578
+ self.failures = nil
579
+ self.errors = nil
580
+ self.skips = nil
581
+ end
582
+
583
+ def passed? # :nodoc:
584
+ results.all?(&:skipped?)
585
+ end
586
+
587
+ def start # :nodoc:
588
+ self.start_time = Time.now
589
+ end
590
+
591
+ def record result # :nodoc:
592
+ self.count += 1
593
+ self.assertions += result.assertions
594
+
595
+ results << result if not result.passed? or result.skipped?
596
+ end
597
+
598
+ def report # :nodoc:
599
+ aggregate = results.group_by { |r| r.failure.class }
600
+ aggregate.default = [] # dumb. group_by should provide this
601
+
602
+ self.total_time = Time.now - start_time
603
+ self.failures = aggregate[Assertion].size
604
+ self.errors = aggregate[UnexpectedError].size
605
+ self.skips = aggregate[Skip].size
606
+ end
607
+ end
608
+
609
+ ##
610
+ # A reporter that prints the header, summary, and failure details at
611
+ # the end of the run.
612
+ #
613
+ # This is added to the top-level CompositeReporter at the start of
614
+ # the run. If you want to change the output of minitest via a
615
+ # plugin, pull this out of the composite and replace it with your
616
+ # own.
617
+
618
+ class SummaryReporter < StatisticsReporter
619
+ # :stopdoc:
620
+ attr_accessor :sync
621
+ attr_accessor :old_sync
622
+ # :startdoc:
623
+
624
+ def start # :nodoc:
625
+ super
626
+
627
+ self.sync = io.respond_to? :"sync=" # stupid emacs
628
+ self.old_sync, io.sync = io.sync, true if self.sync
629
+ end
630
+
631
+ def report # :nodoc:
632
+ super
633
+
634
+ io.sync = self.old_sync
635
+
636
+ io.puts # finish the dots
637
+ io.puts
638
+ io.puts statistics
639
+ io.puts aggregated_results
640
+ io.puts summary
641
+ end
642
+
643
+ def statistics # :nodoc:
644
+ "Finished in #{ChronicDuration.output(total_time.round) || '0s'}"
645
+ end
646
+
647
+ def aggregated_results # :nodoc:
648
+ filtered_results = results.dup
649
+ filtered_results.reject!(&:skipped?) unless options[:verbose]
650
+
651
+ filtered_results.each_with_index.map do |result, i|
652
+ "\n%3d) %s" % [i+1, result]
653
+ end.join("\n") + "\n"
654
+ end
655
+
656
+ def summary # :nodoc:
657
+ "%d runs, %d assertions, %d failures, %d errors, %d skips" %
658
+ [count, assertions, failures, errors, skips]
659
+ end
660
+ end
661
+
662
+ ##
663
+ # Dispatch to multiple reporters as one.
664
+
665
+ class CompositeReporter < AbstractReporter
666
+ ##
667
+ # The list of reporters to dispatch to.
668
+
669
+ attr_accessor :reporters
670
+
671
+ def initialize *reporters # :nodoc:
672
+ self.reporters = reporters
673
+ end
674
+
675
+ ##
676
+ # Add another reporter to the mix.
677
+
678
+ def << reporter
679
+ self.reporters << reporter
680
+ end
681
+
682
+ def passed? # :nodoc:
683
+ self.reporters.all?(&:passed?)
684
+ end
685
+
686
+ def start # :nodoc:
687
+ self.reporters.each(&:start)
688
+ end
689
+
690
+ def record result # :nodoc:
691
+ self.reporters.each do |reporter|
692
+ reporter.record result
693
+ end
694
+ end
695
+
696
+ def report # :nodoc:
697
+ self.reporters.each(&:report)
698
+ end
699
+ end
700
+
701
+ ##
702
+ # Represents run failures.
703
+
704
+ class Assertion < Exception
705
+ def error # :nodoc:
706
+ self
707
+ end
708
+
709
+ ##
710
+ # Where was this run before an assertion was raised?
711
+
712
+ def location
713
+ last_before_assertion = ""
714
+ self.backtrace.reverse_each do |s|
715
+ break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
716
+ last_before_assertion = s
717
+ end
718
+ last_before_assertion.sub(/:in .*$/, "")
719
+ end
720
+
721
+ def result_code # :nodoc:
722
+ result_label[0, 1]
723
+ end
724
+
725
+ def result_label # :nodoc:
726
+ "Failure"
727
+ end
728
+ end
729
+
730
+ ##
731
+ # Assertion raised when skipping a run.
732
+
733
+ class Skip < Assertion
734
+ def result_label # :nodoc:
735
+ "Skipped"
736
+ end
737
+ end
738
+
739
+ ##
740
+ # Assertion wrapping an unexpected error that was raised during a run.
741
+
742
+ class UnexpectedError < Assertion
743
+ attr_accessor :exception # :nodoc:
744
+
745
+ def initialize exception # :nodoc:
746
+ super
747
+ self.exception = exception
748
+ end
749
+
750
+ def backtrace # :nodoc:
751
+ self.exception.backtrace
752
+ end
753
+
754
+ def error # :nodoc:
755
+ self.exception
756
+ end
757
+
758
+ def message # :nodoc:
759
+ bt = Minitest::filter_backtrace(self.backtrace).join "\n "
760
+ "#{self.exception.class}: #{self.exception.message}\n #{bt}"
761
+ end
762
+
763
+ def result_label # :nodoc:
764
+ "Error"
765
+ end
766
+ end
767
+
768
+ ##
769
+ # Provides a simple set of guards that you can use in your tests
770
+ # to skip execution if it is not applicable. These methods are
771
+ # mixed into Test as both instance and class methods so you
772
+ # can use them inside or outside of the test methods.
773
+ #
774
+ # def test_something_for_mri
775
+ # skip "bug 1234" if jruby?
776
+ # # ...
777
+ # end
778
+ #
779
+ # if windows? then
780
+ # # ... lots of test methods ...
781
+ # end
782
+
783
+ module Guard
784
+
785
+ ##
786
+ # Is this running on jruby?
787
+
788
+ def jruby? platform = RUBY_PLATFORM
789
+ "java" == platform
790
+ end
791
+
792
+ ##
793
+ # Is this running on maglev?
794
+
795
+ def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
796
+ "maglev" == platform
797
+ end
798
+
799
+ ##
800
+ # Is this running on mri?
801
+
802
+ def mri? platform = RUBY_DESCRIPTION
803
+ /^ruby/ =~ platform
804
+ end
805
+
806
+ ##
807
+ # Is this running on rubinius?
808
+
809
+ def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
810
+ "rbx" == platform
811
+ end
812
+
813
+ ##
814
+ # Is this running on windows?
815
+
816
+ def windows? platform = RUBY_PLATFORM
817
+ /mswin|mingw/ =~ platform
818
+ end
819
+ end
820
+
821
+ class BacktraceFilter # :nodoc:
822
+ def filter bt
823
+ return ["No backtrace"] unless bt
824
+
825
+ return bt.dup if $DEBUG
826
+
827
+ new_bt = bt.take_while { |line| line !~ /lib\/minitest/ }
828
+ new_bt = bt.select { |line| line !~ /lib\/minitest/ } if new_bt.empty?
829
+ new_bt = bt.dup if new_bt.empty?
830
+
831
+ new_bt
832
+ end
833
+ end
834
+
835
+ self.backtrace_filter = BacktraceFilter.new
836
+ end
837
+
838
+ require "minitest/test"
839
+ require "minitest/unit" unless defined?(MiniTest) # compatibility layer only