ruby-changes:17160
From: ryan <ko1@a...>
Date: Wed, 1 Sep 2010 17:41:09 +0900 (JST)
Subject: [ruby-changes:17160] Ruby:r29159 (trunk): Imported minitest 1.7.1 r5835
ryan 2010-09-01 17:40:53 +0900 (Wed, 01 Sep 2010) New Revision: 29159 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29159 Log: Imported minitest 1.7.1 r5835 Modified files: trunk/ChangeLog trunk/lib/minitest/spec.rb trunk/lib/minitest/unit.rb trunk/test/minitest/test_mini_spec.rb trunk/test/minitest/test_mini_test.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 29158) +++ ChangeLog (revision 29159) @@ -1,3 +1,8 @@ +Wed Sep 1 17:39:02 2010 Ryan Davis <ryand-ruby@z...> + + * lib/minitest/*.rb: Imported minitest 1.7.1 r5835. + * test/minitest/*.rb: ditto. + Wed Sep 1 16:50:42 2010 NARUSE, Yui <naruse@r...> * string.c (tr_setup_table): optimized. don't create hash objects Index: lib/minitest/unit.rb =================================================================== --- lib/minitest/unit.rb (revision 29158) +++ lib/minitest/unit.rb (revision 29159) @@ -195,6 +195,24 @@ 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. + # + # See also: #assert_silent + + def assert_output stdout = nil, stderr = nil + out, err = capture_io do + yield + end + + x = assert_equal stdout, out, "In stdout" if stdout + y = assert_equal stderr, err, "In stderr" if stderr + + (!stdout || x) && (!stderr || y) + end + + ## # Fails unless the block raises one of +exp+ def assert_raises *exp @@ -252,6 +270,17 @@ 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 @@ -474,7 +503,7 @@ end class Unit - VERSION = "1.6.0" # :nodoc: + VERSION = "1.7.1" # :nodoc: attr_accessor :report, :failures, :errors, :skips # :nodoc: attr_accessor :test_count, :assertion_count # :nodoc: @@ -588,6 +617,12 @@ srand seed + help = ["--seed", seed] + help.push "--verbose" if @verbose + help.push("--name", options[:filter].inspect) if options[:filter] + + @@out.puts "Test run options: #{help.join(" ")}" + @@out.puts @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted" start = Time.now @@ -606,10 +641,6 @@ @@out.puts - help = ["--seed", seed] - help.push "--verbose" if @verbose - help.push("--name", options[:filter].inspect) if options[:filter] - @@out.puts "Test run options: #{help.join(" ")}" return failures + errors if @test_count > 0 # or return nil... Index: lib/minitest/spec.rb =================================================================== --- lib/minitest/spec.rb (revision 29158) +++ lib/minitest/spec.rb (revision 29159) @@ -55,7 +55,7 @@ /_in_/ => '_be_within_', /_operator/ => '_be', /_includes/ => '_include', - /(must|wont)_(.*_of|nil|empty)/ => '\1_be_\2', + /(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2', /must_raises/ => 'must_raise') class Object @@ -84,6 +84,7 @@ stack.push cls cls.class_eval(&block) stack.pop + cls end private :describe end @@ -203,6 +204,10 @@ # 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 @@ -223,6 +228,10 @@ # See MiniTest::Assertions#assert_match ## + # :method: must_output + # See MiniTest::Assertions#assert_output + + ## # :method: must_raise # See MiniTest::Assertions#assert_raises @@ -271,6 +280,10 @@ # See MiniTest::Assertions#refute_in_delta ## + # :method: wont_be_within_delta + # See MiniTest::Assertions#refute_in_delta + + ## # :method: wont_be_within_epsilon # See MiniTest::Assertions#refute_in_epsilon Index: test/minitest/test_mini_spec.rb =================================================================== --- test/minitest/test_mini_spec.rb (revision 29158) +++ test/minitest/test_mini_spec.rb (revision 29159) @@ -35,18 +35,22 @@ 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_raise must_respond_to must_send must_throw) + bad = %w[not raise throw send output be_silent] + expected_wonts = expected_musts.map { |m| m.sub(/^must/, 'wont') } - expected_wonts.reject! { |m| m =~ /wont_(not|raise|throw|send)/ } + expected_wonts.reject! { |m| m =~ /wont_#{Regexp.union(*bad)}/ } musts.must_equal expected_musts wonts.must_equal expected_wonts @@ -158,6 +162,32 @@ proc { 1.wont_be_same_as 1 }.must_raise MiniTest::Assertion end + it "needs to verify output in stdout" do + proc { print "blah" }.must_output("blah").must_equal true + + proc { + proc { print "xxx" }.must_output("blah") + }.must_raise MiniTest::Assertion + end + + it "needs to verify output in stderr" do + proc { $stderr.print "blah" }.must_output(nil, "blah").must_equal true + + proc { + proc { $stderr.print "xxx" }.must_output(nil, "blah") + }.must_raise MiniTest::Assertion + end + + it "needs to ensure silence" do + @assertion_count = 5 + + proc { }.must_be_silent.must_equal true + + proc { + proc { print "xxx" }.must_be_silent + }.must_raise MiniTest::Assertion + end + it "needs to be sensible about must_include order" do @assertion_count = 6 [1, 2, 3].must_include(2).must_equal true @@ -170,3 +200,26 @@ proc { [1, 2, 3].wont_include 2 }.must_raise MiniTest::Assertion end end + +class TestMeta < MiniTest::Unit::TestCase + def test_structure + x = y = nil + x = describe "top-level thingy" do + before {} + after {} + + it "top-level-it" do end + + y = describe "inner thingy" do + before {} + it "inner-it" do end + end + end + + top_methods = %w(setup teardown test_0001_top_level_it) + inner_methods = %w(setup 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 } + end +end Index: test/minitest/test_mini_test.rb =================================================================== --- test/minitest/test_mini_test.rb (revision 29158) +++ test/minitest/test_mini_test.rb (revision 29159) @@ -14,20 +14,6 @@ class E < StandardError; include M; end class TestMiniTest < MiniTest::Unit::TestCase - def setup - srand 42 - MiniTest::Unit::TestCase.reset - @tu = MiniTest::Unit.new - @output = StringIO.new("") - MiniTest::Unit.output = @output - assert_equal [0, 0], @tu.run_test_suites - end - - def teardown - MiniTest::Unit.output = $stdout - Object.send :remove_const, :ATestCase if defined? ATestCase - end - pwd = Pathname.new(File.expand_path(Dir.pwd)) basedir = Pathname.new(File.expand_path(MiniTest::MINI_DIR)) + 'mini' basedir = basedir.relative_path_from(pwd).to_s @@ -40,56 +26,39 @@ "#{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 + def assert_report expected = nil + expected ||= "Test run options: --seed 42 - ex = ["lib/autotest.rb:571:in `add_exception'", - "test/test_autotest.rb:62:in `test_add_exception'"] - ex = util_expand_bt ex +Loaded suite blah +Started +. +Finished in 0.00 - fu = MiniTest::filter_backtrace(bt) +1 tests, 1 assertions, 0 failures, 0 errors, 0 skips - assert_equal ex, fu +Test run options: --seed 42 +" + output = @output.string.sub(/Finished in .*/, "Finished in 0.00") + output.sub!(/Loaded suite .*/, 'Loaded suite blah') + output.sub!(/^(\s+)(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+:/o, '\1FILE:LINE:') + output.sub!(/\[(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+\]/o, '[FILE:LINE]') + assert_equal(expected, output) end - def util_expand_bt bt - if RUBY_VERSION =~ /^1\.9/ then - bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f } - else - bt - end + def setup + srand 42 + MiniTest::Unit::TestCase.reset + @tu = MiniTest::Unit.new + @output = StringIO.new("") + MiniTest::Unit.output = @output + assert_equal [0, 0], @tu.run_test_suites 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 + def teardown + MiniTest::Unit.output = $stdout + Object.send :remove_const, :ATestCase if defined? ATestCase 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"] - fu = MiniTest::filter_backtrace(bt) - assert_equal ex, fu - end - def test_class_puke_with_assertion_failed exception = MiniTest::Assertion.new "Oh no!" exception.set_backtrace ["unhappy"] @@ -99,16 +68,6 @@ assert_match("method_name(SomeClass) [unhappy]", @tu.report.first) end - def test_class_puke_with_failure_and_flunk_in_backtrace - exception = begin - MiniTest::Unit::TestCase.new('fake tc').flunk - rescue MiniTest::Assertion => failure - failure - end - assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception) - refute @tu.report.any?{|line| line =~ /in .flunk/} - end - def test_class_puke_with_assertion_failed_and_long_backtrace bt = (["test/test_some_class.rb:615:in `method_name'", "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'", @@ -152,6 +111,16 @@ assert_match("test_method_name(TestSomeClass) [#{ex_location}]", @tu.report.first) end + def test_class_puke_with_failure_and_flunk_in_backtrace + exception = begin + MiniTest::Unit::TestCase.new('fake tc').flunk + rescue MiniTest::Assertion => failure + failure + end + assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception) + refute @tu.report.any?{|line| line =~ /in .flunk/} + end + def test_class_puke_with_flunk_and_user_defined_assertions bt = (["lib/test/my/util.rb:16:in `flunk'", "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'", @@ -194,35 +163,46 @@ assert_equal [1, 1], @tu.run_test_suites end - def test_run_failing # TODO: add error test - tc = Class.new(MiniTest::Unit::TestCase) do - def test_something - assert true - end + 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 - def test_failure - assert false - end - end + ex = ["lib/autotest.rb:571:in `add_exception'", + "test/test_autotest.rb:62:in `test_add_exception'"] + ex = util_expand_bt ex - Object.const_set(:ATestCase, tc) + fu = MiniTest::filter_backtrace(bt) - @tu.run %w[-s 42] + assert_equal ex, fu + end - expected = "Loaded suite blah -Started -F. -Finished in 0.00 + 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 - 1) Failure: -test_failure(ATestCase) [FILE:LINE]: -Failed assertion, no message given. + 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"]) -2 tests, 2 assertions, 1 failures, 0 errors, 0 skips + bt = util_expand_bt bt -Test run options: --seed 42 -" - util_assert_report expected + ex = ["-e:1"] + fu = MiniTest::filter_backtrace(bt) + assert_equal ex, fu end def test_run_error @@ -240,7 +220,9 @@ @tu.run %w[-s 42] - expected = "Loaded suite blah + expected = "Test run options: --seed 42 + +Loaded suite blah Started E. Finished in 0.00 @@ -254,7 +236,7 @@ Test run options: --seed 42 " - util_assert_report expected + assert_report expected end def test_run_error_teardown @@ -272,7 +254,9 @@ @tu.run %w[-s 42] - expected = "Loaded suite blah + expected = "Test run options: --seed 42 + +Loaded suite blah Started E Finished in 0.00 @@ -286,17 +270,17 @@ Test run options: --seed 42 " - util_assert_report expected + assert_report expected end - def test_run_skip + def test_run_failing # TODO: add error test tc = Class.new(MiniTest::Unit::TestCase) do def test_something assert true end - def test_skip - skip "not yet" + def test_failure + assert false end end @@ -304,39 +288,24 @@ @tu.run %w[-s 42] - expected = "Loaded suite blah + expected = "Test run options: --seed 42 + +Loaded suite blah Started -S. +F. Finished in 0.00 - 1) Skipped: -test_skip(ATestCase) [FILE:LINE]: -not yet + 1) Failure: +test_failure(ATestCase) [FILE:LINE]: +Failed assertion, no message given. -2 tests, 1 assertions, 0 failures, 0 errors, 1 skips +2 tests, 2 assertions, 1 failures, 0 errors, 0 skips Test run options: --seed 42 " - util_assert_report expected + assert_report expected end - def util_assert_report expected = nil - expected ||= "Loaded suite blah -Started -. -Finished in 0.00 - -1 tests, 1 assertions, 0 failures, 0 errors, 0 skips - -Test run options: --seed 42 -" - output = @output.string.sub(/Finished in .*/, "Finished in 0.00") - output.sub!(/Loaded suite .*/, 'Loaded suite blah') - output.sub!(/^(\s+)(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+:/o, '\1FILE:LINE:') - output.sub!(/\[(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+\]/o, '[FILE:LINE]') - assert_equal(expected, output) - end - def test_run_failing_filtered tc = Class.new(MiniTest::Unit::TestCase) do def test_something @@ -352,7 +321,9 @@ @tu.run %w[-n /something/ -s 42] - expected = "Loaded suite blah + expected = "Test run options: --seed 42 --name \"/something/\" + +Loaded suite blah Started . Finished in 0.00 @@ -361,7 +332,7 @@ Test run options: --seed 42 --name \"/something/\" " - util_assert_report expected + assert_report expected end def test_run_passing @@ -375,8 +346,49 @@ @tu.run %w[-s 42] - util_assert_report + assert_report end + + def test_run_skip + tc = Class.new(MiniTest::Unit::TestCase) do + def test_something + assert true + end + + def test_skip + skip "not yet" + end + end + + Object.const_set(:ATestCase, tc) + + @tu.run %w[-s 42] + + expected = "Test run options: --seed 42 + +Loaded suite blah +Started +S. +Finished in 0.00 + + 1) Skipped: +test_skip(ATestCase) [FILE:LINE]: +not yet + +2 tests, 1 assertions, 0 failures, 0 errors, 1 skips + +Test run options: --seed 42 +" + assert_report expected + end + + def util_expand_bt bt + if RUBY_VERSION =~ /^1\.9/ then + bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f } + else + bt + end + end end class TestMiniTestTestCase < MiniTest::Unit::TestCase @@ -394,39 +406,6 @@ Object.send :remove_const, :ATestCase if defined? ATestCase end - def test_class_inherited - @assertion_count = 0 - - Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase)) - - assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites - end - - def test_class_test_suites - @assertion_count = 0 - - Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase)) - - assert_equal 1, MiniTest::Unit::TestCase.test_suites.size - assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites - end - - def test_class_asserts_match_refutes - @assertion_count = 0 - - methods = MiniTest::Assertions.public_instance_methods - methods.map! { |m| m.to_s } if Symbol === methods.first - - ignores = %w(assert_block assert_no_match assert_not_equal assert_not_nil - assert_not_same assert_nothing_thrown assert_raise - assert_nothing_raised assert_raises assert_throws assert_send) - 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_assert @assertion_count = 2 @@ -603,6 +582,60 @@ 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_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 + util_assert_triggered "In stdout.\nExpected \"yay\", not \"boo\"." do + @tc.assert_output "yay", "blah" do + print "boo" + $stderr.print "blah blah" + end + end + end + + def test_assert_output_triggered_err + util_assert_triggered "In stderr.\nExpected \"blah\", not \"blah blah\"." do + @tc.assert_output nil, "blah" do + $stderr.print "blah blah" + end + end + end + + def test_assert_output_triggered_out + util_assert_triggered "In stdout.\nExpected \"blah\", not \"blah blah\"." do + @tc.assert_output "blah" do + print "blah blah" + end + end + end + def test_assert_raises @tc.assert_raises RuntimeError do raise "blah" @@ -744,6 +777,32 @@ end end + def test_assert_silent + @assertion_count = 2 + + @tc.assert_silent do + # do nothing + end + end + + def test_assert_silent_triggered_err + @assertion_count = 2 + + util_assert_triggered "In stderr.\nExpected \"\", not \"blah blah\"." do + @tc.assert_silent do + $stderr.print "blah blah" + end + end + end + + def test_assert_silent_triggered_out + util_assert_triggered "In stdout.\nExpected \"\", not \"blah blah\"." do + @tc.assert_silent do + print "blah blah" + end + end + end + def test_assert_throws @tc.assert_throws(:blah) do throw :blah @@ -778,6 +837,41 @@ assert_equal "bye!\n", err end + def test_class_asserts_match_refutes + @assertion_count = 0 + + methods = MiniTest::Assertions.public_instance_methods + methods.map! { |m| m.to_s } if Symbol === methods.first + + ignores = %w(assert_block assert_no_match assert_not_equal + assert_not_nil assert_not_same assert_nothing_raised + assert_nothing_thrown assert_output assert_raise + assert_raises assert_send assert_silent assert_throws) + + 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_class_inherited + @assertion_count = 0 + + Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase)) + + assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites + end + + def test_class_test_suites + @assertion_count = 0 + + Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase)) + + assert_equal 1, MiniTest::Unit::TestCase.test_suites.size + assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites + end + def test_flunk util_assert_triggered 'Epic Fail!' do @tc.flunk @@ -802,34 +896,6 @@ @tc.pass end - def test_test_methods_sorted - @assertion_count = 0 - - sample_test_case = Class.new(MiniTest::Unit::TestCase) 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.test_methods - end - - def test_test_methods_random - @assertion_count = 0 - - sample_test_case = Class.new(MiniTest::Unit::TestCase) do - def test_test1; assert "does not matter" end - def test_test2; assert "does not matter" end - def test_test3; assert "does not matter" end - end - - srand 42 - expected = %w(test_test2 test_test1 test_test3) - assert_equal expected, sample_test_case.test_methods - end - def test_refute @assertion_count = 2 @@ -928,18 +994,6 @@ @tc.refute_match Object.new, 5 # default #=~ returns false end - def test_assert_object_triggered - @assertion_count = 2 - - pattern = Object.new - def pattern.=~(other) false end - def pattern.inspect; "<<Object>>" end - - util_assert_triggered 'Expected <<Object>> to match 5.' do - @tc.assert_match pattern, 5 - end - end - def test_refute_match_object_triggered @assertion_count = 2 @@ -1007,6 +1061,34 @@ end end + def test_test_methods_random + @assertion_count = 0 + + sample_test_case = Class.new(MiniTest::Unit::TestCase) do + def test_test1; assert "does not matter" end + def test_test2; assert "does not matter" end + def test_test3; assert "does not matter" end + end + + srand 42 + expected = %w(test_test2 test_test1 test_test3) + assert_equal expected, sample_test_case.test_methods + end + + def test_test_methods_sorted + @assertion_count = 0 + + sample_test_case = Class.new(MiniTest::Unit::TestCase) 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.test_methods + end + def util_assert_triggered expected, klass = MiniTest::Assertion e = assert_raises(klass) do yield -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/