minitest-5.22.3/ 0000755 0000041 0000041 00000000000 14577531334 013503 5 ustar www-data www-data minitest-5.22.3/Manifest.txt 0000444 0000041 0000041 00000001361 14577531334 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/expectations.rb
lib/minitest/hell.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.22.3/.autotest 0000444 0000041 0000041 00000002123 14577531334 015350 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.22.3/README.rdoc 0000444 0000041 0000041 00000075453 14577531334 015325 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 fairly 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 2023-03-05)
Current versions of rails: (https://endoflife.date/rails)
| rails | min ruby | rec ruby | minitest | status | EOL Date |
|-------+----------+----------+----------+----------+------------|
| 7.0 | >= 2.7 | 3.1 | >= 5.1 | Current | 2025-06-01?|
| 6.1 | >= 2.5 | 3.0 | >= 5.1 | Maint | 2024-06-01?|
| 6.0 | >= 2.5 | 2.6 | >= 5.1 | Security | 2023-06-01 |
| 5.2 | >= 2.2.2 | 2.5 | ~> 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.2 | Current | 2026-03-31 |
| 3.1 | Maint | 2025-03-31 |
| 3.0 | Maint | 2024-03-31 |
| 2.7 | Security| 2023-03-31 |
| 2.6 | EOL | 2022-03-31 |
| 2.5 | EOL | 2021-03-31 |
=== 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.22.3/lib/ 0000755 0000041 0000041 00000000000 14577531334 014251 5 ustar www-data www-data minitest-5.22.3/lib/hoe/ 0000755 0000041 0000041 00000000000 14577531334 015024 5 ustar www-data www-data minitest-5.22.3/lib/hoe/minitest.rb 0000444 0000041 0000041 00000001030 14577531334 017175 0 ustar www-data www-data # :stopdoc:
class Hoe
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.22.3/lib/minitest/ 0000755 0000041 0000041 00000000000 14577531334 016105 5 ustar www-data www-data minitest-5.22.3/lib/minitest/hell.rb 0000444 0000041 0000041 00000000313 14577531334 017351 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.22.3/lib/minitest/unit.rb 0000444 0000041 0000041 00000002372 14577531334 017413 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.22.3/lib/minitest/parallel.rb 0000444 0000041 0000041 00000003107 14577531334 020225 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 = Queue.new
@pool = nil
end
##
# Start the executor
def start
@pool = size.times.map {
Thread.new(@queue) do |queue|
Thread.current.abort_on_exception = true
while (job = queue.pop)
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.22.3/lib/minitest/expectations.rb 0000444 0000041 0000041 00000015331 14577531334 021141 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.22.3/lib/minitest/pride_plugin.rb 0000444 0000041 0000041 00000005752 14577531334 021122 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:
if PrideIO.pride? then
klass = ENV["TERM"] =~ /^xterm|-256color$/ ? 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
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 "." then
io.print pride o
when "E", "F" then
io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
when "S" then
io.print pride o
else
io.print o
end
end
def puts *o # :nodoc:
o.map! { |s|
s.to_s.sub(/Finished/) {
@index = 0
"Fabulous run".split(//).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 = (6 * 7).times.map { |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.22.3/lib/minitest/mock.rb 0000444 0000041 0000041 00000024031 14577531334 017361 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|
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
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 block_given?
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.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)
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.map { |ak, av| [ak, Object] }.to_h 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.map { |ek, ev|
av = kwargs[ek]
[ek, [ev, av]]
}.to_h
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.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
}
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.
def assert_mock mock
assert mock.verify
end
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.22.3/lib/minitest/spec.rb 0000444 0000041 0000041 00000022445 14577531334 017371 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
name = [stack.last, desc, *additional_desc].compact.join("::")
sclas = stack.last || if Class === self && kind_of?(Minitest::Spec::DSL) then
self
else
Minitest::Spec.spec_type desc, *additional_desc
end
cls = sclas.create name, 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 =~ /\Atest/
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.22.3/lib/minitest/test.rb 0000444 0000041 0000041 00000014505 14577531334 017414 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
with_info_handler do
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
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
def with_info_handler &block # :nodoc:
t0 = Minitest.clock_time
handler = lambda do
warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Minitest.clock_time - t0]
end
self.class.on_signal ::Minitest.info_signal, handler, &block
end
include LifecycleHooks
include Guard
extend Guard
end # Test
end
require "minitest/unit" if ENV["MT_COMPAT"] # compatibility layer only
minitest-5.22.3/lib/minitest/compress.rb 0000444 0000041 0000041 00000005171 14577531334 020267 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 = ->(ary, n, off) { # each_slice_with_offset
if off.zero? then
ary.each_slice n
else
# [ ...off... [...n...] [...n...] ... ]
front, back = ary.take(off), ary.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, ary| ### sort by max dist + min offset
d = ary.each_cons(2).sum { |a, b| b-a }
[-d, ary.first]
} # b: [1 3 5] c: [2 4 6]
ranges = order
.map { |k, ary| # [[1..2 3..4] [2..3 4..5]]
ary
.each_cons(2)
.map { |a, b| a..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.22.3/lib/minitest/test_task.rb 0000444 0000041 0000041 00000017450 14577531334 020440 0 ustar www-data www-data require "shellwords"
require "rbconfig"
require "rake/tasklib"
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
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 "Show bottom 25 tests wrt time."
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
self.times.map {
Thread.new do
while job = q.pop # go until quit value
yield job
end
end
}.each(&:join)
end
end
minitest-5.22.3/lib/minitest/assertions.rb 0000444 0000041 0000041 00000057032 14577531334 020631 0 ustar www-data www-data # encoding: UTF-8
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/ &&
system("diff.exe", __FILE__, __FILE__)) then
"diff.exe -u"
elsif system("gdiff", __FILE__, __FILE__)
"gdiff -u" # solaris and kin suck
elsif system("diff", __FILE__, __FILE__)
"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
if defined? Encoding then
s = s.encode Encoding.default_external
if String === obj && (obj.encoding != Encoding.default_external ||
!obj.valid_encoding?) then
enc = "# encoding: #{obj.encoding}"
val = "# valid: #{obj.valid_encoding?}"
s = "#{enc}\n#{val}\n#{s}"
end
end
s
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")}",
"---------------",
].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.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.22.3/lib/minitest/autorun.rb 0000444 0000041 0000041 00000000325 14577531334 020125 0 ustar www-data www-data begin
require "rubygems"
gem "minitest"
rescue Gem::LoadError
# do nothing
end
require "minitest"
require "minitest/spec"
require "minitest/mock"
require "minitest/hell" if ENV["MT_HELL"]
Minitest.autorun
minitest-5.22.3/lib/minitest/benchmark.rb 0000444 0000041 0000041 00000030041 14577531334 020360 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
rescue LocalJumpError # 1.8.6
r = []; (min..max).step(step) { |n| r << n }; r
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.inject { |sum, n| sum + n }
end
##
# Returns a proc that calls the specified fit method and asserts
# that the error is within a tolerable threshold.
def validation_for_fit msg, threshold
proc do |range, times|
a, b, rr = send "fit_#{msg}", range, times
assert_operator rr, :>=, threshold
[a, b, rr]
end
end
end
end
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.22.3/lib/minitest/pride.rb 0000444 0000041 0000041 00000000103 14577531334 017525 0 ustar www-data www-data require "minitest"
Minitest.load_plugins
Minitest::PrideIO.pride!
minitest-5.22.3/lib/minitest.rb 0000444 0000041 0000041 00000065656 14577531334 016452 0 ustar www-data www-data require "optparse"
require "stringio"
require "etc"
require_relative "minitest/parallel"
require_relative "minitest/compress"
##
# :include: README.rdoc
module Minitest
VERSION = "5.22.2" # :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
if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
Warning[:deprecated] = true
end
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
def self.init_plugins options # :nodoc:
self.extensions.each do |name|
msg = "plugin_#{name}_init"
send msg, options if self.respond_to? msg
end
end
def self.load_plugins # :nodoc:
return unless self.extensions.empty?
seen = {}
require "rubygems" unless defined? Gem
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
##
# 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.__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
return empty_run! options if summary && summary.count == 0
reporter.report
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.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
unless extensions.empty?
opts.separator ""
opts.separator "Known extensions: #{extensions.join(", ")}"
extensions.each do |meth|
msg = "plugin_#{meth}_options"
send msg, opts, options if self.respond_to?(msg)
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 =~ /[\s|&<>$()]/ ? s.inspect : s
}.join " "
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.is_a?(String) && pos =~ %r%/(.*)/%
neg = Regexp.new $1 if neg.is_a?(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?
with_info_handler reporter do
filtered_methods.each do |method_name|
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:
handler = lambda do
unless reporter.passed? then
warn "Current results:"
warn ""
warn reporter.reporters.first
warn ""
end
end
on_signal ::Minitest.info_signal, 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.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? { |f| UnexpectedError === f }
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:
if options[:verbose] then
io.print "%s#%s = " % [klass.name, name]
io.flush
end
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
##
# 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
/^ruby/ =~ platform
end
##
# Is this running on macOS?
def osx? platform = RUBY_PLATFORM
/darwin/ =~ platform
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/ =~ platform
end
end
##
# The standard backtrace filter for minitest.
#
# See Minitest.backtrace_filter=.
class BacktraceFilter
MT_RE = %r%lib/minitest% #:nodoc:
attr_accessor :regexp
def initialize regexp = MT_RE
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| line.to_s !~ regexp }
new_bt = bt.select { |line| line.to_s !~ regexp } 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.22.3/test/ 0000755 0000041 0000041 00000000000 14577531334 014462 5 ustar www-data www-data minitest-5.22.3/test/minitest/ 0000755 0000041 0000041 00000000000 14577531334 016316 5 ustar www-data www-data minitest-5.22.3/test/minitest/test_minitest_test_task.rb 0000444 0000041 0000041 00000002324 14577531334 023616 0 ustar www-data www-data require "minitest/autorun"
require "hoe"
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"
mt_path = %w[lib test .].join File::PATH_SEPARATOR
MT_EXPECTED = %W[-I#{mt_path} -w
-e '%srequire "#{PATH}"'
--].join(" ") + " "
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 MT_EXPECTED % [framework].join("; "), @tester.make_test_cmd
.sub(/ -- .+/, " -- ")
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 MT_EXPECTED % [prelude, framework].join("; "), @tester.make_test_cmd
.sub(/ -- .+/, " -- ")
end
end
minitest-5.22.3/test/minitest/test_minitest_test.rb 0000444 0000041 0000041 00000075036 14577531334 022606 0 ustar www-data www-data # encoding: UTF-8
require "pathname"
require "minitest/metametameta"
if defined? Encoding then
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
end
class Minitest::Runnable
def whatever # faked for testing
assert true
end
end
class TestMinitestUnit < MetaMetaMetaTestCase
parallelize_me!
pwd = Pathname.new File.expand_path Dir.pwd
basedir = Pathname.new(File.expand_path "lib/minitest") + "mini"
basedir = basedir.relative_path_from(pwd).to_s
MINITEST_BASE_DIR = basedir[/\A\./] ? basedir : "./#{basedir}"
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
fail 'ЁЁЁ'.force_encoding('ASCII-8BIT')
end
end
expected = clean <<-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 =~ /^\./) ? 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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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 = [: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 = [: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 = [: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 = [: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
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.
RUBY18 = !defined? Encoding
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_output "", /DEPRECATED/ do
assert self.class.rubinius? "rbx"
end
assert_output "", /DEPRECATED/ do
assert self.rubinius? "rbx"
end
end
def test_maglev_eh
assert_output "", /DEPRECATED/ do
assert self.class.maglev? "maglev"
end
assert_output "", /DEPRECATED/ 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 = clean "
Error:
FakeNamedTestXX#test_method:
AnError: AnError
FILE:LINE:in 'test_method'
Error:
FakeNamedTestXX#test_method:
RuntimeError: unhandled exception
FILE:LINE:in 'teardown'
"
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.22.3/test/minitest/test_minitest_spec.rb 0000444 0000041 0000041 00000071665 14577531334 022565 0 ustar www-data www-data # encoding: utf-8
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
# helps to deal with 2.4 deprecation of Fixnum for Integer
Int = 1.class
# 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>")
if 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
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 =~ /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
path_must_exist]
bad = %w[not raise throw send output be_silent]
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 += 1 # extra test
out, err = capture_io do
assert_success _(nil).must_equal(nil)
end
exp = "DEPRECATED: Use assert_nil if expecting nil from #{__FILE__}:#{__LINE__-3}. " \
"This will fail in Minitest 6.\n"
exp = "" if $-w.nil?
assert_empty out
assert_equal exp, err
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 #{Int.name}." do
_(42).wont_be_kind_of Int
end
assert_triggered "msg.\nExpected 42 to not be an instance of #{Int.name}." do
_(42).wont_be_instance_of Int, "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 #{Int.name}." do
_(42).wont_be_kind_of Int
end
assert_triggered "msg.\nExpected 42 to not be a kind of #{Int.name}." do
_(42).wont_be_kind_of Int, "msg"
end
end
it "needs to verify kinds of objects" do
@assertion_count += 3 # extra test
assert_success _(6 * 7).must_be_kind_of(Int)
assert_success _(6 * 7).must_be_kind_of(Numeric)
assert_triggered "Expected 42 to be a kind of String, not #{Int.name}." do
_(6 * 7).must_be_kind_of String
end
assert_triggered "msg.\nExpected 42 to be a kind of String, not #{Int.name}." 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 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 += 1
e = assert_raises RuntimeError do
capture_io do
Thread.new { # forces ctx to be nil
describe("woot") do
(1 + 1).must_equal 2
end
}.join
end
end
assert_equal "Calling #must_equal outside of test.", e.message
end
it "deprecates expectation used without _" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
@assertion_count += 3
exp = /DEPRECATED: global use of must_equal from/
assert_output "", 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 += 3
exp = /DEPRECATED: global use of must_equal from/
with_empty_backtrace_filter do
assert_output "", 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(Int)
exp = "Expected 42 to be an instance of String, not #{Int.name}."
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 (#{Int.name}) to respond to #clear." do
_(42).must_respond_to :clear
end
assert_triggered "msg.\nExpected 42 (#{Int.name}) 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_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.22.3/test/minitest/test_minitest_reporter.rb 0000444 0000041 0000041 00000022071 14577531334 023460 0 ustar www-data www-data require "minitest/autorun"
require "minitest/metametameta"
require "forwardable"
class Runnable
def woot
assert true
end
end
class TestMinitestReporter < MetaMetaMetaTestCase
attr_accessor :r, :io
def new_composite_reporter
# Ruby bug in older versions of 2.2 & 2.3 on all platforms
# Latest Windows builds were 2.2.6 and 2.3.3. Latest Ruby releases were
# 2.2.10 and 2.3.8.
skip if windows? && RUBY_VERSION < '2.4'
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 = Minitest::Test.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 = Minitest::Test.new(:woot)
@sse.failures << Minitest::UnexpectedError.new(ex)
@sse = Minitest::Result.from @sse
end
@sse
end
def fail_test
unless defined? @ft then
@ft = Minitest::Test.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 Minitest::Test.new(:woot)
end
def passing_test_with_metadata
test = Minitest::Test.new(:woot)
test.metadata[:meta] = :data
@pt ||= Minitest::Result.from test
end
def skip_test
unless defined? @st then
@st = Minitest::Test.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 = clean <<-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 = clean <<-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 = clean <<-EOM
Run options:
# Running:
F
Finished in 0.00
1) Failure:
Minitest::Test#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 = clean <<-EOM
Run options:
# Running:
E
Finished in 0.00
1) Error:
Minitest::Test#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 = clean <<-EOM
Run options:
# Running:
E
Finished in 0.00
1) Error:
Minitest::Test#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 = clean <<-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 = "Minitest::Test#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.22.3/test/minitest/test_minitest_benchmark.rb 0000444 0000041 0000041 00000006601 14577531334 023551 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.22.3/test/minitest/test_minitest_assertions.rb 0000444 0000041 0000041 00000117004 14577531334 024011 0 ustar www-data www-data # encoding: UTF-8
require "minitest/autorun"
if defined? Encoding then
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
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.
RUBY18 = !defined? Encoding
# not included in JRuby
RE_LEVELS = /\(\d+ levels\) /
class DummyTest
include Minitest::Assertions
# include Minitest::Reportable # TODO: why do I really need this?
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_deprecated name
dep = /DEPRECATED: #{name}. From #{__FILE__}:\d+(?::.*)?/
dep = "" if $-w.nil?
assert_output nil, dep do
yield
end
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 clean s
s.gsub(/^ {6,10}/, "")
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
object1 = Object.new
object2 = Object.new
msg = "No visible difference in the Array#inspect output.
You should look at the implementation of #== on Array or its members.
[#]".gsub(/^ +/, "")
assert_triggered msg do
@tc.assert_equal [object1], [object2]
end
end
def test_assert_equal_different_collection_hash_hex_invisible
h1, h2 = {}, {}
h1[1] = Object.new
h2[1] = Object.new
msg = "No visible difference in the Hash#inspect output.
You should look at the implementation of #== on Hash or its members.
{1=>#}".gsub(/^ +/, "")
assert_triggered msg do
@tc.assert_equal h1, h2
end
end
def test_assert_equal_different_diff_deactivated
without_diff do
assert_triggered util_msg("haha" * 10, "blah" * 10) do
o1 = "haha" * 10
o2 = "blah" * 10
@tc.assert_equal o1, o2
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
o1 = c.new "a"
o2 = c.new "b"
msg = clean <<-EOS
--- expected
+++ actual
@@ -1 +1 @@
-#<#:0xXXXXXX @name=\"a\">
+#<#:0xXXXXXX @name=\"b\">
EOS
assert_triggered msg do
@tc.assert_equal o1, o2
end
end
def test_assert_equal_different_hex_invisible
o1 = Object.new
o2 = Object.new
msg = "No visible difference in the Object#inspect output.
You should look at the implementation of #== on Object or its members.
#".gsub(/^ +/, "")
assert_triggered msg do
@tc.assert_equal o1, o2
end
end
def test_assert_equal_different_long
msg = "--- expected
+++ actual
@@ -1 +1 @@
-\"hahahahahahahahahahahahahahahahahahahaha\"
+\"blahblahblahblahblahblahblahblahblahblah\"
".gsub(/^ +/, "")
assert_triggered msg do
o1 = "haha" * 10
o2 = "blah" * 10
@tc.assert_equal o1, o2
end
end
def test_assert_equal_different_long_invisible
msg = "No visible difference in the String#inspect output.
You should look at the implementation of #== on String or its members.
\"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
assert_triggered msg do
o1 = "blah" * 10
o2 = "blah" * 10
def o1.== _
false
end
@tc.assert_equal o1, o2
end
end
def test_assert_equal_different_long_msg
msg = "message.
--- expected
+++ actual
@@ -1 +1 @@
-\"hahahahahahahahahahahahahahahahahahahaha\"
+\"blahblahblahblahblahblahblahblahblahblah\"
".gsub(/^ +/, "")
assert_triggered msg do
o1 = "haha" * 10
o2 = "blah" * 10
@tc.assert_equal o1, o2, "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_output "", 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 = <<-'EOF'.gsub(/^ {10}/, "") # note single quotes
--- expected
+++ actual
@@ -1,2 +1 @@
-"\\n
-"
+"\\\"
EOF
exp = "Expected: \"\\\\n\"\n Actual: \"\\\\\""
assert_triggered exp do
@tc.assert_equal "\\n", "\\"
end
end
def test_assert_equal_string_both_escaped_unescaped_newlines
msg = <<-EOM.gsub(/^ {10}/, "")
--- 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.gsub(/^ {10}/, "")
--- 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
x = "bad-utf8-\xF1.txt"
y = x.dup.force_encoding "binary" # TODO: switch to .b when 1.9 dropped
@tc.assert_equal x, y
end
end unless RUBY18
def test_assert_equal_string_encodings_both_different
msg = <<-EOM.gsub(/^ {10}/, "")
--- 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
x = "bad-utf8-\xF1.txt".force_encoding "ASCII"
y = x.dup.force_encoding "binary" # TODO: switch to .b when 1.9 dropped
@tc.assert_equal x, y
end
end unless RUBY18
def test_assert_equal_unescape_newlines
msg = <<-'EOM'.gsub(/^ {10}/, "") # 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 = (RUBY18 and not maglev?) ? "0.1" : "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 = clean <<-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 = clean <<-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 = clean <<-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 = clean <<-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
assert_deprecated :assert_send do
@tc.assert_send [1, :<, 2]
end
end
def test_assert_send_bad
assert_deprecated :assert_send do
assert_triggered "Expected 1.>(*[2]) to return true." do
@tc.assert_send [1, :>, 2]
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_output "", /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 = "No visible difference in the String#inspect output.
You should look at the implementation of #== on String or its members.
\"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
o1 = "blah" * 10
o2 = "blah" * 10
def o1.== _
false
end
assert_equal msg, diff(o1, o2)
end
def test_diff_str_mixed
msg = <<-'EOM'.gsub(/^ {10}/, "") # 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'.gsub(/^ {10}/, "") # NOTE single quotes on heredoc
--- 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'.gsub(/^ {10}/, "").chomp # NOTE single quotes on heredoc
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".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".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".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.22.3/test/minitest/metametameta.rb 0000444 0000041 0000041 00000006222 14577531334 021307 0 ustar www-data www-data require "tempfile"
require "stringio"
require "minitest/autorun"
class Minitest::Test
def clean s
s.gsub(/^ {6}/, "")
end
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
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("".encode('UTF-8'))
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 = clean <<-EOM
Run options: #{flags.map { |s| s =~ /\|/ ? 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.22.3/test/minitest/test_minitest_mock.rb 0000444 0000041 0000041 00000063621 14577531334 022555 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)
@mock.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
skip "Doesn't run on 1.8" if RUBY_VERSION < "1.9"
@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_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(:kw=>false) => nil, got [foo(:kw=>true) => nil]"
assert_equal exp, e.message
end
def test_verify_passes_when_mock_block_returns_true
mock = Minitest::Mock.new
mock.expect :foo, nil do
true
end
mock.foo
assert_mock 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/ [] {: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_output nil, /Using MT_KWARGS_HAC. yet passing kwargs/ do
mock.expect :foo, nil, [{}], k1: arg1, k2: arg2, k3: arg3
end
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
assert_match(/unexpected keyword arguments.* vs .*:k2=>: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
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 = jruby? ? /Undefined method nope_nope_nope for '#{self.class}::Time'/ :
/undefined method [`']nope_nope_nope' for( class)? [`']#{self.class}::Time'/
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
alias test_stub_value__old test_stub_value # TODO: remove/rename
## 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
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.22.3/checksums.yaml.gz.sig 0000444 0000041 0000041 00000000400 14577531334 017544 0 ustar www-data www-data #EЍJJa;nT!N{QH_0T*ݥ'РO
Qc8]j 源Oš:[Ia2T'IU .8Q'*g`%W^5L(A&'Eb7_} ??
dl"0~O*\'uM\jQ@_"G˩!_@(FB}2t!_;] TW3/$bSyc^ minitest-5.22.3/Rakefile 0000444 0000041 0000041 00000004303 14577531334 015146 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)_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
# vim: syntax=Ruby
minitest-5.22.3/data.tar.gz.sig 0000444 0000041 0000041 00000000400 14577531334 016314 0 ustar www-data www-data : e0fF1ma#+Z,ڟQUdWxs@ΘxJt`oċj*س
s4D~ow_DK(em8kQGJۘ]F0~IE{MD0[Hkl6JkKT
"7.!c8ѝ##