mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Imported minitest 4.3.2 (r8026)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37967 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
304885cdff
commit
81eb635f8c
13 changed files with 769 additions and 249 deletions
|
@ -1,3 +1,8 @@
|
|||
Thu Nov 29 12:13:54 2012 Ryan Davis <ryand-ruby@zenspider.com>
|
||||
|
||||
* lib/minitest/*: Imported minitest 4.3.2 (r8026)
|
||||
* test/minitest/*: ditto
|
||||
|
||||
Thu Nov 29 11:06:06 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* thread.c (thread_start_func_2): remove unused code. When
|
||||
|
|
|
@ -49,6 +49,17 @@ discovery.
|
|||
|
||||
-- Piotr Szotkowski
|
||||
|
||||
Comparing to rspec:
|
||||
|
||||
rspec is a testing DSL. minitest is ruby.
|
||||
|
||||
-- Adam Hawkins, "Bow Before MiniTest"
|
||||
|
||||
minitest doesn't reinvent anything that ruby already provides, like:
|
||||
classes, modules, inheritance, methods. This means you only have to
|
||||
learn ruby to use minitest and all of your regular OO practices like
|
||||
extract-method refactorings still apply.
|
||||
|
||||
== FEATURES/PROBLEMS:
|
||||
|
||||
* minitest/autorun - the easy and explicit way to run all your tests.
|
||||
|
@ -93,6 +104,10 @@ Given that you'd like to test the following class:
|
|||
def test_that_it_will_not_blend
|
||||
refute_match /^no/i, @meme.will_it_blend?
|
||||
end
|
||||
|
||||
def test_that_will_be_skipped
|
||||
skip "test this later"
|
||||
end
|
||||
end
|
||||
|
||||
=== Specs
|
||||
|
@ -260,43 +275,74 @@ fixture loading:
|
|||
|
||||
== Known Extensions:
|
||||
|
||||
minitest-capistrano :: Assertions and expectations for testing Capistrano recipes
|
||||
minitest-capybara :: Capybara matchers support for minitest unit and spec
|
||||
minitest-chef-handler :: Run Minitest suites as Chef report handlers
|
||||
minitest-ci :: CI reporter plugin for MiniTest.
|
||||
minitest-colorize :: Colorize MiniTest output and show failing tests instantly.
|
||||
minitest-context :: Defines contexts for code reuse in MiniTest
|
||||
specs that share common expectations.
|
||||
minitest-debugger :: Wraps assert so failed assertions drop into
|
||||
the ruby debugger.
|
||||
minitest-display :: Patches MiniTest to allow for an easily configurable output.
|
||||
minitest-emoji :: Print out emoji for your test passes, fails, and skips.
|
||||
minitest-excludes :: Clean API for excluding certain tests you
|
||||
don't want to run under certain conditions.
|
||||
minitest-firemock :: Makes your MiniTest mocks more resilient.
|
||||
minitest-growl :: Test notifier for minitest via growl.
|
||||
minitest-instrument :: Instrument ActiveSupport::Notifications when
|
||||
test method is executed
|
||||
minitest-instrument-db :: Store information about speed of test
|
||||
execution provided by minitest-instrument in database
|
||||
minitest-libnotify :: Test notifier for minitest via libnotify.
|
||||
minitest-macruby :: Provides extensions to minitest for macruby UI testing.
|
||||
minitest-matchers :: Adds support for RSpec-style matchers to minitest.
|
||||
minitest-metadata :: Annotate tests with metadata (key-value).
|
||||
minitest-mongoid :: Mongoid assertion matchers for MiniTest
|
||||
minitest-must_not :: Provides must_not as an alias for wont in MiniTest
|
||||
minitest-predicates :: Adds support for .predicate? methods
|
||||
minitest-pry :: A minitest plugin to drop into pry on assertion failure.
|
||||
minitest-rails :: MiniTest integration for Rails 3.1.
|
||||
minitest-reporters :: Create customizable MiniTest output formats
|
||||
minitest-rg :: redgreen minitest
|
||||
minitest-spec-magic :: Minitest::Spec extensions for Rails and beyond
|
||||
minitest-tags :: add tags for minitest
|
||||
minitest-wscolor :: Yet another test colorizer.
|
||||
minitest_owrapper :: Get tests results as a TestResult object.
|
||||
minitest_should :: Shoulda style syntax for minitest test::unit.
|
||||
minitest_tu_shim :: minitest_tu_shim bridges between test/unit and minitest.
|
||||
mongoid-minitest :: MiniTest matchers for Mongoid.
|
||||
minitest-capistrano :: Assertions and expectations for testing Capistrano recipes
|
||||
minitest-capybara :: Capybara matchers support for minitest unit and spec
|
||||
minitest-chef-handler :: Run Minitest suites as Chef report handlers
|
||||
minitest-ci :: CI reporter plugin for MiniTest.
|
||||
minitest-colorize :: Colorize MiniTest output and show failing tests instantly.
|
||||
minitest-context :: Defines contexts for code reuse in MiniTest
|
||||
specs that share common expectations.
|
||||
minitest-debugger :: Wraps assert so failed assertions drop into
|
||||
the ruby debugger.
|
||||
minitest-display :: Patches MiniTest to allow for an easily configurable output.
|
||||
minitest-emoji :: Print out emoji for your test passes, fails, and skips.
|
||||
minitest-excludes :: Clean API for excluding certain tests you
|
||||
don't want to run under certain conditions.
|
||||
minitest-firemock :: Makes your MiniTest mocks more resilient.
|
||||
minitest-growl :: Test notifier for minitest via growl.
|
||||
minitest-instrument :: Instrument ActiveSupport::Notifications when
|
||||
test method is executed
|
||||
minitest-instrument-db :: Store information about speed of test
|
||||
execution provided by minitest-instrument in database
|
||||
minitest-libnotify :: Test notifier for minitest via libnotify.
|
||||
minitest-macruby :: Provides extensions to minitest for macruby UI testing.
|
||||
minitest-matchers :: Adds support for RSpec-style matchers to minitest.
|
||||
minitest-metadata :: Annotate tests with metadata (key-value).
|
||||
minitest-mongoid :: Mongoid assertion matchers for MiniTest
|
||||
minitest-must_not :: Provides must_not as an alias for wont in MiniTest
|
||||
minitest-predicates :: Adds support for .predicate? methods
|
||||
minitest-rails :: MiniTest integration for Rails 3.x
|
||||
minitest-rails-capybara :: Capybara integration for MiniTest::Rails
|
||||
minitest-reporters :: Create customizable MiniTest output formats
|
||||
minitest-rg :: redgreen minitest
|
||||
minitest-shouldify :: Adding all manner of shoulds to MiniTest (bad idea)
|
||||
minitest-spec-magic :: Minitest::Spec extensions for Rails and beyond
|
||||
minitest-tags :: add tags for minitest
|
||||
minitest-wscolor :: Yet another test colorizer.
|
||||
minitest_owrapper :: Get tests results as a TestResult object.
|
||||
minitest_should :: Shoulda style syntax for minitest test::unit.
|
||||
minitest_tu_shim :: minitest_tu_shim bridges between test/unit and minitest.
|
||||
mongoid-minitest :: MiniTest matchers for Mongoid.
|
||||
pry-rescue :: A pry plugin w/ minitest support. See pry-rescue/minitest.rb.
|
||||
|
||||
== Unknown Extensions:
|
||||
|
||||
Authors... Please send me a pull request with a description of your minitest extension.
|
||||
|
||||
* assay-minitest
|
||||
* capybara_minitest_spec
|
||||
* detroit-minitest
|
||||
* em-minitest-spec
|
||||
* flexmock-minitest
|
||||
* guard-minitest
|
||||
* guard-minitest-decisiv
|
||||
* minitest-activemodel
|
||||
* minitest-ar-assertions
|
||||
* minitest-around
|
||||
* minitest-capybara-unit
|
||||
* minitest-colorer
|
||||
* minitest-deluxe
|
||||
* minitest-extra-assertions
|
||||
* minitest-nc
|
||||
* minitest-rails-shoulda
|
||||
* minitest-spec
|
||||
* minitest-spec-context
|
||||
* minitest-spec-rails
|
||||
* minitest-spec-should
|
||||
* minitest-sugar
|
||||
* minitest_should
|
||||
* mongoid-minitest
|
||||
* spork-minitest
|
||||
|
||||
== REQUIREMENTS:
|
||||
|
||||
|
|
16
lib/minitest/hell.rb
Normal file
16
lib/minitest/hell.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# encoding: utf-8
|
||||
######################################################################
|
||||
# This file is imported from the minitest project.
|
||||
# DO NOT make modifications in this repo. They _will_ be reverted!
|
||||
# File a patch instead and assign it to Ryan Davis.
|
||||
######################################################################
|
||||
|
||||
class Minitest::Unit::TestCase
|
||||
class << self
|
||||
alias :old_test_order :test_order
|
||||
|
||||
def test_order # :nodoc:
|
||||
:parallel
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,8 +31,8 @@ module MiniTest
|
|||
end
|
||||
|
||||
##
|
||||
# Expect that method +name+ is called, optionally with +args+, and returns
|
||||
# +retval+.
|
||||
# Expect that method +name+ is called, optionally with +args+ or a
|
||||
# +blk+, and returns +retval+.
|
||||
#
|
||||
# @mock.expect(:meaning_of_life, 42)
|
||||
# @mock.meaning_of_life # => 42
|
||||
|
@ -40,6 +40,10 @@ module MiniTest
|
|||
# @mock.expect(:do_something_with, true, [some_obj, true])
|
||||
# @mock.do_something_with(some_obj, true) # => true
|
||||
#
|
||||
# @mock.expect(:do_something_else, true) do |a1, a2|
|
||||
# a1 == "buggs" && a2 == :bunny
|
||||
# end
|
||||
#
|
||||
# +args+ is compared to the expected args using case equality (ie, the
|
||||
# '===' operator), allowing for less specific expectations.
|
||||
#
|
||||
|
@ -51,9 +55,14 @@ module MiniTest
|
|||
# @mock.uses_one_string("bar") # => true
|
||||
# @mock.verify # => raises MockExpectationError
|
||||
|
||||
def expect(name, retval, args=[])
|
||||
raise ArgumentError, "args must be an array" unless Array === args
|
||||
@expected_calls[name] << { :retval => retval, :args => args }
|
||||
def expect(name, retval, args=[], &blk)
|
||||
if block_given?
|
||||
raise ArgumentError, "args ignored when block given" unless args.empty?
|
||||
@expected_calls[name] << { :retval => retval, :block => blk }
|
||||
else
|
||||
raise ArgumentError, "args must be an array" unless Array === args
|
||||
@expected_calls[name] << { :retval => retval, :args => args }
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -103,7 +112,17 @@ module MiniTest
|
|||
[sym, args]
|
||||
end
|
||||
|
||||
expected_args, retval = expected_call[:args], expected_call[:retval]
|
||||
expected_args, retval, val_block =
|
||||
expected_call.values_at(:args, :retval, :block)
|
||||
|
||||
if val_block then
|
||||
raise MockExpectationError, "mocked method %p failed block w/ %p" %
|
||||
[sym, args] unless val_block.call(args)
|
||||
|
||||
# keep "verify" happy
|
||||
@actual_calls[sym] << expected_call
|
||||
return retval
|
||||
end
|
||||
|
||||
if expected_args.size != args.size then
|
||||
raise ArgumentError, "mocked method %p expects %d arguments, got %d" %
|
||||
|
@ -127,9 +146,9 @@ module MiniTest
|
|||
retval
|
||||
end
|
||||
|
||||
def respond_to?(sym) # :nodoc:
|
||||
def respond_to?(sym, include_private = false) # :nodoc:
|
||||
return true if @expected_calls.has_key?(sym.to_sym)
|
||||
return __respond_to?(sym)
|
||||
return __respond_to?(sym, include_private)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -155,7 +174,15 @@ class Object # :nodoc:
|
|||
new_name = "__minitest_stub__#{name}"
|
||||
|
||||
metaclass = class << self; self; end
|
||||
|
||||
if respond_to? name and not methods.map(&:to_s).include? name.to_s then
|
||||
metaclass.send :define_method, name do |*args|
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
metaclass.send :alias_method, new_name, name
|
||||
|
||||
metaclass.send :define_method, name do |*args|
|
||||
if val_or_callable.respond_to? :call then
|
||||
val_or_callable.call(*args)
|
||||
|
|
36
lib/minitest/parallel_each.rb
Normal file
36
lib/minitest/parallel_each.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# encoding: utf-8
|
||||
######################################################################
|
||||
# This file is imported from the minitest project.
|
||||
# DO NOT make modifications in this repo. They _will_ be reverted!
|
||||
# File a patch instead and assign it to Ryan Davis.
|
||||
######################################################################
|
||||
|
||||
class ParallelEach
|
||||
require 'thread'
|
||||
include Enumerable
|
||||
|
||||
N = (ENV['N'] || 2).to_i
|
||||
|
||||
def initialize list
|
||||
@queue = Queue.new # *sigh*... the Queue api sucks sooo much...
|
||||
|
||||
list.each { |i| @queue << i }
|
||||
N.times { @queue << nil }
|
||||
end
|
||||
|
||||
def grep pattern
|
||||
self.class.new super
|
||||
end
|
||||
|
||||
def each
|
||||
threads = N.times.map {
|
||||
Thread.new do
|
||||
Thread.current.abort_on_exception = true
|
||||
while job = @queue.pop
|
||||
yield job
|
||||
end
|
||||
end
|
||||
}
|
||||
threads.map(&:join)
|
||||
end
|
||||
end
|
|
@ -47,7 +47,7 @@ class PrideIO
|
|||
|
||||
def puts(*o) # :nodoc:
|
||||
o.map! { |s|
|
||||
s.sub(/Finished tests/) {
|
||||
s.to_s.sub(/Finished tests/) {
|
||||
@index = 0
|
||||
'Fabulous tests'.split(//).map { |c|
|
||||
pride(c)
|
||||
|
|
|
@ -537,5 +537,5 @@ module MiniTest::Expectations
|
|||
end
|
||||
|
||||
class Object # :nodoc:
|
||||
include MiniTest::Expectations
|
||||
include MiniTest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
||||
end
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
require 'optparse'
|
||||
require 'rbconfig'
|
||||
require 'thread' # required for 1.8
|
||||
require 'minitest/parallel_each'
|
||||
|
||||
##
|
||||
# Minimal (mostly drop-in) replacement for test-unit.
|
||||
|
@ -37,24 +39,36 @@ module MiniTest
|
|||
|
||||
class Skip < Assertion; end
|
||||
|
||||
def self.filter_backtrace bt # :nodoc:
|
||||
return ["No backtrace"] unless bt
|
||||
class << self
|
||||
attr_accessor :backtrace_filter
|
||||
end
|
||||
|
||||
new_bt = []
|
||||
class BacktraceFilter # :nodoc:
|
||||
def filter bt
|
||||
return ["No backtrace"] unless bt
|
||||
|
||||
unless $DEBUG then
|
||||
bt.each do |line|
|
||||
break if line =~ /lib\/minitest/
|
||||
new_bt << line
|
||||
new_bt = []
|
||||
|
||||
unless $DEBUG then
|
||||
bt.each do |line|
|
||||
break if line =~ /lib\/minitest/
|
||||
new_bt << line
|
||||
end
|
||||
|
||||
new_bt = bt.reject { |line| line =~ /lib\/minitest/ } if new_bt.empty?
|
||||
new_bt = bt.dup if new_bt.empty?
|
||||
else
|
||||
new_bt = bt.dup
|
||||
end
|
||||
|
||||
new_bt = bt.reject { |line| line =~ /lib\/minitest/ } if new_bt.empty?
|
||||
new_bt = bt.dup if new_bt.empty?
|
||||
else
|
||||
new_bt = bt.dup
|
||||
new_bt
|
||||
end
|
||||
end
|
||||
|
||||
new_bt
|
||||
self.backtrace_filter = BacktraceFilter.new
|
||||
|
||||
def self.filter_backtrace bt # :nodoc:
|
||||
backtrace_filter.filter bt
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -68,14 +82,12 @@ module MiniTest
|
|||
"UNDEFINED" # again with the rdoc bugs... :(
|
||||
end
|
||||
|
||||
WINDOZE = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ # :nodoc:
|
||||
|
||||
##
|
||||
# Returns the diff command to use in #diff. Tries to intelligently
|
||||
# figure out what diff to use.
|
||||
|
||||
def self.diff
|
||||
@diff = if WINDOZE
|
||||
@diff = if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ then
|
||||
"diff.exe -u"
|
||||
else
|
||||
if system("gdiff", __FILE__, __FILE__)
|
||||
|
@ -136,10 +148,11 @@ module MiniTest
|
|||
if result.empty? then
|
||||
klass = exp.class
|
||||
result = [
|
||||
"No visible difference.",
|
||||
"You should look at your implementation of #{klass}#==.",
|
||||
expect
|
||||
].join "\n"
|
||||
"No visible difference in the #{klass}#inspect output.\n",
|
||||
"You should look at the implementation of #== on ",
|
||||
"#{klass} or its members.\n",
|
||||
expect,
|
||||
].join
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -314,6 +327,8 @@ module MiniTest
|
|||
# "" if you require it to be silent. Pass in a regexp if you want
|
||||
# to pattern match.
|
||||
#
|
||||
# NOTE: this uses #capture_io, not #capture_subprocess_io.
|
||||
#
|
||||
# See also: #assert_silent
|
||||
|
||||
def assert_output stdout = nil, stderr = nil
|
||||
|
@ -351,30 +366,30 @@ module MiniTest
|
|||
def assert_raises *exp
|
||||
msg = "#{exp.pop}.\n" if String === exp.last
|
||||
|
||||
should_raise = false
|
||||
begin
|
||||
yield
|
||||
should_raise = true
|
||||
rescue MiniTest::Skip => e
|
||||
details = "#{msg}#{mu_pp(exp)} exception expected, not"
|
||||
|
||||
if exp.include? MiniTest::Skip then
|
||||
return e
|
||||
else
|
||||
raise e
|
||||
end
|
||||
return e if exp.include? MiniTest::Skip
|
||||
raise e
|
||||
rescue Exception => e
|
||||
details = "#{msg}#{mu_pp(exp)} exception expected, not"
|
||||
assert(exp.any? { |ex|
|
||||
ex.instance_of?(Module) ? e.kind_of?(ex) : ex == e.class
|
||||
}, exception_details(e, details))
|
||||
expected = exp.any? { |ex|
|
||||
if ex.instance_of? Module then
|
||||
e.kind_of? ex
|
||||
else
|
||||
e.instance_of? ex
|
||||
end
|
||||
}
|
||||
|
||||
assert expected, proc {
|
||||
exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not")
|
||||
}
|
||||
|
||||
return e
|
||||
end
|
||||
|
||||
exp = exp.first if exp.size == 1
|
||||
flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised." if
|
||||
should_raise
|
||||
|
||||
flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised."
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -431,6 +446,8 @@ module MiniTest
|
|||
catch(sym) do
|
||||
begin
|
||||
yield
|
||||
rescue ThreadError => e # wtf?!? 1.8 + threads == suck
|
||||
default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
|
||||
rescue ArgumentError => e # 1.9 exception
|
||||
default += ", not #{e.message.split(/ /).last}"
|
||||
rescue NameError => e # 1.8 exception
|
||||
|
@ -446,24 +463,76 @@ module MiniTest
|
|||
# Captures $stdout and $stderr into strings:
|
||||
#
|
||||
# out, err = capture_io do
|
||||
# puts "Some info"
|
||||
# warn "You did a bad thing"
|
||||
# end
|
||||
#
|
||||
# assert_match %r%info%, out
|
||||
# assert_match %r%bad%, err
|
||||
#
|
||||
# NOTE: For efficiency, this method uses StringIO and does not
|
||||
# capture IO for subprocesses. Use #capture_subprocess_io for
|
||||
# that.
|
||||
|
||||
def capture_io
|
||||
require 'stringio'
|
||||
|
||||
orig_stdout, orig_stderr = $stdout, $stderr
|
||||
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
||||
$stdout, $stderr = captured_stdout, captured_stderr
|
||||
|
||||
yield
|
||||
synchronize do
|
||||
orig_stdout, orig_stderr = $stdout, $stderr
|
||||
$stdout, $stderr = captured_stdout, captured_stderr
|
||||
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
$stdout = orig_stdout
|
||||
$stderr = orig_stderr
|
||||
end
|
||||
end
|
||||
|
||||
return captured_stdout.string, captured_stderr.string
|
||||
ensure
|
||||
$stdout = orig_stdout
|
||||
$stderr = orig_stderr
|
||||
end
|
||||
|
||||
##
|
||||
# Captures $stdout and $stderr into strings, using Tempfile to
|
||||
# ensure that subprocess IO is captured as well.
|
||||
#
|
||||
# out, err = capture_subprocess_io do
|
||||
# system "echo Some info"
|
||||
# system "echo You did a bad thing 1>&2"
|
||||
# end
|
||||
#
|
||||
# assert_match %r%info%, out
|
||||
# assert_match %r%bad%, err
|
||||
#
|
||||
# NOTE: This method is approximately 10x slower than #capture_io so
|
||||
# only use it when you need to test the output of a subprocess.
|
||||
|
||||
def capture_subprocess_io
|
||||
require 'tempfile'
|
||||
|
||||
captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
|
||||
|
||||
synchronize do
|
||||
orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
|
||||
$stdout.reopen captured_stdout
|
||||
$stderr.reopen captured_stderr
|
||||
|
||||
begin
|
||||
yield
|
||||
|
||||
$stdout.rewind
|
||||
$stderr.rewind
|
||||
|
||||
[captured_stdout.read, captured_stderr.read]
|
||||
ensure
|
||||
captured_stdout.unlink
|
||||
captured_stderr.unlink
|
||||
$stdout.reopen orig_stdout
|
||||
$stderr.reopen orig_stderr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -656,10 +725,19 @@ module MiniTest
|
|||
msg ||= "Skipped, no message given"
|
||||
raise MiniTest::Skip, msg, bt
|
||||
end
|
||||
|
||||
##
|
||||
# Takes a block and wraps it with the runner's shared mutex.
|
||||
|
||||
def synchronize
|
||||
Minitest::Unit.runner.synchronize do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Unit # :nodoc:
|
||||
VERSION = "3.4.0" # :nodoc:
|
||||
VERSION = "4.3.2" # :nodoc:
|
||||
|
||||
attr_accessor :report, :failures, :errors, :skips # :nodoc:
|
||||
attr_accessor :test_count, :assertion_count # :nodoc:
|
||||
|
@ -667,7 +745,6 @@ module MiniTest
|
|||
attr_accessor :help # :nodoc:
|
||||
attr_accessor :verbose # :nodoc:
|
||||
attr_writer :options # :nodoc:
|
||||
attr_accessor :last_error # :nodoc:
|
||||
|
||||
##
|
||||
# Lazy accessor for options.
|
||||
|
@ -695,7 +772,8 @@ module MiniTest
|
|||
|
||||
def self.autorun
|
||||
at_exit {
|
||||
next if $! # don't run if there was an exception
|
||||
# don't run if there was a non-exit exception
|
||||
next if $! and not $!.kind_of? SystemExit
|
||||
|
||||
# the order here is important. The at_exit handler must be
|
||||
# installed before anyone else gets a chance to install their
|
||||
|
@ -810,10 +888,15 @@ module MiniTest
|
|||
end
|
||||
|
||||
##
|
||||
# Runs all the +suites+ for a given +type+.
|
||||
# Runs all the +suites+ for a given +type+. Runs suites declaring
|
||||
# a test_order of +:parallel+ in parallel, and everything else
|
||||
# serial.
|
||||
|
||||
def _run_suites suites, type
|
||||
suites.map { |suite| _run_suite suite, type }
|
||||
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
||||
|
||||
ParallelEach.new(parallel).map { |suite| _run_suite suite, type } +
|
||||
serial.map { |suite| _run_suite suite, type }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -832,14 +915,10 @@ module MiniTest
|
|||
|
||||
print "#{suite}##{method} = " if @verbose
|
||||
|
||||
@start_time = Time.now
|
||||
self.last_error = nil
|
||||
start_time = Time.now if @verbose
|
||||
result = inst.run self
|
||||
time = Time.now - @start_time
|
||||
|
||||
record suite, method, inst._assertions, time, last_error
|
||||
|
||||
print "%.2f s = " % time if @verbose
|
||||
print "%.2f s = " % (Time.now - start_time) if @verbose
|
||||
print result
|
||||
puts if @verbose
|
||||
|
||||
|
@ -878,7 +957,6 @@ module MiniTest
|
|||
# exception +e+
|
||||
|
||||
def puke klass, meth, e
|
||||
self.last_error = e
|
||||
e = case e
|
||||
when MiniTest::Skip then
|
||||
@skips += 1
|
||||
|
@ -900,7 +978,11 @@ module MiniTest
|
|||
@report = []
|
||||
@errors = @failures = @skips = 0
|
||||
@verbose = false
|
||||
self.last_error = nil
|
||||
@mutex = Mutex.new
|
||||
end
|
||||
|
||||
def synchronize # :nodoc:
|
||||
@mutex.synchronize { yield }
|
||||
end
|
||||
|
||||
def process_args args = [] # :nodoc:
|
||||
|
@ -1103,31 +1185,10 @@ module MiniTest
|
|||
|
||||
module Deprecated # :nodoc:
|
||||
|
||||
##
|
||||
# This entire module is deprecated and slated for removal on 2013-01-01.
|
||||
##
|
||||
# This entire module is deprecated and slated for removal on 2013-01-01.
|
||||
|
||||
module Hooks
|
||||
##
|
||||
# Adds a block of code that will be executed before every
|
||||
# TestCase is run.
|
||||
#
|
||||
# NOTE: This method is deprecated, use before/after_setup. It
|
||||
# will be removed on 2013-01-01.
|
||||
|
||||
def self.add_setup_hook arg=nil, &block
|
||||
warn "NOTE: MiniTest::Unit::TestCase.add_setup_hook is deprecated, use before/after_setup via a module (and call super!). It will be removed on 2013-01-01. Called from #{caller.first}"
|
||||
hook = arg || block
|
||||
@setup_hooks << hook
|
||||
end
|
||||
|
||||
def self.setup_hooks # :nodoc:
|
||||
if superclass.respond_to? :setup_hooks then
|
||||
superclass.setup_hooks
|
||||
else
|
||||
[]
|
||||
end + @setup_hooks
|
||||
end
|
||||
|
||||
def run_setup_hooks # :nodoc:
|
||||
_run_hooks self.class.setup_hooks
|
||||
end
|
||||
|
@ -1142,6 +1203,36 @@ module MiniTest
|
|||
end
|
||||
end
|
||||
|
||||
def run_teardown_hooks # :nodoc:
|
||||
_run_hooks self.class.teardown_hooks.reverse
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This entire module is deprecated and slated for removal on 2013-01-01.
|
||||
|
||||
module HooksCM
|
||||
##
|
||||
# Adds a block of code that will be executed before every
|
||||
# TestCase is run.
|
||||
#
|
||||
# NOTE: This method is deprecated, use before/after_setup. It
|
||||
# will be removed on 2013-01-01.
|
||||
|
||||
def add_setup_hook arg=nil, &block
|
||||
warn "NOTE: MiniTest::Unit::TestCase.add_setup_hook is deprecated, use before/after_setup via a module (and call super!). It will be removed on 2013-01-01. Called from #{caller.first}"
|
||||
hook = arg || block
|
||||
@setup_hooks << hook
|
||||
end
|
||||
|
||||
def setup_hooks # :nodoc:
|
||||
if superclass.respond_to? :setup_hooks then
|
||||
superclass.setup_hooks
|
||||
else
|
||||
[]
|
||||
end + @setup_hooks
|
||||
end
|
||||
|
||||
##
|
||||
# Adds a block of code that will be executed after every
|
||||
# TestCase is run.
|
||||
|
@ -1149,23 +1240,19 @@ module MiniTest
|
|||
# NOTE: This method is deprecated, use before/after_teardown. It
|
||||
# will be removed on 2013-01-01.
|
||||
|
||||
def self.add_teardown_hook arg=nil, &block
|
||||
def add_teardown_hook arg=nil, &block
|
||||
warn "NOTE: MiniTest::Unit::TestCase#add_teardown_hook is deprecated, use before/after_teardown. It will be removed on 2013-01-01. Called from #{caller.first}"
|
||||
hook = arg || block
|
||||
@teardown_hooks << hook
|
||||
end
|
||||
|
||||
def self.teardown_hooks # :nodoc:
|
||||
def teardown_hooks # :nodoc:
|
||||
if superclass.respond_to? :teardown_hooks then
|
||||
superclass.teardown_hooks
|
||||
else
|
||||
[]
|
||||
end + @teardown_hooks
|
||||
end
|
||||
|
||||
def run_teardown_hooks # :nodoc:
|
||||
_run_hooks self.class.teardown_hooks.reverse
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1178,6 +1265,7 @@ module MiniTest
|
|||
class TestCase
|
||||
include LifecycleHooks
|
||||
include Deprecated::Hooks
|
||||
extend Deprecated::HooksCM # UGH... I can't wait 'til 2013!
|
||||
include Guard
|
||||
extend Guard
|
||||
|
||||
|
@ -1202,6 +1290,8 @@ module MiniTest
|
|||
runner.status $stderr
|
||||
end if SUPPORTS_INFO_SIGNAL
|
||||
|
||||
start_time = Time.now
|
||||
|
||||
result = ""
|
||||
begin
|
||||
@passed = nil
|
||||
|
@ -1210,11 +1300,15 @@ module MiniTest
|
|||
self.after_setup
|
||||
self.run_test self.__name__
|
||||
result = "." unless io?
|
||||
time = Time.now - start_time
|
||||
runner.record self.class, self.__name__, self._assertions, time, nil
|
||||
@passed = true
|
||||
rescue *PASSTHROUGH_EXCEPTIONS
|
||||
raise
|
||||
rescue Exception => e
|
||||
@passed = false
|
||||
time = Time.now - start_time
|
||||
runner.record self.class, self.__name__, self._assertions, time, e
|
||||
result = runner.puke self.class, self.__name__, e
|
||||
ensure
|
||||
%w{ before_teardown teardown after_teardown }.each do |hook|
|
||||
|
@ -1278,6 +1372,32 @@ module MiniTest
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Make diffs for this TestCase use #pretty_inspect so that diff
|
||||
# in assert_equal can be more details. NOTE: this is much slower
|
||||
# than the regular inspect but much more usable for complex
|
||||
# objects.
|
||||
|
||||
def self.make_my_diffs_pretty!
|
||||
require 'pp'
|
||||
|
||||
define_method :mu_pp do |o|
|
||||
o.pretty_inspect
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Call this at the top of your tests when you want to run your
|
||||
# tests in parallel. In doing so, you're admitting that you rule
|
||||
# and your tests are awesome.
|
||||
|
||||
def self.parallelize_me!
|
||||
class << self
|
||||
undef_method :test_order if method_defined? :test_order
|
||||
define_method :test_order do :parallel end
|
||||
end
|
||||
end
|
||||
|
||||
def self.inherited klass # :nodoc:
|
||||
@@test_suites[klass] = true
|
||||
klass.reset_setup_teardown_hooks
|
||||
|
@ -1296,6 +1416,9 @@ module MiniTest
|
|||
methods = public_instance_methods(true).grep(/^test/).map { |m| m.to_s }
|
||||
|
||||
case self.test_order
|
||||
when :parallel
|
||||
max = methods.size
|
||||
ParallelEach.new methods.sort.sort_by { rand max }
|
||||
when :random then
|
||||
max = methods.size
|
||||
methods.sort.sort_by { rand max }
|
||||
|
|
|
@ -24,7 +24,9 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase
|
|||
|
||||
EOM
|
||||
|
||||
@tu.run flags
|
||||
with_output do
|
||||
@tu.run flags
|
||||
end
|
||||
|
||||
output = @output.string.dup
|
||||
output.sub!(/Finished tests in .*/, "Finished tests in 0.00")
|
||||
|
@ -49,14 +51,24 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase
|
|||
srand 42
|
||||
MiniTest::Unit::TestCase.reset
|
||||
@tu = MiniTest::Unit.new
|
||||
@output = StringIO.new("")
|
||||
|
||||
MiniTest::Unit.runner = nil # protect the outer runner from the inner tests
|
||||
MiniTest::Unit.output = @output
|
||||
end
|
||||
|
||||
def teardown
|
||||
super
|
||||
MiniTest::Unit.output = $stdout
|
||||
Object.send :remove_const, :ATestCase if defined? ATestCase
|
||||
end
|
||||
|
||||
def with_output
|
||||
synchronize do
|
||||
begin
|
||||
@output = StringIO.new("")
|
||||
MiniTest::Unit.output = @output
|
||||
|
||||
yield
|
||||
ensure
|
||||
MiniTest::Unit.output = STDOUT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,4 +117,3 @@ class TestMiniTestBenchmark < MiniTest::Unit::TestCase
|
|||
assert_in_delta exp_b, b
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ require 'minitest/unit'
|
|||
MiniTest::Unit.autorun
|
||||
|
||||
class TestMiniTestMock < MiniTest::Unit::TestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
def setup
|
||||
@mock = MiniTest::Mock.new.expect(:foo, nil)
|
||||
@mock.expect(:meaning_of_life, 42)
|
||||
|
@ -103,6 +105,7 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
|
|||
|
||||
def test_respond_appropriately
|
||||
assert @mock.respond_to?(:foo)
|
||||
assert @mock.respond_to?(:foo, true)
|
||||
assert @mock.respond_to?('foo')
|
||||
assert !@mock.respond_to?(:bar)
|
||||
end
|
||||
|
@ -202,6 +205,68 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
|
|||
assert_equal exp, e.message
|
||||
end
|
||||
|
||||
def test_verify_passes_when_mock_block_returns_true
|
||||
mock = MiniTest::Mock.new
|
||||
mock.expect :foo, nil do
|
||||
true
|
||||
end
|
||||
|
||||
mock.foo
|
||||
|
||||
assert mock.verify
|
||||
end
|
||||
|
||||
def test_mock_block_is_passed_function_params
|
||||
arg1, arg2, arg3 = :bar, [1,2,3], {:a => 'a'}
|
||||
mock = MiniTest::Mock.new
|
||||
mock.expect :foo, nil do |a1, a2, a3|
|
||||
a1 == arg1 &&
|
||||
a2 == arg2 &&
|
||||
a3 == arg3
|
||||
end
|
||||
|
||||
mock.foo arg1, arg2, arg3
|
||||
|
||||
assert mock.verify
|
||||
end
|
||||
|
||||
def test_verify_fails_when_mock_block_returns_false
|
||||
mock = MiniTest::Mock.new
|
||||
mock.expect :foo, nil do
|
||||
false
|
||||
end
|
||||
|
||||
e = assert_raises(MockExpectationError) { mock.foo }
|
||||
exp = "mocked method :foo failed block w/ []"
|
||||
|
||||
assert_equal exp, e.message
|
||||
end
|
||||
|
||||
def test_mock_block_throws_if_args_passed
|
||||
mock = MiniTest::Mock.new
|
||||
|
||||
e = assert_raises(ArgumentError) do
|
||||
mock.expect :foo, nil, [:a, :b, :c] do
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
exp = "args ignored when block given"
|
||||
|
||||
assert_equal exp, e.message
|
||||
end
|
||||
|
||||
def test_mock_returns_retval_when_called_with_block
|
||||
mock = MiniTest::Mock.new
|
||||
mock.expect(:foo, 32) do
|
||||
true
|
||||
end
|
||||
|
||||
rs = mock.foo
|
||||
|
||||
assert_equal rs, 32
|
||||
end
|
||||
|
||||
def util_verify_bad exp
|
||||
e = assert_raises MockExpectationError do
|
||||
@mock.verify
|
||||
|
@ -214,6 +279,8 @@ end
|
|||
require "minitest/metametameta"
|
||||
|
||||
class TestMiniTestStub < MiniTest::Unit::TestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
def setup
|
||||
super
|
||||
MiniTest::Unit::TestCase.reset
|
||||
|
@ -230,13 +297,15 @@ class TestMiniTestStub < MiniTest::Unit::TestCase
|
|||
def assert_stub val_or_callable
|
||||
@assertion_count += 1
|
||||
|
||||
t = Time.now.to_i
|
||||
synchronize do
|
||||
t = Time.now.to_i
|
||||
|
||||
Time.stub :now, val_or_callable do
|
||||
@tc.assert_equal 42, Time.now
|
||||
Time.stub :now, val_or_callable do
|
||||
@tc.assert_equal 42, Time.now
|
||||
end
|
||||
|
||||
@tc.assert_operator Time.now.to_i, :>=, t
|
||||
end
|
||||
|
||||
@tc.assert_operator Time.now.to_i, :>=, t
|
||||
end
|
||||
|
||||
def test_stub_value
|
||||
|
@ -250,13 +319,15 @@ class TestMiniTestStub < MiniTest::Unit::TestCase
|
|||
def test_stub_block_args
|
||||
@assertion_count += 1
|
||||
|
||||
t = Time.now.to_i
|
||||
synchronize do
|
||||
t = Time.now.to_i
|
||||
|
||||
Time.stub :now, lambda { |n| n * 2 } do
|
||||
@tc.assert_equal 42, Time.now(21)
|
||||
Time.stub :now, lambda { |n| n * 2 } do
|
||||
@tc.assert_equal 42, Time.now(21)
|
||||
end
|
||||
|
||||
@tc.assert_operator Time.now.to_i, :>=, t
|
||||
end
|
||||
|
||||
@tc.assert_operator Time.now.to_i, :>=, t
|
||||
end
|
||||
|
||||
def test_stub_callable
|
||||
|
@ -278,4 +349,29 @@ class TestMiniTestStub < MiniTest::Unit::TestCase
|
|||
|
||||
@tc.assert_equal "bar", val
|
||||
end
|
||||
|
||||
def test_dynamic_method
|
||||
@assertion_count = 2
|
||||
|
||||
dynamic = Class.new do
|
||||
def self.respond_to?(meth)
|
||||
meth == :found
|
||||
end
|
||||
|
||||
def self.method_missing(meth, *args, &block)
|
||||
if meth == :found
|
||||
false
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
val = dynamic.stub(:found, true) do |s|
|
||||
s.found
|
||||
end
|
||||
|
||||
@tc.assert_equal true, val
|
||||
@tc.assert_equal false, dynamic.found
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,8 @@ class ExampleA; end
|
|||
class ExampleB < ExampleA; end
|
||||
|
||||
describe MiniTest::Spec do
|
||||
# do not parallelize this suite... it just can't handle it.
|
||||
|
||||
def assert_triggered expected = "blah", klass = MiniTest::Assertion
|
||||
@assertion_count += 2
|
||||
|
||||
|
@ -567,11 +569,28 @@ describe MiniTest::Spec, :subject do
|
|||
end
|
||||
end
|
||||
|
||||
class TestMeta < MiniTest::Unit::TestCase
|
||||
def test_setup
|
||||
srand 42
|
||||
MiniTest::Unit::TestCase.reset
|
||||
class TestMetaStatic < MiniTest::Unit::TestCase
|
||||
def test_children
|
||||
MiniTest::Spec.children.clear # prevents parallel run
|
||||
|
||||
x = y = z = nil
|
||||
x = describe "top-level thingy" do
|
||||
y = describe "first thingy" do end
|
||||
|
||||
it "top-level-it" do end
|
||||
|
||||
z = describe "second thingy" do end
|
||||
end
|
||||
|
||||
assert_equal [x], MiniTest::Spec.children
|
||||
assert_equal [y, z], x.children
|
||||
assert_equal [], y.children
|
||||
assert_equal [], z.children
|
||||
end
|
||||
end
|
||||
|
||||
class TestMeta < MiniTest::Unit::TestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
def util_structure
|
||||
x = y = z = nil
|
||||
|
@ -659,35 +678,15 @@ class TestMeta < MiniTest::Unit::TestCase
|
|||
_, _, z, before_list, after_list = util_structure
|
||||
|
||||
@tu = MiniTest::Unit.new
|
||||
@output = StringIO.new("")
|
||||
MiniTest::Unit.runner = nil # protect the outer runner from the inner tests
|
||||
MiniTest::Unit.output = @output
|
||||
|
||||
tc = z.new :test_0002_anonymous
|
||||
tc.run @tu
|
||||
with_output do
|
||||
tc = z.new :test_0002_anonymous
|
||||
tc.run @tu
|
||||
end
|
||||
|
||||
assert_equal [1, 2, 3], before_list
|
||||
assert_equal [3, 2, 1], after_list
|
||||
ensure
|
||||
MiniTest::Unit.output = $stdout
|
||||
end
|
||||
|
||||
def test_children
|
||||
MiniTest::Spec.children.clear
|
||||
|
||||
x = y = z = nil
|
||||
x = describe "top-level thingy" do
|
||||
y = describe "first thingy" do end
|
||||
|
||||
it "top-level-it" do end
|
||||
|
||||
z = describe "second thingy" do end
|
||||
end
|
||||
|
||||
assert_equal [x], MiniTest::Spec.children
|
||||
assert_equal [y, z], x.children
|
||||
assert_equal [], y.children
|
||||
assert_equal [], z.children
|
||||
end
|
||||
|
||||
def test_describe_first_structure
|
||||
|
@ -723,4 +722,17 @@ class TestMeta < MiniTest::Unit::TestCase
|
|||
assert_respond_to y.new(nil), "xyz"
|
||||
assert_respond_to z.new(nil), "xyz"
|
||||
end
|
||||
|
||||
def with_output # REFACTOR: dupe from metametameta
|
||||
synchronize do
|
||||
begin
|
||||
@output = StringIO.new("")
|
||||
MiniTest::Unit.output = @output
|
||||
|
||||
yield
|
||||
ensure
|
||||
MiniTest::Unit.output = STDOUT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,8 @@ class AnError < StandardError; include MyModule; end
|
|||
class ImmutableString < String; def inspect; super.freeze; end; end
|
||||
|
||||
class TestMiniTestUnit < MetaMetaMetaTestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
pwd = Pathname.new File.expand_path Dir.pwd
|
||||
basedir = Pathname.new(File.expand_path "lib/minitest") + 'mini'
|
||||
basedir = basedir.relative_path_from(pwd).to_s
|
||||
|
@ -22,6 +24,23 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
"#{MINITEST_BASE_DIR}/test.rb:139:in `run'",
|
||||
"#{MINITEST_BASE_DIR}/test.rb:106:in `run'"]
|
||||
|
||||
def test_wtf
|
||||
$hook_value = nil
|
||||
|
||||
capture_io do # don't care about deprecation
|
||||
MiniTest::Unit::TestCase.add_setup_hook do
|
||||
$hook_value = 42
|
||||
end
|
||||
end
|
||||
|
||||
run_setup_hooks
|
||||
|
||||
assert_equal 42, $hook_value
|
||||
assert_equal [Proc], MiniTest::Unit::TestCase.setup_hooks.map(&:class)
|
||||
MiniTest::Unit::TestCase.reset_setup_teardown_hooks
|
||||
assert_equal [], MiniTest::Unit::TestCase.setup_hooks.map(&:class)
|
||||
end
|
||||
|
||||
def test_class_puke_with_assertion_failed
|
||||
exception = MiniTest::Assertion.new "Oh no!"
|
||||
exception.set_backtrace ["unhappy"]
|
||||
|
@ -156,6 +175,85 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
assert_equal ex, fu
|
||||
end
|
||||
|
||||
def test_default_runner_is_minitest_unit
|
||||
assert_instance_of MiniTest::Unit, MiniTest::Unit.runner
|
||||
end
|
||||
|
||||
def with_overridden_include
|
||||
Class.class_eval do
|
||||
def inherited_with_hacks klass
|
||||
throw :inherited_hook
|
||||
end
|
||||
|
||||
alias inherited_without_hacks inherited
|
||||
alias inherited inherited_with_hacks
|
||||
alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros
|
||||
end
|
||||
|
||||
yield
|
||||
ensure
|
||||
Class.class_eval do
|
||||
alias inherited inherited_without_hacks
|
||||
|
||||
undef_method :inherited_with_hacks
|
||||
undef_method :inherited_without_hacks
|
||||
end
|
||||
|
||||
refute_respond_to Class, :inherited_with_hacks
|
||||
refute_respond_to Class, :inherited_without_hacks
|
||||
end
|
||||
|
||||
def test_inherited_hook_plays_nice_with_others
|
||||
with_overridden_include do
|
||||
assert_throws :inherited_hook do
|
||||
Class.new MiniTest::Unit::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_passed_eh_teardown_good
|
||||
test_class = Class.new MiniTest::Unit::TestCase do
|
||||
def teardown; assert true; end
|
||||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
test = test_class.new :test_omg
|
||||
test.run @tu
|
||||
assert test.passed?
|
||||
end
|
||||
|
||||
def test_passed_eh_teardown_flunked
|
||||
test_class = Class.new MiniTest::Unit::TestCase do
|
||||
def teardown; flunk; end
|
||||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
test = test_class.new :test_omg
|
||||
test.run @tu
|
||||
refute test.passed?
|
||||
end
|
||||
|
||||
def util_expand_bt bt
|
||||
if RUBY_VERSION >= '1.9.0' then
|
||||
bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
|
||||
else
|
||||
bt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class TestMiniTestRunner < MetaMetaMetaTestCase
|
||||
# do not parallelize this suite... it just can't handle it.
|
||||
|
||||
def test_class_test_suites
|
||||
@assertion_count = 0
|
||||
|
||||
tc = Class.new(MiniTest::Unit::TestCase)
|
||||
|
||||
assert_equal 1, MiniTest::Unit::TestCase.test_suites.size
|
||||
assert_equal [tc], MiniTest::Unit::TestCase.test_suites
|
||||
end
|
||||
|
||||
def test_run_test
|
||||
Class.new MiniTest::Unit::TestCase do
|
||||
attr_reader :foo
|
||||
|
@ -352,10 +450,6 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
assert_report expected, %w[--seed 42 --verbose]
|
||||
end
|
||||
|
||||
def test_default_runner_is_minitest_unit
|
||||
assert_instance_of MiniTest::Unit, MiniTest::Unit.runner
|
||||
end
|
||||
|
||||
def test_run_with_other_runner
|
||||
MiniTest::Unit.runner = Class.new MiniTest::Unit do
|
||||
def _run_suite suite, type
|
||||
|
@ -393,38 +487,75 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
assert_report expected
|
||||
end
|
||||
|
||||
def with_overridden_include
|
||||
Class.class_eval do
|
||||
def inherited_with_hacks klass
|
||||
throw :inherited_hook
|
||||
end
|
||||
require 'monitor'
|
||||
|
||||
alias inherited_without_hacks inherited
|
||||
alias inherited inherited_with_hacks
|
||||
alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros
|
||||
class Latch
|
||||
def initialize count = 1
|
||||
@count = count
|
||||
@lock = Monitor.new
|
||||
@cv = @lock.new_cond
|
||||
end
|
||||
|
||||
yield
|
||||
ensure
|
||||
Class.class_eval do
|
||||
alias inherited inherited_without_hacks
|
||||
|
||||
undef_method :inherited_with_hacks
|
||||
undef_method :inherited_without_hacks
|
||||
end
|
||||
|
||||
refute_respond_to Class, :inherited_with_hacks
|
||||
refute_respond_to Class, :inherited_without_hacks
|
||||
end
|
||||
|
||||
def test_inherited_hook_plays_nice_with_others
|
||||
with_overridden_include do
|
||||
assert_throws :inherited_hook do
|
||||
Class.new MiniTest::Unit::TestCase
|
||||
def release
|
||||
@lock.synchronize do
|
||||
@count -= 1 if @count > 0
|
||||
@cv.broadcast if @count == 0
|
||||
end
|
||||
end
|
||||
|
||||
def await
|
||||
@lock.synchronize { @cv.wait_while { @count > 0 } }
|
||||
end
|
||||
end
|
||||
|
||||
def test_run_parallel
|
||||
test_count = 2
|
||||
test_latch = Latch.new test_count
|
||||
main_latch = Latch.new
|
||||
|
||||
thread = Thread.new {
|
||||
Thread.current.abort_on_exception = true
|
||||
|
||||
# This latch waits until both test latches have been released. Both
|
||||
# latches can't be released unless done in separate threads because
|
||||
# `main_latch` keeps the test method from finishing.
|
||||
test_latch.await
|
||||
main_latch.release
|
||||
}
|
||||
|
||||
Class.new MiniTest::Unit::TestCase do
|
||||
parallelize_me!
|
||||
|
||||
test_count.times do |i|
|
||||
define_method :"test_wait_on_main_thread_#{i}" do
|
||||
test_latch.release
|
||||
|
||||
# This latch blocks until the "main thread" releases it. The main
|
||||
# thread can't release this latch until both test latches have
|
||||
# been released. This forces the latches to be released in separate
|
||||
# threads.
|
||||
main_latch.await
|
||||
assert true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
expected = clean <<-EOM
|
||||
..
|
||||
|
||||
Finished tests in 0.00
|
||||
|
||||
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
|
||||
EOM
|
||||
|
||||
assert_report expected
|
||||
assert thread.join
|
||||
end
|
||||
end
|
||||
|
||||
class TestMiniTestUnitOrder < MetaMetaMetaTestCase
|
||||
# do not parallelize this suite... it just can't handle it.
|
||||
|
||||
def test_before_setup
|
||||
call_order = []
|
||||
Class.new MiniTest::Unit::TestCase do
|
||||
|
@ -440,34 +571,14 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
with_output do
|
||||
@tu.run %w[--seed 42]
|
||||
end
|
||||
|
||||
expected = [:before_setup, :setup]
|
||||
assert_equal expected, call_order
|
||||
end
|
||||
|
||||
def test_passed_eh_teardown_good
|
||||
test_class = Class.new MiniTest::Unit::TestCase do
|
||||
def teardown; assert true; end
|
||||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
test = test_class.new :test_omg
|
||||
test.run @tu
|
||||
assert test.passed?
|
||||
end
|
||||
|
||||
def test_passed_eh_teardown_flunked
|
||||
test_class = Class.new MiniTest::Unit::TestCase do
|
||||
def teardown; flunk; end
|
||||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
test = test_class.new :test_omg
|
||||
test.run @tu
|
||||
refute test.passed?
|
||||
end
|
||||
|
||||
def test_after_teardown
|
||||
call_order = []
|
||||
Class.new MiniTest::Unit::TestCase do
|
||||
|
@ -483,7 +594,9 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
with_output do
|
||||
@tu.run %w[--seed 42]
|
||||
end
|
||||
|
||||
expected = [:teardown, :after_teardown]
|
||||
assert_equal expected, call_order
|
||||
|
@ -513,7 +626,9 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
def test_omg; assert true; end
|
||||
end
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
with_output do
|
||||
@tu.run %w[--seed 42]
|
||||
end
|
||||
|
||||
expected = [:before_teardown, :teardown, :after_teardown]
|
||||
assert_equal expected, call_order
|
||||
|
@ -538,24 +653,20 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
|
|||
|
||||
_ = Class.new parent
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
with_output do
|
||||
@tu.run %w[--seed 42]
|
||||
end
|
||||
|
||||
# Once for the parent class, once for the child
|
||||
expected = [:setup_method, :test, :teardown_method] * 2
|
||||
|
||||
assert_equal expected, call_order
|
||||
end
|
||||
|
||||
def util_expand_bt bt
|
||||
if RUBY_VERSION >= '1.9.0' then
|
||||
bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
|
||||
else
|
||||
bt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
RUBY18 = ! defined? Encoding
|
||||
|
||||
def setup
|
||||
|
@ -633,6 +744,30 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
@tc.assert_equal 1, 1
|
||||
end
|
||||
|
||||
def test_assert_equal_different_collection_array_hex_invisible
|
||||
object1 = Object.new
|
||||
object2 = Object.new
|
||||
msg = "No visible difference in the Array#inspect output.
|
||||
You should look at the implementation of #== on Array or its members.
|
||||
[#<Object:0xXXXXXX>]".gsub(/^ +/, "")
|
||||
util_assert_triggered msg do
|
||||
@tc.assert_equal [object1], [object2]
|
||||
end
|
||||
end
|
||||
|
||||
def test_assert_equal_different_collection_hash_hex_invisible
|
||||
h1, h2 = {}, {}
|
||||
h1[1] = Object.new
|
||||
h2[1] = Object.new
|
||||
msg = "No visible difference in the Hash#inspect output.
|
||||
You should look at the implementation of #== on Hash or its members.
|
||||
{1=>#<Object:0xXXXXXX>}".gsub(/^ +/, "")
|
||||
|
||||
util_assert_triggered msg do
|
||||
@tc.assert_equal h1, h2
|
||||
end
|
||||
end
|
||||
|
||||
def test_assert_equal_different_diff_deactivated
|
||||
without_diff do
|
||||
util_assert_triggered util_msg("haha" * 10, "blah" * 10) do
|
||||
|
@ -667,8 +802,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
o1 = Object.new
|
||||
o2 = Object.new
|
||||
|
||||
msg = "No visible difference.
|
||||
You should look at your implementation of Object#==.
|
||||
msg = "No visible difference in the Object#inspect output.
|
||||
You should look at the implementation of #== on Object or its members.
|
||||
#<Object:0xXXXXXX>".gsub(/^ +/, "")
|
||||
|
||||
util_assert_triggered msg do
|
||||
|
@ -693,8 +828,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_assert_equal_different_long_invisible
|
||||
msg = "No visible difference.
|
||||
You should look at your implementation of String#==.
|
||||
msg = "No visible difference in the String#inspect output.
|
||||
You should look at the implementation of #== on String or its members.
|
||||
\"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
|
||||
|
||||
util_assert_triggered msg do
|
||||
|
@ -1181,6 +1316,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
|
||||
orig_verbose = $VERBOSE
|
||||
$VERBOSE = false
|
||||
|
||||
out, err = capture_io do
|
||||
puts 'hi'
|
||||
warn 'bye!'
|
||||
|
@ -1192,6 +1328,24 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
$VERBOSE = orig_verbose
|
||||
end
|
||||
|
||||
def test_capture_subprocess_io
|
||||
@assertion_count = 0
|
||||
skip "Dunno why but the parallel run of this fails"
|
||||
|
||||
orig_verbose = $VERBOSE
|
||||
$VERBOSE = false
|
||||
|
||||
out, err = capture_subprocess_io do
|
||||
system("echo 'hi'")
|
||||
system("echo 'bye!' 1>&2")
|
||||
end
|
||||
|
||||
assert_equal "hi\n", out
|
||||
assert_equal "bye!\n", err
|
||||
ensure
|
||||
$VERBOSE = orig_verbose
|
||||
end
|
||||
|
||||
def test_class_asserts_match_refutes
|
||||
@assertion_count = 0
|
||||
|
||||
|
@ -1215,15 +1369,6 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
assert_empty asserts.map { |n| n.sub(/^assert/, 'refute') } - refutes
|
||||
end
|
||||
|
||||
def test_class_test_suites
|
||||
@assertion_count = 0
|
||||
|
||||
tc = Class.new(MiniTest::Unit::TestCase)
|
||||
|
||||
assert_equal 1, MiniTest::Unit::TestCase.test_suites.size
|
||||
assert_equal [tc], MiniTest::Unit::TestCase.test_suites
|
||||
end
|
||||
|
||||
def test_expectation
|
||||
@assertion_count = 2
|
||||
|
||||
|
@ -1458,6 +1603,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
@assertion_count = 0
|
||||
|
||||
sample_test_case = Class.new MiniTest::Unit::TestCase do
|
||||
def self.test_order; :random; end
|
||||
def test_test1; assert "does not matter" end
|
||||
def test_test2; assert "does not matter" end
|
||||
def test_test3; assert "does not matter" end
|
||||
|
@ -1532,6 +1678,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
|
|||
end
|
||||
|
||||
class TestMiniTestGuard < MiniTest::Unit::TestCase
|
||||
parallelize_me! if ENV["PARALLEL"]
|
||||
|
||||
def test_mri_eh
|
||||
assert self.class.mri? "ruby blah"
|
||||
assert self.mri? "ruby blah"
|
||||
|
|
Loading…
Add table
Reference in a new issue