minitest-spec-rails-tu-shim 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/COPYING.txt ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/LICENSE.txt ADDED
@@ -0,0 +1,3 @@
1
+ * Please read COPYING.txt
2
+ * Redistribution of lib/test source directory from Ruby 1.9.3p392.
3
+ https://github.com/ruby/ruby/tree/v1_9_3_392/lib/test
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # minitest-spec-rails-tu-shim
2
+
3
+ Test::Unit compatability for MiniTest For Ruby 1.8 for use with [minitest-spec-rails](https://github.com/metaskills/minitest-spec-rails).
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile if you
9
+
10
+ gem 'minitest-spec-rails-tu-shim'
11
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/test/unit.rb ADDED
@@ -0,0 +1,640 @@
1
+ # test/unit compatibility layer using minitest.
2
+
3
+ require 'minitest/unit'
4
+ require 'test/unit/assertions'
5
+ require 'test/unit/testcase'
6
+ require 'optparse'
7
+
8
+ module Test
9
+ module Unit
10
+ TEST_UNIT_IMPLEMENTATION = 'test/unit compatibility layer using minitest'
11
+
12
+ module RunCount
13
+ @@run_count = 0
14
+
15
+ def self.have_run?
16
+ @@run_count.nonzero?
17
+ end
18
+
19
+ def run(*)
20
+ @@run_count += 1
21
+ super
22
+ end
23
+
24
+ def run_once
25
+ return if have_run?
26
+ return if $! # don't run if there was an exception
27
+ yield
28
+ end
29
+ module_function :run_once
30
+ end
31
+
32
+ module Options
33
+ def initialize(*, &block)
34
+ @init_hook = block
35
+ @options = nil
36
+ super(&nil)
37
+ end
38
+
39
+ def option_parser
40
+ @option_parser ||= OptionParser.new
41
+ end
42
+
43
+ def process_args(args = [])
44
+ return @options if @options
45
+ orig_args = args.dup
46
+ options = {}
47
+ opts = option_parser
48
+ setup_options(opts, options)
49
+ opts.parse!(args)
50
+ orig_args -= args
51
+ args = @init_hook.call(args, options) if @init_hook
52
+ non_options(args, options)
53
+ @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " "
54
+ @options = options
55
+ if @options[:parallel]
56
+ @files = args
57
+ @args = orig_args
58
+ end
59
+ options
60
+ end
61
+
62
+ private
63
+ def setup_options(opts, options)
64
+ opts.separator 'minitest options:'
65
+ opts.version = MiniTest::Unit::VERSION
66
+
67
+ opts.on '-h', '--help', 'Display this help.' do
68
+ puts opts
69
+ exit
70
+ end
71
+
72
+ opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m|
73
+ options[:seed] = m
74
+ end
75
+
76
+ opts.on '-v', '--verbose', "Verbose. Show progress processing files." do
77
+ options[:verbose] = true
78
+ self.verbose = options[:verbose]
79
+ end
80
+
81
+ opts.on '-n', '--name PATTERN', "Filter test names on pattern." do |a|
82
+ options[:filter] = a
83
+ end
84
+
85
+ opts.on '--jobs-status [TYPE]', [:normal, :replace],
86
+ "Show status of jobs every file; Disabled when --jobs isn't specified." do |type|
87
+ options[:job_status] = type || :normal
88
+ end
89
+
90
+ opts.on '-j N', '--jobs N', "Allow run tests with N jobs at once" do |a|
91
+ if /^t/ =~ a
92
+ options[:testing] = true # For testing
93
+ options[:parallel] = a[1..-1].to_i
94
+ else
95
+ options[:parallel] = a.to_i
96
+ end
97
+ end
98
+
99
+ opts.on '--no-retry', "Don't retry running testcase when --jobs specified" do
100
+ options[:no_retry] = true
101
+ end
102
+
103
+ opts.on '--ruby VAL', "Path to ruby; It'll have used at -j option" do |a|
104
+ options[:ruby] = a.split(/ /).reject(&:empty?)
105
+ end
106
+
107
+ opts.on '-q', '--hide-skip', 'Hide skipped tests' do
108
+ options[:hide_skip] = true
109
+ end
110
+ end
111
+
112
+ def non_options(files, options)
113
+ begin
114
+ require "rbconfig"
115
+ rescue LoadError
116
+ warn "#{caller(1)[0]}: warning: Parallel running disabled because can't get path to ruby; run specify with --ruby argument"
117
+ options[:parallel] = nil
118
+ else
119
+ options[:ruby] ||= RbConfig.ruby
120
+ end
121
+
122
+ true
123
+ end
124
+ end
125
+
126
+ module GlobOption
127
+ include Options
128
+
129
+ @@testfile_prefix = "test"
130
+
131
+ def setup_options(parser, options)
132
+ super
133
+ parser.on '-b', '--basedir=DIR', 'Base directory of test suites.' do |dir|
134
+ options[:base_directory] = dir
135
+ end
136
+ parser.on '-x', '--exclude PATTERN', 'Exclude test files on pattern.' do |pattern|
137
+ (options[:reject] ||= []) << pattern
138
+ end
139
+ end
140
+
141
+ def non_options(files, options)
142
+ paths = [options.delete(:base_directory), nil].uniq
143
+ if reject = options.delete(:reject)
144
+ reject_pat = Regexp.union(reject.map {|r| /#{r}/ })
145
+ end
146
+ files.map! {|f|
147
+ f = f.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
148
+ ((paths if /\A\.\.?(?:\z|\/)/ !~ f) || [nil]).any? do |prefix|
149
+ if prefix
150
+ path = f.empty? ? prefix : "#{prefix}/#{f}"
151
+ else
152
+ next if f.empty?
153
+ path = f
154
+ end
155
+ if !(match = Dir["#{path}/**/#{@@testfile_prefix}_*.rb"]).empty?
156
+ if reject
157
+ match.reject! {|n|
158
+ n[(prefix.length+1)..-1] if prefix
159
+ reject_pat =~ n
160
+ }
161
+ end
162
+ break match
163
+ elsif !reject or reject_pat !~ f and File.exist? path
164
+ break path
165
+ end
166
+ end or
167
+ raise ArgumentError, "file not found: #{f}"
168
+ }
169
+ files.flatten!
170
+ super(files, options)
171
+ end
172
+ end
173
+
174
+ module LoadPathOption
175
+ include Options
176
+
177
+ def setup_options(parser, options)
178
+ super
179
+ parser.on '-Idirectory', 'Add library load path' do |dirs|
180
+ dirs.split(':').each { |d| $LOAD_PATH.unshift d }
181
+ end
182
+ end
183
+ end
184
+
185
+ module GCStressOption
186
+ def setup_options(parser, options)
187
+ super
188
+ parser.on '--[no-]gc-stress', 'Set GC.stress as true' do |flag|
189
+ options[:gc_stress] = flag
190
+ end
191
+ end
192
+
193
+ def non_options(files, options)
194
+ if options.delete(:gc_stress)
195
+ MiniTest::Unit::TestCase.class_eval do
196
+ oldrun = instance_method(:run)
197
+ define_method(:run) do |runner|
198
+ begin
199
+ gc_stress, GC.stress = GC.stress, true
200
+ oldrun.bind(self).call(runner)
201
+ ensure
202
+ GC.stress = gc_stress
203
+ end
204
+ end
205
+ end
206
+ end
207
+ super
208
+ end
209
+ end
210
+
211
+ module RequireFiles
212
+ def non_options(files, options)
213
+ return false if !super
214
+ result = false
215
+ files.each {|f|
216
+ d = File.dirname(path = File.expand_path(f))
217
+ unless $:.include? d
218
+ $: << d
219
+ end
220
+ begin
221
+ require path unless options[:parallel]
222
+ result = true
223
+ rescue LoadError
224
+ puts "#{f}: #{$!}"
225
+ end
226
+ }
227
+ result
228
+ end
229
+ end
230
+
231
+ class Runner < MiniTest::Unit
232
+ include Test::Unit::Options
233
+ include Test::Unit::GlobOption
234
+ include Test::Unit::LoadPathOption
235
+ include Test::Unit::GCStressOption
236
+ include Test::Unit::RunCount
237
+
238
+ class Worker
239
+ def self.launch(ruby,args=[])
240
+ io = IO.popen([*ruby,
241
+ "#{File.dirname(__FILE__)}/unit/parallel.rb",
242
+ *args], "rb+")
243
+ new(io, io.pid, :waiting)
244
+ end
245
+
246
+ def initialize(io, pid, status)
247
+ @io = io
248
+ @pid = pid
249
+ @status = status
250
+ @file = nil
251
+ @real_file = nil
252
+ @loadpath = []
253
+ @hooks = {}
254
+ end
255
+
256
+ def puts(*args)
257
+ @io.puts(*args)
258
+ end
259
+
260
+ def run(task,type)
261
+ @file = File.basename(task).gsub(/\.rb/,"")
262
+ @real_file = task
263
+ begin
264
+ puts "loadpath #{[Marshal.dump($:-@loadpath)].pack("m").gsub("\n","")}"
265
+ @loadpath = $:.dup
266
+ puts "run #{task} #{type}"
267
+ @status = :prepare
268
+ rescue Errno::EPIPE
269
+ died
270
+ rescue IOError
271
+ raise unless ["stream closed","closed stream"].include? $!.message
272
+ died
273
+ end
274
+ end
275
+
276
+ def hook(id,&block)
277
+ @hooks[id] ||= []
278
+ @hooks[id] << block
279
+ self
280
+ end
281
+
282
+ def read
283
+ res = (@status == :quit) ? @io.read : @io.gets
284
+ res && res.chomp
285
+ end
286
+
287
+ def close
288
+ @io.close
289
+ self
290
+ end
291
+
292
+ def died(*additional)
293
+ @status = :quit
294
+ @io.close
295
+
296
+ call_hook(:dead,*additional)
297
+ end
298
+
299
+ def to_s
300
+ if @file
301
+ "#{@pid}=#{@file}"
302
+ else
303
+ "#{@pid}:#{@status.to_s.ljust(7)}"
304
+ end
305
+ end
306
+
307
+ attr_reader :io, :pid
308
+ attr_accessor :status, :file, :real_file, :loadpath
309
+
310
+ private
311
+
312
+ def call_hook(id,*additional)
313
+ @hooks[id] ||= []
314
+ @hooks[id].each{|hook| hook[self,additional] }
315
+ self
316
+ end
317
+
318
+ end
319
+
320
+ class << self; undef autorun; end
321
+
322
+ @@stop_auto_run = false
323
+ def self.autorun
324
+ at_exit {
325
+ Test::Unit::RunCount.run_once {
326
+ exit(Test::Unit::Runner.new.run(ARGV) || true)
327
+ } unless @@stop_auto_run
328
+ } unless @@installed_at_exit
329
+ @@installed_at_exit = true
330
+ end
331
+
332
+ def after_worker_down(worker, e=nil, c=false)
333
+ return unless @options[:parallel]
334
+ return if @interrupt
335
+ if e
336
+ b = e.backtrace
337
+ warn "#{b.shift}: #{e.message} (#{e.class})"
338
+ STDERR.print b.map{|s| "\tfrom #{s}"}.join("\n")
339
+ end
340
+ @need_quit = true
341
+ warn ""
342
+ warn "Some worker was crashed. It seems ruby interpreter's bug"
343
+ warn "or, a bug of test/unit/parallel.rb. try again without -j"
344
+ warn "option."
345
+ warn ""
346
+ STDERR.flush
347
+ exit c
348
+ end
349
+
350
+ def jobs_status
351
+ return unless @options[:job_status]
352
+ puts "" unless @options[:verbose]
353
+ status_line = @workers.map(&:to_s).join(" ")
354
+ if @options[:job_status] == :replace and $stdout.tty?
355
+ @terminal_width ||=
356
+ begin
357
+ require 'io/console'
358
+ $stdout.winsize[1]
359
+ rescue LoadError, NoMethodError
360
+ ENV["COLUMNS"].to_i.nonzero? || 80
361
+ end
362
+ @jstr_size ||= 0
363
+ del_jobs_status
364
+ $stdout.flush
365
+ print status_line[0...@terminal_width]
366
+ $stdout.flush
367
+ @jstr_size = [status_line.size, @terminal_width].min
368
+ else
369
+ puts status_line
370
+ end
371
+ end
372
+
373
+ def del_jobs_status
374
+ return unless @options[:job_status] == :replace && @jstr_size.nonzero?
375
+ print "\r"+" "*@jstr_size+"\r"
376
+ end
377
+
378
+ def after_worker_quit(worker)
379
+ return unless @options[:parallel]
380
+ return if @interrupt
381
+ @workers.delete(worker)
382
+ @dead_workers << worker
383
+ @ios = @workers.map(&:io)
384
+ end
385
+
386
+ def _run_parallel suites, type, result
387
+ if @options[:parallel] < 1
388
+ warn "Error: parameter of -j option should be greater than 0."
389
+ return
390
+ end
391
+
392
+ begin
393
+ # Require needed things for parallel running
394
+ require 'thread'
395
+ require 'timeout'
396
+ @tasks = @files.dup # Array of filenames.
397
+ @need_quit = false
398
+ @dead_workers = [] # Array of dead workers.
399
+ @warnings = []
400
+ shutting_down = false
401
+ rep = [] # FIXME: more good naming
402
+
403
+ # Array of workers.
404
+ @workers = @options[:parallel].times.map {
405
+ worker = Worker.launch(@options[:ruby],@args)
406
+ worker.hook(:dead) do |w,info|
407
+ after_worker_quit w
408
+ after_worker_down w, *info unless info.empty?
409
+ end
410
+ worker
411
+ }
412
+
413
+ # Thread: watchdog
414
+ watchdog = Thread.new do
415
+ while stat = Process.wait2
416
+ break if @interrupt # Break when interrupt
417
+ pid, stat = stat
418
+ w = (@workers + @dead_workers).find{|x| pid == x.pid }.dup
419
+ next unless w
420
+ unless w.status == :quit
421
+ # Worker down
422
+ w.died(nil, !stat.signaled? && stat.exitstatus)
423
+ end
424
+ end
425
+ end
426
+
427
+ @workers_hash = Hash[@workers.map {|w| [w.io,w] }] # out-IO => worker
428
+ @ios = @workers.map{|w| w.io } # Array of worker IOs
429
+
430
+ while _io = IO.select(@ios)[0]
431
+ break unless _io.each do |io|
432
+ break if @need_quit
433
+ worker = @workers_hash[io]
434
+ case worker.read
435
+ when /^okay$/
436
+ worker.status = :running
437
+ jobs_status
438
+ when /^ready$/
439
+ worker.status = :ready
440
+ if @tasks.empty?
441
+ break unless @workers.find{|x| x.status == :running }
442
+ else
443
+ worker.run(@tasks.shift, type)
444
+ end
445
+
446
+ jobs_status
447
+ when /^done (.+?)$/
448
+ r = Marshal.load($1.unpack("m")[0])
449
+ result << r[0..1] unless r[0..1] == [nil,nil]
450
+ rep << {file: worker.real_file,
451
+ report: r[2], result: r[3], testcase: r[5]}
452
+ $:.push(*r[4]).uniq!
453
+ when /^p (.+?)$/
454
+ del_jobs_status
455
+ print $1.unpack("m")[0]
456
+ jobs_status if @options[:job_status] == :replace
457
+ when /^after (.+?)$/
458
+ @warnings << Marshal.load($1.unpack("m")[0])
459
+ when /^bye (.+?)$/
460
+ after_worker_down worker, Marshal.load($1.unpack("m")[0])
461
+ when /^bye$/
462
+ if shutting_down
463
+ after_worker_quit worker
464
+ else
465
+ after_worker_down worker
466
+ end
467
+ end
468
+ break if @need_quit
469
+ end
470
+ end
471
+ rescue Interrupt => e
472
+ @interrupt = e
473
+ return result
474
+ ensure
475
+ shutting_down = true
476
+
477
+ watchdog.kill if watchdog
478
+ if @interrupt
479
+ @ios.select!{|x| @workers_hash[x].status == :running }
480
+ while !@ios.empty? && (__io = IO.select(@ios,[],[],10))
481
+ _io = __io[0]
482
+ _io.each do |io|
483
+ worker = @workers_hash[io]
484
+ case worker.read
485
+ when /^done (.+?)$/
486
+ r = Marshal.load($1.unpack("m")[0])
487
+ result << r[0..1] unless r[0..1] == [nil,nil]
488
+ rep << {file: worker.real_file,
489
+ report: r[2], result: r[3], testcase: r[5]}
490
+ $:.push(*r[4]).uniq!
491
+ @ios.delete(io)
492
+ end
493
+ end
494
+ end
495
+ end
496
+ @workers.each do |worker|
497
+ begin
498
+ timeout(1) do
499
+ worker.puts "quit"
500
+ end
501
+ rescue Errno::EPIPE
502
+ rescue Timeout::Error
503
+ end
504
+ worker.close
505
+ end
506
+ begin
507
+ timeout(0.2*@workers.size) do
508
+ Process.waitall
509
+ end
510
+ rescue Timeout::Error
511
+ @workers.each do |worker|
512
+ begin
513
+ Process.kill(:KILL,worker.pid)
514
+ rescue Errno::ESRCH; end
515
+ end
516
+ end
517
+
518
+ if @interrupt || @options[:no_retry] || @need_quit
519
+ rep.each do |r|
520
+ report.push(*r[:report])
521
+ end
522
+ @errors += rep.map{|x| x[:result][0] }.inject(:+)
523
+ @failures += rep.map{|x| x[:result][1] }.inject(:+)
524
+ @skips += rep.map{|x| x[:result][2] }.inject(:+)
525
+ else
526
+ puts ""
527
+ puts "Retrying..."
528
+ puts ""
529
+ rep.each do |r|
530
+ if r[:testcase] && r[:file] && !r[:report].empty?
531
+ require r[:file]
532
+ _run_suite(eval(r[:testcase]),type)
533
+ else
534
+ report.push(*r[:report])
535
+ @errors += r[:result][0]
536
+ @failures += r[:result][1]
537
+ @skips += r[:result][2]
538
+ end
539
+ end
540
+ end
541
+ if @warnings
542
+ warn ""
543
+ ary = []
544
+ @warnings.reject! do |w|
545
+ r = ary.include?(w[1].message)
546
+ ary << w[1].message
547
+ r
548
+ end
549
+ @warnings.each do |w|
550
+ warn "#{w[0]}: #{w[1].message} (#{w[1].class})"
551
+ end
552
+ warn ""
553
+ end
554
+ end
555
+ end
556
+
557
+ def _run_suites suites, type
558
+ @interrupt = nil
559
+ result = []
560
+ if @options[:parallel]
561
+ _run_parallel suites, type, result
562
+ else
563
+ suites.each {|suite|
564
+ begin
565
+ result << _run_suite(suite, type)
566
+ rescue Interrupt => e
567
+ @interrupt = e
568
+ break
569
+ end
570
+ }
571
+ end
572
+ report.reject!{|r| r.start_with? "Skipped:" } if @options[:hide_skip]
573
+ result
574
+ end
575
+
576
+ # Overriding of MiniTest::Unit#puke
577
+ def puke klass, meth, e
578
+ # TODO:
579
+ # this overriding is for minitest feature that skip messages are
580
+ # hidden when not verbose (-v), note this is temporally.
581
+ e = case e
582
+ when MiniTest::Skip then
583
+ @skips += 1
584
+ "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
585
+ when MiniTest::Assertion then
586
+ @failures += 1
587
+ "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
588
+ else
589
+ @errors += 1
590
+ bt = MiniTest::filter_backtrace(e.backtrace).join "\n "
591
+ "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n #{bt}\n"
592
+ end
593
+ @report << e
594
+ e[0, 1]
595
+ end
596
+
597
+ def status(*args)
598
+ result = super
599
+ raise @interrupt if @interrupt
600
+ result
601
+ end
602
+ end
603
+
604
+ class AutoRunner
605
+ class Runner < Test::Unit::Runner
606
+ include Test::Unit::RequireFiles
607
+ end
608
+
609
+ attr_accessor :to_run, :options
610
+
611
+ def initialize(force_standalone = false, default_dir = nil, argv = ARGV)
612
+ @runner = Runner.new do |files, options|
613
+ options[:base_directory] ||= default_dir
614
+ files << default_dir if files.empty? and default_dir
615
+ @to_run = files
616
+ yield self if block_given?
617
+ files
618
+ end
619
+ Runner.runner = @runner
620
+ @options = @runner.option_parser
621
+ @argv = argv
622
+ end
623
+
624
+ def process_args(*args)
625
+ @runner.process_args(*args)
626
+ !@to_run.empty?
627
+ end
628
+
629
+ def run
630
+ @runner.run(@argv) || true
631
+ end
632
+
633
+ def self.run(*args)
634
+ new(*args).run
635
+ end
636
+ end
637
+ end
638
+ end
639
+
640
+ Test::Unit::Runner.autorun
@@ -0,0 +1,324 @@
1
+ require 'minitest/unit'
2
+ require 'pp'
3
+
4
+ module Test
5
+ module Unit
6
+ module Assertions
7
+ include MiniTest::Assertions
8
+
9
+ def mu_pp(obj) #:nodoc:
10
+ obj.pretty_inspect.chomp
11
+ end
12
+
13
+ MINI_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), "minitest") #:nodoc:
14
+
15
+ UNASSIGNED = Object.new # :nodoc:
16
+
17
+ # :call-seq:
18
+ # assert( test, failure_message = UNASSIGNED )
19
+ #
20
+ #Tests if +test+ is true.
21
+ #
22
+ #+msg+ may be a String or a Proc. If +msg+ is a String, it will be used
23
+ #as the failure message. Otherwise, the result of calling +msg+ will be
24
+ #used as the message if the assertion fails.
25
+ #
26
+ #If no +msg+ is given, a default message will be used.
27
+ #
28
+ # assert(false, "This was expected to be true")
29
+ def assert(test, msg = UNASSIGNED)
30
+ case msg
31
+ when UNASSIGNED
32
+ msg = nil
33
+ when String, Proc
34
+ else
35
+ bt = caller.reject { |s| s.rindex(MINI_DIR, 0) }
36
+ raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt
37
+ end
38
+ super
39
+ end
40
+
41
+ # :call-seq:
42
+ # assert_block( failure_message = nil )
43
+ #
44
+ #Tests the result of the given block. If the block does not return true,
45
+ #the assertion will fail. The optional +failure_message+ argument is the same as in
46
+ #Assertions#assert.
47
+ #
48
+ # assert_block do
49
+ # [1, 2, 3].any? { |num| num < 1 }
50
+ # end
51
+ def assert_block(*msgs)
52
+ assert yield, *msgs
53
+ end
54
+
55
+ # :call-seq:
56
+ # assert_raise( *args, &block )
57
+ #
58
+ #Tests if the given block raises an exception. Acceptable exception
59
+ #types maye be given as optional arguments. If the last argument is a
60
+ #String, it will be used as the error message.
61
+ #
62
+ # assert_raise do #Fails, no Exceptions are raised
63
+ # end
64
+ #
65
+ # assert_raise NameError do
66
+ # puts x #Raises NameError, so assertion succeeds
67
+ # end
68
+ def assert_raise(*args, &b)
69
+ assert_raises(*args, &b)
70
+ end
71
+
72
+ # :call-seq:
73
+ # assert_nothing_raised( *args, &block )
74
+ #
75
+ #If any exceptions are given as arguments, the assertion will
76
+ #fail if one of those exceptions are raised. Otherwise, the test fails
77
+ #if any exceptions are raised.
78
+ #
79
+ #The final argument may be a failure message.
80
+ #
81
+ # assert_nothing_raised RuntimeError do
82
+ # raise Exception #Assertion passes, Exception is not a RuntimeError
83
+ # end
84
+ #
85
+ # assert_nothing_raised do
86
+ # raise Exception #Assertion fails
87
+ # end
88
+ def assert_nothing_raised(*args)
89
+ self._assertions += 1
90
+ if Module === args.last
91
+ msg = nil
92
+ else
93
+ msg = args.pop
94
+ end
95
+ begin
96
+ line = __LINE__; yield
97
+ rescue MiniTest::Skip
98
+ raise
99
+ rescue Exception => e
100
+ bt = e.backtrace
101
+ as = e.instance_of?(MiniTest::Assertion)
102
+ if as
103
+ ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o
104
+ bt.reject! {|ln| ans =~ ln}
105
+ end
106
+ if ((args.empty? && !as) ||
107
+ args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a })
108
+ msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" }
109
+ raise MiniTest::Assertion, msg.call, bt
110
+ else
111
+ raise
112
+ end
113
+ end
114
+ nil
115
+ end
116
+
117
+ # :call-seq:
118
+ # assert_nothing_thrown( failure_message = nil, &block )
119
+ #
120
+ #Fails if the given block uses a call to Kernel#throw.
121
+ #
122
+ #An optional failure message may be provided as the final argument.
123
+ #
124
+ # assert_nothing_thrown "Something was thrown!" do
125
+ # throw :problem?
126
+ # end
127
+ def assert_nothing_thrown(msg=nil)
128
+ begin
129
+ yield
130
+ rescue ArgumentError => error
131
+ raise error if /\Auncaught throw (.+)\z/m !~ error.message
132
+ msg = message(msg) { "<#{$1}> was thrown when nothing was expected" }
133
+ flunk(msg)
134
+ end
135
+ assert(true, "Expected nothing to be thrown")
136
+ end
137
+
138
+ # :call-seq:
139
+ # assert_equal( expected, actual, failure_message = nil )
140
+ #
141
+ #Tests if +expected+ is equal to +actual+.
142
+ #
143
+ #An optional failure message may be provided as the final argument.
144
+ def assert_equal(exp, act, msg = nil)
145
+ msg = message(msg) {
146
+ exp_str = mu_pp(exp)
147
+ act_str = mu_pp(act)
148
+ exp_comment = ''
149
+ act_comment = ''
150
+ if exp_str == act_str
151
+ if (exp.is_a?(String) && act.is_a?(String)) ||
152
+ (exp.is_a?(Regexp) && act.is_a?(Regexp))
153
+ exp_comment = " (#{exp.encoding})"
154
+ act_comment = " (#{act.encoding})"
155
+ elsif exp.is_a?(Float) && act.is_a?(Float)
156
+ exp_str = "%\#.#{Float::DIG+2}g" % exp
157
+ act_str = "%\#.#{Float::DIG+2}g" % act
158
+ elsif exp.is_a?(Time) && act.is_a?(Time)
159
+ if exp.subsec * 1000_000_000 == exp.nsec
160
+ exp_comment = " (#{exp.nsec}[ns])"
161
+ else
162
+ exp_comment = " (subsec=#{exp.subsec})"
163
+ end
164
+ if act.subsec * 1000_000_000 == act.nsec
165
+ act_comment = " (#{act.nsec}[ns])"
166
+ else
167
+ act_comment = " (subsec=#{act.subsec})"
168
+ end
169
+ elsif exp.class != act.class
170
+ # a subclass of Range, for example.
171
+ exp_comment = " (#{exp.class})"
172
+ act_comment = " (#{act.class})"
173
+ end
174
+ elsif !Encoding.compatible?(exp_str, act_str)
175
+ if exp.is_a?(String) && act.is_a?(String)
176
+ exp_str = exp.dump
177
+ act_str = act.dump
178
+ exp_comment = " (#{exp.encoding})"
179
+ act_comment = " (#{act.encoding})"
180
+ else
181
+ exp_str = exp_str.dump
182
+ act_str = act_str.dump
183
+ end
184
+ end
185
+ "<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}"
186
+ }
187
+ assert(exp == act, msg)
188
+ end
189
+
190
+ # :call-seq:
191
+ # assert_not_nil( expression, failure_message = nil )
192
+ #
193
+ #Tests if +expression+ is not nil.
194
+ #
195
+ #An optional failure message may be provided as the final argument.
196
+ def assert_not_nil(exp, msg=nil)
197
+ msg = message(msg) { "<#{mu_pp(exp)}> expected to not be nil" }
198
+ assert(!exp.nil?, msg)
199
+ end
200
+
201
+ # :call-seq:
202
+ # assert_not_equal( expected, actual, failure_message = nil )
203
+ #
204
+ #Tests if +expected+ is not equal to +actual+.
205
+ #
206
+ #An optional failure message may be provided as the final argument.
207
+ def assert_not_equal(exp, act, msg=nil)
208
+ msg = message(msg) { "<#{mu_pp(exp)}> expected to be != to\n<#{mu_pp(act)}>" }
209
+ assert(exp != act, msg)
210
+ end
211
+
212
+ # :call-seq:
213
+ # assert_no_match( regexp, string, failure_message = nil )
214
+ #
215
+ #Tests if the given Regexp does not match a given String.
216
+ #
217
+ #An optional failure message may be provided as the final argument.
218
+ def assert_no_match(regexp, string, msg=nil)
219
+ assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
220
+ self._assertions -= 1
221
+ msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" }
222
+ assert(regexp !~ string, msg)
223
+ end
224
+
225
+ # :call-seq:
226
+ # assert_not_same( expected, actual, failure_message = nil )
227
+ #
228
+ #Tests if +expected+ is not the same object as +actual+.
229
+ #This test uses Object#equal? to test equality.
230
+ #
231
+ #An optional failure message may be provided as the final argument.
232
+ #
233
+ # assert_not_same("x", "x") #Succeeds
234
+ def assert_not_same(expected, actual, message="")
235
+ msg = message(msg) { build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__) }
236
+ <?>
237
+ with id <?> expected to not be equal\\? to
238
+ <?>
239
+ with id <?>.
240
+ EOT
241
+ assert(!actual.equal?(expected), msg)
242
+ end
243
+
244
+ # :call-seq:
245
+ # assert_respond_to( object, method, failure_message = nil )
246
+ #
247
+ #Tests if the given Object responds to +method+.
248
+ #
249
+ #An optional failure message may be provided as the final argument.
250
+ #
251
+ # assert_respond_to("hello", :reverse) #Succeeds
252
+ # assert_respond_to("hello", :does_not_exist) #Fails
253
+ def assert_respond_to obj, meth, msg = nil
254
+ #get rid of overcounting
255
+ super if !caller[0].rindex(MINI_DIR, 0) || !obj.respond_to?(meth)
256
+ end
257
+
258
+ # :call-seq:
259
+ # assert_send( +send_array+, failure_message = nil )
260
+ #
261
+ # Passes if the method send returns a true value.
262
+ #
263
+ # +send_array+ is composed of:
264
+ # * A receiver
265
+ # * A method
266
+ # * Arguments to the method
267
+ #
268
+ # Example:
269
+ # assert_send([[1, 2], :member?, 1]) # -> pass
270
+ # assert_send([[1, 2], :member?, 4]) # -> fail
271
+ def assert_send send_ary, m = nil
272
+ recv, msg, *args = send_ary
273
+ m = message(m) {
274
+ if args.empty?
275
+ argsstr = ""
276
+ else
277
+ (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)')
278
+ end
279
+ "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return true"
280
+ }
281
+ assert recv.__send__(msg, *args), m
282
+ end
283
+
284
+ # :call-seq:
285
+ # assert_not_send( +send_array+, failure_message = nil )
286
+ #
287
+ # Passes if the method send doesn't return a true value.
288
+ #
289
+ # +send_array+ is composed of:
290
+ # * A receiver
291
+ # * A method
292
+ # * Arguments to the method
293
+ #
294
+ # Example:
295
+ # assert_not_send([[1, 2], :member?, 1]) # -> fail
296
+ # assert_not_send([[1, 2], :member?, 4]) # -> pass
297
+ def assert_not_send send_ary, m = nil
298
+ recv, msg, *args = send_ary
299
+ m = message(m) {
300
+ if args.empty?
301
+ argsstr = ""
302
+ else
303
+ (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)')
304
+ end
305
+ "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return false"
306
+ }
307
+ assert !recv.__send__(msg, *args), m
308
+ end
309
+
310
+ ms = instance_methods(true).map {|sym| sym.to_s }
311
+ ms.grep(/\Arefute_/) do |m|
312
+ mname = ('assert_not_' << m.to_s[/.*?_(.*)/, 1])
313
+ alias_method(mname, m) unless ms.include? mname
314
+ end
315
+ alias assert_include assert_includes
316
+ alias assert_not_include assert_not_includes
317
+
318
+ def build_message(head, template=nil, *arguments) #:nodoc:
319
+ template &&= template.chomp
320
+ template.gsub(/\G((?:[^\\]|\\.)*?)(\\)?\?/) { $1 + ($2 ? "?" : mu_pp(arguments.shift)) }
321
+ end
322
+ end
323
+ end
324
+ end
@@ -0,0 +1,161 @@
1
+ require 'test/unit'
2
+
3
+ module Test
4
+ module Unit
5
+ class Worker < Runner
6
+ class << self
7
+ undef autorun
8
+ end
9
+
10
+ alias orig_run_suite _run_suite
11
+ undef _run_suite
12
+ undef _run_suites
13
+ undef run
14
+
15
+ def increment_io(orig)
16
+ *rest, io = 32.times.inject([orig.dup]){|ios, | ios << ios.last.dup }
17
+ rest.each(&:close)
18
+ io
19
+ end
20
+
21
+ def _run_suites(suites, type)
22
+ suites.map do |suite|
23
+ _run_suite(suite, type)
24
+ end
25
+ end
26
+
27
+ def _run_suite(suite, type)
28
+ r = report.dup
29
+ orig_testout = MiniTest::Unit.output
30
+ i,o = IO.pipe
31
+
32
+ MiniTest::Unit.output = o
33
+ orig_stdin, orig_stdout = $stdin, $stdout
34
+
35
+ th = Thread.new do
36
+ begin
37
+ while buf = (self.verbose ? i.gets : i.read(5))
38
+ @stdout.puts "p #{[buf].pack("m").gsub("\n","")}"
39
+ end
40
+ rescue IOError
41
+ rescue Errno::EPIPE
42
+ end
43
+ end
44
+
45
+ e, f, s = @errors, @failures, @skips
46
+
47
+ begin
48
+ result = orig_run_suite(suite, type)
49
+ rescue Interrupt
50
+ @need_exit = true
51
+ result = [nil,nil]
52
+ end
53
+
54
+ MiniTest::Unit.output = orig_testout
55
+ $stdin = orig_stdin
56
+ $stdout = orig_stdout
57
+
58
+ o.close
59
+ begin
60
+ th.join
61
+ rescue IOError
62
+ raise unless ["stream closed","closed stream"].include? $!.message
63
+ end
64
+ i.close
65
+
66
+ result << (report - r)
67
+ result << [@errors-e,@failures-f,@skips-s]
68
+ result << ($: - @old_loadpath)
69
+ result << suite.name
70
+
71
+ begin
72
+ @stdout.puts "done #{[Marshal.dump(result)].pack("m").gsub("\n","")}"
73
+ rescue Errno::EPIPE; end
74
+ return result
75
+ ensure
76
+ MiniTest::Unit.output = orig_stdout
77
+ $stdin = orig_stdin
78
+ $stdout = orig_stdout
79
+ o.close if o && !o.closed?
80
+ i.close if i && !i.closed?
81
+ end
82
+
83
+ def run(args = [])
84
+ process_args args
85
+ @@stop_auto_run = true
86
+ @opts = @options.dup
87
+ @need_exit = false
88
+
89
+ @old_loadpath = []
90
+ begin
91
+ @stdout = increment_io(STDOUT)
92
+ @stdin = increment_io(STDIN)
93
+ @stdout.sync = true
94
+ @stdout.puts "ready"
95
+ while buf = @stdin.gets
96
+ case buf.chomp
97
+ when /^loadpath (.+?)$/
98
+ @old_loadpath = $:.dup
99
+ $:.push(*Marshal.load($1.unpack("m")[0].force_encoding("ASCII-8BIT"))).uniq!
100
+ when /^run (.+?) (.+?)$/
101
+ @stdout.puts "okay"
102
+
103
+ @options = @opts.dup
104
+ suites = MiniTest::Unit::TestCase.test_suites
105
+
106
+ begin
107
+ require $1
108
+ rescue LoadError
109
+ @stdout.puts "after #{[Marshal.dump([$1, $!])].pack("m").gsub("\n","")}"
110
+ @stdout.puts "ready"
111
+ next
112
+ end
113
+ _run_suites MiniTest::Unit::TestCase.test_suites-suites, $2.to_sym
114
+
115
+ if @need_exit
116
+ begin
117
+ @stdout.puts "bye"
118
+ rescue Errno::EPIPE; end
119
+ exit
120
+ else
121
+ @stdout.puts "ready"
122
+ end
123
+ when /^quit$/
124
+ begin
125
+ @stdout.puts "bye"
126
+ rescue Errno::EPIPE; end
127
+ exit
128
+ end
129
+ end
130
+ rescue Errno::EPIPE
131
+ rescue Exception => e
132
+ begin
133
+ @stdout.puts "bye #{[Marshal.dump(e)].pack("m").gsub("\n","")}"
134
+ rescue Errno::EPIPE;end
135
+ exit
136
+ ensure
137
+ @stdin.close
138
+ @stdout.close
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ if $0 == __FILE__
146
+ module Test
147
+ module Unit
148
+ class TestCase < MiniTest::Unit::TestCase
149
+ def on_parallel_worker?
150
+ true
151
+ end
152
+ end
153
+ end
154
+ end
155
+ require 'rubygems'
156
+ class Gem::TestCase < MiniTest::Unit::TestCase
157
+ @@project_dir = File.expand_path('../../../..', __FILE__)
158
+ end
159
+
160
+ Test::Unit::Worker.new.run(ARGV)
161
+ end
@@ -0,0 +1,25 @@
1
+ require 'test/unit/assertions'
2
+
3
+ module Test
4
+ module Unit
5
+ # remove silly TestCase class
6
+ remove_const(:TestCase) if defined?(self::TestCase)
7
+
8
+ class TestCase < MiniTest::Unit::TestCase
9
+ include Assertions
10
+
11
+ def on_parallel_worker?
12
+ false
13
+ end
14
+
15
+ def run runner
16
+ @options = runner.options
17
+ super runner
18
+ end
19
+
20
+ def self.test_order
21
+ :sorted
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "minitest-spec-rails-tu-shim"
3
+ spec.version = '1.9.3'
4
+ spec.authors = ["Nobuyoshi Nakada", "Shota Fukumori", "akr", "unak", "Ryan Davis", "Aaron Patterson", "Yuki Sonoda", "NARUSE, Yui", "Yusuke Endoh", "Eric Hodel", "Kenta Murata"]
5
+ spec.email = ["nobu@ruby-lang.org", "sorah@tubusu.net", "ryand-ruby@zenspider.com", "aaron.patterson@gmail.com", "ugui@yugui.jp", "drbrain@segment7.net", "mrkn+github@mrkn.jp"]
6
+ spec.description = 'Redistribution of lib/test source directory from Ruby 1.9.3p392.'
7
+ spec.summary = spec.description
8
+ spec.homepage = "https://github.com/metaskills/minitest-spec-rails-tu-shim"
9
+ spec.license = "See LICENSE.txt and COPYING.txt"
10
+ spec.files = `git ls-files`.split($/)
11
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
12
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
13
+ spec.require_paths = ["lib"]
14
+ spec.add_development_dependency "bundler", "~> 1.3"
15
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minitest-spec-rails-tu-shim
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nobuyoshi Nakada
9
+ - Shota Fukumori
10
+ - akr
11
+ - unak
12
+ - Ryan Davis
13
+ - Aaron Patterson
14
+ - Yuki Sonoda
15
+ - NARUSE, Yui
16
+ - Yusuke Endoh
17
+ - Eric Hodel
18
+ - Kenta Murata
19
+ autorequire:
20
+ bindir: bin
21
+ cert_chain: []
22
+ date: 2013-03-19 00:00:00.000000000 Z
23
+ dependencies:
24
+ - !ruby/object:Gem::Dependency
25
+ name: bundler
26
+ requirement: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: '1.3'
32
+ type: :development
33
+ prerelease: false
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
40
+ description: Redistribution of lib/test source directory from Ruby 1.9.3p392.
41
+ email:
42
+ - nobu@ruby-lang.org
43
+ - sorah@tubusu.net
44
+ - ryand-ruby@zenspider.com
45
+ - aaron.patterson@gmail.com
46
+ - ugui@yugui.jp
47
+ - drbrain@segment7.net
48
+ - mrkn+github@mrkn.jp
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - COPYING.txt
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - lib/test/unit.rb
59
+ - lib/test/unit/assertions.rb
60
+ - lib/test/unit/parallel.rb
61
+ - lib/test/unit/testcase.rb
62
+ - minitest-spec-rails-tu-shim.gemspec
63
+ homepage: https://github.com/metaskills/minitest-spec-rails-tu-shim
64
+ licenses:
65
+ - See LICENSE.txt and COPYING.txt
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 1.8.25
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Redistribution of lib/test source directory from Ruby 1.9.3p392.
88
+ test_files: []
89
+ has_rdoc: