Imported minitest 2.5.0 (r6557)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
885f5fa2b0
commit
2c43b9664b
@ -1,3 +1,8 @@
|
||||
Wed Aug 24 06:45:20 2011 Ryan Davis <ryand-ruby@zenspider.com>
|
||||
|
||||
* lib/minitest/*: Imported minitest 2.5.0 (r6557)
|
||||
* test/minitest/*: ditto
|
||||
|
||||
Wed Aug 24 00:38:22 2011 Yusuke Endoh <mame@tsg.ne.jp>
|
||||
|
||||
* thread.c (update_coverage): skip coverage count up if the current
|
||||
|
270
lib/minitest/README.txt
Normal file
270
lib/minitest/README.txt
Normal file
@ -0,0 +1,270 @@
|
||||
= minitest/{unit,spec,mock,benchmark}
|
||||
|
||||
home :: https://github.com/seattlerb/minitest
|
||||
rdoc :: http://bfts.rubyforge.org/minitest
|
||||
|
||||
== DESCRIPTION:
|
||||
|
||||
minitest provides a complete suite of testing facilities supporting
|
||||
TDD, BDD, mocking, and benchmarking.
|
||||
|
||||
minitest/unit is a small and incredibly fast unit testing framework.
|
||||
It provides a rich set of assertions to make your tests clean and
|
||||
readable.
|
||||
|
||||
minitest/spec is a functionally complete spec engine. It hooks onto
|
||||
minitest/unit and seamlessly bridges test assertions over to spec
|
||||
expectations.
|
||||
|
||||
minitest/benchmark is an awesome way to assert the performance of your
|
||||
algorithms in a repeatable manner. Now you can assert that your newb
|
||||
co-worker doesn't replace your linear algorithm with an exponential
|
||||
one!
|
||||
|
||||
minitest/mock by Steven Baker, is a beautifully tiny mock object
|
||||
framework.
|
||||
|
||||
minitest/pride shows pride in testing and adds coloring to your test
|
||||
output. I guess it is an example of how to write IO pipes too. :P
|
||||
|
||||
minitest/unit is meant to have a clean implementation for language
|
||||
implementors that need a minimal set of methods to bootstrap a working
|
||||
test suite. For example, there is no magic involved for test-case
|
||||
discovery.
|
||||
|
||||
== FEATURES/PROBLEMS:
|
||||
|
||||
* minitest/autorun - the easy and explicit way to run all your tests.
|
||||
* minitest/unit - a very fast, simple, and clean test system.
|
||||
* minitest/spec - a very fast, simple, and clean spec system.
|
||||
* minitest/mock - a simple and clean mock system.
|
||||
* minitest/benchmark - an awesome way to assert your algorithm's performance.
|
||||
* minitest/pride - show your pride in testing!
|
||||
* Incredibly small and fast runner, but no bells and whistles.
|
||||
|
||||
== RATIONALE:
|
||||
|
||||
See design_rationale.rb to see how specs and tests work in minitest.
|
||||
|
||||
== SYNOPSIS:
|
||||
|
||||
Given that you'd like to test the following class:
|
||||
|
||||
class Meme
|
||||
def i_can_has_cheezburger?
|
||||
"OHAI!"
|
||||
end
|
||||
|
||||
def will_it_blend?
|
||||
"YES!"
|
||||
end
|
||||
end
|
||||
|
||||
=== Unit tests
|
||||
|
||||
require 'minitest/autorun'
|
||||
|
||||
class TestMeme < MiniTest::Unit::TestCase
|
||||
def setup
|
||||
@meme = Meme.new
|
||||
end
|
||||
|
||||
def test_that_kitty_can_eat
|
||||
assert_equal "OHAI!", @meme.i_can_has_cheezburger?
|
||||
end
|
||||
|
||||
def test_that_it_will_not_blend
|
||||
refute_match /^no/i, @meme.will_it_blend?
|
||||
end
|
||||
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
|
||||
|
||||
=== Benchmarks
|
||||
|
||||
Add benchmarks to your regular unit tests. If the unit tests fail, the
|
||||
benchmarks won't run.
|
||||
|
||||
# optionally run benchmarks, good for CI-only work!
|
||||
require 'minitest/benchmark' if ENV["BENCH"]
|
||||
|
||||
class TestMeme < MiniTest::Unit::TestCase
|
||||
# Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]
|
||||
def bench_my_algorithm
|
||||
assert_performance_linear 0.9999 do |n| # n is a range value
|
||||
n.times do
|
||||
@obj.my_algorithm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Or add them to your specs. If you make benchmarks optional, you'll
|
||||
need to wrap your benchmarks in a conditional since the methods won't
|
||||
be defined.
|
||||
|
||||
describe Meme do
|
||||
if ENV["BENCH"] then
|
||||
bench_performance_linear "my_algorithm", 0.9999 do |n|
|
||||
100.times do
|
||||
@obj.my_algorithm(n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
outputs something like:
|
||||
|
||||
# Running benchmarks:
|
||||
|
||||
TestBlah 100 1000 10000
|
||||
bench_my_algorithm 0.006167 0.079279 0.786993
|
||||
bench_other_algorithm 0.061679 0.792797 7.869932
|
||||
|
||||
Output is tab-delimited to make it easy to paste into a spreadsheet.
|
||||
|
||||
=== Mocks
|
||||
|
||||
class MemeAsker
|
||||
def initialize(meme)
|
||||
@meme = meme
|
||||
end
|
||||
|
||||
def ask(question)
|
||||
method = question.tr(" ","_") + "?"
|
||||
@meme.send(method)
|
||||
end
|
||||
end
|
||||
|
||||
require 'minitest/autorun'
|
||||
|
||||
describe MemeAsker do
|
||||
before do
|
||||
@meme = MiniTest::Mock.new
|
||||
@meme_asker = MemeAsker.new @meme
|
||||
end
|
||||
|
||||
describe "#ask" do
|
||||
describe "when passed an unpunctuated question" do
|
||||
it "should invoke the appropriate predicate method on the meme" do
|
||||
@meme.expect :will_it_blend?, :return_value
|
||||
@meme_asker.ask "will it blend"
|
||||
@meme.verify
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
=== Customizable Test Runner Types:
|
||||
|
||||
MiniTest::Unit.runner=(runner) provides an easy way of creating custom
|
||||
test runners for specialized needs. Justin Weiss provides the
|
||||
following real-world example to create an alternative to regular
|
||||
fixture loading:
|
||||
|
||||
class MiniTestWithHooks::Unit < MiniTest::Unit
|
||||
def before_suites
|
||||
end
|
||||
|
||||
def after_suites
|
||||
end
|
||||
|
||||
def _run_suites(suites, type)
|
||||
begin
|
||||
before_suites
|
||||
super(suites, type)
|
||||
ensure
|
||||
after_suites
|
||||
end
|
||||
end
|
||||
|
||||
def _run_suite(suite, type)
|
||||
begin
|
||||
suite.before_suite
|
||||
super(suite, type)
|
||||
ensure
|
||||
suite.after_suite
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module MiniTestWithTransactions
|
||||
class Unit < MiniTestWithHooks::Unit
|
||||
include TestSetupHelper
|
||||
|
||||
def before_suites
|
||||
super
|
||||
setup_nested_transactions
|
||||
# load any data we want available for all tests
|
||||
end
|
||||
|
||||
def after_suites
|
||||
teardown_nested_transactions
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MiniTest::Unit.runner = MiniTestWithTransactions::Unit.new
|
||||
|
||||
== REQUIREMENTS:
|
||||
|
||||
* Ruby 1.8, maybe even 1.6 or lower. No magic is involved.
|
||||
|
||||
== INSTALL:
|
||||
|
||||
sudo gem install minitest
|
||||
|
||||
On 1.9, you already have it. To get newer candy you can still install
|
||||
the gem, but you'll need to activate the gem explicitly to use it:
|
||||
|
||||
require 'rubygems'
|
||||
gem 'minitest' # ensures you're using the gem, and not the built in MT
|
||||
require 'minitest/autorun'
|
||||
|
||||
# ... usual testing stuffs ...
|
||||
|
||||
== 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.
|
@ -15,20 +15,39 @@ module MiniTest
|
||||
# All mock objects are an instance of Mock
|
||||
|
||||
class Mock
|
||||
alias :__respond_to? :respond_to?
|
||||
|
||||
skip_methods = %w(object_id respond_to_missing? inspect === to_s)
|
||||
|
||||
instance_methods.each do |m|
|
||||
undef_method m unless skip_methods.include?(m.to_s) || m =~ /^__/
|
||||
end
|
||||
|
||||
def initialize # :nodoc:
|
||||
@expected_calls = {}
|
||||
@actual_calls = Hash.new {|h,k| h[k] = [] }
|
||||
end
|
||||
|
||||
##
|
||||
# Expect that method +name+ is called, optionally with +args+, and
|
||||
# returns +retval+.
|
||||
# Expect that method +name+ is called, optionally with +args+, 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
|
||||
#
|
||||
# +args+ is compared to the expected args using case equality (ie, the
|
||||
# '===' operator), allowing for less specific expectations.
|
||||
#
|
||||
# @mock.expect(:uses_any_string, true, [String])
|
||||
# @mock.uses_any_string("foo") # => true
|
||||
# @mock.verify # => true
|
||||
#
|
||||
# @mock.expect(:uses_one_string, true, ["foo"]
|
||||
# @mock.uses_one_string("bar") # => true
|
||||
# @mock.verify # => raises MockExpectationError
|
||||
|
||||
def expect(name, retval, args=[])
|
||||
@expected_calls[name] = { :retval => retval, :args => args }
|
||||
@ -43,25 +62,45 @@ module MiniTest
|
||||
def verify
|
||||
@expected_calls.each_key do |name|
|
||||
expected = @expected_calls[name]
|
||||
msg = "expected #{name}, #{expected.inspect}"
|
||||
raise MockExpectationError, msg unless
|
||||
msg1 = "expected #{name}, #{expected.inspect}"
|
||||
msg2 = "#{msg1}, got #{@actual_calls[name].inspect}"
|
||||
|
||||
raise MockExpectationError, msg2 if
|
||||
@actual_calls.has_key? name and
|
||||
not @actual_calls[name].include?(expected)
|
||||
|
||||
raise MockExpectationError, msg1 unless
|
||||
@actual_calls.has_key? name and @actual_calls[name].include?(expected)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def method_missing(sym, *args) # :nodoc:
|
||||
raise NoMethodError unless @expected_calls.has_key?(sym)
|
||||
raise ArgumentError unless @expected_calls[sym][:args].size == args.size
|
||||
retval = @expected_calls[sym][:retval]
|
||||
@actual_calls[sym] << { :retval => retval, :args => args }
|
||||
expected = @expected_calls[sym]
|
||||
|
||||
unless expected then
|
||||
raise NoMethodError, "unmocked method %p, expected one of %p" %
|
||||
[sym, @expected_calls.keys.sort_by(&:to_s)]
|
||||
end
|
||||
|
||||
expected_args, retval = expected[:args], expected[:retval]
|
||||
|
||||
unless expected_args.size == args.size
|
||||
raise ArgumentError, "mocked method %p expects %d arguments, got %d" %
|
||||
[sym, expected[:args].size, args.size]
|
||||
end
|
||||
|
||||
@actual_calls[sym] << {
|
||||
:retval => retval,
|
||||
:args => expected_args.zip(args).map { |mod, a| mod if mod === a }
|
||||
}
|
||||
|
||||
retval
|
||||
end
|
||||
|
||||
alias :original_respond_to? :respond_to?
|
||||
def respond_to?(sym) # :nodoc:
|
||||
return true if @expected_calls.has_key?(sym)
|
||||
return original_respond_to?(sym)
|
||||
return __respond_to?(sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -10,32 +10,90 @@ require "minitest/unit"
|
||||
# Show your testing pride!
|
||||
|
||||
class PrideIO
|
||||
attr_reader :io
|
||||
ESC = "\e["
|
||||
NND = "#{ESC}0m"
|
||||
|
||||
# stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
|
||||
COLORS = (31..36).to_a
|
||||
CHARS = ["*"]
|
||||
attr_reader :io
|
||||
|
||||
def initialize io
|
||||
@io = io
|
||||
@colors = COLORS.cycle
|
||||
@chars = CHARS.cycle
|
||||
# stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
|
||||
# also reference http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
@colors ||= (31..36).to_a
|
||||
@size = @colors.size
|
||||
@index = 0
|
||||
# io.sync = true
|
||||
end
|
||||
|
||||
def print o
|
||||
case o
|
||||
when "." then
|
||||
io.print "\e[#{@colors.next}m#{@chars.next}\e[0m"
|
||||
io.print pride o
|
||||
when "E", "F" then
|
||||
io.print "\e[41m\e[37m#{o}\e[0m"
|
||||
io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
|
||||
else
|
||||
io.print o
|
||||
end
|
||||
end
|
||||
|
||||
def puts(*o)
|
||||
o.map! { |s|
|
||||
s.sub(/Finished tests/) {
|
||||
@index = 0
|
||||
'Fabulous tests'.split(//).map { |c|
|
||||
pride(c)
|
||||
}.join
|
||||
}
|
||||
}
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def pride string
|
||||
string = "*" if string == "."
|
||||
c = @colors[@index % @size]
|
||||
@index += 1
|
||||
"#{ESC}#{c}m#{string}#{NND}"
|
||||
end
|
||||
|
||||
def method_missing msg, *args
|
||||
io.send(msg, *args)
|
||||
end
|
||||
end
|
||||
|
||||
MiniTest::Unit.output = PrideIO.new(MiniTest::Unit.output)
|
||||
class PrideLOL < PrideIO # inspired by lolcat, but massively cleaned up
|
||||
PI_3 = Math::PI / 3
|
||||
|
||||
def initialize io
|
||||
# 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)
|
||||
|
||||
# 6 has wide pretty gradients. 3 == lolcat, about half the width
|
||||
@colors = (0...(6 * 7)).map { |n|
|
||||
n *= 1.0 / 6
|
||||
r = (3 * Math.sin(n ) + 3).to_i
|
||||
g = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
|
||||
b = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
|
||||
|
||||
# Then we take rgb and encode them in a single number using base 6.
|
||||
# For some mysterious reason, we add 16... to clear the bottom 4 bits?
|
||||
# Yes... they're ugly.
|
||||
|
||||
36 * r + 6 * g + b + 16
|
||||
}
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def pride string
|
||||
c = @colors[@index % @size]
|
||||
@index += 1
|
||||
"#{ESC}38;5;#{c}m#{string}#{NND}"
|
||||
end
|
||||
end
|
||||
|
||||
klass = ENV['TERM'] =~ /^xterm(-256color)?$/ ? PrideLOL : PrideIO
|
||||
MiniTest::Unit.output = klass.new(MiniTest::Unit.output)
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
require 'minitest/unit'
|
||||
|
||||
class Module
|
||||
class Module # :nodoc:
|
||||
def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
|
||||
# warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
|
||||
self.class_eval <<-EOM
|
||||
@ -23,39 +23,18 @@ class Module
|
||||
end
|
||||
|
||||
##
|
||||
# Create your own expectations from MiniTest::Assertions using a
|
||||
# flexible set of rules. If you don't like must/wont, then this
|
||||
# method is your friend. For an example of its usage see the bottom
|
||||
# of minitest/spec.rb.
|
||||
# infect_with_assertions has been removed due to excessive clever.
|
||||
# Use infect_an_assertion directly instead.
|
||||
|
||||
def infect_with_assertions(pos_prefix, neg_prefix,
|
||||
skip_re,
|
||||
dont_flip_re = /\c0/,
|
||||
map = {})
|
||||
MiniTest::Assertions.public_instance_methods(false).sort.each do |meth|
|
||||
meth = meth.to_s
|
||||
|
||||
new_name = case meth
|
||||
when /^assert/ then
|
||||
meth.sub(/^assert/, pos_prefix.to_s)
|
||||
when /^refute/ then
|
||||
meth.sub(/^refute/, neg_prefix.to_s)
|
||||
end
|
||||
next unless new_name
|
||||
next if new_name =~ skip_re
|
||||
|
||||
regexp, replacement = map.find { |re, _| new_name =~ re }
|
||||
new_name.sub! regexp, replacement if replacement
|
||||
|
||||
puts "\n##\n# :method: #{new_name}\n# See MiniTest::Assertions##{meth}" if
|
||||
$0 == __FILE__
|
||||
|
||||
infect_an_assertion meth, new_name, new_name =~ dont_flip_re
|
||||
end
|
||||
abort "infect_with_assertions is dead. Use infect_an_assertion directly"
|
||||
end
|
||||
end
|
||||
|
||||
module Kernel
|
||||
module Kernel # :nodoc:
|
||||
##
|
||||
# Describe a series of expectations for a given target +desc+.
|
||||
#
|
||||
@ -80,25 +59,16 @@ module Kernel
|
||||
# end
|
||||
# end
|
||||
|
||||
def describe desc, &block # :doc:
|
||||
def describe desc, additional_desc = nil, &block # :doc:
|
||||
stack = MiniTest::Spec.describe_stack
|
||||
name = [stack.last, desc].compact.join("::")
|
||||
name = [stack.last, desc, additional_desc].compact.join("::")
|
||||
sclas = stack.last || if Class === self && self < MiniTest::Spec then
|
||||
self
|
||||
else
|
||||
MiniTest::Spec.spec_type desc
|
||||
end
|
||||
cls = Class.new sclas
|
||||
|
||||
sclas.children << cls unless cls == MiniTest::Spec
|
||||
|
||||
# :stopdoc:
|
||||
# omg this sucks
|
||||
(class << cls; self; end).send(:define_method, :to_s) { name }
|
||||
(class << cls; self; end).send(:define_method, :desc) { desc }
|
||||
# :startdoc:
|
||||
|
||||
cls.nuke_test_methods!
|
||||
cls = sclas.create name, desc
|
||||
|
||||
stack.push cls
|
||||
cls.class_eval(&block)
|
||||
@ -111,7 +81,7 @@ end
|
||||
##
|
||||
# MiniTest::Spec -- The faster, better, less-magical spec framework!
|
||||
#
|
||||
# For a list of expectations, see Object.
|
||||
# For a list of expectations, see MiniTest::Expectations.
|
||||
|
||||
class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
##
|
||||
@ -151,6 +121,9 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
@@current_spec
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the children of this spec.
|
||||
|
||||
def self.children
|
||||
@children ||= []
|
||||
end
|
||||
@ -166,25 +139,6 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Spec users want setup/teardown to be inherited and NOTHING ELSE.
|
||||
# It is almost like method reuse is lost on them.
|
||||
|
||||
def self.define_inheritable_method name, &block # :nodoc:
|
||||
# regular super() warns
|
||||
super_method = self.superclass.instance_method name
|
||||
|
||||
teardown = name.to_s == "teardown"
|
||||
super_before = super_method && ! teardown
|
||||
super_after = super_method && teardown
|
||||
|
||||
define_method name do
|
||||
super_method.bind(self).call if super_before
|
||||
instance_eval(&block)
|
||||
super_method.bind(self).call if super_after
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Define a 'before' action. Inherits the way normal methods should.
|
||||
#
|
||||
@ -194,7 +148,8 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
|
||||
def self.before type = :each, &block
|
||||
raise "unsupported before type: #{type}" unless type == :each
|
||||
define_inheritable_method :setup, &block
|
||||
|
||||
add_setup_hook {|tc| tc.instance_eval(&block) }
|
||||
end
|
||||
|
||||
##
|
||||
@ -206,7 +161,8 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
|
||||
def self.after type = :each, &block
|
||||
raise "unsupported after type: #{type}" unless type == :each
|
||||
define_inheritable_method :teardown, &block
|
||||
|
||||
add_teardown_hook {|tc| tc.instance_eval(&block) }
|
||||
end
|
||||
|
||||
##
|
||||
@ -232,154 +188,311 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
|
||||
mod.send :undef_method, name if mod.public_method_defined? name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Object.infect_with_assertions(:must, :wont,
|
||||
/^(must|wont)$|wont_(throw)|
|
||||
must_(block|not?_|nothing|raise$)/x,
|
||||
/(must|wont)_(include|respond_to)/,
|
||||
/(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')
|
||||
|
||||
class Object
|
||||
alias :must_be_close_to :must_be_within_delta
|
||||
alias :wont_be_close_to :wont_be_within_delta
|
||||
|
||||
if $0 == __FILE__ then
|
||||
{ "must" => "assert", "wont" => "refute" }.each do |a, b|
|
||||
puts "\n"
|
||||
puts "##"
|
||||
puts "# :method: #{a}_be_close_to"
|
||||
puts "# See MiniTest::Assertions##{b}_in_delta"
|
||||
def self.let name, &block
|
||||
define_method name do
|
||||
@_memoized ||= {}
|
||||
@_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# :method: must_be
|
||||
# See MiniTest::Assertions#assert_operator
|
||||
def self.subject &block
|
||||
let :subject, &block
|
||||
end
|
||||
|
||||
##
|
||||
# :method: must_be_close_to
|
||||
# See MiniTest::Assertions#assert_in_delta
|
||||
def self.create name, desc # :nodoc:
|
||||
cls = Class.new(self) do
|
||||
@name = name
|
||||
@desc = desc
|
||||
|
||||
##
|
||||
# :method: must_be_empty
|
||||
# See MiniTest::Assertions#assert_empty
|
||||
nuke_test_methods!
|
||||
end
|
||||
|
||||
##
|
||||
# :method: must_be_instance_of
|
||||
# See MiniTest::Assertions#assert_instance_of
|
||||
children << cls
|
||||
|
||||
##
|
||||
# :method: must_be_kind_of
|
||||
# See MiniTest::Assertions#assert_kind_of
|
||||
cls
|
||||
end
|
||||
|
||||
##
|
||||
# :method: must_be_nil
|
||||
# See MiniTest::Assertions#assert_nil
|
||||
def self.to_s # :nodoc:
|
||||
defined?(@name) ? @name : super
|
||||
end
|
||||
|
||||
##
|
||||
# :method: must_be_same_as
|
||||
# See MiniTest::Assertions#assert_same
|
||||
|
||||
##
|
||||
# :method: must_be_silent
|
||||
# See MiniTest::Assertions#assert_silent
|
||||
|
||||
##
|
||||
# :method: must_be_within_delta
|
||||
# See MiniTest::Assertions#assert_in_delta
|
||||
|
||||
##
|
||||
# :method: must_be_within_epsilon
|
||||
# See MiniTest::Assertions#assert_in_epsilon
|
||||
|
||||
##
|
||||
# :method: must_equal
|
||||
# See MiniTest::Assertions#assert_equal
|
||||
|
||||
##
|
||||
# :method: must_include
|
||||
# See MiniTest::Assertions#assert_includes
|
||||
|
||||
##
|
||||
# :method: must_match
|
||||
# See MiniTest::Assertions#assert_match
|
||||
|
||||
##
|
||||
# :method: must_output
|
||||
# See MiniTest::Assertions#assert_output
|
||||
|
||||
##
|
||||
# :method: must_raise
|
||||
# See MiniTest::Assertions#assert_raises
|
||||
|
||||
##
|
||||
# :method: must_respond_to
|
||||
# See MiniTest::Assertions#assert_respond_to
|
||||
|
||||
##
|
||||
# :method: must_send
|
||||
# See MiniTest::Assertions#assert_send
|
||||
|
||||
##
|
||||
# :method: must_throw
|
||||
# See MiniTest::Assertions#assert_throws
|
||||
|
||||
##
|
||||
# :method: wont_be
|
||||
# See MiniTest::Assertions#refute_operator
|
||||
|
||||
##
|
||||
# :method: wont_be_close_to
|
||||
# See MiniTest::Assertions#refute_in_delta
|
||||
|
||||
##
|
||||
# :method: wont_be_empty
|
||||
# See MiniTest::Assertions#refute_empty
|
||||
|
||||
##
|
||||
# :method: wont_be_instance_of
|
||||
# See MiniTest::Assertions#refute_instance_of
|
||||
|
||||
##
|
||||
# :method: wont_be_kind_of
|
||||
# See MiniTest::Assertions#refute_kind_of
|
||||
|
||||
##
|
||||
# :method: wont_be_nil
|
||||
# See MiniTest::Assertions#refute_nil
|
||||
|
||||
##
|
||||
# :method: wont_be_same_as
|
||||
# See MiniTest::Assertions#refute_same
|
||||
|
||||
##
|
||||
# :method: wont_be_within_delta
|
||||
# See MiniTest::Assertions#refute_in_delta
|
||||
|
||||
##
|
||||
# :method: wont_be_within_epsilon
|
||||
# See MiniTest::Assertions#refute_in_epsilon
|
||||
|
||||
##
|
||||
# :method: wont_equal
|
||||
# See MiniTest::Assertions#refute_equal
|
||||
|
||||
##
|
||||
# :method: wont_include
|
||||
# See MiniTest::Assertions#refute_includes
|
||||
|
||||
##
|
||||
# :method: wont_match
|
||||
# See MiniTest::Assertions#refute_match
|
||||
|
||||
##
|
||||
# :method: wont_respond_to
|
||||
# See MiniTest::Assertions#refute_respond_to
|
||||
# :stopdoc:
|
||||
class << self
|
||||
attr_reader :name, :desc
|
||||
end
|
||||
# :startdoc:
|
||||
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
|
||||
|
||||
##
|
||||
# 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_within_delta
|
||||
|
||||
infect_an_assertion :assert_in_delta, :must_be_close_to
|
||||
|
||||
alias :must_be_within_delta :must_be_close_to
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#assert_operator
|
||||
#
|
||||
# n.must_be :<=, 42
|
||||
#
|
||||
# :method: must_be
|
||||
|
||||
infect_an_assertion :assert_operator, :must_be
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#assert_output
|
||||
#
|
||||
# proc { ... }.must_output out_or_nil [, err]
|
||||
#
|
||||
# :method: must_output
|
||||
|
||||
infect_an_assertion :assert_output, :must_output
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#assert_raises
|
||||
#
|
||||
# proc { ... }.must_raise exception
|
||||
#
|
||||
# :method: must_raise
|
||||
|
||||
infect_an_assertion :assert_raises, :must_raise
|
||||
|
||||
##
|
||||
# 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_send
|
||||
# TODO: remove me
|
||||
#
|
||||
# a.must_send
|
||||
#
|
||||
# :method: must_send
|
||||
|
||||
infect_an_assertion :assert_send, :must_send
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#assert_silent
|
||||
#
|
||||
# proc { ... }.must_be_silent
|
||||
#
|
||||
# :method: must_be_silent
|
||||
|
||||
infect_an_assertion :assert_silent, :must_be_silent
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#assert_throws
|
||||
#
|
||||
# proc { ... }.must_throw sym
|
||||
#
|
||||
# :method: must_throw
|
||||
|
||||
infect_an_assertion :assert_throws, :must_throw
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#refute_empty
|
||||
#
|
||||
# collection.wont_be_empty
|
||||
#
|
||||
# :method: wont_be_empty
|
||||
|
||||
infect_an_assertion :refute_empty, :wont_be_empty
|
||||
|
||||
##
|
||||
# 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_within_delta
|
||||
|
||||
infect_an_assertion :refute_in_delta, :wont_be_within_delta
|
||||
|
||||
alias :wont_be_close_to :wont_be_within_delta
|
||||
# FIX: reverse aliases
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# See MiniTest::Assertions#refute_operator
|
||||
#
|
||||
# n.wont_be :<=, 42
|
||||
#
|
||||
# :method: wont_be
|
||||
|
||||
infect_an_assertion :refute_operator, :wont_be
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
class Object
|
||||
include MiniTest::Expectations
|
||||
end
|
||||
|
@ -152,7 +152,7 @@ module MiniTest
|
||||
|
||||
def mu_pp obj
|
||||
s = obj.inspect
|
||||
s = s.force_encoding Encoding.default_external if defined? Encoding
|
||||
s = s.encode Encoding.default_external if defined? Encoding
|
||||
s
|
||||
end
|
||||
|
||||
@ -491,7 +491,7 @@ module MiniTest
|
||||
# Fails if +obj+ is empty.
|
||||
|
||||
def refute_empty obj, msg = nil
|
||||
msg = message(msg) { "Expected #{obj.inspect} to not be empty" }
|
||||
msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
|
||||
assert_respond_to obj, :empty?
|
||||
refute obj.empty?, msg
|
||||
end
|
||||
@ -577,7 +577,7 @@ module MiniTest
|
||||
end
|
||||
|
||||
##
|
||||
# Fails if +o1+ is not +op+ +o2+ nil. eg:
|
||||
# Fails if +o1+ is not +op+ +o2+. Eg:
|
||||
#
|
||||
# refute_operator 1, :>, 2 #=> pass
|
||||
# refute_operator 1, :<, 2 #=> fail
|
||||
@ -620,7 +620,7 @@ module MiniTest
|
||||
end
|
||||
|
||||
class Unit
|
||||
VERSION = "2.2.2" # :nodoc:
|
||||
VERSION = "2.5.0" # :nodoc:
|
||||
|
||||
attr_accessor :report, :failures, :errors, :skips # :nodoc:
|
||||
attr_accessor :test_count, :assertion_count # :nodoc:
|
||||
@ -945,6 +945,7 @@ module MiniTest
|
||||
begin
|
||||
@passed = nil
|
||||
self.setup
|
||||
self.run_setup_hooks
|
||||
self.__send__ self.__name__
|
||||
result = "." unless io?
|
||||
@passed = true
|
||||
@ -955,6 +956,7 @@ module MiniTest
|
||||
result = runner.puke self.class, self.__name__, e
|
||||
ensure
|
||||
begin
|
||||
self.run_teardown_hooks
|
||||
self.teardown
|
||||
rescue *PASSTHROUGH_EXCEPTIONS
|
||||
raise
|
||||
@ -987,16 +989,24 @@ module MiniTest
|
||||
|
||||
reset
|
||||
|
||||
def self.inherited klass # :nodoc:
|
||||
@@test_suites[klass] = true
|
||||
##
|
||||
# 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
|
||||
define_method :test_order do :alpha end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Defines test order and is subclassable. Defaults to :random
|
||||
# but can be overridden to return :alpha if your tests are order
|
||||
# dependent (read: weak).
|
||||
def self.inherited klass # :nodoc:
|
||||
@@test_suites[klass] = true
|
||||
klass.reset_setup_teardown_hooks
|
||||
super
|
||||
end
|
||||
|
||||
def self.test_order
|
||||
def self.test_order # :nodoc:
|
||||
:random
|
||||
end
|
||||
|
||||
@ -1035,6 +1045,111 @@ module MiniTest
|
||||
|
||||
def teardown; end
|
||||
|
||||
def self.reset_setup_teardown_hooks # :nodoc:
|
||||
@setup_hooks = []
|
||||
@teardown_hooks = []
|
||||
end
|
||||
|
||||
reset_setup_teardown_hooks
|
||||
|
||||
##
|
||||
# Adds a block of code that will be executed before every TestCase is
|
||||
# run. Equivalent to +setup+, but usable multiple times and without
|
||||
# re-opening any classes.
|
||||
#
|
||||
# All of the setup hooks will run in order after the +setup+ method, if
|
||||
# one is defined.
|
||||
#
|
||||
# The argument can be any object that responds to #call or a block.
|
||||
# That means that this call,
|
||||
#
|
||||
# MiniTest::TestCase.add_setup_hook { puts "foo" }
|
||||
#
|
||||
# ... is equivalent to:
|
||||
#
|
||||
# module MyTestSetup
|
||||
# def call
|
||||
# puts "foo"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# MiniTest::TestCase.add_setup_hook MyTestSetup
|
||||
#
|
||||
# The blocks passed to +add_setup_hook+ take an optional parameter that
|
||||
# will be the TestCase instance that is executing the block.
|
||||
|
||||
def self.add_setup_hook arg=nil, &block
|
||||
hook = arg || block
|
||||
@setup_hooks << hook
|
||||
end
|
||||
|
||||
def self.setup_hooks # :nodoc:
|
||||
if superclass.respond_to? :setup_hooks then
|
||||
superclass.setup_hooks
|
||||
else
|
||||
[]
|
||||
end + @setup_hooks
|
||||
end
|
||||
|
||||
def run_setup_hooks # :nodoc:
|
||||
self.class.setup_hooks.each do |hook|
|
||||
if hook.respond_to?(:arity) && hook.arity == 1
|
||||
hook.call(self)
|
||||
else
|
||||
hook.call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Adds a block of code that will be executed after every TestCase is
|
||||
# run. Equivalent to +teardown+, but usable multiple times and without
|
||||
# re-opening any classes.
|
||||
#
|
||||
# All of the teardown hooks will run in reverse order after the
|
||||
# +teardown+ method, if one is defined.
|
||||
#
|
||||
# The argument can be any object that responds to #call or a block.
|
||||
# That means that this call,
|
||||
#
|
||||
# MiniTest::TestCase.add_teardown_hook { puts "foo" }
|
||||
#
|
||||
# ... is equivalent to:
|
||||
#
|
||||
# module MyTestTeardown
|
||||
# def call
|
||||
# puts "foo"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# MiniTest::TestCase.add_teardown_hook MyTestTeardown
|
||||
#
|
||||
# The blocks passed to +add_teardown_hook+ take an optional parameter
|
||||
# that will be the TestCase instance that is executing the block.
|
||||
|
||||
def self.add_teardown_hook arg=nil, &block
|
||||
hook = arg || block
|
||||
@teardown_hooks << hook
|
||||
end
|
||||
|
||||
def self.teardown_hooks # :nodoc:
|
||||
if superclass.respond_to? :teardown_hooks then
|
||||
superclass.teardown_hooks
|
||||
else
|
||||
[]
|
||||
end + @teardown_hooks
|
||||
end
|
||||
|
||||
def run_teardown_hooks # :nodoc:
|
||||
self.class.teardown_hooks.reverse.each do |hook|
|
||||
if hook.respond_to?(:arity) && hook.arity == 1
|
||||
hook.call(self)
|
||||
else
|
||||
hook.call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include MiniTest::Assertions
|
||||
end # class TestCase
|
||||
end # class Unit
|
||||
|
@ -49,20 +49,34 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
|
||||
util_verify_bad
|
||||
end
|
||||
|
||||
def test_not_verify_if_unexpected_method_is_called
|
||||
assert_raises NoMethodError do
|
||||
@mock.unexpected
|
||||
end
|
||||
end
|
||||
|
||||
def test_blow_up_on_wrong_number_of_arguments
|
||||
@mock.foo
|
||||
@mock.meaning_of_life
|
||||
@mock.expect(:sum, 3, [1, 2])
|
||||
|
||||
assert_raises ArgumentError do
|
||||
e = assert_raises ArgumentError do
|
||||
@mock.sum
|
||||
end
|
||||
|
||||
assert_equal "mocked method :sum expects 2 arguments, got 0", 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.verify
|
||||
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.verify
|
||||
end
|
||||
|
||||
def test_blow_up_on_wrong_arguments
|
||||
@ -81,18 +95,22 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_no_method_error_on_unexpected_methods
|
||||
assert_raises NoMethodError do
|
||||
e = assert_raises NoMethodError do
|
||||
@mock.bar
|
||||
end
|
||||
|
||||
expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]"
|
||||
|
||||
assert_equal 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
|
||||
@ -104,6 +122,30 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
|
||||
assert !MiniTest::Mock.new.respond_to?(:foo)
|
||||
end
|
||||
|
||||
def test_mock_is_a_blank_slate
|
||||
@mock.expect :kind_of?, true, [Fixnum]
|
||||
@mock.expect :==, true, [1]
|
||||
|
||||
assert @mock.kind_of?(Fixnum), "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.verify
|
||||
end
|
||||
|
||||
def test_verify_raises_with_strict_args
|
||||
mock = MiniTest::Mock.new
|
||||
mock.expect :strict_expectation, true, [2]
|
||||
mock.strict_expectation 1
|
||||
|
||||
util_verify_bad
|
||||
end
|
||||
|
||||
def util_verify_bad
|
||||
assert_raises MockExpectationError do
|
||||
@mock.verify
|
||||
|
@ -4,11 +4,9 @@
|
||||
# File a patch instead and assign it to Ryan Davis.
|
||||
######################################################################
|
||||
|
||||
require 'minitest/spec'
|
||||
require 'minitest/autorun'
|
||||
require 'stringio'
|
||||
|
||||
MiniTest::Unit.autorun
|
||||
|
||||
describe MiniTest::Spec do
|
||||
before do
|
||||
@assertion_count = 4
|
||||
@ -202,6 +200,53 @@ describe MiniTest::Spec do
|
||||
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
|
||||
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 TestMeta < MiniTest::Unit::TestCase
|
||||
def test_setup
|
||||
srand 42
|
||||
@ -245,8 +290,8 @@ class TestMeta < MiniTest::Unit::TestCase
|
||||
assert_equal "inner thingy", y.desc
|
||||
assert_equal "very inner thingy", z.desc
|
||||
|
||||
top_methods = %w(setup teardown test_0001_top_level_it)
|
||||
inner_methods = %w(setup teardown test_0001_inner_it)
|
||||
top_methods = %w(test_0001_top_level_it)
|
||||
inner_methods = %w(test_0001_inner_it)
|
||||
|
||||
assert_equal top_methods, x.instance_methods(false).sort.map {|o| o.to_s }
|
||||
assert_equal inner_methods, y.instance_methods(false).sort.map {|o| o.to_s }
|
||||
@ -257,8 +302,9 @@ class TestMeta < MiniTest::Unit::TestCase
|
||||
_, _, z, before_list, after_list = util_structure
|
||||
|
||||
tc = z.new(nil)
|
||||
tc.setup
|
||||
tc.teardown
|
||||
|
||||
tc.run_setup_hooks
|
||||
tc.run_teardown_hooks
|
||||
|
||||
assert_equal [1, 2, 3], before_list
|
||||
assert_equal [3, 2, 1], after_list
|
||||
|
@ -12,6 +12,7 @@ MiniTest::Unit.autorun
|
||||
|
||||
module MyModule; end
|
||||
class AnError < StandardError; include MyModule; end
|
||||
class ImmutableString < String; def inspect; super.freeze; end; end
|
||||
|
||||
class TestMiniTestUnit < MiniTest::Unit::TestCase
|
||||
pwd = Pathname.new(File.expand_path(Dir.pwd))
|
||||
@ -46,12 +47,12 @@ Finished tests in 0.00
|
||||
MiniTest::Unit::TestCase.reset
|
||||
@tu = MiniTest::Unit.new
|
||||
@output = StringIO.new("")
|
||||
MiniTest::Unit.runner = nil # protect the outer runner from the inner tests
|
||||
MiniTest::Unit.output = @output
|
||||
end
|
||||
|
||||
def teardown
|
||||
MiniTest::Unit.output = $stdout
|
||||
MiniTest::Unit.runner = nil
|
||||
Object.send :remove_const, :ATestCase if defined? ATestCase
|
||||
end
|
||||
|
||||
@ -442,6 +443,149 @@ Finished tests in 0.00
|
||||
assert_report expected
|
||||
end
|
||||
|
||||
def with_overridden_include
|
||||
Class.class_eval do
|
||||
def inherited_with_hacks klass
|
||||
throw :inherited_hook
|
||||
end
|
||||
|
||||
alias inherited_without_hacks inherited
|
||||
alias inherited inherited_with_hacks
|
||||
alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
ensure
|
||||
Class.class_eval do
|
||||
alias inherited inherited_without_hacks
|
||||
|
||||
undef_method :inherited_with_hacks
|
||||
undef_method :inherited_without_hacks
|
||||
end
|
||||
|
||||
refute_respond_to Class, :inherited_with_hacks
|
||||
refute_respond_to Class, :inherited_without_hacks
|
||||
end
|
||||
|
||||
def test_inherited_hook_plays_nice_with_others
|
||||
with_overridden_include do
|
||||
assert_throws :inherited_hook do
|
||||
Class.new MiniTest::Unit::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_setup_hooks
|
||||
call_order = []
|
||||
|
||||
tc = Class.new(MiniTest::Unit::TestCase) do
|
||||
define_method :setup do
|
||||
super()
|
||||
call_order << :method
|
||||
end
|
||||
|
||||
define_method :test2 do
|
||||
call_order << :test2
|
||||
end
|
||||
|
||||
define_method :test1 do
|
||||
call_order << :test1
|
||||
end
|
||||
end
|
||||
|
||||
tc.add_setup_hook lambda { call_order << :proc }
|
||||
|
||||
argument = nil
|
||||
|
||||
tc.add_setup_hook do |arg|
|
||||
argument = arg
|
||||
call_order << :block
|
||||
end
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
|
||||
assert_kind_of tc, argument
|
||||
|
||||
expected = [:method, :proc, :block, :test1,
|
||||
:method, :proc, :block, :test2]
|
||||
|
||||
assert_equal expected, call_order
|
||||
end
|
||||
|
||||
def test_teardown_hooks
|
||||
call_order = []
|
||||
|
||||
tc = Class.new(MiniTest::Unit::TestCase) do
|
||||
define_method :teardown do
|
||||
super()
|
||||
call_order << :method
|
||||
end
|
||||
|
||||
define_method :test2 do
|
||||
call_order << :test2
|
||||
end
|
||||
|
||||
define_method :test1 do
|
||||
call_order << :test1
|
||||
end
|
||||
end
|
||||
|
||||
tc.add_teardown_hook lambda { call_order << :proc }
|
||||
|
||||
argument = nil
|
||||
|
||||
tc.add_teardown_hook do |arg|
|
||||
argument = arg
|
||||
call_order << :block
|
||||
end
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
|
||||
assert_kind_of tc, argument
|
||||
|
||||
expected = [:test1, :block, :proc, :method,
|
||||
:test2, :block, :proc, :method]
|
||||
|
||||
assert_equal expected, call_order
|
||||
end
|
||||
|
||||
def test_setup_and_teardown_hooks_survive_inheritance
|
||||
call_order = []
|
||||
|
||||
parent = Class.new(MiniTest::Unit::TestCase) do
|
||||
define_method :setup do
|
||||
super()
|
||||
call_order << :setup_method
|
||||
end
|
||||
|
||||
define_method :teardown do
|
||||
super()
|
||||
call_order << :teardown_method
|
||||
end
|
||||
|
||||
define_method :test_something do
|
||||
call_order << :test
|
||||
end
|
||||
end
|
||||
|
||||
parent.add_setup_hook { call_order << :setup_hook }
|
||||
parent.add_teardown_hook { call_order << :teardown_hook }
|
||||
|
||||
_ = Class.new parent
|
||||
|
||||
parent.add_setup_hook { call_order << :setup_after }
|
||||
parent.add_teardown_hook { call_order << :teardown_after }
|
||||
|
||||
@tu.run %w[--seed 42]
|
||||
|
||||
# Once for the parent class, once for the child
|
||||
expected = [:setup_method, :setup_hook, :setup_after, :test,
|
||||
:teardown_after, :teardown_hook, :teardown_method] * 2
|
||||
|
||||
assert_equal expected, call_order
|
||||
end
|
||||
|
||||
def util_expand_bt bt
|
||||
if RUBY_VERSION =~ /^1\.9/ then
|
||||
bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
|
||||
@ -1084,6 +1228,11 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
|
||||
@tc.pass
|
||||
end
|
||||
|
||||
def test_prints
|
||||
printer = Class.new { extend MiniTest::Assertions }
|
||||
@tc.assert_equal '"test"', printer.mu_pp(ImmutableString.new 'test')
|
||||
end
|
||||
|
||||
def test_refute
|
||||
@assertion_count = 2
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user