summaryrefslogtreecommitdiff
path: root/test/lib/minitest
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2019-06-29 19:43:47 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2019-07-02 07:59:54 +0900
commitc3c0e3f5c9444c197779cb242de46dfffda79dec (patch)
tree03866471345f8c9baa68d548340199408aa51405 /test/lib/minitest
parent142617c8e1cad65fa483c5beb78ab40a99626a87 (diff)
Move to tool/lib from test/lib.
Diffstat (limited to 'test/lib/minitest')
-rw-r--r--test/lib/minitest/README.txt457
-rw-r--r--test/lib/minitest/autorun.rb14
-rw-r--r--test/lib/minitest/benchmark.rb418
-rw-r--r--test/lib/minitest/mock.rb196
-rw-r--r--test/lib/minitest/unit.rb1420
5 files changed, 0 insertions, 2505 deletions
diff --git a/test/lib/minitest/README.txt b/test/lib/minitest/README.txt
deleted file mode 100644
index 368cc3aa4e..0000000000
--- a/test/lib/minitest/README.txt
+++ /dev/null
@@ -1,457 +0,0 @@
-= minitest/{unit,spec,mock,benchmark}
-
-home :: https://github.com/seattlerb/minitest
-rdoc :: http://docs.seattlerb.org/minitest
-vim :: https://github.com/sunaku/vim-ruby-minitest
-
-== DESCRIPTION:
-
-minitest provides a complete suite of testing facilities supporting
-TDD, BDD, mocking, and benchmarking.
-
- "I had a class with Jim Weirich on testing last week and we were
- allowed to choose our testing frameworks. Kirk Haines and I were
- paired up and we cracked open the code for a few test
- frameworks...
-
- I MUST say that minitest is *very* readable / understandable
- compared to the 'other two' options we looked at. Nicely done and
- thank you for helping us keep our mental sanity."
-
- -- Wayne E. Seguin
-
-minitest/unit is a small and incredibly fast unit testing framework.
-It provides a rich set of assertions to make your tests clean and
-readable.
-
-minitest/spec is a functionally complete spec engine. It hooks onto
-minitest/unit and seamlessly bridges test assertions over to spec
-expectations.
-
-minitest/benchmark is an awesome way to assert the performance of your
-algorithms in a repeatable manner. Now you can assert that your newb
-co-worker doesn't replace your linear algorithm with an exponential
-one!
-
-minitest/mock by Steven Baker, is a beautifully tiny mock (and stub)
-object framework.
-
-minitest/pride shows pride in testing and adds coloring to your test
-output. I guess it is an example of how to write IO pipes too. :P
-
-minitest/unit is meant to have a clean implementation for language
-implementors that need a minimal set of methods to bootstrap a working
-test suite. For example, there is no magic involved for test-case
-discovery.
-
- "Again, I can't praise enough the idea of a testing/specing
- framework that I can actually read in full in one sitting!"
-
- -- 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.
-* minitest/unit - a very fast, simple, and clean test system.
-* minitest/spec - a very fast, simple, and clean spec system.
-* minitest/mock - a simple and clean mock/stub system.
-* minitest/benchmark - an awesome way to assert your algorithm's performance.
-* minitest/pride - show your pride in testing!
-* Incredibly small and fast runner, but no bells and whistles.
-
-== RATIONALE:
-
-See design_rationale.rb to see how specs and tests work in minitest.
-
-== SYNOPSIS:
-
-Given that you'd like to test the following class:
-
- class Meme
- def i_can_has_cheezburger?
- "OHAI!"
- end
-
- def will_it_blend?
- "YES!"
- end
- end
-
-=== Unit tests
-
- require 'minitest/autorun'
-
- class TestMeme < MiniTest::Unit::TestCase
- def setup
- @meme = Meme.new
- end
-
- def test_that_kitty_can_eat
- assert_equal "OHAI!", @meme.i_can_has_cheezburger?
- end
-
- 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
-
- require 'minitest/autorun'
-
- describe Meme do
- before do
- @meme = Meme.new
- end
-
- describe "when asked about cheeseburgers" do
- it "must respond positively" do
- @meme.i_can_has_cheezburger?.must_equal "OHAI!"
- end
- end
-
- describe "when asked about blending possibilities" do
- it "won't say no" do
- @meme.will_it_blend?.wont_match /^no/i
- end
- end
- end
-
-For matchers support check out:
-
-https://github.com/zenspider/minitest-matchers
-
-=== Benchmarks
-
-Add benchmarks to your regular unit tests. If the unit tests fail, the
-benchmarks won't run.
-
- # optionally run benchmarks, good for CI-only work!
- require 'minitest/benchmark' if ENV["BENCH"]
-
- class TestMeme < MiniTest::Unit::TestCase
- # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]
- def bench_my_algorithm
- assert_performance_linear 0.9999 do |n| # n is a range value
- @obj.my_algorithm(n)
- end
- end
- end
-
-Or add them to your specs. If you make benchmarks optional, you'll
-need to wrap your benchmarks in a conditional since the methods won't
-be defined.
-
- describe Meme do
- if ENV["BENCH"] then
- bench_performance_linear "my_algorithm", 0.9999 do |n|
- 100.times do
- @obj.my_algorithm(n)
- end
- end
- end
- end
-
-outputs something like:
-
- # Running benchmarks:
-
- TestBlah 100 1000 10000
- bench_my_algorithm 0.006167 0.079279 0.786993
- bench_other_algorithm 0.061679 0.792797 7.869932
-
-Output is tab-delimited to make it easy to paste into a spreadsheet.
-
-=== Mocks
-
- class MemeAsker
- def initialize(meme)
- @meme = meme
- end
-
- def ask(question)
- method = question.tr(" ","_") + "?"
- @meme.__send__(method)
- end
- end
-
- require 'minitest/autorun'
-
- describe MemeAsker do
- before do
- @meme = MiniTest::Mock.new
- @meme_asker = MemeAsker.new @meme
- end
-
- describe "#ask" do
- describe "when passed an unpunctuated question" do
- it "should invoke the appropriate predicate method on the meme" do
- @meme.expect :will_it_blend?, :return_value
- @meme_asker.ask "will it blend"
- @meme.verify
- end
- end
- end
- end
-
-=== Stubs
-
- def test_stale_eh
- obj_under_test = Something.new
-
- refute obj_under_test.stale?
-
- Time.stub :now, Time.at(0) do # stub goes away once the block is done
- assert obj_under_test.stale?
- 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
-test runners for specialized needs. Justin Weiss provides the
-following real-world example to create an alternative to regular
-fixture loading:
-
- class MiniTestWithHooks::Unit < MiniTest::Unit
- def before_suites
- end
-
- def after_suites
- end
-
- def _run_suites(suites, type)
- begin
- before_suites
- super(suites, type)
- ensure
- after_suites
- end
- end
-
- def _run_suite(suite, type)
- begin
- suite.before_suite
- super(suite, type)
- ensure
- suite.after_suite
- end
- end
- end
-
- module MiniTestWithTransactions
- class Unit < MiniTestWithHooks::Unit
- include TestSetupHelper
-
- def before_suites
- super
- setup_nested_transactions
- # load any data we want available for all tests
- end
-
- def after_suites
- teardown_nested_transactions
- super
- end
- end
- end
-
- 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:
-
-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
-* detroit-minitest
-* em-minitest-spec
-* flexmock-minitest
-* guard-minitest
-* guard-minitest-decisiv
-* minitest-activemodel
-* minitest-ar-assertions
-* minitest-capybara-unit
-* minitest-colorer
-* minitest-deluxe
-* minitest-extra-assertions
-* minitest-rails-shoulda
-* minitest-spec
-* minitest-spec-should
-* minitest-sugar
-* minitest_should
-* mongoid-minitest
-* spork-minitest
-
-== REQUIREMENTS:
-
-* Ruby 1.8, maybe even 1.6 or lower. No magic is involved.
-
-== INSTALL:
-
- sudo gem install minitest
-
-On 1.9, you already have it. To get newer candy you can still install
-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
-packages their own gems. They install a gem specification file, but
-don't install the gem contents in the gem path. This messes up
-Gem.find_files and many other things (gem which, gem contents, etc).
-
-Just install minitest as a gem for real and you'll be happier.
-
-== LICENSE:
-
-(The MIT License)
-
-Copyright (c) Ryan Davis, seattle.rb
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/test/lib/minitest/autorun.rb b/test/lib/minitest/autorun.rb
deleted file mode 100644
index 844096623c..0000000000
--- a/test/lib/minitest/autorun.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: true
-
-begin
- require 'rubygems'
- gem 'minitest'
-rescue Gem::LoadError
- # do nothing
-end
-
-require 'minitest/unit'
-require 'minitest/mock'
-
-MiniTest::Unit.autorun
diff --git a/test/lib/minitest/benchmark.rb b/test/lib/minitest/benchmark.rb
deleted file mode 100644
index b3f2bc28b3..0000000000
--- a/test/lib/minitest/benchmark.rb
+++ /dev/null
@@ -1,418 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: true
-
-require 'minitest/unit'
-
-class MiniTest::Unit # :nodoc:
- def run_benchmarks # :nodoc:
- _run_anything :benchmark
- end
-
- def benchmark_suite_header suite # :nodoc:
- "\n#{suite}\t#{suite.bench_range.join("\t")}"
- end
-
- class TestCase
- ##
- # Returns a set of ranges stepped exponentially from +min+ to
- # +max+ by powers of +base+. Eg:
- #
- # bench_exp(2, 16, 2) # => [2, 4, 8, 16]
-
- def self.bench_exp min, max, base = 10
- min = (Math.log10(min) / Math.log10(base)).to_i
- max = (Math.log10(max) / Math.log10(base)).to_i
-
- (min..max).map { |m| base ** m }.to_a
- end
-
- ##
- # Returns a set of ranges stepped linearly from +min+ to +max+ by
- # +step+. Eg:
- #
- # bench_linear(20, 40, 10) # => [20, 30, 40]
-
- def self.bench_linear min, max, step = 10
- (min..max).step(step).to_a
- rescue LocalJumpError # 1.8.6
- r = []; (min..max).step(step) { |n| r << n }; r
- end
-
- ##
- # Returns the benchmark methods (methods that start with bench_)
- # for that class.
-
- def self.benchmark_methods # :nodoc:
- public_instance_methods(true).grep(/^bench_/).map { |m| m.to_s }.sort
- end
-
- ##
- # Returns all test suites that have benchmark methods.
-
- def self.benchmark_suites
- TestCase.test_suites.reject { |s| s.benchmark_methods.empty? }
- end
-
- ##
- # Specifies the ranges used for benchmarking for that class.
- # Defaults to exponential growth from 1 to 10k by powers of 10.
- # Override if you need different ranges for your benchmarks.
- #
- # See also: ::bench_exp and ::bench_linear.
-
- def self.bench_range
- bench_exp 1, 10_000
- end
-
- ##
- # Runs the given +work+, gathering the times of each run. Range
- # and times are then passed to a given +validation+ proc. Outputs
- # the benchmark name and times in tab-separated format, making it
- # easy to paste into a spreadsheet for graphing or further
- # analysis.
- #
- # Ranges are specified by ::bench_range.
- #
- # Eg:
- #
- # def bench_algorithm
- # validation = proc { |x, y| ... }
- # assert_performance validation do |n|
- # @obj.algorithm(n)
- # end
- # end
-
- def assert_performance validation, &work
- range = self.class.bench_range
-
- io.print "#{__name__}"
-
- times = []
-
- range.each do |x|
- GC.start
- t0 = Time.now
- instance_exec(x, &work)
- t = Time.now - t0
-
- io.print "\t%9.6f" % t
- times << t
- end
- io.puts
-
- validation[range, times]
- end
-
- ##
- # Runs the given +work+ and asserts that the times gathered fit to
- # match a constant rate (eg, linear slope == 0) within a given
- # +threshold+. Note: because we're testing for a slope of 0, R^2
- # is not a good determining factor for the fit, so the threshold
- # is applied against the slope itself. As such, you probably want
- # to tighten it from the default.
- #
- # See http://www.graphpad.com/curvefit/goodness_of_fit.htm for
- # more details.
- #
- # Fit is calculated by #fit_linear.
- #
- # Ranges are specified by ::bench_range.
- #
- # Eg:
- #
- # def bench_algorithm
- # assert_performance_constant 0.9999 do |n|
- # @obj.algorithm(n)
- # end
- # end
-
- def assert_performance_constant threshold = 0.99, &work
- validation = proc do |range, times|
- a, b, rr = fit_linear range, times
- assert_in_delta 0, b, 1 - threshold
- [a, b, rr]
- end
-
- assert_performance validation, &work
- end
-
- ##
- # Runs the given +work+ and asserts that the times gathered fit to
- # match a exponential curve within a given error +threshold+.
- #
- # Fit is calculated by #fit_exponential.
- #
- # Ranges are specified by ::bench_range.
- #
- # Eg:
- #
- # def bench_algorithm
- # assert_performance_exponential 0.9999 do |n|
- # @obj.algorithm(n)
- # end
- # end
-
- def assert_performance_exponential threshold = 0.99, &work
- assert_performance validation_for_fit(:exponential, threshold), &work
- end
-
- ##
- # 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.
- #
- # Ranges are specified by ::bench_range.
- #
- # Eg:
- #
- # def bench_algorithm
- # assert_performance_linear 0.9999 do |n|
- # @obj.algorithm(n)
- # end
- # end
-
- def assert_performance_linear threshold = 0.99, &work
- assert_performance validation_for_fit(:linear, threshold), &work
- end
-
- ##
- # Runs the given +work+ and asserts that the times gathered curve
- # fit to match a power curve within a given error +threshold+.
- #
- # Fit is calculated by #fit_power.
- #
- # Ranges are specified by ::bench_range.
- #
- # Eg:
- #
- # def bench_algorithm
- # assert_performance_power 0.9999 do |x|
- # @obj.algorithm
- # end
- # end
-
- def assert_performance_power threshold = 0.99, &work
- assert_performance validation_for_fit(:power, threshold), &work
- end
-
- ##
- # Takes an array of x/y pairs and calculates the general R^2 value.
- #
- # See: http://en.wikipedia.org/wiki/Coefficient_of_determination
-
- def fit_error xys
- y_bar = sigma(xys) { |x, y| y } / xys.size.to_f
- ss_tot = sigma(xys) { |x, y| (y - y_bar) ** 2 }
- ss_err = sigma(xys) { |x, y| (yield(x) - y) ** 2 }
-
- 1 - (ss_err / ss_tot)
- end
-
- ##
- # To fit a functional form: y = ae^(bx).
- #
- # Takes x and y values and returns [a, b, r^2].
- #
- # See: http://mathworld.wolfram.com/LeastSquaresFittingExponential.html
-
- def fit_exponential xs, ys
- n = xs.size
- xys = xs.zip(ys)
- sxlny = sigma(xys) { |x,y| x * Math.log(y) }
- slny = sigma(xys) { |x,y| Math.log(y) }
- sx2 = sigma(xys) { |x,y| x * x }
- sx = sigma xs
-
- c = n * sx2 - sx ** 2
- a = (slny * sx2 - sx * sxlny) / c
- b = ( n * sxlny - sx * slny ) / c
-
- return Math.exp(a), b, fit_error(xys) { |x| Math.exp(a + b * x) }
- 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].
- #
- # See: http://mathworld.wolfram.com/LeastSquaresFitting.html
-
- def fit_linear xs, ys
- n = xs.size
- xys = xs.zip(ys)
- sx = sigma xs
- sy = sigma ys
- sx2 = sigma(xs) { |x| x ** 2 }
- sxy = sigma(xys) { |x,y| x * y }
-
- c = n * sx2 - sx**2
- a = (sy * sx2 - sx * sxy) / c
- b = ( n * sxy - sx * sy ) / c
-
- return a, b, fit_error(xys) { |x| a + b * x }
- end
-
- ##
- # To fit a functional form: y = ax^b.
- #
- # Takes x and y values and returns [a, b, r^2].
- #
- # See: http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
-
- def fit_power xs, ys
- n = xs.size
- xys = xs.zip(ys)
- slnxlny = sigma(xys) { |x, y| Math.log(x) * Math.log(y) }
- slnx = sigma(xs) { |x | Math.log(x) }
- slny = sigma(ys) { | y| Math.log(y) }
- slnx2 = sigma(xs) { |x | Math.log(x) ** 2 }
-
- b = (n * slnxlny - slnx * slny) / (n * slnx2 - slnx ** 2);
- a = (slny - b * slnx) / n
-
- return Math.exp(a), b, fit_error(xys) { |x| (Math.exp(a) * (x ** b)) }
- end
-
- ##
- # Enumerates over +enum+ mapping +block+ if given, returning the
- # sum of the result. Eg:
- #
- # sigma([1, 2, 3]) # => 1 + 2 + 3 => 7
- # sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14
-
- def sigma enum, &block
- enum = enum.map(&block) if block
- enum.inject { |sum, n| sum + n }
- end
-
- ##
- # Returns a proc that calls the specified fit method and asserts
- # that the error is within a tolerable threshold.
-
- def validation_for_fit msg, threshold
- proc do |range, times|
- a, b, rr = send "fit_#{msg}", range, times
- assert_operator rr, :>=, threshold
- [a, b, rr]
- end
- end
- end
-end
-
-class MiniTest::Spec
- ##
- # This is used to define a new benchmark method. You usually don't
- # use this directly and is intended for those needing to write new
- # performance curve fits (eg: you need a specific polynomial fit).
- #
- # See ::bench_performance_linear for an example of how to use this.
-
- def self.bench name, &block
- define_method "bench_#{name.gsub(/\W+/, '_')}", &block
- end
-
- ##
- # Specifies the ranges used for benchmarking for that class.
- #
- # bench_range do
- # bench_exp(2, 16, 2)
- # end
- #
- # See Unit::TestCase.bench_range for more details.
-
- def self.bench_range &block
- return super unless block
-
- meta = (class << self; self; end)
- meta.send :define_method, "bench_range", &block
- end
-
- ##
- # Create a benchmark that verifies that the performance is linear.
- #
- # describe "my class" do
- # bench_performance_linear "fast_algorithm", 0.9999 do |n|
- # @obj.fast_algorithm(n)
- # end
- # end
-
- def self.bench_performance_linear name, threshold = 0.99, &work
- bench name do
- assert_performance_linear threshold, &work
- end
- end
-
- ##
- # Create a benchmark that verifies that the performance is constant.
- #
- # describe "my class" do
- # bench_performance_constant "zoom_algorithm!" do |n|
- # @obj.zoom_algorithm!(n)
- # end
- # end
-
- def self.bench_performance_constant name, threshold = 0.99, &work
- bench name do
- assert_performance_constant threshold, &work
- end
- end
-
- ##
- # Create a benchmark that verifies that the performance is exponential.
- #
- # describe "my class" do
- # bench_performance_exponential "algorithm" do |n|
- # @obj.algorithm(n)
- # end
- # end
-
- def self.bench_performance_exponential name, threshold = 0.99, &work
- bench name do
- assert_performance_exponential threshold, &work
- end
- end
-end
diff --git a/test/lib/minitest/mock.rb b/test/lib/minitest/mock.rb
deleted file mode 100644
index 224b06cb89..0000000000
--- a/test/lib/minitest/mock.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: true
-
-class MockExpectationError < StandardError; end # :nodoc:
-
-##
-# A simple and clean mock object framework.
-
-module MiniTest # :nodoc:
-
- ##
- # All mock objects are an instance of Mock
-
- class Mock
- alias :__respond_to? :respond_to?
-
- skip_methods = %w(object_id respond_to_missing? inspect === to_s)
-
- instance_methods.each do |m|
- undef_method m unless skip_methods.include?(m.to_s) || m =~ /^__/
- end
-
- def initialize # :nodoc:
- @expected_calls = Hash.new { |calls, name| calls[name] = [] }
- @actual_calls = Hash.new { |calls, name| calls[name] = [] }
- end
-
- ##
- # 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
- #
- # @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.
- #
- # @mock.expect(:uses_any_string, true, [String])
- # @mock.uses_any_string("foo") # => true
- # @mock.verify # => true
- #
- # @mock.expect(:uses_one_string, true, ["foo"]
- # @mock.uses_one_string("bar") # => true
- # @mock.verify # => raises MockExpectationError
-
- 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
-
- def __call name, data # :nodoc:
- case data
- when Hash then
- "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}"
- else
- data.map { |d| __call name, d }.join ", "
- end
- end
-
- ##
- # Verify that all methods were called as expected. Raises
- # +MockExpectationError+ if the mock object was not called as
- # expected.
-
- def verify
- @expected_calls.each do |name, calls|
- calls.each do |expected|
- msg1 = "expected #{__call name, expected}"
- msg2 = "#{msg1}, got [#{__call name, @actual_calls[name]}]"
-
- raise MockExpectationError, msg2 if
- @actual_calls.has_key?(name) and
- not @actual_calls[name].include?(expected)
-
- raise MockExpectationError, msg1 unless
- @actual_calls.has_key?(name) and
- @actual_calls[name].include?(expected)
- end
- end
- true
- end
-
- def method_missing(sym, *args) # :nodoc:
- unless @expected_calls.has_key?(sym) then
- raise NoMethodError, "unmocked method %p, expected one of %p" %
- [sym, @expected_calls.keys.sort_by(&:to_s)]
- end
-
- index = @actual_calls[sym].length
- expected_call = @expected_calls[sym][index]
-
- unless expected_call then
- raise MockExpectationError, "No more expects available for %p: %p" %
- [sym, args]
- end
-
- 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" %
- [sym, expected_args.size, args.size]
- end
-
- fully_matched = expected_args.zip(args).all? { |mod, a|
- mod === a or mod == a
- }
-
- unless fully_matched then
- raise MockExpectationError, "mocked method %p called with unexpected arguments %p" %
- [sym, args]
- end
-
- @actual_calls[sym] << {
- :retval => retval,
- :args => expected_args.zip(args).map { |mod, a| mod === a ? mod : a }
- }
-
- retval
- end
-
- def respond_to?(sym, include_private = false) # :nodoc:
- return true if @expected_calls.has_key?(sym.to_sym)
- return __respond_to?(sym, include_private)
- end
- end
-end
-
-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+. The method
- # +name+ must exist before stubbing.
- #
- # def test_stale_eh
- # obj_under_test = Something.new
- # refute obj_under_test.stale?
- #
- # Time.stub :now, Time.at(0) do
- # assert obj_under_test.stale?
- # end
- # end
-
- def stub name, val_or_callable, &block
- 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)
- else
- val_or_callable
- end
- end
-
- yield self
- ensure
- metaclass.send :undef_method, name
- metaclass.send :alias_method, name, new_name
- metaclass.send :undef_method, new_name
- end
-end
diff --git a/test/lib/minitest/unit.rb b/test/lib/minitest/unit.rb
deleted file mode 100644
index d922a5fc41..0000000000
--- a/test/lib/minitest/unit.rb
+++ /dev/null
@@ -1,1420 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: true
-
-require "optparse"
-require "rbconfig"
-require "leakchecker"
-
-##
-# Minimal (mostly drop-in) replacement for test-unit.
-#
-# :include: README.txt
-
-module MiniTest
-
- def self.const_missing name # :nodoc:
- case name
- when :MINI_DIR then
- msg = "MiniTest::MINI_DIR was removed. Don't violate other's internals."
- warn "WAR\NING: #{msg}"
- warn "WAR\NING: Used by #{caller.first}."
- const_set :MINI_DIR, "bad value"
- else
- super
- end
- end
-
- ##
- # Assertion base class
-
- class Assertion < Exception; end
-
- ##
- # Assertion raised when skipping a test
-
- class Skip < Assertion; end
-
- class << self
- ##
- # Filter object for backtraces.
-
- attr_accessor :backtrace_filter
- end
-
- class BacktraceFilter # :nodoc:
- def filter bt
- return ["No backtrace"] unless bt
-
- 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
- end
- end
-
- self.backtrace_filter = BacktraceFilter.new
-
- def self.filter_backtrace bt # :nodoc:
- backtrace_filter.filter bt
- end
-
- ##
- # MiniTest Assertions. All assertion methods accept a +msg+ which is
- # printed if the assertion fails.
-
- module Assertions
- ##
- # Returns the diff command to use in #diff. Tries to intelligently
- # figure out what diff to use.
-
- def self.diff
- unless defined? @diff
- exe = RbConfig::CONFIG['EXEEXT']
- @diff = %W"gdiff#{exe} diff#{exe}".find do |diff|
- if system(diff, "-u", __FILE__, __FILE__)
- break "#{diff} -u"
- end
- end
- end
-
- @diff
- end
-
- ##
- # Set the diff command to use in #diff.
-
- def self.diff= o
- @diff = o
- end
-
- ##
- # Returns a diff between +exp+ and +act+. If there is no known
- # diff command or if it doesn't make sense to diff the output
- # (single line, short output), then it simply returns a basic
- # comparison between the two.
-
- def diff exp, act
- require "tempfile"
-
- expect = mu_pp_for_diff exp
- butwas = mu_pp_for_diff act
- result = nil
-
- need_to_diff =
- MiniTest::Assertions.diff &&
- (expect.include?("\n") ||
- butwas.include?("\n") ||
- expect.size > 30 ||
- butwas.size > 30 ||
- expect == butwas)
-
- return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless
- need_to_diff
-
- tempfile_a = nil
- tempfile_b = nil
-
- Tempfile.open("expect") do |a|
- tempfile_a = a
- a.puts expect
- a.flush
-
- Tempfile.open("butwas") do |b|
- tempfile_b = b
- b.puts butwas
- b.flush
-
- result = `#{MiniTest::Assertions.diff} #{a.path} #{b.path}`
- result.sub!(/^\-\-\- .+/, "--- expected")
- result.sub!(/^\+\+\+ .+/, "+++ actual")
-
- if result.empty? then
- klass = exp.class
- result = [
- "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
-
- result
- ensure
- tempfile_a.close! if tempfile_a
- tempfile_b.close! if tempfile_b
- end
-
- ##
- # This returns a human-readable version of +obj+. By default
- # #inspect is called. You can override this to use #pretty_print
- # if you want.
-
- def mu_pp obj
- s = obj.inspect
- s = s.encode Encoding.default_external if defined? Encoding
- s
- end
-
- ##
- # This returns a diff-able human-readable version of +obj+. This
- # differs from the regular mu_pp because it expands escaped
- # 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
- mu_pp(obj).gsub(/(?<!\\)(?:\\\\)*\K\\n/, "\n").gsub(/:0x[a-fA-F0-9]{4,}/m, ':0xXXXXXX')
- end
-
- def _assertions= n # :nodoc:
- @_assertions = n
- end
-
- def _assertions # :nodoc:
- @_assertions ||= 0
- end
-
- ##
- # Fails unless +test+ is a true value.
-
- def assert test, msg = nil
- msg ||= "Failed assertion, no message given."
- self._assertions += 1
- unless test then
- msg = msg.call if Proc === msg
- raise MiniTest::Assertion, msg
- end
- true
- end
-
- ##
- # Fails unless +obj+ is empty.
-
- def assert_empty obj, msg = nil
- msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" }
- assert_respond_to obj, :empty?
- assert obj.empty?, msg
- end
-
- ##
- # Fails unless <tt>exp == act</tt> printing the difference between
- # the two, if possible.
- #
- # If there is no visible difference but the assertion fails, you
- # should suspect that your #== is buggy, or your inspect output is
- # missing crucial details.
- #
- # For floats use assert_in_delta.
- #
- # See also: MiniTest::Assertions.diff
-
- def assert_equal exp, act, msg = nil
- msg = message(msg, "") { diff exp, act }
- assert exp == act, msg
- end
-
- ##
- # For comparing Floats. Fails unless +exp+ and +act+ are within +delta+
- # of each other.
- #
- # assert_in_delta Math::PI, (22.0 / 7.0), 0.01
-
- 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}"
- }
- assert delta >= n, msg
- end
-
- ##
- # For comparing Floats. Fails unless +exp+ and +act+ have a relative
- # error less than +epsilon+.
-
- def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
- assert_in_delta a, b, [a.abs, b.abs].min * epsilon, msg
- end
-
- ##
- # Fails unless +collection+ includes +obj+.
-
- def assert_includes collection, obj, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
- }
- assert_respond_to collection, :include?
- assert collection.include?(obj), msg
- end
-
- ##
- # Fails unless +obj+ is an instance of +cls+.
-
- def assert_instance_of cls, obj, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
- }
-
- assert obj.instance_of?(cls), msg
- end
-
- ##
- # Fails unless +obj+ is a kind of +cls+.
-
- def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of
- msg = message(msg) {
- "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
-
- assert obj.kind_of?(cls), msg
- end
-
- ##
- # Fails unless +matcher+ <tt>=~</tt> +obj+.
-
- def assert_match matcher, obj, msg = nil
- msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
- assert_respond_to matcher, :"=~"
- matcher = Regexp.new Regexp.escape matcher if String === matcher
- assert matcher =~ obj, msg
- end
-
- ##
- # Fails unless +obj+ is nil
-
- def assert_nil obj, msg = nil
- msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
- assert obj.nil?, msg
- end
-
- ##
- # For testing with binary operators.
- #
- # assert_operator 5, :<=, 4
-
- def assert_operator o1, op, o2 = (predicate = true; nil), msg = nil
- return assert_predicate o1, op, msg if predicate
- msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
- assert o1.__send__(op, o2), msg
- end
-
- ##
- # Fails if stdout or stderr do not output the expected results.
- # Pass in nil if you don't care about that streams output. Pass in
- # "" 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
- out, err = capture_io do
- yield
- end
-
- err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr
- out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout
-
- y = send err_msg, stderr, err, "In stderr" if err_msg
- x = send out_msg, stdout, out, "In stdout" if out_msg
-
- (!stdout || x) && (!stderr || y)
- end
-
- ##
- # For testing with predicates.
- #
- # assert_predicate str, :empty?
- #
- # This is really meant for specs and is front-ended by assert_operator:
- #
- # str.must_be :empty?
-
- def assert_predicate o1, op, msg = nil
- msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
- assert o1.__send__(op), msg
- end
-
- ##
- # Fails unless the block raises one of +exp+. Returns the
- # exception matched so you can check the message, attributes, etc.
-
- def assert_raises *exp
- msg = "#{exp.pop}.\n" if String === exp.last
-
- begin
- yield
- rescue MiniTest::Skip => e
- return e if exp.include? MiniTest::Skip
- raise e
- rescue Exception => e
- 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."
- end
-
- ##
- # Fails unless +obj+ responds to +meth+.
-
- def assert_respond_to obj, meth, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
- }
- assert obj.respond_to?(meth), msg
- end
-
- ##
- # Fails unless +exp+ and +act+ are #equal?
-
- def assert_same exp, act, msg = nil
- msg = message(msg) {
- data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
- "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data
- }
- assert exp.equal?(act), msg
- end
-
- ##
- # +send_ary+ is a receiver, message and arguments.
- #
- # Fails unless the call returns a true value
- # TODO: I should prolly remove this from specs
-
- def assert_send send_ary, m = nil
- recv, msg, *args = send_ary
- m = message(m) {
- "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
- assert recv.__send__(msg, *args), m
- end
-
- ##
- # Fails if the block outputs anything to stderr or stdout.
- #
- # See also: #assert_output
-
- def assert_silent
- assert_output "", "" do
- yield
- end
- end
-
- ##
- # Fails unless the block throws +sym+
-
- def assert_throws sym, msg = nil
- default = "Expected #{mu_pp(sym)} to have been thrown"
- caught = true
- 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
- default += ", not #{e.name.inspect}"
- end
- caught = false
- end
-
- assert caught, message(msg) { default }
- end
-
- ##
- # 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'
-
- captured_stdout, captured_stderr = StringIO.new, StringIO.new
-
- 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
- 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
- $stdout.reopen orig_stdout
- $stderr.reopen orig_stderr
- orig_stdout.close
- orig_stderr.close
- captured_stdout.close!
- captured_stderr.close!
- end
- end
- end
-
- ##
- # Returns details for exception +e+
-
- def exception_details e, msg
- [
- "#{msg}",
- "Class: <#{e.class}>",
- "Message: <#{e.message.inspect}>",
- "---Backtrace---",
- "#{MiniTest::filter_backtrace(e.backtrace).join("\n")}",
- "---------------",
- ].join "\n"
- end
-
- ##
- # Fails with +msg+
-
- def flunk msg = nil
- msg ||= "Epic Fail!"
- assert false, msg
- end
-
- ##
- # Returns a proc that will output +msg+ along with the default message.
-
- 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}"
- }
- end
-
- ##
- # used for counting assertions
-
- def pass msg = nil
- assert true
- end
-
- ##
- # Fails if +test+ is a true value
-
- def refute test, msg = nil
- msg ||= "Failed refutation, no message given"
- not assert(! test, msg)
- end
-
- ##
- # Fails if +obj+ is empty.
-
- def refute_empty obj, msg = nil
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
- assert_respond_to obj, :empty?
- refute obj.empty?, msg
- end
-
- ##
- # Fails if <tt>exp == act</tt>.
- #
- # For floats use refute_in_delta.
-
- def refute_equal exp, act, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
- }
- refute exp == act, msg
- end
-
- ##
- # For comparing Floats. Fails if +exp+ is within +delta+ of +act+.
- #
- # refute_in_delta Math::PI, (22.0 / 7.0)
-
- 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}"
- }
- refute delta >= n, msg
- end
-
- ##
- # For comparing Floats. Fails if +exp+ and +act+ have a relative error
- # less than +epsilon+.
-
- def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
- refute_in_delta a, b, a * epsilon, msg
- end
-
- ##
- # Fails if +collection+ includes +obj+.
-
- def refute_includes collection, obj, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
- }
- assert_respond_to collection, :include?
- refute collection.include?(obj), msg
- end
-
- ##
- # Fails if +obj+ is an instance of +cls+.
-
- def refute_instance_of cls, obj, msg = nil
- msg = message(msg) {
- "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
- }
- refute obj.instance_of?(cls), msg
- end
-
- ##
- # Fails if +obj+ is a kind of +cls+.
-
- def refute_kind_of cls, obj, msg = nil # TODO: merge with instance_of
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
- refute obj.kind_of?(cls), msg
- end
-
- ##
- # Fails if +matcher+ <tt>=~</tt> +obj+.
-
- def refute_match matcher, obj, msg = nil
- msg = message(msg) {"Expected #{mu_pp matcher} to not match #{mu_pp obj}"}
- assert_respond_to matcher, :"=~"
- matcher = Regexp.new Regexp.escape matcher if String === matcher
- refute matcher =~ obj, msg
- end
-
- ##
- # Fails if +obj+ is nil.
-
- def refute_nil obj, msg = nil
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
- refute obj.nil?, msg
- end
-
- ##
- # Fails if +o1+ is not +op+ +o2+. Eg:
- #
- # refute_operator 1, :>, 2 #=> pass
- # refute_operator 1, :<, 2 #=> fail
-
- def refute_operator o1, op, o2 = (predicate = true; nil), msg = nil
- return refute_predicate o1, op, msg if predicate
- msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"}
- refute o1.__send__(op, o2), msg
- end
-
- ##
- # For testing with predicates.
- #
- # refute_predicate str, :empty?
- #
- # This is really meant for specs and is front-ended by refute_operator:
- #
- # str.wont_be :empty?
-
- def refute_predicate o1, op, msg = nil
- msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
- refute o1.__send__(op), msg
- end
-
- ##
- # Fails if +obj+ responds to the message +meth+.
-
- def refute_respond_to obj, meth, msg = nil
- msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
-
- refute obj.respond_to?(meth), msg
- end
-
- ##
- # Fails if +exp+ is the same (by object identity) as +act+.
-
- def refute_same exp, act, msg = nil
- msg = message(msg) {
- data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
- "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data
- }
- refute exp.equal?(act), msg
- end
-
- ##
- # Skips the current test. Gets listed at the end of the run but
- # doesn't cause a failure exit code.
-
- 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
- Minitest::Unit.runner.synchronize do
- yield
- end
- end
- end
-
- class Unit # :nodoc:
- VERSION = "4.7.5" # :nodoc:
-
- attr_accessor :report, :failures, :errors, :skips # :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
- @options ||= {}
- end
-
- @@installed_at_exit ||= false
- @@out = $stdout
- @@after_tests = []
-
- ##
- # A simple hook allowing you to run a block of code after _all_ of
- # the tests are done. Eg:
- #
- # MiniTest::Unit.after_tests { p $debugging_info }
-
- def self.after_tests &block
- @@after_tests << block
- end
-
- ##
- # Registers MiniTest::Unit to run tests at process exit
-
- def self.autorun
- at_exit {
- # 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
- # own, that way we can be assured that our exit will be last
- # to run (at_exit stacks).
- exit_code = nil
-
- at_exit {
- @@after_tests.reverse_each(&:call)
- exit false if exit_code && exit_code != 0
- }
-
- exit_code = MiniTest::Unit.new.run ARGV
- } unless @@installed_at_exit
- @@installed_at_exit = true
- end
-
- ##
- # Returns the stream to use for output.
-
- def self.output
- @@out
- end
-
- ##
- # Sets MiniTest::Unit to write output to +stream+. $stdout is the default
- # output
-
- def self.output= stream
- @@out = stream
- end
-
- ##
- # Tells MiniTest::Unit to delegate to +runner+, an instance of a
- # MiniTest::Unit subclass, when MiniTest::Unit#run is called.
-
- def self.runner= runner
- @@runner = runner
- end
-
- ##
- # Returns the MiniTest::Unit subclass instance that will be used
- # to run the tests. A MiniTest::Unit instance is the default
- # runner.
-
- def self.runner
- @@runner ||= self.new
- end
-
- ##
- # Return all plugins' run methods (methods that start with "run_").
-
- def self.plugins
- @@plugins ||= (["run_tests"] +
- public_instance_methods(false).
- grep(/^run_/).map { |s| s.to_s }).uniq
- end
-
- ##
- # Return the IO for output.
-
- def output
- self.class.output
- end
-
- def puts *a # :nodoc:
- output.puts(*a)
- end
-
- def print *a # :nodoc:
- output.print(*a)
- end
-
- def test_count # :nodoc:
- @test_count ||= 0
- end
-
- ##
- # Runner for a given +type+ (eg, test vs bench).
-
- def _run_anything type
- suites = TestCase.send "#{type}_suites"
- return if suites.empty?
-
- puts
- puts "# Running #{type}s:"
- puts
-
- @test_count, @assertion_count = 0, 0
- test_count = assertion_count = 0
- sync = output.respond_to? :"sync=" # stupid emacs
- old_sync, output.sync = output.sync, true if sync
-
- count = 0
- begin
- start = Time.now
-
- results = _run_suites suites, type
-
- @test_count = results.inject(0) { |sum, (tc, _)| sum + tc }
- @assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac }
- test_count += @test_count
- assertion_count += @assertion_count
- t = Time.now - start
- count += 1
- unless @repeat_count
- puts
- puts
- end
- puts "Finished%s %ss in %.6fs, %.4f tests/s, %.4f assertions/s.\n" %
- [(@repeat_count ? "(#{count}/#{@repeat_count}) " : ""), type,
- t, @test_count.fdiv(t), @assertion_count.fdiv(t)]
- end while @repeat_count && count < @repeat_count &&
- report.empty? && failures.zero? && errors.zero?
-
- output.sync = old_sync if sync
-
- report.each_with_index do |msg, i|
- puts "\n%3d) %s" % [i + 1, msg]
- end
-
- puts
- @test_count = test_count
- @assertion_count = assertion_count
-
- status
- end
-
- ##
- # Runs all the +suites+ for a given +type+.
- #
-
- def _run_suites suites, type
- suites.map { |suite| _run_suite suite, type }
- end
-
- ##
- # Run a single +suite+ for a given +type+.
-
- def _run_suite suite, type
- header = "#{type}_suite_header"
- puts send(header, suite) if respond_to? header
-
- filter = options[:filter] || '/./'
- filter = Regexp.new $1 if filter =~ /\/(.*)\//
-
- all_test_methods = suite.send "#{type}_methods"
-
- filtered_test_methods = all_test_methods.find_all { |m|
- filter === m || filter === "#{suite}##{m}"
- }
-
- leakchecker = LeakChecker.new
-
- assertions = filtered_test_methods.map { |method|
- inst = suite.new method
- inst._assertions = 0
-
- print "#{suite}##{method} = " if @verbose
-
- start_time = Time.now if @verbose
- result = inst.run self
-
- print "%.2f s = " % (Time.now - start_time) if @verbose
- print result
- puts if @verbose
- $stdout.flush
-
- unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # compiler process is wrongly considered as leak
- leakchecker.check("#{inst.class}\##{inst.__name__}")
- end
-
- inst._assertions
- }
-
- return assertions.size, assertions.inject(0) { |sum, n| sum + n }
- end
-
- ##
- # Record the result of a single test. Makes it very easy to gather
- # information. Eg:
- #
- # class StatisticsRecorder < MiniTest::Unit
- # def record suite, method, assertions, time, error
- # # ... record the results somewhere ...
- # end
- # 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
-
- def location e # :nodoc:
- last_before_assertion = ""
- e.backtrace.reverse_each do |s|
- break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
- last_before_assertion = s
- end
- last_before_assertion.sub(/:in .*$/, '')
- end
-
- ##
- # Writes status for failed test +meth+ in +klass+ which finished with
- # exception +e+
-
- def puke klass, meth, e
- e = case e
- when MiniTest::Skip then
- @skips += 1
- return "S" unless @verbose
- "Skipped:\n#{klass}##{meth} [#{location e}]:\n#{e.message}\n"
- when MiniTest::Assertion then
- @failures += 1
- "Failure:\n#{klass}##{meth} [#{location e}]:\n#{e.message}\n"
- else
- @errors += 1
- bt = MiniTest::filter_backtrace(e.backtrace).join "\n "
- "Error:\n#{klass}##{meth}:\n#{e.class}: #{e.message.b}\n #{bt}\n"
- end
- @report << e
- e[0, 1]
- end
-
- def initialize # :nodoc:
- @report = []
- @errors = @failures = @skips = 0
- @verbose = false
- @mutex = Thread::Mutex.new
- @info_signal = Signal.list['INFO']
- @repeat_count = nil
- end
-
- def synchronize # :nodoc:
- if @mutex then
- @mutex.synchronize { yield }
- else
- yield
- end
- end
-
- def process_args args = [] # :nodoc:
- options = {}
- orig_args = args.dup
-
- OptionParser.new do |opts|
- opts.banner = 'minitest options:'
- opts.version = MiniTest::Unit::VERSION
-
- opts.on '-h', '--help', 'Display this help.' do
- puts opts
- exit
- end
-
- opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m|
- options[:seed] = m.to_i
- end
-
- opts.on '-v', '--verbose', "Verbose. Show progress processing files." do
- options[:verbose] = true
- end
-
- opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |a|
- options[:filter] = a
- end
-
- opts.parse! args
- orig_args -= args
- end
-
- unless options[:seed] then
- srand
- options[:seed] = srand % 0xFFFF
- orig_args << "--seed" << options[:seed].to_s
- end
-
- srand options[:seed]
-
- self.verbose = options[:verbose]
- @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " "
-
- options
- end
-
- ##
- # Begins the full test run. Delegates to +runner+'s #_run method.
-
- def run args = []
- self.class.runner._run(args)
- end
-
- ##
- # Top level driver, controls all output and filtering.
-
- def _run args = []
- args = process_args args # ARGH!! blame test/unit process_args
- self.options.merge! args
-
- puts "Run options: #{help}"
-
- self.class.plugins.each do |plugin|
- send plugin
- break unless report.empty?
- end
-
- return failures + errors if self.test_count > 0 # or return nil...
- rescue Interrupt
- abort 'Interrupted'
- end
-
- ##
- # Runs test suites matching +filter+.
-
- def run_tests
- _run_anything :test
- end
-
- ##
- # Writes status to +io+
-
- def status io = self.output
- format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
- io.puts format % [test_count, assertion_count, failures, errors, skips]
- end
-
- ##
- # Provides a simple set of guards that you can use in your tests
- # to skip execution if it is not applicable. These methods are
- # mixed into TestCase as both instance and class methods so you
- # can use them inside or outside of the test methods.
- #
- # def test_something_for_mri
- # skip "bug 1234" if jruby?
- # # ...
- # end
- #
- # if windows? then
- # # ... lots of test methods ...
- # end
-
- module Guard
-
- ##
- # Is this running on jruby?
-
- def jruby? platform = RUBY_PLATFORM
- "java" == platform
- end
-
- ##
- # 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
-
- ##
- # Is this running on rubinius?
-
- def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
- "rbx" == platform
- end
-
- ##
- # Is this running on windows?
-
- def windows? platform = RUBY_PLATFORM
- /mswin|mingw/ =~ platform
- end
-
- ##
- # Is this running on mingw?
-
- def mingw? platform = RUBY_PLATFORM
- /mingw/ =~ platform
- end
-
- end
-
- ##
- # Provides before/after hooks for setup and teardown. These are
- # meant for library writers, NOT for regular test authors. See
- # #before_setup for an example.
-
- module LifecycleHooks
- ##
- # Runs before every test, after setup. This hook is meant for
- # libraries to extend minitest. It is not meant to be used by
- # test developers.
- #
- # See #before_setup for an example.
-
- def after_setup; end
-
- ##
- # Runs before every test, before setup. This hook is meant for
- # libraries to extend minitest. It is not meant to be used by
- # test developers.
- #
- # As a simplistic example:
- #
- # module MyMinitestPlugin
- # def before_setup
- # super
- # # ... stuff to do before setup is run
- # end
- #
- # def after_setup
- # # ... stuff to do after setup is run
- # super
- # end
- #
- # def before_teardown
- # super
- # # ... stuff to do before teardown is run
- # end
- #
- # def after_teardown
- # # ... stuff to do after teardown is run
- # super
- # end
- # end
- #
- # class MiniTest::Unit::TestCase
- # include MyMinitestPlugin
- # end
-
- def before_setup; end
-
- ##
- # Runs after every test, before teardown. This hook is meant for
- # libraries to extend minitest. It is not meant to be used by
- # test developers.
- #
- # See #before_setup for an example.
-
- def before_teardown; end
-
- ##
- # Runs after every test, after teardown. This hook is meant for
- # libraries to extend minitest. It is not meant to be used by
- # test developers.
- #
- # See #before_setup for an example.
-
- def after_teardown; end
- end
-
- ##
- # Subclass TestCase to create your own tests. Typically you'll want a
- # TestCase subclass per implementation class.
- #
- # See MiniTest::Assertions
-
- class TestCase
- include LifecycleHooks
- include Guard
- extend Guard
-
- attr_reader :__name__ # :nodoc:
-
- PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException,
- Interrupt, SystemExit] # :nodoc:
-
- ##
- # Runs the tests reporting the status to +runner+
-
- def run runner
- trap "INFO" do
- runner.report.each_with_index do |msg, i|
- warn "\n%3d) %s" % [i + 1, msg]
- end
- warn ''
- 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 runner.info_signal
-
- start_time = Time.now
-
- result = ""
- begin
- @passed = nil
- self.before_setup
- self.setup
- 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 = 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
- ensure
- %w{ before_teardown teardown after_teardown }.each do |hook|
- begin
- self.send hook
- rescue *PASSTHROUGH_EXCEPTIONS
- 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 runner.info_signal
- end
- result
- end
-
- alias :run_test :__send__
-
- def initialize name # :nodoc:
- @__name__ = name
- @__io__ = nil
- @passed = nil
- @@current = self # FIX: make thread local
- end
-
- def self.current # :nodoc:
- @@current # FIX: make thread local
- end
-
- ##
- # Return the output IO object
-
- def io
- @__io__ = true
- MiniTest::Unit.output
- end
-
- ##
- # Have we hooked up the IO yet?
-
- def io?
- @__io__
- end
-
- def self.reset # :nodoc:
- @@test_suites = {}
- end
-
- reset
-
- ##
- # 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
-
- def self.inherited klass # :nodoc:
- @@test_suites[klass] = true
- super
- end
-
- def self.test_order # :nodoc:
- :random
- end
-
- def self.test_suites # :nodoc:
- @@test_suites.keys.sort_by { |ts| ts.name.to_s }
- end
-
- def self.test_methods # :nodoc:
- 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 }
- when :alpha, :sorted then
- methods.sort
- else
- raise "Unknown test_order: #{self.test_order.inspect}"
- end
- end
-
- ##
- # Returns true if the test passed.
-
- def passed?
- @passed
- end
-
- ##
- # Runs before every test. Use this to set up before each test
- # run.
-
- def setup; end
-
- ##
- # Runs after every test. Use this to clean up after each test
- # run.
-
- def teardown; end
-
- include MiniTest::Assertions
- end # class TestCase
- end # class Unit
-
- Test = Unit::TestCase
-end # module MiniTest
-
-Minitest = MiniTest # :nodoc: because ugh... I typo this all the time