minitest-5.25.4/ 0000755 0000041 0000041 00000000000 14743220663 013502 5 ustar www-data www-data minitest-5.25.4/Manifest.txt 0000444 0000041 0000041 00000001461 14743220663 016011 0 ustar www-data www-data .autotest
History.rdoc
Manifest.txt
README.rdoc
Rakefile
design_rationale.rb
lib/hoe/minitest.rb
lib/minitest.rb
lib/minitest/assertions.rb
lib/minitest/autorun.rb
lib/minitest/benchmark.rb
lib/minitest/compress.rb
lib/minitest/error_on_warning.rb
lib/minitest/expectations.rb
lib/minitest/hell.rb
lib/minitest/manual_plugins.rb
lib/minitest/mock.rb
lib/minitest/parallel.rb
lib/minitest/pride.rb
lib/minitest/pride_plugin.rb
lib/minitest/spec.rb
lib/minitest/test.rb
lib/minitest/test_task.rb
lib/minitest/unit.rb
test/minitest/metametameta.rb
test/minitest/test_minitest_assertions.rb
test/minitest/test_minitest_benchmark.rb
test/minitest/test_minitest_mock.rb
test/minitest/test_minitest_reporter.rb
test/minitest/test_minitest_spec.rb
test/minitest/test_minitest_test.rb
test/minitest/test_minitest_test_task.rb
minitest-5.25.4/.autotest 0000444 0000041 0000041 00000002123 14743220663 015347 0 ustar www-data www-data # -*- ruby -*-
require 'autotest/restart'
require 'autotest/rcov' if ENV['RCOV']
Autotest.add_hook :initialize do |at|
at.testlib = 'minitest/autorun'
bench_tests = %w(TestMinitestBenchmark)
mock_tests = %w(TestMinitestMock TestMinitestStub)
spec_tests = %w(TestMinitestReporter TestMetaStatic TestMeta
TestSpecInTestCase)
unit_tests = %w(TestMinitestGuard TestMinitestRunnable
TestMinitestRunner TestMinitestTest TestMinitestUnit
TestMinitestUnitInherited TestMinitestUnitOrder
TestMinitestUnitRecording TestMinitestUnitTestCase)
{
bench_tests => "test/minitest/test_minitest_benchmark.rb",
mock_tests => "test/minitest/test_minitest_mock.rb",
spec_tests => "test/minitest/test_minitest_reporter.rb",
unit_tests => "test/minitest/test_minitest_unit.rb",
}.each do |klasses, file|
klasses.each do |klass|
at.extra_class_map[klass] = file
end
end
at.add_exception 'coverage.info'
at.add_exception 'coverage'
end
# require 'autotest/rcov'
# Autotest::RCov.command = 'rcov_info'
minitest-5.25.4/README.rdoc 0000444 0000041 0000041 00000075545 14743220663 015326 0 ustar www-data www-data = minitest/{test,spec,mock,benchmark}
home :: https://github.com/minitest/minitest
bugs :: https://github.com/minitest/minitest/issues
rdoc :: https://docs.seattlerb.org/minitest
clog :: https://github.com/minitest/minitest/blob/master/History.rdoc
vim :: https://github.com/sunaku/vim-ruby-minitest
emacs:: https://github.com/arthurnn/minitest-emacs
== 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/test 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/test 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/test 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/test - 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!
* minitest/test_task - a full-featured and clean rake task generator.
* Incredibly small and fast runner, but no bells and whistles.
* Written by squishy human beings. Software can never be perfect. We will all eventually die.
== 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
Define your tests as methods beginning with +test_+.
require "minitest/autorun"
class TestMeme < Minitest::Test
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/wojtekmach/minitest-matchers
* https://github.com/rmm5t/minitest-matchers_vaccine
=== Benchmarks
Add benchmarks to your tests.
# optionally run benchmarks, good for CI-only work!
require "minitest/benchmark" if ENV["BENCH"]
class TestMeme < Minitest::Benchmark
# 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. In minitest 5, the describe name needs to match
/Bench(mark)?$/.
describe "Meme Benchmark" 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
Mocks and stubs defined using terminology by Fowler & Meszaros at
https://www.martinfowler.com/bliki/TestDouble.html:
"Mocks are pre-programmed with expectations which form a specification
of the calls they are expected to receive. They can throw an exception
if they receive a call they don't expect and are checked during
verification to ensure they got all the calls they were expecting."
class MemeAsker
def initialize(meme)
@meme = meme
end
def ask(question)
method = question.tr(" ", "_") + "?"
@meme.__send__(method)
end
end
require "minitest/autorun"
describe MemeAsker, :ask do
describe "when passed an unpunctuated question" do
it "should invoke the appropriate predicate method on the meme" do
@meme = Minitest::Mock.new
@meme_asker = MemeAsker.new @meme
@meme.expect :will_it_blend?, :return_value
@meme_asker.ask "will it blend"
@meme.verify
end
end
end
==== Multi-threading and Mocks
Minitest mocks do not support multi-threading. If it works, fine, if it doesn't
you can use regular ruby patterns and facilities like local variables. Here's
an example of asserting that code inside a thread is run:
def test_called_inside_thread
called = false
pr = Proc.new { called = true }
thread = Thread.new(&pr)
thread.join
assert called, "proc not called"
end
=== Stubs
Mocks and stubs are defined using terminology by Fowler & Meszaros at
https://www.martinfowler.com/bliki/TestDouble.html:
"Stubs provide canned answers to calls made during the test".
Minitest's stub method overrides a single method for the duration of
the block.
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
=== Running Your Tests
Ideally, you'll use a rake task to run your tests (see below), either
piecemeal or all at once. BUT! You don't have to:
% ruby -Ilib:test test/minitest/test_minitest_test.rb
Run options: --seed 37685
# Running:
...................................................................... (etc)
Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s.
155 runs, 317 assertions, 0 failures, 0 errors, 0 skips
There are runtime options available, both from minitest itself, and also
provided via plugins. To see them, simply run with +--help+:
% ruby -Ilib:test test/minitest/test_minitest_test.rb --help
minitest options:
-h, --help Display this help.
-s, --seed SEED Sets random seed. Also via env. Eg: SEED=n rake
-v, --verbose Verbose. Show progress processing files.
-n, --name PATTERN Filter run on /regexp/ or string.
-e, --exclude PATTERN Exclude /regexp/ or string from run.
Known extensions: pride, autotest
-p, --pride Pride. Show your testing pride!
-a, --autotest Connect to autotest server.
=== Rake Tasks
You can set up a rake task to run all your tests by adding this to your Rakefile:
require "minitest/test_task"
Minitest::TestTask.create # named test, sensible defaults
# or more explicitly:
Minitest::TestTask.create(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.warning = false
t.test_globs = ["test/**/*_test.rb"]
end
task :default => :test
Each of these will generate 4 tasks:
rake test :: Run the test suite.
rake test:cmd :: Print out the test command.
rake test:isolated :: Show which test files fail when run separately.
rake test:slow :: Show bottom 25 tests sorted by time.
=== Rake Task Variables
There are a bunch of variables you can supply to rake to modify the run.
MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
N :: -n: Tests to run (string or /regexp/).
X :: -x: Tests to exclude (string or /regexp/).
A :: Any extra arguments. Honors shell quoting.
MT_CPU :: How many threads to use for parallel test runs
SEED :: -s --seed Sets random seed.
TESTOPTS :: Deprecated, same as A
FILTER :: Deprecated, same as A
== Writing Extensions
To define a plugin, add a file named minitest/XXX_plugin.rb to your
project/gem. That file must be discoverable via ruby's LOAD_PATH (via
rubygems or otherwise). Minitest will find and require that file using
Gem.find_files. It will then try to call +plugin_XXX_init+ during
startup. The option processor will also try to call +plugin_XXX_options+
passing the OptionParser instance and the current options hash. This
lets you register your own command-line options. Here's a totally
bogus example:
# minitest/bogus_plugin.rb:
module Minitest
def self.plugin_bogus_options(opts, options)
opts.on "--myci", "Report results to my CI" do
options[:myci] = true
options[:myci_addr] = get_myci_addr
options[:myci_port] = get_myci_port
end
end
def self.plugin_bogus_init(options)
self.reporter << MyCI.new(options) if options[:myci]
end
end
=== Adding custom reporters
Minitest uses composite reporter to output test results using multiple
reporter instances. You can add new reporters to the composite during
the init_plugins phase. As we saw in +plugin_bogus_init+ above, you
simply add your reporter instance to the composite via <<.
+AbstractReporter+ defines the API for reporters. You may subclass it
and override any method you want to achieve your desired behavior.
start :: Called when the run has started.
record :: Called for each result, passed or otherwise.
report :: Called at the end of the run.
passed? :: Called to see if you detected any problems.
Using our example above, here is how we might implement MyCI:
# minitest/bogus_plugin.rb
module Minitest
class MyCI < AbstractReporter
attr_accessor :results, :addr, :port
def initialize options
self.results = []
self.addr = options[:myci_addr]
self.port = options[:myci_port]
end
def record result
self.results << result
end
def report
CI.connect(addr, port).send_results self.results
end
end
# code from above...
end
== FAQ
=== What versions are compatible with what? Or what versions are supported?
Minitest is a dependency of rails, which until very recently had an
overzealous backwards compatibility policy. As such, I'm stuck
supporting versions of ruby that are long past EOL. Hopefully I'll be
able to support only current versions of ruby sometime in the near
future.
(As of 2024-05-10)
Current versions of rails: (https://endoflife.date/rails)
| rails | min ruby | minitest | status | EOL Date |
|-------+----------+----------+----------+------------|
| 7.1 | >= 2.7 | >= 5.1 | Current | 2026-06-01?|
| 7.0 | >= 2.7 | >= 5.1 | Maint | 2025-06-01?|
| 6.1 | >= 2.5 | >= 5.1 | Security | 2024-06-01?|
| 6.0 | >= 2.5 | >= 5.1 | EOL | 2023-06-01 |
| 5.2 | >= 2.2.2 | ~> 5.1 | EOL | 2022-06-01 |
If you want to look at the requirements for a specific version, run:
gem spec -r --ruby rails -v 7.0.0
Current versions of ruby: (https://endoflife.date/ruby)
| ruby | Status | EOL Date |
|------+---------+------------|
| 3.3 | Current | 2027-03-31 |
| 3.2 | Maint | 2026-03-31 |
| 3.1 | Security| 2025-03-31 |
| 3.0 | EOL | 2024-03-31 |
| 2.7 | EOL | 2023-03-31 |
| 2.6 | EOL | 2022-03-31 |
| 2.5 | EOL | 2021-03-31 | DO YOU SEE WHAT I'M STUCK WITH???
=== 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) 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
=== How to share code across test classes?
Use a module. That's exactly what they're for:
module UsefulStuff
def useful_method
# ...
end
end
describe Blah do
include UsefulStuff
def test_whatever
# useful_method available here
end
end
Remember, +describe+ simply creates test classes. It's just ruby at
the end of the day and all your normal Good Ruby Rules (tm) apply. If
you want to extend your test using setup/teardown via a module, just
make sure you ALWAYS call super. before/after automatically call super
for you, so make sure you don't do it twice.
=== How to run code before a group of tests?
Use a constant with begin...end like this:
describe Blah do
SETUP = begin
# ... this runs once when describe Blah starts
end
# ...
end
This can be useful for expensive initializations or sharing state.
Remember, this is just ruby code, so you need to make sure this
technique and sharing state doesn't interfere with your tests.
=== Why am I seeing uninitialized constant MiniTest::Test (NameError)?
Are you running the test with Bundler (e.g. via bundle exec )? If so,
in order to require minitest, you must first add the gem 'minitest'
to your Gemfile and run +bundle+. Once it's installed, you should be
able to require minitest and run your tests.
== Prominent Projects using Minitest:
* arel
* journey
* mime-types
* nokogiri
* rails (active_support et al)
* rake
* rdoc
* ...and of course, everything from seattle.rb...
== Developing Minitest:
Minitest requires {Hoe}[https://rubygems.org/gems/hoe].
=== Minitest's own tests require UTF-8 external encoding.
This is a common problem in Windows, where the default external Encoding is
often CP850, but can affect any platform.
Minitest can run test suites using any Encoding, but to run Minitest's
own tests you must have a default external Encoding of UTF-8.
If your encoding is wrong, you'll see errors like:
--- expected
+++ actual
@@ -1,2 +1,3 @@
# encoding: UTF-8
-"Expected /\\w+/ to not match \"blah blah blah\"."
+"Expected /\\w+/ to not match # encoding: UTF-8
+\"blah blah blah\"."
To check your current encoding, run:
ruby -e 'puts Encoding.default_external'
If your output is something other than UTF-8, you can set the RUBYOPTS
env variable to a value of '-Eutf-8'. Something like:
RUBYOPT='-Eutf-8' ruby -e 'puts Encoding.default_external'
Check your OS/shell documentation for the precise syntax (the above
will not work on a basic Windows CMD prompt, look for the SET command).
Once you've got it successfully outputing UTF-8, use the same setting
when running rake in Minitest.
=== Minitest's own tests require GNU (or similar) diff.
This is also a problem primarily affecting Windows developers. PowerShell
has a command called diff, but it is not suitable for use with Minitest.
If you see failures like either of these, you are probably missing diff tool:
4) Failure:
TestMinitestUnitTestCase#test_assert_equal_different_long [D:/ruby/seattlerb/minitest/test/minitest/test_minitest_test.rb:936]:
Expected: "--- expected\n+++ actual\n@@ -1 +1 @@\n-\"hahahahahahahahahahahahahahahahahahahaha\"\n+\"blahblahblahblahblahblahblahblahblahblah\"\n"
Actual: "Expected: \"hahahahahahahahahahahahahahahahahahahaha\"\n Actual: \"blahblahblahblahblahblahblahblahblahblah\""
5) Failure:
TestMinitestUnitTestCase#test_assert_equal_different_collection_hash_hex_invisible [D:/ruby/seattlerb/minitest/test/minitest/test_minitest_test.rb:845]:
Expected: "No visible difference in the Hash#inspect output.\nYou should look at the implementation of #== on Hash or its members.\n
{1=>#}"
Actual: "Expected: {1=>#}\n Actual: {1=>#}"
If you use Cygwin or MSYS2 or similar there are packages that include a
GNU diff for Windows. If you don't, you can download GNU diffutils from
http://gnuwin32.sourceforge.net/packages/diffutils.htm
(make sure to add it to your PATH).
You can make sure it's installed and path is configured properly with:
diff.exe -v
There are multiple lines of output, the first should be something like:
diff (GNU diffutils) 2.8.1
If you are using PowerShell make sure you run diff.exe, not just diff,
which will invoke the PowerShell built in function.
== Known Extensions:
capybara_minitest_spec :: Bridge between Capybara RSpec matchers and
Minitest::Spec expectations (e.g.
page.must_have_content("Title")).
color_pound_spec_reporter :: Test names print Ruby Object types in color with
your Minitest Spec style tests.
minispec-metadata :: Metadata for describe/it blocks & CLI tag filter.
E.g. it "requires JS driver", js: true do &
ruby test.rb --tag js runs tests tagged :js.
minispec-rails :: Minimal support to use Spec style in Rails 5+.
mini-apivore :: for swagger based automated API testing.
minitest-around :: Around block for minitest. An alternative to
setup/teardown dance.
minitest-assert_errors :: Adds Minitest assertions to test for errors raised
or not raised by Minitest itself.
minitest-autotest :: autotest is a continuous testing facility meant to
be used during development.
minitest-bacon :: minitest-bacon extends minitest with bacon-like
functionality.
minitest-bang :: Adds support for RSpec-style let! to immediately
invoke let statements before each test.
minitest-bisect :: Helps you isolate and debug random test failures.
minitest-blink1_reporter :: Display test results with a Blink1.
minitest-capistrano :: Assertions and expectations for testing
Capistrano recipes.
minitest-capybara :: Capybara matchers support for minitest unit and
spec.
minitest-cc :: It provides minimal information about code coverage.
minitest-chef-handler :: Run Minitest suites as Chef report handlers
minitest-ci :: CI reporter plugin for Minitest.
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-documentation :: Minimal documentation format inspired by rspec's.
minitest-doc_reporter :: Detailed output inspired by rspec's documentation
format.
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-fail-fast :: Reimplements RSpec's "fail fast" feature
minitest-filecontent :: Support unit tests with expectation results in files.
Differing results will be stored again in files.
minitest-filesystem :: Adds assertion and expectation to help testing
filesystem contents.
minitest-firemock :: Makes your Minitest mocks more resilient.
minitest-focus :: Focus on one test at a time.
minitest-gcstats :: A minitest plugin that adds a report of the top
tests by number of objects allocated.
minitest-global_expectations:: Support minitest expectation methods for all objects
minitest-great_expectations :: Generally useful additions to minitest's
assertions and expectations.
minitest-growl :: Test notifier for minitest via growl.
minitest-happy :: GLOBALLY ACTIVATE MINITEST PRIDE! RAWR!
minitest-have_tag :: Adds Minitest assertions to test for the existence of
HTML tags, including contents, within a provided string.
minitest-heat :: Reporting that builds a heat map of failure locations
minitest-hooks :: Around and before_all/after_all/around_all hooks
minitest-hyper :: Pretty, single-page HTML reports for your Minitest runs
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-junit :: JUnit-style XML reporter for minitest.
minitest-keyword :: Use Minitest assertions with keyword arguments.
minitest-libnotify :: Test notifier for minitest via libnotify.
minitest-line :: Run test at line number.
minitest-logger :: Define assert_log and enable minitest to test log messages.
Supports Logger and Log4r::Logger.
minitest-macruby :: Provides extensions to minitest for macruby UI
testing.
minitest-matchers :: Adds support for RSpec-style matchers to
minitest.
minitest-matchers_vaccine :: Adds assertions that adhere to the matcher spec,
but without any expectation infections.
minitest-metadata :: Annotate tests with metadata (key-value).
minitest-mock_expectations :: Provides method call assertions for minitest.
minitest-mongoid :: Mongoid assertion matchers for Minitest.
minitest-must_not :: Provides must_not as an alias for wont in
Minitest.
minitest-optional_retry :: Automatically retry failed test to help with flakiness.
minitest-osx :: Reporter for the Mac OS X notification center.
minitest-parallel_fork :: Fork-based parallelization
minitest-parallel-db :: Run tests in parallel with a single database.
minitest-power_assert :: PowerAssert for Minitest.
minitest-predicates :: Adds support for .predicate? methods.
minitest-profile :: List the 10 slowest tests in your suite.
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 :: Colored red/green output for Minitest.
minitest-rspec_mocks :: Use RSpec Mocks with Minitest.
minitest-server :: minitest-server provides a client/server setup
with your minitest process, allowing your test
run to send its results directly to a handler.
minitest-sequel :: Minitest assertions to speed-up development and
testing of Ruby Sequel database setups.
minitest-shared_description :: Support for shared specs and shared spec
subclasses
minitest-should_syntax :: RSpec-style x.should == y assertions for
Minitest.
minitest-shouldify :: Adding all manner of shoulds to Minitest (bad
idea)
minitest-snail :: Print a list of tests that take too long
minitest-spec-context :: Provides rspec-ish context method to
Minitest::Spec.
minitest-spec-expect :: Expect syntax for Minitest::Spec (e.g.
expect(sequences).to_include :celery_man).
minitest-spec-magic :: Minitest::Spec extensions for Rails and beyond.
minitest-spec-rails :: Drop in Minitest::Spec superclass for
ActiveSupport::TestCase.
minitest-sprint :: Runs (Get it? It's fast!) your tests and makes
it easier to rerun individual failures.
minitest-stately :: Find leaking state between tests
minitest-stub_any_instance :: Stub any instance of a method on the given class
for the duration of a block.
minitest-stub-const :: Stub constants for the duration of a block.
minitest-tags :: Add tags for minitest.
minitest-unordered :: Adds a new assertion to minitest for checking the
contents of a collection, ignoring element order.
minitest-vcr :: Automatic cassette management with Minitest::Spec
and VCR.
minitest_log :: Adds structured logging, data explication, and verdicts.
minitest_owrapper :: Get tests results as a TestResult object.
minitest_should :: Shoulda style syntax for minitest test::unit.
minitest_tu_shim :: Bridges between test/unit and minitest.
mongoid-minitest :: Minitest matchers for Mongoid.
mutant-minitest :: Minitest integration for mutant.
pry-rescue :: A pry plugin w/ minitest support. See
pry-rescue/minitest.rb.
rematch :: Declutter your test files from large hardcoded data
and update them automatically when your code changes.
rspec2minitest :: Easily translate any RSpec matchers to Minitest
assertions and expectations.
stubberry :: Multiple stubbing 'berries', sweet and useful
stub helpers and assertions. ( stub_must,
assert_method_called, stubbing ORM objects by id )
== 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
* spork-minitest
== Minitest related goods
* minitest/pride fabric: https://www.spoonflower.com/fabric/3928730-again-by-katie_allen
== REQUIREMENTS:
* Ruby 2.3+. No magic is involved. I hope.
== INSTALL:
sudo gem install minitest
On 1.9, you already have it. To get newer candy you can still install
the gem, and then requiring "minitest/autorun" should automatically
pull it in. If not, you'll need to do it yourself:
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.
minitest-5.25.4/lib/ 0000755 0000041 0000041 00000000000 14743220663 014250 5 ustar www-data www-data minitest-5.25.4/lib/hoe/ 0000755 0000041 0000041 00000000000 14743220663 015023 5 ustar www-data www-data minitest-5.25.4/lib/hoe/minitest.rb 0000444 0000041 0000041 00000001040 14743220663 017175 0 ustar www-data www-data # :stopdoc:
class Hoe
# empty
end
module Hoe::Minitest
def minitest?
self.name == "minitest"
end
def initialize_minitest
unless minitest? then
dir = "../../minitest/dev/lib"
Hoe.add_include_dirs dir if File.directory? dir
end
gem "minitest"
require "minitest"
version = Minitest::VERSION.split(".").first(2).join "."
dependency "minitest", "~> #{version}", :development unless
minitest? or ENV["MT_NO_ISOLATE"]
end
def define_minitest_tasks
self.testlib = :minitest
end
end
minitest-5.25.4/lib/minitest/ 0000755 0000041 0000041 00000000000 14743220663 016104 5 ustar www-data www-data minitest-5.25.4/lib/minitest/hell.rb 0000444 0000041 0000041 00000000313 14743220663 017350 0 ustar www-data www-data require "minitest/parallel"
class Minitest::Test
parallelize_me!
end
begin
require "minitest/proveit"
rescue LoadError
warn "NOTE: `gem install minitest-proveit` for even more hellish tests"
end
minitest-5.25.4/lib/minitest/error_on_warning.rb 0000444 0000041 0000041 00000000373 14743220663 022004 0 ustar www-data www-data module Minitest
module ErrorOnWarning # :nodoc:
def warn message, category: nil
message = "[#{category}] #{message}" if category
raise UnexpectedWarning, message
end
end
::Warning.singleton_class.prepend ErrorOnWarning
end
minitest-5.25.4/lib/minitest/unit.rb 0000444 0000041 0000041 00000002372 14743220663 017412 0 ustar www-data www-data unless defined?(Minitest) then
# all of this crap is just to avoid circular requires and is only
# needed if a user requires "minitest/unit" directly instead of
# "minitest/autorun", so we also warn
from = caller.reject { |s| s =~ /rubygems/ }.join("\n ")
warn "Warning: you should require 'minitest/autorun' instead."
warn %(Warning: or add 'gem "minitest"' before 'require "minitest/autorun"')
warn "From:\n #{from}"
module Minitest # :nodoc:
end
MiniTest = Minitest # :nodoc: # prevents minitest.rb from requiring back to us
require "minitest"
end
MiniTest = Minitest unless defined?(MiniTest)
module Minitest
class Unit # :nodoc:
VERSION = Minitest::VERSION
class TestCase < Minitest::Test # :nodoc:
def self.inherited klass # :nodoc:
from = caller.first
warn "MiniTest::Unit::TestCase is now Minitest::Test. From #{from}"
super
end
end
def self.autorun # :nodoc:
from = caller.first
warn "MiniTest::Unit.autorun is now Minitest.autorun. From #{from}"
Minitest.autorun
end
def self.after_tests &b # :nodoc:
from = caller.first
warn "MiniTest::Unit.after_tests is now Minitest.after_run. From #{from}"
Minitest.after_run(&b)
end
end
end
minitest-5.25.4/lib/minitest/parallel.rb 0000444 0000041 0000041 00000003121 14743220663 020220 0 ustar www-data www-data module Minitest
module Parallel # :nodoc:
##
# The engine used to run multiple tests in parallel.
class Executor
##
# The size of the pool of workers.
attr_reader :size
##
# Create a parallel test executor of with +size+ workers.
def initialize size
@size = size
@queue = Thread::Queue.new
@pool = nil
end
##
# Start the executor
def start
@pool = Array.new(size) {
Thread.new @queue do |queue|
Thread.current.abort_on_exception = true
while job = queue.pop do
klass, method, reporter = job
reporter.synchronize { reporter.prerecord klass, method }
result = Minitest.run_one_method klass, method
reporter.synchronize { reporter.record result }
end
end
}
end
##
# Add a job to the queue
def << work; @queue << work; end
##
# Shuts down the pool of workers by signalling them to quit and
# waiting for them all to finish what they're currently working
# on.
def shutdown
size.times { @queue << nil }
@pool.each(&:join)
end
end
module Test # :nodoc:
def _synchronize; Minitest::Test.io_lock.synchronize { yield }; end # :nodoc:
module ClassMethods # :nodoc:
def run_one_method klass, method_name, reporter
Minitest.parallel_executor << [klass, method_name, reporter]
end
def test_order
:parallel
end
end
end
end
end
minitest-5.25.4/lib/minitest/expectations.rb 0000444 0000041 0000041 00000015331 14743220663 021140 0 ustar www-data www-data ##
# It's where you hide your "assertions".
#
# Please note, because of the way that expectations are implemented,
# all expectations (eg must_equal) are dependent upon a thread local
# variable +:current_spec+. If your specs rely on mixing threads into
# the specs themselves, you're better off using assertions or the new
# _(value) wrapper. For example:
#
# it "should still work in threads" do
# my_threaded_thingy do
# (1+1).must_equal 2 # bad
# assert_equal 2, 1+1 # good
# _(1 + 1).must_equal 2 # good
# value(1 + 1).must_equal 2 # good, also #expect
# _ { 1 + "1" }.must_raise TypeError # good
# end
# end
module Minitest::Expectations
##
# See Minitest::Assertions#assert_empty.
#
# _(collection).must_be_empty
#
# :method: must_be_empty
infect_an_assertion :assert_empty, :must_be_empty, :unary
##
# See Minitest::Assertions#assert_equal
#
# _(a).must_equal b
#
# :method: must_equal
infect_an_assertion :assert_equal, :must_equal
##
# See Minitest::Assertions#assert_in_delta
#
# _(n).must_be_close_to m [, delta]
#
# :method: must_be_close_to
infect_an_assertion :assert_in_delta, :must_be_close_to
infect_an_assertion :assert_in_delta, :must_be_within_delta # :nodoc:
##
# See Minitest::Assertions#assert_in_epsilon
#
# _(n).must_be_within_epsilon m [, epsilon]
#
# :method: must_be_within_epsilon
infect_an_assertion :assert_in_epsilon, :must_be_within_epsilon
##
# See Minitest::Assertions#assert_includes
#
# _(collection).must_include obj
#
# :method: must_include
infect_an_assertion :assert_includes, :must_include, :reverse
##
# See Minitest::Assertions#assert_instance_of
#
# _(obj).must_be_instance_of klass
#
# :method: must_be_instance_of
infect_an_assertion :assert_instance_of, :must_be_instance_of
##
# See Minitest::Assertions#assert_kind_of
#
# _(obj).must_be_kind_of mod
#
# :method: must_be_kind_of
infect_an_assertion :assert_kind_of, :must_be_kind_of
##
# See Minitest::Assertions#assert_match
#
# _(a).must_match b
#
# :method: must_match
infect_an_assertion :assert_match, :must_match
##
# See Minitest::Assertions#assert_nil
#
# _(obj).must_be_nil
#
# :method: must_be_nil
infect_an_assertion :assert_nil, :must_be_nil, :unary
##
# See Minitest::Assertions#assert_operator
#
# _(n).must_be :<=, 42
#
# This can also do predicates:
#
# _(str).must_be :empty?
#
# :method: must_be
infect_an_assertion :assert_operator, :must_be, :reverse
##
# See Minitest::Assertions#assert_output
#
# _ { ... }.must_output out_or_nil [, err]
#
# :method: must_output
infect_an_assertion :assert_output, :must_output, :block
##
# See Minitest::Assertions#assert_pattern_match
#
# _ { ... }.must_pattern_match [...]
#
# :method: must_pattern_match
infect_an_assertion :assert_pattern, :must_pattern_match, :block
##
# See Minitest::Assertions#assert_raises
#
# _ { ... }.must_raise exception
#
# :method: must_raise
infect_an_assertion :assert_raises, :must_raise, :block
##
# See Minitest::Assertions#assert_respond_to
#
# _(obj).must_respond_to msg
#
# :method: must_respond_to
infect_an_assertion :assert_respond_to, :must_respond_to, :reverse
##
# See Minitest::Assertions#assert_same
#
# _(a).must_be_same_as b
#
# :method: must_be_same_as
infect_an_assertion :assert_same, :must_be_same_as
##
# See Minitest::Assertions#assert_silent
#
# _ { ... }.must_be_silent
#
# :method: must_be_silent
infect_an_assertion :assert_silent, :must_be_silent, :block
##
# See Minitest::Assertions#assert_throws
#
# _ { ... }.must_throw sym
#
# :method: must_throw
infect_an_assertion :assert_throws, :must_throw, :block
##
# See Minitest::Assertions#assert_path_exists
#
# _(some_path).path_must_exist
#
# :method: path_must_exist
infect_an_assertion :assert_path_exists, :path_must_exist, :unary
##
# See Minitest::Assertions#refute_path_exists
#
# _(some_path).path_wont_exist
#
# :method: path_wont_exist
infect_an_assertion :refute_path_exists, :path_wont_exist, :unary
##
# See Minitest::Assertions#refute_empty
#
# _(collection).wont_be_empty
#
# :method: wont_be_empty
infect_an_assertion :refute_empty, :wont_be_empty, :unary
##
# See Minitest::Assertions#refute_equal
#
# _(a).wont_equal b
#
# :method: wont_equal
infect_an_assertion :refute_equal, :wont_equal
##
# See Minitest::Assertions#refute_in_delta
#
# _(n).wont_be_close_to m [, delta]
#
# :method: wont_be_close_to
infect_an_assertion :refute_in_delta, :wont_be_close_to
infect_an_assertion :refute_in_delta, :wont_be_within_delta # :nodoc:
##
# See Minitest::Assertions#refute_in_epsilon
#
# _(n).wont_be_within_epsilon m [, epsilon]
#
# :method: wont_be_within_epsilon
infect_an_assertion :refute_in_epsilon, :wont_be_within_epsilon
##
# See Minitest::Assertions#refute_includes
#
# _(collection).wont_include obj
#
# :method: wont_include
infect_an_assertion :refute_includes, :wont_include, :reverse
##
# See Minitest::Assertions#refute_instance_of
#
# _(obj).wont_be_instance_of klass
#
# :method: wont_be_instance_of
infect_an_assertion :refute_instance_of, :wont_be_instance_of
##
# See Minitest::Assertions#refute_kind_of
#
# _(obj).wont_be_kind_of mod
#
# :method: wont_be_kind_of
infect_an_assertion :refute_kind_of, :wont_be_kind_of
##
# See Minitest::Assertions#refute_match
#
# _(a).wont_match b
#
# :method: wont_match
infect_an_assertion :refute_match, :wont_match
##
# See Minitest::Assertions#refute_nil
#
# _(obj).wont_be_nil
#
# :method: wont_be_nil
infect_an_assertion :refute_nil, :wont_be_nil, :unary
##
# See Minitest::Assertions#refute_operator
#
# _(n).wont_be :<=, 42
#
# This can also do predicates:
#
# str.wont_be :empty?
#
# :method: wont_be
infect_an_assertion :refute_operator, :wont_be, :reverse
##
# See Minitest::Assertions#refute_pattern_match
#
# _ { ... }.wont_pattern_match [...]
#
# :method: wont_pattern_match
infect_an_assertion :refute_pattern, :wont_pattern_match, :block
##
# See Minitest::Assertions#refute_respond_to
#
# _(obj).wont_respond_to msg
#
# :method: wont_respond_to
infect_an_assertion :refute_respond_to, :wont_respond_to, :reverse
##
# See Minitest::Assertions#refute_same
#
# _(a).wont_be_same_as b
#
# :method: wont_be_same_as
infect_an_assertion :refute_same, :wont_be_same_as
end
minitest-5.25.4/lib/minitest/pride_plugin.rb 0000444 0000041 0000041 00000005647 14743220663 021124 0 ustar www-data www-data require "minitest"
module Minitest
def self.plugin_pride_options opts, _options # :nodoc:
opts.on "-p", "--pride", "Pride. Show your testing pride!" do
PrideIO.pride!
end
end
def self.plugin_pride_init options # :nodoc:
return unless PrideIO.pride?
klass = ENV["TERM"] =~ /^xterm|-(?:256color|direct)$/ ? PrideLOL : PrideIO
io = klass.new options[:io]
self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
rep.io = io if rep.io.tty?
end
end
##
# Show your testing pride!
class PrideIO
##
# Activate the pride plugin. Called from both -p option and minitest/pride
def self.pride!
@pride = true
end
##
# Are we showing our testing pride?
def self.pride?
@pride ||= false
end
# Start an escape sequence
ESC = "\e["
# End the escape sequence
NND = "#{ESC}0m"
# The IO we're going to pipe through.
attr_reader :io
def initialize io # :nodoc:
@io = io
# stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
# also reference https://en.wikipedia.org/wiki/ANSI_escape_code
@colors ||= (31..36).to_a
@size = @colors.size
@index = 0
end
##
# Wrap print to colorize the output.
def print o
case o
when ".", "S" then
io.print pride o
when "E", "F" then
io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
else
io.print o
end
end
def puts *o # :nodoc:
o.map! { |s|
s.to_s.sub("Finished") {
@index = 0
"Fabulous run".chars.map { |c| pride(c) }.join
}
}
io.puts(*o)
end
##
# Color a string.
def pride string
string = "*" if string == "."
c = @colors[@index % @size]
@index += 1
"#{ESC}#{c}m#{string}#{NND}"
end
def method_missing msg, *args # :nodoc:
io.send(msg, *args)
end
end
##
# If you thought the PrideIO was colorful...
#
# (Inspired by lolcat, but with clean math)
class PrideLOL < PrideIO
PI_3 = Math::PI / 3 # :nodoc:
def initialize io # :nodoc:
# walk red, green, and blue around a circle separated by equal thirds.
#
# To visualize, type this into wolfram-alpha:
#
# plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3)
@colors = Array.new(6 * 7) { |n|
n *= 1.0 / 3
r = (3 * Math.sin(n ) + 3).to_i
g = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
b = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
# Then we take rgb and encode them in a single number using
# base 6, shifted by 16 for the base 16 ansi colors.
36 * r + 6 * g + b + 16
}.rotate(4) # puts "red" first
super
end
##
# Make the string even more colorful. Damnit.
def pride string
c = @colors[@index % @size]
@index += 1
"#{ESC}38;5;#{c}m#{string}#{NND}"
end
end
end
minitest-5.25.4/lib/minitest/manual_plugins.rb 0000444 0000041 0000041 00000000363 14743220663 021447 0 ustar www-data www-data require "minitest"
ARGV << "--no-plugins"
module Minitest
##
# Manually load plugins by name.
def self.load *names
names.each do |name|
require "minitest/#{name}_plugin"
self.extensions << name.to_s
end
end
end
minitest-5.25.4/lib/minitest/mock.rb 0000444 0000041 0000041 00000024670 14743220663 017371 0 ustar www-data www-data class MockExpectationError < StandardError; end # :nodoc:
module Minitest # :nodoc:
##
# A simple and clean mock object framework.
#
# All mock objects are an instance of Mock
class Mock
alias __respond_to? respond_to?
overridden_methods = %i[
===
class
inspect
instance_eval
instance_variables
object_id
public_send
respond_to_missing?
send
to_s
]
overridden_methods << :singleton_method_added if defined?(::DEBUGGER__)
instance_methods.each do |m|
undef_method m unless overridden_methods.include?(m) || m =~ /^__/
end
overridden_methods.map(&:to_sym).each do |method_id|
old_w, $-w = $-w, nil
define_method method_id do |*args, **kwargs, &b|
if @expected_calls.key? method_id then
if kwargs.empty? then # FIX: drop this after 2.7 dead
method_missing(method_id, *args, &b)
else
method_missing(method_id, *args, **kwargs, &b)
end
else
if kwargs.empty? then # FIX: drop this after 2.7 dead
super(*args, &b)
else
super(*args, **kwargs, &b)
end
end
end
ensure
$-w = old_w
end
def initialize delegator = nil # :nodoc:
@delegator = delegator
@expected_calls = Hash.new { |calls, name| calls[name] = [] }
@actual_calls = Hash.new { |calls, name| calls[name] = [] }
end
@@KW_WARNED = false # :nodoc:
##
# Expect that method +name+ is called, optionally with +args+ (and
# +kwargs+ 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") # => raises MockExpectationError
#
# If a method will be called multiple times, specify a new expect for each one.
# They will be used in the order you define them.
#
# @mock.expect(:ordinal_increment, 'first')
# @mock.expect(:ordinal_increment, 'second')
#
# @mock.ordinal_increment # => 'first'
# @mock.ordinal_increment # => 'second'
# @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment"
#
def expect name, retval, args = [], **kwargs, &blk
name = name.to_sym
if blk then
raise ArgumentError, "args ignored when block given" unless args.empty?
raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
@expected_calls[name] << { :retval => retval, :block => blk }
else
raise ArgumentError, "args must be an array" unless Array === args
if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last ||
Hash == args.last) then
if kwargs.empty? then
kwargs = args.pop
else
unless @@KW_WARNED then
from = caller(1..1).first
warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
@@KW_WARNED = true
end
end
end
@expected_calls[name] <<
{ :retval => retval, :args => args, :kwargs => kwargs }
end
self
end
def __call name, data # :nodoc:
case data
when Hash then
args = data[:args].inspect[1..-2]
kwargs = data[:kwargs]
if kwargs && !kwargs.empty? then
args << ", " unless args.empty?
args << kwargs.inspect[1..-2]
end
"#{name}(#{args}) => #{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, expected|
actual = @actual_calls.fetch name, nil # defaults to []
raise MockExpectationError, "Expected #{__call name, expected[0]}" unless actual
raise MockExpectationError, "Expected #{__call name, expected[actual.size]}, got [#{__call name, actual}]" if
actual.size < expected.size
end
true
end
def method_missing sym, *args, **kwargs, &block # :nodoc:
unless @expected_calls.key? sym then
if @delegator && @delegator.respond_to?(sym)
if kwargs.empty? then # FIX: drop this after 2.7 dead
return @delegator.public_send(sym, *args, &block)
else
return @delegator.public_send(sym, *args, **kwargs, &block)
end
else
raise NoMethodError, "unmocked method %p, expected one of %p" %
[sym, @expected_calls.keys.sort_by(&:to_s)]
end
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 %p" %
[sym, args, kwargs]
end
expected_args, expected_kwargs, retval, val_block =
expected_call.values_at :args, :kwargs, :retval, :block
expected_kwargs = kwargs.to_h { |ak, av| [ak, Object] } if
Hash == expected_kwargs
if val_block then
# keep "verify" happy
@actual_calls[sym] << expected_call
raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
[sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
return retval
end
if expected_args.size != args.size then
raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
[sym, expected_args.size, args]
end
if expected_kwargs.size != kwargs.size then
raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
[sym, expected_kwargs.size, kwargs]
end
zipped_args = expected_args.zip args
fully_matched = zipped_args.all? { |mod, a|
mod === a or mod == a
}
unless fully_matched then
fmt = "mocked method %p called with unexpected arguments %p"
raise MockExpectationError, fmt % [sym, args]
end
unless expected_kwargs.keys.sort == kwargs.keys.sort then
fmt = "mocked method %p called with unexpected keywords %p vs %p"
raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
end
zipped_kwargs = expected_kwargs.to_h { |ek, ev|
av = kwargs[ek]
[ek, [ev, av]]
}
fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
ev === av or ev == av
}
unless fully_matched then
fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
end
@actual_calls[sym] << {
:retval => retval,
:args => zipped_args.map { |e, a| e === a ? e : a },
:kwargs => zipped_kwargs.to_h { |k, (e, a)| [k, e === a ? e : a] },
}
retval
end
def respond_to? sym, include_private = false # :nodoc:
return true if @expected_calls.key? sym.to_sym
return true if @delegator && @delegator.respond_to?(sym, include_private)
__respond_to? sym, include_private
end
end
end
module Minitest::Assertions
##
# Assert that the mock verifies correctly and fail if not.
def assert_mock mock, msg = nil
assert mock.verify
rescue MockExpectationError => e
msg = message(msg) { e.message }
flunk msg
end
end
module Minitest::Expectations
##
# See Minitest::Assertions#assert_mock.
#
# _(collection).must_verify
#
# :method: must_verify
infect_an_assertion :assert_mock, :must_verify, :unary if
defined?(infect_an_assertion)
end
##
# Object extensions for Minitest::Mock.
class Object
##
# 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. If stubbed method yields a block, +block_args+ will be
# passed along. 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
#--
# NOTE: keyword args in callables are NOT checked for correctness
# against the existing method. Too many edge cases to be worth it.
def stub name, val_or_callable, *block_args, **block_kwargs, &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, **kwargs|
super(*args, **kwargs)
end
end
metaclass.send :alias_method, new_name, name
if ENV["MT_KWARGS_HAC\K"] then
metaclass.send :define_method, name do |*args, &blk|
if val_or_callable.respond_to? :call then
val_or_callable.call(*args, &blk)
else
blk.call(*block_args, **block_kwargs) if blk
val_or_callable
end
end
else
metaclass.send :define_method, name do |*args, **kwargs, &blk|
if val_or_callable.respond_to? :call then
if kwargs.empty? then # FIX: drop this after 2.7 dead
val_or_callable.call(*args, &blk)
else
val_or_callable.call(*args, **kwargs, &blk)
end
else
if blk then
if block_kwargs.empty? then # FIX: drop this after 2.7 dead
blk.call(*block_args)
else
blk.call(*block_args, **block_kwargs)
end
end
val_or_callable
end
end
end
block[self]
ensure
metaclass.send :undef_method, name
metaclass.send :alias_method, name, new_name
metaclass.send :undef_method, new_name
end
end
minitest-5.25.4/lib/minitest/spec.rb 0000444 0000041 0000041 00000022463 14743220663 017370 0 ustar www-data www-data require "minitest/test"
class Module # :nodoc:
def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
block = dont_flip == :block
dont_flip = false if block
target_obj = block ? "_{obj.method}" : "_(obj)"
# https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
# Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06)
kw_extra = "ruby2_keywords %p" % [new_name] if respond_to? :ruby2_keywords, true
# warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
def #{new_name} *args
where = Minitest.filter_backtrace(caller).first
where = where.split(/:in /, 2).first # clean up noise
Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
end
#{kw_extra}
EOM
Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
def #{new_name} *args
raise "Calling ##{new_name} outside of test." unless ctx
case
when #{!!dont_flip} then
ctx.#{meth}(target, *args)
when #{block} && Proc === target then
ctx.#{meth}(*args, &target)
else
ctx.#{meth}(args.first, target, *args[1..-1])
end
end
#{kw_extra}
EOM
end
end
Minitest::Expectation = Struct.new :target, :ctx # :nodoc:
##
# Kernel extensions for minitest
module Kernel
##
# Describe a series of expectations for a given target +desc+.
#
# Defines a test class subclassing from either Minitest::Spec or
# from the surrounding describe's class. The surrounding class may
# subclass Minitest::Spec manually in order to easily share code:
#
# class MySpec < Minitest::Spec
# # ... shared code ...
# end
#
# class TestStuff < MySpec
# it "does stuff" do
# # shared code available here
# end
# describe "inner stuff" do
# it "still does stuff" do
# # ...and here
# end
# end
# end
#
# For more information on getting started with writing specs, see:
#
# http://www.rubyinside.com/a-minitestspec-tutorial-elegant-spec-style-testing-that-comes-with-ruby-5354.html
#
# For some suggestions on how to improve your specs, try:
#
# https://betterspecs.org
#
# but do note that several items there are debatable or specific to
# rspec.
#
# For more information about expectations, see Minitest::Expectations.
def describe desc, *additional_desc, &block # :doc:
stack = Minitest::Spec.describe_stack
is_spec_class = Class === self && kind_of?(Minitest::Spec::DSL)
name = [stack.last, desc, *additional_desc]
name.prepend self if stack.empty? && is_spec_class
sclas =
stack.last \
|| (is_spec_class && self) \
|| Minitest::Spec.spec_type(desc, *additional_desc)
cls = sclas.create name.compact.join("::"), desc
stack.push cls
cls.class_eval(&block)
stack.pop
cls
end
private :describe
end
##
# Minitest::Spec -- The faster, better, less-magical spec framework!
#
# For a list of expectations, see Minitest::Expectations.
class Minitest::Spec < Minitest::Test
def self.current # :nodoc:
Thread.current[:current_spec]
end
def initialize name # :nodoc:
super
Thread.current[:current_spec] = self
end
##
# 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, 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 spec_type desc, *additional
TYPES.find { |matcher, _klass|
if matcher.respond_to? :call then
matcher.call desc, *additional
else
matcher === desc.to_s
end
}.last
end
def describe_stack # :nodoc:
Thread.current[:describe_stack] ||= []
end
def children # :nodoc:
@children ||= []
end
def nuke_test_methods! # :nodoc:
self.public_instance_methods.grep(/^test_/).each do |name|
self.send :undef_method, name
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::Test#setup.
def before _type = nil, &block
define_method :setup do
super()
self.instance_eval(&block)
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::Test#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 inheritance, use minitest/test. 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)" }
@specs ||= 0
@specs += 1
name = "test_%04d_%s" % [ @specs, desc ]
undef_klasses = self.children.reject { |c| c.public_method_defined? name }
define_method name, &block
undef_klasses.each do |undef_klass|
undef_klass.send :undef_method, name
end
name
end
##
# Essentially, define an accessor for +name+ with +block+.
#
# Why use let instead of def? I honestly don't know.
def let name, &block
name = name.to_s
pre, post = "let '#{name}' cannot ", ". Please use another name."
methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
raise ArgumentError, "#{pre}begin with 'test'#{post}" if
name.start_with? "test"
raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
methods.include? name
define_method name do
@_memoized ||= {}
@_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
end
end
##
# 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
def create name, desc # :nodoc:
cls = Class.new self do
@name = name
@desc = desc
nuke_test_methods!
end
children << cls
cls
end
def name # :nodoc:
defined?(@name) ? @name : super
end
def to_s # :nodoc:
name # Can't alias due to 1.8.7, not sure why
end
attr_reader :desc # :nodoc:
alias specify it
##
# Rdoc... why are you so dumb?
module InstanceMethods
##
# Takes a value or a block and returns a value monad that has
# all of Expectations methods available to it.
#
# _(1 + 1).must_equal 2
#
# And for blocks:
#
# _ { 1 + "1" }.must_raise TypeError
#
# This method of expectation-based testing is preferable to
# straight-expectation methods (on Object) because it stores its
# test context, bypassing our hacky use of thread-local variables.
#
# NOTE: At some point, the methods on Object will be deprecated
# and then removed.
#
# It is also aliased to #value and #expect for your aesthetic
# pleasure:
#
# _(1 + 1).must_equal 2
# value(1 + 1).must_equal 2
# expect(1 + 1).must_equal 2
def _ value = nil, &block
Minitest::Expectation.new block || value, self
end
alias value _
alias expect _
def before_setup # :nodoc:
super
Thread.current[:current_spec] = self
end
end
def self.extended obj # :nodoc:
obj.send :include, InstanceMethods
end
end
extend DSL
TYPES = DSL::TYPES # :nodoc:
end
require "minitest/expectations"
class Object # :nodoc:
include Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
end
minitest-5.25.4/lib/minitest/test.rb 0000444 0000041 0000041 00000013760 14743220663 017415 0 ustar www-data www-data require "minitest" unless defined? Minitest::Runnable
module Minitest
##
# Subclass Test to create your own tests. Typically you'll want a
# Test subclass per implementation class.
#
# See Minitest::Assertions
class Test < Runnable
require "minitest/assertions"
include Minitest::Assertions
include Minitest::Reportable
def class_name # :nodoc:
self.class.name # for Minitest::Reportable
end
PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, SystemExit] # :nodoc:
SETUP_METHODS = %w[ before_setup setup after_setup ] # :nodoc:
TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
# :stopdoc:
class << self; attr_accessor :io_lock; end
self.io_lock = Mutex.new
# :startdoc:
##
# Call this at the top of your tests when you absolutely
# positively need to have ordered tests. In doing so, you're
# admitting that you suck and your tests are weak.
def self.i_suck_and_my_tests_are_order_dependent!
class << self
undef_method :test_order if method_defined? :test_order
define_method :test_order do :alpha end
end
end
##
# Make diffs for this Test use #pretty_inspect so that diff
# in assert_equal can have 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, &:pretty_inspect
end
##
# Call this at the top of your tests (inside the +Minitest::Test+
# subclass or +describe+ block) when you want to run your tests in
# parallel. In doing so, you're admitting that you rule and your
# tests are awesome.
def self.parallelize_me!
include Minitest::Parallel::Test
extend Minitest::Parallel::Test::ClassMethods
end
##
# Returns all instance methods starting with "test_". Based on
# #test_order, the methods are either sorted, randomized
# (default), or run in parallel.
def self.runnable_methods
methods = methods_matching(/^test_/)
case self.test_order
when :random, :parallel then
srand Minitest.seed
methods.sort.shuffle
when :alpha, :sorted then
methods.sort
else
raise "Unknown test_order: #{self.test_order.inspect}"
end
end
##
# Runs a single test with setup/teardown hooks.
def run
time_it do
capture_exceptions do
SETUP_METHODS.each do |hook|
self.send hook
end
self.send self.name
end
TEARDOWN_METHODS.each do |hook|
capture_exceptions do
self.send hook
end
end
end
Result.from self # per contract
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, 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::Test
# include MyMinitestPlugin
# end
def before_setup; end
##
# Runs before every test. Use this to set up before each test
# run.
def setup; end
##
# 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 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. Use this to clean up after each test
# run.
def 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 # LifecycleHooks
def capture_exceptions # :nodoc:
yield
rescue *PASSTHROUGH_EXCEPTIONS
raise
rescue Assertion => e
self.failures << e
rescue Exception => e
self.failures << UnexpectedError.new(sanitize_exception e)
end
def sanitize_exception e # :nodoc:
Marshal.dump e
e # good: use as-is
rescue
neuter_exception e
end
def neuter_exception e # :nodoc:
bt = e.backtrace
msg = e.message.dup
new_exception e.class, msg, bt # e.class can be a problem...
rescue
msg.prepend "Neutered Exception #{e.class}: "
new_exception RuntimeError, msg, bt, true # but if this raises, we die
end
def new_exception klass, msg, bt, kill = false # :nodoc:
ne = klass.new msg
ne.set_backtrace bt
if kill then
ne.instance_variables.each do |v|
ne.remove_instance_variable v
end
end
Marshal.dump ne # can raise TypeError
ne
end
include LifecycleHooks
include Guard
extend Guard
end # Test
end
require "minitest/unit" if ENV["MT_COMPAT"] # compatibility layer only
minitest-5.25.4/lib/minitest/compress.rb 0000444 0000041 0000041 00000005162 14743220663 020266 0 ustar www-data www-data module Minitest
##
# Compresses backtraces.
module Compress
##
# Takes a backtrace (array of strings) and compresses repeating
# cycles in it to make it more readable.
def compress orig
ary = orig
eswo = ->(a, n, off) { # each_slice_with_offset
if off.zero? then
a.each_slice n
else
# [ ...off... [...n...] [...n...] ... ]
front, back = a.take(off), a.drop(off)
[front].chain back.each_slice n
end
}
3.times do # maybe don't use loop do here?
index = ary # [ a b c b c b c d ]
.size
.times # 0...size
.group_by { |i| ary[i] } # { a: [0] b: [1 3 5], c: [2 4 6], d: [7] }
order = index
.reject { |k, v| v.size == 1 } # { b: [1 3 5], c: [2 4 6] }
.sort_by { |k, a1| ### sort by max dist + min offset
d = a1.each_cons(2).sum { |a2, b| b-a2 }
[-d, a1.first]
} # b: [1 3 5] c: [2 4 6]
ranges = order
.map { |k, a1| # [[1..2 3..4] [2..3 4..5]]
a1
.each_cons(2)
.map { |a2, b| a2..b-1 }
}
big_ranges = ranges
.flat_map { |a| # [1..2 3..4 2..3 4..5]
a.sort_by { |r| [-r.size, r.first] }.first 5
}
.first(100)
culprits = big_ranges
.map { |r|
eswo[ary, r.size, r.begin] # [o1 s1 s1 s2 s2]
.chunk_while { |a, b| a == b } # [[o1] [s1 s1] [s2 s2]]
.map { |a| [a.size, a.first] } # [[1 o1] [2 s1] [2 s2]]
}
.select { |chunks|
chunks.any? { |a| a.first > 1 } # compressed anything?
}
min = culprits
.min_by { |a| a.flatten.size } # most compressed
break unless min
ary = min.flat_map { |(n, lines)|
if n > 1 then
[[n, compress(lines)]] # [o1 [2 s1] [2 s2]]
else
lines
end
}
end
format = ->(lines) {
lines.flat_map { |line|
case line
when Array then
n, lines = line
lines = format[lines]
[
" +->> #{n} cycles of #{lines.size} lines:",
*lines.map { |s| " | #{s}" },
" +-<<",
]
else
line
end
}
}
format[ary]
end
end
end
minitest-5.25.4/lib/minitest/test_task.rb 0000444 0000041 0000041 00000017622 14743220663 020440 0 ustar www-data www-data require "shellwords"
require "rbconfig"
begin
require "rake/tasklib"
rescue LoadError => e
warn e.message
return
end
module Minitest # :nodoc:
##
# Minitest::TestTask is a rake helper that generates several rake
# tasks under the main test task's name-space.
#
# task :: the main test task
# task :cmd :: prints the command to use
# task :deps :: runs each test file by itself to find dependency errors
# task :slow :: runs the tests and reports the slowest 25 tests.
#
# Examples:
#
# Minitest::TestTask.create
#
# The most basic and default setup.
#
# Minitest::TestTask.create :my_tests
#
# The most basic/default setup, but with a custom name
#
# Minitest::TestTask.create :unit do |t|
# t.test_globs = ["test/unit/**/*_test.rb"]
# t.warning = false
# end
#
# Customize the name and only run unit tests.
#
# NOTE: To hook this task up to the default, make it a dependency:
#
# task default: :unit
class TestTask < Rake::TaskLib
WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc:
##
# Create several test-oriented tasks under +name+. Takes an
# optional block to customize variables.
def self.create name = :test, &block
task = new name
task.instance_eval(&block) if block
task.process_env
task.define
task
end
##
# Extra arguments to pass to the tests. Defaults empty but gets
# populated by a number of enviroment variables:
#
# N (-n flag) :: a string or regexp of tests to run.
# X (-e flag) :: a string or regexp of tests to exclude.
# A (arg) :: quick way to inject an arbitrary argument (eg A=--help).
#
# See #process_env
attr_accessor :extra_args
##
# The code to load the framework. Defaults to requiring
# minitest/autorun...
#
# Why do I have this as an option?
attr_accessor :framework
##
# Extra library directories to include. Defaults to %w[lib test
# .]. Also uses $MT_LIB_EXTRAS allowing you to dynamically
# override/inject directories for custom runs.
attr_accessor :libs
##
# The name of the task and base name for the other tasks generated.
attr_accessor :name
##
# File globs to find test files. Defaults to something sensible to
# find test files under the test directory.
attr_accessor :test_globs
##
# Turn on ruby warnings (-w flag). Defaults to true.
attr_accessor :warning
##
# Optional: Additional ruby to run before the test framework is loaded.
attr_accessor :test_prelude
##
# Print out commands as they run. Defaults to Rake's +trace+ (-t
# flag) option.
attr_accessor :verbose
##
# Use TestTask.create instead.
def initialize name = :test # :nodoc:
self.extra_args = []
self.framework = %(require "minitest/autorun")
self.libs = %w[lib test .]
self.name = name
self.test_globs = ["test/**/test_*.rb",
"test/**/*_test.rb"]
self.test_prelude = nil
self.verbose = Rake.application.options.trace || Rake.verbose == true
self.warning = true
end
##
# Extract variables from the environment and convert them to
# command line arguments. See #extra_args.
#
# Environment Variables:
#
# MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
# N :: Tests to run (string or /regexp/).
# X :: Tests to exclude (string or /regexp/).
# A :: Any extra arguments. Honors shell quoting.
#
# Deprecated:
#
# TESTOPTS :: For argument passing, use +A+.
# N :: For parallel testing, use +MT_CPU+.
# FILTER :: Same as +TESTOPTS+.
def process_env
warn "TESTOPTS is deprecated in Minitest::TestTask. Use A instead" if
ENV["TESTOPTS"]
warn "FILTER is deprecated in Minitest::TestTask. Use A instead" if
ENV["FILTER"]
warn "N is deprecated in Minitest::TestTask. Use MT_CPU instead" if
ENV["N"] && ENV["N"].to_i > 0
lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR
self.libs[0, 0] = lib_extras
extra_args << "-n" << ENV["N"] if ENV["N"]
extra_args << "-e" << ENV["X"] if ENV["X"]
extra_args.concat Shellwords.split(ENV["TESTOPTS"]) if ENV["TESTOPTS"]
extra_args.concat Shellwords.split(ENV["FILTER"]) if ENV["FILTER"]
extra_args.concat Shellwords.split(ENV["A"]) if ENV["A"]
ENV.delete "N" if ENV["N"]
# TODO? RUBY_DEBUG = ENV["RUBY_DEBUG"]
# TODO? ENV["RUBY_FLAGS"]
extra_args.compact!
end
def define # :nodoc:
desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args."
task name do
ruby make_test_cmd, verbose: verbose
end
desc "Print out the test command. Good for profiling and other tools."
task "#{name}:cmd" do
puts "ruby #{make_test_cmd}"
end
desc "Show which test files fail when run in isolation."
task "#{name}:isolated" do
tests = Dir[*self.test_globs].uniq
# 3 seems to be the magic number... (tho not by that much)
bad, good, n = {}, [], (ENV.delete("K") || 3).to_i
file = ENV.delete "F"
times = {}
tt0 = Time.now
n.threads_do tests.sort do |path|
t0 = Time.now
output = `#{Gem.ruby} #{make_test_cmd path} 2>&1`
t1 = Time.now - t0
times[path] = t1
if $?.success?
$stderr.print "."
good << path
else
$stderr.print "x"
bad[path] = output
end
end
puts "done"
puts "Ran in %.2f seconds" % [ Time.now - tt0 ]
if file then
require "json"
File.open file, "w" do |io|
io.puts JSON.pretty_generate times
end
end
unless good.empty?
puts
puts "# Good tests:"
puts
good.sort.each do |path|
puts "%.2fs: %s" % [times[path], path]
end
end
unless bad.empty?
puts
puts "# Bad tests:"
puts
bad.keys.sort.each do |path|
puts "%.2fs: %s" % [times[path], path]
end
puts
puts "# Bad Test Output:"
puts
bad.sort.each do |path, output|
puts
puts "# #{path}:"
puts output
end
exit 1
end
end
task "#{name}:deps" => "#{name}:isolated" # now just an alias
desc "Run the test suite and report the slowest 25 tests."
task "#{name}:slow" do
sh ["rake #{name} A=-v",
"egrep '#test_.* s = .'",
"sort -n -k2 -t=",
"tail -25"].join " | "
end
end
##
# Generate the test command-line.
def make_test_cmd globs = test_globs
tests = []
tests.concat Dir[*globs].sort.shuffle # TODO: SEED -> srand first?
tests.map! { |f| %(require "#{f}") }
runner = []
runner << test_prelude if test_prelude
runner << framework
runner.concat tests
runner = runner.join "; "
args = []
args << "-I#{libs.join File::PATH_SEPARATOR}" unless libs.empty?
args << "-w" if warning
args << "-e"
args << "'#{runner}'"
args << "--"
args << extra_args.map(&:shellescape)
args.join " "
end
end
end
class Work < Queue # :nodoc:
def initialize jobs = [] # :nodoc:
super()
jobs.each do |job|
self << job
end
close
end
end
class Integer # :nodoc:
def threads_do jobs # :nodoc:
q = Work.new jobs
Array.new(self) {
Thread.new do
while job = q.pop # go until quit value
yield job
end
end
}.each(&:join)
end
end
minitest-5.25.4/lib/minitest/assertions.rb 0000444 0000041 0000041 00000056564 14743220663 020641 0 ustar www-data www-data require "rbconfig"
require "tempfile"
require "stringio"
module Minitest
##
# Minitest Assertions. All assertion methods accept a +msg+ which is
# printed if the assertion fails.
#
# Protocol: Nearly everything here boils up to +assert+, which
# expects to be able to increment an instance accessor named
# +assertions+. This is not provided by Assertions and must be
# provided by the thing including Assertions. See Minitest::Runnable
# for an example.
module Assertions
UNDEFINED = Object.new # :nodoc:
def UNDEFINED.inspect # :nodoc:
"UNDEFINED" # again with the rdoc bugs... :(
end
##
# Returns the diff command to use in #diff. Tries to intelligently
# figure out what diff to use.
def self.diff
return @diff if defined? @diff
@diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ and
system "diff.exe", __FILE__, __FILE__) then
"diff.exe -u"
elsif system "gdiff", __FILE__, __FILE__ then
"gdiff -u" # solaris and kin suck
elsif system "diff", __FILE__, __FILE__ then
"diff -u"
else
nil
end
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.
#
# See +things_to_diff+ for more info.
def diff exp, act
result = nil
expect, butwas = things_to_diff exp, act
return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless
expect
Tempfile.open "expect" do |a|
a.puts expect
a.flush
Tempfile.open "butwas" do |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
end
##
# Returns things to diff [expect, butwas], or [nil, nil] if nothing to diff.
#
# Criterion:
#
# 1. Strings include newlines or escaped newlines, but not both.
# 2. or: String lengths are > 30 characters.
# 3. or: Strings are equal to each other (but maybe different encodings?).
# 4. and: we found a diff executable.
def things_to_diff exp, act
expect = mu_pp_for_diff exp
butwas = mu_pp_for_diff act
e1, e2 = expect.include?("\n"), expect.include?("\\n")
b1, b2 = butwas.include?("\n"), butwas.include?("\\n")
need_to_diff =
(e1 ^ e2 ||
b1 ^ b2 ||
expect.size > 30 ||
butwas.size > 30 ||
expect == butwas) &&
Minitest::Assertions.diff
need_to_diff && [expect, butwas]
end
##
# This returns a human-readable version of +obj+. By default
# #inspect is called. You can override this to use #pretty_inspect
# if you want.
#
# See Minitest::Test.make_my_diffs_pretty!
def mu_pp obj
s = obj.inspect.encode Encoding.default_external
return s unless String === obj &&
(obj.encoding != Encoding.default_external || !obj.valid_encoding?)
enc = "# encoding: #{obj.encoding}"
val = "# valid: #{obj.valid_encoding?}"
[enc, val, s].join "\n"
end
##
# This returns a diff-able more human-readable version of +obj+.
# This differs from the regular mu_pp because it expands escaped
# newlines and makes hex-values (like object_ids) generic. This
# uses mu_pp to do the first pass and then cleans it up.
def mu_pp_for_diff obj
str = mu_pp obj
# both '\n' & '\\n' (_after_ mu_pp (aka inspect))
single = str.match?(/(?exp == act 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 nicer structural diffing, set
# Minitest::Test.make_my_diffs_pretty!
#
# For floats use assert_in_delta.
#
# See also: Minitest::Assertions.diff
def assert_equal exp, act, msg = nil
msg = message(msg, E) { diff exp, act }
result = assert exp == act, msg
if nil == exp then
if Minitest::VERSION >= "6" then
refute_nil exp, "Use assert_nil if expecting nil."
else
warn "DEPRECATED: Use assert_nil if expecting nil from #{_where}. This will fail in Minitest 6."
end
end
result
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 exp, act, epsilon = 0.001, msg = nil
assert_in_delta exp, act, [exp.abs, act.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
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+ =~ +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
Regexp.last_match
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. Eg:
#
# assert_operator 5, :<=, 4
def assert_operator o1, op, o2 = UNDEFINED, msg = nil
return assert_predicate o1, op, msg if UNDEFINED == o2
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.
#
# assert_output(/hey/) { method_with_output }
#
# NOTE: this uses #capture_io, not #capture_subprocess_io.
#
# See also: #assert_silent
def assert_output stdout = nil, stderr = nil
flunk "assert_output requires a block to capture output." unless
block_given?
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)
rescue Assertion
raise
rescue => e
raise UnexpectedError, e
end
##
# Fails unless +path+ exists.
def assert_path_exists path, msg = nil
msg = message(msg) { "Expected path '#{path}' to exist" }
assert File.exist?(path), msg
end
##
# For testing with pattern matching (only supported with Ruby 3.0 and later)
#
# # pass
# assert_pattern { [1,2,3] => [Integer, Integer, Integer] }
#
# # fail "length mismatch (given 3, expected 1)"
# assert_pattern { [1,2,3] => [Integer] }
#
# The bare => pattern will raise a NoMatchingPatternError on failure, which would
# normally be counted as a test error. This assertion rescues NoMatchingPatternError and
# generates a test failure. Any other exception will be raised as normal and generate a test
# error.
def assert_pattern
raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0"
flunk "assert_pattern requires a block to capture errors." unless block_given?
begin # TODO: remove after ruby 2.6 dropped
yield
pass
rescue NoMatchingPatternError => e
flunk e.message
end
end
##
# For testing with predicates. Eg:
#
# 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.
#
# +exp+ takes an optional message on the end to help explain
# failures and defaults to StandardError if no exception class is
# passed. Eg:
#
# assert_raises(CustomError) { method_with_custom_error }
#
# With custom error message:
#
# assert_raises(CustomError, 'This should have raised CustomError') { method_with_custom_error }
#
# Using the returned object:
#
# error = assert_raises(CustomError) do
# raise CustomError, 'This is really bad'
# end
#
# assert_equal 'This is really bad', error.message
def assert_raises *exp
flunk "assert_raises requires a block to capture errors." unless
block_given?
msg = "#{exp.pop}.\n" if String === exp.last
exp << StandardError if exp.empty?
begin
yield
rescue *exp => e
pass # count assertion
return e
rescue Minitest::Assertion # incl Skip & UnexpectedError
# don't count assertion
raise
rescue SignalException, SystemExit
raise
rescue Exception => e
flunk proc {
exception_details(e, "#{msg}#{mu_pp exp} exception expected, not")
}
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+.
# include_all defaults to false to match Object#respond_to?
def assert_respond_to obj, meth, msg = nil, include_all: false
msg = message(msg) {
"Expected #{mu_pp obj} (#{obj.class}) to respond to ##{meth}"
}
assert obj.respond_to?(meth, include_all), 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
def assert_send send_ary, m = nil
warn "DEPRECATED: assert_send. From #{_where}"
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
value = 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
raise e unless e.message.include? "uncaught throw"
default += ", not #{e.message.split(/ /).last}"
rescue NameError => e # 1.8 exception
raise e unless e.name == sym
default += ", not #{e.name.inspect}"
end
caught = false
end
assert caught, message(msg) { default }
value
rescue Assertion
raise
rescue => e
raise UnexpectedError, e
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
_synchronize do
begin
captured_stdout, captured_stderr = StringIO.new, StringIO.new
orig_stdout, orig_stderr = $stdout, $stderr
$stdout, $stderr = captured_stdout, captured_stderr
yield
return captured_stdout.string, captured_stderr.string
ensure
$stdout = orig_stdout
$stderr = orig_stderr
end
end
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
_synchronize do
begin
require "tempfile"
captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
$stdout.reopen captured_stdout
$stderr.reopen captured_stderr
yield
$stdout.rewind
$stderr.rewind
return 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"
end
##
# Fails after a given date (in the local time zone). This allows
# you to put time-bombs in your tests if you need to keep
# something around until a later date lest you forget about it.
def fail_after y, m, d, msg
flunk msg if Time.now > Time.local(y, m, d)
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 = nil, &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 truthy.
def refute test, msg = nil
msg ||= message { "Expected #{mu_pp test} to not be truthy" }
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 exp == act.
#
# 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
msg = message(msg) { "Expected #{mu_pp obj} to not be a kind of #{cls}" }
refute obj.kind_of?(cls), msg
end
##
# Fails if +matcher+ =~ +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
##
# For testing with pattern matching (only supported with Ruby 3.0 and later)
#
# # pass
# refute_pattern { [1,2,3] => [String] }
#
# # fail "NoMatchingPatternError expected, but nothing was raised."
# refute_pattern { [1,2,3] => [Integer, Integer, Integer] }
#
# This assertion expects a NoMatchingPatternError exception, and will fail if none is raised. Any
# other exceptions will be raised as normal and generate a test error.
def refute_pattern
raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0"
flunk "refute_pattern requires a block to capture errors." unless block_given?
begin
yield
flunk "NoMatchingPatternError expected, but nothing was raised."
rescue NoMatchingPatternError
pass
end
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 = UNDEFINED, msg = nil
return refute_predicate o1, op, msg if UNDEFINED == o2
msg = message(msg) { "Expected #{mu_pp o1} to not be #{op} #{mu_pp o2}" }
refute o1.__send__(op, o2), msg
end
##
# Fails if +path+ exists.
def refute_path_exists path, msg = nil
msg = message(msg) { "Expected path '#{path}' to not exist" }
refute File.exist?(path), 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+.
# include_all defaults to false to match Object#respond_to?
def refute_respond_to obj, meth, msg = nil, include_all: false
msg = message(msg) { "Expected #{mu_pp obj} to not respond to #{meth}" }
refute obj.respond_to?(meth, include_all), 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 run. If run in verbose-mode, the skipped run
# gets listed at the end of the run but doesn't cause a failure
# exit code.
def skip msg = nil, _ignored = nil
msg ||= "Skipped, no message given"
@skip = true
raise Minitest::Skip, msg
end
##
# Skips the current run until a given date (in the local time
# zone). This allows you to put some fixes on hold until a later
# date, but still holds you accountable and prevents you from
# forgetting it.
def skip_until y, m, d, msg
skip msg if Time.now < Time.local(y, m, d)
where = caller(1..1).first.rpartition(":in").reject(&:empty?).first
warn "Stale skip_until %p at %s" % [msg, where]
end
##
# Was this testcase skipped? Meant for #teardown.
def skipped?
defined?(@skip) and @skip
end
end
end
minitest-5.25.4/lib/minitest/autorun.rb 0000444 0000041 0000041 00000000177 14743220663 020131 0 ustar www-data www-data require "minitest"
require "minitest/spec"
require "minitest/mock"
require "minitest/hell" if ENV["MT_HELL"]
Minitest.autorun
minitest-5.25.4/lib/minitest/benchmark.rb 0000444 0000041 0000041 00000027647 14743220663 020401 0 ustar www-data www-data require "minitest/test"
require "minitest/spec"
module Minitest
##
# Subclass Benchmark to create your own benchmark runs. Methods
# starting with "bench_" get executed on a per-class.
#
# See Minitest::Assertions
class Benchmark < Test
def self.io # :nodoc:
@io
end
def io # :nodoc:
self.class.io
end
def self.run reporter, options = {} # :nodoc:
@io = reporter.io
super
end
def self.runnable_methods # :nodoc:
methods_matching(/^bench_/)
end
##
# 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
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 self.name
times = []
range.each do |x|
GC.start
t0 = Minitest.clock_time
instance_exec(x, &work)
t = Minitest.clock_time - 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 https://www.graphpad.com/guides/prism/8/curve-fitting/reg_intepretingnonlinr2.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: https://en.wikipedia.org/wiki/Coefficient_of_determination
def fit_error xys
y_bar = sigma(xys) { |_, y| y } / xys.size.to_f
ss_tot = sigma(xys) { |_, 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: https://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) { |_, y| Math.log(y) }
sx2 = sigma(xys) { |x, _| 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: https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html
def fit_logarithmic xs, ys
n = xs.size
xys = xs.zip ys
slnx2 = sigma(xys) { |x, _| Math.log(x) ** 2 }
slnx = sigma(xys) { |x, _| Math.log(x) }
sylnx = sigma(xys) { |x, y| y * Math.log(x) }
sy = sigma(xys) { |_, 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: https://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: https://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 => 6
# sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14
def sigma enum, &block
enum = enum.map(&block) if block
enum.sum
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
module Minitest
##
# The spec version of Minitest::Benchmark.
class BenchSpec < Benchmark
extend Minitest::Spec::DSL
##
# 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 Minitest::Benchmark#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 Bench" 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 Bench" 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 Bench" 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
##
# Create a benchmark that verifies that the performance is logarithmic.
#
# describe "my class Bench" do
# bench_performance_logarithmic "algorithm" do |n|
# @obj.algorithm(n)
# end
# end
def self.bench_performance_logarithmic name, threshold = 0.99, &work
bench name do
assert_performance_logarithmic threshold, &work
end
end
##
# Create a benchmark that verifies that the performance is power.
#
# describe "my class Bench" do
# bench_performance_power "algorithm" do |n|
# @obj.algorithm(n)
# end
# end
def self.bench_performance_power name, threshold = 0.99, &work
bench name do
assert_performance_power threshold, &work
end
end
end
Minitest::Spec.register_spec_type(/Bench(mark)?$/, Minitest::BenchSpec)
end
minitest-5.25.4/lib/minitest/pride.rb 0000444 0000041 0000041 00000000103 14743220663 017524 0 ustar www-data www-data require "minitest"
Minitest.load_plugins
Minitest::PrideIO.pride!
minitest-5.25.4/lib/minitest.rb 0000444 0000041 0000041 00000072202 14743220663 016432 0 ustar www-data www-data require "optparse"
require "stringio"
require "etc"
require_relative "minitest/parallel"
require_relative "minitest/compress"
##
# The top-level namespace for Minitest. Also the location of the main
# runtime. See +Minitest.run+ for more information.
module Minitest
VERSION = "5.25.4" # :nodoc:
@@installed_at_exit ||= false
@@after_run = []
@extensions = []
def self.cattr_accessor name # :nodoc:
(class << self; self; end).attr_accessor name
end
##
# The random seed used for this run. This is used to srand at the
# start of the run and between each +Runnable.run+.
#
# Set via Minitest.run after processing args.
cattr_accessor :seed
##
# Parallel test executor
cattr_accessor :parallel_executor
warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0
n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
self.parallel_executor = Parallel::Executor.new n_threads
##
# Filter object for backtraces.
cattr_accessor :backtrace_filter
##
# Reporter object to be used for all runs.
#
# NOTE: This accessor is only available during setup, not during runs.
cattr_accessor :reporter
##
# Names of known extension plugins.
cattr_accessor :extensions
##
# The signal to use for dumping information to STDERR. Defaults to "INFO".
cattr_accessor :info_signal
self.info_signal = "INFO"
cattr_accessor :allow_fork
self.allow_fork = false
##
# Registers Minitest to run at process exit
def self.autorun
Warning[:deprecated] = true if
Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
at_exit {
next if $! and not ($!.kind_of? SystemExit and $!.success?)
exit_code = nil
pid = Process.pid
at_exit {
next if !Minitest.allow_fork && Process.pid != pid
@@after_run.reverse_each(&:call)
exit exit_code || false
}
exit_code = Minitest.run ARGV
} unless @@installed_at_exit
@@installed_at_exit = true
end
##
# A simple hook allowing you to run a block of code after everything
# is done running. Eg:
#
# Minitest.after_run { p $debugging_info }
def self.after_run &block
@@after_run << block
end
##
# Register a plugin to be used. Does NOT require / load it.
def self.register_plugin name_or_mod
self.extensions << name_or_mod
nil
end
def self.load_plugins # :nodoc:
return unless defined? Gem
seen = {}
Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
name = File.basename plugin_path, "_plugin.rb"
next if seen[name]
seen[name] = true
require plugin_path
self.extensions << name
end
end
def self.init_plugins options # :nodoc:
self.extensions.each do |mod_or_meth|
case mod_or_meth
when Symbol, String then
name = mod_or_meth
msg = "plugin_#{name}_init"
next unless self.respond_to? msg
send msg, options
when Module then
recv = mod_or_meth
next unless recv.respond_to? :minitest_plugin_init
recv.minitest_plugin_init options
else
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
end
end
end
def self.process_args args = [] # :nodoc:
options = {
:io => $stdout,
}
orig_args = args.dup
OptionParser.new do |opts|
opts.banner = "minitest options:"
opts.version = Minitest::VERSION
opts.on "-h", "--help", "Display this help." do
puts opts
exit
end
opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)."
desc = "Sets random seed. Also via env. Eg: SEED=n rake"
opts.on "-s", "--seed SEED", Integer, desc do |m|
options[:seed] = m.to_i
end
opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
options[:verbose] = true
end
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
options[:quiet] = true
end
opts.on "--show-skips", "Show skipped at the end of run." do
options[:show_skips] = true
end
opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
options[:filter] = a
end
opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
options[:exclude] = a
end
opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
options[:skip] = s.chars.to_a
end
ruby27plus = ::Warning.respond_to? :[]=
opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
options[:Werror] = true
case s
when "error", "all", nil then
require "minitest/error_on_warning"
$VERBOSE = true
::Warning[:deprecated] = true if ruby27plus
else
::Warning[s.to_sym] = true if ruby27plus # check validity of category
end
end
unless extensions.empty?
opts.separator ""
opts.separator "Known extensions: #{extensions.join ", "}"
extensions.each do |mod_or_meth|
case mod_or_meth
when Symbol, String then
meth = mod_or_meth
msg = "plugin_#{meth}_options"
send msg, opts, options if respond_to? msg
when Module
recv = mod_or_meth
next unless recv.respond_to? :minitest_plugin_options
recv.minitest_plugin_options opts, options
else
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
end
end
end
begin
opts.parse! args
rescue OptionParser::InvalidOption => e
puts
puts e
puts
puts opts
exit 1
end
orig_args -= args
end
unless options[:seed] then
srand
options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF
orig_args << "--seed" << options[:seed].to_s
end
options[:args] = orig_args.map { |s|
s.match?(/[\s|&<>$()]/) ? s.inspect : s
}.join " "
options
end
##
# This is the top-level run method. Everything starts from here. It
# tells each Runnable sub-class to run, and each of those are
# responsible for doing whatever they do.
#
# The overall structure of a run looks like this:
#
# Minitest.autorun
# Minitest.run(args)
# Minitest.load_plugins
# Minitest.process_args
# Minitest.init_plugins
# Minitest.__run(reporter, options)
# Runnable.runnables.each
# runnable_klass.run(reporter, options)
# self.runnable_methods.each
# self.run_one_method(self, runnable_method, reporter)
# Minitest.run_one_method(klass, runnable_method)
# klass.new(runnable_method).run
def self.run args = []
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
options = process_args args
Minitest.seed = options[:seed]
srand Minitest.seed
reporter = CompositeReporter.new
reporter << SummaryReporter.new(options[:io], options)
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
self.reporter = reporter # this makes it available to plugins
self.init_plugins options
self.reporter = nil # runnables shouldn't depend on the reporter, ever
self.parallel_executor.start if parallel_executor.respond_to? :start
reporter.start
begin
__run reporter, options
rescue Interrupt
warn "Interrupted. Exiting..."
end
self.parallel_executor.shutdown
# might have been removed/replaced during init_plugins:
summary = reporter.reporters.grep(SummaryReporter).first
reporter.report
return empty_run! options if summary && summary.count == 0
reporter.passed?
end
def self.empty_run! options # :nodoc:
filter = options[:filter]
return true unless filter # no filter, but nothing ran == success
warn "Nothing ran for filter: %s" % [filter]
require "did_you_mean" # soft dependency, punt if it doesn't load
ms = Runnable.runnables.flat_map(&:runnable_methods)
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
warn DidYouMean::Formatter.message_for cs unless cs.empty?
rescue LoadError
# do nothing
end
##
# Internal run method. Responsible for telling all Runnable
# sub-classes to run.
def self.__run reporter, options
suites = Runnable.runnables.shuffle
parallel, serial = suites.partition { |s| s.test_order == :parallel }
# If we run the parallel tests before the serial tests, the parallel tests
# could run in parallel with the serial tests. This would be bad because
# the serial tests won't lock around Reporter#record. Run the serial tests
# first, so that after they complete, the parallel tests will lock when
# recording results.
serial.map { |suite| suite.run reporter, options } +
parallel.map { |suite| suite.run reporter, options }
end
def self.filter_backtrace bt # :nodoc:
result = backtrace_filter.filter bt
result = bt.dup if result.empty?
result
end
##
# Represents anything "runnable", like Test, Spec, Benchmark, or
# whatever you can dream up.
#
# Subclasses of this are automatically registered and available in
# Runnable.runnables.
class Runnable
##
# Number of assertions executed in this run.
attr_accessor :assertions
##
# An assertion raised during the run, if any.
attr_accessor :failures
##
# The time it took to run.
attr_accessor :time
def time_it # :nodoc:
t0 = Minitest.clock_time
yield
ensure
self.time = Minitest.clock_time - t0
end
##
# Name of the run.
def name
@NAME
end
##
# Set the name of the run.
def name= o
@NAME = o
end
##
# Returns all instance methods matching the pattern +re+.
def self.methods_matching re
public_instance_methods(true).grep(re).map(&:to_s)
end
def self.reset # :nodoc:
@@runnables = []
end
reset
##
# Responsible for running all runnable methods in a given class,
# each in its own instance. Each instance is passed to the
# reporter to record.
def self.run reporter, options = {}
pos = options[:filter]
neg = options[:exclude]
pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
filtered_methods = self.runnable_methods
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
return if filtered_methods.empty?
t0 = name = nil
@_info_handler = lambda do
unless reporter.passed? then
warn "Current results:"
warn reporter.reporters.grep(SummaryReporter).first
end
warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
end
with_info_handler reporter do
filtered_methods.each do |method_name|
name = method_name
t0 = Minitest.clock_time
run_one_method self, method_name, reporter
end
end
end
##
# Runs a single method and has the reporter record the result.
# This was considered internal API but is factored out of run so
# that subclasses can specialize the running of an individual
# test. See Minitest::ParallelTest::ClassMethods for an example.
def self.run_one_method klass, method_name, reporter
reporter.prerecord klass, method_name
reporter.record Minitest.run_one_method(klass, method_name)
end
##
# Defines the order to run tests (:random by default). Override
# this or use a convenience method to change it for your tests.
def self.test_order
:random
end
def self.with_info_handler reporter, &block # :nodoc:
on_signal ::Minitest.info_signal, @_info_handler, &block
end
SIGNALS = Signal.list # :nodoc:
def self.on_signal name, action # :nodoc:
supported = SIGNALS[name]
old_trap = trap name do
old_trap.call if old_trap.respond_to? :call
action.call
end if supported
yield
ensure
trap name, old_trap if supported
end
##
# Each subclass of Runnable is responsible for overriding this
# method to return all runnable methods. See #methods_matching.
def self.runnable_methods
raise NotImplementedError, "subclass responsibility"
end
##
# Returns all subclasses of Runnable.
def self.runnables
@@runnables
end
@@marshal_dump_warned = false
def marshal_dump # :nodoc:
unless @@marshal_dump_warned then
warn ["Minitest::Runnable#marshal_dump is deprecated.",
"You might be violating internals. From", caller(1..1).first].join " "
@@marshal_dump_warned = true
end
[self.name, self.failures, self.assertions, self.time]
end
def marshal_load ary # :nodoc:
self.name, self.failures, self.assertions, self.time = ary
end
def failure # :nodoc:
self.failures.first
end
def initialize name # :nodoc:
self.name = name
self.failures = []
self.assertions = 0
# lazy initializer for metadata
end
##
# Metadata you attach to the test results that get sent to the reporter.
#
# Lazily initializes to a hash, to keep memory down.
#
# NOTE: this data *must* be plain (read: marshal-able) data!
# Hashes! Arrays! Strings!
def metadata
@metadata ||= {}
end
##
# Sets metadata, mainly used for +Result.from+.
attr_writer :metadata
##
# Returns true if metadata exists.
def metadata?
defined? @metadata
end
##
# Runs a single method. Needs to return self.
def run
raise NotImplementedError, "subclass responsibility"
end
##
# Did this run pass?
#
# Note: skipped runs are not considered passing, but they don't
# cause the process to exit non-zero.
def passed?
raise NotImplementedError, "subclass responsibility"
end
##
# Returns a single character string to print based on the result
# of the run. One of ".", "F",
# "E" or "S".
def result_code
raise NotImplementedError, "subclass responsibility"
end
##
# Was this run skipped? See #passed? for more information.
def skipped?
raise NotImplementedError, "subclass responsibility"
end
end
##
# Shared code for anything that can get passed to a Reporter. See
# Minitest::Test & Minitest::Result.
module Reportable
##
# Did this run pass?
#
# Note: skipped runs are not considered passing, but they don't
# cause the process to exit non-zero.
def passed?
not self.failure
end
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
##
# The location identifier of this test. Depends on a method
# existing called class_name.
def location
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
"#{self.class_name}##{self.name}#{loc}"
end
def class_name # :nodoc:
raise NotImplementedError, "subclass responsibility"
end
##
# Returns ".", "F", or "E" based on the result of the run.
def result_code
self.failure and self.failure.result_code or "."
end
##
# Was this run skipped?
def skipped?
self.failure and Skip === self.failure
end
##
# Did this run error?
def error?
self.failures.any? UnexpectedError
end
end
##
# This represents a test result in a clean way that can be
# marshalled over a wire. Tests can do anything they want to the
# test instance and can create conditions that cause Marshal.dump to
# blow up. By using Result.from(a_test) you can be reasonably sure
# that the test result can be marshalled.
class Result < Runnable
include Minitest::Reportable
undef_method :marshal_dump
undef_method :marshal_load
##
# The class name of the test result.
attr_accessor :klass
##
# The location of the test method.
attr_accessor :source_location
##
# Create a new test result from a Runnable instance.
def self.from runnable
o = runnable
r = self.new o.name
r.klass = o.class.name
r.assertions = o.assertions
r.failures = o.failures.dup
r.time = o.time
r.metadata = o.metadata if o.metadata?
r.source_location = o.method(o.name).source_location rescue ["unknown", -1]
r
end
def class_name # :nodoc:
self.klass # for Minitest::Reportable
end
def to_s # :nodoc:
return location if passed? and not skipped?
failures.map { |failure|
"#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
}.join "\n"
end
end
##
# Defines the API for Reporters. Subclass this and override whatever
# you want. Go nuts.
class AbstractReporter
def initialize # :nodoc:
@mutex = Mutex.new
end
##
# Starts reporting on the run.
def start
end
##
# About to start running a test. This allows a reporter to show
# that it is starting or that we are in the middle of a test run.
def prerecord klass, name
end
##
# Output and record the result of the test. Call
# {result#result_code}[rdoc-ref:Runnable#result_code] to get the
# result character string. Stores the result of the run if the run
# did not pass.
def record result
end
##
# Outputs the summary of the run.
def report
end
##
# Did this run pass?
def passed?
true
end
def synchronize &block # :nodoc:
@mutex.synchronize(&block)
end
end
class Reporter < AbstractReporter # :nodoc:
##
# The IO used to report.
attr_accessor :io
##
# Command-line options for this run.
attr_accessor :options
def initialize io = $stdout, options = {} # :nodoc:
super()
self.io = io
self.options = options
end
end
##
# A very simple reporter that prints the "dots" during the run.
#
# This is added to the top-level CompositeReporter at the start of
# the run. If you want to change the output of minitest via a
# plugin, pull this out of the composite and replace it with your
# own.
class ProgressReporter < Reporter
def prerecord klass, name # :nodoc:
return unless options[:verbose]
io.print "%s#%s = " % [klass.name, name]
io.flush
end
def record result # :nodoc:
io.print "%.2f s = " % [result.time] if options[:verbose]
io.print result.result_code
io.puts if options[:verbose]
end
end
##
# A reporter that gathers statistics about a test run. Does not do
# any IO because meant to be used as a parent class for a reporter
# that does.
#
# If you want to create an entirely different type of output (eg,
# CI, HTML, etc), this is the place to start.
#
# Example:
#
# class JenkinsCIReporter < StatisticsReporter
# def report
# super # Needed to calculate some statistics
#
# print " #{new_bt.size}"
error.set_backtrace new_bt
end
self.error = error
end
def backtrace # :nodoc:
self.error.backtrace
end
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
def message # :nodoc:
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
.gsub(BASE_RE, "")
"#{self.error.class}: #{self.error.message}\n #{bt}"
end
def result_label # :nodoc:
"Error"
end
end
##
# Assertion raised on warning when running in -Werror mode.
class UnexpectedWarning < Assertion
def result_label # :nodoc:
"Warning"
end
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 Test 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 maglev?
def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
where = Minitest.filter_backtrace(caller).first
where = where.split(":in ", 2).first # clean up noise
warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
"maglev" == platform
end
##
# Is this running on mri?
def mri? platform = RUBY_DESCRIPTION
platform.start_with? "ruby"
end
##
# Is this running on macOS?
def osx? platform = RUBY_PLATFORM
platform.include? "darwin"
end
##
# Is this running on rubinius?
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
where = Minitest.filter_backtrace(caller).first
where = where.split(":in ", 2).first # clean up noise
warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
"rbx" == platform
end
##
# Is this running on windows?
def windows? platform = RUBY_PLATFORM
/mswin|mingw/.match? platform
end
end
##
# The standard backtrace filter for minitest.
#
# See Minitest.backtrace_filter=.
class BacktraceFilter
MT_RE = %r%lib/minitest|internal:warning% # :nodoc:
##
# The regular expression to use to filter backtraces. Defaults to +MT_RE+.
attr_accessor :regexp
def initialize regexp = MT_RE # :nodoc:
self.regexp = regexp
end
##
# Filter +bt+ to something useful. Returns the whole thing if
# $DEBUG (ruby) or $MT_DEBUG (env).
def filter bt
return ["No backtrace"] unless bt
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
new_bt = bt.take_while { |line| !regexp.match? line.to_s }
new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty?
new_bt = bt.dup if new_bt.empty?
new_bt
end
end
self.backtrace_filter = BacktraceFilter.new
def self.run_one_method klass, method_name # :nodoc:
result = klass.new(method_name).run
raise "#{klass}#run _must_ return a Result" unless Result === result
result
end
# :stopdoc:
if defined? Process::CLOCK_MONOTONIC # :nodoc:
def self.clock_time
Process.clock_gettime Process::CLOCK_MONOTONIC
end
else
def self.clock_time
Time.now
end
end
class Runnable # re-open
def self.inherited klass # :nodoc:
self.runnables << klass
super
end
end
# :startdoc:
end
require "minitest/test"
minitest-5.25.4/test/ 0000755 0000041 0000041 00000000000 14743220663 014461 5 ustar www-data www-data minitest-5.25.4/test/minitest/ 0000755 0000041 0000041 00000000000 14743220663 016315 5 ustar www-data www-data minitest-5.25.4/test/minitest/test_minitest_test_task.rb 0000444 0000041 0000041 00000002450 14743220663 023615 0 ustar www-data www-data require "minitest/autorun"
begin
require "hoe"
rescue LoadError => e
warn e.message
return
end
require "minitest/test_task"
Hoe.load_plugins # make sure Hoe::Test is loaded
class TestHoeTest < Minitest::Test
PATH = "test/minitest/test_minitest_test_task.rb"
def util_cmd_string *prelude_framework
mt_path = %w[lib test .].join File::PATH_SEPARATOR
mt_expected = "-I%s -w -e '%srequire %p' -- "
mt_expected % [mt_path, prelude_framework.join("; "), PATH]
end
def util_exp_cmd
@tester.make_test_cmd.sub(/ -- .+/, " -- ")
end
def test_make_test_cmd_for_minitest
skip "Using TESTOPTS... skipping" if ENV["TESTOPTS"]
require "minitest/test_task"
framework = %(require "minitest/autorun"; )
@tester = Minitest::TestTask.create :test do |t|
t.test_globs = [PATH]
end
assert_equal util_cmd_string(framework), util_exp_cmd
end
def test_make_test_cmd_for_minitest_prelude
skip "Using TESTOPTS... skipping" if ENV["TESTOPTS"]
require "minitest/test_task"
prelude = %(require "other/file")
framework = %(require "minitest/autorun"; )
@tester = Minitest::TestTask.create :test do |t|
t.test_prelude = prelude
t.test_globs = [PATH]
end
assert_equal util_cmd_string(prelude, framework), util_exp_cmd
end
end
minitest-5.25.4/test/minitest/test_minitest_test.rb 0000444 0000041 0000041 00000074242 14743220663 022603 0 ustar www-data www-data require "minitest/metametameta"
e = Encoding.default_external
if e != Encoding::UTF_8 then
warn ""
warn ""
warn "NOTE: External encoding #{e} is not UTF-8. Tests WILL fail."
warn " Run tests with `RUBYOPT=-Eutf-8 rake` to avoid errors."
warn ""
warn ""
end
class Minitest::Runnable
attr_reader :gc_stats # only needed if running w/ minitest-gcstats
def whatever # faked for testing
assert true
end
end
class TestMinitestUnit < MetaMetaMetaTestCase
parallelize_me!
MINITEST_BASE_DIR = "./lib/minitest/mini"
BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:161:in 'each'",
"#{MINITEST_BASE_DIR}/test.rb:158:in 'each'",
"#{MINITEST_BASE_DIR}/test.rb:139:in 'run'",
"#{MINITEST_BASE_DIR}/test.rb:106:in 'run'"]
def test_filter_backtrace
# this is a semi-lame mix of relative paths.
# I cheated by making the autotest parts not have ./
bt = (["lib/autotest.rb:571:in 'add_exception'",
"test/test_autotest.rb:62:in 'test_add_exception'",
"#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] +
BT_MIDDLE +
["#{MINITEST_BASE_DIR}/test.rb:29",
"test/test_autotest.rb:422"])
bt = util_expand_bt bt
ex = ["lib/autotest.rb:571:in 'add_exception'",
"test/test_autotest.rb:62:in 'test_add_exception'"]
ex = util_expand_bt ex
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
fu = Minitest.filter_backtrace bt
assert_equal ex, fu
end
end
def test_filter_backtrace_all_unit
bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] +
BT_MIDDLE +
["#{MINITEST_BASE_DIR}/test.rb:29"])
ex = bt.clone
fu = Minitest.filter_backtrace bt
assert_equal ex, fu
end
def test_filter_backtrace_unit_starts
bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] +
BT_MIDDLE +
["#{MINITEST_BASE_DIR}/mini/test.rb:29",
"-e:1"])
bt = util_expand_bt bt
ex = ["-e:1"]
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
fu = Minitest.filter_backtrace bt
assert_equal ex, fu
end
end
def test_filter_backtrace__empty
with_empty_backtrace_filter do
bt = %w[first second third]
fu = Minitest.filter_backtrace bt.dup
assert_equal bt, fu
end
end
def test_infectious_binary_encoding
@tu = Class.new FakeNamedTest do
def test_this_is_not_ascii_assertion
assert_equal "ЁЁЁ", "ёёё"
end
def test_this_is_non_ascii_failure_message
raise "ЁЁЁ".dup.force_encoding(Encoding::BINARY)
end
end
expected = <<~EOM
FE
Finished in 0.00
1) Failure:
FakeNamedTestXX#test_this_is_not_ascii_assertion [FILE:LINE]:
Expected: "ЁЁЁ"
Actual: "ёёё"
2) Error:
FakeNamedTestXX#test_this_is_non_ascii_failure_message:
RuntimeError: ЁЁЁ
FILE:LINE:in 'test_this_is_non_ascii_failure_message'
2 runs, 1 assertions, 1 failures, 1 errors, 0 skips
EOM
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
assert_report expected
end
end
def test_passed_eh_teardown_good
test_class = Class.new FakeNamedTest do
def teardown; assert true; end
def test_omg; assert true; end
end
test = test_class.new :test_omg
test.run
refute_predicate test, :error?
assert_predicate test, :passed?
refute_predicate test, :skipped?
end
def test_passed_eh_teardown_skipped
test_class = Class.new FakeNamedTest do
def teardown; assert true; end
def test_omg; skip "bork"; end
end
test = test_class.new :test_omg
test.run
refute_predicate test, :error?
refute_predicate test, :passed?
assert_predicate test, :skipped?
end
def test_passed_eh_teardown_flunked
test_class = Class.new FakeNamedTest do
def teardown; flunk; end
def test_omg; assert true; end
end
test = test_class.new :test_omg
test.run
refute_predicate test, :error?
refute_predicate test, :passed?
refute_predicate test, :skipped?
end
def util_expand_bt bt
bt.map { |f| f.start_with?(".") ? File.expand_path(f) : f }
end
end
class TestMinitestUnitInherited < MetaMetaMetaTestCase
def with_overridden_include
Class.class_eval do
def inherited_with_hacks _klass
throw :inherited_hook
end
alias inherited_without_hacks inherited
alias inherited inherited_with_hacks
alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros
end
yield
ensure
Class.class_eval do
alias inherited inherited_without_hacks
undef_method :inherited_with_hacks
undef_method :inherited_without_hacks
end
refute_respond_to Class, :inherited_with_hacks
refute_respond_to Class, :inherited_without_hacks
end
def test_inherited_hook_plays_nice_with_others
with_overridden_include do
assert_throws :inherited_hook do
Class.new FakeNamedTest
end
end
end
end
class TestMinitestRunner < MetaMetaMetaTestCase
# do not parallelize this suite... it just can't handle it.
def test_class_runnables
@assertion_count = 0
tc = Class.new Minitest::Test
assert_equal 1, Minitest::Test.runnables.size
assert_equal [tc], Minitest::Test.runnables
end
def test_run_test
@tu = Class.new FakeNamedTest do
attr_reader :foo
def run
@foo = "hi mom!"
r = super
@foo = "okay"
r
end
def test_something
assert_equal "hi mom!", foo
end
end
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_report expected
end
def test_run_error
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def test_error
raise "unhandled exception"
end
end
expected = <<~EOM
.E
Finished in 0.00
1) Error:
FakeNamedTestXX#test_error:
RuntimeError: unhandled exception
FILE:LINE:in 'test_error'
2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
EOM
assert_report expected
end
def test_run_error_teardown
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def teardown
raise "unhandled exception"
end
end
expected = <<~EOM
E
Finished in 0.00
1) Error:
FakeNamedTestXX#test_something:
RuntimeError: unhandled exception
FILE:LINE:in 'teardown'
1 runs, 1 assertions, 0 failures, 1 errors, 0 skips
EOM
assert_report expected
end
def test_run_failing
setup_basic_tu
expected = <<~EOM
.F
Finished in 0.00
1) Failure:
FakeNamedTestXX#test_failure [FILE:LINE]:
Expected false to be truthy.
2 runs, 2 assertions, 1 failures, 0 errors, 0 skips
EOM
assert_report expected
end
def setup_basic_tu
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def test_failure
assert false
end
end
end
def test_seed # this is set for THIS run, so I'm not testing it's actual value
assert_instance_of Integer, Minitest.seed
end
def test_run_failing_filtered
setup_basic_tu
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_report expected, %w[--name /some|thing/ --seed 42]
end
def assert_filtering filter, name, expected, a = false
args = %W[--#{filter} #{name} --seed 42]
alpha = Class.new FakeNamedTest do
define_method :test_something do
assert a
end
end
Object.const_set :Alpha, alpha
beta = Class.new FakeNamedTest do
define_method :test_something do
assert true
end
end
Object.const_set :Beta, beta
@tus = [alpha, beta]
assert_report expected, args
ensure
Object.send :remove_const, :Alpha
Object.send :remove_const, :Beta
end
def test_run_filtered_including_suite_name
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "name", "/Beta#test_something/", expected
end
def test_run_filtered_including_suite_name_string
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "name", "Beta#test_something", expected
end
def test_run_filtered_string_method_only
expected = <<~EOM
..
Finished in 0.00
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "name", "test_something", expected, :pass
end
def test_run_failing_excluded
setup_basic_tu
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_report expected, %w[--exclude /failure/ --seed 42]
end
def test_run_filtered_excluding_suite_name
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "exclude", "/Alpha#test_something/", expected
end
def test_run_filtered_excluding_suite_name_string
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "exclude", "Alpha#test_something", expected
end
def test_run_filtered_excluding_string_method_only
expected = <<~EOM
Finished in 0.00
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_filtering "exclude", "test_something", expected, :pass
end
def test_run_passing
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
end
expected = <<~EOM
.
Finished in 0.00
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_report expected
end
def test_run_skip
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def test_skip
skip "not yet"
end
end
expected = <<~EOM
.S
Finished in 0.00
2 runs, 1 assertions, 0 failures, 0 errors, 1 skips
You have skipped tests. Run with --verbose for details.
EOM
restore_env do
assert_report expected
end
end
def test_run_skip_verbose
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def test_skip
skip "not yet"
end
end
expected = <<~EOM
FakeNamedTestXX#test_something = 0.00 s = .
FakeNamedTestXX#test_skip = 0.00 s = S
Finished in 0.00
1) Skipped:
FakeNamedTestXX#test_skip [FILE:LINE]:
not yet
2 runs, 1 assertions, 0 failures, 0 errors, 1 skips
EOM
assert_report expected, %w[--seed 42 --verbose]
end
def test_run_skip_show_skips
@tu = Class.new FakeNamedTest do
def test_something
assert true
end
def test_skip
skip "not yet"
end
end
expected = <<~EOM
.S
Finished in 0.00
1) Skipped:
FakeNamedTestXX#test_skip [FILE:LINE]:
not yet
2 runs, 1 assertions, 0 failures, 0 errors, 1 skips
EOM
assert_report expected, %w[--seed 42 --show-skips]
end
def test_run_with_other_runner
@tu = Class.new FakeNamedTest do
def self.run reporter, options = {}
@reporter = reporter
before_my_suite
super
end
def self.name; "wacky!" end
def self.before_my_suite
@reporter.io.puts "Running #{self.name} tests"
@@foo = 1
end
def test_something
assert_equal 1, @@foo
end
def test_something_else
assert_equal 1, @@foo
end
end
expected = <<~EOM
Running wacky! tests
..
Finished in 0.00
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_report expected
end
require "monitor"
class Latch
def initialize count = 1
@count = count
@lock = Monitor.new
@cv = @lock.new_cond
end
def release
@lock.synchronize do
@count -= 1 if @count > 0
@cv.broadcast if @count == 0
end
end
def await
@lock.synchronize { @cv.wait_while { @count > 0 } }
end
end
def test_run_parallel
test_count = 2
test_latch = Latch.new test_count
wait_latch = Latch.new test_count
main_latch = Latch.new
thread = Thread.new {
Thread.current.abort_on_exception = true
# This latch waits until both test latches have been released. Both
# latches can't be released unless done in separate threads because
# `main_latch` keeps the test method from finishing.
test_latch.await
main_latch.release
}
@tu = Class.new FakeNamedTest do
parallelize_me!
test_count.times do |i|
define_method :"test_wait_on_main_thread_#{i}" do
test_latch.release
# This latch blocks until the "main thread" releases it. The main
# thread can't release this latch until both test latches have
# been released. This forces the latches to be released in separate
# threads.
main_latch.await
assert true
end
end
end
expected = <<~EOM
..
Finished in 0.00
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
EOM
skip if Minitest.parallel_executor.size < 2 # locks up test runner if 1 CPU
assert_report expected do |reporter|
reporter.extend Module.new {
define_method :record do |result|
super(result)
wait_latch.release
end
define_method :report do
wait_latch.await
super()
end
}
end
assert thread.join
end
end
class TestMinitestUnitOrder < MetaMetaMetaTestCase
# do not parallelize this suite... it just can't handle it.
def test_before_setup
call_order = []
@tu = Class.new FakeNamedTest do
define_method :setup do
super()
call_order << :setup
end
define_method :before_setup do
call_order << :before_setup
end
def test_omg; assert true; end
end
run_tu_with_fresh_reporter
expected = %i[before_setup setup]
assert_equal expected, call_order
end
def test_after_teardown
call_order = []
@tu = Class.new FakeNamedTest do
define_method :teardown do
super()
call_order << :teardown
end
define_method :after_teardown do
call_order << :after_teardown
end
def test_omg; assert true; end
end
run_tu_with_fresh_reporter
expected = %i[teardown after_teardown]
assert_equal expected, call_order
end
def test_all_teardowns_are_guaranteed_to_run
call_order = []
@tu = Class.new FakeNamedTest do
define_method :after_teardown do
super()
call_order << :after_teardown
raise
end
define_method :teardown do
super()
call_order << :teardown
raise
end
define_method :before_teardown do
super()
call_order << :before_teardown
raise
end
def test_omg; assert true; end
end
run_tu_with_fresh_reporter
expected = %i[before_teardown teardown after_teardown]
assert_equal expected, call_order
end
def test_setup_and_teardown_survive_inheritance
call_order = []
@tu = Class.new FakeNamedTest do
define_method :setup do
call_order << :setup_method
end
define_method :teardown do
call_order << :teardown_method
end
define_method :test_something do
call_order << :test
end
end
run_tu_with_fresh_reporter
@tu = Class.new @tu
run_tu_with_fresh_reporter
# Once for the parent class, once for the child
expected = %i[setup_method test teardown_method] * 2
assert_equal expected, call_order
end
end
class BetterError < RuntimeError # like better_error w/o infecting RuntimeError
def set_backtrace bt
super
@bad_ivar = binding
end
end
class TestMinitestRunnable < Minitest::Test
def setup_marshal klass
tc = klass.new "whatever"
tc.assertions = 42
tc.failures << "a failure"
yield tc if block_given?
def tc.setup
@blah = "blah"
end
tc.setup
@tc = Minitest::Result.from tc
end
def assert_marshal expected_ivars
new_tc = Marshal.load Marshal.dump @tc
ivars = new_tc.instance_variables.map(&:to_s).sort
ivars.delete "@gc_stats" # only needed if running w/ minitest-gcstats
assert_equal expected_ivars, ivars
assert_equal "whatever", new_tc.name
assert_equal 42, new_tc.assertions
assert_equal ["a failure"], new_tc.failures
yield new_tc if block_given?
end
def test_marshal
setup_marshal Minitest::Runnable
assert_marshal %w[@NAME @assertions @failures @klass @source_location @time]
end
def test_spec_marshal
klass = describe("whatever") { it("passes") { assert true } }
rm = klass.runnable_methods.first
# Run the test
@tc = klass.new(rm).run
assert_kind_of Minitest::Result, @tc
# Pass it over the wire
over_the_wire = Marshal.load Marshal.dump @tc
assert_equal @tc.time, over_the_wire.time
assert_equal @tc.name, over_the_wire.name
assert_equal @tc.assertions, over_the_wire.assertions
assert_equal @tc.failures, over_the_wire.failures
assert_equal @tc.klass, over_the_wire.klass
end
def test_spec_marshal_with_exception
klass = describe("whatever") {
it("raises, badly") {
raise Class.new(StandardError), "this is bad!"
}
}
rm = klass.runnable_methods.first
# Run the test
@tc = klass.new(rm).run
assert_kind_of Minitest::Result, @tc
assert_instance_of Minitest::UnexpectedError, @tc.failure
msg = @tc.failure.error.message
assert_includes msg, "Neutered Exception #: boom", msg
# Pass it over the wire
over_the_wire = Marshal.load Marshal.dump @tc
assert_equal @tc.time, over_the_wire.time
assert_equal @tc.name, over_the_wire.name
assert_equal @tc.assertions, over_the_wire.assertions
assert_equal @tc.failures, over_the_wire.failures
assert_equal @tc.klass, over_the_wire.klass
end
end
class TestMinitestTest < TestMinitestRunnable
def test_dup
setup_marshal Minitest::Test do |tc|
tc.time = 3.14
end
assert_marshal %w[@NAME @assertions @failures @klass @source_location @time] do |new_tc|
assert_in_epsilon 3.14, new_tc.time
end
end
end
class TestMinitestUnitTestCase < Minitest::Test
# do not call parallelize_me! - teardown accesses @tc._assertions
# which is not threadsafe. Nearly every method in here is an
# assertion test so it isn't worth splitting it out further.
def setup
super
Minitest::Test.reset
@tc = Minitest::Test.new "fake tc"
@zomg = "zomg ponies!"
@assertion_count = 1
end
def teardown
assert_equal(@assertion_count, @tc.assertions,
"expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}") if @tc.passed?
end
def non_verbose
orig_verbose = $VERBOSE
$VERBOSE = false
yield
ensure
$VERBOSE = orig_verbose
end
def sample_test_case rand
srand rand
Class.new FakeNamedTest do
100.times do |i|
define_method("test_#{i}") { assert true }
end
end.runnable_methods
end
# srand varies with OS
def test_runnable_methods_random
@assertion_count = 0
random_tests_1 = sample_test_case 42
random_tests_2 = sample_test_case 42
random_tests_3 = sample_test_case 1_000
assert_equal random_tests_1, random_tests_2
assert_equal random_tests_1, random_tests_3
end
def test_runnable_methods_sorted
@assertion_count = 0
sample_test_case = Class.new FakeNamedTest do
def self.test_order; :sorted end
def test_test3; assert "does not matter" end
def test_test2; assert "does not matter" end
def test_test1; assert "does not matter" end
end
expected = %w[test_test1 test_test2 test_test3]
assert_equal expected, sample_test_case.runnable_methods
end
def test_i_suck_and_my_tests_are_order_dependent_bang_sets_test_order_alpha
@assertion_count = 0
shitty_test_case = Class.new FakeNamedTest
shitty_test_case.i_suck_and_my_tests_are_order_dependent!
assert_equal :alpha, shitty_test_case.test_order
end
def test_i_suck_and_my_tests_are_order_dependent_bang_does_not_warn
@assertion_count = 0
shitty_test_case = Class.new FakeNamedTest
def shitty_test_case.test_order; :lol end
assert_silent do
shitty_test_case.i_suck_and_my_tests_are_order_dependent!
end
end
def test_autorun_does_not_affect_fork_success_status
@assertion_count = 0
skip "windows doesn't have fork" unless Process.respond_to? :fork
Process.waitpid(fork {})
assert_equal true, $?.success?
end
def test_autorun_does_not_affect_fork_exit_status
@assertion_count = 0
skip "windows doesn't have fork" unless Process.respond_to? :fork
Process.waitpid(fork { exit 42 })
assert_equal 42, $?.exitstatus
end
def test_autorun_optionally_can_affect_fork_exit_status
@assertion_count = 0
skip "windows doesn't have fork" unless Process.respond_to? :fork
Minitest.allow_fork = true
Process.waitpid(fork { exit 42 })
refute_equal 42, $?.exitstatus
ensure
Minitest.allow_fork = false
end
end
class TestMinitestGuard < Minitest::Test
parallelize_me!
def test_mri_eh
assert self.class.mri? "ruby blah"
assert self.mri? "ruby blah"
end
def test_jruby_eh
assert self.class.jruby? "java"
assert self.jruby? "java"
end
def test_rubinius_eh
assert_deprecation do
assert self.class.rubinius? "rbx"
end
assert_deprecation do
assert self.rubinius? "rbx"
end
end
def test_maglev_eh
assert_deprecation do
assert self.class.maglev? "maglev"
end
assert_deprecation do
assert self.maglev? "maglev"
end
end
def test_osx_eh
assert self.class.osx? "darwin"
assert self.osx? "darwin"
end
def test_windows_eh
assert self.class.windows? "mswin"
assert self.windows? "mswin"
end
end
class TestMinitestUnitRecording < MetaMetaMetaTestCase
# do not parallelize this suite... it just can't handle it.
def assert_run_record *expected, &block
@tu = Class.new FakeNamedTest, &block
run_tu_with_fresh_reporter
recorded = first_reporter.results.map(&:failures).flatten.map { |f| f.error.class }
assert_equal expected, recorded
end
def test_run_with_bogus_reporter
# https://github.com/seattlerb/minitest/issues/659
# TODO: remove test for minitest 6
@tu = Class.new FakeNamedTest do
def test_method
assert true
end
end
bogus_reporter = Class.new do # doesn't subclass AbstractReporter
def start; @success = false; end
# def prerecord klass, name; end # doesn't define full API
def record _result; @success = true; end
def report; end
def passed?; end
def results; end
def success?; @success; end
end.new
self.reporter = Minitest::CompositeReporter.new
reporter << bogus_reporter
Minitest::Runnable.runnables.delete @tu
@tu.run reporter, {}
assert_predicate bogus_reporter, :success?
end
def test_record_passing
assert_run_record do
def test_method
assert true
end
end
end
def test_record_failing
assert_run_record Minitest::Assertion do
def test_method
assert false
end
end
end
def test_record_error
assert_run_record RuntimeError do
def test_method
raise "unhandled exception"
end
end
end
def test_record_error_teardown
assert_run_record RuntimeError do
def test_method
assert true
end
def teardown
raise "unhandled exception"
end
end
end
def test_record_error_in_test_and_teardown
assert_run_record AnError, RuntimeError do
def test_method
raise AnError
end
def teardown
raise "unhandled exception"
end
end
end
def test_to_s_error_in_test_and_teardown
@tu = Class.new FakeNamedTest do
def test_method
raise AnError
end
def teardown
raise "unhandled exception"
end
end
run_tu_with_fresh_reporter
exp = <<~EOM
Error:
FakeNamedTestXX#test_method:
AnError: AnError
FILE:LINE:in 'test_method'
Error:
FakeNamedTestXX#test_method:
RuntimeError: unhandled exception
FILE:LINE:in 'teardown'
EOM
assert_equal exp.strip, normalize_output(first_reporter.results.first.to_s).strip
end
def test_record_skip
assert_run_record Minitest::Skip do
def test_method
skip "not yet"
end
end
end
end
class TestUnexpectedError < Minitest::Test
def assert_compress exp, input
e = Minitest::UnexpectedError.new RuntimeError.new
exp = exp.lines.map(&:chomp) if String === exp
act = e.compress input
assert_equal exp, act
end
ACT1 = %w[ a b c b c b c b c d ]
def test_normal
assert_compress <<~EXP, %w[ a b c b c b c b c d ]
a
+->> 4 cycles of 2 lines:
| b
| c
+-<<
d
EXP
end
def test_normal2
assert_compress <<~EXP, %w[ a b c b c b c b c ]
a
+->> 4 cycles of 2 lines:
| b
| c
+-<<
EXP
end
def test_longer_c_than_b
# the extra c in the front makes the overall length longer sorting it first
assert_compress <<~EXP, %w[ c a b c b c b c b c b d ]
c
a
b
+->> 4 cycles of 2 lines:
| c
| b
+-<<
d
EXP
end
def test_1_line_cycles
assert_compress <<~EXP, %w[ c a b c b c b c b c b b b d ]
c
a
+->> 4 cycles of 2 lines:
| b
| c
+-<<
+->> 3 cycles of 1 lines:
| b
+-<<
d
EXP
end
def test_sanity3
pre = ("aa".."am").to_a
mid = ("a".."z").to_a * 67
post = ("aa".."am").to_a
ary = pre + mid + post
exp = pre +
[" +->> 67 cycles of 26 lines:"] +
("a".."z").map { |s| " | #{s}" } +
[" +-<<"] +
post
assert_compress exp, ary
end
def test_absurd_patterns
assert_compress <<~EXP, %w[ a b c b c a b c b c a b c ]
+->> 2 cycles of 5 lines:
| a
| +->> 2 cycles of 2 lines:
| | b
| | c
| +-<<
+-<<
a
b
c
EXP
end
end
minitest-5.25.4/test/minitest/test_minitest_spec.rb 0000444 0000041 0000041 00000073100 14743220663 022546 0 ustar www-data www-data require "minitest/metametameta"
require "stringio"
class MiniSpecA < Minitest::Spec; end
class MiniSpecB < Minitest::Test; extend Minitest::Spec::DSL; end
class MiniSpecC < MiniSpecB; end
class NamedExampleA < MiniSpecA; end
class NamedExampleB < MiniSpecB; end
class NamedExampleC < MiniSpecC; end
class ExampleA; end
class ExampleB < ExampleA; end
describe Minitest::Spec do
# do not parallelize this suite... it just can"t handle it.
def assert_triggered expected = "blah", klass = Minitest::Assertion
@assertion_count += 1
e = assert_raises klass do
yield
end
msg = e.message.sub(/(---Backtrace---).*/m, '\1')
msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform
msg.gsub!(/:0x[Xa-fA-F0-9]{4,}[ @].+?>/, ":0xXXXXXX@PATH>")
return unless expected
@assertion_count += 1
case expected
when String then
assert_equal expected, msg
when Regexp then
@assertion_count += 1
assert_match expected, msg
else
flunk "Unknown: #{expected.inspect}"
end
end
def assert_success spec
assert_equal true, spec
end
before do
@assertion_count = 4
end
after do
_(self.assertions).must_equal @assertion_count if passed? and not skipped?
end
it "needs to be able to catch a Minitest::Assertion exception" do
@assertion_count = 1
assert_triggered "Expected 1 to not be equal to 1." do
_(1).wont_equal 1
end
end
it "needs to check for file existence" do
@assertion_count = 3
assert_success _(__FILE__).path_must_exist
assert_triggered "Expected path 'blah' to exist." do
_("blah").path_must_exist
end
end
it "needs to check for file non-existence" do
@assertion_count = 3
assert_success _("blah").path_wont_exist
assert_triggered "Expected path '#{__FILE__}' to not exist." do
_(__FILE__).path_wont_exist
end
end
it "needs to be sensible about must_include order" do
@assertion_count += 3 # must_include is 2 assertions
assert_success _([1, 2, 3]).must_include(2)
assert_triggered "Expected [1, 2, 3] to include 5." do
_([1, 2, 3]).must_include 5
end
assert_triggered "msg.\nExpected [1, 2, 3] to include 5." do
_([1, 2, 3]).must_include 5, "msg"
end
end
it "needs to be sensible about wont_include order" do
@assertion_count += 3 # wont_include is 2 assertions
assert_success _([1, 2, 3]).wont_include(5)
assert_triggered "Expected [1, 2, 3] to not include 2." do
_([1, 2, 3]).wont_include 2
end
assert_triggered "msg.\nExpected [1, 2, 3] to not include 2." do
_([1, 2, 3]).wont_include 2, "msg"
end
end
it "needs to catch an expected exception" do
@assertion_count = 2
expect { raise "blah" }.must_raise RuntimeError
expect { raise Minitest::Assertion }.must_raise Minitest::Assertion
end
it "needs to catch an unexpected exception" do
@assertion_count -= 2 # no positive
msg = <<-EOM.gsub(/^ {6}/, "").chomp
[RuntimeError] exception expected, not
Class:
Message: <"woot">
---Backtrace---
EOM
assert_triggered msg do
expect { raise StandardError, "woot" }.must_raise RuntimeError
end
assert_triggered "msg.\n#{msg}" do
expect { raise StandardError, "woot" }.must_raise RuntimeError, "msg"
end
end
def good_pattern
capture_io do # 3.0 is noisy
eval "[1,2,3] => [Integer, Integer, Integer]" # eval to escape parser for ruby<3
end
end
def bad_pattern
capture_io do # 3.0 is noisy
eval "[1,2,3] => [Integer, Integer]" # eval to escape parser for ruby<3
end
end
it "needs to pattern match" do
@assertion_count = 1
if RUBY_VERSION > "3" then
expect { good_pattern }.must_pattern_match
else
assert_raises NotImplementedError do
expect {}.must_pattern_match
end
end
end
it "needs to error on bad pattern match" do
skip unless RUBY_VERSION > "3"
@assertion_count = 1
exp = if RUBY_VERSION.start_with? "3.0"
"[1, 2, 3]" # terrible error message!
else
/length mismatch/
end
assert_triggered exp do
expect { bad_pattern }.must_pattern_match
end
end
it "needs to ensure silence" do
@assertion_count -= 1 # no msg
@assertion_count += 2 # assert_output is 2 assertions
assert_success expect {}.must_be_silent
assert_triggered "In stdout.\nExpected: \"\"\n Actual: \"xxx\"" do
expect { print "xxx" }.must_be_silent
end
end
it "needs to have all methods named well" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
@assertion_count = 2
methods = Minitest::Expectations.public_instance_methods.grep(/must|wont/)
methods.map!(&:to_s) if Symbol === methods.first
musts, wonts = methods.sort.partition { |m| m.include? "must" }
expected_musts = %w[must_be
must_be_close_to
must_be_empty
must_be_instance_of
must_be_kind_of
must_be_nil
must_be_same_as
must_be_silent
must_be_within_delta
must_be_within_epsilon
must_equal
must_include
must_match
must_output
must_pattern_match
must_raise
must_respond_to
must_throw
must_verify
path_must_exist]
bad = %w[not raise throw send output be_silent verify]
expected_wonts = expected_musts.map { |m| m.sub("must", "wont") }.sort
expected_wonts.reject! { |m| m =~ /wont_#{Regexp.union(*bad)}/ }
_(musts).must_equal expected_musts
_(wonts).must_equal expected_wonts
end
it "needs to raise if an expected exception is not raised" do
@assertion_count -= 2 # no positive test
assert_triggered "RuntimeError expected but nothing was raised." do
expect { 42 }.must_raise RuntimeError
end
assert_triggered "msg.\nRuntimeError expected but nothing was raised." do
expect { 42 }.must_raise RuntimeError, "msg"
end
end
it "needs to verify binary messages" do
assert_success _(42).wont_be(:<, 24)
assert_triggered "Expected 24 to not be < 42." do
_(24).wont_be :<, 42
end
assert_triggered "msg.\nExpected 24 to not be < 42." do
_(24).wont_be :<, 42, "msg"
end
end
it "needs to verify emptyness" do
@assertion_count += 3 # empty is 2 assertions
assert_success _([]).must_be_empty
assert_triggered "Expected [42] to be empty." do
_([42]).must_be_empty
end
assert_triggered "msg.\nExpected [42] to be empty." do
_([42]).must_be_empty "msg"
end
end
it "needs to verify equality" do
@assertion_count += 1
assert_success _(6 * 7).must_equal(42)
assert_triggered "Expected: 42\n Actual: 54" do
_(6 * 9).must_equal 42
end
assert_triggered "msg.\nExpected: 42\n Actual: 54" do
_(6 * 9).must_equal 42, "msg"
end
assert_triggered(/^-42\n\+#\n/) do
_(proc { 42 }).must_equal 42 # proc isn't called, so expectation fails
end
end
it "needs to warn on equality with nil" do
@assertion_count = 3
@assertion_count += 2 unless error_on_warn? # 2 extra assertions
exp = /DEPRECATED: Use assert_nil if expecting nil from .* This will fail in Minitest 6./
assert_deprecation exp do
assert_success _(nil).must_equal(nil)
end
end
it "needs to verify floats outside a delta" do
@assertion_count += 1 # extra test
assert_success _(24).wont_be_close_to(42)
assert_triggered "Expected |42 - 42.0| (0.0) to not be <= 0.001." do
_(6 * 7.0).wont_be_close_to 42
end
x = "1.0e-05"
assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
_(6 * 7.0).wont_be_close_to 42, 0.00001
end
assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
_(6 * 7.0).wont_be_close_to 42, 0.00001, "msg"
end
end
it "needs to verify floats outside an epsilon" do
@assertion_count += 1 # extra test
assert_success _(24).wont_be_within_epsilon(42)
x = "0.042"
assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
_(6 * 7.0).wont_be_within_epsilon 42
end
x = "0.00042"
assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
_(6 * 7.0).wont_be_within_epsilon 42, 0.00001
end
assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
_(6 * 7.0).wont_be_within_epsilon 42, 0.00001, "msg"
end
end
it "needs to verify floats within a delta" do
@assertion_count += 1 # extra test
assert_success _(6.0 * 7).must_be_close_to(42.0)
assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.001." do
_(1.0 / 100).must_be_close_to 0.0
end
x = "1.0e-06"
assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
_(1.0 / 1000).must_be_close_to 0.0, 0.000001
end
assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= #{x}." do
_(1.0 / 1000).must_be_close_to 0.0, 0.000001, "msg"
end
end
it "needs to verify floats within an epsilon" do
@assertion_count += 1 # extra test
assert_success _(6.0 * 7).must_be_within_epsilon(42.0)
assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.0." do
_(1.0 / 100).must_be_within_epsilon 0.0
end
assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= 0.0." do
_(1.0 / 1000).must_be_within_epsilon 0.0, 0.000001
end
assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= 0.0." do
_(1.0 / 1000).must_be_within_epsilon 0.0, 0.000001, "msg"
end
end
it "needs to verify identity" do
assert_success _(1).must_be_same_as(1)
assert_triggered "Expected 1 (oid=N) to be the same as 2 (oid=N)." do
_(1).must_be_same_as 2
end
assert_triggered "msg.\nExpected 1 (oid=N) to be the same as 2 (oid=N)." do
_(1).must_be_same_as 2, "msg"
end
end
it "needs to verify inequality" do
@assertion_count += 2
assert_success _(42).wont_equal(6 * 9)
assert_success _(proc {}).wont_equal(42)
assert_triggered "Expected 1 to not be equal to 1." do
_(1).wont_equal 1
end
assert_triggered "msg.\nExpected 1 to not be equal to 1." do
_(1).wont_equal 1, "msg"
end
end
it "needs to verify instances of a class" do
assert_success _(42).wont_be_instance_of(String)
assert_triggered "Expected 42 to not be a kind of Integer." do
_(42).wont_be_kind_of Integer
end
assert_triggered "msg.\nExpected 42 to not be an instance of Integer." do
_(42).wont_be_instance_of Integer, "msg"
end
end
it "needs to verify kinds of a class" do
@assertion_count += 2
assert_success _(42).wont_be_kind_of(String)
assert_success _(proc {}).wont_be_kind_of(String)
assert_triggered "Expected 42 to not be a kind of Integer." do
_(42).wont_be_kind_of Integer
end
assert_triggered "msg.\nExpected 42 to not be a kind of Integer." do
_(42).wont_be_kind_of Integer, "msg"
end
end
it "needs to verify kinds of objects" do
@assertion_count += 3 # extra test
assert_success _(6 * 7).must_be_kind_of(Integer)
assert_success _(6 * 7).must_be_kind_of(Numeric)
assert_triggered "Expected 42 to be a kind of String, not Integer." do
_(6 * 7).must_be_kind_of String
end
assert_triggered "msg.\nExpected 42 to be a kind of String, not Integer." do
_(6 * 7).must_be_kind_of String, "msg"
end
exp = "Expected # to be a kind of String, not Proc."
assert_triggered exp do
_(proc {}).must_be_kind_of String
end
end
it "needs to verify mismatch" do
@assertion_count += 3 # match is 2
assert_success _("blah").wont_match(/\d+/)
assert_triggered "Expected /\\w+/ to not match \"blah\"." do
_("blah").wont_match(/\w+/)
end
assert_triggered "msg.\nExpected /\\w+/ to not match \"blah\"." do
_("blah").wont_match(/\w+/, "msg")
end
end
it "needs to verify nil" do
assert_success _(nil).must_be_nil
assert_triggered "Expected 42 to be nil." do
_(42).must_be_nil
end
assert_triggered "msg.\nExpected 42 to be nil." do
_(42).must_be_nil "msg"
end
end
it "needs to verify non-emptyness" do
@assertion_count += 3 # empty is 2 assertions
assert_success _(["some item"]).wont_be_empty
assert_triggered "Expected [] to not be empty." do
_([]).wont_be_empty
end
assert_triggered "msg.\nExpected [] to not be empty." do
_([]).wont_be_empty "msg"
end
end
it "needs to verify non-identity" do
assert_success _(1).wont_be_same_as(2)
assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do
_(1).wont_be_same_as 1
end
assert_triggered "msg.\nExpected 1 (oid=N) to not be the same as 1 (oid=N)." do
_(1).wont_be_same_as 1, "msg"
end
end
it "needs to verify non-nil" do
assert_success _(42).wont_be_nil
assert_triggered "Expected nil to not be nil." do
_(nil).wont_be_nil
end
assert_triggered "msg.\nExpected nil to not be nil." do
_(nil).wont_be_nil "msg"
end
end
it "needs to verify objects not responding to a message" do
assert_success _("").wont_respond_to(:woot!)
assert_triggered "Expected \"\" to not respond to to_s." do
_("").wont_respond_to :to_s
end
assert_triggered "msg.\nExpected \"\" to not respond to to_s." do
_("").wont_respond_to :to_s, "msg"
end
end
it "needs to verify output in stderr" do
@assertion_count -= 1 # no msg
assert_success expect { $stderr.print "blah" }.must_output(nil, "blah")
assert_triggered "In stderr.\nExpected: \"blah\"\n Actual: \"xxx\"" do
expect { $stderr.print "xxx" }.must_output(nil, "blah")
end
end
it "needs to verify output in stdout" do
@assertion_count -= 1 # no msg
assert_success expect { print "blah" }.must_output("blah")
assert_triggered "In stdout.\nExpected: \"blah\"\n Actual: \"xxx\"" do
expect { print "xxx" }.must_output("blah")
end
end
it "needs to verify regexp matches" do
@assertion_count += 3 # must_match is 2 assertions
assert_kind_of MatchData, _("blah").must_match(/\w+/)
assert_triggered "Expected /\\d+/ to match \"blah\"." do
_("blah").must_match(/\d+/)
end
assert_triggered "msg.\nExpected /\\d+/ to match \"blah\"." do
_("blah").must_match(/\d+/, "msg")
end
end
describe "expect" do
before do
@assertion_count -= 3
end
it "can use expect" do
_(1 + 1).must_equal 2
end
it "can use expect with a lambda" do
_ { raise "blah" }.must_raise RuntimeError
end
it "can use expect in a thread" do
Thread.new { _(1 + 1).must_equal 2 }.join
end
it "can NOT use must_equal in a thread. It must use expect in a thread" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
assert_raises RuntimeError, Minitest::UnexpectedWarning do
capture_io do
Thread.new { (1 + 1).must_equal 2 }.join
end
end
end
it "fails gracefully when expectation used outside of `it`" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
@assertion_count += 2 # assert_match is compound
e = assert_raises RuntimeError, Minitest::UnexpectedWarning do
capture_io do
Thread.new { # forces ctx to be nil
describe "woot" do
(1 + 1).must_equal 2
end
}.join
end
end
exp = "Calling #must_equal outside of test."
exp = "DEPRECATED: global use of must_equal from" if error_on_warn?
assert_match exp, e.message
end
it "deprecates expectation used without _" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
@assertion_count += 1
@assertion_count += 2 unless error_on_warn?
exp = /DEPRECATED: global use of must_equal from/
assert_deprecation exp do
(1 + 1).must_equal 2
end
end
# https://github.com/seattlerb/minitest/issues/837
# https://github.com/rails/rails/pull/39304
it "deprecates expectation used without _ with empty backtrace_filter" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
@assertion_count += 1
@assertion_count += 2 unless error_on_warn?
exp = /DEPRECATED: global use of must_equal from/
with_empty_backtrace_filter do
assert_deprecation exp do
(1 + 1).must_equal 2
end
end
end
end
it "needs to verify throw" do
@assertion_count += 4 # 2 extra tests
assert_nil expect { throw :blah }.must_throw(:blah)
assert_equal 42, expect { throw :blah, 42 }.must_throw(:blah)
assert_triggered "Expected :blah to have been thrown." do
expect {}.must_throw :blah
end
assert_triggered "Expected :blah to have been thrown, not :xxx." do
expect { throw :xxx }.must_throw :blah
end
assert_triggered "msg.\nExpected :blah to have been thrown." do
expect {}.must_throw :blah, "msg"
end
assert_triggered "msg.\nExpected :blah to have been thrown, not :xxx." do
expect { throw :xxx }.must_throw :blah, "msg"
end
end
it "needs to verify types of objects" do
assert_success _(6 * 7).must_be_instance_of(Integer)
exp = "Expected 42 to be an instance of String, not Integer."
assert_triggered exp do
_(6 * 7).must_be_instance_of String
end
assert_triggered "msg.\n#{exp}" do
_(6 * 7).must_be_instance_of String, "msg"
end
end
it "needs to verify using any (negative) predicate" do
@assertion_count -= 1 # doesn"t take a message
assert_success _("blah").wont_be(:empty?)
assert_triggered "Expected \"\" to not be empty?." do
_("").wont_be :empty?
end
end
it "needs to verify using any binary operator" do
@assertion_count -= 1 # no msg
assert_success _(41).must_be(:<, 42)
assert_triggered "Expected 42 to be < 41." do
_(42).must_be :<, 41
end
end
it "needs to verify using any predicate" do
@assertion_count -= 1 # no msg
assert_success _("").must_be(:empty?)
assert_triggered "Expected \"blah\" to be empty?." do
_("blah").must_be :empty?
end
end
it "needs to verify using respond_to" do
assert_success _(42).must_respond_to(:+)
assert_triggered "Expected 42 (Integer) to respond to #clear." do
_(42).must_respond_to :clear
end
assert_triggered "msg.\nExpected 42 (Integer) to respond to #clear." do
_(42).must_respond_to :clear, "msg"
end
end
end
describe Minitest::Spec, :let do
i_suck_and_my_tests_are_order_dependent!
def _count
$let_count ||= 0
end
let :count do
$let_count += 1
$let_count
end
it "is evaluated once per example" do
_(_count).must_equal 0
_(count).must_equal 1
_(count).must_equal 1
_(_count).must_equal 1
end
it "is REALLY evaluated once per example" do
_(_count).must_equal 1
_(count).must_equal 2
_(count).must_equal 2
_(_count).must_equal 2
end
it 'raises an error if the name begins with "test"' do
expect { self.class.let(:test_value) { true } }.must_raise ArgumentError
end
it "raises an error if the name shadows a normal instance method" do
expect { self.class.let(:message) { true } }.must_raise ArgumentError
end
it "doesn't raise an error if it is just another let" do
v = proc do
describe :outer do
let :bar
describe :inner do
let :bar
end
end
:good
end.call
_(v).must_equal :good
end
it "procs come after dont_flip" do
p = proc {}
assert_respond_to p, :call
_(p).must_respond_to :call
end
end
describe Minitest::Spec, :subject do
attr_reader :subject_evaluation_count
subject do
@subject_evaluation_count ||= 0
@subject_evaluation_count += 1
@subject_evaluation_count
end
it "is evaluated once per example" do
_(subject).must_equal 1
_(subject).must_equal 1
_(subject_evaluation_count).must_equal 1
end
end
class TestMetaStatic < Minitest::Test
def assert_method_count expected, klass
assert_equal expected, klass.public_instance_methods.grep(/^test_/).count
end
def test_children
Minitest::Spec.children.clear # prevents parallel run
y = z = nil
x = describe "top-level thingy" do
y = describe "first thingy" do end
it "top-level-it" do end
z = describe "second thingy" do end
end
assert_equal [x], Minitest::Spec.children
assert_equal [y, z], x.children
assert_equal [], y.children
assert_equal [], z.children
end
def test_it_wont_remove_existing_child_test_methods
Minitest::Spec.children.clear # prevents parallel run
inner = nil
outer = describe "outer" do
inner = describe "inner" do
it do
assert true
end
end
it do
assert true
end
end
assert_method_count 1, outer
assert_method_count 1, inner
end
def test_it_wont_add_test_methods_to_children
Minitest::Spec.children.clear # prevents parallel run
inner = nil
outer = describe "outer" do
inner = describe "inner" do end
it do
assert true
end
end
assert_method_count 1, outer
assert_method_count 0, inner
end
end
class TestMeta < MetaMetaMetaTestCase
# do not call parallelize_me! here because specs use register_spec_type globally
def assert_defined_methods expected, klass
assert_equal expected, klass.instance_methods(false).sort.map(&:to_s)
end
def util_structure
y = z = nil
before_list = []
after_list = []
x = describe "top-level thingy" do
before { before_list << 1 }
after { after_list << 1 }
it "top-level-it" do end
y = describe "inner thingy" do
before { before_list << 2 }
after { after_list << 2 }
it "inner-it" do end
z = describe "very inner thingy" do
before { before_list << 3 }
after { after_list << 3 }
it "inner-it" do end
it { } # ignore me
specify { } # anonymous it
end
end
end
return x, y, z, before_list, after_list
end
def test_register_spec_type
original_types = Minitest::Spec::TYPES.dup
assert_includes Minitest::Spec::TYPES, [//, Minitest::Spec]
Minitest::Spec.register_spec_type(/woot/, TestMeta)
p = lambda do |_| true end
Minitest::Spec.register_spec_type TestMeta, &p
keys = Minitest::Spec::TYPES.map(&:first)
assert_includes keys, /woot/
assert_includes keys, p
ensure
Minitest::Spec::TYPES.replace original_types
end
def test_spec_type
original_types = Minitest::Spec::TYPES.dup
Minitest::Spec.register_spec_type(/A$/, MiniSpecA)
Minitest::Spec.register_spec_type MiniSpecB do |desc|
desc.superclass == ExampleA
end
Minitest::Spec.register_spec_type MiniSpecC do |_desc, *addl|
addl.include? :woot
end
assert_equal MiniSpecA, Minitest::Spec.spec_type(ExampleA)
assert_equal MiniSpecB, Minitest::Spec.spec_type(ExampleB)
assert_equal MiniSpecC, Minitest::Spec.spec_type(ExampleB, :woot)
ensure
Minitest::Spec::TYPES.replace original_types
end
def test_bug_dsl_expectations
spec_class = Class.new MiniSpecB do
it "should work" do
_(0).must_equal 0
end
end
test_name = spec_class.instance_methods.sort.grep(/test_/).first
spec = spec_class.new test_name
result = spec.run
assert spec.passed?
assert result.passed?
assert_equal 1, result.assertions
end
def test_name
spec_a = describe ExampleA do; end
spec_b = describe ExampleB, :random_method do; end
spec_c = describe ExampleB, :random_method, :addl_context do; end
assert_equal "ExampleA", spec_a.name
assert_equal "ExampleB::random_method", spec_b.name
assert_equal "ExampleB::random_method::addl_context", spec_c.name
end
def test_name2
assert_equal "NamedExampleA", NamedExampleA.name
assert_equal "NamedExampleB", NamedExampleB.name
assert_equal "NamedExampleC", NamedExampleC.name
spec_a = describe ExampleA do; end
spec_b = describe ExampleB, :random_method do; end
assert_equal "ExampleA", spec_a.name
assert_equal "ExampleB::random_method", spec_b.name
end
def test_name_inside_class
spec_a = nil
spec_b = nil
inside_class_example = Class.new Minitest::Spec
Object.const_set :InsideClassExample, inside_class_example
inside_class_example.class_eval do
spec_a = describe "a" do
spec_b = describe "b" do; end
end
end
assert_equal "InsideClassExample::a", spec_a.name
assert_equal "InsideClassExample::a::b", spec_b.name
ensure
Object.send :remove_const, :InsideClassExample
end
def test_structure
x, y, z, * = util_structure
assert_equal "top-level thingy", x.to_s
assert_equal "top-level thingy::inner thingy", y.to_s
assert_equal "top-level thingy::inner thingy::very inner thingy", z.to_s
assert_equal "top-level thingy", x.desc
assert_equal "inner thingy", y.desc
assert_equal "very inner thingy", z.desc
top_methods = %w[setup teardown test_0001_top-level-it]
inner_methods1 = %w[setup teardown test_0001_inner-it]
inner_methods2 = inner_methods1 +
%w[test_0002_anonymous test_0003_anonymous]
assert_defined_methods top_methods, x
assert_defined_methods inner_methods1, y
assert_defined_methods inner_methods2, z
end
def test_structure_postfix_it
z = nil
y = describe "outer" do
# NOT here, below the inner-describe!
# it "inner-it" do end
z = describe "inner" do
it "inner-it" do end
end
# defined AFTER inner describe means we'll try to wipe out the inner-it
it "inner-it" do end
end
assert_defined_methods %w[test_0001_inner-it], y
assert_defined_methods %w[test_0001_inner-it], z
end
def test_setup_teardown_behavior
_, _, z, before_list, after_list = util_structure
@tu = z
run_tu_with_fresh_reporter
size = z.runnable_methods.size
assert_equal [1, 2, 3] * size, before_list
assert_equal [3, 2, 1] * size, after_list
end
def test_describe_first_structure
x1 = x2 = y = z = nil
x = describe "top-level thingy" do
y = describe "first thingy" do end
x1 = it "top level it" do end
x2 = it "не латинские &いった α, β, γ, δ, ε hello!!! world" do end
z = describe "second thingy" do end
end
test_methods = [
"test_0001_top level it",
"test_0002_не латинские &いった α, β, γ, δ, ε hello!!! world",
].sort
assert_equal test_methods, [x1, x2]
assert_defined_methods test_methods, x
assert_defined_methods [], y
assert_defined_methods [], z
end
def test_structure_subclasses
z = nil
x = Class.new Minitest::Spec do
def xyz; end
end
y = Class.new x do
z = describe("inner") { }
end
assert_respond_to x.new(nil), "xyz"
assert_respond_to y.new(nil), "xyz"
assert_respond_to z.new(nil), "xyz"
end
end
class TestSpecInTestCase < MetaMetaMetaTestCase
def setup
super
Thread.current[:current_spec] = self
@tc = self
@assertion_count = 2
end
def assert_triggered expected, klass = Minitest::Assertion
@assertion_count += 1
e = assert_raises klass do
yield
end
msg = e.message.sub(/(---Backtrace---).*/m, "\1")
msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
assert_equal expected, msg
end
def teardown
msg = "expected #{@assertion_count} assertions, not #{@tc.assertions}"
assert_equal @assertion_count, @tc.assertions, msg
end
def test_expectation
@tc.assert_equal true, _(1).must_equal(1)
end
def test_expectation_triggered
assert_triggered "Expected: 2\n Actual: 1" do
_(1).must_equal 2
end
end
include Minitest::Spec::DSL::InstanceMethods
def test_expectation_with_a_message
assert_triggered "woot.\nExpected: 2\n Actual: 1" do
_(1).must_equal 2, "woot"
end
end
end
class ValueMonadTest < Minitest::Test
attr_accessor :struct
def setup
@struct = { :_ => "a", :value => "b", :expect => "c" }
def @struct.method_missing k # think openstruct
self[k]
end
end
def test_value_monad_method
assert_equal "a", struct._
end
def test_value_monad_value_alias
assert_equal "b", struct.value
end
def test_value_monad_expect_alias
assert_equal "c", struct.expect
end
end
describe Minitest::Spec, :infect_an_assertion do
class << self
attr_accessor :infect_mock
end
def assert_infects exp, act, msg = nil, foo: nil, bar: nil
self.class.infect_mock.assert_infects exp, act, msg, foo: foo, bar: bar
end
infect_an_assertion :assert_infects, :must_infect
infect_an_assertion :assert_infects, :must_infect_without_flipping, :dont_flip
it "infects assertions with kwargs" do
mock = Minitest::Mock.new
mock.expect :assert_infects, true, [:exp, :act, nil], foo: :foo, bar: :bar
self.class.infect_mock = mock
_(:act).must_infect :exp, foo: :foo, bar: :bar
assert_mock mock
end
it "infects assertions with kwargs (dont_flip)" do
mock = Minitest::Mock.new
mock.expect :assert_infects, true, [:act, :exp, nil], foo: :foo, bar: :bar
self.class.infect_mock = mock
_(:act).must_infect_without_flipping :exp, foo: :foo, bar: :bar
assert_mock mock
end
end
minitest-5.25.4/test/minitest/test_minitest_reporter.rb 0000444 0000041 0000041 00000021425 14743220663 023461 0 ustar www-data www-data require "minitest/autorun"
require "minitest/metametameta"
require "forwardable"
class FakeTest < Minitest::Test
def woot
assert true
end
end
class TestMinitestReporter < MetaMetaMetaTestCase
attr_accessor :r, :io
def new_composite_reporter
reporter = Minitest::CompositeReporter.new
reporter << Minitest::SummaryReporter.new(self.io)
reporter << Minitest::ProgressReporter.new(self.io)
# eg reporter.results -> reporters.first.results
reporter.extend Forwardable
reporter.delegate :first => :reporters
reporter.delegate %i[results count assertions options to_s] => :first
reporter
end
def setup
super
self.io = StringIO.new(+"")
self.r = new_composite_reporter
end
def error_test
unless defined? @et then
@et = FakeTest.new :woot
@et.failures << Minitest::UnexpectedError.new(begin
raise "no"
rescue => e
e
end)
@et = Minitest::Result.from @et
end
@et
end
def system_stack_error_test
unless defined? @sse then
ex = SystemStackError.new
pre = ("a".."c").to_a
mid = ("aa".."ad").to_a * 67
post = ("d".."f").to_a
ary = pre + mid + post
ex.set_backtrace ary
@sse = FakeTest.new :woot
@sse.failures << Minitest::UnexpectedError.new(ex)
@sse = Minitest::Result.from @sse
end
@sse
end
def fail_test
unless defined? @ft then
@ft = FakeTest.new :woot
@ft.failures << begin
raise Minitest::Assertion, "boo"
rescue Minitest::Assertion => e
e
end
@ft = Minitest::Result.from @ft
end
@ft
end
def passing_test
@pt ||= Minitest::Result.from FakeTest.new(:woot)
end
def passing_test_with_metadata
test = FakeTest.new :woot
test.metadata[:meta] = :data
@pt ||= Minitest::Result.from test
end
def skip_test
unless defined? @st then
@st = FakeTest.new :woot
@st.failures << begin
raise Minitest::Skip
rescue Minitest::Assertion => e
e
end
@st = Minitest::Result.from @st
end
@st
end
def test_to_s
r.record passing_test
r.record fail_test
assert_match "woot", r.to_s
end
def test_options_skip_F
r.options[:skip] = "F"
r.record passing_test
r.record fail_test
refute_match "woot", r.to_s
end
def test_options_skip_E
r.options[:skip] = "E"
r.record passing_test
r.record error_test
refute_match "RuntimeError: no", r.to_s
end
def test_passed_eh_empty
assert_predicate r, :passed?
end
def test_passed_eh_failure
r.results << fail_test
refute_predicate r, :passed?
end
SKIP_MSG = "\n\nYou have skipped tests. Run with --verbose for details."
def test_passed_eh_error
r.start
r.results << error_test
refute_predicate r, :passed?
r.report
refute_match SKIP_MSG, io.string
end
def test_passed_eh_skipped
r.start
r.results << skip_test
assert r.passed?
restore_env do
r.report
end
assert_match SKIP_MSG, io.string
end
def test_passed_eh_skipped_verbose
r.options[:verbose] = true
r.start
r.results << skip_test
assert r.passed?
r.report
refute_match SKIP_MSG, io.string
end
def test_start
r.start
exp = "Run options: \n\n# Running:\n\n"
assert_equal exp, io.string
end
def test_record_pass
r.record passing_test
assert_equal ".", io.string
assert_empty r.results
assert_equal 1, r.count
assert_equal 0, r.assertions
end
def test_record_pass_with_metadata
reporter = self.r
def reporter.metadata
@metadata
end
def reporter.record result
super
@metadata = result.metadata if result.metadata?
end
r.record passing_test_with_metadata
exp = { :meta => :data }
assert_equal exp, reporter.metadata
assert_equal ".", io.string
assert_empty r.results
assert_equal 1, r.count
assert_equal 0, r.assertions
end
def test_record_fail
fail_test = self.fail_test
r.record fail_test
assert_equal "F", io.string
assert_equal [fail_test], r.results
assert_equal 1, r.count
assert_equal 0, r.assertions
end
def test_record_error
error_test = self.error_test
r.record error_test
assert_equal "E", io.string
assert_equal [error_test], r.results
assert_equal 1, r.count
assert_equal 0, r.assertions
end
def test_record_skip
skip_test = self.skip_test
r.record skip_test
assert_equal "S", io.string
assert_equal [skip_test], r.results
assert_equal 1, r.count
assert_equal 0, r.assertions
end
def test_report_empty
r.start
r.report
exp = <<~EOM
Run options:
# Running:
Finished in 0.00
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_passing
r.start
r.record passing_test
r.report
exp = <<~EOM
Run options:
# Running:
.
Finished in 0.00
1 runs, 0 assertions, 0 failures, 0 errors, 0 skips
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_failure
r.start
r.record fail_test
r.report
exp = <<~EOM
Run options:
# Running:
F
Finished in 0.00
1) Failure:
FakeTest#woot [FILE:LINE]:
boo
1 runs, 0 assertions, 1 failures, 0 errors, 0 skips
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_error
r.start
r.record error_test
r.report
exp = <<~EOM
Run options:
# Running:
E
Finished in 0.00
1) Error:
FakeTest#woot:
RuntimeError: no
FILE:LINE:in 'error_test'
FILE:LINE:in 'test_report_error'
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_error__sse
r.start
r.record system_stack_error_test
r.report
exp = <<~EOM
Run options:
# Running:
E
Finished in 0.00
1) Error:
FakeTest#woot:
SystemStackError: 274 -> 12
a
b
c
+->> 67 cycles of 4 lines:
| aa
| ab
| ac
| ad
+-<<
d
e
f
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_skipped
r.start
r.record skip_test
restore_env do
r.report
end
exp = <<~EOM
Run options:
# Running:
S
Finished in 0.00
1 runs, 0 assertions, 0 failures, 0 errors, 1 skips
You have skipped tests. Run with --verbose for details.
EOM
assert_equal exp, normalize_output(io.string)
end
def test_report_failure_uses_backtrace_filter
filter = Minitest::BacktraceFilter.new
def filter.filter _bt
["foo.rb:123:in 'foo'"]
end
with_backtrace_filter filter do
r.start
r.record fail_test
r.report
end
exp = "FakeTest#woot [foo.rb:123]"
assert_includes io.string, exp
end
def test_report_failure_uses_backtrace_filter_complex_sorbet
backtrace = <<~EOBT
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/assertions.rb:183:in 'assert'
example_test.rb:9:in 'assert_false'
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in 'bind_call'
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in 'validate_call'
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/_methods.rb:275:in 'block in _on_method_added'
example_test.rb:25:in 'test_something'
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:94:in 'block (3 levels) in run'
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:191:in 'capture_exceptions'
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:89:in 'block (2 levels) in run'
... so many lines ...
EOBT
filter = Minitest::BacktraceFilter.new %r%lib/minitest|gems/sorbet%
with_backtrace_filter filter do
begin
assert_equal 1, 2
rescue Minitest::Assertion => e
e.set_backtrace backtrace.lines.map(&:chomp)
assert_match "example_test.rb:25", e.location
end
end
end
end
minitest-5.25.4/test/minitest/test_minitest_benchmark.rb 0000444 0000041 0000041 00000006600 14743220663 023547 0 ustar www-data www-data require "minitest/autorun"
require "minitest/benchmark"
##
# Used to verify data:
# https://www.wolframalpha.com/examples/RegressionAnalysis.html
class TestMinitestBenchmark < Minitest::Test
def test_cls_bench_exp
assert_equal [2, 4, 8, 16, 32], Minitest::Benchmark.bench_exp(2, 32, 2)
end
def test_cls_bench_linear
assert_equal [2, 4, 6, 8, 10], Minitest::Benchmark.bench_linear(2, 10, 2)
end
def test_cls_runnable_methods
assert_equal [], Minitest::Benchmark.runnable_methods
c = Class.new Minitest::Benchmark do
def bench_blah
end
end
assert_equal ["bench_blah"], c.runnable_methods
end
def test_cls_bench_range
assert_equal [1, 10, 100, 1_000, 10_000], Minitest::Benchmark.bench_range
end
def test_fit_exponential_clean
x = [1.0, 2.0, 3.0, 4.0, 5.0]
y = x.map { |n| 1.1 * Math.exp(2.1 * n) }
assert_fit :exponential, x, y, 1.0, 1.1, 2.1
end
def test_fit_exponential_noisy
x = [1.0, 1.9, 2.6, 3.4, 5.0]
y = [12, 10, 8.2, 6.9, 5.9]
# verified with Numbers and R
assert_fit :exponential, x, y, 0.95, 13.81148, -0.1820
end
def test_fit_logarithmic_clean
x = [1.0, 2.0, 3.0, 4.0, 5.0]
y = x.map { |n| 1.1 + 2.1 * Math.log(n) }
assert_fit :logarithmic, x, y, 1.0, 1.1, 2.1
end
def test_fit_logarithmic_noisy
x = [1.0, 2.0, 3.0, 4.0, 5.0]
# Generated with
# y = x.map { |n| jitter = 0.999 + 0.002 * rand; (Math.log(n) ) * jitter }
y = [0.0, 0.6935, 1.0995, 1.3873, 1.6097]
assert_fit :logarithmic, x, y, 0.95, 0, 1
end
def test_fit_constant_clean
x = (1..5).to_a
y = [5.0, 5.0, 5.0, 5.0, 5.0]
assert_fit :linear, x, y, nil, 5.0, 0
end
def test_fit_constant_noisy
x = (1..5).to_a
y = [1.0, 1.2, 1.0, 0.8, 1.0]
# verified in numbers and R
assert_fit :linear, x, y, nil, 1.12, -0.04
end
def test_fit_linear_clean
# y = m * x + b where m = 2.2, b = 3.1
x = (1..5).to_a
y = x.map { |n| 2.2 * n + 3.1 }
assert_fit :linear, x, y, 1.0, 3.1, 2.2
end
def test_fit_linear_noisy
x = [ 60, 61, 62, 63, 65]
y = [3.1, 3.6, 3.8, 4.0, 4.1]
# verified in numbers and R
assert_fit :linear, x, y, 0.8315, -7.9635, 0.1878
end
def test_fit_power_clean
# y = A x ** B, where B = b and A = e ** a
# if, A = 1, B = 2, then
x = [1.0, 2.0, 3.0, 4.0, 5.0]
y = [1.0, 4.0, 9.0, 16.0, 25.0]
assert_fit :power, x, y, 1.0, 1.0, 2.0
end
def test_fit_power_noisy
# from www.engr.uidaho.edu/thompson/courses/ME330/lecture/least_squares.html
x = [10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35]
y = [95, 105, 125, 141, 173, 200, 253, 298, 385, 459, 602]
# verified in numbers
assert_fit :power, x, y, 0.90, 2.6217, 1.4556
# income to % of households below income amount
# https://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
x = [15_000, 25_000, 35_000, 50_000, 75_000, 100_000]
y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
# verified in numbers
assert_fit :power, x, y, 0.96, 3.119e-5, 0.8959
end
def assert_fit msg, x, y, fit, exp_a, exp_b
bench = Minitest::Benchmark.new :blah
a, b, rr = bench.send "fit_#{msg}", x, y
assert_operator rr, :>=, fit if fit
assert_in_delta exp_a, a
assert_in_delta exp_b, b
end
end
describe "my class Bench" do
klass = self
it "should provide bench methods" do
klass.must_respond_to :bench
end
end
minitest-5.25.4/test/minitest/test_minitest_assertions.rb 0000444 0000041 0000041 00000116154 14743220663 024015 0 ustar www-data www-data require "minitest/autorun"
require_relative "metametameta"
e = Encoding.default_external
if e != Encoding::UTF_8 then
warn ""
warn ""
warn "NOTE: External encoding #{e} is not UTF-8. Tests WILL fail."
warn " Run tests with `RUBYOPT=-Eutf-8 rake` to avoid errors."
warn ""
warn ""
end
SomeError = Class.new Exception
unless defined? MyModule then
module MyModule; end
class AnError < StandardError; include MyModule; end
end
class TestMinitestAssertions < Minitest::Test
# do not call parallelize_me! - teardown accesses @tc._assertions
# which is not threadsafe. Nearly every method in here is an
# assertion test so it isn't worth splitting it out further.
# not included in JRuby
RE_LEVELS = /\(\d+ levels\) /
class DummyTest
include Minitest::Assertions
attr_accessor :assertions, :failure
def initialize
self.assertions = 0
self.failure = nil
end
end
def setup
super
Minitest::Test.reset
@tc = DummyTest.new
@zomg = "zomg ponies!" # TODO: const
@assertion_count = 1
end
def teardown
assert_equal(@assertion_count, @tc.assertions,
"expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}")
end
def assert_triggered expected, klass = Minitest::Assertion
e = assert_raises klass do
yield
end
msg = e.message.sub(/(---Backtrace---).*/m, '\1')
msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform
assert_msg = Regexp === expected ? :assert_match : :assert_equal
self.send assert_msg, expected, msg
end
def assert_unexpected expected
expected = Regexp.new expected if String === expected
assert_triggered expected, Minitest::UnexpectedError do
yield
end
end
def non_verbose
orig_verbose = $VERBOSE
$VERBOSE = false
yield
ensure
$VERBOSE = orig_verbose
end
def test_assert
@assertion_count = 2
@tc.assert_equal true, @tc.assert(true), "returns true on success"
end
def test_assert__triggered
assert_triggered "Expected false to be truthy." do
@tc.assert false
end
end
def test_assert__triggered_message
assert_triggered @zomg do
@tc.assert false, @zomg
end
end
def test_assert__triggered_lambda
assert_triggered "whoops" do
@tc.assert false, lambda { "whoops" }
end
end
def test_assert_empty
@assertion_count = 2
@tc.assert_empty []
end
def test_assert_empty_triggered
@assertion_count = 2
assert_triggered "Expected [1] to be empty." do
@tc.assert_empty [1]
end
end
def test_assert_equal
@tc.assert_equal 1, 1
end
def test_assert_equal_different_collection_array_hex_invisible
exp = Object.new
act = Object.new
msg = <<~EOM.chomp
No visible difference in the Array#inspect output.
You should look at the implementation of #== on Array or its members.
[#]
EOM
assert_triggered msg do
@tc.assert_equal [exp], [act]
end
end
def test_assert_equal_different_collection_hash_hex_invisible
exp, act = {}, {}
exp[1] = Object.new
act[1] = Object.new
act_obj = act[1]
# TODO: switch to endless when 2.7 is dropped
act_obj.define_singleton_method(:inspect) { "#" }
msg = <<~EOM.chomp % [act]
No visible difference in the Hash#inspect output.
You should look at the implementation of #== on Hash or its members.
%p
EOM
assert_triggered msg do
@tc.assert_equal exp, act
end
end
def test_assert_equal_different_diff_deactivated
without_diff do
assert_triggered util_msg("haha" * 10, "blah" * 10) do
exp = "haha" * 10
act = "blah" * 10
@tc.assert_equal exp, act
end
end
end
def test_assert_equal_different_message
assert_triggered "whoops.\nExpected: 1\n Actual: 2" do
@tc.assert_equal 1, 2, message { "whoops" }
end
end
def test_assert_equal_different_lambda
assert_triggered "whoops.\nExpected: 1\n Actual: 2" do
@tc.assert_equal 1, 2, lambda { "whoops" }
end
end
def test_assert_equal_different_hex
c = Class.new do
def initialize s; @name = s; end
end
exp = c.new "a"
act = c.new "b"
msg = <<~EOS
--- expected
+++ actual
@@ -1 +1 @@
-#<#:0xXXXXXX @name="a">
+#<#:0xXXXXXX @name="b">
EOS
assert_triggered msg do
@tc.assert_equal exp, act
end
end
def test_assert_equal_different_hex_invisible
exp = Object.new
act = Object.new
msg = <<~EOM.chomp
No visible difference in the Object#inspect output.
You should look at the implementation of #== on Object or its members.
#
EOM
assert_triggered msg do
@tc.assert_equal exp, act
end
end
def test_assert_equal_different_long
msg = <<~EOM
--- expected
+++ actual
@@ -1 +1 @@
-"hahahahahahahahahahahahahahahahahahahaha"
+"blahblahblahblahblahblahblahblahblahblah"
EOM
assert_triggered msg do
exp = "haha" * 10
act = "blah" * 10
@tc.assert_equal exp, act
end
end
def test_assert_equal_different_long_invisible
msg = <<~EOM.chomp
No visible difference in the String#inspect output.
You should look at the implementation of #== on String or its members.
"blahblahblahblahblahblahblahblahblahblah"
EOM
assert_triggered msg do
exp = "blah" * 10
act = "blah" * 10
def exp.== _
false
end
@tc.assert_equal exp, act
end
end
def test_assert_equal_different_long_msg
msg = <<~EOM
message.
--- expected
+++ actual
@@ -1 +1 @@
-"hahahahahahahahahahahahahahahahahahahaha"
+"blahblahblahblahblahblahblahblahblahblah"
EOM
assert_triggered msg do
exp = "haha" * 10
act = "blah" * 10
@tc.assert_equal exp, act, "message"
end
end
def test_assert_equal_different_short
assert_triggered util_msg(1, 2) do
@tc.assert_equal 1, 2
end
end
def test_assert_equal_different_short_msg
assert_triggered util_msg(1, 2, "message") do
@tc.assert_equal 1, 2, "message"
end
end
def test_assert_equal_different_short_multiline
msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n"
assert_triggered msg do
@tc.assert_equal "a\nb", "a\nc"
end
end
def test_assert_equal_does_not_allow_lhs_nil
if Minitest::VERSION >= "6" then
warn "Time to strip the MT5 test"
@assertion_count += 1
assert_triggered(/Use assert_nil if expecting nil/) do
@tc.assert_equal nil, nil
end
else
err_re = /Use assert_nil if expecting nil from .*test_minitest_\w+.rb/
err_re = "" if $-w.nil?
assert_deprecation err_re do
@tc.assert_equal nil, nil
end
end
end
def test_assert_equal_does_not_allow_lhs_nil_triggered
assert_triggered "Expected: nil\n Actual: false" do
@tc.assert_equal nil, false
end
end
def test_assert_equal_string_bug791
exp = <<~EOM.chomp
Expected: "\\\\n"
Actual: "\\\\"
EOM
assert_triggered exp do
@tc.assert_equal "\\n", "\\"
end
end
def test_assert_equal_string_both_escaped_unescaped_newlines
msg = <<~EOM
--- expected
+++ actual
@@ -1,2 +1 @@
-"A\\n
-B"
+"A\\n\\\\nB"
EOM
assert_triggered msg do
exp = "A\\nB"
act = "A\n\\nB"
@tc.assert_equal exp, act
end
end
def test_assert_equal_string_encodings
msg = <<~EOM
--- expected
+++ actual
@@ -1,3 +1,3 @@
-# encoding: UTF-8
-# valid: false
+# encoding: #{Encoding::BINARY.name}
+# valid: true
"bad-utf8-\\xF1.txt"
EOM
assert_triggered msg do
exp = "bad-utf8-\xF1.txt"
act = exp.dup.b
@tc.assert_equal exp, act
end
end
def test_assert_equal_string_encodings_both_different
msg = <<~EOM
--- expected
+++ actual
@@ -1,3 +1,3 @@
-# encoding: US-ASCII
-# valid: false
+# encoding: #{Encoding::BINARY.name}
+# valid: true
"bad-utf8-\\xF1.txt"
EOM
assert_triggered msg do
exp = "bad-utf8-\xF1.txt".dup.force_encoding Encoding::ASCII
act = exp.dup.b
@tc.assert_equal exp, act
end
end
def test_assert_equal_unescape_newlines
msg = <<~'EOM' # NOTE single quotes on heredoc
--- expected
+++ actual
@@ -1,2 +1,2 @@
-"hello
+"hello\n
world"
EOM
assert_triggered msg do
exp = "hello\nworld"
act = 'hello\nworld' # notice single quotes
@tc.assert_equal exp, act
end
end
def test_assert_in_delta
@tc.assert_in_delta 0.0, 1.0 / 1000, 0.1
end
def test_assert_in_delta_triggered
x = "1.0e-06"
assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
@tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001
end
end
def test_assert_in_epsilon
@assertion_count = 10
@tc.assert_in_epsilon 10_000, 9991
@tc.assert_in_epsilon 9991, 10_000
@tc.assert_in_epsilon 1.0, 1.001
@tc.assert_in_epsilon 1.001, 1.0
@tc.assert_in_epsilon 10_000, 9999.1, 0.0001
@tc.assert_in_epsilon 9999.1, 10_000, 0.0001
@tc.assert_in_epsilon 1.0, 1.0001, 0.0001
@tc.assert_in_epsilon 1.0001, 1.0, 0.0001
@tc.assert_in_epsilon(-1, -1)
@tc.assert_in_epsilon(-10_000, -9991)
end
def test_assert_in_epsilon_triggered
assert_triggered "Expected |10000 - 9990| (10) to be <= 9.99." do
@tc.assert_in_epsilon 10_000, 9990
end
end
def test_assert_in_epsilon_triggered_negative_case
x = "0.100000xxx"
y = "0.1"
assert_triggered "Expected |-1.1 - -1| (#{x}) to be <= #{y}." do
@tc.assert_in_epsilon(-1.1, -1, 0.1)
end
end
def test_assert_includes
@assertion_count = 2
@tc.assert_includes [true], true
end
def test_assert_includes_triggered
@assertion_count = 3
e = @tc.assert_raises Minitest::Assertion do
@tc.assert_includes [true], false
end
expected = "Expected [true] to include false."
assert_equal expected, e.message
end
def test_assert_instance_of
@tc.assert_instance_of String, "blah"
end
def test_assert_instance_of_triggered
assert_triggered 'Expected "blah" to be an instance of Array, not String.' do
@tc.assert_instance_of Array, "blah"
end
end
def test_assert_kind_of
@tc.assert_kind_of String, "blah"
end
def test_assert_kind_of_triggered
assert_triggered 'Expected "blah" to be a kind of Array, not String.' do
@tc.assert_kind_of Array, "blah"
end
end
def test_assert_match
@assertion_count = 2
m = @tc.assert_match(/\w+/, "blah blah blah")
assert_kind_of MatchData, m
assert_equal "blah", m[0]
end
def test_assert_match_matchee_to_str
@assertion_count = 2
obj = Object.new
def obj.to_str; "blah" end
@tc.assert_match "blah", obj
end
def test_assert_match_matcher_object
@assertion_count = 2
pattern = Object.new
def pattern.=~ _; true end
@tc.assert_match pattern, 5
end
def test_assert_match_object_triggered
@assertion_count = 2
pattern = Object.new
def pattern.=~ _; false end
def pattern.inspect; "[Object]" end
assert_triggered "Expected [Object] to match 5." do
@tc.assert_match pattern, 5
end
end
def test_assert_match_triggered
@assertion_count = 2
assert_triggered 'Expected /\d+/ to match "blah blah blah".' do
@tc.assert_match(/\d+/, "blah blah blah")
end
end
def test_assert_nil
@tc.assert_nil nil
end
def test_assert_nil_triggered
assert_triggered "Expected 42 to be nil." do
@tc.assert_nil 42
end
end
def test_assert_operator
@tc.assert_operator 2, :>, 1
end
def test_assert_operator_bad_object
bad = Object.new
def bad.== _; true end
@tc.assert_operator bad, :equal?, bad
end
def test_assert_operator_triggered
assert_triggered "Expected 2 to be < 1." do
@tc.assert_operator 2, :<, 1
end
end
def test_assert_output_both
@assertion_count = 2
@tc.assert_output "yay", "blah" do
print "yay"
$stderr.print "blah"
end
end
def test_assert_output_both_regexps
@assertion_count = 4
@tc.assert_output(/y.y/, /bl.h/) do
print "yay"
$stderr.print "blah"
end
end
def test_assert_output_err
@tc.assert_output nil, "blah" do
$stderr.print "blah"
end
end
def test_assert_output_neither
@assertion_count = 0
@tc.assert_output do
# do nothing
end
end
def test_assert_output_out
@tc.assert_output "blah" do
print "blah"
end
end
def test_assert_output_triggered_both
assert_triggered util_msg("blah", "blah blah", "In stderr") do
@tc.assert_output "yay", "blah" do
print "boo"
$stderr.print "blah blah"
end
end
end
def test_assert_output_triggered_err
assert_triggered util_msg("blah", "blah blah", "In stderr") do
@tc.assert_output nil, "blah" do
$stderr.print "blah blah"
end
end
end
def test_assert_output_triggered_out
assert_triggered util_msg("blah", "blah blah", "In stdout") do
@tc.assert_output "blah" do
print "blah blah"
end
end
end
def test_assert_output_no_block
assert_triggered "assert_output requires a block to capture output." do
@tc.assert_output "blah"
end
end
def test_assert_output_nested_assert_uncaught
@assertion_count = 1
assert_triggered "Epic Fail!" do
@tc.assert_output "blah\n" do
puts "blah"
@tc.flunk
end
end
end
def test_assert_output_nested_raise
@assertion_count = 2
@tc.assert_output "blah\n" do
@tc.assert_raises RuntimeError do
puts "blah"
raise "boom!"
end
end
end
def test_assert_output_nested_raise_bad
@assertion_count = 0
assert_unexpected "boom!" do
@tc.assert_raises do # 2) bypassed via UnexpectedError
@tc.assert_output "blah\n" do # 1) captures and raises UnexpectedError
puts "not_blah"
raise "boom!"
end
end
end
end
def test_assert_output_nested_raise_mismatch
# this test is redundant, but illustrative
@assertion_count = 0
assert_unexpected "boom!" do
@tc.assert_raises RuntimeError do # 2) bypassed via UnexpectedError
@tc.assert_output "blah\n" do # 1) captures and raises UnexpectedError
puts "not_blah"
raise ArgumentError, "boom!"
end
end
end
end
def test_assert_output_nested_throw_caught
@assertion_count = 2
@tc.assert_output "blah\n" do
@tc.assert_throws :boom! do
puts "blah"
throw :boom!
end
end
end
def test_assert_output_nested_throw_caught_bad
@assertion_count = 1 # want 0; can't prevent throw from escaping :(
@tc.assert_throws :boom! do # 2) captured via catch
@tc.assert_output "blah\n" do # 1) bypassed via throw
puts "not_blah"
throw :boom!
end
end
end
def test_assert_output_nested_throw_mismatch
@assertion_count = 0
assert_unexpected "uncaught throw :boom!" do
@tc.assert_throws :not_boom! do # 2) captured via assert_throws+rescue
@tc.assert_output "blah\n" do # 1) bypassed via throw
puts "not_blah"
throw :boom!
end
end
end
end
def test_assert_output_uncaught_raise
@assertion_count = 0
assert_unexpected "RuntimeError: boom!" do
@tc.assert_output "blah\n" do
puts "not_blah"
raise "boom!"
end
end
end
def test_assert_output_uncaught_throw
@assertion_count = 0
assert_unexpected "uncaught throw :boom!" do
@tc.assert_output "blah\n" do
puts "not_blah"
throw :boom!
end
end
end
def test_assert_predicate
@tc.assert_predicate "", :empty?
end
def test_assert_predicate_triggered
assert_triggered 'Expected "blah" to be empty?.' do
@tc.assert_predicate "blah", :empty?
end
end
def test_assert_raises
@tc.assert_raises RuntimeError do
raise "blah"
end
end
def test_assert_raises_default
@tc.assert_raises do
raise StandardError, "blah"
end
end
def test_assert_raises_default_triggered
e = assert_raises Minitest::Assertion do
@tc.assert_raises do
raise SomeError, "blah"
end
end
expected = <<~EOM.chomp
[StandardError] exception expected, not
Class:
Message: <"blah">
---Backtrace---
FILE:LINE:in 'block in test_assert_raises_default_triggered'
---------------
EOM
actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
actual.gsub! RE_LEVELS, "" unless jruby?
actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ")
assert_equal expected, actual
end
def test_assert_raises_exit
@tc.assert_raises SystemExit do
exit 1
end
end
def test_assert_raises_module
@tc.assert_raises MyModule do
raise AnError
end
end
def test_assert_raises_signals
@tc.assert_raises SignalException do
raise SignalException, :INT
end
end
def test_assert_raises_throw_nested_bad
@assertion_count = 0
assert_unexpected "RuntimeError: boom!" do
@tc.assert_raises do
@tc.assert_throws :blah do
raise "boom!"
throw :not_blah
end
end
end
end
##
# *sigh* This is quite an odd scenario, but it is from real (albeit
# ugly) test code in ruby-core:
# https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
def test_assert_raises_skip
@assertion_count = 0
assert_triggered "skipped", Minitest::Skip do
@tc.assert_raises ArgumentError do
begin
raise "blah"
rescue
skip "skipped"
end
end
end
end
def test_assert_raises_subclass
@tc.assert_raises StandardError do
raise AnError
end
end
def test_assert_raises_subclass_triggered
e = assert_raises Minitest::Assertion do
@tc.assert_raises SomeError do
raise AnError, "some message"
end
end
expected = <<~EOM
[SomeError] exception expected, not
Class:
Message: <"some message">
---Backtrace---
FILE:LINE:in 'block in test_assert_raises_subclass_triggered'
---------------
EOM
actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
actual.gsub! RE_LEVELS, "" unless jruby?
actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ")
assert_equal expected.chomp, actual
end
def test_assert_raises_triggered_different
e = assert_raises Minitest::Assertion do
@tc.assert_raises RuntimeError do
raise SyntaxError, "icky"
end
end
expected = <<~EOM.chomp
[RuntimeError] exception expected, not
Class:
Message: <"icky">
---Backtrace---
FILE:LINE:in 'block in test_assert_raises_triggered_different'
---------------
EOM
actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
actual.gsub! RE_LEVELS, "" unless jruby?
actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ")
assert_equal expected, actual
end
def test_assert_raises_triggered_different_msg
e = assert_raises Minitest::Assertion do
@tc.assert_raises RuntimeError, "XXX" do
raise SyntaxError, "icky"
end
end
expected = <<~EOM
XXX.
[RuntimeError] exception expected, not
Class:
Message: <"icky">
---Backtrace---
FILE:LINE:in 'block in test_assert_raises_triggered_different_msg'
---------------
EOM
actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
actual.gsub! RE_LEVELS, "" unless jruby?
actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ")
assert_equal expected.chomp, actual
end
def test_assert_raises_triggered_none
e = assert_raises Minitest::Assertion do
@tc.assert_raises Minitest::Assertion do
# do nothing
end
end
expected = "Minitest::Assertion expected but nothing was raised."
assert_equal expected, e.message
end
def test_assert_raises_triggered_none_msg
e = assert_raises Minitest::Assertion do
@tc.assert_raises Minitest::Assertion, "XXX" do
# do nothing
end
end
expected = "XXX.\nMinitest::Assertion expected but nothing was raised."
assert_equal expected, e.message
end
def test_assert_raises_without_block
assert_triggered "assert_raises requires a block to capture errors." do
@tc.assert_raises StandardError
end
end
def test_assert_respond_to
@tc.assert_respond_to "blah", :empty?
end
def test_assert_respond_to_triggered
assert_triggered 'Expected "blah" (String) to respond to #rawr!.' do
@tc.assert_respond_to "blah", :rawr!
end
end
def test_assert_respond_to__include_all
@tc.assert_respond_to @tc, :exit, include_all: true
end
def test_assert_respond_to__include_all_triggered
assert_triggered(/Expected .+::DummyTest. to respond to #exit\?/) do
@tc.assert_respond_to @tc, :exit?, include_all: true
end
end
def test_assert_same
@assertion_count = 3
o = "blah"
@tc.assert_same 1, 1
@tc.assert_same :blah, :blah
@tc.assert_same o, o
end
def test_assert_same_triggered
@assertion_count = 2
assert_triggered "Expected 2 (oid=N) to be the same as 1 (oid=N)." do
@tc.assert_same 1, 2
end
s1 = +"blah"
s2 = +"blah"
assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do
@tc.assert_same s1, s2
end
end
def test_assert_send
@assertion_count = 0 if error_on_warn?
assert_deprecation(/DEPRECATED: assert_send/) do
@tc.assert_send [1, :<, 2]
end
end
def test_assert_send_bad
if error_on_warn? then
@assertion_count = 0
assert_deprecation(/DEPRECATED: assert_send/) do
@tc.assert_send [1, :>, 2]
end
else
assert_triggered "Expected 1.>(*[2]) to return true." do
assert_deprecation(/DEPRECATED: assert_send/) do
@tc.assert_send [1, :>, 2]
end
end
end
end
def test_assert_silent
@assertion_count = 2
@tc.assert_silent do
# do nothing
end
end
def test_assert_silent_triggered_err
assert_triggered util_msg("", "blah blah", "In stderr") do
@tc.assert_silent do
$stderr.print "blah blah"
end
end
end
def test_assert_silent_triggered_out
@assertion_count = 2
assert_triggered util_msg("", "blah blah", "In stdout") do
@tc.assert_silent do
print "blah blah"
end
end
end
def test_assert_throws
v = @tc.assert_throws :blah do
throw :blah
end
assert_nil v
end
def test_assert_throws_value
v = @tc.assert_throws :blah do
throw :blah, 42
end
assert_equal 42, v
end
def test_assert_throws_argument_exception
@assertion_count = 0
assert_unexpected "ArgumentError" do
@tc.assert_throws :blah do
raise ArgumentError
end
end
end
def test_assert_throws_different
assert_triggered "Expected :blah to have been thrown, not :not_blah." do
@tc.assert_throws :blah do
throw :not_blah
end
end
end
def test_assert_throws_name_error
@assertion_count = 0
assert_unexpected "NameError" do
@tc.assert_throws :blah do
raise NameError
end
end
end
def test_assert_throws_unthrown
assert_triggered "Expected :blah to have been thrown." do
@tc.assert_throws :blah do
# do nothing
end
end
end
def test_assert_path_exists
@tc.assert_path_exists __FILE__
end
def test_assert_path_exists_triggered
assert_triggered "Expected path 'blah' to exist." do
@tc.assert_path_exists "blah"
end
end
def test_assert_pattern
if RUBY_VERSION > "3" then
@tc.assert_pattern do
exp = if RUBY_VERSION.start_with? "3.0"
"(eval):1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!\n"
else
""
end
assert_output nil, exp do
eval "[1,2,3] => [Integer, Integer, Integer]" # eval to escape parser for ruby<3
end
end
else
@assertion_count = 0
assert_raises NotImplementedError do
@tc.assert_pattern do
# do nothing
end
end
end
end
def test_assert_pattern_traps_nomatchingpatternerror
skip unless RUBY_VERSION > "3"
exp = if RUBY_VERSION.start_with? "3.0" then
"[1, 2, 3]" # terrible error message!
else
/length mismatch/
end
assert_triggered exp do
@tc.assert_pattern do
capture_io do # 3.0 is noisy
eval "[1,2,3] => [Integer, Integer]" # eval to escape parser for ruby<3
end
end
end
end
def test_assert_pattern_raises_other_exceptions
skip unless RUBY_VERSION >= "3.0"
@assertion_count = 0
assert_raises RuntimeError do
@tc.assert_pattern do
raise "boom"
end
end
end
def test_assert_pattern_with_no_block
skip unless RUBY_VERSION >= "3.0"
assert_triggered "assert_pattern requires a block to capture errors." do
@tc.assert_pattern
end
end
def test_capture_io
@assertion_count = 0
non_verbose do
out, err = capture_io do
puts "hi"
$stderr.puts "bye!"
end
assert_equal "hi\n", out
assert_equal "bye!\n", err
end
end
def test_capture_subprocess_io
@assertion_count = 0
non_verbose do
out, err = capture_subprocess_io do
system "echo hi"
system "echo bye! 1>&2"
end
assert_equal "hi\n", out
assert_equal "bye!", err.strip
end
end
def test_class_asserts_match_refutes
@assertion_count = 0
methods = Minitest::Assertions.public_instance_methods.map(&:to_s)
# These don't have corresponding refutes _on purpose_. They're
# useless and will never be added, so don't bother.
ignores = %w[assert_output assert_raises assert_send
assert_silent assert_throws assert_mock]
ignores += %w[assert_allocations] # for minitest-gcstats
asserts = methods.grep(/^assert/).sort - ignores
refutes = methods.grep(/^refute/).sort - ignores
assert_empty refutes.map { |n| n.sub(/^refute/, "assert") } - asserts
assert_empty asserts.map { |n| n.sub(/^assert/, "refute") } - refutes
end
def test_delta_consistency
@assertion_count = 2
@tc.assert_in_delta 0, 1, 1
assert_triggered "Expected |0 - 1| (1) to not be <= 1." do
@tc.refute_in_delta 0, 1, 1
end
end
def test_epsilon_consistency
@assertion_count = 2
@tc.assert_in_epsilon 1.0, 1.001
msg = "Expected |1.0 - 1.001| (0.000999xxx) to not be <= 0.001."
assert_triggered msg do
@tc.refute_in_epsilon 1.0, 1.001
end
end
def assert_fail_after t
@tc.fail_after t.year, t.month, t.day, "remove the deprecations"
end
def test_fail_after
d0 = Time.now
d1 = d0 + 86_400 # I am an idiot
assert_silent do
assert_fail_after d1
end
assert_triggered "remove the deprecations" do
assert_fail_after d0
end
end
def test_flunk
assert_triggered "Epic Fail!" do
@tc.flunk
end
end
def test_flunk_message
assert_triggered @zomg do
@tc.flunk @zomg
end
end
def test_pass
@tc.pass
end
def test_refute
@assertion_count = 2
@tc.assert_equal true, @tc.refute(false), "returns true on success"
end
def test_refute_empty
@assertion_count = 2
@tc.refute_empty [1]
end
def test_refute_empty_triggered
@assertion_count = 2
assert_triggered "Expected [] to not be empty." do
@tc.refute_empty []
end
end
def test_refute_equal
@tc.refute_equal "blah", "yay"
end
def test_refute_equal_triggered
assert_triggered 'Expected "blah" to not be equal to "blah".' do
@tc.refute_equal "blah", "blah"
end
end
def test_refute_in_delta
@tc.refute_in_delta 0.0, 1.0 / 1000, 0.000001
end
def test_refute_in_delta_triggered
x = "0.1"
assert_triggered "Expected |0.0 - 0.001| (0.001) to not be <= #{x}." do
@tc.refute_in_delta 0.0, 1.0 / 1000, 0.1
end
end
def test_refute_in_epsilon
@tc.refute_in_epsilon 10_000, 9990-1
end
def test_refute_in_epsilon_triggered
assert_triggered "Expected |10000 - 9990| (10) to not be <= 10.0." do
@tc.refute_in_epsilon 10_000, 9990
flunk
end
end
def test_refute_includes
@assertion_count = 2
@tc.refute_includes [true], false
end
def test_refute_includes_triggered
@assertion_count = 3
e = @tc.assert_raises Minitest::Assertion do
@tc.refute_includes [true], true
end
expected = "Expected [true] to not include true."
assert_equal expected, e.message
end
def test_refute_instance_of
@tc.refute_instance_of Array, "blah"
end
def test_refute_instance_of_triggered
assert_triggered 'Expected "blah" to not be an instance of String.' do
@tc.refute_instance_of String, "blah"
end
end
def test_refute_kind_of
@tc.refute_kind_of Array, "blah"
end
def test_refute_kind_of_triggered
assert_triggered 'Expected "blah" to not be a kind of String.' do
@tc.refute_kind_of String, "blah"
end
end
def test_refute_match
@assertion_count = 2
@tc.refute_match(/\d+/, "blah blah blah")
end
def test_refute_match_matcher_object
@assertion_count = 2
pattern = Object.new
def pattern.=~ _; false end
@tc.refute_match pattern, 5
end
def test_refute_match_object_triggered
@assertion_count = 2
pattern = Object.new
def pattern.=~ _; true end
def pattern.inspect; "[Object]" end
assert_triggered "Expected [Object] to not match 5." do
@tc.refute_match pattern, 5
end
end
def test_refute_match_triggered
@assertion_count = 2
assert_triggered 'Expected /\w+/ to not match "blah blah blah".' do
@tc.refute_match(/\w+/, "blah blah blah")
end
end
def test_refute_nil
@tc.refute_nil 42
end
def test_refute_nil_triggered
assert_triggered "Expected nil to not be nil." do
@tc.refute_nil nil
end
end
def test_refute_operator
@tc.refute_operator 2, :<, 1
end
def test_refute_operator_bad_object
bad = Object.new
def bad.== _; true end
@tc.refute_operator true, :equal?, bad
end
def test_refute_operator_triggered
assert_triggered "Expected 2 to not be > 1." do
@tc.refute_operator 2, :>, 1
end
end
def test_refute_pattern
if RUBY_VERSION >= "3.0"
@tc.refute_pattern do
capture_io do # 3.0 is noisy
eval "[1,2,3] => [Integer, Integer, String]"
end
end
else
@assertion_count = 0
assert_raises NotImplementedError do
@tc.refute_pattern do
eval "[1,2,3] => [Integer, Integer, String]"
end
end
end
end
def test_refute_pattern_expects_nomatchingpatternerror
skip unless RUBY_VERSION > "3"
assert_triggered(/NoMatchingPatternError expected, but nothing was raised./) do
@tc.refute_pattern do
capture_io do # 3.0 is noisy
eval "[1,2,3] => [Integer, Integer, Integer]"
end
end
end
end
def test_refute_pattern_raises_other_exceptions
skip unless RUBY_VERSION >= "3.0"
@assertion_count = 0
assert_raises RuntimeError do
@tc.refute_pattern do
raise "boom"
end
end
end
def test_refute_pattern_with_no_block
skip unless RUBY_VERSION >= "3.0"
assert_triggered "refute_pattern requires a block to capture errors." do
@tc.refute_pattern
end
end
def test_refute_predicate
@tc.refute_predicate "42", :empty?
end
def test_refute_predicate_triggered
assert_triggered 'Expected "" to not be empty?.' do
@tc.refute_predicate "", :empty?
end
end
def test_refute_respond_to
@tc.refute_respond_to "blah", :rawr!
end
def test_refute_respond_to_triggered
assert_triggered 'Expected "blah" to not respond to empty?.' do
@tc.refute_respond_to "blah", :empty?
end
end
def test_refute_respond_to__include_all
@tc.refute_respond_to "blah", :missing, include_all: true
end
def test_refute_respond_to__include_all_triggered
assert_triggered(/Expected .*DummyTest.* to not respond to exit./) do
@tc.refute_respond_to @tc, :exit, include_all: true
end
end
def test_refute_same
@tc.refute_same 1, 2
end
def test_refute_same_triggered
assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do
@tc.refute_same 1, 1
end
end
def test_refute_path_exists
@tc.refute_path_exists "blah"
end
def test_refute_path_exists_triggered
assert_triggered "Expected path '#{__FILE__}' to not exist." do
@tc.refute_path_exists __FILE__
end
end
def test_skip
@assertion_count = 0
assert_triggered "haha!", Minitest::Skip do
@tc.skip "haha!"
end
end
def assert_skip_until t, msg
@tc.skip_until t.year, t.month, t.day, msg
end
def test_skip_until
@assertion_count = 0
d0 = Time.now
d1 = d0 + 86_400 # I am an idiot
assert_deprecation(/Stale skip_until \"not yet\" at .*?:\d+$/) do
assert_skip_until d0, "not yet"
end
assert_triggered "not ready yet", Minitest::Skip do
assert_skip_until d1, "not ready yet"
end
end
def util_msg exp, act, msg = nil
s = "Expected: #{exp.inspect}\n Actual: #{act.inspect}"
s = "#{msg}.\n#{s}" if msg
s
end
def without_diff
old_diff = Minitest::Assertions.diff
Minitest::Assertions.diff = nil
yield
ensure
Minitest::Assertions.diff = old_diff
end
end
class TestMinitestAssertionHelpers < Minitest::Test
def assert_mu_pp exp, input, raw = false
act = mu_pp input
if String === input && !raw then
assert_equal "\"#{exp}\"", act
else
assert_equal exp, act
end
end
def assert_mu_pp_for_diff exp, input, raw = false
act = mu_pp_for_diff input
if String === input && !raw then
assert_equal "\"#{exp}\"", act
else
assert_equal exp, act
end
end
def test_diff_equal
msg = <<~EOM.chomp
No visible difference in the String#inspect output.
You should look at the implementation of #== on String or its members.
"blahblahblahblahblahblahblahblahblahblah"
EOM
o1 = "blah" * 10
o2 = "blah" * 10
def o1.== _
false
end
assert_equal msg, diff(o1, o2)
end
def test_diff_str_mixed
msg = <<~'EOM' # NOTE single quotes on heredoc
--- expected
+++ actual
@@ -1 +1 @@
-"A\\n\nB"
+"A\n\\nB"
EOM
exp = "A\\n\nB"
act = "A\n\\nB"
assert_equal msg, diff(exp, act)
end
def test_diff_str_multiline
msg = <<~EOM
--- expected
+++ actual
@@ -1,2 +1,2 @@
"A
-B"
+C"
EOM
exp = "A\nB"
act = "A\nC"
assert_equal msg, diff(exp, act)
end
def test_diff_str_simple
msg = <<~EOM.chomp
Expected: "A"
Actual: "B"
EOM
exp = "A"
act = "B"
assert_equal msg, diff(exp, act)
end
def test_message
assert_equal "blah2.", message { "blah2" }.call
assert_equal "blah2.", message("") { "blah2" }.call
assert_equal "blah1.\nblah2.", message(:blah1) { "blah2" }.call
assert_equal "blah1.\nblah2.", message("blah1") { "blah2" }.call
message = proc { "blah1" }
assert_equal "blah1.\nblah2.", message(message) { "blah2" }.call
message = message { "blah1" }
assert_equal "blah1.\nblah2.", message(message) { "blah2" }.call
end
def test_message_deferred
var = nil
msg = message { var = "blah" }
assert_nil var
msg.call
assert_equal "blah", var
end
def test_mu_pp
assert_mu_pp 42.inspect, 42
assert_mu_pp %w[a b c].inspect, %w[a b c]
assert_mu_pp "A B", "A B"
assert_mu_pp "A\\nB", "A\nB"
assert_mu_pp "A\\\\nB", 'A\nB' # notice single quotes
end
def test_mu_pp_for_diff
assert_mu_pp_for_diff "#", Object.new
assert_mu_pp_for_diff "A B", "A B"
assert_mu_pp_for_diff [1, 2, 3].inspect, [1, 2, 3]
assert_mu_pp_for_diff "A\nB", "A\nB"
end
def test_mu_pp_for_diff_str_bad_encoding
str = "\666".dup.force_encoding Encoding::UTF_8
exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6\""
assert_mu_pp_for_diff exp, str, :raw
end
def test_mu_pp_for_diff_str_bad_encoding_both
str = "\666A\\n\nB".dup.force_encoding Encoding::UTF_8
exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6A\\\\n\\nB\""
assert_mu_pp_for_diff exp, str, :raw
end
def test_mu_pp_for_diff_str_encoding
str = "A\nB".b
exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\nB\""
assert_mu_pp_for_diff exp, str, :raw
end
def test_mu_pp_for_diff_str_encoding_both
str = "A\\n\nB".b
exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\\\n\\nB\""
assert_mu_pp_for_diff exp, str, :raw
end
def test_mu_pp_for_diff_str_nerd
assert_mu_pp_for_diff "A\\nB\\\\nC", "A\nB\\nC"
assert_mu_pp_for_diff "\\nB\\\\nC", "\nB\\nC"
assert_mu_pp_for_diff "\\nB\\\\n", "\nB\\n"
assert_mu_pp_for_diff "\\n\\\\n", "\n\\n"
assert_mu_pp_for_diff "\\\\n\\n", "\\n\n"
assert_mu_pp_for_diff "\\\\nB\\n", "\\nB\n"
assert_mu_pp_for_diff "\\\\nB\\nC", "\\nB\nC"
assert_mu_pp_for_diff "A\\\\n\\nB", "A\\n\nB"
assert_mu_pp_for_diff "A\\n\\\\nB", "A\n\\nB"
assert_mu_pp_for_diff "\\\\n\\n", "\\n\n"
assert_mu_pp_for_diff "\\n\\\\n", "\n\\n"
end
def test_mu_pp_for_diff_str_normal
assert_mu_pp_for_diff "", ""
assert_mu_pp_for_diff "A\\n\n", "A\\n"
assert_mu_pp_for_diff "A\\n\nB", "A\\nB"
assert_mu_pp_for_diff "A\n", "A\n"
assert_mu_pp_for_diff "A\nB", "A\nB"
assert_mu_pp_for_diff "\\n\n", "\\n"
assert_mu_pp_for_diff "\n", "\n"
assert_mu_pp_for_diff "\\n\nA", "\\nA"
assert_mu_pp_for_diff "\nA", "\nA"
end
def test_mu_pp_str_bad_encoding
str = "\666".dup.force_encoding Encoding::UTF_8
exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6\""
assert_mu_pp exp, str, :raw
end
def test_mu_pp_str_encoding
str = "A\nB".b
exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\nB\""
assert_mu_pp exp, str, :raw
end
def test_mu_pp_str_immutable
printer = Class.new { extend Minitest::Assertions }
str = "test".freeze
assert_equal '"test"', printer.mu_pp(str)
end
end
minitest-5.25.4/test/minitest/metametameta.rb 0000444 0000041 0000041 00000006633 14743220663 021314 0 ustar www-data www-data require "tempfile"
require "stringio"
require "minitest/autorun"
class Minitest::Test
def with_empty_backtrace_filter
with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do
yield
end
end
def with_backtrace_filter filter
original = Minitest.backtrace_filter
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
begin
Minitest.backtrace_filter = filter
yield
ensure
Minitest.backtrace_filter = original
end
end
end
def error_on_warn?
defined?(Minitest::ErrorOnWarning)
end
def assert_deprecation re = /DEPRECATED/
re = // if $-w.nil? # "skip" if running `rake testW0`
assert_output "", re do
yield
end
rescue Minitest::UnexpectedWarning => e # raised if -Werror was used
assert_match re, e.message
end
end
class FakeNamedTest < Minitest::Test
@@count = 0
def self.name
@fake_name ||= begin
@@count += 1
"FakeNamedTest%02d" % @@count
end
end
end
module MyModule; end
class AnError < StandardError; include MyModule; end
class MetaMetaMetaTestCase < Minitest::Test
attr_accessor :reporter, :output, :tu
def with_stderr err
old = $stderr
$stderr = err
yield
ensure
$stderr = old
end
def run_tu_with_fresh_reporter flags = %w[--seed 42]
options = Minitest.process_args flags
@output = StringIO.new(+"")
self.reporter = Minitest::CompositeReporter.new
reporter << Minitest::SummaryReporter.new(@output, options)
reporter << Minitest::ProgressReporter.new(@output, options)
with_stderr @output do
reporter.start
yield reporter if block_given?
@tus ||= [@tu]
@tus.each do |tu|
Minitest::Runnable.runnables.delete tu
tu.run reporter, options
end
reporter.report
end
end
def first_reporter
reporter.reporters.first
end
def assert_report expected, flags = %w[--seed 42], &block
header = <<~EOM
Run options: #{flags.map { |s| s.include?("|") ? s.inspect : s }.join " "}
# Running:
EOM
run_tu_with_fresh_reporter flags, &block
output = normalize_output @output.string.dup
assert_equal header + expected, output
end
def normalize_output output
output.sub!(/Finished in .*/, "Finished in 0.00")
output.sub!(/Loaded suite .*/, "Loaded suite blah")
output.gsub!(/FakeNamedTest\d+/, "FakeNamedTestXX")
output.gsub!(/ = \d+.\d\d s = /, " = 0.00 s = ")
output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
output.gsub!(/ +$/, "")
file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" }
if windows? then
output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in [`']/, '\1FILE:LINE:in \'')
else
output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" }
output.gsub!(/^(\s+)([^:]+):\d+:in [`']/) { "#{$1}#{file[$2]}:LINE:in '" }
end
output.gsub!(/in [`']block in (?:([^']+)[#.])?/, "in 'block in")
output.gsub!(/in [`'](?:([^']+)[#.])?/, "in '")
output.gsub!(/( at )([^:]+):\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
output
end
def restore_env
old_value = ENV["MT_NO_SKIP_MSG"]
ENV.delete "MT_NO_SKIP_MSG"
yield
ensure
ENV["MT_NO_SKIP_MSG"] = old_value
end
def setup
super
Minitest.seed = 42
Minitest::Test.reset
@tu = nil
end
end
minitest-5.25.4/test/minitest/test_minitest_mock.rb 0000444 0000041 0000041 00000067160 14743220663 022556 0 ustar www-data www-data require "minitest/autorun"
def with_kwargs_env
ENV["MT_KWARGS_HAC\K"] = "1"
yield
ensure
ENV.delete "MT_KWARGS_HAC\K"
end
class TestMinitestMock < Minitest::Test
def setup
@mock = Minitest::Mock.new
.expect(:foo, nil)
.expect(:meaning_of_life, 42)
end
def test_create_stub_method
assert_nil @mock.foo
end
def test_allow_return_value_specification
assert_equal 42, @mock.meaning_of_life
end
def test_blow_up_if_not_called
@mock.foo
util_verify_bad "Expected meaning_of_life() => 42"
end
def test_not_blow_up_if_everything_called
@mock.foo
@mock.meaning_of_life
assert_mock @mock
end
def test_allow_expectations_to_be_added_after_creation
@mock.expect :bar, true
assert @mock.bar
end
def test_not_verify_if_new_expected_method_is_not_called
@mock.foo
@mock.meaning_of_life
@mock.expect :bar, true
util_verify_bad "Expected bar() => true"
end
def test_blow_up_on_wrong_number_of_arguments
@mock.foo
@mock.meaning_of_life
@mock.expect :sum, 3, [1, 2]
e = assert_raises ArgumentError do
@mock.sum
end
assert_equal "mocked method :sum expects 2 arguments, got []", e.message
end
def test_return_mock_does_not_raise
retval = Minitest::Mock.new
mock = Minitest::Mock.new
mock.expect :foo, retval
mock.foo
assert_mock mock
end
def test_mock_args_does_not_raise
arg = Minitest::Mock.new
mock = Minitest::Mock.new
mock.expect :foo, nil, [arg]
mock.foo arg
assert_mock mock
end
def test_set_expectation_on_special_methods
mock = Minitest::Mock.new
mock.expect :object_id, "received object_id"
assert_equal "received object_id", mock.object_id
mock.expect :respond_to_missing?, "received respond_to_missing?"
assert_equal "received respond_to_missing?", mock.respond_to_missing?
mock.expect :===, "received ==="
assert_equal "received ===", mock.===
mock.expect :inspect, "received inspect"
assert_equal "received inspect", mock.inspect
mock.expect :to_s, "received to_s"
assert_equal "received to_s", mock.to_s
mock.expect :public_send, "received public_send"
assert_equal "received public_send", mock.public_send
mock.expect :send, "received send"
assert_equal "received send", mock.send
assert_mock mock
end
def test_expectations_can_be_satisfied_via_send
@mock.send :foo
@mock.send :meaning_of_life
assert_mock @mock
end
def test_expectations_can_be_satisfied_via_public_send
@mock.public_send :foo
@mock.public_send :meaning_of_life
assert_mock @mock
end
def test_blow_up_on_wrong_arguments
@mock.foo
@mock.meaning_of_life
@mock.expect :sum, 3, [1, 2]
e = assert_raises MockExpectationError do
@mock.sum 2, 4
end
exp = "mocked method :sum called with unexpected arguments [2, 4]"
assert_equal exp, e.message
end
def test_expect_with_non_array_args
e = assert_raises ArgumentError do
@mock.expect :blah, 3, false
end
assert_match "args must be an array", e.message
end
def test_respond_appropriately
assert @mock.respond_to?(:foo)
assert @mock.respond_to?(:foo, true)
assert @mock.respond_to?("foo")
assert !@mock.respond_to?(:bar)
end
def test_no_method_error_on_unexpected_methods
e = assert_raises NoMethodError do
@mock.bar
end
expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]"
assert_match expected, e.message
end
def test_assign_per_mock_return_values
a = Minitest::Mock.new
b = Minitest::Mock.new
a.expect :foo, :a
b.expect :foo, :b
assert_equal :a, a.foo
assert_equal :b, b.foo
end
def test_do_not_create_stub_method_on_new_mocks
a = Minitest::Mock.new
a.expect :foo, :a
assert !Minitest::Mock.new.respond_to?(:foo)
end
def test_mock_is_a_blank_slate
@mock.expect :kind_of?, true, [String]
@mock.expect :==, true, [1]
assert @mock.kind_of?(String), "didn't mock :kind_of?"
assert @mock == 1, "didn't mock :=="
end
def test_assert_mock__pass
mock = Minitest::Mock.new
mock.expect :loose_expectation, true, [Integer]
mock.loose_expectation 1
result = assert_mock mock
assert_equal true, result
end
def assert_bad_mock klass, msg
mock = Minitest::Mock.new
mock.expect :foo, nil, [:bar]
mock.expect :foo, nil, [:baz]
mock.foo :bar
e = assert_raises klass do
yield mock
end
assert_equal msg, e.message
end
def test_verify__error
exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]"
assert_bad_mock MockExpectationError, exp do |mock|
mock.verify
end
end
def test_assert_mock__fail
exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]."
assert_bad_mock Minitest::Assertion, exp do |mock|
assert_mock mock
end
end
def test_assert_mock__fail_msg
exp = "BLAH.\nExpected foo(:baz) => nil, got [foo(:bar) => nil]."
assert_bad_mock Minitest::Assertion, exp do |mock|
assert_mock mock, "BLAH"
end
end
def test_assert_mock__fail_exp
exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]."
assert_bad_mock Minitest::Assertion, exp do |mock|
describe "X" do
it "y" do
_(mock).must_verify
end
end.new(:blah).send(:test_0001_y)
end
end
def test_assert_mock__fail_exp_msg
exp = "BLAH.\nExpected foo(:baz) => nil, got [foo(:bar) => nil]."
assert_bad_mock Minitest::Assertion, exp do |mock|
describe "X" do
it "y" do
_(mock).must_verify "BLAH"
end
end.new(:blah).send(:test_0001_y)
end
end
def test_verify_allows_called_args_to_be_loosely_specified
mock = Minitest::Mock.new
mock.expect :loose_expectation, true, [Integer]
mock.loose_expectation 1
assert_mock mock
end
def test_verify_raises_with_strict_args
mock = Minitest::Mock.new
mock.expect :strict_expectation, true, [2]
e = assert_raises MockExpectationError do
mock.strict_expectation 1
end
exp = "mocked method :strict_expectation called with unexpected arguments [1]"
assert_equal exp, e.message
end
def test_method_missing_empty
mock = Minitest::Mock.new
mock.expect :a, nil
mock.a
e = assert_raises MockExpectationError do
mock.a
end
assert_equal "No more expects available for :a: [] {}", e.message
end
def test_same_method_expects_are_verified_when_all_called
mock = Minitest::Mock.new
mock.expect :foo, nil, [:bar]
mock.expect :foo, nil, [:baz]
mock.foo :bar
mock.foo :baz
assert_mock mock
end
def test_same_method_expects_blow_up_when_not_all_called
mock = Minitest::Mock.new
mock.expect :foo, nil, [:bar]
mock.expect :foo, nil, [:baz]
mock.foo :bar
e = assert_raises(MockExpectationError) { mock.verify }
exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]"
assert_equal exp, e.message
end
def test_same_method_expects_with_same_args_blow_up_when_not_all_called
mock = Minitest::Mock.new
mock.expect :foo, nil, [:bar]
mock.expect :foo, nil, [:bar]
mock.foo :bar
e = assert_raises(MockExpectationError) { mock.verify }
exp = "Expected foo(:bar) => nil, got [foo(:bar) => nil]"
assert_equal exp, e.message
end
def test_delegator_calls_are_propagated
delegator = Object.new
mock = Minitest::Mock.new delegator
refute delegator.nil?
refute mock.nil?
assert_mock mock
end
def test_handles_kwargs_in_error_message
mock = Minitest::Mock.new
mock.expect :foo, nil, [], kw: true
mock.expect :foo, nil, [], kw: false
mock.foo kw: true
e = assert_raises(MockExpectationError) { mock.verify }
exp = "Expected foo(%p) => nil, got [foo(%p) => nil]" \
% [{ :kw => false }, { :kw => true }]
assert_equal exp.delete("{}"), e.message
end
def test_verify_passes_when_mock_block_returns_true
mock = Minitest::Mock.new
mock.expect :foo, nil do
true
end
mock.foo
assert_mock mock
end
def test_mock_block_is_passed_function_params
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil do |a1, a2, a3|
a1 == arg1 && a2 == arg2 && a3 == arg3
end
assert_silent do
if RUBY_VERSION > "3" then
mock.foo arg1, arg2, arg3
else
mock.foo arg1, arg2, **arg3 # oddity just for ruby 2.7
end
end
assert_mock mock
end
def test_mock_block_is_passed_keyword_args__block
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil do |k1:, k2:, k3:|
k1 == arg1 && k2 == arg2 && k3 == arg3
end
mock.foo k1: arg1, k2: arg2, k3: arg3
assert_mock mock
end
def test_mock_block_is_passed_keyword_args__block_bad_missing
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil do |k1:, k2:, k3:|
k1 == arg1 && k2 == arg2 && k3 == arg3
end
e = assert_raises ArgumentError do
mock.foo k1: arg1, k2: arg2
end
# basically testing ruby ... need ? for ruby < 2.7 :(
assert_match(/missing keyword: :?k3/, e.message)
end
def test_mock_block_is_passed_keyword_args__block_bad_extra
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil do |k1:, k2:|
k1 == arg1 && k2 == arg2 && k3 == arg3
end
e = assert_raises ArgumentError do
mock.foo k1: arg1, k2: arg2, k3: arg3
end
# basically testing ruby ... need ? for ruby < 2.7 :(
assert_match(/unknown keyword: :?k3/, e.message)
end
def test_mock_block_is_passed_keyword_args__block_bad_value
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil do |k1:, k2:, k3:|
k1 == arg1 && k2 == arg2 && k3 == arg3
end
e = assert_raises MockExpectationError do
mock.foo k1: arg1, k2: arg2, k3: :BAD!
end
exp = "mocked method :foo failed block w/ [] %p" \
% [{ :k1 => :bar, :k2 => [1, 2, 3], :k3 => :BAD! }]
assert_equal exp, e.message
end
def test_mock_block_is_passed_keyword_args__args
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3
mock.foo k1: arg1, k2: arg2, k3: arg3
assert_mock mock
end
def test_mock_allow_all_kwargs__old_style_env
with_kwargs_env do
mock = Minitest::Mock.new
mock.expect :foo, true, [Hash]
assert_equal true, mock.foo(bar: 42)
end
end
def test_mock_allow_all_kwargs__old_style_env__rewrite
with_kwargs_env do
mock = Minitest::Mock.new
mock.expect :foo, true, [], bar: Integer
assert_equal true, mock.foo(bar: 42)
end
end
def test_mock_block_is_passed_keyword_args__args__old_style_bad
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, [{ k1: arg1, k2: arg2, k3: arg3 }]
e = assert_raises ArgumentError do
mock.foo k1: arg1, k2: arg2, k3: arg3
end
assert_equal "mocked method :foo expects 1 arguments, got []", e.message
end
def test_mock_block_is_passed_keyword_args__args__old_style_env
with_kwargs_env do
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, [{ k1: arg1, k2: arg2, k3: arg3 }]
mock.foo k1: arg1, k2: arg2, k3: arg3
assert_mock mock
end
end
def test_mock_block_is_passed_keyword_args__args__old_style_both
with_kwargs_env do
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
assert_deprecation(/Using MT_KWARGS_HAC. yet passing kwargs/) do
mock.expect :foo, nil, [{}], k1: arg1, k2: arg2, k3: arg3
end
skip "-Werror" if error_on_warn? # mock above raised, so this is dead
mock.foo({}, k1: arg1, k2: arg2, k3: arg3)
assert_mock mock
end
end
def test_mock_block_is_passed_keyword_args__args_bad_missing
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3
e = assert_raises ArgumentError do
mock.foo k1: arg1, k2: arg2
end
assert_equal "mocked method :foo expects 3 keyword arguments, got %p" % { k1: arg1, k2: arg2 }, e.message
end
def test_mock_block_is_passed_keyword_args__args_bad_extra
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, k1: arg1, k2: arg2
e = assert_raises ArgumentError do
mock.foo k1: arg1, k2: arg2, k3: arg3
end
assert_equal "mocked method :foo expects 2 keyword arguments, got %p" % { k1: arg1, k2: arg2, k3: arg3 }, e.message
end
def test_mock_block_is_passed_keyword_args__args_bad_key
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3
e = assert_raises MockExpectationError do
mock.foo k1: arg1, k2: arg2, BAD: arg3
end
assert_includes e.message, "unexpected keywords [:k1, :k2, :k3]"
assert_includes e.message, "vs [:k1, :k2, :BAD]"
end
def test_mock_block_is_passed_keyword_args__args_bad_val
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3
e = assert_raises MockExpectationError do
mock.foo k1: arg1, k2: :BAD!, k3: arg3
end
bad = { :k2 => :BAD! }.inspect.delete "{}"
assert_match(/unexpected keyword arguments.* vs .*#{bad}/, e.message)
end
def test_mock_block_is_passed_function_block
mock = Minitest::Mock.new
block = proc { "bar" }
mock.expect :foo, nil do |arg, &blk|
arg == "foo" && blk == block
end
mock.foo "foo", &block
assert_mock mock
end
def test_mock_forward_keyword_arguments
mock = Minitest::Mock.new
mock.expect(:foo, nil) { |bar:| bar == "bar" }
mock.foo bar: "bar"
assert_mock mock
end
def test_verify_fails_when_mock_block_returns_false
mock = Minitest::Mock.new
mock.expect :foo, nil do
false
end
e = assert_raises(MockExpectationError) { mock.foo }
exp = "mocked method :foo failed block w/ [] {}"
assert_equal exp, e.message
end
def test_mock_block_raises_if_args_passed
mock = Minitest::Mock.new
e = assert_raises ArgumentError do
mock.expect :foo, nil, [:a, :b, :c] do
true
end
end
exp = "args ignored when block given"
assert_match exp, e.message
end
def test_mock_block_raises_if_kwargs_passed
mock = Minitest::Mock.new
e = assert_raises ArgumentError do
mock.expect :foo, nil, kwargs: 1 do
true
end
end
exp = "kwargs ignored when block given"
assert_match exp, e.message
end
def test_mock_returns_retval_when_called_with_block
mock = Minitest::Mock.new
mock.expect :foo, 32 do
true
end
rs = mock.foo
assert_equal rs, 32
end
def util_verify_bad exp
e = assert_raises MockExpectationError do
@mock.verify
end
assert_equal exp, e.message
end
def test_mock_called_via_send
mock = Minitest::Mock.new
mock.expect :foo, true
mock.send :foo
assert_mock mock
end
def test_mock_called_via___send__
mock = Minitest::Mock.new
mock.expect :foo, true
mock.__send__ :foo
assert_mock mock
end
def test_mock_called_via_send_with_args
mock = Minitest::Mock.new
mock.expect :foo, true, [1, 2, 3]
mock.send :foo, 1, 2, 3
assert_mock mock
end
end
require "minitest/metametameta"
class TestMinitestStub < Minitest::Test
# Do not parallelize since we're calling stub on class methods
def setup
super
Minitest::Test.reset
@tc = Minitest::Test.new "fake tc"
@assertion_count = 1
end
def teardown
super
assert_equal @assertion_count, @tc.assertions if self.passed?
end
class Time
def self.now
24
end
end
def assert_stub val_or_callable
@assertion_count += 1
t = Time.now.to_i
Time.stub :now, val_or_callable do
@tc.assert_equal 42, Time.now
end
@tc.assert_operator Time.now.to_i, :>=, t
end
def test_stub_private_module_method
@assertion_count += 1
t0 = Time.now
self.stub :sleep, nil do
@tc.assert_nil sleep(10)
end
@tc.assert_operator Time.now - t0, :<=, 1
end
def test_stub_private_module_method_indirect
@assertion_count += 1
fail_clapper = Class.new do
def fail_clap
raise
:clap
end
end.new
fail_clapper.stub :raise, nil do |safe_clapper|
@tc.assert_equal :clap, safe_clapper.fail_clap # either form works
@tc.assert_equal :clap, fail_clapper.fail_clap # yay closures
end
end
def test_stub_public_module_method
Math.stub :log10, :stubbed do
@tc.assert_equal :stubbed, Math.log10(1000)
end
end
def test_stub_value__literal
assert_stub 42
end
def test_stub_block
assert_stub lambda { 42 }
end
def test_stub_block_args
@assertion_count += 1
t = Time.now.to_i
Time.stub :now, lambda { |n| n * 2 } do
@tc.assert_equal 42, Time.now(21)
end
@tc.assert_operator Time.now.to_i, :>=, t
end
def test_stub_callable
obj = Object.new
def obj.call
42
end
assert_stub obj
end
def test_stub_yield_self
obj = +"foo"
val = obj.stub :to_s, "bar" do |s|
s.to_s
end
@tc.assert_equal "bar", val
end
def test_dynamic_method
@assertion_count = 2
dynamic = Class.new do
def self.respond_to? meth
meth == :found
end
def self.method_missing meth, *args, &block
if meth == :found
false
else
super
end
end
end
val = dynamic.stub :found, true do |s|
s.found
end
@tc.assert_equal true, val
@tc.assert_equal false, dynamic.found
end
def test_stub_NameError
e = @tc.assert_raises NameError do
Time.stub :nope_nope_nope, 42 do
# do nothing
end
end
exp = if jruby? then
/Undefined method nope_nope_nope for '#{self.class}::Time'/
else
/undefined method [`']nope_nope_nope' for( class)? [`']#{self.class}::Time'/
end
assert_match exp, e.message
end
def test_mock_with_yield
mock = Minitest::Mock.new
mock.expect :write, true do
true
end
rs = nil
File.stub :open, true, mock do
File.open "foo.txt", "r" do |f|
rs = f.write
end
end
@tc.assert_equal true, rs
end
def test_mock_with_yield_kwargs
mock = Minitest::Mock.new
rs = nil
File.stub :open, true, mock, kw: 42 do
File.open "foo.txt", "r" do |f, kw:|
rs = kw
end
end
@tc.assert_equal 42, rs
end
## Permutation Sets:
# [:value, :lambda]
# [:*, :block, :block_call]
# [:**, :block_args]
#
# Where:
#
# :value = a normal value
# :lambda = callable or lambda
# :* = no block
# :block = normal block
# :block_call = :lambda invokes the block (N/A for :value)
# :** = no args
# :args = args passed to stub
## Permutations
# [:call, :*, :**] =>5 callable+block FIX: CALL BOTH (bug)
# [:call, :*, :**] =>6 callable
# [:lambda, :*, :**] => lambda result
# [:lambda, :*, :args] => lambda result NO ARGS
# [:lambda, :block, :**] =>5 lambda result FIX: CALL BOTH (bug)
# [:lambda, :block, :**] =>6 lambda result
# [:lambda, :block, :args] =>5 lambda result FIX: CALL BOTH (bug)
# [:lambda, :block, :args] =>6 lambda result
# [:lambda, :block, :args] =>7 raise ArgumentError
# [:lambda, :block_call, :**] =>5 lambda FIX: BUG!-not passed block to lambda
# [:lambda, :block_call, :**] =>6 lambda+block result
# [:lambda, :block_call, :args] =>5 lambda FIX: BUG!-not passed block to lambda
# [:lambda, :block_call, :args] =>6 lambda+block result
# [:value, :*, :**] => value
# [:value, :*, :args] => value, ignore args
# [:value, :block, :**] =>5 value, call block
# [:value, :block, :**] =>6 value
# [:value, :block, :args] =>5 value, call block w/ args
# [:value, :block, :args] =>6 value, call block w/ args, deprecated
# [:value, :block, :args] =>7 raise ArgumentError
# [:value, :block_call, :**] => N/A
# [:value, :block_call, :args] => N/A
class Bar
def call &_ # to ignore unused block
puts "hi"
end
end
class Foo
def self.blocking
yield
end
end
class Thingy
def self.identity arg
arg
end
end
class Keywords
def self.args req, kw1:, kw2: 24
[req, kw1, kw2]
end
end
def test_stub_callable_keyword_args
Keywords.stub :args, ->(*args, **kws) { [args, kws] } do
@tc.assert_equal [["woot"], { kw1: 42 }], Keywords.args("woot", kw1: 42)
end
end
def test_stub__hash_as_last_real_arg
with_kwargs_env do
token = Object.new
def token.create_with_retry _u, _p; raise "shouldn't see this"; end
controller = Object.new
controller.define_singleton_method :create do |u, p|
token.create_with_retry u, p
end
params = Object.new
def params.to_hash; raise "nah"; end
token.stub(:create_with_retry, ->(u, p) { 42 }) do
act = controller.create :u, params
@tc.assert_equal 42, act
end
end
end
def test_stub_callable_block_5 # from tenderlove
@assertion_count += 1
Foo.stub5 :blocking, Bar.new do
@tc.assert_output "hi\n", "" do
Foo.blocking do
@tc.flunk "shouldn't ever hit this"
end
end
end
end
def test_stub_callable_block_6 # from tenderlove
skip_stub6
@assertion_count += 1
Foo.stub6 :blocking, Bar.new do
@tc.assert_output "hi\n", "" do
Foo.blocking do
@tc.flunk "shouldn't ever hit this"
end
end
end
end
def test_stub_lambda
Thread.stub :new, lambda { 21+21 } do
@tc.assert_equal 42, Thread.new
end
end
def test_stub_lambda_args
Thread.stub :new, lambda { 21+21 }, :wtf do
@tc.assert_equal 42, Thread.new
end
end
def test_stub_lambda_block_5
Thread.stub5 :new, lambda { 21+21 } do
result = Thread.new do
@tc.flunk "shouldn't ever hit this"
end
@tc.assert_equal 42, result
end
end
def test_stub_lambda_block_6
skip_stub6
Thread.stub6 :new, lambda { 21+21 } do
result = Thread.new do
@tc.flunk "shouldn't ever hit this"
end
@tc.assert_equal 42, result
end
end
def test_stub_lambda_block_args_5
@assertion_count += 1
Thingy.stub5 :identity, lambda { |y| @tc.assert_equal :nope, y; 21+21 }, :WTF? do
result = Thingy.identity :nope do |x|
@tc.flunk "shouldn't reach this"
end
@tc.assert_equal 42, result
end
end
def test_stub_lambda_block_args_6
skip_stub6
@assertion_count += 1
Thingy.stub6 :identity, lambda { |y| @tc.assert_equal :nope, y; 21+21 }, :WTF? do
result = Thingy.identity :nope do |x|
@tc.flunk "shouldn't reach this"
end
@tc.assert_equal 42, result
end
end
def test_stub_lambda_block_args_6_2
skip_stub6
@tc.assert_raises ArgumentError do
Thingy.stub6_2 :identity, lambda { |y| :__not_run__ }, :WTF? do
# doesn't matter
end
end
end
def test_stub_lambda_block_call_5
@assertion_count += 1
rs = nil
io = StringIO.new(+"", "w")
File.stub5 :open, lambda { |p, m, &blk| blk and blk.call io } do
File.open "foo.txt", "r" do |f|
rs = f && f.write("woot")
end
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_lambda_block_call_6
skip_stub6
@assertion_count += 1
rs = nil
io = StringIO.new(+"", "w")
File.stub6 :open, lambda { |p, m, &blk| blk.call io } do
File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_lambda_block_call_args_5
@assertion_count += 1
rs = nil
io = StringIO.new(+"", "w")
File.stub5(:open, lambda { |p, m, &blk| blk and blk.call io }, :WTF?) do
File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_lambda_block_call_args_6
skip_stub6
@assertion_count += 1
rs = nil
io = StringIO.new(+"", "w")
File.stub6(:open, lambda { |p, m, &blk| blk.call io }, :WTF?) do
File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_lambda_block_call_args_6_2
skip_stub6
@assertion_count += 2
rs = nil
io = StringIO.new(+"", "w")
@tc.assert_raises ArgumentError do
File.stub6_2(:open, lambda { |p, m, &blk| blk.call io }, :WTF?) do
File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
end
end
@tc.assert_nil rs
@tc.assert_equal "", io.string
end
def test_stub_value
Thread.stub :new, 42 do
result = Thread.new
@tc.assert_equal 42, result
end
end
def test_stub_value_args
Thread.stub :new, 42, :WTF? do
result = Thread.new
@tc.assert_equal 42, result
end
end
def test_stub_value_block_5
@assertion_count += 1
Thread.stub5 :new, 42 do
result = Thread.new do
@tc.assert true
end
@tc.assert_equal 42, result
end
end
def test_stub_value_block_6
skip_stub6
Thread.stub6 :new, 42 do
result = Thread.new do
@tc.flunk "shouldn't hit this"
end
@tc.assert_equal 42, result
end
end
def test_stub_value_block_args_5
@assertion_count += 2
rs = nil
io = StringIO.new(+"", "w")
File.stub5 :open, :value, io do
result = File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
@tc.assert_equal :value, result
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_value_block_args_5__break_if_not_passed
e = @tc.assert_raises NoMethodError do
File.stub5 :open, :return_value do # intentionally bad setup w/ no args
File.open "foo.txt", "r" do |f|
f.write "woot"
end
end
end
exp = /undefined method [`']write' for nil/
assert_match exp, e.message
end
def test_stub_value_block_args_6
skip_stub6
@assertion_count += 2
rs = nil
io = StringIO.new(+"", "w")
assert_deprecated do
File.stub6 :open, :value, io do
result = File.open "foo.txt", "r" do |f|
rs = f.write "woot"
end
@tc.assert_equal :value, result
end
end
@tc.assert_equal 4, rs
@tc.assert_equal "woot", io.string
end
def test_stub_value_block_args_6_2
skip_stub6
@assertion_count += 2
rs = nil
io = StringIO.new(+"", "w")
@tc.assert_raises ArgumentError do
File.stub6_2 :open, :value, io do
result = File.open "foo.txt", "r" do |f|
@tc.flunk "shouldn't hit this"
end
@tc.assert_equal :value, result
end
end
@tc.assert_nil rs
@tc.assert_equal "", io.string
end
def assert_deprecated re = /deprecated/
assert_output "", re do
yield
end
end
def skip_stub6
skip "not yet" unless STUB6
end
end
STUB6 = ENV["STUB6"]
if STUB6 then
require "minitest/mock6" if STUB6
else
class Object
alias stub5 stub
alias stub6 stub
end
end
minitest-5.25.4/checksums.yaml.gz.sig 0000444 0000041 0000041 00000000400 14743220663 017543 0 ustar www-data www-data Akb㢩)8)HsF=2/|db~8x(Khԡ`mF`Bz `8W$G4m0-rp7K8}ҲLN!/:kspD]k/c97^ GHN]js-~LKo=C
y2=OY&&00?NեfW1-|d3R5O+B_)CڡQ#EOLF}&} minitest-5.25.4/Rakefile 0000444 0000041 0000041 00000004546 14743220663 015156 0 ustar www-data www-data # -*- ruby -*-
require "rubygems"
require "hoe"
$:.unshift "lib" # to pick up lib/minitest/test_task.rb when minitest not installed
Hoe.plugin :seattlerb
Hoe.plugin :rdoc
Hoe.spec "minitest" do
developer "Ryan Davis", "ryand-ruby@zenspider.com"
license "MIT"
require_ruby_version [">= 2.6", "< 4.0"]
end
desc "Find missing expectations"
task :specs do
$:.unshift "lib"
require "minitest/test"
require "minitest/spec"
pos_prefix, neg_prefix = "must", "wont"
skip_re = /^(must|wont)$|wont_(throw)|must_(block|not?_|nothing|send|raise$)/x
dont_flip_re = /(must|wont)_(include|respond_to)/
map = {
/(must_throw)s/ => '\1',
/(?!not)_same/ => "_be_same_as",
/_in_/ => "_be_within_",
/_operator/ => "_be",
/_includes/ => "_include",
/(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2',
/must_raises/ => "must_raise",
/(must|wont)_pattern/ => '\1_pattern_match',
/(must|wont)_predicate/ => '\1_be',
/(must|wont)_path_exists/ => 'path_\1_exist',
}
expectations = Minitest::Expectations.public_instance_methods.map(&:to_s)
assertions = Minitest::Assertions.public_instance_methods.map(&:to_s)
assertions.sort.each do |assertion|
expectation = case assertion
when /^assert/ then
assertion.sub(/^assert/, pos_prefix.to_s)
when /^refute/ then
assertion.sub(/^refute/, neg_prefix.to_s)
end
next unless expectation
next if expectation =~ skip_re
regexp, replacement = map.find { |re, _| expectation =~ re }
expectation.sub! regexp, replacement if replacement
next if expectations.include? expectation
args = [assertion, expectation].map(&:to_sym).map(&:inspect)
args << :reverse if expectation =~ dont_flip_re
puts
puts "##"
puts "# :method: #{expectation}"
puts "# See Minitest::Assertions##{assertion}"
puts
puts "infect_an_assertion #{args.join ", "}"
end
end
task :bugs do
sh "for f in bug*.rb ; do echo $f; echo; #{Gem.ruby} -Ilib $f && rm $f ; done"
end
Minitest::TestTask.create :testW0 do |t|
t.warning = false
t.test_prelude = "$-w = nil"
end
# vim: syntax=Ruby
minitest-5.25.4/data.tar.gz.sig 0000444 0000041 0000041 00000000400 14743220663 016313 0 ustar www-data www-data P&7##;BM[(h4jC2J]dgBpvP2̴M [('}P==sVKGi3hvO|y*ۊ'p
]#0WrFJGir)p|X`?W uw䋑kvp3HV/qE;v5\Q5 "~}KcҦ(8
2BiM <* minitest-5.25.4/design_rationale.rb 0000444 0000041 0000041 00000003576 14743220663 017347 0 ustar www-data www-data # Specs: # Equivalent Unit Tests:
###############################################################################
describe Thingy do # class TestThingy < Minitest::Test
before do # def setup
do_some_setup # super
end # do_some_setup
# end
it "should do the first thing" do #
1.must_equal 1 # def test_first_thing
end # assert_equal 1, 1
# end
describe SubThingy do # end
before do #
do_more_setup # class TestSubThingy < TestThingy
end # def setup
# super
it "should do the second thing" do # do_more_setup
2.must_equal 2 # end
end #
end # def test_second_thing
end # assert_equal 2, 2
# end
# end
###############################################################################
# runs 2 specs # runs 3 tests
###############################################################################
# The specs generate:
class ThingySpec < Minitest::Spec
def setup
super
do_some_setup
end
def test_should_do_the_first_thing
assert_equal 1, 1
end
end
class SubThingySpec < ThingySpec
def setup
super
do_more_setup
end
# because only setup/teardown is inherited, not specs
remove_method :test_should_do_the_first_thing
def test_should_do_the_second_thing
assert_equal 2, 2
end
end
minitest-5.25.4/History.rdoc 0000444 0000041 0000041 00000147402 14743220663 016022 0 ustar www-data www-data === 5.25.4 / 2024-12-03
* 1 bug fix:
* Fix for must_verify definition if only requiring minitest/mock (but why?).
=== 5.25.3 / 2024-12-03
* 5 bug fixes:
* Fixed assert_mock to fail instead of raise on unmet mock expectations.
* Fixed assert_mock to take an optional message argument.
* Fixed formatting of unmet mock expectation messages.
* Fixed missing must_verify expectation to match assert_mock.
* minitest/pride: Fixed to use true colors with *-direct terminals (bk2204)
=== 5.25.2 / 2024-11-21
* 4 bug fixes:
* Include class name in spec name. (thomasmarshall)
* Fixed 'redefining object_id' warning from ruby 3.4. (mattbrictson)
* Minitest top-level namespace no longer includes entire contents of README.rdoc. Too much!
* Refactored spec's describe to more cleanly determine the superclass and name
=== 5.25.1 / 2024-08-16
* 2 bug fixes:
* Fix incompatibility caused by minitest-hooks & rails invading minitest internals.
* Revert change from =~ to match? to allow for nil if $TERM undefined.
=== 5.25.0 / 2024-08-13
* 2 minor enhancements:
* Fixed some inefficiencies filtering and matching (mostly backtraces).
* Refactored siginfo handler to reduce runtime costs. Saved ~30%!
* 5 bug fixes:
* Added missing rdoc to get back to 100% coverage.
* Cleaning up ancient code checking for defined?(Encoding) and the like.
* Disambiguated some shadowed variables in minitest/compress.
* Fixed an ironic bug if using string-literals AND Werror.
* Improve description of test:slow task. (stomar)
=== 5.24.1 / 2024-06-29
* 1 bug fix:
* Fix the error message when an extension is invalid value. (y-yagi)
=== 5.24.0 / 2024-06-18
* 2 minor enhancements:
* Added Minitest.register_plugin.
* Extended plugin system to work with modules/classes for opt-out plugins.
* 1 bug fix:
* Removed anacronism, but allow load_plugins to exit gracefully if --disable=gems.
=== 5.23.1 / 2024-05-21
* 1 bug fix:
* Fully qualify the Queue class to avoid conflicts with other libraries. (rafaelfranca)
=== 5.23.0 / 2024-05-15
* 3 minor enhancements:
* Added -Werror to raise on any warning output. (byroot)
* Added UnexpectedWarning as a failure summary type, added count to output if activated.
* Added minitest/manual_plugins.rb w/ new Minitest.load method. (tenderlove)
* 2 bug fixes:
* Allow empty_run! and reporter to display summary for empty runs. (zzak)
* Make test task verbose using either rake's -v or -t (was just -t).
=== 5.22.3 / 2024-03-13
* 1 minor enhancement:
* MASSIVE improvement of minitest's pride plugin output: Frequencies doubled! Sine waves shifted!! Comments improved!!! Colors rotated!!!! (havenwood)
* 3 bug fixes:
* Improved wording on Minitest::Test#parallelize_me! to clarify it goes INSIDE your test class/describe.
* Minor changes to tests to pass when tests ran with extra flags (eg -p).
* Support Ruby 3.4's new error message format. (mame)
=== 5.22.2 / 2024-02-07
* 1 bug fix:
* Third time's a charm? Remember: 'ensure' is almost always the
wrong way to go (for results... it's great for cleaning up).
=== 5.22.1 / 2024-02-06
* 1 bug fix:
* Don't exit non-zero if no tests ran and no filter (aka, the test file is empty).
(I'm starting to think the exit 1 thing for @tenderlove was a mistake...)
=== 5.22.0 / 2024-02-05
* 1 minor enhancement:
* Added "did you mean" output if your --name filter matches nothing. (tenderlove)
* 2 bug fixes:
* Big cleanup of test filtering. Much prettier / more functional.
* Fix situation where Assertion#location can't find the location. (pftg)
=== 5.21.2 / 2024-01-17
* 1 bug fix:
* Fixed bug in Minitest::Compress#compress formatting w/ nested patterns. Now recurses properly.
=== 5.21.1 / 2024-01-11
* 1 bug fix:
* Rails' default backtrace filter can't currently work with caller_locations, so reverting back to caller.
=== 5.21.0 / 2024-01-11
* 10 minor enhancements:
* Add include_all kw arg to assert_respond_to and refute_respond_to.
* Added --quiet flag to skip ProgressReporter (prints the dots). Minor speedup.
* Added Minitest::Compress#compress and added it to UnexpectedError.
* Added ability to initialize BacktraceFilter w/ custom regexp.
* Filter failure backtraces using backtrace_filter before calculating location. (thomasmarshall)
* Make BacktraceFilter#filter compatible with locations (still compares strings).
* Optimized Assertion#location ~30%.
* Output relative paths for all failures/errors/backtraces.
* Refactored location information in assertions, now using locations.
* Removed thread and mutex_m dependencies. (hsbt, eregon)
* 2 bug fixes:
* Drop undocumented bt arg in #skip. Dunno why that ever happened, prolly for testing?
* Fix mock to work with ruby debugger enabled. (keithlayne)
=== 5.20.0 / 2023-09-06
* 1 minor enhancement:
* Optionally allow autorun exit hook to remain active in forked child. (casperisfine)
=== 5.19.0 / 2023-07-26
* 2 minor enhancements:
* Add metadata lazy accessor to Runnable / Result. (matteeyah)
* Only load minitest/unit (aka ancient MiniTest compatibility layer) if \ENV[\"MT_COMPAT\"]
* 1 bug fix:
* Minitest::TestTask enthusiastically added itself to default. (ParadoxV5)
=== 5.18.1 / 2023-06-16
* 3 bug fixes:
* Avoid extra string allocations when filtering tests. (tenderlove)
* Only mention deprecated \ENV[\'N\'] if it is an integer string.
* Push up test_order to Minitest::Runnable to fix minitest/hell. (koic)
=== 5.18.0 / 2023-03-04
* 2 major enhancements:
* Added assert_pattern & refute_pattern for pattern matching. (flavorjones)
* Added matching must_pattern_match & wont_pattern_match to minitest/spec.
* 1 bug fix:
* Support the new message format of NameError in Ruby 3.3 (mame)
=== 5.17.0 / 2022-12-31
* 1 minor enhancement:
* Refactor setup hooks into a SETUP_METHODS constant. (MSP-Greg)
* 3 bug fixes:
* Fix kwargs for Mock calls to delegator. (blowmage)
* Fix kwargs for expectations. (bobmazanec, blowmage)
* Remove check for .b method. (tenderlove)
=== 5.16.3 / 2022-08-17
* 2 bug fixes:
* Fixed exception sanitization by removing TypeError restriction on rescue.
* Use A instead of deprecated TESTOPTS in rake test:slow. (davidstosik)
=== 5.16.2 / 2022-07-03
* 4 bug fixes:
* Added MT_KWARGS_HACK kludge for stub to deal with ruby 2.7 kwargs nastiness. (tsugimoto)
* In #expect, pop Hash class from args if $MT_KWARGS_HACK. (casperisfine)
* In above scenario, set expected kwargs (as Objects) based on actual kwargs.
* Nuke ivars if exception fails to marshal twice (eg better_errors). (irphilli)
=== 5.16.1 / 2022-06-20
* 2 bug fixes:
* Apparently adding real kwarg support to mocks/stubs broke some code. Fixed.
* Use `MT_KWARGS_HACK=1` to activate the kludgy kwargs support w/ caveats.
* Clarified some doco wrt the block on #stub.
=== 5.16.0 / 2022-06-14
* 2 major enhancements:
* Added Minitest::TestTask.
* Dropping ruby 2.2 - 2.5. 2.6 is DTM soon too.
* 11 minor enhancements:
* Added --show-skips option to show skips at end of run but not require --verbose. (MSP-Greg)
* Added Minitest.seed, the random seed used by the run.
* Calling `srand Minitest.seed` before all shuffles to ensure determinism.
* Extended #stub to handle kwargs for both block and call args. (SampsonCrowley)
* Extended Mock#__call to display kwargs.
* Extended Mock#expect to record kwargs.
* Extended Mock#method_missing to take kwargs & compare them against expected.
* Mock#method_missing displays better errors on arity mismatch.
* Removed minor optimization removing empty suites before run.
* Simplified test randomization (test order will change even with fixed seed).
* assert_match now returns the MatchData on success. (Nakilon)
* 3 bug fixes:
* (Re)Fixed marshalling of exceptions, neutering them in 2 passes.
* Fixed more problems with rdoc.
* Had to patch up mock and stub to deal with <=2.7 kwargs oddities
=== 5.15.0 / 2021-12-14
* 1 major enhancement:
* assert_throws returns the value returned, if any. (volmer)
* 3 minor enhancements:
* Added -S option to skip reporting of certain types of output
* Enable Ruby deprecation warnings by default. (casperisfine)
* Use Etc.nprocessors by default in order to maximize cpu usage. (tonytonyjan)
* 6 bug fixes:
* Close then unlink tempfiles on Windows. (nobu)
* Fixed #skip_until for windows paths. (MSP-Greg)
* Fixed a bunch of tests for jruby and windows. (MSP-Greg)
* Fixed marshalling of specs if they error. (tenderlove, jeremyevans, et al)
* Updated deprecation message for block expectations. (blowmage)
* Use Kernel.warn directly in expectations in case CUT defines their own warn. (firien)
=== 5.14.4 / 2021-02-23
* 1 bug fix:
* Fixed deprecation warning using stub with methods using keyword arguments. (Nakilon)
=== 5.14.3 / 2021-01-05
* 1 bug fix:
* Bumped require_ruby_version to < 4 (trunk = 3.1).
=== 5.14.2 / 2020-08-31
* 1 bug fix:
* Bumped ruby version to include 3.0 (trunk).
=== 5.14.1 / 2020-05-15
* 3 minor enhancements:
* Minitest.filter_backtrace returns original backtrace if filter comes back empty.
* Minitest::BacktraceFilter now returns entire backtrace if $MT_DEBUG set in env.
* Return true on a successful refute. (jusleg)
* 1 bug fix:
* Fixed expectation doco to not use global expectations.
=== 5.14.0 / 2020-01-11
* 2 minor enhancements:
* Block-assertions (eg assert_output) now error if raised inside the block. (casperisfine)
* Changed assert_raises to only catch Assertion since that covers Skip and friends.
* 3 bug fixes:
* Added example for value wrapper with block to Expectations module. (stomar)
* Fixed use of must/wont_be_within_delta on Expectation instance. (stomar)
* Renamed UnexpectedError#exception to #error to avoid problems with reraising. (casperisfine)
=== 5.13.0 / 2019-10-29
* 9 minor enhancements:
* Added Minitest::Guard#osx?
* Added examples to documentation for assert_raises. (lxxxvi)
* Added expectations #path_must_exist and #path_wont_exist. Not thrilled with the names.
* Added fail_after(year, month, day, msg) to allow time-bombing after a deadline.
* Added skip_until(year, month, day, msg) to allow deferring until a deadline.
* Deprecated Minitest::Guard#maglev?
* Deprecated Minitest::Guard#rubinius?
* Finally added assert_path_exists and refute_path_exists. (deivid-rodriguez)
* Refactored and pulled Assertions#things_to_diff out of #diff. (BurdetteLamar)
* 3 bug fixes:
* Fix autorun bug that affects fork exit status in tests. (dylanahsmith/jhawthorn)
* Improved documentation for _/value/expect, especially for blocks. (svoop)
* Support new Proc#to_s format. (ko1)
=== 5.12.2 / 2019-09-28
* 1 bug fix:
* After chatting w/ @y-yagi and others, decided to lower support to include ruby 2.2.
=== 5.12.1 / 2019-09-28
* 1 minor enhancement:
* Added documentation for Reporter classes. (sshaw)
* 3 bug fixes:
* Avoid using 'match?' to support older ruby versions. (y-yagi)
* Fixed broken link to reference on goodness-of-fit testing. (havenwood)
* Update requirements in readme and Rakefile/hoe spec.
=== 5.12.0 / 2019-09-22
* 8 minor enhancements:
* Added a descriptive error if assert_output or assert_raises called without a block. (okuramasafumi)
* Changed mu_pp_for_diff to make having both \n and \\n easier to debug.
* Deprecated $N for specifying number of parallel test runners. Use MT_CPU.
* Deprecated use of global expectations. To be removed from MT6.
* Extended Assertions#mu_pp to encoding validity output for strings to improve diffs.
* Extended Assertions#mu_pp to output encoding and validity if invalid to improve diffs.
* Extended Assertions#mu_pp_for_diff to make escaped newlines more obvious in diffs.
* Fail gracefully when expectation used outside of `it`.
* 3 bug fixes:
* Check \option[:filter] klass before match. Fixes 2.6 warning. (y-yagi)
* Fixed Assertions#diff from recalculating if set to nil
* Fixed spec section of readme to not use deprecated global expectations. (CheezItMan)
=== 5.11.3 / 2018-01-26
* 1 bug fix:
* Pushed #error? up to Reportable module. (composerinteralia)
=== 5.11.2 / 2018-01-25
* 1 minor enhancement:
* Reversed Test < Result. Back to < Runnable and using Reportable for shared code.
* 2 bug fixes:
* Fixed Result#location for instances of Test. (alexisbernard)
* Fixed deprecation message for Runnable#marshal_dump. (y-yagi)
=== 5.11.1 / 2018-01-02
* 1 bug fix:
* Fixed Result (a superclass of Test) overriding Runnable's name accessors. (y-yagi, MSP-Greg)
=== 5.11.0 / 2018-01-01
* 2 major enhancements:
* Added Minitest::Result and Minitest::Result.from(runnable).
* Changed Minitest::Test to subclass Result and refactored methods up.
* 7 minor enhancements:
* Added --no-plugins and MT_NO_PLUGINS to bypass MT plugin autoloading. Helps with bad actors installed globally.
* Added bench_performance_{logarithmic,power} for spec-style benchmarks. (rickhull)
* Added deprecation warning for Runnable#marshal_dump.
* Minitest.run_one_method now checks for instance of Result, not exact same class.
* Minitest::Test.run returns a Result version of self, not self.
* ProgressReporter#prerecord now explicitly prints klass.name. Allows for fakers.
* 4 bug fixes:
* Object.stub no longer calls the passed block if stubbed with a callable.
* Object.stub now passes blocks down to the callable result.
* Pushed Minitest::Test#time & #time_it up to Runnable.
* Test nil equality directly in assert_equal. Fixes #679. (voxik)
=== 5.11.0b1 / 2017-12-20
* 2 major enhancements:
* Added Minitest::Result and Minitest::Result.from(runnable).
* Changed Minitest::Test to subclass Result and refactored methods up.
* 6 minor enhancements:
* Added --no-plugins and MT_NO_PLUGINS to bypass MT plugin autoloading. Helps with bad actors installed globally.
* Added bench_performance_{logarithmic,power} for spec-style benchmarks. (rickhull)
* Minitest.run_one_method now checks for instance of Result, not exact same class.
* Minitest::Test.run returns a Result version of self, not self.
* ProgressReporter#prerecord now explicitly prints klass.name. Allows for fakers.
* Removed Runnable.marshal_dump/load.
* 4 bug fixes:
* Object.stub no longer calls the passed block if stubbed with a callable.
* Object.stub now passes blocks down to the callable result.
* Pushed Minitest::Test#time & #time_it up to Runnable.
* Test nil equality directly in assert_equal. Fixes #679. (voxik)
=== 5.10.3 / 2017-07-21
* 1 minor enhancement:
* Extended documentation for Mock#expect for multiple calls to mock object. (insti)
* 2 bug fixes:
* Finished off missing doco.
* Fixed verbose output on parallelize_me! classes. (chanks)
=== 5.10.2 / 2017-05-09
* 1 minor enhancement:
* Added suggestion in minitest/hell to install minitest/proveit.
* 7 bug fixes:
* Expand MT6 to Minitest 6. (xaviershay)
* Fixed location of assert_send deprecation. (rab)
* Fixed location of nil assert_equal deprecation to work with expectations. (jeremyevans)
* Fixed minitest/hell to use parallelize_me! (azul)
* Made deprecation use warn so -W0 will silence it.
* Workaround for rdoc nodoc generation bug that totally f'd up minitest doco. (Paxa)
* Write aggregated_results directly to the IO object to avoid mixed encoding errors. (tenderlove)
=== 5.10.1 / 2016-12-01
* 1 bug fix:
* Added a hack/kludge to deal with missing #prerecord on reporters that aren't properly subclassing AbstractReporter (I'm looking at you minitest-reporters)
=== 5.10.0 / 2016-11-30
* 1 major enhancement:
* Deprecated ruby 1.8, 1.9, possibly 2.0, assert_send, & old MiniTest namespace.
* 3 minor enhancements:
* Warn if assert_equal expects a nil. This will fail in minitest 6+. (tenderlove)
* Added AbstractReporter#prerecord and extended ProgressReporter and CompositeReporter to use it.
* Minor optimization: remove runnables with no runnable methods before run.
* 3 bug fixes:
* Fix assert_throw rescuing any NameError and ArgumentError. (waldyr)
* Clean up (most of the) last remaining vestiges of minitest/unit.
* 2.4: removed deprecation warnings when referring to Fixnum.
=== 5.9.1 / 2016-09-25
* 2 bug fixes:
* Re-release to refresh gem certificate signing. ugh.
* Fixed hoe/minitest to not augment load path if we're actually testing minitest.
=== 5.9.0 / 2016-05-16
* 8 minor enhancements:
* Added Minitest.info_signal accessors to customize signal for test run info. (nate)
* Added assert_mock to make it more clear that you're testing w/ them.
* Added negative filter by test name. (utilum)
* Added warning to README that 1.8 and 1.9 support will be dropped in minitest 6.
* Automatically activate minitest/hell if $MT_HELL is defined.
* Improved default error messages for assert and refute. (bhenderson)
* minitest/hell now tries to require minitest/proveit
* mu_pp for strings prints out non-standard encodings to improve assert_equal diffs.
* 1 bug fix:
* Removed Interrupt from PASSTHROUGH_EXCEPTIONS (already handled). (waldyr)
=== 5.8.5 / 2016-09-25
* 2 bug fixes:
* Re-release to refresh gem certificate signing. ugh.
* Fixed hoe/minitest to not augment load path if we're actually testing minitest.
=== 5.8.4 / 2016-01-21
* 1 bug fix:
* Allow Minitest::Assertion to pass through assert_raises so inner failures are dealt with first.
=== 5.8.3 / 2015-11-17
* 1 minor enhancement:
* Added extra note about mocks and threads to readme. (zamith)
* 1 bug fix:
* Fixed bug in Mock#verify. (pithub/zamith)
=== 5.8.2 / 2015-10-26
* 1 bug fix:
* Fixed using parallelize_me! and capture_io (or any locking io). (arlt/tenderlove)
=== 5.8.1 / 2015-09-23
* 1 minor enhancement:
* Refactor assert_raises to be cleaner and to pass SystemExit and SignalException. (bhenderson)
=== 5.8.0 / 2015-08-06
* 2 minor enhancements:
* Add optional delegation mechanism to extend object with a mock. (zamith)
* Return early if there are no filtered methods. (jeremyevans)
* 1 bug fix:
* Don't extend io with pride if io is not a tty. (toy)
=== 5.7.0 / 2015-05-27
* 1 major enhancement:
* assert_raises now matches subclasses of the expected exception types. (jeremyevans)
* 3 minor enhancements:
* Added :block type for minitest/spec's #infect_an_assertion. (jeremyevans)
* Inline verification error messages in minitest/mock for GC performance. (zamith)
* assert_raises defaults to RuntimeError if not specified. (jeremyevans)
* 4 bug fixes:
* Added 'class' to minitest/mock's overridden_methods list. (zamith)
* Added file/line to infect_an_assertion's class_eval call. (jeremyevans)
* Cleared UnexpectedError's mesg w/ generic string.
* Fixed non-proc-oriented expectations when used on proc target. (jeremyevans)
=== 5.6.1 / 2015-04-27
* 2 bug fixes:
* Added Minitest.clock_time and switched all Time.now to it. (tenderlove)
* Moved Minitest::Expectations#_ into Minitest::Spec::DSL.
=== 5.6.0 / 2015-04-13
* 4 major enhancements:
* Added Minitest::Expectation value monad.
* Added Minitest::Expectations#_ that returns an Expectation. Aliased to value.
* All expectations are added to Minitest::Expectation.
* At some point, the methods on Object will be deprecated and then removed.
* 4 minor enhancements:
* Added a note about bundle exec pitfall in ruby 2.2+. (searls)
* Lazily start the parallel executor. (tenderlove)
* Make mocks more debugger-friendly (edward)
* Print out the current test run on interrupt. (riffraff)
* 3 bug fixes:
* Fix failing test under Windows. (kimhmadsen)
* Record mocked calls before they happen so mocks can raise exceptions easier (tho I'm not a fan). (corecode)
* Tried to clarify mocks vs stubs terminology better. (kkirsche)
=== 5.5.1 / 2015-01-09
* 1 bug fix:
* Fixed doco problems. (zzak)
=== 5.5.0 / 2014-12-12 // mri 2.2.0 (as a real gem)
* 1 minor enhancement:
* Allow seed to be given via ENV for rake test loader sadness: eg rake SEED=42.
=== 5.4.3 / 2014-11-11
* 2 bug fixes:
* Clarified requirements for ruby are now 1.8.7 or better.
* Force encode error output in case mal-encoded exception is raised. (jasonrclark)
=== 5.4.2 / 2014-09-26
* 2 minor enhancements:
* Extract teardown method list.
* Thanks to minitest-gcstats got a 5-10% speedup via reduced GC!
=== 5.4.1 / 2014-08-28
* 1 bug fix:
* Fixed specs hidden by nesting/ordering bug (blowmage/apotonick)
=== 5.4.0 / 2014-07-07
* 2 minor enhancements:
* Kernel#describe extended to splat additional_desc.
* Spec#spec_type extended to take a splat of additional items, passed to matcher procs.
* 1 bug fix:
* minitest/spec should require minitest/test, not minitest/unit. (doudou)
=== 5.3.5 / 2014-06-17
* 1 minor enhancement:
* Spit and polish (mostly spit).
=== 5.3.4 / 2014-05-15
* 1 minor enhancement:
* Test classes are randomized before running. (judofyr)
=== 5.3.3 / 2014-04-14
* 1 bug fix:
* Fixed using expectations w/ DSL in Test class w/o describe. (blowmage+others)
=== 5.3.2 / 2014-04-02
* 1 bug fix:
* Fixed doco on Assertions.assertions. (xaviershay)
=== 5.3.1 / 2014-03-14
* 1 minor enhancement:
* Modified verbage on bad 'let' names to be more helpful. (Archytaus)
* 1 bug fix:
* Fixed 2 cases still using MiniTest. (mikesea)
=== 5.3.0 / 2014-02-25
* 1 minor enhancement:
* Mocked methods can take a block to verify state. Seattle.rb 12 bday present from ernie! Thanks!!
=== 5.2.3 / 2014-02-10
* 1 bug fix:
* Fixed Spec#let check to allow overriding of other lets. (mvz)
=== 5.2.2 / 2014-01-22
* 1 minor enhancement:
* Spec#let raises ArgumentError if you override _any_ instance method (except subject). (rynr)
* 1 bug fix:
* Fixed up benchmark spec doco and added a test to demonstrate. (bhenderson)
=== 5.2.1 / 2014-01-07
* 1 bug fix:
* Properly deal with horrible mix of runtime load errors + other at_exit handlers. (dougo/chqr)
=== 5.2.0 / 2013-12-13
* 1 minor enhancement:
* Change expectations to allow calling most on procs (but not calling the proc). (bhenderson+others)
=== 5.1.0 / 2013-12-05
* 1 minor enhancement:
* Use a Queue for scheduling parallel tests. (tenderlove)
* 1 bug fix:
* Fixed misspelling in doco. (amatsuda)
=== 5.0.8 / 2013-09-20
* 1 bug fix:
* Fixed siginfo handler by rearranging reporters and fixing to_s. (tenderlove)
=== 5.0.7 / 2013-09-05
* 2 minor enhancements:
* Added clarification about the use of thread local variables in expectations. (jemc)
* Added extra message about skipped tests, if any. Disable globally with $MT_NO_SKIP_MSG.
* 2 bug fixes:
* Only require minitest, not minitest/autorun in pride_plugin. (judofyr)
* Require rubygems in load_plugins in case you're not using minitest/autorun.
=== 5.0.6 / 2013-06-28
* 3 minor enhancements:
* Allow stub to pass args to blocks. (swindsor)
* Improved warning message about minitest/autorun to address 1.9's minitest/autorun.
* Made minitest/test require minitest as needed. For lib writers. (erikh)
* 1 bug fix:
* Fixed missing require in minitest/test. (erikh)
=== 4.7.5 / 2013-06-21 // mri 2.1.1
* 2 bug fixes:
* Fix Spec#describe_stack to be thread local.
* Fix multithreaded test failures by defining Time local to mock test namespace
=== 5.0.5 / 2013-06-20
* 6 bug fixes:
* DOH! Fixed the rest of the new casing on Minitest. (splattael)
* Fixed typo on minitest/mock rdoc. (mrgilman/guiceolin)
* Make Spec::DSL.describe_stack thread local to avoid failing on my own tests.
* Make a fake Time.now local to the tests so they won't interfere with real reporter timings.
* Make everything mockable by wrapping all 'special' methods in a smarter wrapper. (bestie)
* Raise ArgumentError if let name starts with 'test'. (johnmaxwell)
=== 5.0.4 / 2013-06-07
* 5 minor enhancements:
* Added AbstractReporter, defining required Reporter API to quack properly.
* Added doco for writing reporters.
* Refactored Reporter into ProgressReporter and SummaryReporter. (idea: phiggins, code:me+scotch)
* Refactored SummaryReporter pushing up to StatisticsReporter. (phiggins)
* Removed Reporter#run_and_report... cleaner, but doesn't "fit" in the API.
=== 5.0.3 / 2013-05-29
* 4 minor enhancements:
* Added Runnable.with_info_handler and Runnable.on_signal.
* Moved io.sync restore to Reporter#run_and_report.
* Refactored inner loop of Reporter#report to #to_s. Callable for status updates.
* Restored MT4's mid-run report (^t). (tenderlove).
=== 5.0.2 / 2013-05-20
* 3 bug fixes:
* Gem.find_files is smarter than I remember... cause I wrote it that way. *sigh* I'm getting old.
* Pride wasn't doing puts through its #io. (tmiller/tenderlove)
* Replaced Runnable#dup and Test#dup with marshal_dump/load. Too many problems cropping up on untested rails code. (tenderlove/rubys)
=== 5.0.1 / 2013-05-14
* 2 bug fixes:
* Documented Assertions' need for @assertions to be defined by the includer.
* Only load one plugin version per name. Tries for latest.
=== 5.0.0 / 2013-05-10
Oh god... here we go...
Minitest 5:
* 4 deaths in the family:
* MiniTest.runner is dead. No more manager objects.
* MiniTest::Unit#record is dead. Use a Reporter instance instead.
* MiniTest::Unit._run_* is dead. Runnable things are responsible for their own runs.
* MiniTest::Unit.output is dead. No more centralized IO.
* 12 major (oft incompatible) changes:
* Renamed MiniTest to Minitest. Your pinkies will thank me. (aliased to MiniTest)
* Removed MiniTest::Unit entirely. No more manager objects.
* Added Minitest::Runnable. Everything minitest can run subclasses this.
* Renamed MiniTest::Unit::TestCase to Minitest::Test (subclassing Runnable).
* Added Minitest::Benchmark.
* Your benchmarks need to move to their own subclass.
* Benchmarks using the spec DSL have to have "Bench" somewhere in their describe.
* MiniTest::Unit.after_tests moved to Minitest.after_run
* MiniTest::Unit.autorun is now Minitest.autorun. Just require minitest/autorun pls.
* Removed ParallelEach#grep since it isn't used anywhere.
* Renamed Runnable#__name__ to Runnable#name (but uses @NAME internally).
* Runnable#run needs to return self. Allows for swapping of results as needed.
* 8 minor moves:
* Moved Assertions module to minitest/assertions.rb
* Moved Expectations module to minitest/expectations.rb
* Moved Test to minitest/test.rb
* Moved everything else in minitest/unit.rb to minitest.rb
* minitest/unit.rb is now just a small (user-test only) compatibility layer.
* Moved most of minitest/pride into minitest/pride_plugin.
* minitest/pride now just activates pride.
* Moved ParallelEach under Minitest.
* 9 additions:
* Added a plugin system that can extend command-line options.
* Added Minitest.extensions.
* Added Minitest.reporter (only available during startup).
* Added Minitest.run(args). This is the very top of any Minitest run.
* Added Minitest::Reporter. Everything minitest can report goes through here.
* Minitest.reporter is a composite so you can add your own.
* Added Minitest::CompositeReporter. Much easier to extend with your own reporters.
* Added UnexpectedError, an Assertion subclass, to wrap up errors.
* Minitest::Test#run is now freakin' beautiful. 47 -> 17 loc
* 11 other:
* Removed Object.infect_with_assertions (it was already dead code).
* Runnables are responsible for knowing their result_code (eg "." or "F").
* Minitest.autorun now returns boolean, not exit code.
* Added FAQ entry for extending via modules. (phiggins)
* Implement Runnable#dup to cleanse state back to test results. Helps with serialization. pair:tenderlove
* Moved ParallelEach under Minitest.
* Runnable#run needs to return self. Allows for swapping of results as needed.
* Minitest.init_plugins passes down options.
* Minitest.load_plugins only loads once.
* Fixed minitest/pride to work with rake test loader again. (tmiller)
* Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb)
* 5 voodoo:
* Removed mutex from minitest.rb (phiggins)
* Removed mutex from test.rb (phiggins)
* Removed Minitest::Reporter.synchronize (phiggins)
* Removed Minitest::Test.synchronize (phiggins)
* Upon loading minitest/parallel_each, record, capture_io and capture_subprocess_io are doped with synchronization code. (phiggins)
=== 4.7.4 / 2013-05-01
This is probably the last release of the 4.x series. It will be merged
to ruby and will be put into maintenance mode there.
I'm not set in stone on this, but at this point further development of
minitest (5+) will be gem-only. It is just too hard to work w/in
ruby-core w/ test-unit compatibility holding minitest development
back.
* 2 minor enhancements:
* Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb)
* Allow disabling of info_signal handler in runner. (erikh)
=== 4.7.3 / 2013-04-20
* 1 bug fix:
* Reverted stubbing of module methods change. Stub the user, not the impl. (ab9/tyabe)
=== 4.7.2 / 2013-04-18
* 2 bug fixes:
* Fixed inconsistency in refute_in_delta/epsilon. I double negatived my logic. (nettsundere)
* Fixed stubbing of module methods (eg Kernel#sleep). (steveklabnik)
=== 4.7.1 / 2013-04-09
* 1 minor enhancement:
* Added FAQ section to README
* 1 bug fix:
* Fixed bug where guard runs tests bypassing minitest/autorun and an ivar isn't set right. (darrencauthon)
=== 4.7.0 / 2013-03-18
* 1 major enhancement:
* Refactored MiniTest::Spec into MiniTest::Spec::DSL.
* 1 bug fix:
* Removed $DEBUG handler that detected when test/unit and minitest were both loaded. (tenderlove)
=== 4.6.2 / 2013-02-27
* 1 minor enhancement:
* Change error output to match Class#method, making it easier to use -n filter.
=== 4.6.1 / 2013-02-14
* 1 bug fix:
* Fixed an option processing bug caused by test/unit's irresponsibly convoluted code. (floehopper)
=== 4.6.0 / 2013-02-07
* 3 major enhancements:
* Removed ::reset_setup_teardown_hooks
* Removed the long deprecated assert_block
* Removed the long deprecated lifecycle hooks: add_(setup|teardown)_hook
* 1 minor enhancement:
* Allow filtering tests by suite name as well as test name. (lazyatom)
* 2 bug fixes:
* Made hex handling (eg object_ids) in mu_pp_for_diff more specific. (maxim)
* nodoc top-level module. (zzak)
=== 4.5.0 / 2013-01-22
* 1 major enhancement:
* Rearranged minitest/unit.rb so NO parallelization code is loaded/used until you opt-in.
* 4 minor enhancements:
* Added TestCase#skipped? for teardown guards
* Added maglev? guard
* Document that record can be sent twice if teardown fails or errors (randycoulman)
* Errors in teardown are now recorded. (randycoulman)
* 3 bug fixes:
* Added hacks and skips to get clean test runs on maglev
* Modified float tests for maglev float output differences. Not sure this is right. Not sure I care.
* Test for existance of diff.exe instead of assuming they have devkit. (blowmage/Cumbayah)
=== 4.4.0 / 2013-01-07
* 3 minor enhancements:
* Added fit_logarithic and assert_performance_logarithmic. (ktheory)
* Merge processed options so others can mess with defaults. (tenderlove)
* TestCase#message can now take another proc to defer custom message cost. (ordinaryzelig/bhenderson)
* 1 bug fix:
* TestCase#passed? now true if test is skipped. (qanhd)
=== 4.3.3 / 2012-12-06
* 1 bug fix:
* Updated information about stubbing. (daviddavis)
=== 4.3.2 / 2012-11-27 // mri 2.0.0
* 1 minor enhancement:
* Improved assert_equals error message to point you at #== of member objects. (kcurtin)
=== 4.3.1 / 2012-11-23
* 1 bug fix:
* Moved test_children to serial testcase to prevent random failures.
=== 4.3.0 / 2012-11-17
* 4 minor enhancements:
* Allow #autorun to run even if loaded with other test libs that call exit. (sunaku)
* Do not include Expectations in Object if $MT_NO_EXPECTATIONS is set (experimental?)
* Gave some much needed love to assert_raises.
* Mock#expect can take a block to custom-validate args. (gmoothart)
=== 4.2.0 / 2012-11-02
* 4 major enhancements:
* Added minitest/hell - run all your tests through the ringer!
* Added support for :parallel test_order to run test cases in parallel.
* Removed last_error and refactored runner code to be threadsafe.
* _run_suites now runs suites in parallel if they opt-in.
* 4 minor enhancements:
* Added TestCase#synchronize
* Added TestCase.make_my_diffs_pretty!
* Added TestCase.parallelize_me!
* Lock on capture_io for thread safety (tenderlove)
=== 4.1.0 / 2012-10-05
* 2 minor enhancements:
* Added skip example to readme. (dissolved)
* Extracted backtrace filter to object. (tenderlove)
* 1 bug fix:
* OMG I'm so dumb. Fixed access to deprecated hook class methods. I hate ruby modules. (route)
=== 4.0.0 / 2012-09-28
* 1 major enhancement:
* The names of a privately-used undocumented constants are Super Important™.
* 1 minor enhancement:
* Support stubbing methods that would be handled via method_missing. (jhsu)
* 3 bug fixes:
* Add include_private param to MiniTest::Mock#respond_to? (rf-)
* Fixed use of minitest/pride with --help. (zw963)
* Made 'No visible difference.' message more clear. (ckrailo)
=== 3.5.0 / 2012-09-21
* 1 minor enhancement:
* Added #capture_subprocess_io. (route)
=== 3.4.0 / 2012-09-05
* 2 minor enhancements:
* assert_output can now take regexps for expected values. (suggested by stomar)
* Clarified that ruby 1.9/2.0's phony gems cause serious confusion for rubygems.
=== 3.3.0 / 2012-07-26
* 1 major enhancement:
* Deprecated add_(setup|teardown)_hook in favor of (before|after)_(setup|teardown) [2013-01-01]
* 4 minor enhancements:
* Refactored deprecated hook system into a module.
* Refactored lifecycle hooks into a module.
* Removed after_setup/before_teardown + run_X_hooks from Spec.
* Spec#before/after now do a simple define_method and call super. DUR.
* 2 bug fixes:
* Fixed #passed? when used against a test that called flunk. (floehopper)
* Fixed rdoc bug preventing doco for some expectations. (stomar).
=== 3.2.0 / 2012-06-26
* 1 minor enhancement:
* Stubs now yield self. (peterhellberg)
* 1 bug fix:
* Fixed verbose test that only fails when run in verbose mode. mmmm irony.
=== 3.1.0 / 2012-06-13
* 2 minor enhancements:
* Removed LONG deprecated Unit.out accessor
* Removed generated method name munging from minitest/spec. (ordinaryzelig/tenderlove)
=== 3.0.1 / 2012-05-24
* 1 bug fix:
* I'm a dumbass and refactored into Mock#call. Renamed to #__call so you can mock #call. (mschuerig)
=== 3.0.0 / 2012-05-08
* 3 major enhancements:
* Added Object#stub (in minitest/mock.rb).
* Mock#expect mocks are used in the order they're given.
* Mock#verify now strictly compares against expect calls.
* 3 minor enhancements:
* Added caller to deprecation message.
* Mock error messages are much prettier.
* Removed String check for RHS of assert/refute_match. This lets #to_str work properly.
* 1 bug fix:
* Support drive letter on Windows. Patch provided from MRI by Usaku NAKAMURA. (ayumin)
=== 2.12.1 / 2012-04-10
* 1 minor enhancement:
* Added ruby releases to History.txt to make it easier to see what you're missing
* 1 bug fix:
* Rolled my own deprecate msg to allow MT to work with rubygems < 1.7
=== 2.12.0 / 2012-04-03
* 4 minor enhancements:
* ::it returns test method name (wojtekmach)
* Added #record method to runner so runner subclasses can cleanly gather data.
* Added Minitest alias for MiniTest because even I forget.
* Deprecated assert_block!! Yay!!!
* 1 bug fix:
* Fixed warning in i_suck_and_my_tests_are_order_dependent! (phiggins)
=== 2.11.4 / 2012-03-20
* 2 minor enhancements:
* Updated known extensions
* You got your unicode in my tests! You got your tests in my unicode! (fl00r)
* 1 bug fix:
* Fixed MiniTest::Mock example in the readme. (conradwt)
=== 2.11.3 / 2012-02-29
* 2 bug fixes:
* Clarified that assert_raises returns the exception for further testing
* Fixed assert_in_epsilon when both args are negative. (tamc)
=== 2.11.2 / 2012-02-14
* 1 minor enhancement:
* Display failures/errors on SIGINFO. (tenderlove)
* 1 bug fix:
* Fixed MiniTest::Unit.after_tests for Ruby 1.9.3. (ysbaddaden)
=== 2.11.1 / 2012-02-01
* 3 bug fixes:
* Improved description for --name argument. (drd)
* Ensure Mock#expect's expected args is an Array. (mperham)
* Ensure Mock#verify verifies multiple expects of the same method. (chastell)
=== 2.11.0 / 2012-01-25
* 2 minor enhancements:
* Added before / after hooks for setup and teardown. (tenderlove)
* Pushed run_setup_hooks down to Spec. (tenderlove)
=== 2.10.1 / 2012-01-17
* 1 bug fix:
* Fixed stupid 1.9 path handling grumble grumble. (graaff)
=== 2.10.0 / 2011-12-20
* 3 minor enhancements:
* Added specs for must/wont be_empty/respond_to/be_kind_of and others.
* Added tests for assert/refute predicate.
* Split minitest/excludes.rb out to its own gem.
* 1 bug fix:
* Fixed must_be_empty and wont_be_empty argument handling. (mrsimo)
=== 2.9.1 / 2011-12-13
* 4 minor enhancements:
* Added a ton of tests on spec error message output.
* Cleaned up consistency of msg handling on unary expectations.
* Improved error messages on assert/refute_in_delta.
* infect_an_assertion no longer checks arity and better handles args.
* 1 bug fix:
* Fixed error message on specs when 2+ args and custom message provided. (chastell)
=== 2.9.0 / 2011-12-07
* 4 minor enhancements:
* Added TestCase.exclude and load_excludes for programmatic filtering of tests.
* Added guard methods so you can cleanly skip based on platform/impl
* Holy crap! 100% doco! `rdoc -C` ftw
* Switch assert_output to test stderr before stdout to possibly improve debugging
=== 2.8.1 / 2011-11-17
* 1 bug fix:
* Ugh. 1.9's test/unit violates my internals. Added const_missing.
=== 2.8.0 / 2011-11-08
* 2 minor enhancements:
* Add a method so that code can be run around a particular test case (tenderlove)
* Turn off backtrace filtering if we're running inside a ruby checkout. (drbrain)
* 2 bug fixes:
* Fixed 2 typos and 2 doc glitches. (splattael)
* Remove unused block arguments to avoid creating Proc objects. (k-tsj)
=== 2.7.0 / 2011-10-25
* 2 minor enhancements:
* Include failed values in the expected arg output in MockExpectationError. (nono)
* Make minitest/pride work with other 256 color capable terms. (sunaku)
* 2 bug fixes:
* Clarified the documentation of minitest/benchmark (eregon)
* Fixed using expectations in regular unit tests. (sunaku)
=== 2.6.2 / 2011-10-19
* 1 minor enhancement:
* Added link to vim bundle. (sunaku)
* 2 bug fixes:
* Force gem activation in hoe minitest plugin
* Support RUBY_VERSION='2.0.0' (nagachika)
=== 2.6.1 / 2011-09-27
* 2 bug fixes:
* Alias Spec.name from Spec.to_s so it works when @name is nil (nathany)
* Fixed assert and refute_operator where second object has a bad == method.
=== 2.6.0 / 2011-09-13
* 2 minor enhancements:
* Added specify alias for it and made desc optional.
* Spec#must_be and #wont_be can be used with predicates (metaskills)
* 1 bug fix:
* Fixed Mock.respond_to?(var) to work with strings. (holli)
=== 2.5.1 / 2011-08-27 // ruby 1.9.3: p0, p125, p34579
* 2 minor enhancements:
* Added gem activation for minitest in minitest/autoload to help out 1.9 users
* Extended Spec.register_spec_type to allow for procs instead of just regexps.
=== 2.5.0 / 2011-08-18
* 4 minor enhancements:
* Added 2 more arguments against rspec: let & subject in 9 loc! (emmanuel/luis)
* Added TestCase.i_suck_and_my_tests_are_order_dependent!
* Extended describe to take an optional method name (2 line change!). (emmanuel)
* Refactored and extended minitest/pride to do full 256 color support. (lolcat)
* 1 bug fix:
* Doc fixes. (chastell)
=== 2.4.0 / 2011-08-09
* 4 minor enhancements:
* Added simple examples for all expectations.
* Improved Mock error output when args mismatch.
* Moved all expectations from Object to MiniTest::Expectations.
* infect_with_assertions has been removed due to excessive clever
* 4 bug fixes:
* Fix Assertions#mu_pp to deal with immutable encoded strings. (ferrous26)
* Fix minitest/pride for MacRuby (ferrous26)
* Made error output less fancy so it is more readable
* Mock shouldn't undef === and inspect. (dgraham)
=== 2.3.1 / 2011-06-22
* 1 bug fix:
* Fixed minitest hoe plugin to be a spermy dep and not depend on itself.
=== 2.3.0 / 2011-06-15
* 5 minor enhancements:
* Add setup and teardown hooks to MiniTest::TestCase. (phiggins)
* Added nicer error messages for MiniTest::Mock. (phiggins)
* Allow for less specific expected arguments in Mock. (bhenderson/phiggins)
* Made MiniTest::Mock a blank slate. (phiggins)
* Refactored minitest/spec to use the hooks instead of define_inheritable_method. (phiggins)
* 2 bug fixes:
* Fixed TestCase's inherited hook. (dchelimsky/phiggins/jamis, the 'good' neighbor)
* MiniTest::Assertions#refute_empty should use mu_pp in the default message. (whatthejeff)
=== 2.2.2 / 2011-06-01
* 2 bug fixes:
* Got rid of the trailing period in message for assert_equal. (tenderlove)
* Windows needs more flushing. (Akio Tajima)
=== 2.2.1 / 2011-05-31
* 1 bug fix:
* My _ONE_ non-rubygems-using minitest user goes to Seattle.rb!
=== 2.2.0 / 2011-05-29
* 6 minor enhancements:
* assert_equal (and must_equal) now tries to diff output where it makes sense.
* Added Assertions#diff(exp, act) to be used by assert_equal.
* Added Assertions#mu_pp_for_diff
* Added Assertions.diff and diff=
* Moved minitest hoe-plugin from hoe-seattlerb. (erikh)
* Skipped tests only output details in verbose mode. (tenderlove+zenspider=xoxo)
=== 2.1.0 / 2011-04-11
* 5 minor enhancements:
* Added MiniTest::Spec.register_spec_type(matcher, klass) and spec_type(desc)
* Added ability for specs to share code via subclassing of Spec. (metaskills)
* Clarified (or tried to) bench_performance_linear's use of threshold.
* MiniTest::Unit.runner=(runner) provides an easy way of creating custom test runners for specialized needs. (justinweiss)
* Reverse order of inheritance in teardowns of specs. (deepfryed)
* 3 bug fixes:
* FINALLY fixed problems of inheriting specs in describe/it/describe scenario. (MGPalmer)
* Fixed a new warning in 1.9.3.
* Fixed assert_block's message handling. (nobu)
=== 2.0.2 / 2010-12-24
* 1 minor enhancement:
* Completed doco on minitest/benchmark for specs.
* 1 bug fix:
* Benchmarks in specs that didn't call bench_range would die. (zzak).
=== 2.0.1 / 2010-12-15
* 4 minor enhancements:
* Do not filter backtrace if $DEBUG
* Exit autorun via nested at_exit handler, in case other libs call exit
* Make options accesor lazy.
* Split printing of test name and its time. (nurse)
* 1 bug fix:
* Fix bug when ^T is hit before runner start
=== 2.0.0 / 2010-11-11
* 3 major enhancements:
* Added minitest/benchmark! Assert your performance! YAY!
* Refactored runner to allow for more extensibility. See minitest/benchmark.
* This makes the runner backwards incompatible in some ways!
* 9 minor enhancements:
* Added MiniTest::Unit.after_tests { ... }
* Improved output by adding test rates and a more sortable verbose format
* Improved readme based on feedback from others
* Added io method to TestCase. If used, it'll supplant '.EF' output.
* Refactored IO in MiniTest::Unit.
* Refactored _run_anything to _run_suite to make it easier to wrap (ngauthier)
* Spec class names are now the unmunged descriptions (btakita)
* YAY for not having redundant rdoc/readmes!
* Help output is now generated from the flags you passed straight up.
* 4 bug fixes:
* Fixed scoping issue on minitest/mock (srbaker/prosperity)
* Fixed some of the assertion default messages
* Fixes autorun when on windows with ruby install on different drive (larsch)
* Fixed rdoc output bug in spec.rb
=== 1.7.2 / 2010-09-23
* 3 bug fixes:
* Fixed doco for expectations and Spec.
* Fixed test_capture_io on 1.9.3+ (sora_h)
* assert_raises now lets MiniTest::Skip through. (shyouhei)
=== 1.7.1 / 2010-09-01
* 1 bug fix:
* 1.9.2 fixes for spec tests
=== 1.7.0 / 2010-07-15
* 5 minor enhancements:
* Added assert_output (mapped to must_output).
* Added assert_silent (mapped to must_be_silent).
* Added examples to readme (Mike Dalessio)
* Added options output at the top of the run, for fatal run debugging (tenderlove)
* Spec's describe method returns created class
=== 1.6.0 / 2010-03-27 // ruby 1.9.2-p290
* 10 minor enhancements:
* Added --seed argument so you can reproduce a random order for debugging.
* Added documentation for assertions
* Added more rdoc and tons of :nodoc:
* Added output to give you all the options you need to reproduce that run.
* Added proper argument parsing to minitest.
* Added unique serial # to spec names so order can be preserved (needs tests). (phrogz)
* Empty 'it' fails with default msg. (phrogz)
* Remove previous method on expect to remove 1.9 warnings
* Spec#it is now order-proof wrt subclasses/nested describes.
* assert_same error message now reports in decimal, eg: oid=123. (mattkent)
* 2 bug fixes:
* Fixed message on refute_same to be consistent with assert_same.
* Fixed method randomization to be stable for testing.
=== 1.5.0 / 2010-01-06
* 4 minor enhancements:
* Added ability to specify what assertions should have their args flipped.
* Don't flip arguments on *include and *respond_to assertions.
* Refactored Module.infect_an_assertion from Module.infect_with_assertions.
* before/after :all now bitches and acts like :each
* 3 bug fixes:
* Nested describes now map to nested test classes to avoid namespace collision.
* Using undef_method instead of remove_method to clean out inherited specs.
* assert_raises was ignoring passed in message.
=== 1.4.2 / 2009-06-25
* 1 bug fix:
* Fixed info handler for systems that don't have siginfo.
=== 1.4.1 / 2009-06-23
* 1 major enhancement:
* Handle ^C and other fatal exceptions by failing
* 1 minor enhancement:
* Added something to catch mixed use of test/unit and minitest if $DEBUG
* 1 bug fix:
* Added SIGINFO handler for finding slow tests without verbose
=== 1.4.0 / 2009-06-18
* 5 minor enhancement:
* Added clarification doco.
* Added specs and mocks to autorun.
* Changed spec test class creation to be non-destructive.
* Updated rakefile for new hoe capabilities.
* describes are nestable (via subclass). before/after/def inherits, specs don't.
* 3 bug fixes:
* Fixed location on must/wont.
* Switched to __name__ to avoid common ivar name.
* Fixed indentation in test file (1.9).
=== 1.3.1 / 2009-01-20 // ruby 1.9.1-p431
* 1 minor enhancement:
* Added miniunit/autorun.rb as replacement for test/unit.rb's autorun.
* 16 bug fixes:
* 1.9 test fixes.
* Bug fixes from nobu and akira for really odd scenarios. They run ruby funny.
* Fixed (assert|refute)_match's argument order.
* Fixed LocalJumpError in autorun if exception thrown before at_exit.
* Fixed assert_in_delta (should be >=, not >).
* Fixed assert_raises to match Modules.
* Fixed capture_io to not dup IOs.
* Fixed indentation of capture_io for ruby 1.9 warning.
* Fixed location to deal better with custom assertions and load paths. (Yuki)
* Fixed order of (must|wont)_include in MiniTest::Spec.
* Fixed skip's backtrace.
* Got arg order wrong in *_match in tests, message wrong as a result.
* Made describe private. For some reason I thought that an attribute of Kernel.
* Removed disable_autorun method, added autorun.rb instead.
* assert_match escapes if passed string for pattern.
* instance_of? is different from ===, use instance_of.
=== 1.3.0 / 2008-10-09
* 2 major enhancements:
* renamed to minitest and pulled out test/unit compatibility.
* mini/test.rb is now minitest/unit.rb, everything else maps directly.
* 12 minor enhancements:
* assert_match now checks that act can call =~ and converts exp to a
regexp only if needed.
* Added assert_send... seems useless to me tho.
* message now forces to string... ruby-core likes to pass classes and arrays :(
* Added -v handling and switched to @verbose from $DEBUG.
* Verbose output now includes test class name and adds a sortable running time!
* Switched message generation into procs for message deferment.
* Added skip and renamed fail to flunk.
* Improved output failure messages for assert_instance_of, assert_kind_of
* Improved output for assert_respond_to, assert_same.
* at_exit now exits false instead of errors+failures.
* Made the tests happier and more readable imhfo.
* Switched index(s) == 0 to rindex(s, 0) on nobu's suggestion. Faster.
* 5 bug fixes:
* 1.9: Added encoding normalization in mu_pp.
* 1.9: Fixed backtrace filtering (BTs are expanded now)
* Added back exception_details to assert_raises. DOH.
* Fixed shadowed variable in mock.rb
* Fixed stupid muscle memory message bug in assert_send.
=== 1.2.1 / 2008-06-10
* 7 minor enhancements:
* Added deprecations everywhere in test/unit.
* Added test_order to TestCase. :random on mini, :sorted on test/unit (for now).
* Big cleanup in test/unit for rails. Thanks Jeremy Kemper!
* Minor readability cleanup.
* Pushed setup/run/teardown down to testcase allowing specialized testcases.
* Removed pp. Tests run 2x faster. :/
* Renamed deprecation methods and moved to test/unit/deprecate.rb.
=== 1.2.0 / 2008-06-09
* 2 major enhancements:
* Added Mini::Spec.
* Added Mini::Mock. Thanks Steven Baker!!
* 23 minor enhancements:
* Added bin/use_miniunit to make it easy to test out miniunit.
* Added -n filtering, thanks to Phil Hagelberg!
* Added args argument to #run, takes ARGV from at_exit.
* Added test name output if $DEBUG.
* Added a refute (was deny) for every assert.
* Added capture_io and a bunch of nice assertions from zentest.
* Added deprecation mechanism for assert_no/not methods to test/unit/assertions.
* Added pp output when available.
* Added tests for all assertions. Pretty much maxed out coverage.
* Added tests to verify consistency and good naming.
* Aliased and deprecated all ugly assertions.
* Cleaned out test/unit. Moved autorun there.
* Code cleanup to make extensions easier. Thanks Chad!
* Got spec args reversed in all but a couple assertions. Much more readable.
* Improved error messages across the board. Adds your message to the default.
* Moved into Mini namespace, renamed to Mini::Test and Mini::Spec.
* Pulled the assertions into their own module...
* Removed as much code as I could while still maintaining full functionality.
* Moved filter_backtrace into MiniTest.
* Removed MiniTest::Unit::run. Unnecessary.
* Removed location_of_failure. Unnecessary.
* Rewrote test/unit's filter_backtrace. Flog from 37.0 to 18.1
* Removed assert_send. Google says it is never used.
* Renamed MiniTest::Unit.autotest to #run.
* Renamed deny to refute.
* Rewrote some ugly/confusing default assertion messages.
* assert_in_delta now defaults to 0.001 precision. Makes specs prettier.
* 9 bug fixes:
* Fixed assert_raises to raise outside of the inner-begin/rescue.
* Fixed for ruby 1.9 and rubinius.
* No longer exits 0 if exception in code PRE-test run causes early exit.
* Removed implementors method list from mini/test.rb - too stale.
* assert_nothing_raised takes a class as an arg. wtf? STUPID
* ".EF" output is now unbuffered.
* Bunch of changes to get working with rails... UGH.
* Added stupid hacks to deal with rails not requiring their dependencies.
* Now bitch loudly if someone defines one of my classes instead of requiring.
* Fixed infect method to work better on 1.9.
* Fixed all shadowed variable warnings in 1.9.
=== 1.1.0 / 2007-11-08
* 4 major enhancements:
* Finished writing all missing assertions.
* Output matches original test/unit.
* Documented every method needed by language implementor.
* Fully switched over to self-testing setup.
* 2 minor enhancements:
* Added deny (assert ! test), our favorite extension to test/unit.
* Added .autotest and fairly complete unit tests. (thanks Chad for help here)
=== 1.0.0 / 2006-10-30
* 1 major enhancement
* Birthday!
minitest-5.25.4/metadata.gz.sig 0000444 0000041 0000041 00000000400 14743220663 016375 0 ustar www-data www-data k8eO4eT~ab]nR{$g > f"'>sΏx7`U*(1
HgT8olt sm뵣Mٱ^' JwY9`IW'=|ڦKzoLT/*q6!+kzUz:oc)g)K<_D ᭻q߯6YL:ܒL;Xw)iϱ*ŸGNa minitest-5.25.4/minitest.gemspec 0000644 0000041 0000041 00000014045 14743220663 016707 0 ustar www-data www-data #########################################################
# This file has been automatically generated by gem2tgz #
#########################################################
# -*- encoding: utf-8 -*-
# stub: minitest 5.25.4 ruby lib
Gem::Specification.new do |s|
s.name = "minitest".freeze
s.version = "5.25.4"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "bug_tracker_uri" => "https://github.com/minitest/minitest/issues", "changelog_uri" => "https://github.com/minitest/minitest/blob/master/History.rdoc", "homepage_uri" => "https://github.com/minitest/minitest" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Ryan Davis".freeze]
s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDPjCCAiagAwIBAgIBCDANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu\nZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB\nGRYDY29tMB4XDTI0MDEwMjIxMjEyM1oXDTI1MDEwMTIxMjEyM1owRTETMBEGA1UE\nAwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS\nJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda\nb9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx\ntaCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT\noOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh\nGiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt\nqhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV\ngBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBCwUAA4IB\nAQCygvpmncmkiSs9r/Kceo4bBPDszhTv6iBi4LwMReqnFrpNLMOWJw7xi8x+3eL2\nXS09ZPNOt2zm70KmFouBMgOysnDY4k2dE8uF6B8JbZOO8QfalW+CoNBliefOTcn2\nbg5IOP7UoGM5lC174/cbDJrJnRG9bzig5FAP0mvsgA8zgTRXQzIUAZEo92D5K7p4\nB4/O998ho6BSOgYBI9Yk1ttdCtti6Y+8N9+fZESsjtWMykA+WXWeGUScHqiU+gH8\nS7043fq9EbQdBr2AXdj92+CDwuTfHI6/Hj5FVBDULufrJaan4xUgL70Hvc6pTTeW\ndeKfBjgVAq7EYHu1AczzlUly\n-----END CERTIFICATE-----\n".freeze]
s.date = "2024-12-04"
s.description = "minitest provides a complete suite of testing facilities supporting\nTDD, BDD, mocking, and benchmarking.\n\n \"I had a class with Jim Weirich on testing last week and we were\n allowed to choose our testing frameworks. Kirk Haines and I were\n paired up and we cracked open the code for a few test\n frameworks...\n\n I MUST say that minitest is *very* readable / understandable\n compared to the 'other two' options we looked at. Nicely done and\n thank you for helping us keep our mental sanity.\"\n\n -- Wayne E. Seguin\n\nminitest/test is a small and incredibly fast unit testing framework.\nIt provides a rich set of assertions to make your tests clean and\nreadable.\n\nminitest/spec is a functionally complete spec engine. It hooks onto\nminitest/test and seamlessly bridges test assertions over to spec\nexpectations.\n\nminitest/benchmark is an awesome way to assert the performance of your\nalgorithms in a repeatable manner. Now you can assert that your newb\nco-worker doesn't replace your linear algorithm with an exponential\none!\n\nminitest/mock by Steven Baker, is a beautifully tiny mock (and stub)\nobject framework.\n\nminitest/pride shows pride in testing and adds coloring to your test\noutput. I guess it is an example of how to write IO pipes too. :P\n\nminitest/test is meant to have a clean implementation for language\nimplementors that need a minimal set of methods to bootstrap a working\ntest suite. For example, there is no magic involved for test-case\ndiscovery.\n\n \"Again, I can't praise enough the idea of a testing/specing\n framework that I can actually read in full in one sitting!\"\n\n -- Piotr Szotkowski\n\nComparing to rspec:\n\n rspec is a testing DSL. minitest is ruby.\n\n -- Adam Hawkins, \"Bow Before MiniTest\"\n\nminitest doesn't reinvent anything that ruby already provides, like:\nclasses, modules, inheritance, methods. This means you only have to\nlearn ruby to use minitest and all of your regular OO practices like\nextract-method refactorings still apply.".freeze
s.email = ["ryand-ruby@zenspider.com".freeze]
s.extra_rdoc_files = ["History.rdoc".freeze, "Manifest.txt".freeze, "README.rdoc".freeze]
s.files = [".autotest".freeze, "History.rdoc".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "design_rationale.rb".freeze, "lib/hoe/minitest.rb".freeze, "lib/minitest.rb".freeze, "lib/minitest/assertions.rb".freeze, "lib/minitest/autorun.rb".freeze, "lib/minitest/benchmark.rb".freeze, "lib/minitest/compress.rb".freeze, "lib/minitest/error_on_warning.rb".freeze, "lib/minitest/expectations.rb".freeze, "lib/minitest/hell.rb".freeze, "lib/minitest/manual_plugins.rb".freeze, "lib/minitest/mock.rb".freeze, "lib/minitest/parallel.rb".freeze, "lib/minitest/pride.rb".freeze, "lib/minitest/pride_plugin.rb".freeze, "lib/minitest/spec.rb".freeze, "lib/minitest/test.rb".freeze, "lib/minitest/test_task.rb".freeze, "lib/minitest/unit.rb".freeze, "test/minitest/metametameta.rb".freeze, "test/minitest/test_minitest_assertions.rb".freeze, "test/minitest/test_minitest_benchmark.rb".freeze, "test/minitest/test_minitest_mock.rb".freeze, "test/minitest/test_minitest_reporter.rb".freeze, "test/minitest/test_minitest_spec.rb".freeze, "test/minitest/test_minitest_test.rb".freeze, "test/minitest/test_minitest_test_task.rb".freeze]
s.homepage = "https://github.com/minitest/minitest".freeze
s.licenses = ["MIT".freeze]
s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]
s.required_ruby_version = Gem::Requirement.new([">= 2.6".freeze, "< 4.0".freeze])
s.rubygems_version = "3.3.15".freeze
s.summary = "minitest provides a complete suite of testing facilities supporting TDD, BDD, mocking, and benchmarking".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
end
if s.respond_to? :add_runtime_dependency then
s.add_development_dependency(%q.freeze, ["~> 4.2"])
s.add_development_dependency(%q.freeze, [">= 4.0", "< 7"])
else
s.add_dependency(%q.freeze, ["~> 4.2"])
s.add_dependency(%q.freeze, [">= 4.0", "< 7"])
end
end