diff options
author | ryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-02 04:48:43 +0000 |
---|---|---|
committer | ryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-02 04:48:43 +0000 |
commit | f8e5c7c79e720d3b0af3cb96f27d421f08eb7744 (patch) | |
tree | 0d950c668cf9141d516152aa7ca117d62afa3676 /lib | |
parent | ce3029cd19dc40f4ffe09b8c6633500bd182b324 (diff) |
Imported minitest 4.7.4 (r8483)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40553 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/minitest/README.txt | 155 | ||||
-rw-r--r-- | lib/minitest/benchmark.rb | 43 | ||||
-rw-r--r-- | lib/minitest/hell.rb | 8 | ||||
-rw-r--r-- | lib/minitest/mock.rb | 6 | ||||
-rw-r--r-- | lib/minitest/parallel_each.rb | 46 | ||||
-rw-r--r-- | lib/minitest/spec.rb | 275 | ||||
-rw-r--r-- | lib/minitest/unit.rb | 249 |
7 files changed, 446 insertions, 336 deletions
diff --git a/lib/minitest/README.txt b/lib/minitest/README.txt index 6430c1b442..368cc3aa4e 100644 --- a/lib/minitest/README.txt +++ b/lib/minitest/README.txt @@ -104,7 +104,7 @@ 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 @@ -221,6 +221,14 @@ Output is tab-delimited to make it easy to paste into a spreadsheet. end end +A note on stubbing: In order to stub a method, the method must +actually exist prior to stubbing. Use a singleton method to create a +new non-existing method: + + def obj_under_test.fake_method + ... + end + === Customizable Test Runner Types: MiniTest::Unit.runner=(runner) provides an easy way of creating custom @@ -273,54 +281,113 @@ fixture loading: MiniTest::Unit.runner = MiniTestWithTransactions::Unit.new +== FAQ + +=== How to test SimpleDelegates? + +The following implementation and test: + + class Worker < SimpleDelegator + def work + end + end + + describe Worker do + before do + @worker = Worker.new(Object.new) + end + + it "must respond to work" do + @worker.must_respond_to :work + end + end + +outputs a failure: + + 1) Failure: + Worker#test_0001_must respond to work [bug11.rb:16]: + Expected #<Object:0x007f9e7184f0a0> (Object) to respond to #work. + +Worker is a SimpleDelegate which in 1.9+ is a subclass of BasicObject. +Expectations are put on Object (one level down) so the Worker +(SimpleDelegate) hits `method_missing` and delegates down to the +`Object.new` instance. That object doesn't respond to work so the test +fails. + +You can bypass `SimpleDelegate#method_missing` by extending the worker +with `MiniTest::Expectations`. You can either do that in your setup at +the instance level, like: + + before do + @worker = Worker.new(Object.new) + @worker.extend MiniTest::Expectations + end + +or you can extend the Worker class (within the test file!), like: + + class Worker + include ::MiniTest::Expectations + end + == 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-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. +capybara_minitest_spec :: Bridge between Capybara RSpec matchers and MiniTest::Spec expectations (e.g. page.must_have_content('Title')). +minispec-metadata :: Metadata for describe/it blocks + (e.g. `it 'requires JS driver', js: true do`) +minitest-ansi :: Colorize minitest output with ANSI colors. +minitest-around :: Around block for minitest. An alternative to setup/teardown dance. +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-english :: Semantically symmetric aliases for assertions and expectations. +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-great_expectations :: Generally useful additions to minitest's assertions and expectations +minitest-growl :: Test notifier for minitest via growl. +minitest-implicit-subject :: Implicit declaration of the test subject. +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-nc :: Test notifier for minitest via Mountain Lion's Notification Center +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-should_syntax :: RSpec-style +x.should == y+ assertions for MiniTest +minitest-shouldify :: Adding all manner of shoulds to MiniTest (bad idea) +minitest-spec-context :: Provides rspec-ish context method to MiniTest::Spec +minitest-spec-magic :: Minitest::Spec extensions for Rails and beyond +minitest-spec-rails :: Drop in MiniTest::Spec superclass for ActiveSupport::TestCase. +minitest-stub-const :: Stub constants for the duration of a block +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 @@ -328,16 +395,12 @@ Authors... Please send me a pull request with a description of your minitest ext * 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 @@ -358,7 +421,7 @@ the gem, but you'll need to activate the gem explicitly to use it: require 'rubygems' gem 'minitest' # ensures you're using the gem, and not the built in MT require 'minitest/autorun' - + # ... usual testing stuffs ... DO NOTE: There is a serious problem with the way that ruby 1.9/2.0 diff --git a/lib/minitest/benchmark.rb b/lib/minitest/benchmark.rb index 02121db340..e233282b0a 100644 --- a/lib/minitest/benchmark.rb +++ b/lib/minitest/benchmark.rb @@ -163,6 +163,26 @@ class MiniTest::Unit # :nodoc: ## # Runs the given +work+ and asserts that the times gathered fit to + # match a logarithmic curve within a given error +threshold+. + # + # Fit is calculated by #fit_logarithmic. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_logarithmic 0.9999 do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance_logarithmic threshold = 0.99, &work + assert_performance validation_for_fit(:logarithmic, threshold), &work + end + + ## + # Runs the given +work+ and asserts that the times gathered fit to # match a straight line within a given error +threshold+. # # Fit is calculated by #fit_linear. @@ -237,6 +257,29 @@ class MiniTest::Unit # :nodoc: end ## + # To fit a functional form: y = a + b*ln(x). + # + # Takes x and y values and returns [a, b, r^2]. + # + # See: http://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html + + def fit_logarithmic xs, ys + n = xs.size + xys = xs.zip(ys) + slnx2 = sigma(xys) { |x,y| Math.log(x) ** 2 } + slnx = sigma(xys) { |x,y| Math.log(x) } + sylnx = sigma(xys) { |x,y| y * Math.log(x) } + sy = sigma(xys) { |x,y| y } + + c = n * slnx2 - slnx ** 2 + b = ( n * sylnx - sy * slnx ) / c + a = (sy - b * slnx) / n + + return a, b, fit_error(xys) { |x| a + b * Math.log(x) } + end + + + ## # Fits the functional form: a + bx. # # Takes x and y values and returns [a, b, r^2]. diff --git a/lib/minitest/hell.rb b/lib/minitest/hell.rb index 0e4101f3f8..827bf0e320 100644 --- a/lib/minitest/hell.rb +++ b/lib/minitest/hell.rb @@ -5,12 +5,16 @@ # File a patch instead and assign it to Ryan Davis. ###################################################################### -class Minitest::Unit::TestCase # :nodoc: +require "minitest/parallel_each" + +# :stopdoc: +class Minitest::Unit::TestCase class << self alias :old_test_order :test_order - def test_order # :nodoc: + def test_order :parallel end end end +# :startdoc: diff --git a/lib/minitest/mock.rb b/lib/minitest/mock.rb index c636b9e901..a5b0f602f5 100644 --- a/lib/minitest/mock.rb +++ b/lib/minitest/mock.rb @@ -5,8 +5,7 @@ # File a patch instead and assign it to Ryan Davis. ###################################################################### -class MockExpectationError < StandardError # :nodoc: -end # omg... worst bug ever. rdoc doesn't allow 1-liners +class MockExpectationError < StandardError; end # :nodoc: ## # A simple and clean mock object framework. @@ -159,7 +158,8 @@ class Object # :nodoc: # Add a temporary stubbed method replacing +name+ for the duration # of the +block+. If +val_or_callable+ responds to #call, then it # returns the result of calling it, otherwise returns the value - # as-is. Cleans up the stub at the end of the +block+. + # as-is. Cleans up the stub at the end of the +block+. The method + # +name+ must exist before stubbing. # # def test_stale_eh # obj_under_test = Something.new diff --git a/lib/minitest/parallel_each.rb b/lib/minitest/parallel_each.rb index d501aa34ef..e1020b35a0 100644 --- a/lib/minitest/parallel_each.rb +++ b/lib/minitest/parallel_each.rb @@ -5,12 +5,24 @@ # File a patch instead and assign it to Ryan Davis. ###################################################################### +## +# Provides a parallel #each that lets you enumerate using N threads. +# Use environment variable N to customize. Defaults to 2. Enumerable, +# so all the goodies come along (tho not all are wrapped yet to +# return another ParallelEach instance). + class ParallelEach require 'thread' include Enumerable + ## + # How many Threads to use for this parallel #each. + N = (ENV['N'] || 2).to_i + ## + # Create a new ParallelEach instance over +list+. + def initialize list @queue = Queue.new # *sigh*... the Queue api sucks sooo much... @@ -18,10 +30,20 @@ class ParallelEach N.times { @queue << nil } end - def grep pattern + def grep pattern # :nodoc: self.class.new super end + def select(&block) # :nodoc: + self.class.new super + end + + alias find_all select # :nodoc: + + ## + # Starts N threads that yield each element to your block. Joins the + # threads at the end. + def each threads = N.times.map { Thread.new do @@ -33,4 +55,26 @@ class ParallelEach } threads.map(&:join) end + + def count + [@queue.size - N, 0].max + end + + alias_method :size, :count +end + +class MiniTest::Unit + alias _old_run_suites _run_suites + + ## + # 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 + 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 end diff --git a/lib/minitest/spec.rb b/lib/minitest/spec.rb index 7588982038..c8584f6e4a 100644 --- a/lib/minitest/spec.rb +++ b/lib/minitest/spec.rb @@ -66,7 +66,7 @@ module Kernel # :nodoc: def describe desc, additional_desc = nil, &block # :doc: stack = MiniTest::Spec.describe_stack name = [stack.last, desc, additional_desc].compact.join("::") - sclas = stack.last || if Class === self && self < MiniTest::Spec then + sclas = stack.last || if Class === self && is_a?(MiniTest::Spec::DSL) then self else MiniTest::Spec.spec_type desc @@ -88,173 +88,184 @@ end # For a list of expectations, see MiniTest::Expectations. class MiniTest::Spec < MiniTest::Unit::TestCase - ## - # Contains pairs of matchers and Spec classes to be used to - # calculate the superclass of a top-level describe. This allows for - # automatically customizable spec types. - # - # See: register_spec_type and spec_type - - TYPES = [[//, MiniTest::Spec]] - - ## - # Register a new type of spec that matches the spec's description. - # This method can take either a Regexp and a spec class or a spec - # class and a block that takes the description and returns true if - # it matches. - # - # Eg: - # - # register_spec_type(/Controller$/, MiniTest::Spec::Rails) - # - # or: - # - # register_spec_type(MiniTest::Spec::RailsModel) do |desc| - # desc.superclass == ActiveRecord::Base - # end - - def self.register_spec_type(*args, &block) - if block then - matcher, klass = block, args.first - else - matcher, klass = *args - end - TYPES.unshift [matcher, klass] - end ## - # Figure out the spec class to use based on a spec's description. Eg: - # - # spec_type("BlahController") # => MiniTest::Spec::Rails - - def self.spec_type desc - TYPES.find { |matcher, klass| - if matcher.respond_to? :call then - matcher.call desc + # Oh look! A MiniTest::Spec::DSL module! Eat your heart out DHH. + + module DSL + ## + # Contains pairs of matchers and Spec classes to be used to + # calculate the superclass of a top-level describe. This allows for + # automatically customizable spec types. + # + # See: register_spec_type and spec_type + + TYPES = [[//, MiniTest::Spec]] + + ## + # Register a new type of spec that matches the spec's description. + # This method can take either a Regexp and a spec class or a spec + # class and a block that takes the description and returns true if + # it matches. + # + # Eg: + # + # register_spec_type(/Controller$/, MiniTest::Spec::Rails) + # + # or: + # + # register_spec_type(MiniTest::Spec::RailsModel) do |desc| + # desc.superclass == ActiveRecord::Base + # end + + def register_spec_type(*args, &block) + if block then + matcher, klass = block, args.first else - matcher === desc.to_s + matcher, klass = *args end - }.last - end - - @@describe_stack = [] - def self.describe_stack # :nodoc: - @@describe_stack - end + TYPES.unshift [matcher, klass] + end - ## - # Returns the children of this spec. + ## + # Figure out the spec class to use based on a spec's description. Eg: + # + # spec_type("BlahController") # => MiniTest::Spec::Rails - def self.children - @children ||= [] - end + def spec_type desc + TYPES.find { |matcher, klass| + if matcher.respond_to? :call then + matcher.call desc + else + matcher === desc.to_s + end + }.last + end - def self.nuke_test_methods! # :nodoc: - self.public_instance_methods.grep(/^test_/).each do |name| - self.send :undef_method, name + @@describe_stack = [] + def describe_stack # :nodoc: + @@describe_stack end - end - ## - # Define a 'before' action. Inherits the way normal methods should. - # - # NOTE: +type+ is ignored and is only there to make porting easier. - # - # Equivalent to MiniTest::Unit::TestCase#setup. + ## + # Returns the children of this spec. - def self.before type = nil, &block - define_method :setup do - super() - self.instance_eval(&block) + def children + @children ||= [] end - end - ## - # Define an 'after' action. Inherits the way normal methods should. - # - # NOTE: +type+ is ignored and is only there to make porting easier. - # - # Equivalent to MiniTest::Unit::TestCase#teardown. + def nuke_test_methods! # :nodoc: + self.public_instance_methods.grep(/^test_/).each do |name| + self.send :undef_method, name + end + end - def self.after type = nil, &block - define_method :teardown do - self.instance_eval(&block) - super() + ## + # Define a 'before' action. Inherits the way normal methods should. + # + # NOTE: +type+ is ignored and is only there to make porting easier. + # + # Equivalent to MiniTest::Unit::TestCase#setup. + + def before type = nil, &block + define_method :setup do + super() + self.instance_eval(&block) + end end - end - ## - # Define an expectation with name +desc+. Name gets morphed to a - # proper test method name. For some freakish reason, people who - # write specs don't like class inheritence, so this goes way out of - # its way to make sure that expectations aren't inherited. - # - # This is also aliased to #specify and doesn't require a +desc+ arg. - # - # Hint: If you _do_ want inheritence, use minitest/unit. You can mix - # and match between assertions and expectations as much as you want. + ## + # Define an 'after' action. Inherits the way normal methods should. + # + # NOTE: +type+ is ignored and is only there to make porting easier. + # + # Equivalent to MiniTest::Unit::TestCase#teardown. + + def after type = nil, &block + define_method :teardown do + self.instance_eval(&block) + super() + end + end + + ## + # Define an expectation with name +desc+. Name gets morphed to a + # proper test method name. For some freakish reason, people who + # write specs don't like class inheritance, so this goes way out of + # its way to make sure that expectations aren't inherited. + # + # This is also aliased to #specify and doesn't require a +desc+ arg. + # + # Hint: If you _do_ want inheritence, use minitest/unit. You can mix + # and match between assertions and expectations as much as you want. + + def it desc = "anonymous", &block + block ||= proc { skip "(no tests defined)" } - def self.it desc = "anonymous", &block - block ||= proc { skip "(no tests defined)" } + @specs ||= 0 + @specs += 1 - @specs ||= 0 - @specs += 1 + name = "test_%04d_%s" % [ @specs, desc ] - name = "test_%04d_%s" % [ @specs, desc ] + define_method name, &block - define_method name, &block + self.children.each do |mod| + mod.send :undef_method, name if mod.public_method_defined? name + end - self.children.each do |mod| - mod.send :undef_method, name if mod.public_method_defined? name + name end - name - end + ## + # Essentially, define an accessor for +name+ with +block+. + # + # Why use let instead of def? I honestly don't know. - ## - # Essentially, define an accessor for +name+ with +block+. - # - # Why use let instead of def? I honestly don't know. + def let name, &block + define_method name do + @_memoized ||= {} + @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) } + end + end - def self.let name, &block - define_method name do - @_memoized ||= {} - @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) } + ## + # Another lazy man's accessor generator. Made even more lazy by + # setting the name for you to +subject+. + + def subject &block + let :subject, &block end - end - ## - # Another lazy man's accessor generator. Made even more lazy by - # setting the name for you to +subject+. + def create name, desc # :nodoc: + cls = Class.new(self) do + @name = name + @desc = desc - def self.subject &block - let :subject, &block - end + nuke_test_methods! + end - def self.create name, desc # :nodoc: - cls = Class.new(self) do - @name = name - @desc = desc + children << cls - nuke_test_methods! + cls end - children << cls - - cls - end + def name # :nodoc: + defined?(@name) ? @name : super + end - def self.to_s # :nodoc: - defined?(@name) ? @name : super - end + def to_s # :nodoc: + name # Can't alias due to 1.8.7, not sure why + end - # :stopdoc: - class << self + # :stopdoc: attr_reader :desc alias :specify :it - alias :name :to_s + # :startdoc: end - # :startdoc: + + extend DSL + + TYPES = DSL::TYPES # :nodoc: end ## diff --git a/lib/minitest/unit.rb b/lib/minitest/unit.rb index a221dda4b4..a29c8ec93b 100644 --- a/lib/minitest/unit.rb +++ b/lib/minitest/unit.rb @@ -5,10 +5,8 @@ # File a patch instead and assign it to Ryan Davis. ###################################################################### -require 'optparse' -require 'rbconfig' -require 'thread' # required for 1.8 -require 'minitest/parallel_each' +require "optparse" +require "rbconfig" ## # Minimal (mostly drop-in) replacement for test-unit. @@ -40,6 +38,9 @@ module MiniTest class Skip < Assertion; end class << self + ## + # Filter object for backtraces. + attr_accessor :backtrace_filter end @@ -87,16 +88,17 @@ module MiniTest # figure out what diff to use. def self.diff - @diff = if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ then + @diff = if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ && + system("diff.exe", __FILE__, __FILE__)) then "diff.exe -u" + elsif Minitest::Unit::Guard.maglev? then # HACK + "diff -u" + elsif system("gdiff", __FILE__, __FILE__) + "gdiff -u" # solaris and kin suck + elsif system("diff", __FILE__, __FILE__) + "diff -u" else - if system("gdiff", __FILE__, __FILE__) - "gdiff -u" # solaris and kin suck - elsif system("diff", __FILE__, __FILE__) - "diff -u" - else - nil - end + nil end unless defined? @diff @diff @@ -177,8 +179,8 @@ module MiniTest # newlines and makes hex-values generic (like object_ids). This # uses mu_pp to do the first pass and then cleans it up. - def mu_pp_for_diff obj # TODO: possibly rename - mu_pp(obj).gsub(/\\n/, "\n").gsub(/0x[a-f0-9]+/m, '0xXXXXXX') + def mu_pp_for_diff obj + mu_pp(obj).gsub(/\\n/, "\n").gsub(/:0x[a-fA-F0-9]{4,}/m, ':0xXXXXXX') end def _assertions= n # :nodoc: @@ -203,18 +205,6 @@ module MiniTest end ## - # Fails unless the block returns a true value. - # - # NOTE: This method is deprecated, use assert. It will be removed - # on 2013-01-01." - - def assert_block msg = nil - warn "NOTE: MiniTest::Unit::TestCase#assert_block is deprecated, use assert. It will be removed on 2013-01-01. Called from #{caller.first}" - msg = message(msg) { "Expected block to return true value" } - assert yield, msg - end - - ## # Fails unless +obj+ is empty. def assert_empty obj, msg = nil @@ -237,7 +227,7 @@ module MiniTest def assert_equal exp, act, msg = nil msg = message(msg, "") { diff exp, act } - assert(exp == act, msg) + assert exp == act, msg end ## @@ -248,7 +238,9 @@ module MiniTest def assert_in_delta exp, act, delta = 0.001, msg = nil n = (exp - act).abs - msg = message(msg) { "Expected |#{exp} - #{act}| (#{n}) to be < #{delta}"} + msg = message(msg) { + "Expected |#{exp} - #{act}| (#{n}) to be <= #{delta}" + } assert delta >= n, msg end @@ -562,6 +554,7 @@ module MiniTest def message msg = nil, ending = ".", &default proc { + msg = msg.call.chomp(".") if Proc === msg custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? "#{custom_message}#{default.call}#{ending}" } @@ -611,9 +604,9 @@ module MiniTest def refute_in_delta exp, act, delta = 0.001, msg = nil n = (exp - act).abs msg = message(msg) { - "Expected |#{exp} - #{act}| (#{n}) to not be < #{delta}" + "Expected |#{exp} - #{act}| (#{n}) to not be <= #{delta}" } - refute delta > n, msg + refute delta >= n, msg end ## @@ -723,10 +716,18 @@ module MiniTest def skip msg = nil, bt = caller msg ||= "Skipped, no message given" + @skip = true raise MiniTest::Skip, msg, bt end ## + # Was this testcase skipped? Meant for #teardown. + + def skipped? + defined?(@skip) and @skip + end + + ## # Takes a block and wraps it with the runner's shared mutex. def synchronize @@ -737,16 +738,28 @@ module MiniTest end class Unit # :nodoc: - VERSION = "4.3.2" # :nodoc: + VERSION = "4.7.4" # :nodoc: attr_accessor :report, :failures, :errors, :skips # :nodoc: - attr_accessor :test_count, :assertion_count # :nodoc: + attr_accessor :assertion_count # :nodoc: + attr_writer :test_count # :nodoc: attr_accessor :start_time # :nodoc: attr_accessor :help # :nodoc: attr_accessor :verbose # :nodoc: attr_writer :options # :nodoc: ## + # :attr: + # + # if true, installs an "INFO" signal handler (only available to BSD and + # OS X users) which prints diagnostic information about the test run. + # + # This is auto-detected by default but may be overridden by custom + # runners. + + attr_accessor :info_signal + + ## # Lazy accessor for options. def options @@ -847,6 +860,10 @@ module MiniTest output.print(*a) end + def test_count # :nodoc: + @test_count ||= 0 + end + ## # Runner for a given +type+ (eg, test vs bench). @@ -888,15 +905,13 @@ module MiniTest end ## - # Runs all the +suites+ for a given +type+. Runs suites declaring - # a test_order of +:parallel+ in parallel, and everything else - # serial. + # Runs all the +suites+ for a given +type+. + # + # NOTE: this method is redefined in parallel_each.rb, which is + # loaded if a test-suite calls parallelize_me!. def _run_suites suites, 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 } + suites.map { |suite| _run_suite suite, type } end ## @@ -909,7 +924,13 @@ module MiniTest filter = options[:filter] || '/./' filter = Regexp.new $1 if filter =~ /\/(.*)\// - assertions = suite.send("#{type}_methods").grep(filter).map { |method| + all_test_methods = suite.send "#{type}_methods" + + filtered_test_methods = all_test_methods.find_all { |m| + filter === m || filter === "#{suite}##{m}" + } + + assertions = filtered_test_methods.map { |method| inst = suite.new method inst._assertions = 0 @@ -929,7 +950,7 @@ module MiniTest end ## - # Record the result of a single run. Makes it very easy to gather + # Record the result of a single test. Makes it very easy to gather # information. Eg: # # class StatisticsRecorder < MiniTest::Unit @@ -939,6 +960,11 @@ module MiniTest # end # # MiniTest::Unit.runner = StatisticsRecorder.new + # + # NOTE: record might be sent more than once per test. It will be + # sent once with the results from the test itself. If there is a + # failure or error in teardown, it will be sent again with the + # error or failure. def record suite, method, assertions, time, error end @@ -961,14 +987,14 @@ module MiniTest when MiniTest::Skip then @skips += 1 return "S" unless @verbose - "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" + "Skipped:\n#{klass}##{meth} [#{location e}]:\n#{e.message}\n" when MiniTest::Assertion then @failures += 1 - "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" + "Failure:\n#{klass}##{meth} [#{location e}]:\n#{e.message}\n" else @errors += 1 bt = MiniTest::filter_backtrace(e.backtrace).join "\n " - "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n #{bt}\n" + "Error:\n#{klass}##{meth}:\n#{e.class}: #{e.message}\n #{bt}\n" end @report << e e[0, 1] @@ -978,11 +1004,16 @@ module MiniTest @report = [] @errors = @failures = @skips = 0 @verbose = false - @mutex = Mutex.new + @mutex = defined?(Mutex) ? Mutex.new : nil + @info_signal = Signal.list['INFO'] end def synchronize # :nodoc: - @mutex.synchronize { yield } + if @mutex then + @mutex.synchronize { yield } + else + yield + end end def process_args args = [] # :nodoc: @@ -1039,7 +1070,8 @@ module MiniTest # Top level driver, controls all output and filtering. def _run args = [] - self.options = process_args args + args = process_args args # ARGH!! blame test/unit process_args + self.options.merge! args puts "Run options: #{help}" @@ -1048,7 +1080,7 @@ module MiniTest break unless report.empty? end - return failures + errors if @test_count > 0 # or return nil... + return failures + errors if self.test_count > 0 # or return nil... rescue Interrupt abort 'Interrupted' end @@ -1095,6 +1127,15 @@ module MiniTest ## # Is this running on mri? + def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE + "maglev" == platform + end + + module_function :maglev? + + ## + # Is this running on mri? + def mri? platform = RUBY_DESCRIPTION /^ruby/ =~ platform end @@ -1183,79 +1224,6 @@ module MiniTest def after_teardown; end end - module Deprecated # :nodoc: - - ## - # This entire module is deprecated and slated for removal on 2013-01-01. - - module Hooks - def run_setup_hooks # :nodoc: - _run_hooks self.class.setup_hooks - end - - def _run_hooks hooks # :nodoc: - hooks.each do |hook| - if hook.respond_to?(:arity) && hook.arity == 1 - hook.call(self) - else - hook.call - end - 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. - # - # NOTE: This method is deprecated, use before/after_teardown. It - # will be removed on 2013-01-01. - - 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 teardown_hooks # :nodoc: - if superclass.respond_to? :teardown_hooks then - superclass.teardown_hooks - else - [] - end + @teardown_hooks - end - end - end - ## # Subclass TestCase to create your own tests. Typically you'll want a # TestCase subclass per implementation class. @@ -1264,8 +1232,6 @@ module MiniTest class TestCase include LifecycleHooks - include Deprecated::Hooks - extend Deprecated::HooksCM # UGH... I can't wait 'til 2013! include Guard extend Guard @@ -1274,8 +1240,6 @@ module MiniTest PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt, SystemExit] # :nodoc: - SUPPORTS_INFO_SIGNAL = Signal.list['INFO'] # :nodoc: - ## # Runs the tests reporting the status to +runner+ @@ -1288,7 +1252,7 @@ module MiniTest time = runner.start_time ? Time.now - runner.start_time : 0 warn "Current Test: %s#%s %.2fs" % [self.class, self.__name__, time] runner.status $stderr - end if SUPPORTS_INFO_SIGNAL + end if runner.info_signal start_time = Time.now @@ -1306,7 +1270,7 @@ module MiniTest rescue *PASSTHROUGH_EXCEPTIONS raise rescue Exception => e - @passed = false + @passed = Skip === e time = Time.now - start_time runner.record self.class, self.__name__, self._assertions, time, e result = runner.puke self.class, self.__name__, e @@ -1318,10 +1282,11 @@ module MiniTest raise rescue Exception => e @passed = false + runner.record self.class, self.__name__, self._assertions, time, e result = runner.puke self.class, self.__name__, e end end - trap 'INFO', 'DEFAULT' if SUPPORTS_INFO_SIGNAL + trap 'INFO', 'DEFAULT' if runner.info_signal end result end @@ -1332,11 +1297,11 @@ module MiniTest @__name__ = name @__io__ = nil @passed = nil - @@current = self + @@current = self # FIX: make thread local end def self.current # :nodoc: - @@current + @@current # FIX: make thread local end ## @@ -1392,6 +1357,8 @@ module MiniTest # and your tests are awesome. def self.parallelize_me! + require "minitest/parallel_each" + class << self undef_method :test_order if method_defined? :test_order define_method :test_order do :parallel end @@ -1400,7 +1367,6 @@ module MiniTest def self.inherited klass # :nodoc: @@test_suites[klass] = true - klass.reset_setup_teardown_hooks super end @@ -1448,30 +1414,9 @@ module MiniTest def teardown; end - def self.reset_setup_teardown_hooks # :nodoc: - # also deprecated... believe it. - @setup_hooks = [] - @teardown_hooks = [] - end - - reset_setup_teardown_hooks - include MiniTest::Assertions end # class TestCase end # class Unit end # module MiniTest Minitest = MiniTest # :nodoc: because ugh... I typo this all the time - -if $DEBUG then - module Test # :nodoc: - module Unit # :nodoc: - class TestCase # :nodoc: - def self.inherited x # :nodoc: - # this helps me ferret out porting issues - raise "Using minitest and test/unit in the same process: #{x}" - end - end - end - end -end |