test-unit-3.3.9/0000755000004100000410000000000013775322563013527 5ustar www-datawww-datatest-unit-3.3.9/test-unit.gemspec0000644000004100000410000001711313775322563017033 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: test-unit 3.3.9 ruby lib Gem::Specification.new do |s| s.name = "test-unit".freeze s.version = "3.3.9" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "source_code_uri" => "https://github.com/test-unit/test-unit" } if s.respond_to? :metadata= s.require_paths = ["lib".freeze] s.authors = ["Kouhei Sutou".freeze, "Haruka Yoshihara".freeze] s.date = "2020-12-28" s.description = "test-unit (Test::Unit) is unit testing framework for Ruby, based on xUnit\nprinciples. These were originally designed by Kent Beck, creator of extreme\nprogramming software development methodology, for Smalltalk's SUnit. It allows\nwriting tests, checking results and automated testing in Ruby.\n".freeze s.email = ["kou@cozmixng.org".freeze, "yoshihara@clear-code.com".freeze] s.files = ["BSDL".freeze, "COPYING".freeze, "PSFL".freeze, "README.md".freeze, "Rakefile".freeze, "doc/text/getting-started.md".freeze, "doc/text/how-to.md".freeze, "doc/text/news.md".freeze, "lib/test-unit.rb".freeze, "lib/test/unit.rb".freeze, "lib/test/unit/assertion-failed-error.rb".freeze, "lib/test/unit/assertions.rb".freeze, "lib/test/unit/attribute-matcher.rb".freeze, "lib/test/unit/attribute.rb".freeze, "lib/test/unit/auto-runner-loader.rb".freeze, "lib/test/unit/autorunner.rb".freeze, "lib/test/unit/code-snippet-fetcher.rb".freeze, "lib/test/unit/collector.rb".freeze, "lib/test/unit/collector/descendant.rb".freeze, "lib/test/unit/collector/dir.rb".freeze, "lib/test/unit/collector/load.rb".freeze, "lib/test/unit/collector/objectspace.rb".freeze, "lib/test/unit/collector/xml.rb".freeze, "lib/test/unit/color-scheme.rb".freeze, "lib/test/unit/color.rb".freeze, "lib/test/unit/data-sets.rb".freeze, "lib/test/unit/data.rb".freeze, "lib/test/unit/diff.rb".freeze, "lib/test/unit/error.rb".freeze, "lib/test/unit/exception-handler.rb".freeze, "lib/test/unit/failure.rb".freeze, "lib/test/unit/fault-location-detector.rb".freeze, "lib/test/unit/fixture.rb".freeze, "lib/test/unit/notification.rb".freeze, "lib/test/unit/omission.rb".freeze, "lib/test/unit/pending.rb".freeze, "lib/test/unit/priority.rb".freeze, "lib/test/unit/runner/console.rb".freeze, "lib/test/unit/runner/emacs.rb".freeze, "lib/test/unit/runner/xml.rb".freeze, "lib/test/unit/test-suite-creator.rb".freeze, "lib/test/unit/testcase.rb".freeze, "lib/test/unit/testresult.rb".freeze, "lib/test/unit/testsuite.rb".freeze, "lib/test/unit/ui/console/outputlevel.rb".freeze, "lib/test/unit/ui/console/testrunner.rb".freeze, "lib/test/unit/ui/emacs/testrunner.rb".freeze, "lib/test/unit/ui/testrunner.rb".freeze, "lib/test/unit/ui/testrunnermediator.rb".freeze, "lib/test/unit/ui/testrunnerutilities.rb".freeze, "lib/test/unit/ui/xml/testrunner.rb".freeze, "lib/test/unit/util/backtracefilter.rb".freeze, "lib/test/unit/util/method-owner-finder.rb".freeze, "lib/test/unit/util/observable.rb".freeze, "lib/test/unit/util/output.rb".freeze, "lib/test/unit/util/procwrapper.rb".freeze, "lib/test/unit/version.rb".freeze, "sample/adder.rb".freeze, "sample/subtracter.rb".freeze, "sample/test_adder.rb".freeze, "sample/test_subtracter.rb".freeze, "sample/test_user.rb".freeze, "test/collector/test-descendant.rb".freeze, "test/collector/test-load.rb".freeze, "test/collector/test_dir.rb".freeze, "test/collector/test_objectspace.rb".freeze, "test/fixtures/header-label.csv".freeze, "test/fixtures/header-label.tsv".freeze, "test/fixtures/header.csv".freeze, "test/fixtures/header.tsv".freeze, "test/fixtures/no-header.csv".freeze, "test/fixtures/no-header.tsv".freeze, "test/fixtures/plus.csv".freeze, "test/run-test.rb".freeze, "test/test-assertions.rb".freeze, "test/test-attribute-matcher.rb".freeze, "test/test-attribute.rb".freeze, "test/test-code-snippet.rb".freeze, "test/test-color-scheme.rb".freeze, "test/test-color.rb".freeze, "test/test-data.rb".freeze, "test/test-diff.rb".freeze, "test/test-emacs-runner.rb".freeze, "test/test-error.rb".freeze, "test/test-failure.rb".freeze, "test/test-fault-location-detector.rb".freeze, "test/test-fixture.rb".freeze, "test/test-notification.rb".freeze, "test/test-omission.rb".freeze, "test/test-pending.rb".freeze, "test/test-priority.rb".freeze, "test/test-test-case.rb".freeze, "test/test-test-result.rb".freeze, "test/test-test-suite-creator.rb".freeze, "test/test-test-suite.rb".freeze, "test/testunit-test-util.rb".freeze, "test/ui/test_testrunmediator.rb".freeze, "test/util/test-method-owner-finder.rb".freeze, "test/util/test-output.rb".freeze, "test/util/test_backtracefilter.rb".freeze, "test/util/test_observable.rb".freeze, "test/util/test_procwrapper.rb".freeze] s.homepage = "http://test-unit.github.io/".freeze s.licenses = ["Ruby".freeze, "BSDL".freeze, "PSFL".freeze] s.rubygems_version = "2.5.2.1".freeze s.summary = "An xUnit family unit testing framework for Ruby.".freeze s.test_files = ["test/collector/test-descendant.rb".freeze, "test/collector/test-load.rb".freeze, "test/collector/test_dir.rb".freeze, "test/collector/test_objectspace.rb".freeze, "test/fixtures/header-label.csv".freeze, "test/fixtures/header-label.tsv".freeze, "test/fixtures/header.csv".freeze, "test/fixtures/header.tsv".freeze, "test/fixtures/no-header.csv".freeze, "test/fixtures/no-header.tsv".freeze, "test/fixtures/plus.csv".freeze, "test/run-test.rb".freeze, "test/test-assertions.rb".freeze, "test/test-attribute-matcher.rb".freeze, "test/test-attribute.rb".freeze, "test/test-code-snippet.rb".freeze, "test/test-color-scheme.rb".freeze, "test/test-color.rb".freeze, "test/test-data.rb".freeze, "test/test-diff.rb".freeze, "test/test-emacs-runner.rb".freeze, "test/test-error.rb".freeze, "test/test-failure.rb".freeze, "test/test-fault-location-detector.rb".freeze, "test/test-fixture.rb".freeze, "test/test-notification.rb".freeze, "test/test-omission.rb".freeze, "test/test-pending.rb".freeze, "test/test-priority.rb".freeze, "test/test-test-case.rb".freeze, "test/test-test-result.rb".freeze, "test/test-test-suite-creator.rb".freeze, "test/test-test-suite.rb".freeze, "test/testunit-test-util.rb".freeze, "test/ui/test_testrunmediator.rb".freeze, "test/util/test-method-owner-finder.rb".freeze, "test/util/test-output.rb".freeze, "test/util/test_backtracefilter.rb".freeze, "test/util/test_observable.rb".freeze, "test/util/test_procwrapper.rb".freeze] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end end test-unit-3.3.9/COPYING0000644000004100000410000000504113775322563014562 0ustar www-datawww-datatest-unit is copyrighted free software by Kouhei Sutou , Ryan Davis and Nathaniel Talbott . You can redistribute it and/or modify it under either the terms of the 2-clause BSDL (see the file BSDL), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, provided that you do at least ONE of the following: a. place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software. b. use the modified software only within your corporation or organization. c. give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d. make other distribution arrangements with the author. 3. You may distribute the software in object code or binary form, provided that you do at least ONE of the following: a. distribute the binaries and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b. accompany the distribution with the machine-readable source of the software. c. give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d. make other distribution arrangements with the author. 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the author, so that they are not under these terms. For the list of those files and their copying conditions, see the file LEGAL. 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Exceptions ---------- * lib/test/unit/diff.rb: This license and PSF license test-unit-3.3.9/test/0000755000004100000410000000000013775322563014506 5ustar www-datawww-datatest-unit-3.3.9/test/test-assertions.rb0000644000004100000410000017334713775322563020221 0ustar www-datawww-data# -*- coding: utf-8 -*- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # Copyright (c) 2009-2014 Kouhei Sutou. All rights reserved. # License:: Ruby license. require 'test/unit' require "testunit-test-util" module Test module Unit module AssertionCheckable include TestUnitTestUtil private def check(value, message="") add_assertion raise AssertionFailedError.new(message) unless value end def check_assertions(expect_fail, options={}) expected_message = options[:expected_message] actual_message_normalizer = options[:actual_message_normalizer] return_value_expected = options[:return_value_expected] @actual_assertion_count = 0 failed = true actual_message = nil @catch_assertions = true return_value = nil begin return_value = yield failed = false rescue AssertionFailedError => error return_value = error actual_message = error.message end @catch_assertions = false if expect_fail message = "Should have failed, but didn't" else message = "Should not have failed, but did with message\n" + "<#{actual_message}>" end check(expect_fail == failed, message) message = "Should have made one assertion but made\n" + "<#{@actual_assertion_count}>" check(1 == @actual_assertion_count, message) if expect_fail if actual_message_normalizer actual_message = actual_message_normalizer.call(actual_message) end case expected_message when String check(expected_message == actual_message, "Should have the correct message.\n" + "<#{expected_message.inspect}> expected but was\n" + "<#{actual_message.inspect}>") when Regexp check(expected_message =~ actual_message, "The message should match correctly.\n" + " expected to match\n" + "<#{actual_message.inspect}>") else check(false, "Incorrect expected message type in assert_nothing_failed") end else case return_value_expected when :dont_care # do nothing when true check(!return_value.nil?, "Should return a value") else check(return_value.nil?, "Should not return a value but returned <#{return_value}>") end end return_value end def check_nothing_fails(return_value_expected=false, &proc) check_assertions(false, {:expected_message => nil, :return_value_expected => return_value_expected}, &proc) end def check_fail(expected_message, options={}, &proc) check_assertions(true, options.merge(:expected_message => expected_message), &proc) end def check_fail_exception(expected_message, options={}, &proc) normalizer = lambda do |actual_message| actual_message.gsub(/^(?: )?[^:\n]+:\d+:.+\n/, "") end check_assertions(true, options.merge(:expected_message => expected_message, :actual_message_normalizer => normalizer), &proc) end def inspect_tag(tag) tag.inspect end def add_failure(message, location=caller, options=nil) unless @catch_assertions super end end def add_assertion if @catch_assertions @actual_assertion_count += 1 else super end end end class TestAssertions < TestCase include AssertionCheckable class TestAssertBlock < self def test_pass_without_message check_nothing_fails { assert_block {true} } end def test_pass_with_message check_nothing_fails { assert_block("successful assert_block") {true} } end def test_failure_without_message check_fail("assert_block failed.") { assert_block {false} } end def test_failure_with_message check_fail("failed assert_block") { assert_block("failed assert_block") {false} } end end class TestAssertEqual < self class TestSuccess < self def test_without_message check_nothing_fails { assert_equal("string1", "string1") } end def test_with_message check_nothing_fails { assert_equal("string1", "string1", "successful assert_equal") } end end class TestFailure < self def test_without_message message = <<-EOM.chomp <"string1"> expected but was <"string2">. diff: - string1 ? ^ + string2 ? ^ EOM check_fail(message) { assert_equal("string1", "string2") } end def test_with_message message = <<-EOM.chomp failed assert_equal. <"string1"> expected but was <"string2">. diff: - string1 ? ^ + string2 ? ^ EOM check_fail(message) { assert_equal("string1", "string2", "failed assert_equal") } end def test_with_message_proc message = <<-EOM.chomp failed assert_equal. <"string1"> expected but was <"string2">. diff: - string1 ? ^ + string2 ? ^ EOM check_fail(message) do assert_equal("string1", "string2", lambda {"failed assert_equal"}) end end end class TestSystemMessage < self def test_different_type message = <<-EOM.chomp <"111111"> expected but was <111111>. diff: - "111111" ? - - + 111111 EOM check_fail(message) do assert_equal("111111", 111111) end end def test_long_line expected = ["0123456789", "1123456789", "2123456789", "3123456789", "4123456789", "5123456789", "6123456789", "7123456789", "8123456789"].join actual = ["0000000000", "1123456789", "2123456789", "3123456789", "4123456789", "5123456789", "6123456789", "7123456789", "8123456789"].join message = <<-EOM.chomp <"#{expected}"> expected but was <"#{actual}">. diff: - #{expected} ? ^^^^^^^^^ + #{actual} ? ^^^^^^^^^ folded diff: - 012345678911234567892123456789312345678941234567895123456789612345678971234567 ? ^^^^^^^^^ + 000000000011234567892123456789312345678941234567895123456789612345678971234567 ? ^^^^^^^^^ 898123456789 EOM check_fail(message) do assert_equal(expected, actual) end end def test_too_small_difference message = <<-EOM.chomp <1> expected but was <2>. EOM check_fail(message) do assert_equal(1, 2) end end def test_same_inspected_objects same_inspected_class = Class.new do def inspect "inspected" end end object1 = same_inspected_class.new object2 = same_inspected_class.new message = <<-EOM.chomp expected but was . EOM check_fail(message) do assert_equal(object1, object2) end end def test_multi_lines_result message = <<-EOM.chomp <#{AssertionMessage.convert("a\nb")}> expected but was <#{AssertionMessage.convert("x")}>. diff: + x - a - b EOM check_fail(message) do assert_equal("a\nb", "x") end end def test_large_string message = <<-EOM.chomp <#{AssertionMessage.convert("a\n" + "x" * 997)}> expected but was <#{AssertionMessage.convert("x")}>. diff: + x - a - #{"x" * 997} folded diff: + x - a #{(["- " + ("x" * 78)] * 12).join("\n")} - #{"x" * 61} EOM check_fail(message) do assert_equal("a\n" + "x" * 997, "x") end message = <<-EOM.chomp <#{AssertionMessage.convert("a\n" + "x" * 998)}> expected but was <#{AssertionMessage.convert("x")}>. EOM check_fail(message) do assert_equal("a\n" + "x" * 998, "x") end end def test_max_diff_target_string_size key = "TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE" before_value = ENV[key] ENV[key] = "100" begin message = <<-EOM.chomp <#{AssertionMessage.convert("a\n" + "x" * 97)}> expected but was <#{AssertionMessage.convert("x")}>. diff: + x - a - #{"x" * 97} folded diff: + x - a #{(["- " + ("x" * 78)]).join("\n")} - #{"x" * 19} EOM check_fail(message) do assert_equal("a\n" + "x" * 97, "x") end message = <<-EOM.chomp <#{AssertionMessage.convert("a\n" + "x" * 98)}> expected but was <#{AssertionMessage.convert("x")}>. EOM check_fail(message) do assert_equal("a\n" + "x" * 98, "x") end ensure ENV[key] = before_value end end def test_different_encoding utf8_string = "こんにちは" unless utf8_string.respond_to?(:force_encoding) omit("encoding test is for Ruby >= 1.9") end ascii_8bit_string = utf8_string.dup.force_encoding("ascii-8bit") message = <<-EOM.chomp <#{utf8_string.inspect}>("UTF-8") expected but was <#{ascii_8bit_string.inspect}>("ASCII-8BIT"). EOM check_fail(message) do assert_equal(utf8_string, ascii_8bit_string) end end def test_different_hash designers = { "Ruby" => "Matz", "Lisp" => "John McCarthy", } categories = { "LL" => ["Ruby", "Python"], "Heavy" => ["C", "C++"], } message = <<-EOM.chomp <{"Lisp"=>"John McCarthy", "Ruby"=>"Matz"}> expected but was <{"Heavy"=>["C", "C++"], "LL"=>["Ruby", "Python"]}>. EOM check_fail(message) do assert_equal(designers, categories) end end def test_recursive_hash alice = {"name" => "Alice"} bob = {"name" => "Bob"} alice["followers"] = [bob] bob["followers"] = [alice] message = <<-EOM.chomp <{"followers"=>[{"followers"=>[{...}], "name"=>"Bob"}], "name"=>"Alice"}> expected but was <{"followers"=>[{"followers"=>[{...}], "name"=>"Alice"}], "name"=>"Bob"}>. diff: - {"followers"=>[{"followers"=>[{...}], "name"=>"Bob"}], "name"=>"Alice"} ? ----------------- + {"followers"=>[{"followers"=>[{...}], "name"=>"Alice"}], "name"=>"Bob"} ? +++++++++++++++++ EOM check_fail(message) do assert_equal(alice, bob) end end def test_numeric numeric_family_class = Class.new(Numeric) do def inspect "inspect is called" end def to_s "to_s is called" end end numeric = numeric_family_class.new message = <<-MESSAGE.chomp expected but was <"must be failed">. MESSAGE check_fail(message) do assert_equal(numeric, "must be failed") end end end end def test_assert_raise_success return_value = nil check_nothing_fails(true) do return_value = assert_raise(RuntimeError) do raise "Error" end end check(return_value.kind_of?(Exception), "Should have returned the exception " + "from a successful assert_raise") check(return_value.message == "Error", "Should have returned the correct exception " + "from a successful assert_raise") check_nothing_fails(true) do assert_raise(ArgumentError, "successful assert_raise") do raise ArgumentError.new("Error") end end check_nothing_fails(true) do assert_raise(RuntimeError) do raise "Error" end end check_nothing_fails(true) do assert_raise(RuntimeError, "successful assert_raise") do raise "Error" end end check_nothing_fails(true) do assert_raise do raise Exception, "Any exception" end end end def test_assert_raise_fail check_fail(" exception was expected but none was thrown.") do assert_raise(RuntimeError) do 1 + 1 end end message = <<-EOM.chomp failed assert_raise. exception expected but was ) >. EOM check_fail_exception(message) do assert_raise(ArgumentError, "failed assert_raise") do raise "Error" end end message = <<-EOM must be a subclass of Exception, an object of Exception subclasses or a Module. EOM check_fail(message.chomp) do assert_nothing_raised(Object) do 1 + 1 end end end def test_assert_raise_module exceptions = [ArgumentError, TypeError] modules = [Math, Comparable] rescues = exceptions + modules exceptions.each do |exc| return_value = nil check_nothing_fails(true) do return_value = assert_raise(*rescues) do raise exc, "Error" end end check(return_value.instance_of?(exc), "Should have returned #{exc} but was #{return_value.class}") check(return_value.message == "Error", "Should have returned the correct exception " + "from a successful assert_raise") end modules.each do |mod| return_value = nil check_nothing_fails(true) do return_value = assert_raise(*rescues) do raise Exception.new("Error").extend(mod) end end check(mod === return_value, "Should have returned #{mod}") check(return_value.message == "Error", "Should have returned the correct exception " + "from a successful assert_raise") end check_fail("<[ArgumentError, TypeError, Math, Comparable]> exception " + "was expected but none was thrown.") do assert_raise(*rescues) do 1 + 1 end end message = <<-EOM.chomp failed assert_raise. <[ArgumentError, TypeError]> exception expected but was ) >. EOM check_fail_exception(message) do assert_raise(ArgumentError, TypeError, "failed assert_raise") do raise "Error" end end end def test_assert_raise_instance return_value = nil check_nothing_fails(true) do return_value = assert_raise(RuntimeError.new("Error")) do raise "Error" end end check(return_value.kind_of?(Exception), "Should have returned the exception " + "from a successful assert_raise") check(return_value.message == "Error", "Should have returned the correct exception " + "from a successful assert_raise") message = <<-EOM.chomp )> exception expected but was ) >. EOM check_fail_exception(message) do return_value = assert_raise(RuntimeError.new("XXX")) do raise "Error" end end different_error_class = Class.new(StandardError) message = <<-EOM.chomp <#{different_error_class.inspect}()> exception expected but was ) >. EOM check_fail_exception(message) do assert_raise(different_error_class.new("Error")) do raise "Error" end end different_error = different_error_class.new("Error") def different_error.inspect "DifferentError: \"Error\"" end message = <<-EOM.chomp exception expected but was ) >. EOM check_fail_exception(message) do assert_raise(different_error) do raise "Error" end end check_nothing_fails(true) do assert_raise(different_error_class.new("Error"), RuntimeError.new("Error"), RuntimeError.new("XXX")) do raise "Error" end end end def test_assert_raise_jruby jruby_only_test exception = Java::JavaLang::StringIndexOutOfBoundsException return_value = nil check_nothing_fails(true) do return_value = assert_raise(exception) do Java::JavaLang::String.new("abc").char_at(4) end end check(return_value.instance_of?(exception), "Should have returned #{exception} but was #{return_value.class}") end def test_assert_instance_of check_nothing_fails { assert_instance_of(String, "string") } check_nothing_fails { assert_instance_of(String, "string", "successful assert_instance_of") } check_nothing_fails { assert_instance_of(String, "string", "successful assert_instance_of") } check_fail(%Q{<"string"> was expected to be instance_of?\n but was\n.}) { assert_instance_of(Hash, "string") } check_fail(%Q{failed assert_instance_of.\n<"string"> was expected to be instance_of?\n but was\n.}) { assert_instance_of(Hash, "string", "failed assert_instance_of") } check_nothing_fails do assert_instance_of([Class, NilClass], Array) end check_fail(%Q{<"string"> was expected to be instance_of?\n[, ] but was\n.}) do assert_instance_of([Class, NilClass], "string") end check_fail(%Q{ was expected to be instance_of?\n[, ] but was\n.}) do assert_instance_of([Module, NilClass], Array) end end def test_assert_not_instance_of check_nothing_fails { assert_not_instance_of(NilClass, "string") } check_nothing_fails { assert_not_instance_of(NilClass, "string", "successful assert_instance_of") } check_fail(%Q{<"string"> was expected to not be instance_of?\n but was.}) { assert_not_instance_of(String, "string") } check_fail(%Q{failed assert.\n<"string"> was expected to not be instance_of?\n but was.}) { assert_not_instance_of(String, "string", "failed assert") } check_nothing_fails do assert_not_instance_of([Module, NilClass], Array) end check_fail(%Q{ was expected to not be instance_of?\n[, ] but was.}) do assert_not_instance_of([Class, NilClass], Array) end check_fail(%Q{<"str"> was expected to not be instance_of?\n[, ] but was.}) do assert_not_instance_of([Numeric, String], 'str') end end def test_assert_nil check_nothing_fails { assert_nil(nil) } check_nothing_fails { assert_nil(nil, "successful assert_nil") } check_nothing_fails { assert_nil(nil, "successful assert_nil") } check_fail(%Q{<"string"> was expected to be nil.}) { assert_nil("string") } check_fail(%Q{failed assert_nil.\n<"string"> was expected to be nil.}) { assert_nil("string", "failed assert_nil") } end def test_assert_not_nil check_nothing_fails{assert_not_nil(false)} check_nothing_fails{assert_not_nil(false, "message")} check_fail(" was expected to not be nil."){assert_not_nil(nil)} check_fail("message.\n was expected to not be nil.") {assert_not_nil(nil, "message")} end def test_assert_kind_of check_nothing_fails { assert_kind_of(Module, Array) } check_nothing_fails { assert_kind_of(Object, "string", "successful assert_kind_of") } check_nothing_fails { assert_kind_of(String, "string", "successful assert_kind_of") } check_nothing_fails { assert_kind_of(Comparable, 1) } check_fail(%Q{<"string"> was expected to be kind_of?\n but was\n.}) { assert_kind_of(Class, "string") } check_fail(%Q{failed assert_kind_of.\n<"string"> was expected to be kind_of?\n but was\n.}) { assert_kind_of(Class, "string", "failed assert_kind_of") } check_nothing_fails do assert_kind_of([Class, NilClass], Array) end check_fail(%Q{<"string"> was expected to be kind_of?\n[, ] but was\n.}) do assert_kind_of([Class, NilClass], "string") end end def test_assert_not_kind_of check_nothing_fails { assert_not_kind_of(Class, 42) } check_nothing_fails { assert_not_kind_of(Symbol, "string", "successful assert_not_kind_of") } check_nothing_fails { assert_not_kind_of(Integer, 1.1) } check_fail(%Q{<1> was expected to not be kind_of?\n but was.}) { assert_not_kind_of(Integer, 1) } check_fail(%Q{failed assert_not_kind_of.\n<"string"> was expected to not be kind_of?\n but was.}) { assert_not_kind_of(String, "string", "failed assert_not_kind_of") } check_nothing_fails do assert_not_kind_of([String, NilClass], 100) end check_fail(%Q{ was expected to not be kind_of?\n[, ] but was.}) do assert_not_kind_of([Class, NilClass], Array) end end def test_assert_match check_nothing_fails { assert_match(/strin./, "string") } check_nothing_fails { assert_match("strin", "string") } check_nothing_fails { assert_match(/strin./, "string", "successful assert_match") } check_nothing_fails { assert_match(/strin./, "string", "successful assert_match") } check_fail(%Q{ was expected to be =~\n<"string">.}) { assert_match(/slin./, "string") } check_fail(%Q{ was expected to be =~\n<"string">.}) { assert_match("strin.", "string") } check_fail(%Q{failed assert_match.\n was expected to be =~\n<"string">.}) { assert_match(/slin./, "string", "failed assert_match") } end def test_assert_same thing = "thing" check_nothing_fails { assert_same(thing, thing) } check_nothing_fails { assert_same(thing, thing, "successful assert_same") } check_nothing_fails { assert_same(thing, thing, "successful assert_same") } thing2 = thing.dup check_fail(%Q{<"thing">\nwith id <#{thing.__id__}> was expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) { assert_same(thing, thing2) } check_fail(%Q{failed assert_same.\n<"thing">\nwith id <#{thing.__id__}> was expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) { assert_same(thing, thing2, "failed assert_same") } end def test_assert_nothing_raised check_nothing_fails(:dont_care) { assert_nothing_raised { 1 + 1 } } check_nothing_fails(:dont_care) { assert_nothing_raised("successful assert_nothing_raised") { 1 + 1 } } check_nothing_fails(:dont_care) { assert_nothing_raised("successful assert_nothing_raised") { 1 + 1 } } check_nothing_fails(:dont_care) { begin assert_nothing_raised(RuntimeError, StandardError, Comparable, "successful assert_nothing_raised") { raise ZeroDivisionError.new("ArgumentError") } rescue ZeroDivisionError end } expected_message = " must be a subclass of Exception, " + "an object of Exception subclasses or a Module." check_fail(expected_message) { assert_nothing_raised(Object) { 1 + 1 } } expected_message = <<-EOM.chomp Exception raised: RuntimeError() EOM check_fail_exception(expected_message) { assert_nothing_raised { raise "Error" } } expected_message = <<-EOM.chomp failed assert_nothing_raised. Exception raised: RuntimeError() EOM check_fail_exception(expected_message) { assert_nothing_raised("failed assert_nothing_raised") { raise "Error" } } expected_message = <<-EOM.chomp Exception raised: RuntimeError() EOM check_fail_exception(expected_message) { assert_nothing_raised(StandardError, RuntimeError) { raise "Error" } } check_fail("Failure.") do assert_nothing_raised do flunk("Failure") end end end def test_flunk check_fail("Flunked.") { flunk } check_fail("flunk message.") { flunk("flunk message") } end def test_assert_not_same thing = "thing" thing2 = thing.dup check_nothing_fails { assert_not_same(thing, thing2) } check_nothing_fails { assert_not_same(thing, thing2, "message") } check_fail(%Q{<"thing">\nwith id <#{thing.__id__}> was expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) { assert_not_same(thing, thing) } check_fail(%Q{message.\n<"thing">\nwith id <#{thing.__id__}> was expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) { assert_not_same(thing, thing, "message") } end def test_assert_not_equal check_nothing_fails { assert_not_equal("string1", "string2") } check_nothing_fails { assert_not_equal("string1", "string2", "message") } check_fail(%Q{<"string"> was expected to be != to\n<"string">.}) { assert_not_equal("string", "string") } check_fail(%Q{message.\n<"string"> was expected to be != to\n<"string">.}) { assert_not_equal("string", "string", "message") } end def test_assert_not_match_pass check_nothing_fails do assert_not_match(/sling/, "string") end end def test_assert_not_match_pass_with_message check_nothing_fails do assert_not_match(/sling/, "string", "message") end end def test_assert_not_match_fail_match check_fail(" was expected to not match\n" + "<\"string\">.") do assert_not_match(/string/, "string") end end def test_assert_not_match_fail_match_string check_fail(" was expected to not match\n" + "<\"asdf\">.") do assert_not_match("asdf", "asdf") end end def test_assert_not_match_fail_match_with_message check_fail("message.\n" + " was expected to not match\n" + "<\"string\">.") do assert_not_match(/string/, "string", "message") end end def test_assert_no_match check_nothing_fails{assert_no_match(/sling/, "string")} check_nothing_fails{assert_no_match(/sling/, "string", "message")} check_fail(%Q{The first argument to assert_no_match should be a Regexp.\n<"asdf"> was expected to be instance_of?\n but was\n.}) do assert_no_match("asdf", "asdf") end check_fail(%Q{ was expected to not match\n<"string">.}) do assert_no_match(/string/, "string") end check_fail(%Q{message.\n was expected to not match\n<"string">.}) do assert_no_match(/string/, "string", "message") end end def test_assert_throw check_nothing_fails do assert_throw(:thing, "message") do throw :thing end end tag = :thing2 check_fail("message.\n" + "<:thing> was expected to be thrown but\n" + "<#{inspect_tag(tag)}> was thrown.") do assert_throw(:thing, "message") do throw :thing2 end end check_fail("message.\n" + "<:thing> should have been thrown.") do assert_throw(:thing, "message") do 1 + 1 end end end def test_assert_nothing_thrown check_nothing_fails do assert_nothing_thrown("message") do 1 + 1 end end tag = :thing inspected = inspect_tag(tag) check_fail("message.\n" + "<#{inspected}> was thrown when nothing was expected.") do assert_nothing_thrown("message") do throw tag end end end def test_assert_operator check_nothing_fails { assert_operator("thing", :==, "thing", "message") } check_fail(%Q{<0.15>\ngiven as the operator for #assert_operator must be a Symbol or #respond_to?(:to_str).}) do assert_operator("thing", 0.15, "thing") end check_fail(%Q{message.\n<"thing1"> was expected to be\n==\n<"thing2">.}) { assert_operator("thing1", :==, "thing2", "message") } end def test_assert_not_operator check_nothing_fails { assert_not_operator("thing", :==, "Thing", "message") } check_fail(%Q{<42>\ngiven as the operator for #assert_not_operator must be a Symbol or #respond_to?(:to_str).}) do assert_not_operator("thing", 42, "message") end check_fail(%Q{message.\n<0> was expected to not be\n==\n<0.0>.}) { assert_not_operator(0, :==, 0.0, "message") } end def test_assert_respond_to check_nothing_fails { assert_respond_to("thing", :to_s, "message") } check_nothing_fails { assert_respond_to("thing", "to_s", "message") } check_fail("<0.15>.kind_of?(Symbol) or\n" + "<0.15>.respond_to?(:to_str) expected") { assert_respond_to("thing", 0.15) } check_fail("message.\n" + "<:symbol>.respond_to?(:nonexistence) expected\n" + "(Class: )") { assert_respond_to(:symbol, :nonexistence, "message") } end def test_assert_not_respond_to_pass_symbol check_nothing_fails do assert_not_respond_to("thing", :nonexistent, "message") end end def test_assert_not_respond_to_pass_string check_nothing_fails do assert_not_respond_to("thing", :nonexistent, "message") end end def test_assert_not_respond_to_fail_number check_fail("<0.15>.kind_of?(Symbol) or\n" + "<0.15>.respond_to?(:to_str) expected") do assert_respond_to("thing", 0.15) end end def tset_assert_not_respond_to_fail_existence check_fail("message.\n" + "!<:symbol>.respond_to?(:to_s) expected\n" + "(Class: )") do assert_respond_to(:symbol, :to_s, "message") end end def test_assert_send object = Object.new class << object private def return_argument(argument, bogus) return argument end end check_nothing_fails do assert_send([object, :return_argument, true, "bogus"], "message") end inspected_object = AssertionMessage.convert(object) expected_message = <<-EOM message. <#{inspected_object}> was expected to respond to with a true value but was . EOM check_fail(expected_message.chomp) do assert_send([object, :return_argument, false, "bogus"], "message") end end def test_condition_invariant object = Object.new def object.inspect @changed = true end def object.==(other) @changed ||= false return (!@changed) end check_nothing_fails do assert_equal(object, object, "message") end end def test_assert_boolean check_nothing_fails do assert_boolean(true) end check_nothing_fails do assert_boolean(false) end check_fail(" or expected but was\n<1>") do assert_boolean(1) end check_fail(" or expected but was\n") do assert_boolean(nil) end check_fail("message.\n or expected but was\n<\"XXX\">") do assert_boolean("XXX", "message") end end def test_assert_true check_nothing_fails do assert_true(true) end check_fail(" expected but was\n") do assert_true(false) end check_fail(" expected but was\n<1>") do assert_true(1) end exception = check_fail("message.\n expected but was\n") do assert_true(nil, "message") end assert_equal("message", exception.user_message) end def test_assert_false check_nothing_fails do assert_false(false) end check_fail(" expected but was\n") do assert_false(true) end check_fail(" expected but was\n") do assert_false(nil) end check_fail("message.\n expected but was\n<:false>") do assert_false(:false, "message") end end def test_assert_compare check_nothing_fails do assert_compare(1.4, "<", 10.0) end check_nothing_fails do assert_compare(2, "<=", 2) end check_nothing_fails do assert_compare(14, ">=", 10.0) end check_nothing_fails do assert_compare(14, ">", 13.9) end expected_message = <<-EOM <15> < <10> should be true <15> was expected to be less than <10>. EOM check_fail(expected_message.chomp) do assert_compare(15, "<", 10) end expected_message = <<-EOM <15> <= <10> should be true <15> was expected to be less than or equal to <10>. EOM check_fail(expected_message.chomp) do assert_compare(15, "<=", 10) end expected_message = <<-EOM <10> > <15> should be true <10> was expected to be greater than <15>. EOM check_fail(expected_message.chomp) do assert_compare(10, ">", 15) end expected_message = <<-EOM <10> >= <15> should be true <10> was expected to be greater than or equal to <15>. EOM check_fail(expected_message.chomp) do assert_compare(10, ">=", 15) end end def test_assert_fail_assertion check_nothing_fails do assert_fail_assertion do flunk end end check_fail("Failed assertion was expected.") do assert_fail_assertion do end end end def test_assert_raise_message check_nothing_fails do assert_raise_message("Raise!") do raise "Raise!" end end check_nothing_fails do assert_raise_message("Raise!") do raise Exception, "Raise!" end end check_nothing_fails do assert_raise_message(/raise/i) do raise "Raise!" end end expected_message = <<-EOM <"Expected message"> exception message expected but was <"Actual message">. EOM check_fail(expected_message.chomp) do assert_raise_message("Expected message") do raise "Actual message" end end expected_message = <<-EOM <"Expected message"> exception message was expected but none was thrown. EOM check_fail(expected_message.chomp) do assert_raise_message("Expected message") do end end end def test_assert_raise_kind_of check_nothing_fails(true) do assert_raise_kind_of(SystemCallError) do raise Errno::EACCES end end expected_message = <<-EOM.chomp family exception expected but was ) >. EOM check_fail_exception(expected_message) do assert_raise_kind_of(SystemCallError) do raise RuntimeError, "XXX" end end end def test_assert_const_defined check_nothing_fails do assert_const_defined(Test, :Unit) end check_nothing_fails do assert_const_defined(Test, "Unit") end check_fail(".const_defined?(<:Nonexistence>) expected.") do assert_const_defined(Test, :Nonexistence) end end def test_assert_not_const_defined check_nothing_fails do assert_not_const_defined(Test, :Nonexistence) end check_fail("!.const_defined?(<:Unit>) expected.") do assert_not_const_defined(Test, :Unit) end check_fail("!.const_defined?(<\"Unit\">) expected.") do assert_not_const_defined(Test, "Unit") end end def test_assert_predicate check_nothing_fails do assert_predicate([], :empty?) end check_fail("<[1]>.empty? is true value expected but was\n") do assert_predicate([1], :empty?) end check_fail("<[1]>.respond_to?(:nonexistent?) expected\n" + "(Class: )") do assert_predicate([1], :nonexistent?) end end def test_assert_not_predicate check_nothing_fails do assert_not_predicate([1], :empty?) end check_fail("<[]>.empty? is false value expected but was\n") do assert_not_predicate([], :empty?) end check_fail("<[]>.respond_to?(:nonexistent?) expected\n" + "(Class: )") do assert_not_predicate([], :nonexistent?) end end def test_assert_alias_method object = Object.new class << object def original_method end alias_method :alias_method, :original_method def other end end check_nothing_fails do assert_alias_method(object, :alias_method, :original_method) end check_nothing_fails do assert_alias_method(object, :original_method, :alias_method) end check_fail("<#{object.method(:other).inspect}> is alias of\n" + "<#{object.method(:original_method).inspect}> expected") do assert_alias_method(object, :other, :original_method) end inspected_object = AssertionMessage.convert(object) check_fail("<#{inspected_object}>.nonexistent doesn't exist\n" + "(Class: )") do assert_alias_method(object, :nonexistent, :original_method) end check_fail("<#{inspected_object}>.nonexistent doesn't exist\n" + "(Class: )") do assert_alias_method(object, :alias_method, :nonexistent) end end def test_assert_path_exist check_nothing_fails do assert_path_exist(__FILE__) end nonexistent_file = __FILE__ + ".nonexistent" check_fail("<#{nonexistent_file.inspect}> was expected to exist") do assert_path_exist(nonexistent_file) end end def test_assert_path_not_exist nonexistent_file = __FILE__ + ".nonexistent" check_nothing_fails do assert_path_not_exist(nonexistent_file) end check_fail("<#{__FILE__.inspect}> was expected to not exist") do assert_path_not_exist(__FILE__) end end end class TestAssert < TestCase include AssertionCheckable def test_pass check_nothing_fails do assert(true) end end def test_pass_neither_false_or_nil check_nothing_fails do assert("a") end end def test_pass_with_message check_nothing_fails do assert(true, "successful assert") end end def test_pass_block check_nothing_fails do assert do true end end end def test_fail_nil check_fail(" is not true.") do assert(nil) end end def test_fail_false check_fail(" is not true.") do assert(false) end end def test_fail_false_with_message check_fail("failed assert.\n" + " is not true.") do assert(false, "failed assert") end end def test_fail_with_assertion_message check_fail("user message.\n" + "placeholder <:in> message") do assert(false, build_message("user message", "placeholder message", :in)) end end def test_fail_block check_fail(//) do assert do 0.odd? end end end def test_error_invalid_message_true check_fail("assertion message must be String, Proc or " + "Test::Unit::Assertions::AssertionMessage: " + "()") do begin assert(true, true) rescue ArgumentError raise AssertionFailedError, $!.message end end end def test_error_wrong_number_of_arguments check_fail("wrong number of arguments (0 for 1..2)") do begin assert rescue ArgumentError raise AssertionFailedError, $!.message end end end class TestBlock < self def test_with_message if defined?(PowerAssert) system_message = <<-MESSAGE.chomp 1.to_s == "2" | | | false "1" MESSAGE else system_message = " is not true." end check_fail("user message.\n#{system_message}") do assert("user message") do 1.to_s == "2" end end end end end class TestRefute < TestCase include AssertionCheckable class TestPass < self def test_nil check_nothing_fails do refute(nil) end end def test_false check_nothing_fails do refute(false) end end def test_with_message check_nothing_fails do refute(nil, "successful refute") end end end class TestFailure < self def test_true check_fail(" is neither nil or false.") do refute(true) end end def test_with_message check_fail("failed refute.\n" + " is neither nil or false.") do refute(true, "failed refute") end end def test_fail_with_assertion_message check_fail("user message.\n" + "placeholder <:in> message") do refute(true, build_message("user message", "placeholder message", :in)) end end def test_error_invalid_message_true check_fail("assertion message must be String, Proc or " + "Test::Unit::Assertions::AssertionMessage: " + "()") do begin refute(true, false) rescue ArgumentError raise AssertionFailedError, $!.message end end end end end class TestAssertInDelta < TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_in_delta(1.4, 1.4, 0) end end def test_pass_without_delta check_nothing_fails do assert_in_delta(1.401, 1.402) end end def test_pass_with_message check_nothing_fails do assert_in_delta(0.5, 0.4, 0.1, "message") end end def test_pass_float_like_object check_nothing_fails do float_thing = Object.new def float_thing.to_f 0.2 end assert_in_delta(0.1, float_thing, 0.1) end end def test_pass_string_expected check_nothing_fails do assert_in_delta("0.5", 0.4, 0.1) end end def test_fail_with_message check_fail("message.\n" + "<0.5> -/+ <0.05> was expected to include\n" + "<0.4>.\n" + "\n" + "Relation:\n" + "<<0.4> < <0.5>-<0.05>[0.45] <= <0.5>+<0.05>[0.55]>") do assert_in_delta(0.5, 0.4, 0.05, "message") end end def test_fail_because_not_float_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The arguments must respond to to_f; " + "the first float did not.\n" + "<#{inspected_object}>.respond_to?(:to_f) expected\n" + "(Class: )") do assert_in_delta(object, 0.4, 0.1) end end def test_fail_because_negaitve_delta check_fail("The delta should not be negative.\n" + "<-0.1> was expected to be\n>=\n<0.0>.") do assert_in_delta(0.5, 0.4, -0.1, "message") end end def test_fail_without_delta check_fail("<1.402> -/+ <0.001> was expected to include\n" + "<1.404>.\n" + "\n" + "Relation:\n" + "<" + "<1.402>-<0.001>[#{1.402 - 0.001}] <= " + "<1.402>+<0.001>[#{1.402 + 0.001}] < " + "<1.404>" + ">") do assert_in_delta(1.402, 1.404) end end end class TestAssertNotInDelta < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_not_in_delta(1.42, 1.44, 0.01) end end def test_pass_without_delta check_nothing_fails do assert_not_in_delta(1.402, 1.404) end end def test_pass_with_message check_nothing_fails do assert_not_in_delta(0.5, 0.4, 0.09, "message") end end def test_pass_float_like_object check_nothing_fails do float_thing = Object.new def float_thing.to_f 0.2 end assert_not_in_delta(0.1, float_thing, 0.09) end end def test_pass_string_epxected check_nothing_fails do assert_not_in_delta("0.5", 0.4, 0.09) end end def test_fail check_fail("<1.4> -/+ <0.11> was expected to not include\n" + "<1.5>.\n" + "\n" + "Relation:\n" + "<" + "<1.4>-<0.11>[#{1.4 - 0.11}] <= " + "<1.5> <= " + "<1.4>+<0.11>[#{1.4 + 0.11}]" + ">") do assert_not_in_delta(1.4, 1.5, 0.11) end end def test_fail_without_delta check_fail("<1.402> -/+ <0.001> was expected to not include\n" + "<1.4021>.\n" + "\n" + "Relation:\n" + "<" + "<1.402>-<0.001>[#{1.402 - 0.001}] <= " + "<1.4021> <= " + "<1.402>+<0.001>[#{1.402 + 0.001}]" + ">") do assert_not_in_delta(1.402, 1.4021) end end def test_fail_with_message check_fail("message.\n" + "<0.5> -/+ <0.11> was expected to not include\n" + "<0.4>.\n" + "\n" + "Relation:\n" + "<" + "<0.5>-<0.11>[0.39] <= " + "<0.4> <= " + "<0.5>+<0.11>[0.61]" + ">") do assert_not_in_delta(0.5, 0.4, 0.11, "message") end end def test_fail_because_not_float_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The arguments must respond to to_f; " + "the first float did not.\n" + "<#{inspected_object}>.respond_to?(:to_f) expected\n" + "(Class: )") do assert_not_in_delta(object, 0.4, 0.1) end end def test_fail_because_negaitve_delta check_fail("The delta should not be negative.\n" + "<-0.11> was expected to be\n>=\n<0.0>.") do assert_not_in_delta(0.5, 0.4, -0.11, "message") end end end class TestAssertInEpsilon < TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_in_epsilon(10000, 9000, 0.1) end end def test_pass_without_epsilon check_nothing_fails do assert_in_epsilon(10000, 9991) end end def test_pass_with_message check_nothing_fails do assert_in_epsilon(10000, 9000, 0.1, "message") end end def test_pass_float_like_object check_nothing_fails do float_thing = Object.new def float_thing.to_f 9000.0 end assert_in_epsilon(10000, float_thing, 0.1) end end def test_pass_string_expected check_nothing_fails do assert_in_epsilon("10000", 9000, 0.1) end end def test_pass_zero_expected check_nothing_fails do assert_in_epsilon(0, 0.00000001) end end def test_pass_minus_expected check_nothing_fails do assert_in_epsilon(-1, -1) end end def test_fail_with_message check_fail("message.\n" + "<10000> -/+ (<10000> * <0.1>)[1000.0] " + "was expected to include\n" + "<8999>.\n" + "\n" + "Relation:\n" + "<" + "<8999> < " + "<10000>-(<10000>*<0.1>)[9000.0] <= " + "<10000>+(<10000>*<0.1>)[11000.0]" + ">") do assert_in_epsilon(10000, 8999, 0.1, "message") end end def test_fail_because_not_float_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The arguments must respond to to_f; " + "the first float did not.\n" + "<#{inspected_object}>.respond_to?(:to_f) expected\n" + "(Class: )") do assert_in_epsilon(object, 9000, 0.1) end end def test_fail_because_negaitve_epsilon check_fail("The epsilon should not be negative.\n" + "<-0.1> was expected to be\n>=\n<0.0>.") do assert_in_epsilon(10000, 9000, -0.1, "message") end end def test_fail_without_epsilon check_fail("<10000> -/+ (<10000> * <0.001>)[10.0] " + "was expected to include\n" + "<10011>.\n" + "\n" + "Relation:\n" + "<" + "<10000>-(<10000>*<0.001>)[9990.0] <= " + "<10000>+(<10000>*<0.001>)[10010.0] < " + "<10011>" + ">") do assert_in_epsilon(10000, 10011) end end end class TestAssertNotInEpsilon < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_not_in_epsilon(10000, 8999, 0.1) end end def test_pass_without_epsilon check_nothing_fails do assert_not_in_epsilon(10000, 9989) end end def test_pass_with_message check_nothing_fails do assert_not_in_epsilon(10000, 8999, 0.1, "message") end end def test_pass_float_like_object check_nothing_fails do float_thing = Object.new def float_thing.to_f 8999.0 end assert_not_in_epsilon(10000, float_thing, 0.1) end end def test_pass_string_epxected check_nothing_fails do assert_not_in_epsilon("10000", 8999, 0.1) end end def test_fail check_fail("<10000> -/+ (<10000> * <0.1>)[1000.0] " + "was expected to not include\n" + "<9000>.\n" + "\n" + "Relation:\n" + "<" + "<10000>-(<10000>*<0.1>)[9000.0] <= " + "<9000> <= " + "<10000>+(<10000>*<0.1>)[11000.0]" + ">") do assert_not_in_epsilon(10000, 9000, 0.1) end end def test_fail_without_epsilon check_fail("<10000> -/+ (<10000> * <0.001>)[10.0] " + "was expected to not include\n" + "<9990>.\n" + "\n" + "Relation:\n" + "<" + "<10000>-(<10000>*<0.001>)[9990.0] <= " + "<9990> <= " + "<10000>+(<10000>*<0.001>)[10010.0]" + ">") do assert_not_in_epsilon(10000, 9990) end end def test_fail_with_message check_fail("message.\n" + "<10000> -/+ (<10000> * <0.1>)[1000.0] " + "was expected to not include\n" + "<9000>.\n" + "\n" + "Relation:\n" + "<" + "<10000>-(<10000>*<0.1>)[9000.0] <= " + "<9000> <= " + "<10000>+(<10000>*<0.1>)[11000.0]" + ">") do assert_not_in_epsilon(10000, 9000, 0.1, "message") end end def test_fail_because_not_float_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The arguments must respond to to_f; " + "the first float did not.\n" + "<#{inspected_object}>.respond_to?(:to_f) expected\n" + "(Class: )") do assert_not_in_epsilon(object, 9000, 0.1) end end def test_fail_because_negaitve_epsilon check_fail("The epsilon should not be negative.\n" + "<-0.1> was expected to be\n>=\n<0.0>.") do assert_not_in_epsilon(10000, 9000, -0.1, "message") end end end class TestAssertInclude < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_include([1, 2, 3], 1) end end def test_pass_with_message check_nothing_fails do assert_include([1, 2, 3], 1, "message") end end def test_fail check_fail("<[1, 2, 3]> was expected to include\n" + "<4>.") do assert_include([1, 2, 3], 4) end end def test_fail_with_message check_fail("message.\n" + "<[1, 2, 3]> was expected to include\n" + "<4>.") do assert_include([1, 2, 3], 4, "message") end end def test_fail_because_not_collection_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The collection must respond to :include?.\n" + "<#{inspected_object}>.respond_to?(:include?) expected\n" + "(Class: )") do assert_include(object, 1) end end end class TestAssertNotInclude < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_not_include([1, 2, 3], 5) end end def test_pass_with_message check_nothing_fails do assert_not_include([1, 2, 3], 5, "message") end end def test_fail check_fail("<[1, 2, 3]> was expected to not include\n" + "<2>.") do assert_not_include([1, 2, 3], 2) end end def test_fail_with_message check_fail("message.\n" + "<[1, 2, 3]> was expected to not include\n" + "<2>.") do assert_not_include([1, 2, 3], 2, "message") end end def test_fail_because_not_collection_like_object object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The collection must respond to :include?.\n" + "<#{inspected_object}>.respond_to?(:include?) expected\n" + "(Class: )") do assert_not_include(object, 1) end end end class TestAssertEmpty < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_empty([]) end end def test_pass_with_message check_nothing_fails do assert_empty([], "message") end end def test_fail check_fail("<[1]> was expected to be empty.") do assert_empty([1]) end end def test_fail_with_message check_fail("message.\n" + "<[1]> was expected to be empty.") do assert_empty([1], "message") end end def test_fail_because_no_empty_method object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The object must respond to :empty?.\n" + "<#{inspected_object}>.respond_to?(:empty?) expected\n" + "(Class: )") do assert_empty(object) end end end class TestAssertNotEmpty < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_not_empty([1]) end end def test_pass_with_message check_nothing_fails do assert_not_empty([1], "message") end end def test_fail check_fail("<[]> was expected to not be empty.") do assert_not_empty([]) end end def test_fail_with_message check_fail("message.\n" + "<[]> was expected to not be empty.") do assert_not_empty([], "message") end end def test_fail_because_no_empty_method object = Object.new inspected_object = AssertionMessage.convert(object) check_fail("The object must respond to :empty?.\n" + "<#{inspected_object}>.respond_to?(:empty?) expected\n" + "(Class: )") do assert_not_empty(object) end end end class TestAssertNotSend < Test::Unit::TestCase include AssertionCheckable def test_pass check_nothing_fails do assert_not_send([[1, 2], :member?, 4], "message") end end def test_fail expected_message = <<-EOM message. <[1, 2]> was expected to respond to with not a true value but was . EOM check_fail(expected_message.chomp) do assert_not_send([[1, 2], :member?, 2], "message") end end end class TestTemplate < Test::Unit::TestCase def test_incompatible_encoding_by_diff need_encoding assert_raise(AssertionFailedError) do assert_equal("UTF-8の日本語\n" * 3, ("Shift_JISの日本語\n" * 3).force_encoding("ASCII-8BIT")) end end private def need_encoding omit("need Encoding") unless Object.const_defined?(:Encoding) end end end end test-unit-3.3.9/test/test-data.rb0000644000004100000410000003226713775322563016733 0ustar www-datawww-datarequire "testunit-test-util" class TestData < Test::Unit::TestCase class Calc def initialize end def plus(augend, addend) augend + addend end end class TestCalc < Test::Unit::TestCase @@testing = false class << self def testing=(testing) @@testing = testing end end def valid? @@testing end def setup @calc = Calc.new end class TestDataSet < TestCalc data("positive positive" => {:expected => 4, :augend => 3, :addend => 1}, "positive negative" => {:expected => -1, :augend => 1, :addend => -2}) def test_plus(data) assert_equal(data[:expected], @calc.plus(data[:augend], data[:addend])) end end class TestNData < TestCalc data("positive positive", {:expected => 4, :augend => 3, :addend => 1}) data("positive negative", {:expected => -1, :augend => 1, :addend => -2}) def test_plus(data) assert_equal(data[:expected], @calc.plus(data[:augend], data[:addend])) end end class TestDynamicDataSet < TestCalc DATA_PROC = lambda do data_set = {} data_set["positive positive"] = { :expected => 3, :augend => 1, :addend => 2 } data_set["positive negative"] = { :expected => -1, :augend => 1, :addend => -2 } data_set end data(&DATA_PROC) def test_plus(data) assert_equal(data[:expected], @calc.plus(data[:augend], data[:addend])) end end class TestLoadDataSet < TestCalc extend TestUnitTestUtil load_data(fixture_file_path("plus.csv")) def test_plus(data) assert_equal(data["expected"], @calc.plus(data["augend"], data["addend"])) end end class TestSuperclass < TestCalc data("positive positive" => {:expected => 4, :augend => 3, :addend => 1}, "positive negative" => {:expected => -1, :augend => 1, :addend => -2}) def test_plus(data) assert_equal(data[:expected], @calc.plus(data[:augend], data[:addend])) end class TestNormalTestInSubclass < self def test_plus assert_equal(2, @calc.plus(1, 1)) end end end class TestMethod < TestCalc def data_test_plus { "positive positive" => {:expected => 4, :augend => 3, :addend => 1}, "positive negative" => {:expected => -1, :augend => 1, :addend => -2}, } end def test_plus(data) assert_equal(data[:expected], @calc.plus(data[:augend], data[:addend])) end end class TestPatterns < TestCalc data(:x, [-1, 1, 0]) data(:y, [-100, 100]) data(:z, ["a", "b", "c"]) def test_use_data(data) end end class TestPatternsKeep < TestCalc data(:x, [-1, 1, 0], keep: true) data(:y, [-100, 100]) data(:z, ["a", "b", "c"], keep: true) def test_use_data(data) end def test_use_data_keep(data) end end class TestPatternsGroup < TestCalc data(:a, [-1, 1, 0], group: 1) data(:b, [:a, :b], group: 1) data(:x, [2, 9], group: :z) data(:y, ["a", "b", "c"], group: :z) def test_use_data(data) end end end def setup TestCalc.testing = true end def teardown TestCalc.testing = false end def test_data_no_arguments_without_block assert_raise(ArgumentError) do self.class.data end end data("data set", { :test_case => TestCalc::TestDataSet, :data_sets => [ { "positive positive" => { :expected => 4, :augend => 3, :addend => 1, }, "positive negative" => { :expected => -1, :augend => 1, :addend => -2, }, }, ], }) data("n-data", { :test_case => TestCalc::TestNData, :data_sets => [ { "positive positive" => { :expected => 4, :augend => 3, :addend => 1, }, }, { "positive negative" => { :expected => -1, :augend => 1, :addend => -2, }, }, ], }) data("dynamic-data-set", { :test_case => TestCalc::TestDynamicDataSet, :data_sets => [TestCalc::TestDynamicDataSet::DATA_PROC], }) data("load-data-set", { :test_case => TestCalc::TestLoadDataSet, :data_sets => [ { "positive positive" => { "expected" => 4, "augend" => 3, "addend" => 1, }, }, { "positive negative" => { "expected" => -1, "augend" => 1, "addend" => -2, }, }, ], }) def test_data(data) test_plus = data[:test_case].new("test_plus") data_sets = Test::Unit::DataSets.new data[:data_sets].each do |data_set| data_sets.add(data_set) end assert_equal(data_sets, test_plus[:data]) end def test_data_patterns test = TestCalc::TestPatterns.new("test_use_data") data_sets = Test::Unit::DataSets.new data_sets << [:x, [-1, 1, 0]] data_sets << [:y, [-100, 100]] data_sets << [:z, ["a", "b", "c"]] assert_equal(data_sets, test[:data]) end def test_data_patterns_keep test = TestCalc::TestPatternsKeep.new("test_use_data_keep") data_sets = Test::Unit::DataSets.new data_sets.add([:x, [-1, 1, 0]], {keep: true}) data_sets.add([:z, ["a", "b", "c"]], {keep: true}) assert_equal(data_sets, test[:data]) end data("data set" => TestCalc::TestDataSet, "n-data" => TestCalc::TestNData, "dynamic-data-set" => TestCalc::TestDynamicDataSet, "load-data-set" => TestCalc::TestLoadDataSet) def test_suite(test_case) suite = test_case.suite assert_equal(["test_plus[positive negative](#{test_case.name})", "test_plus[positive positive](#{test_case.name})"], suite.tests.collect {|test| test.name}.sort) end def test_suite_patterns test_case = TestCalc::TestPatterns suite = test_case.suite assert_equal([ "test_use_data[x: -1, y: -100, z: \"a\"](#{test_case.name})", "test_use_data[x: -1, y: -100, z: \"b\"](#{test_case.name})", "test_use_data[x: -1, y: -100, z: \"c\"](#{test_case.name})", "test_use_data[x: -1, y: 100, z: \"a\"](#{test_case.name})", "test_use_data[x: -1, y: 100, z: \"b\"](#{test_case.name})", "test_use_data[x: -1, y: 100, z: \"c\"](#{test_case.name})", "test_use_data[x: 0, y: -100, z: \"a\"](#{test_case.name})", "test_use_data[x: 0, y: -100, z: \"b\"](#{test_case.name})", "test_use_data[x: 0, y: -100, z: \"c\"](#{test_case.name})", "test_use_data[x: 0, y: 100, z: \"a\"](#{test_case.name})", "test_use_data[x: 0, y: 100, z: \"b\"](#{test_case.name})", "test_use_data[x: 0, y: 100, z: \"c\"](#{test_case.name})", "test_use_data[x: 1, y: -100, z: \"a\"](#{test_case.name})", "test_use_data[x: 1, y: -100, z: \"b\"](#{test_case.name})", "test_use_data[x: 1, y: -100, z: \"c\"](#{test_case.name})", "test_use_data[x: 1, y: 100, z: \"a\"](#{test_case.name})", "test_use_data[x: 1, y: 100, z: \"b\"](#{test_case.name})", "test_use_data[x: 1, y: 100, z: \"c\"](#{test_case.name})", ], suite.tests.collect {|test| test.name}.sort) end def test_suite_patterns_group test_case = TestCalc::TestPatternsGroup suite = test_case.suite assert_equal([ "test_use_data[group: 1, a: -1, b: :a](#{test_case.name})", "test_use_data[group: 1, a: -1, b: :b](#{test_case.name})", "test_use_data[group: 1, a: 0, b: :a](#{test_case.name})", "test_use_data[group: 1, a: 0, b: :b](#{test_case.name})", "test_use_data[group: 1, a: 1, b: :a](#{test_case.name})", "test_use_data[group: 1, a: 1, b: :b](#{test_case.name})", "test_use_data[group: :z, x: 2, y: \"a\"](#{test_case.name})", "test_use_data[group: :z, x: 2, y: \"b\"](#{test_case.name})", "test_use_data[group: :z, x: 2, y: \"c\"](#{test_case.name})", "test_use_data[group: :z, x: 9, y: \"a\"](#{test_case.name})", "test_use_data[group: :z, x: 9, y: \"b\"](#{test_case.name})", "test_use_data[group: :z, x: 9, y: \"c\"](#{test_case.name})", ], suite.tests.collect {|test| test.name}.sort) end data("data set" => TestCalc::TestDataSet, "n-data" => TestCalc::TestNData, "dynamic-data-set" => TestCalc::TestDynamicDataSet, "load-data-set" => TestCalc::TestLoadDataSet, "superclass" => TestCalc::TestSuperclass, "method" => TestCalc::TestMethod) def test_run(test_case) result = _run_test(test_case) assert_equal("2 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, " \ "0 omissions, 0 notifications", result.to_s) end def test_run_normal_test_in_subclass result = _run_test(TestCalc::TestSuperclass::TestNormalTestInSubclass) assert_equal("1 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, " \ "0 omissions, 0 notifications", result.to_s) end data("data set" => TestCalc::TestDataSet, "n-data" => TestCalc::TestNData, "dynamic-data-set" => TestCalc::TestDynamicDataSet, "load-data-set" => TestCalc::TestLoadDataSet) def test_equal(test_case) suite = test_case.suite positive_positive_test = suite.tests.find do |test| test.data_label == "positive positive" end suite.tests.delete(positive_positive_test) assert_equal(["test_plus[positive negative](#{test_case.name})"], suite.tests.collect {|test| test.name}.sort) end data("true" => {:expected => true, :target => "true"}, "false" => {:expected => false, :target => "false"}, "integer" => {:expected => 1, :target => "1"}, "float" => {:expected => 1.5, :target => "1.5"}, "string" => {:expected => "hello", :target => "hello"}) def test_normalize_value(data) loader = Test::Unit::Data::ClassMethods::Loader.new(self) assert_equal(data[:expected], loader.__send__(:normalize_value, data[:target])) end def _run_test(test_case) result = Test::Unit::TestResult.new test = test_case.suite yield(test) if block_given? test.run(result) {} result end class TestLoadData < Test::Unit::TestCase include TestUnitTestUtil def test_invalid_csv_file_name garbage = "X" file_name = "data.csv#{garbage}" assert_raise(ArgumentError, "unsupported file format: <#{file_name}>") do self.class.load_data(file_name) end end class TestFileFormat < self def setup self.class.current_attribute(:data).clear end class TestHeader < self data("csv" => "header.csv", "tsv" => "header.tsv") def test_normal(file_name) self.class.load_data(fixture_file_path(file_name)) data_sets = Test::Unit::DataSets.new data_sets << { "empty string" => { "expected" => true, "target" => "" } } data_sets << { "plain string" => { "expected" => false, "target" => "hello" } } assert_equal(data_sets, self.class.current_attribute(:data)[:value]) end data("csv" => "header-label.csv", "tsv" => "header-label.tsv") def test_label(file_name) self.class.load_data(fixture_file_path(file_name)) data_sets = Test::Unit::DataSets.new data_sets << { "upper case" => { "expected" => "HELLO", "label" => "HELLO" } } data_sets << { "lower case" => { "expected" => "Hello", "label" => "hello" } } assert_equal(data_sets, self.class.current_attribute(:data)[:value]) end end data("csv" => "no-header.csv", "tsv" => "no-header.tsv") def test_without_header(file_name) self.class.load_data(fixture_file_path(file_name)) data_sets = Test::Unit::DataSets.new data_sets << {"empty string" => [true, ""]} data_sets << {"plain string" => [false, "hello"]} assert_equal(data_sets, self.class.current_attribute(:data)[:value]) end end end end test-unit-3.3.9/test/fixtures/0000755000004100000410000000000013775322563016357 5ustar www-datawww-datatest-unit-3.3.9/test/fixtures/header-label.tsv0000644000004100000410000000010313775322563021414 0ustar www-datawww-datalabel expected label upper case HELLO HELLO lower case Hello hello test-unit-3.3.9/test/fixtures/no-header.csv0000644000004100000410000000005613775322563020737 0ustar www-datawww-dataempty string,true,"" plain string,false,hello test-unit-3.3.9/test/fixtures/no-header.tsv0000644000004100000410000000005613775322563020760 0ustar www-datawww-dataempty string true "" plain string false hello test-unit-3.3.9/test/fixtures/header.csv0000644000004100000410000000010413775322563020317 0ustar www-datawww-datalabel,expected,target empty string,true,"" plain string,false,hello test-unit-3.3.9/test/fixtures/header.tsv0000644000004100000410000000010413775322563020340 0ustar www-datawww-datalabel expected target empty string true "" plain string false hello test-unit-3.3.9/test/fixtures/header-label.csv0000644000004100000410000000010313775322563021373 0ustar www-datawww-datalabel,expected,label upper case,HELLO,HELLO lower case,Hello,hello test-unit-3.3.9/test/fixtures/plus.csv0000644000004100000410000000011713775322563020056 0ustar www-datawww-datalabel,expected,augend,addend positive positive,4,3,1 positive negative,-1,1,-2 test-unit-3.3.9/test/test-fault-location-detector.rb0000644000004100000410000000767313775322563022555 0ustar www-datawww-data# Copyright (C) 2012 Kouhei Sutou # # License: Ruby's require "test-unit" require "test/unit/fault-location-detector" require "testunit-test-util" class TestFaultLocationDetector < Test::Unit::TestCase include TestUnitTestUtil def setup @fetcher = Test::Unit::CodeSnippetFetcher.new end private def run_test_case(test_case) suite = test_case.suite result = Test::Unit::TestResult.new suite.run(result) {} result.faults[0] end def assert_detect(fault, target_line_number) detector = Test::Unit::FaultLocationDetector.new(fault, @fetcher) expected_backtrace_entries_until_detected = [] fault.location.each do |backtrace_entry| expected_backtrace_entries_until_detected << backtrace_entry _, line_number, = detector.split_backtrace_entry(backtrace_entry) break if target_line_number == line_number end actual_backtrace_entries_until_detected = [] fault.location.each do |backtrace_entry| actual_backtrace_entries_until_detected << backtrace_entry break if detector.target?(backtrace_entry) end assert_equal(expected_backtrace_entries_until_detected, actual_backtrace_entries_until_detected) end module AlwaysFailAssertion private def assert_always_failed assert_true(false) end end class TestSourceLocation < self setup def setup_check_source_location unless lambda {}.respond_to?(:source_location) omit("Need Proc#source_location") end end def test_detected target_line_number = nil test_case = Class.new(Test::Unit::TestCase) do include AlwaysFailAssertion test "failed" do target_line_number = __LINE__; assert_always_failed end end fault = run_test_case(test_case) assert_detect(fault, target_line_number) end class TestOneLine < self def test_brace target_line_number = nil test_case = Class.new(Test::Unit::TestCase) do include AlwaysFailAssertion test("failed") {target_line_number = __LINE__; assert_always_failed} def other_method # body end end fault = run_test_case(test_case) assert_detect(fault, target_line_number) end def test_do_end target_line_number = nil test_case = Class.new(Test::Unit::TestCase) do include AlwaysFailAssertion test "failed" do target_line_number = __LINE__; assert_always_failed; end def other_method # body end end fault = run_test_case(test_case) assert_detect(fault, target_line_number) end end end class TestMethodName < self def test_detected test_case = Class.new(Test::Unit::TestCase) do include AlwaysFailAssertion class << self def target_line_number @@target_line_number end def target_line_number=(line_number) @@target_line_number = line_number end end def test_failed self.class.target_line_number = __LINE__; assert_always_failed end end fault = run_test_case(test_case) assert_detect(fault, test_case.target_line_number) end end class TestInBlock < self def test_in_block test_case = Class.new(Test::Unit::TestCase) do include AlwaysFailAssertion class << self def target_line_number @@target_line_number end def target_line_number=(line_number) @@target_line_number = line_number end end def run_yield yield end def test_failed run_yield do self.class.target_line_number = __LINE__; assert_always_failed end end end fault = run_test_case(test_case) assert_detect(fault, test_case.target_line_number) end end end test-unit-3.3.9/test/test-diff.rb0000644000004100000410000004407313775322563016730 0ustar www-datawww-dataclass TestUnitDiff < Test::Unit::TestCase def test_binary_search_ranges assert_found_binary_search_ranges(5, [1..2, 4..5, 7..9]) assert_not_found_binary_search_ranges(3, [1..2, 4..5, 7..9]) end def test_to_indexes assert_to_indexes({"abc def" => [0, 2], "abc" => [1]}, ["abc def", "abc", "abc def"]) assert_to_indexes({?a => [0, 3], ?b => [1], ?c => [2], ?d => [4]}, "abcad") assert_to_indexes({ ?1 => [0, 35], ?t => [2, 5, 16], ?e => [3, 14, 31, 38], ?s => [4, 6, 12, 13, 20, 32, 44], ?, => [7, 21, 33], ?0 => [9, 23], ?a => [11, 26], ?r => [15, 30], ?i => [17, 27, 41], ?o => [18], ?n => [19, 39, 42], ?f => [25], ?l => [28], ?u => [29], ?p => [37], ?d => [40], ?g => [43], }, "1 tests, 0 assertions, 0 failures, 1 pendings") do |x| x == " "[0] end end def test_longest_match assert_longest_match([0, 1, 3], %w(b c d), %w(a b c d x y z), 0, 2, 0, 7) assert_longest_match([1, 2, 2], %w(b c d), %w(a b c d x y z), 1, 2, 0, 6) assert_longest_match([0, 0, 0], %w(a b), %w(c), 0, 1, 0, 0) assert_longest_match([1, 0, 2], %w(q a b x c d), %w(a b y c d f), 0, 5, 0, 5) assert_longest_match([4, 3, 2], %w(q a b x c d), %w(a b y c d f), 3, 5, 2, 5) assert_longest_match([1, 0, 2], "qabxcd", "abycdf", 0, 5, 0, 5) assert_longest_match([0, 0, 1], "efg", "eg", 0, 2, 0, 1) assert_longest_match([2, 1, 1], "efg", "eg", 1, 2, 1, 1) end def test_longest_match_with_junk_predicate assert_longest_match([0, 4, 5], " abcd", "abcd abcd", 0, 4, 0, 8) assert_longest_match([1, 0, 4], " abcd", "abcd abcd", 0, 4, 0, 8) do |x| x == ' '[0] end end def test_matches assert_matches([[0, 0, 2], [3, 2, 2]], %w(a b x c d), %w(a b c d)) assert_matches([[1, 0, 2], [4, 3, 2]], %w(q a b x c d), %w(a b y c d f)) assert_matches([[1, 0, 2], [4, 3, 2]], "qabxcd", "abycdf") assert_matches([[0, 0, 1], [2, 1, 1]], "efg", "eg") end def test_matches_with_junk_predicate assert_matches([[0, 0, 23], [24, 24, 11], [36, 36, 9]], "1 tests, 0 assertions, 1 failures, 0 pendings", "1 tests, 0 assertions, 0 failures, 1 pendings") assert_matches([[0, 0, 1], [1, 1, 8], [9, 9, 1], [10, 10, 13], [24, 24, 11], [36, 36, 9]], "1 tests, 0 assertions, 1 failures, 0 pendings", "1 tests, 0 assertions, 0 failures, 1 pendings") do |x| x == " "[0] end end def test_blocks assert_blocks([[0, 0, 2], [3, 2, 2], [5, 4, 0]], %w(a b x c d), %w(a b c d)) assert_blocks([[1, 0, 2], [4, 3, 2], [6, 6, 0]], %w(q a b x c d), %w(a b y c d f)) assert_blocks([[1, 0, 2], [4, 3, 2], [6, 6, 0]], "qabxcd", "abycdf") assert_blocks([[0, 0, 1], [2, 1, 1], [3, 2, 0]], "efg", "eg") end def test_blocks_with_junk_predicate assert_blocks([[0, 0, 23], [24, 24, 11], [36, 36, 9], [45, 45, 0]], "1 tests, 0 assertions, 1 failures, 0 pendings", "1 tests, 0 assertions, 0 failures, 1 pendings") do |x| x == " "[0] end end def test_operations assert_operations([], %w(), %w()) assert_operations([[:delete, 0, 1, 0, 0], [:equal, 1, 3, 0, 2], [:replace, 3, 4, 2, 3], [:equal, 4, 6, 3, 5], [:insert, 6, 6, 5, 6]], %w(q a b x c d), %w(a b y c d f)) assert_operations([[:delete, 0, 1, 0, 0], [:equal, 1, 3, 0, 2], [:replace, 3, 4, 2, 3], [:equal, 4, 6, 3, 5], [:insert, 6, 6, 5, 6]], "qabxcd", "abycdf") assert_operations([[:equal, 0, 23, 0, 23], [:replace, 23, 24, 23, 24], [:equal, 24, 35, 24, 35], [:replace, 35, 36, 35, 36], [:equal, 36, 45, 36, 45]], "1 tests, 0 assertions, 1 failures, 0 pendings", "1 tests, 0 assertions, 0 failures, 1 pendings") assert_operations([[:equal, 0, 23, 0, 23], [:replace, 23, 24, 23, 24], [:equal, 24, 35, 24, 35], [:replace, 35, 36, 35, 36], [:equal, 36, 45, 36, 45]], "1 tests, 0 assertions, 1 failures, 0 pendings", "1 tests, 0 assertions, 0 failures, 1 pendings") do |x| x == " "[0] end end def test_grouped_operations assert_grouped_operations([[[:equal, 0, 0, 0, 0]]], %w(), %w()) assert_grouped_operations([[[:equal, 0, 3, 0, 3]]], %w(a b c), %w(a b c)) assert_grouped_operations([[[:equal, 0, 1, 0, 1], [:replace, 1, 2, 1, 2], [:equal, 2, 5, 2, 5]], [[:equal, 8, 11, 8, 11], [:replace, 11, 12, 11, 12], [:equal, 12, 13, 12, 13], [:delete, 13, 16, 13, 13], [:equal, 16, 17, 13, 14], [:replace, 17, 18, 14, 15], [:equal, 18, 20, 15, 17]]], %w(1 2 3 4 5 6 7 8 9 a b c d e f g h i j k), %w(1 i 3 4 5 6 7 8 9 a b cX d h iX j k)) end def test_ratio assert_ratio(0.75, "abcd", "bcde") assert_ratio(0.80, "efg", "eg") end def test_1_length_readable_diff differ = Test::Unit::Diff::ReadableDiffer.new(["0"], ["1"]) def differ.cut_off_ratio 0 end def differ.default_ratio 0 end assert_equal("- 0\n" + "? ^\n" + "+ 1\n" + "? ^", differ.diff.join("\n")) end def test_same_contents_readable_diff assert_readable_diff(" aaa", ["aaa"], ["aaa"]) assert_readable_diff(" aaa\n" \ " bbb", ["aaa", "bbb"], ["aaa", "bbb"]) end def test_deleted_readable_diff assert_readable_diff(" aaa\n" \ "- bbb", ["aaa", "bbb"], ["aaa"]) assert_readable_diff(" aaa\n" \ "- bbb\n" \ "- ccc\n" \ "- ddd", ["aaa", "bbb", "ccc", "ddd"], ["aaa"]) end def test_inserted_readable_diff assert_readable_diff(" aaa\n" \ "+ bbb\n" \ "+ ccc\n" \ "+ ddd", ["aaa"], ["aaa", "bbb", "ccc", "ddd"]) end def test_replace_readable_diff assert_readable_diff(" aaa\n" \ "- bbb\n" \ "+ BbB\n" \ " ccc\n" \ "- ddd\n" \ "- efg\n" \ "? -\n" \ "+ eg", ["aaa", "bbb", "ccc", "ddd", "efg"], ["aaa", "BbB", "ccc", "eg"]) assert_readable_diff("- abcd xyz abc\n" \ "? -\n" \ "+ abcd abcd xyz abc\n" \ "? +++++", [" abcd xyz abc"], ["abcd abcd xyz abc"]) end def test_difference_readable_diff assert_readable_diff("- 1 tests, 0 assertions, 1 failures, 0 pendings\n" \ "? ^ ^\n" \ "+ 1 tests, 0 assertions, 0 failures, 1 pendings\n" \ "? ^ ^", ["1 tests, 0 assertions, 1 failures, 0 pendings"], ["1 tests, 0 assertions, 0 failures, 1 pendings"]) end def test_complex_readable_diff assert_readable_diff(" aaa\n" \ "- bbb\n" \ "- ccc\n" \ "+ \n" \ "+ # \n" \ " ddd", ["aaa", "bbb", "ccc", "ddd"], ["aaa", "", " # ", "ddd"]) assert_readable_diff("- one1\n" \ "? ^\n" \ "+ ore1\n" \ "? ^\n" \ "- two2\n" \ "- three3\n" \ "? - -\n" \ "+ tree\n" \ "+ emu", ["one1", "two2", "three3"], ["ore1", "tree", "emu"]) end def test_empty_readable_diff assert_readable_diff("", [""], [""]) end def test_unified_diff assert_unified_diff("", ["one", "two", "three"], ["one", "two", "three"], "content 1", "content 2") assert_unified_diff("--- Original Sat Jan 26 23:30:50 1991\n" \ "+++ Current Fri Jun 06 10:20:52 2003\n" \ "@@ -1,4 +1,4 @@\n" \ "+zero\n" \ " one\n" \ "-two\n" \ "-three\n" \ "+tree\n" \ " four", ["one", "two", "three", "four"], ["zero", "one", "tree", "four"], "Original Sat Jan 26 23:30:50 1991", "Current Fri Jun 06 10:20:52 2003", :show_context => false) from = File.read(__FILE__).split(/\n/) to = from.dup target_line = __LINE__ to[target_line - 1, 1] = [] context = " def test_unified_diff" summary = "@@ -#{target_line - 3},7 +#{target_line - 3},6 @@ #{context}" assert_unified_diff((["--- revision 10", "+++ revision 11", summary] + from[target_line - 4, 3].collect {|line| " #{line}"} + ["-#{from[target_line - 1]}"] + from[target_line, 3].collect {|line| " #{line}"} ).join("\n"), from, to, "revision 10", "revision 11") end def test_empty_unified_diff assert_unified_diff("", [""], [""], "From", "To") assert_unified_diff("", [], [], "From", "To") end def test_diff_lines assert_diff_lines(["- ddd", "- efg", "? -", "+ eg"], ["aaa", "bbb", "ccc", "ddd", "efg"], ["aaa", "BbB", "ccc", "eg"], 3, 5, 3, 4) end def test_diff_line assert_diff_line(["- abcDefghiJkl", "? ^ ^ ^", "+ abcdefGhijkl", "? ^ ^ ^"], "abcDefghiJkl", "abcdefGhijkl") assert_diff_line(["- bcDefghiJklx", "? ^ ^ ^ -", "+ abcdefGhijkl", "? + ^ ^ ^"], "bcDefghiJklx", "abcdefGhijkl") end def test_empty_diff_line assert_diff_line(["- ", "+ "], "", "") end def test_format_diff_point assert_format_diff_point(["- \tabcDefghiJkl", "? \t ^ ^ ^", "+ \t\tabcdefGhijkl", "? \t ^ ^ ^"], "\tabcDefghiJkl", "\t\tabcdefGhijkl", " ^ ^ ^ ", "+ ^ ^ ^ ") assert_format_diff_point(["- efg", "? ^", "+ eg"], "efg", "eg", " ^", "") end def test_interesting_line from = ["class X", " def find(x=0)", " body", " end", "end"] to = ["def xxx", " raise 'not call me'", "end"] assert_interesting_line(" def find(x=0)", from, to, 2, 1) assert_interesting_line("def xxx", from, to, 2, 0) assert_interesting_line("class X", from, to, 0, 0) end private def assert_found_binary_search_ranges(numeric, ranges) assert_true(Test::Unit::Diff::UTF8Line.send(:binary_search_ranges, numeric, ranges)) end def assert_not_found_binary_search_ranges(numeric, ranges) assert_false(Test::Unit::Diff::UTF8Line.send(:binary_search_ranges, numeric, ranges)) end def assert_to_indexes(expected, to, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new([""], to, &junk_predicate) assert_equal(expected, matcher.instance_variable_get("@to_indexes")) end def assert_find_best_match_position(expected, from, to, from_start, from_end, to_start, to_end, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to, &junk_predicate) assert_equal(expected, matcher.send(:find_best_match_position, from_start, from_end, to_start, to_end)) end def assert_longest_match(expected, from, to, from_start, from_end, to_start, to_end, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to, &junk_predicate) assert_equal(expected, matcher.longest_match(from_start, from_end, to_start, to_end)) end def assert_matches(expected, from, to, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to, &junk_predicate) assert_equal(expected, matcher.send(:matches)) end def assert_blocks(expected, from, to, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to, &junk_predicate) assert_equal(expected, matcher.blocks) end def assert_operations(expected, from, to, &junk_predicate) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to, &junk_predicate) assert_equal(expected, matcher.operations) end def assert_grouped_operations(expected, from, to) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to) assert_equal(expected, matcher.grouped_operations) end def assert_ratio(expected, from, to) matcher = Test::Unit::Diff::SequenceMatcher.new(from, to) assert_in_delta(expected, 0.001, matcher.ratio) end def assert_readable_diff(expected, from, to) assert_equal(expected, Test::Unit::Diff.readable(from.join("\n"), to.join("\n"))) end def assert_unified_diff(expected, from, to, from_label, to_label, options={}) options = options.merge(:from_label => from_label, :to_label => to_label) assert_equal(expected, Test::Unit::Diff.unified(from.join("\n"), to.join("\n"), options)) end def assert_diff_lines(expected, from, to, from_start, from_end, to_start, to_end) differ = Test::Unit::Diff::ReadableDiffer.new(from, to) result = [] differ.instance_variable_set("@result", result) differ.send(:diff_lines, from_start, from_end, to_start, to_end) assert_equal(expected, result) end def assert_diff_line(expected, from_line, to_line) differ = Test::Unit::Diff::ReadableDiffer.new([""], [""]) result = [] differ.instance_variable_set("@result", result) differ.send(:diff_line, from_line, to_line) assert_equal(expected, result) end def assert_format_diff_point(expected, from_line, to_line, from_tags, to_tags) differ = Test::Unit::Diff::ReadableDiffer.new([""], [""]) result = [] differ.instance_variable_set("@result", result) differ.send(:format_diff_point, from_line, to_line, from_tags, to_tags) assert_equal(expected, result) end def assert_interesting_line(expected, from, to, from_start, to_start) differ = Test::Unit::Diff::UnifiedDiffer.new(from, to) assert_equal(expected, differ.send(:find_interesting_line, from_start, to_start, :define_line?)) end end test-unit-3.3.9/test/test-emacs-runner.rb0000644000004100000410000000336313775322563020414 0ustar www-datawww-datarequire 'test/unit' require 'test/unit/ui/emacs/testrunner' class TestUnitEmacsRunner < Test::Unit::TestCase def test_format_failure_with_a_location runner = create_runner test_name = "test_failure" file = "/home/user/test_xxx.rb" line = "3" info = "in `xxx'" location = "#{file}:#{line}: #{info}" message = "FAIL!!!" failure = Test::Unit::Failure.new(test_name, [location], message) assert_equal(<<-EOM.chomp, runner.send(:format_fault, failure)) Failure: #{test_name} [#{file}:#{line}]: #{message} EOM end def test_format_failure_with_locations runner = create_runner test_name = "test_failure" locations = ["/home/user/test_xxx.rb:3: in `xxx'", "/home/user/yyy/test_yyy.rb:999: in `yyy'", "/home/user/xyz/zzz.rb:29: in `zzz'"] message = "Many backtrace!!!" failure = Test::Unit::Failure.new(test_name, locations, message) assert_equal(<<-EOM.chomp, runner.send(:format_fault, failure)) Failure: #{test_name} #{locations.join("\n")}: #{message} EOM end def test_format_error runner = create_runner test_name = "test_error" message = "Error Message!!!" backtrace = ["/home/user/test_xxx.rb:3: in `xxx'", "/home/user/yyy/test_yyy.rb:999: in `yyy'", "/home/user/xyz/zzz.rb:29: in `zzz'"] exception = RuntimeError.new(message) exception.set_backtrace(backtrace) error = Test::Unit::Error.new(test_name, exception) assert_equal(<<-EOM.chomp, runner.send(:format_fault, error)) Error: #{test_name}: #{exception.class.name}: #{message} #{backtrace.join("\n")} EOM end private def create_runner(suite=nil) suite ||= Test::Unit::TestSuite.new Test::Unit::UI::Emacs::TestRunner.new(suite) end end test-unit-3.3.9/test/test-attribute.rb0000644000004100000410000000564713775322563020027 0ustar www-datawww-dataclass TestUnitAttribute < Test::Unit::TestCase class TestStack < Test::Unit::TestCase class << self def suite Test::Unit::TestSuite.new(name) end end class Stack def initialize @data = [] end def push(data) @data.push(data) end def peek @data[-2] end def empty? @data.empty? end def size @data.size + 11 end end def setup @stack = Stack.new end attribute :category, :accessor def test_peek @stack.push(1) @stack.push(2) assert_equal(2, @stack.peek) end attribute :bug, 1234 def test_bug_1234 assert_equal(0, @stack.size) end def test_no_attributes assert(@stack.empty?) @stack.push(1) assert(!@stack.empty?) assert_equal(1, @stack.size) end end def test_set_attributes test_for_accessor_category = TestStack.new("test_peek") assert_equal({"category" => :accessor}, test_for_accessor_category.attributes) test_for_bug_1234 = TestStack.new("test_bug_1234") assert_equal({"bug" => 1234}, test_for_bug_1234.attributes) test_no_attributes = TestStack.new("test_no_attributes") assert_equal({}, test_no_attributes.attributes) end def test_callback changed_attributes = [] observer = Proc.new do |test_case, key, old_value, value, method_name| changed_attributes << [test_case, key, old_value, value, method_name] end test_case = Class.new(TestStack) do register_attribute_observer(:bug, &observer) attribute("bug", 9876, "test_bug_1234") attribute(:description, "Test for peek", "test_peek") attribute(:bug, 29, "test_peek") end assert_equal([ [test_case, "bug", 1234, 9876, "test_bug_1234"], [test_case, "bug", nil, 29, "test_peek"], ], changed_attributes) end def test_attributes_with_prepended_module omit("Module#prepend is needed") unless Module.respond_to?(:prepend, true) test_case = Class.new(TestStack) do prepend Module.new end assert_equal({ "category" => :accessor, }, test_case.attributes("test_peek")) end class TestDescription < self def test_decoration_style test_case = Class.new(TestStack) do description "Test for push" def test_push end end test_push = test_case.new("test_push") assert_equal({"description" => "Test for push"}, test_push.attributes) end def test_explicit_test_name_style test_case = Class.new(TestStack) do def test_push end description "Test for push", :test_push end test_push = test_case.new("test_push") assert_equal({"description" => "Test for push"}, test_push.attributes) end end end test-unit-3.3.9/test/util/0000755000004100000410000000000013775322563015463 5ustar www-datawww-datatest-unit-3.3.9/test/util/test_backtracefilter.rb0000644000004100000410000000425213775322563022177 0ustar www-datawww-datarequire 'test/unit' require 'test/unit/util/backtracefilter' module Test::Unit::Util class TestBacktraceFilter < Test::Unit::TestCase include BacktraceFilter def test_filter_backtrace backtrace = [%q{C:\some\old\path/test/unit/assertions.rb:44:in 'assert'}, %q{tc_thing.rb:4:in 'a'}, %q{tc_thing.rb:4:in 'test_stuff'}, %q{C:\some\old\path/test/unit/testcase.rb:44:in 'send'}, %q{C:\some\old\path\test\unit\testcase.rb:44:in 'run'}, %q{C:\some\old\path\test\unit.rb:44:in 'run'}, %q{tc_thing.rb:3}] assert_equal(backtrace[1..2], filter_backtrace(backtrace, %q{C:\some\old\path\test\unit}), "Should filter out all TestUnit-specific lines") backtrace = [%q{tc_thing.rb:4:in 'a'}, %q{tc_thing.rb:4:in 'test_stuff'}, %q{tc_thing.rb:3}] assert_equal(backtrace, filter_backtrace(backtrace, %q{C:\some\old\path\test\unit}), "Shouldn't filter too much") backtrace = [%q{C:\some\old\path/test/unit/assertions.rb:44:in 'assert'}, %q{tc_thing.rb:4:in 'a'}, %q{tc_thing.rb:4:in 'test_stuff'}, %q{tc_thing.rb:3}] assert_equal(backtrace[1..3], filter_backtrace(backtrace, %q{C:\some\old\path\test\unit}), "Should filter out all TestUnit-specific lines") backtrace = [%q{C:\some\old\path/test/unit/assertions.rb:44:in 'assert'}, %q{C:\some\old\path/test/unit/testcase.rb:44:in 'send'}, %q{C:\some\old\path\test\unit\testcase.rb:44:in 'run'}, %q{C:\some\old\path\test\unit.rb:44:in 'run'}] assert_equal(backtrace, filter_backtrace(backtrace, %q{C:\some\old\path\test\unit}), "Should filter out all TestUnit-specific lines") end def test_nil_backtrace assert_equal(["No backtrace"], filter_backtrace(nil)) end def test_power_assert_backtrace omit('test for power_assert') unless defined?(PowerAssert) blk = Proc.new {caller.find {|i| /power_assert.*in \`start\'/ =~ i}} PowerAssert.start(blk) do |pa| backtrace = [pa.yield, %q{tc_thing.rb:4:in 'a'}, %q{tc_thing.rb:4:in 'test_stuff'}] assert_equal(backtrace[1..2], filter_backtrace(backtrace)) end end end end test-unit-3.3.9/test/util/test_observable.rb0000644000004100000410000000765313775322563021206 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/util/observable' module Test module Unit module Util class TC_Observable < TestCase class TF_Observable include Observable end def setup @observable = TF_Observable.new end def test_simple_observation assert_raises(ArgumentError, "add_listener should throw an exception if no callback is supplied") do @observable.add_listener(:property, "a") end heard = false callback = proc { heard = true } assert_equal("a", @observable.add_listener(:property, "a", &callback), "add_listener should return the listener that was added") count = 0 @observable.instance_eval do count = notify_listeners(:property) end assert_equal(1, count, "notify_listeners should have returned the number of listeners that were notified") assert(heard, "Should have heard the property changed") heard = false assert_equal(callback, @observable.remove_listener(:property, "a"), "remove_listener should return the callback") count = 1 @observable.instance_eval do count = notify_listeners(:property) end assert_equal(0, count, "notify_listeners should have returned the number of listeners that were notified") assert(!heard, "Should not have heard the property change") end def test_value_observation value = nil @observable.add_listener(:property, "a") do |passed_value| value = passed_value end count = 0 @observable.instance_eval do count = notify_listeners(:property, "stuff") end assert_equal(1, count, "Should have update the correct number of listeners") assert_equal("stuff", value, "Should have received the value as an argument to the listener") end def test_multiple_value_observation values = [] @observable.add_listener(:property, "a") do |first_value, second_value| values = [first_value, second_value] end count = 0 @observable.instance_eval do count = notify_listeners(:property, "stuff", "more stuff") end assert_equal(1, count, "Should have update the correct number of listeners") assert_equal(["stuff", "more stuff"], values, "Should have received the value as an argument to the listener") end def test_add_remove_with_default_listener assert_raises(ArgumentError, "add_listener should throw an exception if no callback is supplied") do @observable.add_listener(:property) end heard = false callback = proc { heard = true } assert_equal(callback, @observable.add_listener(:property, &callback), "add_listener should return the listener that was added") count = 0 @observable.instance_eval do count = notify_listeners(:property) end assert_equal(1, count, "notify_listeners should have returned the number of listeners that were notified") assert(heard, "Should have heard the property changed") heard = false assert_equal(callback, @observable.remove_listener(:property, callback), "remove_listener should return the callback") count = 1 @observable.instance_eval do count = notify_listeners(:property) end assert_equal(0, count, "notify_listeners should have returned the number of listeners that were notified") assert(!heard, "Should not have heard the property change") end end end end end test-unit-3.3.9/test/util/test-output.rb0000644000004100000410000000041513775322563020325 0ustar www-datawww-datarequire 'test/unit' class TestUnitOutput < Test::Unit::TestCase def test_capture_output assert_equal(["stdout\n", "stderr\n"], capture_output do puts("stdout") warn("stderr") end) end end test-unit-3.3.9/test/util/test_procwrapper.rb0000644000004100000410000000237113775322563021416 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' require 'test/unit/util/procwrapper' module Test module Unit module Util class TC_ProcWrapper < TestCase def munge_proc(&a_proc) return a_proc end def setup @original = proc {} @munged = munge_proc(&@original) @wrapped_original = ProcWrapper.new(@original) @wrapped_munged = ProcWrapper.new(@munged) end def test_wrapping assert_same(@original, @wrapped_original.to_proc, "The wrapper should return what was wrapped") end def test_hashing assert_equal(@wrapped_original.hash, @wrapped_munged.hash, "The original and munged should have the same hash when wrapped") assert_equal(@wrapped_original, @wrapped_munged, "The wrappers should be equivalent") a_hash = {@wrapped_original => @original} assert(a_hash[@wrapped_original], "Should be able to access the wrapper in the hash") assert_equal(a_hash[@wrapped_original], @original, "Should be able to access the wrapper in the hash") end end end end end test-unit-3.3.9/test/util/test-method-owner-finder.rb0000644000004100000410000000202213775322563022636 0ustar www-datawww-datarequire 'test/unit' require 'test/unit/util/method-owner-finder' class TestUnitMethodOwnerFinder < Test::Unit::TestCase def test_find assert_equal(Exception, find(RuntimeError.new, :inspect)) assert_equal(Exception, find(Exception.new, :inspect)) anonymous_class = Class.new do end assert_equal(Kernel, find(anonymous_class.new, :inspect)) anonymous_parent_class = Class.new do def inspect super + " by anonymous parent class" end end anonymous_sub_class = Class.new(anonymous_parent_class) do end assert_equal(anonymous_parent_class, find(anonymous_sub_class.new, :inspect)) anonymous_module = Module.new do def inspect super + " by anonymous module" end end anonymous_include_class = Class.new do include anonymous_module end assert_equal(anonymous_module, find(anonymous_include_class.new, :inspect)) end private def find(object, method_name) Test::Unit::Util::MethodOwnerFinder.find(object, method_name) end end test-unit-3.3.9/test/test-color-scheme.rb0000644000004100000410000000717213775322563020377 0ustar www-datawww-dataclass TestUnitColorScheme < Test::Unit::TestCase def test_register inverted_scheme_spec = { "success" => {:name => "red"}, "failure" => {:name => "green"}, } Test::Unit::ColorScheme["inverted"] = inverted_scheme_spec assert_equal({ "success" => color("red"), "failure" => color("green"), }, Test::Unit::ColorScheme["inverted"].to_hash) end def test_new_with_colors scheme = Test::Unit::ColorScheme.new(:success => color("blue"), "failure" => color("green", :underline => true)) assert_equal({ "success" => color("blue"), "failure" => color("green", :underline => true), }, scheme.to_hash) end def test_new_with_spec scheme = Test::Unit::ColorScheme.new(:success => { :name => "blue", :bold => true }, "failure" => {:name => "green"}) assert_equal({ "success" => color("blue", :bold => true), "failure" => color("green"), }, scheme.to_hash) end private def color(name, options={}) Test::Unit::Color.new(name, options) end module CleanEnvironment def setup @original_term, ENV["TERM"] = ENV["TERM"], nil @original_color_term, ENV["COLORTERM"] = ENV["COLORTERM"], nil @original_vte_version, ENV["VTE_VERSION"] = ENV["VTE_VERSION"], nil ENV["TERM"] = "xterm" end def teardown ENV["TERM"] = @original_term ENV["COLORTERM"] = @original_color_term ENV["VTE_VERSION"] = @original_vte_version end end class TestFor8Colors < self include CleanEnvironment def test_default expected_schema_keys = [ "pass", "pass-marker", "failure", "failure-marker", "pending", "pending-marker", "omission", "omission-marker", "notification", "notification-marker", "error", "error-marker", "case", "suite", "diff-inserted-tag", "diff-deleted-tag", "diff-difference-tag", "diff-inserted", "diff-deleted", ] assert_equal(expected_schema_keys.sort, Test::Unit::ColorScheme.default.to_hash.keys.sort) end end class TestGuessAvailableColors < self include CleanEnvironment { "rxvt" => 8, "xterm-color" => 8, "alacritty" => 256, "iTerm.app" => 256, "screen-256color" => 256, "screenxterm-256color" => 256, "tmux-256color" => 256, "vte-256color" => 256, "vscode-direct" => 2**24, "vte-direct" => 2**24, "xterm-direct" => 2**24, }.each do |term, colors| data("%20s => %8d" % [term, colors], {term: term, colors: colors}) end def test_term_env(data) ENV["TERM"] = data[:term] assert_equal(data[:colors], Test::Unit::ColorScheme.available_colors, "Incorrect available_colors for TERM=%s" % [data[:term]]) end end class TestDefaultScheme < self include CleanEnvironment def test_direct_color ENV["TERM"] = "xterm-direct" assert_equal(Test::Unit::ColorScheme.default_for_256_colors, Test::Unit::ColorScheme.default) end end end test-unit-3.3.9/test/test-test-suite.rb0000644000004100000410000001126613775322563020124 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' module Test module Unit class TestTestSuite < TestCase def setup @testcase1 = Class.new(TestCase) do def test_succeed1 assert_block { true } end def test_fail assert_block { false } end end @testcase2 = Class.new(TestCase) do def test_succeed2 assert_block { true } end def test_error raise end end end def test_add s = TestSuite.new assert_equal(s, s << self.class.new("test_add")) end def test_delete s = TestSuite.new t1 = self.class.new("test_delete") s << t1 t2 = self.class.new("test_add") s << t2 assert_equal(t1, s.delete(t1)) assert_nil(s.delete(t1)) assert_equal(TestSuite.new << t2, s) end def test_delete_tests suite = TestSuite.new test1 = self.class.new("test_delete_1") suite << test1 test2 = self.class.new("test_delete_2") suite << test2 test3 = self.class.new("test_add") suite << test3 suite.delete_tests([test1, test2]) assert_equal(1, suite.size) assert_equal(TestSuite.new << test3, suite) end def test_size suite = TestSuite.new suite2 = TestSuite.new suite2 << self.class.new("test_size") suite << suite2 suite << self.class.new("test_size") assert_equal(2, suite.size, "The count should be correct") end def test_run progress = [] @testcase1.test_order = :alphabetic suite = @testcase1.suite tests = suite.tests.dup result = TestResult.new suite.run(result) { |*values| progress << values } assert_equal(2, result.run_count, "Should have had four test runs") assert_equal(1, result.failure_count, "Should have had one test failure") assert_equal(0, result.error_count, "Should have had one test error") assert_equal([[TestSuite::STARTED, suite.name], [TestSuite::STARTED_OBJECT, suite], [TestCase::STARTED, "test_fail(#{suite.name})"], [TestCase::STARTED_OBJECT, tests[0]], [TestCase::FINISHED, "test_fail(#{suite.name})"], [TestCase::FINISHED_OBJECT, tests[0]], [TestCase::STARTED, "test_succeed1(#{suite.name})"], [TestCase::STARTED_OBJECT, tests[1]], [TestCase::FINISHED, "test_succeed1(#{suite.name})"], [TestCase::FINISHED_OBJECT, tests[1]], [TestSuite::FINISHED, suite.name], [TestSuite::FINISHED_OBJECT, suite]], progress, "Should have had the correct progress") suite = TestSuite.new suite << @testcase1.suite suite << @testcase2.suite result = TestResult.new progress = [] suite.run(result) { |*values| progress << values } assert_equal(4, result.run_count, "Should have had four test runs") assert_equal(1, result.failure_count, "Should have had one test failure") assert_equal(1, result.error_count, "Should have had one test error") assert_equal(28, progress.size, "Should have had the correct number of progress calls") end def test_empty? assert(TestSuite.new.empty?, "A new test suite should be empty?") assert(!@testcase2.suite.empty?, "A test suite with tests should not be empty") end def test_equality suite1 = TestSuite.new suite2 = TestSuite.new assert_equal(suite1, suite2) assert_equal(suite2, suite1) suite1 = TestSuite.new('name') assert_not_equal(suite1, suite2) assert_not_equal(suite2, suite1) suite2 = TestSuite.new('name') assert_equal(suite1, suite2) assert_equal(suite2, suite1) suite1 << 'test' assert_not_equal(suite1, suite2) assert_not_equal(suite2, suite1) suite2 << 'test' assert_equal(suite1, suite2) assert_equal(suite2, suite1) suite2 = Object.new class << suite2 def name 'name' end def tests ['test'] end end assert_not_equal(suite1, suite2) assert_not_equal(suite2, suite1) assert_not_equal(suite1, Object.new) assert_not_equal(Object.new, suite1) end end end end test-unit-3.3.9/test/testunit-test-util.rb0000644000004100000410000000120013775322563020633 0ustar www-datawww-datarequire "tempfile" module TestUnitTestUtil private def jruby? RUBY_PLATFORM == "java" end def jruby_only_test if jruby? require "java" else omit("test for JRuby") end end def assert_fault_messages(expected, faults) assert_equal(expected, faults.collect {|fault| fault.message}) end def _run_test(test_case, name) result = Test::Unit::TestResult.new test = test_case.new(name) yield(test) if block_given? test.run(result) {} result end def fixture_file_path(file_name) base_dir = File.dirname(__FILE__) File.join(base_dir, "fixtures", file_name) end end test-unit-3.3.9/test/test-pending.rb0000644000004100000410000000372713775322563017445 0ustar www-datawww-datarequire 'test/unit' require 'testunit-test-util' class TestUnitPending < Test::Unit::TestCase include TestUnitTestUtil class TestCase < Test::Unit::TestCase class << self def suite Test::Unit::TestSuite.new(name) end end def test_pend pend("1st pend") pend("2nd pend. Should not be reached here.") assert(true, "Should not be reached here too.") end def test_pend_with_failure_in_block pend("Wait a minute") do raise "Not implemented yet" end assert(true, "Reached here.") end def test_pend_with_no_failure_in_block pend("Wait a minute") do "Nothing raised" end assert(true, "Not reached here.") end end def test_pend test = nil result = _run_test("test_pend") {|t| test = t} assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 1 pendings, " \ "0 omissions, 0 notifications", result.to_s) assert_fault_messages(["1st pend"], result.pendings) assert_true(test.interrupted?) end def test_pend_with_failure_in_block test = nil result = _run_test("test_pend_with_failure_in_block") {|t| test = t} assert_equal("1 tests, 1 assertions, 0 failures, 0 errors, 1 pendings, " \ "0 omissions, 0 notifications", result.to_s) assert_fault_messages(["Wait a minute"], result.pendings) assert_false(test.interrupted?) end def test_pend_with_no_failure_in_block test = nil result = _run_test("test_pend_with_no_failure_in_block") {|t| test = t} assert_equal("1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, " \ "0 omissions, 0 notifications", result.to_s) assert_fault_messages(["Pending block should not be passed: Wait a minute."], result.failures) assert_true(test.interrupted?) end private def _run_test(name, &block) super(TestCase, name, &block) end end test-unit-3.3.9/test/test-omission.rb0000644000004100000410000000447513775322563017662 0ustar www-datawww-datarequire 'test/unit' require 'testunit-test-util' class TestUnitOmission < Test::Unit::TestCase include TestUnitTestUtil class TestCase < Test::Unit::TestCase class << self def suite Test::Unit::TestSuite.new(name) end end def test_omit omit("1st omit") omit("2nd omit. Should not be reached here.") assert(true, "Should not be reached here too.") end def test_omit_with_condition omit_if(false, "Never omit.") omit_unless(true, "Never omit too.") omit_if(true, "Should omit.") omit("The last omit. Should not be reached here.") end def test_omit_with_block omit("Omit block") do flunk("Should not be reached here.") end assert(true, "Should be reached here.") end def test_omit_with_block_and_condition omit_if(false, "Never omit.") do assert(true, "Should be reached here.") end omit_if(true, "Should omit.") do flunk("Never reached here.") end assert(true, "Should be reached here too.") end end def test_omit result = _run_test("test_omit") assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, " \ "1 omissions, 0 notifications", result.to_s) assert_fault_messages(["1st omit"], result.omissions) end def test_omit_with_condition result = _run_test("test_omit_with_condition") assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, " \ "1 omissions, 0 notifications", result.to_s) assert_fault_messages(["Should omit."], result.omissions) end def test_omit_with_block result = _run_test("test_omit_with_block") assert_equal("1 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, " \ "1 omissions, 0 notifications", result.to_s) assert_fault_messages(["Omit block"], result.omissions) end def test_omit_with_condition_and_block result = _run_test("test_omit_with_block_and_condition") assert_equal("1 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, " \ "1 omissions, 0 notifications", result.to_s) assert_fault_messages(["Should omit."], result.omissions) end private def _run_test(name) super(TestCase, name) end end test-unit-3.3.9/test/test-test-result.rb0000644000004100000410000000611213775322563020303 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/testcase' require 'test/unit/testresult' module Test module Unit class TC_TestResult < TestCase def setup @my_result = TestResult.new @my_result.add_assertion() @failure = "failure" @my_result.add_failure(@failure) @error = "error" @my_result.add_error(@error) end def test_result_changed_notification called1 = false @my_result.add_listener(TestResult::CHANGED) do |result| assert_equal(@my_result, result) called1 = true end @my_result.add_assertion assert_true(called1) called1, called2 = false, false @my_result.add_listener(TestResult::CHANGED) do |result| assert_equal(@my_result, result) called2 = true end @my_result.add_assertion assert_equal([true, true], [called1, called2]) called1, called2 = false, false @my_result.add_failure("") assert_equal([true, true], [called1, called2]) called1, called2 = false, false @my_result.add_error("") assert_equal([true, true], [called1, called2]) called1, called2 = false, false @my_result.add_run assert_equal([true, true], [called1, called2]) end def test_fault_notification called1 = false fault = "fault" @my_result.add_listener(TestResult::FAULT) do |passed_fault| assert_equal(fault, passed_fault) called1 = true end @my_result.add_assertion assert_false(called1) @my_result.add_failure(fault) assert_true(called1) called1, called2 = false, false @my_result.add_listener(TestResult::FAULT) do |passed_fault| assert_equal(fault, passed_fault) called2 = true end @my_result.add_assertion assert_equal([false, false], [called1, called2]) called1, called2 = false, false @my_result.add_failure(fault) assert_equal([true, true], [called1, called2]) called1, called2 = false, false @my_result.add_error(fault) assert_equal([true, true], [called1, called2]) called1, called2 = false, false @my_result.add_run assert_equal([false, false], [called1, called2]) end def test_passed? result = TestResult.new assert_true(result.passed?) result.add_assertion assert_true(result.passed?) result.add_run assert_true(result.passed?) result.add_failure("") assert_false(result.passed?) result = TestResult.new result.add_error("") assert_false(result.passed?) end def test_faults assert_equal([@failure, @error], @my_result.faults) notification = "notification" @my_result.add_notification(notification) assert_equal([@failure, @error, notification], @my_result.faults) end end end end test-unit-3.3.9/test/test-code-snippet.rb0000644000004100000410000000341213775322563020402 0ustar www-datawww-data# coding: utf-8 require "test-unit" require "testunit-test-util" class TestCodeSnippet < Test::Unit::TestCase include TestUnitTestUtil class TestJRuby < self def test_error_inside_jruby jruby_only_test backtrace = backtrace_from_jruby no_rb_entries = backtrace.find_all do |(file, _, _)| File.extname(file) != ".rb" end fetcher = Test::Unit::CodeSnippetFetcher.new snippets = no_rb_entries.collect do |(file, line, _)| fetcher.fetch(file, line) end assert_equal([[]] * no_rb_entries.size, snippets) end private def backtrace_from_jruby begin java.util.Vector.new(-1) rescue Exception $@.collect do |entry| entry.split(/:/, 3) end else flunk("failed to raise an exception from JRuby.") end end end class TestDefaultExternal < self def suppress_warning verbose = $VERBOSE begin $VERBOSE = false yield ensure $VERBOSE = verbose end end def setup suppress_warning do @default_external = Encoding.default_external end @fetcher = Test::Unit::CodeSnippetFetcher.new end def teardown suppress_warning do Encoding.default_external = @default_external end end def test_windows_31j source = Tempfile.new(["test-code-snippet", ".rb"]) source.puts(<<-SOURCE) puts("あいうえお") SOURCE source.flush suppress_warning do Encoding.default_external = "Windows-31J" end assert_equal([ [1, "puts(\"あいうえお\")", {:target_line? => false}], ], @fetcher.fetch(source.path, 0)) end end end test-unit-3.3.9/test/test-test-suite-creator.rb0000644000004100000410000000440413775322563021555 0ustar www-datawww-datarequire "test/unit" module Test module Unit class TestTestSuiteCreator < TestCase def collect_test_names(test_case) creator = TestSuiteCreator.new(test_case) creator.send(:collect_test_names) end class TestStandalone < self def setup @test_case = Class.new(TestCase) do def test_in_test_case end end end def test_collect_test_names assert_equal(["test_in_test_case"], collect_test_names(@test_case)) end end class TestInherited < self def setup @parent_test_case = Class.new(TestCase) do def test_in_parent end end @child_test_case = Class.new(@parent_test_case) do def test_in_child end end end def test_collect_test_names assert_equal(["test_in_child"], collect_test_names(@child_test_case)) end end class TestModule < self def setup test_module = Module.new do def test_in_module end end @test_case = Class.new(TestCase) do include test_module def test_in_test_case end end end def test_collect_test_names assert_equal(["test_in_module", "test_in_test_case"].sort, collect_test_names(@test_case).sort) end end class TestInheritedModule < self def setup parent_test_module = Module.new do def test_in_module_in_parent end end child_test_module = Module.new do def test_in_module_in_child end end @parent_test_case = Class.new(TestCase) do include parent_test_module def test_in_parent end end @child_test_case = Class.new(@parent_test_case) do include child_test_module def test_in_child end end end def test_collect_test_names assert_equal(["test_in_child", "test_in_module_in_child"].sort, collect_test_names(@child_test_case).sort) end end end end end test-unit-3.3.9/test/test-failure.rb0000644000004100000410000000146713775322563017447 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2003 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' require 'test/unit/failure' module Test::Unit class TestFailure < TestCase def test_display f = Failure.new("name", [%q{location:1 in 'l'}], "message1\nmessage2") assert_equal("name: message1", f.short_display) assert_equal(< :append}], [{:before => :append}], [{:before => :prepend}], [{:before => :prepend}]]) assert_inherited_setup(expected_setup_calls, test_case) assert_inherited_setup([:setup], nil) assert_called_fixtures(expected_setup_calls, test_case) end def test_with_after_option expected_setup_calls = [:setup, :custom_setup_callback3, :custom_setup_method3, :custom_setup_method0, :custom_setup_callback0, :custom_setup_method1, :custom_setup_callback1] test_case = assert_setup(expected_setup_calls, [[{:after => :append}], [{:after => :append}], [{:after => :prepend}], [{:after => :prepend}]]) assert_inherited_setup(expected_setup_calls, test_case) assert_inherited_setup([:setup], nil) assert_called_fixtures(expected_setup_calls, test_case) end def test_with_invalid_option assert_invalid_setup_option(:unknown => true) assert_invalid_setup_option(:before => :unknown) assert_invalid_setup_option(:after => :unknown) end def test_with_option_to_inherited expected_setup_calls = [:setup] test_case = assert_setup(expected_setup_calls, nil) assert_inherited_setup([:setup, :custom_setup_method0, :custom_setup_callback0, :custom_setup_method1, :custom_setup_callback1, :custom_setup_method3, :custom_setup_callback3], test_case, []) assert_inherited_setup([:setup], nil) assert_called_fixtures(expected_setup_calls, test_case) end private def assert_setup_customizable(expected, parent, options) test_case = Class.new(parent || Test::Unit::TestCase) do yield(self, :before) if block_given? def called_ids @called_ids ||= [] end def called(id) called_ids << id end def setup called(:setup) end setup(*(options[0] || [])) if options def custom_setup_method0 called(:custom_setup_method0) end if options setup(*(options[0] || [])) do called(:custom_setup_callback0) end end def custom_setup_method1 called(:custom_setup_method1) end setup(*[:custom_setup_method1, *(options[1] || [])]) if options if options setup(*(options[1] || [])) do called(:custom_setup_callback1) end end setup(*(options[2] || [])) if options def custom_setup_method2 called(:custom_setup_method2) end unregister_setup(:custom_setup_method2) if options if options callback = lambda do called(:custom_setup_callback2) end setup(*(options[2] || []), &callback) unregister_setup(callback) end setup(*(options[3] || [])) if options def custom_setup_method3 called(:custom_setup_method3) end if options setup(*(options[3] || [])) do called(:custom_setup_callback3) end end def test_nothing end yield(self, :after) if block_given? end assert_called_fixtures(expected, test_case) test_case end def assert_setup(expected, options) _test_case = assert_setup_customizable(expected, nil, options) assert_setup_customizable(expected, nil, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end _test_case end def assert_inherited_setup(expected, parent, options=nil) _test_case = assert_setup_customizable(expected, parent, options) assert_setup_customizable(expected, parent, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end _test_case end def assert_invalid_setup_option(option) assert_invalid_option(:setup, option) end end class TestCleanup < self def test_without_option expected_cleanup_calls = [:custom_cleanup_callback3, :custom_cleanup_method3, :custom_cleanup_callback1, :custom_cleanup_method1, :custom_cleanup_callback0, :custom_cleanup_method0, :cleanup] test_case = assert_cleanup(expected_cleanup_calls, []) assert_inherited_cleanup(expected_cleanup_calls, test_case) assert_inherited_cleanup([:cleanup], nil) assert_called_fixtures(expected_cleanup_calls, test_case) end def test_with_before_option expected_cleanup_calls = [:custom_cleanup_callback3, :custom_cleanup_method3, :custom_cleanup_method0, :custom_cleanup_callback0, :custom_cleanup_method1, :custom_cleanup_callback1, :cleanup] test_case = assert_cleanup(expected_cleanup_calls, [[{:before => :append}], [{:before => :append}], [{:before => :prepend}], [{:before => :prepend}]]) assert_inherited_cleanup(expected_cleanup_calls, test_case) assert_inherited_cleanup([:cleanup], nil) assert_called_fixtures(expected_cleanup_calls, test_case) end def test_with_after_option expected_cleanup_calls = [:cleanup, :custom_cleanup_callback3, :custom_cleanup_method3, :custom_cleanup_method0, :custom_cleanup_callback0, :custom_cleanup_method1, :custom_cleanup_callback1] test_case = assert_cleanup(expected_cleanup_calls, [[{:after => :append}], [{:after => :append}], [{:after => :prepend}], [{:after => :prepend}]]) assert_inherited_cleanup(expected_cleanup_calls, test_case) assert_inherited_cleanup([:cleanup], nil) assert_called_fixtures(expected_cleanup_calls, test_case) end def test_with_invalid_option assert_invalid_cleanup_option(:unknown => true) assert_invalid_cleanup_option(:before => :unknown) assert_invalid_cleanup_option(:after => :unknown) end def test_with_option_to_inherited expected_cleanup_calls = [:cleanup] test_case = assert_cleanup(expected_cleanup_calls, nil) assert_inherited_cleanup([:custom_cleanup_callback3, :custom_cleanup_method3, :custom_cleanup_callback1, :custom_cleanup_method1, :custom_cleanup_callback0, :custom_cleanup_method0, :cleanup], test_case, []) assert_inherited_cleanup([:cleanup], nil) assert_called_fixtures(expected_cleanup_calls, test_case) end def test_with_exception test_case = Class.new(Test::Unit::TestCase) do def called_ids @called_ids ||= [] end def called(id) called_ids << id end def cleanup called(:cleanup) raise "cleanup" end cleanup def custom_cleanup_method0 called(:custom_cleanup_method0) raise "custom_cleanup_method0" end cleanup do called(:custom_cleanup_callback0) raise "custom_cleanup_callback0" end cleanup def custom_cleanup_method1 called(:custom_cleanup_method1) raise "custom_cleanup_method1" end cleanup do called(:custom_cleanup_callback1) raise "custom_cleanup_callback1" end def test_nothing end end assert_called_fixtures([:custom_cleanup_callback1], test_case) end private def assert_cleanup_customizable(expected, parent, options) test_case = Class.new(parent || Test::Unit::TestCase) do yield(self, :before) if block_given? def called_ids @called_ids ||= [] end def called(id) called_ids << id end def cleanup called(:cleanup) end cleanup(*(options[0] || [])) if options def custom_cleanup_method0 called(:custom_cleanup_method0) end if options cleanup(*(options[0] || [])) do called(:custom_cleanup_callback0) end end def custom_cleanup_method1 called(:custom_cleanup_method1) end cleanup(*[:custom_cleanup_method1, *(options[1] || [])]) if options if options cleanup(*(options[1] || [])) do called(:custom_cleanup_callback1) end end cleanup(*(options[2] || [])) if options def custom_cleanup_method2 called(:custom_cleanup_method2) end unregister_cleanup(:custom_cleanup_method2) if options if options callback = lambda do called(:custom_cleanup_callback2) end cleanup(*(options[2] || []), &callback) unregister_cleanup(callback) end cleanup(*(options[3] || [])) if options def custom_cleanup_method3 called(:custom_cleanup_method3) end if options cleanup(*(options[3] || [])) do called(:custom_cleanup_callback3) end end def test_nothing end yield(self, :after) if block_given? end assert_called_fixtures(expected, test_case) test_case end def assert_cleanup(expected, options) assert_cleanup_customizable(expected, nil, options) assert_cleanup_customizable(expected, nil, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end end def assert_inherited_cleanup(expected, parent, options=nil) assert_cleanup_customizable(expected, parent, options) assert_cleanup_customizable(expected, parent, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end end def assert_invalid_cleanup_option(option) assert_invalid_option(:cleanup, option) end end class TestTeardown < self def test_without_option expected_teardown_calls = [:custom_teardown_callback3, :custom_teardown_method3, :custom_teardown_callback1, :custom_teardown_method1, :custom_teardown_callback0, :custom_teardown_method0, :teardown] test_case = assert_teardown(expected_teardown_calls, []) assert_inherited_teardown(expected_teardown_calls, test_case) assert_inherited_teardown([:teardown], nil) assert_called_fixtures(expected_teardown_calls, test_case) end def test_with_before_option expected_teardown_calls = [:custom_teardown_callback3, :custom_teardown_method3, :custom_teardown_method0, :custom_teardown_callback0, :custom_teardown_method1, :custom_teardown_callback1, :teardown] test_case = assert_teardown(expected_teardown_calls, [[{:before => :append}], [{:before => :append}], [{:before => :prepend}], [{:before => :prepend}]]) assert_inherited_teardown(expected_teardown_calls, test_case) assert_inherited_teardown([:teardown], nil) assert_called_fixtures(expected_teardown_calls, test_case) end def test_with_after_option expected_teardown_calls = [:teardown, :custom_teardown_callback3, :custom_teardown_method3, :custom_teardown_method0, :custom_teardown_callback0, :custom_teardown_method1, :custom_teardown_callback1] test_case = assert_teardown(expected_teardown_calls, [[{:after => :append}], [{:after => :append}], [{:after => :prepend}], [{:after => :prepend}]]) assert_inherited_teardown(expected_teardown_calls, test_case) assert_inherited_teardown([:teardown], nil) assert_called_fixtures(expected_teardown_calls, test_case) end def test_with_invalid_option assert_invalid_teardown_option(:unknown => true) assert_invalid_teardown_option(:before => :unknown) assert_invalid_teardown_option(:after => :unknown) end def test_with_option_to_inherited expected_teardown_calls = [:teardown] test_case = assert_teardown(expected_teardown_calls, nil) assert_inherited_teardown([:custom_teardown_callback3, :custom_teardown_method3, :custom_teardown_callback1, :custom_teardown_method1, :custom_teardown_callback0, :custom_teardown_method0, :teardown], test_case, []) assert_inherited_teardown([:teardown], nil) assert_called_fixtures(expected_teardown_calls, test_case) end def test_with_exception test_case = Class.new(Test::Unit::TestCase) do def called_ids @called_ids ||= [] end def called(id) called_ids << id end def teardown called(:teardown) raise "teardown" end teardown def custom_teardown_method0 called(:custom_teardown_method0) raise "custom_teardown_method0" end teardown do called(:custom_teardown_callback0) raise "custom_teardown_callback0" end teardown def custom_teardown_method1 called(:custom_teardown_method1) raise "custom_teardown_method1" end teardown do called(:custom_teardown_callback1) raise "custom_teardown_callback1" end def test_nothing end end assert_called_fixtures([:custom_teardown_callback1, :custom_teardown_method1, :custom_teardown_callback0, :custom_teardown_method0, :teardown], test_case) end def test_nested called = [] parent_test_case = Class.new(Test::Unit::TestCase) do teardown do called << :parent end end child_test_case = Class.new(parent_test_case) do teardown do called << :child end def test_nothing end end run_test_nothing(child_test_case) assert_equal([:child, :parent], called) end def test_setup_with_block test_case = Class.new(Test::Unit::TestCase) do def called_ids @called_ids ||= [] end def called(id) called_ids << id end setup def setup1 called(:setup1) begin yield called(:setup1_after_yield) ensure called(:setup1_teardown) end end setup def setup2 called(:setup2) begin yield called(:setup2_after_yield) ensure called(:setup2_teardown) end end def teardown called(:teardown) end def test_nothing called(:test) flunk called(:test_after_failure) end end assert_called_fixtures([ :setup1, :setup2, :test, :setup2_teardown, :setup1_teardown, :teardown, ], test_case) end private def assert_teardown_customizable(expected, parent, options) test_case = Class.new(parent || Test::Unit::TestCase) do yield(self, :before) if block_given? def called_ids @called_ids ||= [] end def called(id) called_ids << id end def teardown called(:teardown) end teardown(*(options[0] || [])) if options def custom_teardown_method0 called(:custom_teardown_method0) end if options teardown(*(options[0] || [])) do called(:custom_teardown_callback0) end end def custom_teardown_method1 called(:custom_teardown_method1) end teardown(*[:custom_teardown_method1, *(options[1] || [])]) if options if options teardown(*(options[1] || [])) do called(:custom_teardown_callback1) end end teardown(*(options[2] || [])) if options def custom_teardown_method2 called(:custom_teardown_method2) end unregister_teardown(:custom_teardown_method2) if options if options callback = lambda do called(:custom_teardown_callback2) end teardown(*(options[2] || []), &callback) unregister_teardown(callback) end teardown(*(options[3] || [])) if options def custom_teardown_method3 called(:custom_teardown_method3) end if options teardown(*(options[3] || [])) do called(:custom_teardown_callback3) end end def test_nothing end yield(self, :after) if block_given? end assert_called_fixtures(expected, test_case) test_case end def assert_teardown(expected, options) assert_teardown_customizable(expected, nil, options) assert_teardown_customizable(expected, nil, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end end def assert_inherited_teardown(expected, parent, options=nil) assert_teardown_customizable(expected, parent, options) assert_teardown_customizable(expected, parent, options) do |test_case, tag| test_case.send(:include, EmptyModule) if tag == :before end end def assert_invalid_teardown_option(option) assert_invalid_option(:teardown, option) end end private def run_test_nothing(test_case) test = test_case.new("test_nothing") test.run(Test::Unit::TestResult.new) {} test end def assert_called_fixtures(expected, test_case) test = run_test_nothing(test_case) assert_equal(expected, test.called_ids) end def assert_invalid_option(fixture_type, option) exception = assert_raise(ArgumentError) do Class.new(Test::Unit::TestCase) do def test_nothing end send(fixture_type, option) def fixture end end end assert_equal("must be {:before => :prepend}, {:before => :append}, " + "{:after => :prepend} or {:after => :append}" + ": #{option.inspect}", exception.message) end end test-unit-3.3.9/test/test-color.rb0000644000004100000410000000306213775322563017127 0ustar www-datawww-dataclass TestUnitColor < Test::Unit::TestCase def test_color_escape_sequence assert_escape_sequence(["31"], color("red")) assert_escape_sequence(["32", "1"], color("green", :bold => true)) assert_escape_sequence(["0"], color("reset")) assert_escape_sequence(["45"], color("magenta", :background => true)) end def test_mix_color_escape_sequence assert_escape_sequence(["34", "1"], mix_color([color("blue"), color("none", :bold => true)])) assert_escape_sequence(["34", "1", "4"], mix_color([color("blue"), color("none", :bold => true)]) + color("none", :underline => true)) assert_escape_sequence(["34", "1", "4"], color("blue") + color("none", :bold => true) + color("none", :underline => true)) end def test_equal red = color("red") red_bold = color("red", :bold => true) assert_operator(red, :==, red) assert_not_equal(red, nil) assert_equal(red, color("red")) assert_not_equal(red, red_bold) end private def color(name, options={}) Test::Unit::Color.new(name, options) end def mix_color(colors) Test::Unit::MixColor.new(colors) end def assert_escape_sequence(expected, color) assert_equal(expected, color.sequence) assert_match(/\e\[(?:\d+;)*\d+m/, color.escape_sequence) assert_equal(expected, color.escape_sequence[2..-2].split(";")) end end test-unit-3.3.9/test/test-attribute-matcher.rb0000644000004100000410000000143613775322563021440 0ustar www-datawww-datarequire 'test/unit' require 'testunit-test-util' class TestAttributeMatcher < Test::Unit::TestCase include TestUnitTestUtil def setup @test = {} @matcher = Test::Unit::AttributeMatcher.new(@test) end def test_nonexistent assert_false(@matcher.match?("nonexistent")) end def test_existent @test[:existent] = true assert_true(@matcher.match?("existent")) end def test_and @test[:slow] = true @test[:important] = true assert_true(@matcher.match?("important and slow")) end def test_complex @test[:tags] = [:slow, :web] @test[:bug] = "2929" assert_true(@matcher.match?("tags.include?(:web) or bug == '29'")) end def test_exception assert_raise(NoMethodError) do @matcher.match?("nonexistent > 100") end end end test-unit-3.3.9/test/test-test-case.rb0000644000004100000410000011033713775322563017705 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2008-2014 Kouhei Sutou # Copyright:: Copyright (c) 2011 Haruka Yoshihara # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott # License:: Ruby license. require 'test/unit' module Test module Unit class TestTestCase < TestCase self.test_order = :random def test_creation test_case = Class.new(TestCase) do def test_with_arguments(arg1, arg2) end end test = test_case.new(:test_with_arguments) check("Should have caught an invalid test when there are arguments", !test.valid?) test = test_case.new(:non_existent_test) check("Should have caught an invalid test when the method does not exist", !test.valid?) end def setup @tc_failure_error = Class.new(TestCase) do def test_failure assert_block("failure") do false end end def test_error 1 / 0 end def test_nested_failure nested end def nested assert_block("nested") do false end end def return_passed? return passed? end end def @tc_failure_error.name "TC_FailureError" end end def jruby_backtrace_entry?(entry) entry.start_with?("org/jruby/") end def rubinius_backtrace_entry?(entry) entry.start_with?("kernel/") end def internal_backtrace_entry?(entry) entry.start_with?(" fault.class, :message => fault.message, :test_name => fault.test_name, :location => normalize_location(fault.location), } end assert_equal([ { :class => Failure, :message => "failure", :test_name => "test_failure(TC_FailureError)", :location => [ "#{__FILE__}:0:in `test_failure'", "#{__FILE__}:0:in `#{__method__}'", ], }, ], fault_details) assert do not test_case.passed? end assert_equal([ [TestCase::STARTED, test_case.name], [TestCase::STARTED_OBJECT, test_case], [TestCase::FINISHED, test_case.name], [TestCase::FINISHED_OBJECT, test_case], ], progress) end def test_add_failure_nested test_case = @tc_failure_error.new(:test_nested_failure) assert do test_case.passed? end result = TestResult.new faults = [] result.add_listener(TestResult::FAULT) do |fault| faults << fault end test_case.run(result) do end fault_details = faults.collect do |fault| { :class => fault.class, :message => fault.message, :test_name => fault.test_name, :location => normalize_location(fault.location), } end assert_equal([ { :class => Failure, :message => "nested", :test_name => "test_nested_failure(TC_FailureError)", :location => [ "#{__FILE__}:0:in `nested'", "#{__FILE__}:0:in `test_nested_failure'", "#{__FILE__}:0:in `#{__method__}'", ], }, ], fault_details) assert do not test_case.passed? end end def jruby? defined?(JRUBY_VERSION) end def rubinius? false # TODO end def cruby? (not jruby?) and (not rubinius?) end def test_add_error test_case = @tc_failure_error.new(:test_error) assert do test_case.passed? end result = TestResult.new faults = [] result.add_listener(TestResult::FAULT) do |fault| faults << fault end test_case.run(result) do end fault_details = faults.collect do |fault| { :class => fault.class, :message => fault.message, :test_name => fault.test_name, :location => normalize_location(fault.location), } end location = [] location << "#{__FILE__}:0:in `/'" if cruby? location << "#{__FILE__}:0:in `test_error'" location << "#{__FILE__}:0:in `#{__method__}'" assert_equal([ { :class => Error, :message => "ZeroDivisionError: divided by 0", :test_name => "test_error(TC_FailureError)", :location => location, }, ], fault_details) assert do not test_case.passed? end end def test_no_tests suite = TestCase.suite check("Should have a test suite", suite.instance_of?(TestSuite)) check("Should have one test", suite.size == 1) check("Should have the default test", suite.tests.first.name == "default_test(Test::Unit::TestCase)") result = TestResult.new suite.run(result) {} check("Should have had one test run", result.run_count == 1) check("Should have had one test failure", result.failure_count == 1) check("Should have had no errors", result.error_count == 0) end def test_suite tc = Class.new(TestCase) do def test_succeed assert_block {true} end def test_fail assert_block {false} end def test_error 1/0 end def dont_run assert_block {true} end def test_dont_run(argument) assert_block {true} end def test assert_block {true} end end suite = tc.suite check("Should have a test suite", suite.instance_of?(TestSuite)) check("Should have three tests", suite.size == 3) result = TestResult.new suite.run(result) {} check("Should have had three test runs", result.run_count == 3) check("Should have had one test failure", result.failure_count == 1) check("Should have had one test error", result.error_count == 1) end def test_setup_teardown tc = Class.new(TestCase) do attr_reader(:setup_called, :teardown_called) def initialize(test) super(test) @setup_called = false @teardown_called = false end def setup @setup_called = true end def teardown @teardown_called = true end def test_succeed assert_block {true} end def test_fail assert_block {false} end def test_error raise "Error!" end end result = TestResult.new test = tc.new(:test_succeed) test.run(result) {} check("Should have called setup the correct number of times", test.setup_called) check("Should have called teardown the correct number of times", test.teardown_called) test = tc.new(:test_fail) test.run(result) {} check("Should have called setup the correct number of times", test.setup_called) check("Should have called teardown the correct number of times", test.teardown_called) test = tc.new(:test_error) test.run(result) {} check("Should have called setup the correct number of times", test.setup_called) check("Should have called teardown the correct number of times", test.teardown_called) check("Should have had two test runs", result.run_count == 3) check("Should have had a test failure", result.failure_count == 1) check("Should have had a test error", result.error_count == 1) end def test_assertion_failed_not_called tc = Class.new(TestCase) do def test_thing raise AssertionFailedError.new end end suite = tc.suite check("Should have one test", suite.size == 1) result = TestResult.new suite.run(result) {} check("Should have had one test run", result.run_count == 1) check("Should have had one assertion failure", result.failure_count == 1) check("Should not have any assertion errors but had #{result.error_count}", result.error_count == 0) end def test_equality tc1 = Class.new(TestCase) do def test_1 end def test_2 end end tc2 = Class.new(TestCase) do def test_1 end end test1 = tc1.new('test_1') test2 = tc1.new('test_1') check("Should be equal", test1 == test2) check("Should be equal", test2 == test1) test1 = tc1.new('test_2') check("Should not be equal", test1 != test2) check("Should not be equal", test2 != test1) test2 = tc1.new('test_2') check("Should be equal", test1 == test2) check("Should be equal", test2 == test1) test1 = tc1.new('test_1') test2 = tc2.new('test_1') check("Should not be equal", test1 != test2) check("Should not be equal", test2 != test1) check("Should not be equal", test1 != Object.new) check("Should not be equal", Object.new != test1) end def test_re_raise_exception test_case = Class.new(TestCase) do def test_raise_interrupt raise Interrupt, "from test" end end test = test_case.new("test_raise_interrupt") begin test.run(TestResult.new) {} check("Should not be reached", false) rescue Exception check("Interrupt exception should be re-raised", $!.class == Interrupt) end end def test_timeout_error test_case = Class.new(TestCase) do def test_raise_timeout_error require "timeout" raise Timeout::Error end end test_suite = test_case.suite result = TestResult.new begin test_suite.run(result) {} check("Timeout::Error should be handled as error", result.error_count == 1) rescue Exception check("Timeout::Error should not be passed through: #{$!}", false) end end def test_interrupted test_case = Class.new(TestCase) do def test_fail flunk end def test_nothing end end failed_test = test_case.new(:test_fail) failed_test.run(TestResult.new) {} check("Should be interrupted", failed_test.interrupted?) success_test = test_case.new(:test_nothing) success_test.run(TestResult.new) {} check("Should not be interrupted", !success_test.interrupted?) end def test_inherited_test_should_be_ignored test_case = Class.new(TestCase) do def test_nothing end end sub_test_case = Class.new(test_case) do def test_fail flunk end end test = test_case.new("test_nothing") assert_predicate(test, :valid?) test = sub_test_case.new("test_fail") assert_predicate(test, :valid?) test = sub_test_case.new("test_nothing") assert_not_predicate(test, :valid?) end def test_mixin_test_should_not_be_ignored test_module = Module.new do def test_nothing end end test_case = Class.new(Test::Unit::TestCase) do include test_module def test_fail flunk end end assert_nothing_thrown do test_case.new("test_nothing") end assert_nothing_thrown do test_case.new("test_fail") end end def test_defined_order test_case = Class.new(Test::Unit::TestCase) do def test_z end def test_1 end def test_a end end test_case.test_order = :defined assert_equal(["test_z", "test_1", "test_a"], test_case.suite.tests.collect {|test| test.method_name}) end def test_declarative_style test_case = Class.new(Test::Unit::TestCase) do test "declarative style test definition" do end test "include parenthesis" do end test "1 + 2 = 3" do end end test_case.test_order = :defined assert_equal(["test: declarative style test definition", "test: include parenthesis", "test: 1 + 2 = 3"], test_case.suite.tests.collect {|test| test.method_name}) assert_equal(["declarative style test definition", "include parenthesis", "1 + 2 = 3"], test_case.suite.tests.collect {|test| test.description}) end def test_test_mark test_case = Class.new(Test::Unit::TestCase) do test def my_test_method end end test_case.test_order = :defined assert_equal(["my_test_method"], test_case.suite.tests.collect {|test| test.method_name}) end def test_redefine_method test_case = Class.new(Test::Unit::TestCase) do self.test_order = :alphabetic def test_name end alias_method :test_name2, :test_name def test_name end end suite = test_case.suite assert_equal(["test_name", "test_name2"], suite.tests.collect {|test| test.method_name}) result = TestResult.new suite.run(result) {} assert_equal("2 tests, 0 assertions, 0 failures, " + "0 errors, 0 pendings, 0 omissions, 1 notifications", result.summary) end def test_data_driven_test test_case = Class.new(TestCase) do def test_with_data(data) end end test = test_case.new("test_with_data") assert_not_predicate(test, :valid?) test.assign_test_data("label1", :test_data1) assert_predicate(test, :valid?) end def test_data_driven_test_without_parameter test_case = Class.new(TestCase) do data("label" => "value") def test_without_parameter assert_equal("value", data) end end suite = test_case.suite assert_equal(["test_without_parameter"], suite.tests.collect {|test| test.method_name}) result = TestResult.new suite.run(result) {} assert_equal("1 tests, 1 assertions, 0 failures, " + "0 errors, 0 pendings, 0 omissions, 0 notifications", result.summary) end private def check(message, passed) add_assertion raise AssertionFailedError.new(message) unless passed end class TestTestDefined < self class TestNoQuery < self def test_no_test test_case = Class.new(TestCase) do end assert_false(test_case.test_defined?({})) end def test_have_def_style_test test_case = Class.new(TestCase) do def test_nothing end end assert_true(test_case.test_defined?({})) end def test_have_method_style_test test_case = Class.new(TestCase) do test "nothing" do end end assert_true(test_case.test_defined?({})) end end class TestPath < self class TestDefStyle < self def test_base_name test_case = Class.new(TestCase) do def test_nothing end end base_name = File.basename(__FILE__) assert_true(test_case.test_defined?(:path => base_name)) end def test_absolute_path test_case = Class.new(TestCase) do def test_nothing end end assert_true(test_case.test_defined?(:path => __FILE__)) end def test_not_match test_case = Class.new(TestCase) do def test_nothing end end assert_false(test_case.test_defined?(:path => "nonexistent.rb")) end end class TestMethodStyle < self def test_base_name test_case = Class.new(TestCase) do test "nothing" do end end base_name = File.basename(__FILE__) assert_true(test_case.test_defined?(:path => base_name)) end def test_absolute_path test_case = Class.new(TestCase) do test "nothing" do end end assert_true(test_case.test_defined?(:path => __FILE__)) end def test_not_match test_case = Class.new(TestCase) do test "nothing" do end end assert_false(test_case.test_defined?(:path => "nonexistent.rb")) end end end class TestLine < self class TestDefStyle < self def test_before line_before = nil test_case = Class.new(TestCase) do line_before = __LINE__ def test_nothing end end assert_false(test_case.test_defined?(:line => line_before)) end def test_def line_def = nil test_case = Class.new(TestCase) do line_def = __LINE__; def test_nothing end end assert_true(test_case.test_defined?(:line => line_def)) end def test_after line_after = nil test_case = Class.new(TestCase) do def test_nothing end line_after = __LINE__ end assert_true(test_case.test_defined?(:line => line_after)) end def test_child child_test_case = nil line_child = nil parent_test_case = Class.new(TestCase) do test "parent" do end child_test_case = Class.new(self) do line_child = __LINE__; test "child" do end end end assert_equal([ false, true, ], [ parent_test_case.test_defined?(:line => line_child), child_test_case.test_defined?(:line => line_child), ]) end end class TestMethodStyle < self def test_before line_before = nil test_case = Class.new(TestCase) do line_before = __LINE__ test "nothing" do end end assert_false(test_case.test_defined?(:line => line_before)) end def test_method line_method = nil test_case = Class.new(TestCase) do line_method = __LINE__; test "nothing" do end end assert_true(test_case.test_defined?(:line => line_method)) end def test_after line_after = nil test_case = Class.new(TestCase) do test "nothing" do end line_after = __LINE__ end assert_true(test_case.test_defined?(:line => line_after)) end def test_child child_test_case = nil line_child = nil parent_test_case = Class.new(TestCase) do test "parent" do end child_test_case = Class.new(self) do line_child = __LINE__; test "child" do end end end assert_equal([ false, true, ], [ parent_test_case.test_defined?(:line => line_child), child_test_case.test_defined?(:line => line_child), ]) end def test_with_setup line = nil test_case = Class.new(TestCase) do setup do end line = __LINE__; test "with setup" do end end assert do test_case.test_defined?(:line => line, :method_name => "test: with setup") end end end end class TestMethodName < self class TestDefStyle < self def test_match test_case = Class.new(TestCase) do def test_nothing end end query = {:method_name => "test_nothing"} assert_true(test_case.test_defined?(query)) end def test_not_match test_case = Class.new(TestCase) do def test_nothing end end query = {:method_name => "test_nonexistent"} assert_false(test_case.test_defined?(query)) end end class TestMethodStyle < self def test_match test_case = Class.new(TestCase) do test "nothing" do end end query = {:method_name => "test: nothing"} assert_true(test_case.test_defined?(query)) end def test_not_match test_case = Class.new(TestCase) do test "nothing" do end end query = {:method_name => "test: nonexistent"} assert_false(test_case.test_defined?(query)) end end end class TestCombine < self class TestDefStyle < self def test_line_middle line_middle = nil test_case = Class.new(TestCase) do def test_before end line_middle = __LINE__ def test_after end end query = { :path => __FILE__, :line => line_middle, :method_name => "test_before", } assert_true(test_case.test_defined?(query)) end def test_line_after_def line_after_def = nil test_case = Class.new(TestCase) do def test_before end line_after_def = __LINE__; def test_after end end query = { :path => __FILE__, :line => line_after_def, :method_name => "test_before", } assert_false(test_case.test_defined?(query)) end end class TestMethodStyle < self def test_line_middle line_middle = nil test_case = Class.new(TestCase) do test "before" do end line_middle = __LINE__ test "after" do end end query = { :path => __FILE__, :line => line_middle, :method_name => "test: before", } assert_true(test_case.test_defined?(query)) end def test_line_after_method line_after_method = nil test_case = Class.new(TestCase) do test "before" do end line_after_method = __LINE__; test "after" do end end query = { :path => __FILE__, :line => line_after_method, :method_name => "test: before", } assert_false(test_case.test_defined?(query)) end end end end class TestSubTestCase < self class TestName < self def test_anonymous test_case = Class.new(TestCase) sub_test_case = test_case.sub_test_case("sub test case") do end assert_equal("sub test case", sub_test_case.name) end def test_named test_case = Class.new(TestCase) def test_case.name "ParentTestCase" end sub_test_case = test_case.sub_test_case("sub test case") do end assert_equal("ParentTestCase::sub test case", sub_test_case.name) end end def test_suite test_case = Class.new(TestCase) sub_test_case = test_case.sub_test_case("sub test case") do def test_nothing end end test_method_names = sub_test_case.suite.tests.collect do |test| test.method_name end assert_equal(["test_nothing"], test_method_names) end def test_duplicated_name test_case = Class.new(TestCase) do def test_nothing end end sub_test_case = test_case.sub_test_case("sub test case") do def test_nothing end end test_method_names = test_case.suite.tests.collect do |test| test.method_name end sub_test_method_names = sub_test_case.suite.tests.collect do |test| test.method_name end assert_equal([ ["test_nothing"], ["test_nothing"], ], [ test_method_names, sub_test_method_names, ]) end end class TestStartupShutdown < self class TestOrder < self module CallLogger def called @@called ||= [] end end def call_order(test_case) test_case.called.clear test_suite = test_case.suite test_suite.run(TestResult.new) {} test_case.called end class TestNoInheritance < self def setup @test_case = Class.new(TestCase) do extend CallLogger class << self def startup called << :startup end def shutdown called << :shutdown end end def setup self.class.called << :setup end def teardown self.class.called << :teardown end def test1 end def test2 end end end def test_call_order assert_equal([ :startup, :setup, :teardown, :setup, :teardown, :shutdown, ], call_order(@test_case)) end end class TestInheritance < self def setup @original_descendants = TestCase::DESCENDANTS.dup TestCase::DESCENDANTS.clear @parent_test_case = Class.new(TestCase) do extend CallLogger self.test_order = :alphabetic class << self def startup called << :startup_parent end def shutdown called << :shutdown_parent end end def setup self.class.called << :setup_parent end def teardown self.class.called << :teardown_parent end def test1_parent self.class.called << :test1_parent end def test2_parent self.class.called << :test2_parent end end @child_test_case = Class.new(@parent_test_case) do class << self def startup called << :startup_child end def shutdown called << :shutdown_child end end def setup self.class.called << :setup_child end def teardown self.class.called << :teardown_child end def test1_child self.class.called << :test1_child end def test2_child self.class.called << :test2_child end end end def teardown TestCase::DESCENDANTS.replace(@original_descendants) end def test_call_order collector = Collector::Descendant.new test_suite = collector.collect test_suite.run(TestResult.new) {} called = @parent_test_case.called assert_equal([ :startup_parent, :setup_parent, :test1_parent, :teardown_parent, :setup_parent, :test2_parent, :teardown_parent, :startup_child, :setup_child, :test1_child, :teardown_child, :setup_child, :test2_child, :teardown_child, :shutdown_child, :shutdown_parent, ], called) end end end class TestError < self def run_test_case(test_case) test_suite = test_case.suite result = TestResult.new test_suite.run(result) {} result end def error_count(test_case) run_test_case(test_case).error_count end def test_on_startup test_case = Class.new(TestCase) do class << self def startup raise "from startup" end end def test_nothing end end assert_equal(1, error_count(test_case)) end def test_pass_through_on_startup test_case = Class.new(TestCase) do class << self def startup raise Interrupt, "from startup" end end def test_nothing end end assert_raise(Interrupt) do run_test_case(test_case) end end def test_on_shutdown test_case = Class.new(TestCase) do class << self def shutdown raise "from shutdown" end end def test_nothing end end assert_equal(1, error_count(test_case)) end def test_pass_through_on_shutdown test_case = Class.new(TestCase) do class << self def shutdown raise Interrupt, "from shutdown" end end def test_nothing end end assert_raise(Interrupt) do run_test_case(test_case) end end def test_pass_through_in_test test_case = Class.new(TestCase) do @called = [] class << self def called @called end def startup @called << :startup end def shutdown @called << :shutdown end end def test_error raise Interrupt, "from test" end end assert_raise(Interrupt) do run_test_case(test_case) end assert_equal([:startup, :shutdown], test_case.called) end class TestName < self def test_no_data test_case = Class.new(TestCase) do class << self def name "TestCase" end end def test_nothing end end test = test_case.new("test_nothing") assert_equal("test_nothing(TestCase)", test.name) end def test_data test_case = Class.new(TestCase) do class << self def name "TestCase" end end def test_nothing end end test = test_case.new("test_nothing") test.assign_test_data("(nil)", nil) assert_equal("test_nothing[(nil)](TestCase)", test.name) end end class TestLocalName < self def test_no_data test_case = Class.new(TestCase) do class << self def name "TestCase" end end def test_nothing end end test = test_case.new("test_nothing") assert_equal("test_nothing", test.local_name) end def test_data test_case = Class.new(TestCase) do class << self def name "TestCase" end end def test_nothing end end test = test_case.new("test_nothing") test.assign_test_data("(nil)", nil) assert_equal("test_nothing[(nil)]", test.local_name) end end end end end end end test-unit-3.3.9/test/run-test.rb0000755000004100000410000000115413775322563016620 0ustar www-datawww-data#!/usr/bin/env ruby $VERBOSE = true $KCODE = "utf8" unless "".respond_to?(:encoding) base_dir = File.expand_path(File.join(File.dirname(__FILE__), "..")) lib_dir = File.join(base_dir, "lib") test_dir = File.join(base_dir, "test") $LOAD_PATH.unshift(lib_dir) require 'test/unit' test_unit_notify_base_dir = File.join(base_dir, "..", "test-unit-notify") test_unit_notify_base_dir = File.expand_path(test_unit_notify_base_dir) if File.exist?(test_unit_notify_base_dir) $LOAD_PATH.unshift(File.join(test_unit_notify_base_dir, "lib")) require 'test/unit/notify' end exit Test::Unit::AutoRunner.run(true, test_dir) test-unit-3.3.9/test/collector/0000755000004100000410000000000013775322563016474 5ustar www-datawww-datatest-unit-3.3.9/test/collector/test_dir.rb0000644000004100000410000002532713775322563020647 0ustar www-datawww-datarequire 'test/unit' require 'test/unit/collector/dir' require 'pp' module Test module Unit module Collector class TestDir < TestCase class FileSystem class Directory def initialize(name, fs, parent=self, &block) @name = name @fs = fs @parent = parent @contents = {'.' => self, '..' => parent} instance_eval(&block) if(block) end def file(name, contents) @contents[name] = contents end def dir(name, &block) @contents[name] = self.class.new(name, @fs, self, &block) end def entries @contents.keys end def directory?(name) return true if(name.nil? || name.empty?) return false unless(@contents.include?(name)) @contents[name].kind_of?(self.class) end def file?(name) return false unless(@contents.include?(name)) !directory?(name) end def exist?(name) @contents.include?(name) end def [](name) raise Errno::ENOENT, name unless(@contents.include?(name)) @contents[name] end def path_to(name=nil) if(!name) @parent.path_to(@name) elsif(@parent == self) @fs.join('/', name) else @fs.join(@parent.path_to(@name), name) end end end class ObjectSpace def initialize @objects = [] end def each_object(klass, &block) @objects.find_all{|o| o.kind_of?(klass)}.each(&block) end def <<(object) @objects << object end end attr_reader :object_space def initialize(&block) @root = Directory.new('/', self, &block) @pwd = @root @object_space = ObjectSpace.new @required = [] end def entries(dir) e = find(dir) require_directory(dir) e.entries end def directory?(name) return true if (base = basename(name)) == '/' e = find(dirname(name)) return false unless(e) e.directory?(base) end def find(path) if(/\A\// =~ path) thing = @root else thing = @pwd end path.scan(/[^\/]+/) do |e| break thing = false unless(thing.kind_of?(Directory)) thing = thing[e] end thing end def dirname(name) if (name = name.tr_s('/', '/')) == '/' name else name[%r"\A.+(?=/[^/]+/?\z)|\A/"] || "." end end def basename(name) name[%r"(\A/|[^/]+)/*\z", 1] end def split(name) [dirname(name), basename(name)] end def join(*parts) parts.join('/').gsub(%r{/+}, '/') end def file?(name) e = find(dirname(name)) return false unless(e) e.file?(basename(name)) end def pwd @pwd.path_to end def chdir(to) e = find(to) require_directory(to) @pwd = e end def expand_path(path, base = nil) until /\A\// =~ path base ||= pwd path = join(base, path) base = nil end path.gsub!(%r"(?:/\.)+(?=/)", '') nil while path.sub!(%r"/(?!\.\./)[^/]+/\.\.(?=/)", '') path.sub!(%r"\A(?:/\.\.)+(?=/)", '') path.sub!(%r"(?:\A(/)|/)\.\.?\z", '\1') path end def require_directory(path) raise Errno::ENOTDIR, path unless(directory?(path)) end def require(file) return false if(@required.include?(file)) begin e = find(file) rescue Errno::ENOENT => e if(/\.rb\Z/ =~ file) raise LoadError, file end e = find(file + '.rb') end @required << file @object_space << e true rescue Errno::ENOENT raise LoadError, file end end def test_dir inner_dir = nil dirs = FileSystem::Directory.new('/', nil) do file 'a', nil inner_dir = dir 'b' end assert_equal(inner_dir, dirs['b']) end def test_fs fs = FileSystem.new do file 'a', nil dir 'b' end assert_equal(['.', '..', 'a', 'b'].sort, fs.entries('/').sort) assert(fs.directory?('/')) assert(!fs.directory?('/a')) assert(!fs.directory?('/bogus')) assert(fs.file?('/a')) assert(!fs.file?('/')) assert(!fs.file?('/bogus')) assert(fs.directory?('/b')) assert(fs.file?('a')) assert(fs.directory?('b')) end def test_fs_sub fs = FileSystem.new do dir 'a' do file 'b', nil dir 'c' do file 'd', nil end end end assert(fs.file?('/a/b')) assert(!fs.file?('/a/b/c/d')) assert(fs.file?('/a/c/d')) end def test_fs_pwd fs = FileSystem.new do file 'a', nil dir 'b' do file 'c', nil dir 'd' do file 'e', nil end end end assert_equal('/', fs.pwd) assert_raises(Errno::ENOENT) do fs.chdir('bogus') end assert_raises(Errno::ENOTDIR) do fs.chdir('a') end fs.chdir('b') assert_equal('/b', fs.pwd) fs.chdir('d') assert_equal('/b/d', fs.pwd) fs.chdir('..') assert_equal('/b', fs.pwd) fs.chdir('..') assert_equal('/', fs.pwd) end def test_fs_entries fs = FileSystem.new do file 'a', nil dir 'b' do file 'c', nil file 'd', nil end file 'e', nil dir 'f' do file 'g', nil dir 'h' do file 'i', nil end end end assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('/').sort) assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('.').sort) assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('b/..').sort) assert_equal(['.', '..', 'c', 'd'], fs.entries('b').sort) assert_raises(Errno::ENOENT) do fs.entries('z') end assert_raises(Errno::ENOTDIR) do fs.entries('a') end fs.chdir('f') assert_equal(['.', '..', 'i'], fs.entries('h').sort) end class TestClass1 end class TestClass2 end def test_fs_require fs = FileSystem.new do file 'test_class1.rb', TestClass1 dir 'dir' do file 'test_class2.rb', TestClass2 end end c = [] fs.object_space.each_object(Class) do |o| c << o end assert_equal([], c) assert_raises(LoadError) do fs.require('bogus') end assert(fs.require('test_class1.rb')) assert(!fs.require('test_class1.rb')) c = [] fs.object_space.each_object(Class) do |o| c << o end assert_equal([TestClass1], c) fs.require('dir/test_class2') c = [] fs.object_space.each_object(Class) do |o| c << o end assert_equal([TestClass1, TestClass2], c) c = [] fs.object_space.each_object(Time) do |o| c << o end assert_equal([], c) end def setup @t1 = t1 = create_test(1) @t2 = t2 = create_test(2) @t3 = t3 = create_test(3) @t4 = t4 = create_test(4) @t5 = t5 = create_test(5) @t6 = t6 = create_test(6) fs = FileSystem.new do file 'test_1.rb', t1 file 'test_2.rb', t2 dir 'd1' do file 'test_3.rb', t3 end file 't4.rb', t4 dir 'd2' do file 'test_5', t5 file 'test_6.rb', Time end file 't6.rb', t6 end fs.require('t6') @c = Dir.new(fs, fs, fs.object_space, fs) end def create_test(name) t = Class.new(TestCase) t.class_eval <<-EOC self.test_order = :alphabetic def self.name "T\#{#{name}}" end def test_#{name}a end def test_#{name}b end EOC t end def test_simple_collect expected = TestSuite.new('d1') expected << (@t3.suite) assert_equal(expected, @c.collect('d1')) end def test_multilevel_collect expected = TestSuite.new('.') expected << @t1.suite << @t2.suite expected << (TestSuite.new('d1') << @t3.suite) assert_equal(expected, @c.collect) end def test_collect_file expected = TestSuite.new('test_1.rb') expected << @t1.suite assert_equal(expected, @c.collect('test_1.rb')) expected = TestSuite.new('t4.rb') expected << @t4.suite assert_equal(expected, @c.collect('t4.rb')) end def test_nil_pattern expected = TestSuite.new('d2') expected << @t5.suite @c.pattern.clear assert_equal(expected, @c.collect('d2')) end def test_filtering expected = TestSuite.new('.') expected << @t1.suite @c.filter = proc{|t| t.method_name == 'test_1a' || t.method_name == 'test_1b'} assert_equal(expected, @c.collect) end def test_collect_multi expected = TestSuite.new('[d1, d2]') expected << (TestSuite.new('d1') << @t3.suite) expected << (TestSuite.new('d2') << @t5.suite) @c.pattern.replace([/\btest_/]) assert_equal(expected, @c.collect('d1', 'd2')) end end end end end test-unit-3.3.9/test/collector/test-load.rb0000644000004100000410000003333613775322563020725 0ustar www-datawww-datarequire 'tmpdir' require 'pathname' require 'test/unit' require 'test/unit/collector/load' class TestUnitCollectorLoad < Test::Unit::TestCase def setup @previous_descendants = Test::Unit::TestCase::DESCENDANTS.dup Test::Unit::TestCase::DESCENDANTS.clear @temporary_test_cases_module_name = "TempTestCases" ::Object.const_set(@temporary_test_cases_module_name, Module.new) @test_dir = Pathname(Dir.tmpdir) + "test-unit" @extra_test_dir = Pathname(Dir.tmpdir) + "test-unit-extra" ensure_clean_directory(@test_dir) ensure_clean_directory(@extra_test_dir) end setup def setup_top_level_test_cases @test_case1_base_name = "test_case1.rb" @test_case1 = @test_dir + @test_case1_base_name @test_case2 = @test_dir + "test_case2.rb" @no_load_test_case3 = @test_dir + "case3.rb" @test_case1.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class TestCase1 < Test::Unit::TestCase def test1_1 end def test1_2 end end end EOT end @test_case2.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class TestCase2 < Test::Unit::TestCase def test2 end end end EOT end @no_load_test_case3.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class NoLoadTestCase3 < Test::Unit::TestCase def test3 end end end EOT end end setup def setup_sub_level_test_cases @sub_test_dir = @test_dir + "sub" @sub_test_dir.mkpath @sub_test_case1 = @sub_test_dir + @test_case1_base_name @sub_test_case4 = @sub_test_dir + "test_case4.rb" @no_load_sub_test_case5 = @sub_test_dir + "case5.rb" @sub_test_case6 = @sub_test_dir + "test_case6.rb" @sub_test_case1.open("w") do |test_case| test_case.puts(<<-TEST_CASE) module #{@temporary_test_cases_module_name} class SubTestCase1 < Test::Unit::TestCase def test1_1 end def test1_2 end end end TEST_CASE end @sub_test_case4.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SubTestCase4 < Test::Unit::TestCase def test4_1 end def test4_2 end end end EOT end @no_load_sub_test_case5.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class NoLoadSubTestCase5 < Test::Unit::TestCase def test5_1 end def test5_2 end end end EOT end @sub_test_case6.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SubTestCase6 < Test::Unit::TestCase def test6 end end end EOT end end setup def setup_sub_level_test_cases2 @sub2_test_dir = @test_dir + "sub2" @sub2_test_dir.mkpath @no_load_sub2_test_case7 = @sub2_test_dir + "case7.rb" @sub2_test_case8 = @sub2_test_dir + "test_case8.rb" @sub2_test_case9 = @sub2_test_dir + "test_case9.rb" @no_load_sub2_test_case7.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class NoLoadSub2TestCase7 < Test::Unit::TestCase def test7_1 end def test7_2 end end end EOT end @sub2_test_case8.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class Sub2TestCase8 < Test::Unit::TestCase def test8_1 end def test8_2 end end end EOT end @sub2_test_case9.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class Sub2TestCase9 < Test::Unit::TestCase def test9 end end end EOT end end setup def setup_svn_test_cases @svn_test_dir = @test_dir + ".svn" @svn_test_dir.mkpath @svn_test_case10 = @svn_test_dir + "test_case10.rb" @svn_test_case10.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SvnTestCase10 < Test::Unit::TestCase def test7 end end end EOT end end setup def setup_sub_cvs_test_cases @sub_cvs_test_dir = @sub_test_dir + "CVS" @sub_cvs_test_dir.mkpath @sub_cvs_test_case11 = @sub_cvs_test_dir + "test_case11.rb" @sub_cvs_test_case11.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SubCVSTestCase11 < Test::Unit::TestCase def test11 end end end EOT end end setup def setup_sub_git_test_cases @sub_git_test_dir = @sub_test_dir + ".git" @sub_git_test_dir.mkpath @sub_git_test_case11 = @sub_git_test_dir + "test_case11.rb" @sub_git_test_case11.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SubGitTestCase11 < Test::Unit::TestCase def test11 end end end EOT end end setup def setup_extra_top_level_test_cases @test_cases12 = @extra_test_dir + "test_cases12.rb" @test_cases12.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class TestCase121 < Test::Unit::TestCase def test121_1 end def test121_2 end end class TestCase122 < Test::Unit::TestCase def test122_1 end def test122_2 end end end EOT end end setup def setup_sub_level_extra_test_cases @sub_extra_test_dir = @extra_test_dir + "sub" @sub_extra_test_dir.mkpath @cases13_test = @sub_extra_test_dir + "13cases_test.rb" @cases13_test.open("w") do |test_case| test_case.puts(<<-EOT) module #{@temporary_test_cases_module_name} class SubTestCase13 < Test::Unit::TestCase def test13_1 end def test13_2 end end end EOT end end def teardown @test_dir.rmtree if @test_dir.exist? ::Object.send(:remove_const, @temporary_test_cases_module_name) Test::Unit::TestCase::DESCENDANTS.replace(@previous_descendants) end def test_simple_collect assert_collect([:suite, {:name => @sub_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("SubTestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("SubTestCase4")}, [:test, {:name => "test4_1"}], [:test, {:name => "test4_2"}]], [:suite, {:name => _test_case_name("SubTestCase6")}, [:test, {:name => "test6"}]]], @sub_test_dir.to_s) end def test_simple_collect_test_suffix assert_collect([:suite, {:name => @extra_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("TestCase121")}, [:test, {:name => "test121_1"}], [:test, {:name => "test121_2"}]], [:suite, {:name => _test_case_name("TestCase122")}, [:test, {:name => "test122_1"}], [:test, {:name => "test122_2"}]], [:suite, {:name => @sub_extra_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("SubTestCase13")}, [:test, {:name => "test13_1"}], [:test, {:name => "test13_2"}]]]], @extra_test_dir.to_s) end def test_multilevel_collect assert_collect([:suite, {:name => "."}, [:suite, {:name => _test_case_name("TestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("TestCase2")}, [:test, {:name => "test2"}]], [:suite, {:name => @sub_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("SubTestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("SubTestCase4")}, [:test, {:name => "test4_1"}], [:test, {:name => "test4_2"}]], [:suite, {:name => _test_case_name("SubTestCase6")}, [:test, {:name => "test6"}]]], [:suite, {:name => @sub2_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("Sub2TestCase8")}, [:test, {:name => "test8_1"}], [:test, {:name => "test8_2"}]], [:suite, {:name => _test_case_name("Sub2TestCase9")}, [:test, {:name => "test9"}]]]]) end def test_collect_file assert_collect([:suite, {:name => _test_case_name("TestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], @test_case1.to_s) end def test_collect_file_no_pattern_match_file_name assert_collect([:suite, {:name => _test_case_name("NoLoadSubTestCase5")}, [:test, {:name => "test5_1"}], [:test, {:name => "test5_2"}]], @no_load_sub_test_case5.to_s) end def test_collect_file_test_cases assert_collect([:suite, {:name => "[#{@test_cases12}]"}, [:suite, {:name => _test_case_name("TestCase121")}, [:test, {:name => "test121_1"}], [:test, {:name => "test121_2"}]], [:suite, {:name => _test_case_name("TestCase122")}, [:test, {:name => "test122_1"}], [:test, {:name => "test122_2"}]]], @test_cases12.to_s) end def test_collect_files assert_collect([:suite, {:name => "[#{@test_case1}, #{@test_case2}]"}, [:suite, {:name => _test_case_name("TestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("TestCase2")}, [:test, {:name => "test2"}]]], @test_case1.to_s, @test_case2.to_s) end def test_nil_pattern assert_collect([:suite, {:name => @sub_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("NoLoadSubTestCase5")}, [:test, {:name => "test5_1"}], [:test, {:name => "test5_2"}]], [:suite, {:name => _test_case_name("SubTestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("SubTestCase4")}, [:test, {:name => "test4_1"}], [:test, {:name => "test4_2"}]], [:suite, {:name => _test_case_name("SubTestCase6")}, [:test, {:name => "test6"}]]], @sub_test_dir.to_s) do |collector| collector.patterns.clear end end def test_filtering assert_collect([:suite, {:name => "."}, [:suite, {:name => _test_case_name("TestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => @sub_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("SubTestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]]]]) do |collector| collector.filter = Proc.new do |test| !/\Atest1/.match(test.method_name).nil? end end end def test_collect_multi test_dirs = [@sub_test_dir.to_s, @sub2_test_dir.to_s] assert_collect([:suite, {:name => "[#{test_dirs.join(', ')}]"}, [:suite, {:name => @sub_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("SubTestCase1")}, [:test, {:name => "test1_1"}], [:test, {:name => "test1_2"}]], [:suite, {:name => _test_case_name("SubTestCase4")}, [:test, {:name => "test4_1"}], [:test, {:name => "test4_2"}]], [:suite, {:name => _test_case_name("SubTestCase6")}, [:test, {:name => "test6"}]]], [:suite, {:name => @sub2_test_dir.basename.to_s}, [:suite, {:name => _test_case_name("Sub2TestCase8")}, [:test, {:name => "test8_1"}], [:test, {:name => "test8_2"}]], [:suite, {:name => _test_case_name("Sub2TestCase9")}, [:test, {:name => "test9"}]]]], *test_dirs) end private def assert_collect(expected, *collect_args) keep_required_files do Dir.chdir(@test_dir.to_s) do collector = Test::Unit::Collector::Load.new yield(collector) if block_given? actual = inspect_test_object(collector.send(:collect, *collect_args)) assert_equal(expected, actual) end end end def ensure_clean_directory(directory) directory.rmtree if directory.exist? directory.mkpath end def keep_required_files required_files = $".dup yield ensure $".replace(required_files) end def _test_case_name(test_case_class_name) "#{@temporary_test_cases_module_name}::#{test_case_class_name}" end def inspect_test_object(test_object) return nil if test_object.nil? case test_object when Test::Unit::TestSuite sub_tests = test_object.tests.collect do |test| inspect_test_object(test) end.sort_by do |type, attributes, *children| attributes[:name] end [:suite, {:name => test_object.name}, *sub_tests] when Test::Unit::TestCase [:test, {:name => test_object.method_name}] else raise "unexpected test object: #{test_object.inspect}" end end end test-unit-3.3.9/test/collector/test_objectspace.rb0000644000004100000410000000573713775322563022356 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' require 'test/unit/collector/objectspace' module Test module Unit module Collector class TC_ObjectSpace < TestCase def setup @tc1 = Class.new(TestCase) do self.test_order = :alphabetic def self.name "tc_1" end def test_1 end def test_2 end end @tc2 = Class.new(TestCase) do self.test_order = :alphabetic def self.name "tc_2" end def test_0 end end @no_tc = Class.new do def test_4 end end @object_space = {Class => [@tc1, @tc2, @no_tc], String => ['']} def @object_space.each_object(type) self[type].each{|item| yield(item) } end @c = ObjectSpace.new(@object_space) end def full_suite(name=ObjectSpace::NAME) expected = TestSuite.new(name) expected << (TestSuite.new(@tc1.name) << @tc1.new('test_1') << @tc1.new('test_2')) expected << (TestSuite.new(@tc2.name) << @tc2.new('test_0')) end def empty_suite TestSuite.new(ObjectSpace::NAME) end def test_basic_collection assert_equal(full_suite("name"), @c.collect("name")) @c.filter = [] assert_equal(full_suite("name"), @c.collect("name")) end def test_filtered_collection @c.filter = proc{false} assert_equal(empty_suite, @c.collect) @c.filter = proc{true} assert_equal(full_suite, @c.collect) @c.filter = proc{nil} assert_equal(full_suite, @c.collect) @c.filter = [proc{false}, proc{true}] assert_equal(empty_suite, @c.collect) @c.filter = [proc{true}, proc{false}] assert_equal(empty_suite, @c.collect) @c.filter = [proc{nil}, proc{false}] assert_equal(empty_suite, @c.collect) @c.filter = [proc{nil}, proc{true}] assert_equal(full_suite, @c.collect) expected = TestSuite.new(ObjectSpace::NAME) expected << (TestSuite.new(@tc1.name) << @tc1.new('test_1')) expected << (TestSuite.new(@tc2.name) << @tc2.new('test_0')) @c.filter = proc{|test| ['test_1', 'test_0'].include?(test.method_name)} assert_equal(expected, @c.collect) expected = TestSuite.new(ObjectSpace::NAME) TestSuite.new(@tc1.name) << @tc1.new('test_1') TestSuite.new(@tc2.name) << @tc2.new('test_0') @c.filter = [proc{|t| t.method_name == 'test_1' ? true : nil}, proc{|t| t.method_name == 'test_0' ? true : nil}, proc{false}] assert_equal(empty_suite, @c.collect) end end end end end test-unit-3.3.9/test/collector/test-descendant.rb0000644000004100000410000001064113775322563022110 0ustar www-datawww-datarequire 'test/unit' require 'test/unit/collector/descendant' class TestUnitCollectorDescendant < Test::Unit::TestCase def setup @previous_descendants = Test::Unit::TestCase::DESCENDANTS.dup Test::Unit::TestCase::DESCENDANTS.clear end def teardown Test::Unit::TestCase::DESCENDANTS.replace(@previous_descendants) end private def assert_collect(expected, *collect_args) collector = Test::Unit::Collector::Descendant.new yield(collector) if block_given? assert_equal(expected, collector.send(:collect, *collect_args)) end def default_name Test::Unit::Collector::Descendant::NAME end def empty_suite(name=nil) Test::Unit::TestSuite.new(name || default_name) end class TestCollect < self def setup super @test_case1 = Class.new(Test::Unit::TestCase) do self.test_order = :alphabetic def self.name "test-case1" end def test_1 end def test_2 end end @test_case2 = Class.new(Test::Unit::TestCase) do self.test_order = :alphabetic def self.name "test-case2" end def test_0 end end @no_test_case = Class.new do def self.name "no-test-case" end def test_4 end end end def test_basic assert_collect(full_suite("name"), "name") assert_collect(full_suite("name"), "name") do |collector| collector.filter = [] end end def test_filtered assert_collect(empty_suite) do |collector| collector.filter = Proc.new {false} end assert_collect(full_suite) do |collector| collector.filter = Proc.new {true} end assert_collect(full_suite) do |collector| collector.filter = Proc.new {nil} end assert_collect(empty_suite) do |collector| collector.filter = [Proc.new {false}, Proc.new {true}] end assert_collect(empty_suite) do |collector| collector.filter = [Proc.new {true}, Proc.new {false}] end assert_collect(empty_suite) do |collector| collector.filter = [Proc.new {nil}, Proc.new {false}] end assert_collect(full_suite) do |collector| collector.filter = [Proc.new {nil}, Proc.new {true}] end expected = empty_suite suite1 = Test::Unit::TestSuite.new(@test_case1.name) suite1 << @test_case1.new("test_1") suite2 = Test::Unit::TestSuite.new(@test_case2.name) suite2 << @test_case2.new("test_0") expected << suite1 << suite2 assert_collect(expected) do |collector| collector.filter = Proc.new do |test| ['test_1', 'test_0'].include?(test.method_name) end end suite1 = Test::Unit::TestSuite.new(@test_case1.name) suite1 << @test_case1.new("test_1") suite2 = Test::Unit::TestSuite.new(@test_case2.name) suite2 << @test_case2.new("test_0") assert_collect(empty_suite) do |collector| filters = [Proc.new {|test| test.method_name == 'test_1' ? true : nil}, Proc.new {|test| test.method_name == 'test_0' ? true : nil}, Proc.new {false}] collector.filter = filters end end private def full_suite(name=nil) sub_suite1 = Test::Unit::TestSuite.new(@test_case1.name) sub_suite1 << @test_case1.new('test_1') sub_suite1 << @test_case1.new('test_2') sub_suite2 = Test::Unit::TestSuite.new(@test_case2.name) sub_suite2 << @test_case2.new('test_0') suite = empty_suite(name) suite << sub_suite1 suite << sub_suite2 suite end end class TestModule < self def test_included_in_child tests = Module.new do def test_in_module end end parent_test_case = Class.new(Test::Unit::TestCase) do class << self def name "Parent" end end end child_test_case = Class.new(parent_test_case) do include tests class << self def name "Child" end end end child_suite = Test::Unit::TestSuite.new(child_test_case.name) child_suite << child_test_case.new("test_in_module") parent_suite = Test::Unit::TestSuite.new(parent_test_case.name) parent_suite << child_suite suite = empty_suite("all") suite << parent_suite assert_collect(suite, "all") end end end test-unit-3.3.9/test/test-error.rb0000644000004100000410000000120413775322563017136 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' module Test module Unit class TC_Error < TestCase TF_Exception = Struct.new('TF_Exception', :message, :backtrace) def test_display ex = TF_Exception.new("message1\nmessage2", ['line1', 'line2']) e = Error.new("name", ex) assert_equal("name: #{TF_Exception.name}: message1", e.short_display) assert_equal(< % sudo gem install test-unit If you want to use full test-unit features:
% sudo gem install test-unit-full
## License This software is distributed under either the terms of new Ruby License or BSDL. See the file [COPYING](COPYING). Exception: * lib/test/unit/diff.rb is a triple license of (the new Ruby license or BSDL) and PSF license. ## Authors ### Active * Kouhei Sutou: The current maintainer * Haruka Yoshihara: Data driven test supports. ### Inactive * Nathaniel Talbott: The original author * Ryan Davis: The second maintainer ### Images * Mayu & Co.: kinotan icons ## Thanks * Daniel Berger: Suggestions and bug reports. * Designing Patterns: Suggestions. * Erik Hollensbe: Suggestions and bug reports. * Bill Lear: A suggestion. * Diego Pettenò: A bug report. * Angelo Lakra: A bug report. * Mike Pomraning: A bug report. * David MARCHALAND: Suggestions and bug reports. * Andrew Grimm: A bug report. * Champak Ch: A bug report. * Florian Frank: A bug report. * grafi-tt: Bug fixes and reports. * Jeremy Stephens: A bug report. * Hans de Graaff: Bug reports. * James Mead: A bug report. * Marc Seeger (Acquia): A bug report. * boutil: A bug report. * Vladislav Rassokhin: A bug report. test-unit-3.3.9/PSFL0000644000004100000410000003244613775322563014227 0ustar www-datawww-dataThis is the official license for the Python 2.5 release: A. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. Release Derived Year Owner GPL- from compatible? (1) 0.9.0 thru 1.2 1991-1995 CWI yes 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 1.6 1.5.2 2000 CNRI no 2.0 1.6 2000 BeOpen.com no 1.6.1 1.6 2001 CNRI yes (2) 2.1 2.0+1.6.1 2001 PSF no 2.0.1 2.0+1.6.1 2001 PSF yes 2.1.1 2.1+2.0.1 2001 PSF yes 2.2 2.1.1 2001 PSF yes 2.1.2 2.1.1 2002 PSF yes 2.1.3 2.1.2 2002 PSF yes 2.2.1 2.2 2002 PSF yes 2.2.2 2.2.1 2002 PSF yes 2.2.3 2.2.2 2003 PSF yes 2.3 2.2.2 2002-2003 PSF yes 2.3.1 2.3 2002-2003 PSF yes 2.3.2 2.3.1 2002-2003 PSF yes 2.3.3 2.3.2 2002-2003 PSF yes 2.3.4 2.3.3 2004 PSF yes 2.3.5 2.3.4 2005 PSF yes 2.4 2.3 2004 PSF yes 2.4.1 2.4 2005 PSF yes 2.4.2 2.4.1 2005 PSF yes 2.4.3 2.4.2 2006 PSF yes 2.5 2.4 2006 PSF yes Footnotes: (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't. (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license has a choice of law clause. According to CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 ------------------------------------------- BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 --------------------------------------- 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 -------------------------------------------------- Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. test-unit-3.3.9/Rakefile0000644000004100000410000000251013775322563015172 0ustar www-datawww-data# -*- ruby -*- # # Copyright (C) 2008-2017 Kouhei Sutou Encoding.default_internal = "UTF-8" if defined?(Encoding.default_internal) # TODO: Remove me when we drop Ruby 1.9 support. unless "".respond_to?(:b) class String def b dup.force_encoding("ASCII-8BIT") end end end require "erb" require "yaml" require "rubygems" require "rake/clean" require "yard" require "bundler/gem_helper" require "packnga" task :default => :test base_dir = File.dirname(__FILE__) html_base_dir = File.join(base_dir, "doc", "html") helper = Bundler::GemHelper.new(base_dir) def helper.version_tag version end helper.install spec = helper.gemspec document_task = Packnga::DocumentTask.new(spec) do |task| task.original_language = "en" task.translate_languages = ["ja"] end Packnga::ReleaseTask.new(spec) do |task| test_unit_github_io_dir_candidates = [ "../../www/test-unit.github.io", ] test_unit_github_io_dir = test_unit_github_io_dir_candidates.find do |dir| File.directory?(dir) end task.index_html_dir = test_unit_github_io_dir end def rake(*arguments) ruby($0, *arguments) end namespace :html do desc "Publish HTML to Web site." task :publish do # FIXME Do nothing for now #rsync_to_rubyforge(spec, "#{html_base_dir}/", "") end end task :test do ruby("test/run-test.rb") end test-unit-3.3.9/lib/0000755000004100000410000000000013775322563014275 5ustar www-datawww-datatest-unit-3.3.9/lib/test/0000755000004100000410000000000013775322563015254 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/0000755000004100000410000000000013775322563016233 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/testresult.rb0000644000004100000410000000631213775322563021000 0ustar www-datawww-data#-- # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/util/observable' require 'test/unit/failure' require 'test/unit/error' require 'test/unit/omission' require 'test/unit/pending' require 'test/unit/notification' module Test module Unit module NullResultContainerInitializer private def initialize_containers end end # Collects Test::Unit::Failure and Test::Unit::Error so that # they can be displayed to the user. To this end, observers # can be added to it, allowing the dynamic updating of, say, a # UI. class TestResult include Util::Observable include NullResultContainerInitializer include TestResultFailureSupport include TestResultErrorSupport include TestResultPendingSupport include TestResultOmissionSupport include TestResultNotificationSupport FINISHED = name + "::FINISHED" CHANGED = name + "::CHANGED" PASS_ASSERTION = name + "::PASS_ASSERTION" FAULT = name + "::FAULT" attr_reader :run_count, :pass_count, :assertion_count, :faults attr_accessor :stop_tag # Constructs a new, empty TestResult. def initialize @run_count, @pass_count, @assertion_count = 0, 0, 0 @summary_generators = [] @problem_checkers = [] @faults = [] @stop_tag = nil initialize_containers end # Records a test run. def add_run @run_count += 1 notify_listeners(FINISHED, self) notify_changed end def add_pass @pass_count += 1 end # Records an individual assertion. def add_assertion @assertion_count += 1 notify_listeners(PASS_ASSERTION, self) notify_changed end # Returns a string contain the recorded runs, assertions, # failures and errors in this TestResult. def summary ["#{run_count} tests", "#{assertion_count} assertions", *@summary_generators.collect {|generator| __send__(generator)}].join(", ") end # Returnes a string that shows result status. def status if passed? if pending_count > 0 "pending" elsif omission_count > 0 "omission" elsif notification_count > 0 "notification" else "pass" end elsif error_count > 0 "error" elsif failure_count > 0 "failure" end end def stop throw @stop_tag end def to_s summary end # Returns whether or not this TestResult represents # successful completion. def passed? @problem_checkers.all? {|checker| not __send__(checker)} end def pass_percentage n_tests = @run_count - omission_count if n_tests.zero? 0 else 100.0 * (@pass_count / n_tests.to_f) end end private def notify_changed notify_listeners(CHANGED, self) end def notify_fault(fault) @faults << fault notify_listeners(FAULT, fault) end end end end test-unit-3.3.9/lib/test/unit/testsuite.rb0000644000004100000410000001146413775322563020617 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # Copyright:: Copyright (c) 2008-2011 Kouhei Sutou. All rights reserved. # License:: Ruby license. require 'test/unit/error' module Test module Unit # A collection of tests which can be #run. # # Note: It is easy to confuse a TestSuite instance with # something that has a static suite method; I know because _I_ # have trouble keeping them straight. Think of something that # has a suite method as simply providing a way to get a # meaningful TestSuite instance. class TestSuite attr_reader :name, :tests, :test_case, :start_time, :elapsed_time # Test suite that has higher priority is ran prior to # test suites that have lower priority. attr_accessor :priority STARTED = name + "::STARTED" STARTED_OBJECT = name + "::STARTED::OBJECT" FINISHED = name + "::FINISHED" FINISHED_OBJECT = name + "::FINISHED::OBJECT" # Creates a new TestSuite with the given name. def initialize(name="Unnamed TestSuite", test_case=nil) @name = name @tests = [] @test_case = test_case @n_tests = 0 @priority = 0 @start_time = nil @elapsed_time = nil @passed = true end # Runs the tests and/or suites contained in this # TestSuite. def run(result, &progress_block) @start_time = Time.now yield(STARTED, name) yield(STARTED_OBJECT, self) run_startup(result) while test = @tests.shift @n_tests += test.size run_test(test, result, &progress_block) @passed = false unless test.passed? end ensure begin run_shutdown(result) ensure @elapsed_time = Time.now - @start_time yield(FINISHED, name) yield(FINISHED_OBJECT, self) end end # Adds the test to the suite. def <<(test) @tests << test self end def delete(test) @tests.delete(test) end def delete_tests(tests) @tests -= tests end # Retuns the rolled up number of tests in this suite; # i.e. if the suite contains other suites, it counts the # tests within those suites, not the suites themselves. def size total_size = @n_tests @tests.each { |test| total_size += test.size } total_size end def empty? size.zero? end # Overridden to return the name given the suite at # creation. def to_s @name end # It's handy to be able to compare TestSuite instances. def ==(other) return false unless(other.kind_of?(self.class)) return false unless(@name == other.name) @tests == other.tests end def passed? @passed end private def run_startup(result) return if @test_case.nil? or !@test_case.respond_to?(:startup) begin @test_case.startup rescue Exception raise unless handle_exception($!, result) end end def run_test(test, result) finished_is_yielded = false finished_object_is_yielded = false previous_event_name = nil test.run(result) do |event_name, *args| case previous_event_name when Test::Unit::TestCase::STARTED if event_name != Test::Unit::TestCase::STARTED_OBJECT yield(Test::Unit::TestCase::STARTED_OBJECT, test) end when Test::Unit::TestCase::FINISHED if event_name != Test::Unit::TestCase::FINISHED_OBJECT yield(Test::Unit::TestCase::FINISHED_OBJECT, test) end finished_object_is_yielded = true end case event_name when Test::Unit::TestCase::STARTED finished_is_yielded = false finished_object_is_yielded = false when Test::Unit::TestCase::FINISHED finished_is_yielded = true end previous_event_name = event_name yield(event_name, *args) end if finished_is_yielded and not finished_object_is_yielded yield(Test::Unit::TestCase::FINISHED_OBJECT, test) end end def run_shutdown(result) return if @test_case.nil? or !@test_case.respond_to?(:shutdown) begin @test_case.shutdown rescue Exception raise unless handle_exception($!, result) end end def handle_exception(exception, result) case exception when *ErrorHandler::PASS_THROUGH_EXCEPTIONS false else result.add_error(Error.new(@test_case.name, exception)) @passed = false true end end end end end test-unit-3.3.9/lib/test/unit/version.rb0000644000004100000410000000007213775322563020244 0ustar www-datawww-datamodule Test module Unit VERSION = "3.3.9" end end test-unit-3.3.9/lib/test/unit/pending.rb0000644000004100000410000000722313775322563020210 0ustar www-datawww-datarequire 'test/unit/util/backtracefilter' module Test module Unit class Pending include Util::BacktraceFilter attr_reader :test_name, :location, :message attr_reader :method_name SINGLE_CHARACTER = 'P' LABEL = "Pending" # Creates a new Pending with the given location and # message. def initialize(test_name, location, message, options={}) @test_name = test_name @location = location @message = message @method_name = options[:method_name] end # Returns a single character representation of a pending. def single_character_display SINGLE_CHARACTER end def label LABEL end # Returns a brief version of the error description. def short_display "#{@test_name}: #{@message.split("\n")[0]}" end # Returns a verbose version of the error description. def long_display backtrace = filter_backtrace(location).join("\n") "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" end # Overridden to return long_display. def to_s long_display end def critical? true end end class PendedError < StandardError end module TestCasePendingSupport class << self def included(base) base.class_eval do include PendingHandler end end end # Marks the test or part of the test is pending. # # Example: # # def test_pending # pend # # Not reached here # end # # def test_pending_with_here # pend do # # Ran here # # Fails if the block doesn't raise any error. # # Because it means the block is passed unexpectedly. # end # # Reached here # end def pend(message=nil, &block) message ||= "pended." if block_given? pending = nil begin yield rescue Exception pending = Pending.new(name, filter_backtrace(caller), message, :method_name => @method_name) add_pending(pending) end unless pending flunk("Pending block should not be passed: #{message}") end else raise PendedError.new(message) end end private def add_pending(pending) problem_occurred current_result.add_pending(pending) end end module PendingHandler class << self def included(base) base.exception_handler(:handle_pended_error) end end private def handle_pended_error(exception) return false unless exception.is_a?(PendedError) pending = Pending.new(name, filter_backtrace(exception.backtrace), exception.message, :method_name => @method_name) add_pending(pending) true end end module TestResultPendingSupport attr_reader :pendings # Records a Test::Unit::Pending. def add_pending(pending) @pendings << pending notify_fault(pending) notify_changed end # Returns the number of pendings this TestResult has # recorded. def pending_count @pendings.size end private def initialize_containers super @pendings = [] @summary_generators << :pending_summary end def pending_summary "#{pending_count} pendings" end end end end test-unit-3.3.9/lib/test/unit/fault-location-detector.rb0000644000004100000410000000534213775322563023314 0ustar www-datawww-data# Copyright (C) 2012 Kouhei Sutou # # License: Ruby's require "English" module Test module Unit class FaultLocationDetector def initialize(fault, code_snippet_fetcher) @fault = fault @code_snippet_fetcher = code_snippet_fetcher extract_fault_information end def split_backtrace_entry(entry) match_data = /\A(.+):(\d+)(?::(.*))?\z/.match(entry) return nil if match_data.nil? file, line_number, context = match_data.to_a[1..-1] line_number = line_number.to_i if /\Ain `(.+?)'/ =~ context method_name = $1 if /\Ablock (?:\(.+?\) )?in / =~ method_name method_name = $POSTMATCH end else method_name = nil end [file, line_number, context, method_name] end def target?(backtrace_entry) file, line_number, context, method_name = split_backtrace_entry(backtrace_entry) _ = context return false if file.nil? if @fault_source_location target_source_location?(file, line_number, method_name) elsif @fault_method_name target_method?(method_name) else true end end private def target_source_location?(file, line_number, method_name) fault_file, fault_line_number = @fault_source_location return false unless file.end_with?(fault_file) return false if line_number < fault_line_number lines = @code_snippet_fetcher.source(file) return false if lines.nil? base_indent_level = nil fault_line_number.step(lines.size) do |current_line_number| line = lines[current_line_number - 1] current_indent_level = guess_indent_level(line) base_indent_level ||= current_indent_level return true if current_line_number == line_number if current_line_number == fault_line_number break if /(?:\send|\})\s*$/ =~ line else break if current_indent_level == base_indent_level end end false end def target_method?(method_name) @fault_method_name == method_name end def guess_indent_level(line) if /\A(\s*)/ =~ line $1.sub(/\t/, " " * 8).count(" ") else 0 end end def extract_fault_information if @fault.respond_to?(:source_location) @fault_source_location = @fault.source_location else @fault_source_location = nil end if @fault.respond_to?(:method_name) @fault_method_name = @fault.method_name else @fault_method_name = nil end end end end end test-unit-3.3.9/lib/test/unit/diff.rb0000644000004100000410000006256213775322563017503 0ustar www-datawww-data# port of Python's difflib. # # Copyright (c) 2001-2008 Python Software Foundation; All Rights Reserved # Copyright (c) 2008-2011 Kouhei Sutou; All Rights Reserved # # It is free software, and is distributed under (the new Ruby license # or BSDL) and the PSF license. module Test module Unit module Diff class SequenceMatcher def initialize(from, to, &junk_predicate) @from = from @to = to @junk_predicate = junk_predicate update_to_indexes end def longest_match(from_start, from_end, to_start, to_end) best_info = find_best_match_position(from_start, from_end, to_start, to_end) unless @junks.empty? args = [from_start, from_end, to_start, to_end] best_info = adjust_best_info_with_junk_predicate(false, best_info, *args) best_info = adjust_best_info_with_junk_predicate(true, best_info, *args) end best_info end def blocks @blocks ||= compute_blocks end def operations @operations ||= compute_operations end def grouped_operations(context_size=nil) context_size ||= 3 _operations = operations.dup _operations = [[:equal, 0, 0, 0, 0]] if _operations.empty? expand_edge_equal_operations!(_operations, context_size) group_window = context_size * 2 groups = [] group = [] _operations.each do |tag, from_start, from_end, to_start, to_end| if tag == :equal and from_end - from_start > group_window group << [tag, from_start, [from_end, from_start + context_size].min, to_start, [to_end, to_start + context_size].min] groups << group group = [] from_start = [from_start, from_end - context_size].max to_start = [to_start, to_end - context_size].max end group << [tag, from_start, from_end, to_start, to_end] end groups << group unless group.empty? groups end def ratio @ratio ||= compute_ratio end private def update_to_indexes @to_indexes = {} @junks = {} if @to.is_a?(String) each = " "[0].is_a?(Integer) ? :each_byte : :each_char else each = :each end i = 0 @to.__send__(each) do |item| @to_indexes[item] ||= [] @to_indexes[item] << i i += 1 end return if @junk_predicate.nil? @to_indexes = @to_indexes.reject do |key, value| junk = @junk_predicate.call(key) @junks[key] = true if junk junk end end def find_best_match_position(from_start, from_end, to_start, to_end) best_from, best_to, best_size = from_start, to_start, 0 sizes = {} from_start.upto(from_end) do |from_index| _sizes = {} (@to_indexes[@from[from_index]] || []).each do |to_index| next if to_index < to_start break if to_index > to_end size = _sizes[to_index] = (sizes[to_index - 1] || 0) + 1 if size > best_size best_from = from_index - size + 1 best_to = to_index - size + 1 best_size = size end end sizes = _sizes end [best_from, best_to, best_size] end def adjust_best_info_with_junk_predicate(should_junk, best_info, from_start, from_end, to_start, to_end) best_from, best_to, best_size = best_info while best_from > from_start and best_to > to_start and (should_junk ? @junks.has_key?(@to[best_to - 1]) : !@junks.has_key?(@to[best_to - 1])) and @from[best_from - 1] == @to[best_to - 1] best_from -= 1 best_to -= 1 best_size += 1 end while best_from + best_size < from_end and best_to + best_size < to_end and (should_junk ? @junks.has_key?(@to[best_to + best_size]) : !@junks.has_key?(@to[best_to + best_size])) and @from[best_from + best_size] == @to[best_to + best_size] best_size += 1 end [best_from, best_to, best_size] end def matches @matches ||= compute_matches end def compute_matches matches = [] queue = [[0, @from.size, 0, @to.size]] until queue.empty? from_start, from_end, to_start, to_end = queue.pop match = longest_match(from_start, from_end - 1, to_start, to_end - 1) match_from_index, match_to_index, size = match unless size.zero? if from_start < match_from_index and to_start < match_to_index queue.push([from_start, match_from_index, to_start, match_to_index]) end matches << match if match_from_index + size < from_end and match_to_index + size < to_end queue.push([match_from_index + size, from_end, match_to_index + size, to_end]) end end end matches.sort_by do |(from_index, _, _)| from_index end end def compute_blocks blocks = [] current_from_index = current_to_index = current_size = 0 matches.each do |from_index, to_index, size| if current_from_index + current_size == from_index and current_to_index + current_size == to_index current_size += size else unless current_size.zero? blocks << [current_from_index, current_to_index, current_size] end current_from_index = from_index current_to_index = to_index current_size = size end end unless current_size.zero? blocks << [current_from_index, current_to_index, current_size] end blocks << [@from.size, @to.size, 0] blocks end def compute_operations from_index = to_index = 0 operations = [] blocks.each do |match_from_index, match_to_index, size| tag = determine_tag(from_index, to_index, match_from_index, match_to_index) if tag != :equal operations << [tag, from_index, match_from_index, to_index, match_to_index] end from_index, to_index = match_from_index + size, match_to_index + size if size > 0 operations << [:equal, match_from_index, from_index, match_to_index, to_index] end end operations end def compute_ratio matches = blocks.inject(0) {|result, block| result + block[-1]} length = @from.length + @to.length if length.zero? 1.0 else 2.0 * matches / length end end def determine_tag(from_index, to_index, match_from_index, match_to_index) if from_index < match_from_index and to_index < match_to_index :replace elsif from_index < match_from_index :delete elsif to_index < match_to_index :insert else :equal end end def expand_edge_equal_operations!(_operations, context_size) tag, from_start, from_end, to_start, to_end = _operations[0] if tag == :equal _operations[0] = [tag, [from_start, from_end - context_size].max, from_end, [to_start, to_end - context_size].max, to_end] end tag, from_start, from_end, to_start, to_end = _operations[-1] if tag == :equal _operations[-1] = [tag, from_start, [from_end, from_start + context_size].min, to_start, [to_end, to_start + context_size].min] end end end class Differ def initialize(from, to) @from = from @to = to end private def tag(mark, contents) contents.collect {|content| mark + content} end end class UTF8Line class << self # from http://unicode.org/reports/tr11/ WIDE_CHARACTERS = [0x1100..0x1159, 0x115F..0x115F, 0x2329..0x232A, 0x2E80..0x2E99, 0x2E9B..0x2EF3, 0x2F00..0x2FD5, 0x2FF0..0x2FFB, 0x3000..0x303E, 0x3041..0x3096, 0x3099..0x30FF, 0x3105..0x312D, 0x3131..0x318E, 0x3190..0x31B7, 0x31C0..0x31E3, 0x31F0..0x321E, 0x3220..0x3243, 0x3250..0x32FE, 0x3300..0x4DB5, 0x4E00..0x9FC3, 0xA000..0xA48C, 0xA490..0xA4C6, 0xAC00..0xD7A3, 0xF900..0xFA2D, 0xFA30..0xFA6A, 0xFA70..0xFAD9, 0xFE10..0xFE19, 0xFE30..0xFE52, 0xFE54..0xFE66, 0xFE68..0xFE6B, 0xFF01..0xFF60, 0xFFE0..0xFFE6, 0x20000..0x2FFFD, 0x30000..0x3FFFD, ] AMBIGUOUS = [0x00A1..0x00A1, 0x00A4..0x00A4, 0x00A7..0x00A8, 0x00AA..0x00AA, 0x00AD..0x00AE, 0x00B0..0x00B4, 0x00B6..0x00BA, 0x00BC..0x00BF, 0x00C6..0x00C6, 0x00D0..0x00D0, 0x00D7..0x00D8, 0x00DE..0x00E1, 0x00E6..0x00E6, 0x00E8..0x00EA, 0x00EC..0x00ED, 0x00F0..0x00F0, 0x00F2..0x00F3, 0x00F7..0x00FA, 0x00FC..0x00FC, 0x00FE..0x00FE, 0x0101..0x0101, 0x0111..0x0111, 0x0113..0x0113, 0x011B..0x011B, 0x0126..0x0127, 0x012B..0x012B, 0x0131..0x0133, 0x0138..0x0138, 0x013F..0x0142, 0x0144..0x0144, 0x0148..0x014B, 0x014D..0x014D, 0x0152..0x0153, 0x0166..0x0167, 0x016B..0x016B, 0x01CE..0x01CE, 0x01D0..0x01D0, 0x01D2..0x01D2, 0x01D4..0x01D4, 0x01D6..0x01D6, 0x01D8..0x01D8, 0x01DA..0x01DA, 0x01DC..0x01DC, 0x0251..0x0251, 0x0261..0x0261, 0x02C4..0x02C4, 0x02C7..0x02C7, 0x02C9..0x02CB, 0x02CD..0x02CD, 0x02D0..0x02D0, 0x02D8..0x02DB, 0x02DD..0x02DD, 0x02DF..0x02DF, 0x0300..0x036F, 0x0391..0x03A1, 0x03A3..0x03A9, 0x03B1..0x03C1, 0x03C3..0x03C9, 0x0401..0x0401, 0x0410..0x044F, 0x0451..0x0451, 0x2010..0x2010, 0x2013..0x2016, 0x2018..0x2019, 0x201C..0x201D, 0x2020..0x2022, 0x2024..0x2027, 0x2030..0x2030, 0x2032..0x2033, 0x2035..0x2035, 0x203B..0x203B, 0x203E..0x203E, 0x2074..0x2074, 0x207F..0x207F, 0x2081..0x2084, 0x20AC..0x20AC, 0x2103..0x2103, 0x2105..0x2105, 0x2109..0x2109, 0x2113..0x2113, 0x2116..0x2116, 0x2121..0x2122, 0x2126..0x2126, 0x212B..0x212B, 0x2153..0x2154, 0x215B..0x215E, 0x2160..0x216B, 0x2170..0x2179, 0x2190..0x2199, 0x21B8..0x21B9, 0x21D2..0x21D2, 0x21D4..0x21D4, 0x21E7..0x21E7, 0x2200..0x2200, 0x2202..0x2203, 0x2207..0x2208, 0x220B..0x220B, 0x220F..0x220F, 0x2211..0x2211, 0x2215..0x2215, 0x221A..0x221A, 0x221D..0x2220, 0x2223..0x2223, 0x2225..0x2225, 0x2227..0x222C, 0x222E..0x222E, 0x2234..0x2237, 0x223C..0x223D, 0x2248..0x2248, 0x224C..0x224C, 0x2252..0x2252, 0x2260..0x2261, 0x2264..0x2267, 0x226A..0x226B, 0x226E..0x226F, 0x2282..0x2283, 0x2286..0x2287, 0x2295..0x2295, 0x2299..0x2299, 0x22A5..0x22A5, 0x22BF..0x22BF, 0x2312..0x2312, 0x2460..0x24E9, 0x24EB..0x254B, 0x2550..0x2573, 0x2580..0x258F, 0x2592..0x2595, 0x25A0..0x25A1, 0x25A3..0x25A9, 0x25B2..0x25B3, 0x25B6..0x25B7, 0x25BC..0x25BD, 0x25C0..0x25C1, 0x25C6..0x25C8, 0x25CB..0x25CB, 0x25CE..0x25D1, 0x25E2..0x25E5, 0x25EF..0x25EF, 0x2605..0x2606, 0x2609..0x2609, 0x260E..0x260F, 0x2614..0x2615, 0x261C..0x261C, 0x261E..0x261E, 0x2640..0x2640, 0x2642..0x2642, 0x2660..0x2661, 0x2663..0x2665, 0x2667..0x266A, 0x266C..0x266D, 0x266F..0x266F, 0x273D..0x273D, 0x2776..0x277F, 0xE000..0xF8FF, 0xFE00..0xFE0F, 0xFFFD..0xFFFD, 0xE0100..0xE01EF, 0xF0000..0xFFFFD, 0x100000..0x10FFFD, ] def wide_character?(character) binary_search_ranges(character, WIDE_CHARACTERS) or binary_search_ranges(character, AMBIGUOUS) end private def binary_search_ranges(character, ranges) if ranges.size.zero? false elsif ranges.size == 1 ranges[0].include?(character) else half = ranges.size / 2 range = ranges[half] if range.include?(character) true elsif character < range.begin binary_search_ranges(character, ranges[0...half]) else binary_search_ranges(character, ranges[(half + 1)..-1]) end end end end def initialize(line) @line = line @characters = @line.unpack("U*") end def [](*args) result = @characters[*args] if result.respond_to?(:pack) result.pack("U*") else result end end def each(&block) @characters.each(&block) end def size @characters.size end def to_s @line end def compute_width(start, _end) width = 0 start.upto(_end - 1) do |i| if self.class.wide_character?(@characters[i]) width += 2 else width += 1 end end width end end class ReadableDiffer < Differ def diff(options={}) @result = [] operations.each do |tag, from_start, from_end, to_start, to_end| case tag when :replace diff_lines(from_start, from_end, to_start, to_end) when :delete tag_deleted(@from[from_start...from_end]) when :insert tag_inserted(@to[to_start...to_end]) when :equal tag_equal(@from[from_start...from_end]) else raise "unknown tag: #{tag}" end end @result end private def operations @operations ||= nil if @operations.nil? matcher = SequenceMatcher.new(@from, @to) @operations = matcher.operations end @operations end def default_ratio 0.74 end def cut_off_ratio 0.75 end def tag(mark, contents) contents.each do |content| @result << (mark + content) end end def tag_deleted(contents) tag("- ", contents) end def tag_inserted(contents) tag("+ ", contents) end def tag_equal(contents) tag(" ", contents) end def tag_difference(contents) tag("? ", contents) end def find_diff_line_info(from_start, from_end, to_start, to_end) best_ratio = default_ratio from_equal_index = to_equal_index = nil from_best_index = to_best_index = nil to_start.upto(to_end - 1) do |to_index| from_start.upto(from_end - 1) do |from_index| if @from[from_index] == @to[to_index] from_equal_index ||= from_index to_equal_index ||= to_index next end matcher = SequenceMatcher.new(@from[from_index], @to[to_index], &method(:space_character?)) if matcher.ratio > best_ratio best_ratio = matcher.ratio from_best_index = from_index to_best_index = to_index end end end [best_ratio, from_equal_index, to_equal_index, from_best_index, to_best_index] end def diff_lines(from_start, from_end, to_start, to_end) info = find_diff_line_info(from_start, from_end, to_start, to_end) best_ratio, from_equal_index, to_equal_index, *info = info from_best_index, to_best_index = info from_best_index ||= from_start to_best_index ||= to_start if best_ratio < cut_off_ratio if from_equal_index.nil? if to_end - to_start < from_end - from_start tag_inserted(@to[to_start...to_end]) tag_deleted(@from[from_start...from_end]) else tag_deleted(@from[from_start...from_end]) tag_inserted(@to[to_start...to_end]) end return end from_best_index = from_equal_index to_best_index = to_equal_index best_ratio = 1.0 end _diff_lines(from_start, from_best_index, to_start, to_best_index) diff_line(@from[from_best_index], @to[to_best_index]) _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end) end def _diff_lines(from_start, from_end, to_start, to_end) if from_start < from_end if to_start < to_end diff_lines(from_start, from_end, to_start, to_end) else tag_deleted(@from[from_start...from_end]) end else tag_inserted(@to[to_start...to_end]) end end def line_operations(from_line, to_line) if !from_line.respond_to?(:force_encoding) and $KCODE == "UTF8" from_line = UTF8Line.new(from_line) to_line = UTF8Line.new(to_line) end matcher = SequenceMatcher.new(from_line, to_line, &method(:space_character?)) [from_line, to_line, matcher.operations] end def compute_width(line, start, _end) if line.respond_to?(:encoding) and Encoding.compatible?(Encoding::UTF_8, line.encoding) utf8_line = line[start..._end].encode(Encoding::UTF_8) width = 0 utf8_line.each_codepoint do |unicode_codepoint| if UTF8Line.wide_character?(unicode_codepoint) width += 2 else width += 1 end end width elsif line.is_a?(UTF8Line) line.compute_width(start, _end) else _end - start end end def diff_line(from_line, to_line) from_tags = "" to_tags = "" from_line, to_line, _operations = line_operations(from_line, to_line) _operations.each do |tag, from_start, from_end, to_start, to_end| from_width = compute_width(from_line, from_start, from_end) to_width = compute_width(to_line, to_start, to_end) case tag when :replace from_tags += "^" * from_width to_tags += "^" * to_width when :delete from_tags += "-" * from_width when :insert to_tags += "+" * to_width when :equal from_tags += " " * from_width to_tags += " " * to_width else raise "unknown tag: #{tag}" end end format_diff_point(from_line, to_line, from_tags, to_tags) end def format_diff_point(from_line, to_line, from_tags, to_tags) common = [n_leading_characters(from_line, ?\t), n_leading_characters(to_line, ?\t)].min common = [common, n_leading_characters(from_tags[0, common], " "[0])].min from_tags = from_tags[common..-1].rstrip to_tags = to_tags[common..-1].rstrip tag_deleted([from_line]) unless from_tags.empty? tag_difference(["#{"\t" * common}#{from_tags}"]) end tag_inserted([to_line]) unless to_tags.empty? tag_difference(["#{"\t" * common}#{to_tags}"]) end end def n_leading_characters(string, character) n = 0 while string[n] == character n += 1 end n end def space_character?(character) [" "[0], "\t"[0]].include?(character) end end class UnifiedDiffer < Differ def diff(options={}) groups = SequenceMatcher.new(@from, @to).grouped_operations return [] if groups.empty? return [] if same_content?(groups) show_context = options[:show_context] show_context = true if show_context.nil? result = ["--- #{options[:from_label]}".rstrip, "+++ #{options[:to_label]}".rstrip] groups.each do |operations| result << format_summary(operations, show_context) operations.each do |args| operation_tag, from_start, from_end, to_start, to_end = args case operation_tag when :replace result.concat(tag("-", @from[from_start...from_end])) result.concat(tag("+", @to[to_start...to_end])) when :delete result.concat(tag("-", @from[from_start...from_end])) when :insert result.concat(tag("+", @to[to_start...to_end])) when :equal result.concat(tag(" ", @from[from_start...from_end])) end end end result end private def same_content?(groups) return false if groups.size != 1 group = groups[0] return false if group.size != 1 tag, from_start, from_end, to_start, to_end = group[0] tag == :equal and [from_start, from_end] == [to_start, to_end] end def format_summary(operations, show_context) _, first_from_start, _, first_to_start, _ = operations[0] _, _, last_from_end, _, last_to_end = operations[-1] summary = "@@ -%d,%d +%d,%d @@" % [first_from_start + 1, last_from_end - first_from_start, first_to_start + 1, last_to_end - first_to_start,] if show_context interesting_line = find_interesting_line(first_from_start, first_to_start, :define_line?) summary << " #{interesting_line}" if interesting_line end summary end def find_interesting_line(from_start, to_start, predicate) from_index = from_start to_index = to_start while from_index >= 0 or to_index >= 0 [@from[from_index], @to[to_index]].each do |line| return line if line and __send__(predicate, line) end from_index -= 1 to_index -= 1 end nil end def define_line?(line) /\A(?:[_a-zA-Z$]|\s*(?:class|module|def)\b)/ =~ line end end module_function def need_fold?(diff) /^[-+].{79}/ =~ diff end def fold(string) string.split(/\r?\n/).collect do |line| line.gsub(/(.{78})/, "\\1\n") end.join("\n") end def folded_readable(from, to, options={}) readable(fold(from), fold(to), options) end def readable(from, to, options={}) diff(ReadableDiffer, from, to, options) end def unified(from, to, options={}) diff(UnifiedDiffer, from, to, options) end def diff(differ_class, from, to, options={}) if from.respond_to?(:valid_encoding?) and not from.valid_encoding? from = from.dup.force_encoding("ASCII-8BIT") end if to.respond_to?(:valid_encoding?) and not to.valid_encoding? to = to.dup.force_encoding("ASCII-8BIT") end differ = differ_class.new(from.split(/\r?\n/), to.split(/\r?\n/)) lines = differ.diff(options) if Object.const_defined?(:EncodingError) begin lines.join("\n") rescue EncodingError lines.collect {|line| line.force_encoding("ASCII-8BIT")}.join("\n") end else lines.join("\n") end end end end end test-unit-3.3.9/lib/test/unit/attribute.rb0000644000004100000410000001603713775322563020572 0ustar www-datawww-datamodule Test module Unit module Attribute class StringifyKeyHash < Hash class << self def stringify(object) object.to_s end end def key?(key) super(self.class.stringify(key)) end def [](key) super(self.class.stringify(key)) end def []=(key, value) super(self.class.stringify(key), value) end end class << self def included(base) base.extend(BaseClassMethods) base.extend(ClassMethods) end end module BaseClassMethods def attributes_table {} end end module ClassMethods def method_added(name) super return unless defined?(@current_attributes) attributes = {} kept_attributes = StringifyKeyHash.new @current_attributes.each do |attribute_name, attribute| attributes[attribute_name] = attribute[:value] if attribute[:keep] keep_hook = attribute[:keep_hook] attribute = keep_hook.call(attribute) if keep_hook kept_attributes[attribute_name] = attribute end end set_attributes(name, attributes) @current_attributes = kept_attributes end # Set an attribute to test methods. # # @overload attribute(name, value) # @example # attribute :speed, :slow # def test_my_slow_method # self[:speed] # => :slow # end # # @param [Object] name the attribute name # @param [Object] value the attribute value # @return [void] # # @overload attribute(name, value, *method_names) # @example # def test_my_slow_method1 # self[:speed] # => :slow # end # # attribute :speed, :slow, :test_my_slow_method1, :test_my_slow_method2 # # def test_my_slow_method2 # self[:speed] # => :slow # end # # @param [Object] name the attribute name # @param [Object] value the attribute value # @param [Array] method_names the test method names set the attribute # @return [void] # # @overload attribute(name, value, options) # @example # attribute :speed, :slow, keep: true # def test_my_slow_method1 # self[:speed] # => :slow # end # # def test_my_slow_method2 # self[:speed] # => :slow # end # # @param [Object] name the attribute name # @param [Object] value the attribute value # @option options [Boolean] :keep whether or not to set attribute to following test methods # @return [void] # # @overload attribute(name, value, options, *method_names) # @example # def test_my_slow_method1 # self[:speed] # => :slow # end # # # There are no valid options for now. # attribute :speed, :slow, {}, :test_my_slow_method1 # # def test_my_slow_method2 # self[:speed] # => nil # end # # @param [Object] name the attribute name # @param [Object] value the attribute value # @param [Hash] options ignored # @param [Array] method_names the test method names set the attribute # @return [void] def attribute(name, value, options={}, *method_names) unless options.is_a?(Hash) method_names << options options = {} end if method_names.empty? current_attributes[name] = options.merge(:value => value) else method_names.each do |method_name| set_attributes(method_name, {name => value}) end end end def current_attributes @current_attributes ||= StringifyKeyHash.new end def current_attribute(name) current_attributes[name] || StringifyKeyHash.new end def attributes_table @attributes_table ||= StringifyKeyHash.new super.merge(@attributes_table) end def set_attributes(method_name, new_attributes) return if new_attributes.empty? @attributes_table ||= StringifyKeyHash.new @attributes_table[method_name] ||= StringifyKeyHash.new current_attributes = @attributes_table[method_name] new_attributes.each do |key, value| observers = attribute_observers(key) || [] observers.each do |observer| observer.call(self, StringifyKeyHash.stringify(key), (attributes(method_name) || {})[key], value, method_name) end current_attributes[key] = value end end def attributes(method_name) attributes = attributes_table[method_name] ancestors.each do |ancestor| next if ancestor == self if ancestor.is_a?(Class) and ancestor < Test::Unit::Attribute parent_attributes = ancestor.attributes(method_name) if attributes attributes = (parent_attributes || {}).merge(attributes) else attributes = parent_attributes end break end end attributes || StringifyKeyHash.new end def find_attribute(method_name, name, options={}) recursive_p = options[:recursive] recursive_p = true if recursive_p.nil? @attributes_table ||= StringifyKeyHash.new if @attributes_table.key?(method_name) attributes = @attributes_table[method_name] if attributes.key?(name) return attributes[name] end end return nil unless recursive_p return nil if self == TestCase @cached_parent_test_case ||= ancestors.find do |ancestor| ancestor != self and ancestor.is_a?(Class) and ancestor < Test::Unit::Attribute end @cached_parent_test_case.find_attribute(method_name, name, options) end @@attribute_observers = StringifyKeyHash.new def register_attribute_observer(attribute_name, observer=nil, &block) observer ||= Proc.new(&block) @@attribute_observers[attribute_name] ||= [] @@attribute_observers[attribute_name] << observer end def attribute_observers(attribute_name) @@attribute_observers[attribute_name] end end def attributes self.class.attributes(@method_name) || StringifyKeyHash.new end def [](name) self.class.find_attribute(@method_name, name) end end end end test-unit-3.3.9/lib/test/unit/color-scheme.rb0000644000004100000410000001673713775322563021156 0ustar www-datawww-datarequire 'test/unit/color' module Test module Unit class ColorScheme include Enumerable TERM_256 = / [+-]256color| \A(?: alacritty| iTerm\s?\d*\.app| kitty| mintty| ms-terminal| nsterm-build\d+| nsterm| terminator| terminology(?:-[0-9.]+)?| termite| vscode )\z/x class << self def default if available_colors >= 256 default_for_256_colors else default_for_8_colors end end @@default_for_8_colors = nil def default_for_8_colors @@default_for_8_colors ||= new("pass" => Color.new("green", :background => true) + Color.new("white", :bold => true), "pass-marker" => Color.new("green", :bold => true), "failure" => Color.new("red", :background => true) + Color.new("white", :bold => true), "failure-marker" => Color.new("red"), "pending" => Color.new("magenta", :background => true) + Color.new("white", :bold => true), "pending-marker" => Color.new("magenta"), "omission" => Color.new("blue", :background => true) + Color.new("white", :bold => true), "omission-marker" => Color.new("blue"), "notification" => Color.new("cyan", :background => true) + Color.new("white", :bold => true), "notification-marker" => Color.new("cyan"), "error" => Color.new("black", :background => true) + Color.new("yellow", :bold => true), "error-marker" => Color.new("yellow"), "case" => Color.new("blue", :background => true) + Color.new("white", :bold => true), "suite" => Color.new("green", :background => true) + Color.new("white", :bold => true), "diff-inserted-tag" => Color.new("red", :background => true) + Color.new("black", :bold => true), "diff-deleted-tag" => Color.new("green", :background => true) + Color.new("black", :bold => true), "diff-difference-tag" => Color.new("cyan", :background => true) + Color.new("white", :bold => true), "diff-inserted" => Color.new("red", :background => true) + Color.new("white", :bold => true), "diff-deleted" => Color.new("green", :background => true) + Color.new("white", :bold => true)) end @@default_for_256_colors = nil def default_for_256_colors @@default_for_256_colors ||= new("pass" => Color.new("030", :background => true) + Color.new("555", :bold => true), "pass-marker" => Color.new("050", :bold => true), "failure" => Color.new("300", :background => true) + Color.new("555", :bold => true), "failure-marker" => Color.new("500"), "pending" => Color.new("303", :background => true) + Color.new("555", :bold => true), "pending-marker" => Color.new("303"), "omission" => Color.new("001", :background => true) + Color.new("555", :bold => true), "omission-marker" => Color.new("001"), "notification" => Color.new("011", :background => true) + Color.new("555", :bold => true), "notification-marker" => Color.new("011"), "error" => Color.new("000", :background => true) + Color.new("550", :bold => true), "error-marker" => Color.new("550"), "case" => Color.new("220", :background => true) + Color.new("555", :bold => true), "suite" => Color.new("110", :background => true) + Color.new("555", :bold => true), "diff-inserted-tag" => Color.new("500", :background => true) + Color.new("000", :bold => true), "diff-deleted-tag" => Color.new("050", :background => true) + Color.new("000", :bold => true), "diff-difference-tag" => Color.new("005", :background => true) + Color.new("555", :bold => true), "diff-inserted" => Color.new("300", :background => true) + Color.new("555", :bold => true), "diff-deleted" => Color.new("030", :background => true) + Color.new("555", :bold => true)) end @@schemes = {} def all @@schemes.merge("default" => default) end def [](id) @@schemes[id.to_s] end def []=(id, scheme_or_spec) if scheme_or_spec.is_a?(self) scheme = scheme_or_spec else scheme = new(scheme_or_spec) end @@schemes[id.to_s] = scheme end def available_colors guess_available_colors_from_vte_version_env || guess_available_colors_from_colorterm_env || guess_available_colors_from_term_env || 8 end private def guess_available_colors_from_vte_version_env vte_version = ENV["VTE_VERSION"] return nil if vte_version.nil? major = 0 minor = 13 micro = 0 packed_version = major * 10000 + minor * 100 + micro if vte_version.to_i >= packed_version 256 else 8 end end def guess_available_colors_from_colorterm_env case ENV["COLORTERM"] when "gnome-terminal", "xfce4-terminal" 256 else nil end end def guess_available_colors_from_term_env case ENV["TERM"] when /[+-]direct/ 2**24 when TERM_256 256 else nil end end end def initialize(scheme_spec) @scheme = {} scheme_spec.each do |key, color_spec| self[key] = color_spec end end def [](name) @scheme[name.to_s] end def []=(name, color_spec) @scheme[name.to_s] = make_color(color_spec) end def each(&block) @scheme.each(&block) end def to_hash hash = {} @scheme.each do |key, color| hash[key] = color end hash end private def make_color(color_spec) if color_spec.is_a?(Color) or color_spec.is_a?(MixColor) color_spec else color_name = nil normalized_color_spec = {} color_spec.each do |key, value| key = key.to_sym if key == :name color_name = value else normalized_color_spec[key] = value end end Color.new(color_name, normalized_color_spec) end end end end end test-unit-3.3.9/lib/test/unit/failure.rb0000644000004100000410000001213013775322563020204 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. module Test module Unit # Encapsulates a test failure. Created by Test::Unit::TestCase # when an assertion fails. class Failure attr_reader :test_name, :location, :message attr_reader :method_name, :source_location attr_reader :expected, :actual, :user_message attr_reader :inspected_expected, :inspected_actual SINGLE_CHARACTER = 'F' LABEL = "Failure" # Creates a new Failure with the given location and # message. def initialize(test_name, location, message, options={}) @test_name = test_name @location = location @message = message @method_name = options[:method_name] @source_location = options[:source_location] @expected = options[:expected] @actual = options[:actual] @inspected_expected = options[:inspected_expected] @inspected_actual = options[:inspected_actual] @user_message = options[:user_message] end # Returns a single character representation of a failure. def single_character_display SINGLE_CHARACTER end def label LABEL end # Returns a brief version of the error description. def short_display "#@test_name: #{@message.split("\n")[0]}" end # Returns a verbose version of the error description. def long_display if location.size == 1 location_display = location[0].sub(/\A(.+:\d+).*/, ' [\\1]') else location_display = "\n [#{location.join("\n ")}]" end "#{label}:\n#@test_name#{location_display}:\n#@message" end # Overridden to return long_display. def to_s long_display end def critical? true end def diff @diff ||= compute_diff end private def compute_diff Assertions::AssertionMessage.delayed_diff(@expected, @actual).inspect end end module FailureHandler class << self def included(base) base.exception_handler(:handle_assertion_failed_error) end end # Report a failure. # # This is a public API for developers who extend test-unit. # # @param message [String] The description about the failure. # @param backtrace [Array] The backtrace for the failure. # @option options [Object] :expected # The expected value of the assertion. # @option options [Object] :actual # The actual value of the assertion. # @option options [String] :inspected_expected # The inspected expected value of the assertion. # It is used for diff between expected and actual of the failure. # @option options [String] :inspected_actual # The inspected actual value of the assertion. # It is used for diff between expected and actual of the failure. # @option options [String] :user_message # The message of the assertion from user. # @option options [String] :method_name (@method_name) # The method name of the test. # @option options [Array] :source_location # The location where the test is defined. It is the same # format as Proc#source_location. That is, it's an array of # path and and line number where the test definition is # started. # @return [void] def add_failure(message, backtrace, options={}) default_options = { :method_name => @method_name, :source_location => self[:source_location], } failure = Failure.new(name, filter_backtrace(backtrace), message, default_options.merge(options)) current_result.add_failure(failure) end private def handle_assertion_failed_error(exception) return false unless exception.is_a?(AssertionFailedError) problem_occurred add_failure(exception.message, exception.backtrace, :expected => exception.expected, :actual => exception.actual, :inspected_expected => exception.inspected_expected, :inspected_actual => exception.inspected_actual, :user_message => exception.user_message) true end end module TestResultFailureSupport attr_reader :failures # Records a Test::Unit::Failure. def add_failure(failure) @failures << failure notify_fault(failure) notify_changed end # Returns the number of failures this TestResult has # recorded. def failure_count @failures.size end def failure_occurred? not @failures.empty? end private def initialize_containers super @failures = [] @summary_generators << :failure_summary @problem_checkers << :failure_occurred? end def failure_summary "#{failure_count} failures" end end end end test-unit-3.3.9/lib/test/unit/autorunner.rb0000644000004100000410000004303613775322563020770 0ustar www-datawww-datarequire "English" require "test/unit/color-scheme" require "test/unit/priority" require "test/unit/attribute-matcher" require "test/unit/testcase" require "optparse" module Test module Unit class AutoRunner RUNNERS = {} COLLECTORS = {} ADDITIONAL_OPTIONS = [] PREPARE_HOOKS = [] class << self def register_runner(id, runner_builder=nil, &block) runner_builder ||= Proc.new(&block) RUNNERS[id] = runner_builder RUNNERS[id.to_s] = runner_builder end def runner(id) RUNNERS[id.to_s] end @@default_runner = nil def default_runner runner(@@default_runner) end def default_runner=(id) @@default_runner = id end def register_collector(id, collector_builder=nil, &block) collector_builder ||= Proc.new(&block) COLLECTORS[id] = collector_builder COLLECTORS[id.to_s] = collector_builder end def collector(id) COLLECTORS[id.to_s] end def register_color_scheme(id, scheme) ColorScheme[id] = scheme end def setup_option(option_builder=nil, &block) option_builder ||= Proc.new(&block) ADDITIONAL_OPTIONS << option_builder end def prepare(hook=nil, &block) hook ||= Proc.new(&block) PREPARE_HOOKS << hook end def run(force_standalone=false, default_dir=nil, argv=ARGV, &block) r = new(force_standalone || standalone?, &block) r.base = default_dir r.prepare r.process_args(argv) r.run end def standalone? return false unless("-e" == $0) ObjectSpace.each_object(Class) do |klass| return false if(klass < TestCase) end true end @@need_auto_run = true def need_auto_run? @@need_auto_run end def need_auto_run=(need) @@need_auto_run = need end end register_collector(:descendant) do |auto_runner| require "test/unit/collector/descendant" collector = Collector::Descendant.new collector.filter = auto_runner.filters collector.collect($0.sub(/\.rb\Z/, "")) end register_collector(:load) do |auto_runner| require "test/unit/collector/load" collector = Collector::Load.new unless auto_runner.pattern.empty? collector.patterns.replace(auto_runner.pattern) end unless auto_runner.exclude.empty? collector.excludes.replace(auto_runner.exclude) end collector.base = auto_runner.base collector.default_test_paths = auto_runner.default_test_paths collector.filter = auto_runner.filters collector.collect(*auto_runner.to_run) end # JUST TEST! # register_collector(:xml) do |auto_runner| # require "test/unit/collector/xml" # collector = Collector::XML.new # collector.filter = auto_runner.filters # collector.collect(auto_runner.to_run[0]) # end # deprecated register_collector(:object_space) do |auto_runner| require "test/unit/collector/objectspace" c = Collector::ObjectSpace.new c.filter = auto_runner.filters c.collect($0.sub(/\.rb\Z/, "")) end # deprecated register_collector(:dir) do |auto_runner| require "test/unit/collector/dir" c = Collector::Dir.new c.filter = auto_runner.filters unless auto_runner.pattern.empty? c.pattern.replace(auto_runner.pattern) end unless auto_runner.exclude.empty? c.exclude.replace(auto_runner.exclude) end c.base = auto_runner.base $:.push(auto_runner.base) if auto_runner.base c.collect(*(auto_runner.to_run.empty? ? ["."] : auto_runner.to_run)) end attr_reader :suite, :runner_options attr_accessor :filters, :to_run attr_accessor :default_test_paths attr_accessor :pattern, :exclude, :base, :workdir attr_accessor :color_scheme, :listeners attr_writer :stop_on_failure attr_writer :runner, :collector def initialize(standalone) @standalone = standalone @runner = default_runner @collector = default_collector @filters = [] @to_run = [] @default_test_paths = [] @color_scheme = ColorScheme.default @runner_options = {} @default_arguments = [] @workdir = nil @listeners = [] @stop_on_failure = false config_file = "test-unit.yml" if File.exist?(config_file) load_config(config_file) else load_global_config end yield(self) if block_given? end def stop_on_failure? @stop_on_failure end def prepare PREPARE_HOOKS.each do |handler| handler.call(self) end end def process_args(args=ARGV) begin args.unshift(*@default_arguments) options.order!(args) {|arg| add_test_path(arg)} rescue OptionParser::ParseError => e puts e puts options exit(false) end not @to_run.empty? end def options @options ||= OptionParser.new do |o| o.banner = "Test::Unit automatic runner." o.banner += "\nUsage: #{$0} [options] [-- untouched arguments]" o.on("-r", "--runner=RUNNER", RUNNERS, "Use the given RUNNER.", "(" + keyword_display(RUNNERS) + ")") do |r| @runner = r end o.on("--collector=COLLECTOR", COLLECTORS, "Use the given COLLECTOR.", "(" + keyword_display(COLLECTORS) + ")") do |collector| @collector = collector end if (@standalone) o.on("-b", "--basedir=DIR", "Base directory of test suites.") do |b| @base = b end o.on("-w", "--workdir=DIR", "Working directory to run tests.") do |w| @workdir = w end o.on("--default-test-path=PATH", "Add PATH to the default test paths.", "The PATH is used when user doesn't specify any test path.", "You can specify this option multiple times.") do |path| @default_test_paths << path end o.on("-a", "--add=TORUN", Array, "Add TORUN to the list of things to run;", "can be a file or a directory.") do |paths| paths.each do |path| add_test_path(path) end end @pattern = [] o.on("-p", "--pattern=PATTERN", Regexp, "Match files to collect against PATTERN.") do |e| @pattern << e end @exclude = [] o.on("-x", "--exclude=PATTERN", Regexp, "Ignore files to collect against PATTERN.") do |e| @exclude << e end end o.on("-n", "--name=NAME", String, "Runs tests matching NAME.", "Use '/PATTERN/' for NAME to use regular expression.", "Regular expression accepts options.", "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name| name = prepare_name(name) @filters << lambda do |test| match_test_name(test, name) end end o.on("--ignore-name=NAME", String, "Ignores tests matching NAME.", "Use '/PATTERN/' for NAME to use regular expression.", "Regular expression accepts options.", "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name| name = prepare_name(name) @filters << lambda do |test| not match_test_name(test, name) end end o.on("-t", "--testcase=TESTCASE", String, "Runs tests in TestCases matching TESTCASE.", "Use '/PATTERN/' for TESTCASE to use regular expression.", "Regular expression accepts options.", "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name| name = prepare_name(name) @filters << lambda do |test| match_test_case_name(test, name) end end o.on("--ignore-testcase=TESTCASE", String, "Ignores tests in TestCases matching TESTCASE.", "Use '/PATTERN/' for TESTCASE to use regular expression.", "Regular expression accepts options.", "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name| name = prepare_name(name) @filters << lambda do |test| not match_test_case_name(test, name) end end o.on("--location=LOCATION", String, "Runs tests that defined in LOCATION.", "LOCATION is one of PATH:LINE, PATH or LINE.") do |location| case location when /\A(\d+)\z/ path = nil line = $1.to_i when /:(\d+)\z/ path = $PREMATCH line = $1.to_i else path = location line = nil end add_location_filter(path, line) end o.on("--attribute=EXPRESSION", String, "Runs tests that matches EXPRESSION.", "EXPRESSION is evaluated as Ruby's expression.", "Test attribute name can be used with no receiver in EXPRESSION.", "EXPRESSION examples:", " !slow", " tag == 'important' and !slow") do |expression| @filters << lambda do |test| matcher = AttributeMatcher.new(test) matcher.match?(expression) end end priority_filter = Proc.new do |test| if @filters == [priority_filter] Priority::Checker.new(test).need_to_run? else nil end end o.on("--[no-]priority-mode", "Runs some tests based on their priority.") do |priority_mode| if priority_mode Priority.enable @filters |= [priority_filter] else Priority.disable @filters -= [priority_filter] end end o.on("--default-priority=PRIORITY", Priority.available_values, "Uses PRIORITY as default priority", "(#{keyword_display(Priority.available_values)})") do |priority| Priority.default = priority end o.on("-I", "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]", "Appends directory list to $LOAD_PATH.") do |dirs| $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR)) end color_schemes = ColorScheme.all o.on("--color-scheme=SCHEME", color_schemes, "Use SCHEME as color scheme.", "(#{keyword_display(color_schemes)})") do |scheme| @color_scheme = scheme end o.on("--config=FILE", "Use YAML format FILE content as configuration file.") do |file| load_config(file) end o.on("--order=ORDER", TestCase::AVAILABLE_ORDERS, "Run tests in a test case in ORDER order.", "(#{keyword_display(TestCase::AVAILABLE_ORDERS)})") do |order| TestCase.test_order = order end assertion_message_class = Test::Unit::Assertions::AssertionMessage o.on("--max-diff-target-string-size=SIZE", Integer, "Shows diff if both expected result string size and " + "actual result string size are " + "less than or equal SIZE in bytes.", "(#{assertion_message_class.max_diff_target_string_size})") do |size| assertion_message_class.max_diff_target_string_size = size end o.on("--[no-]stop-on-failure", "Stops immediately on the first non success test", "(#{@stop_on_failure})") do |boolean| @stop_on_failure = boolean end ADDITIONAL_OPTIONS.each do |option_builder| option_builder.call(self, o) end o.on("--", "Stop processing options so that the", "remaining options will be passed to the", "test."){o.terminate} o.on("-h", "--help", "Display this help."){puts o; exit} o.on_tail o.on_tail("Deprecated options:") o.on_tail("--console", "Console runner (use --runner).") do warn("Deprecated option (--console).") @runner = self.class.runner(:console) end if RUNNERS[:fox] o.on_tail("--fox", "Fox runner (use --runner).") do warn("Deprecated option (--fox).") @runner = self.class.runner(:fox) end end o.on_tail end end def keyword_display(keywords) keywords = keywords.collect do |keyword, _| keyword.to_s end.uniq.sort i = 0 keywords.collect do |keyword| if (i > 0 and keyword[0] == keywords[i - 1][0]) or ((i < keywords.size - 1) and (keyword[0] == keywords[i + 1][0])) n = 2 else n = 1 end i += 1 keyword.sub(/^(.{#{n}})([A-Za-z]+)(?=\w*$)/, '\\1[\\2]') end.join(", ") end def run self.class.need_auto_run = false suite = @collector[self] return false if suite.nil? return true if suite.empty? runner = @runner[self] return false if runner.nil? @runner_options[:color_scheme] ||= @color_scheme @runner_options[:listeners] ||= [] @runner_options[:listeners].concat(@listeners) if @stop_on_failure @runner_options[:listeners] << StopOnFailureListener.new end change_work_directory do runner.run(suite, @runner_options).passed? end end def load_config(file) require "yaml" config = YAML.load(File.read(file)) runner_name = config["runner"] @runner = self.class.runner(runner_name) || @runner @collector = self.class.collector(config["collector"]) || @collector (config["color_schemes"] || {}).each do |name, options| ColorScheme[name] = options end runner_options = {} (config["#{runner_name}_options"] || {}).each do |key, value| key = key.to_sym value = ColorScheme[value] if key == :color_scheme if key == :arguments @default_arguments.concat(value.split) else runner_options[key] = value end end @runner_options = @runner_options.merge(runner_options) end private def default_runner runner = self.class.default_runner if ENV["EMACS"] == "t" runner ||= self.class.runner(:emacs) else runner ||= self.class.runner(:console) end runner end def default_collector self.class.collector(@standalone ? :load : :descendant) end def global_config_file File.expand_path("~/.test-unit.yml") rescue ArgumentError nil end def load_global_config file = global_config_file load_config(file) if file and File.exist?(file) end def change_work_directory(&block) if @workdir Dir.chdir(@workdir, &block) else yield end end def prepare_name(name) case name when /\A\/(.*)\/([imx]*)\z/ pattern = $1 options_raw = $2 options = 0 options |= Regexp::IGNORECASE if options_raw.include?("i") options |= Regexp::MULTILINE if options_raw.include?("m") options |= Regexp::EXTENDED if options_raw.include?("x") Regexp.new(pattern, options) else name end end def match_test_name(test, pattern) return true if pattern === test.method_name return true if pattern === test.local_name if pattern.is_a?(String) return true if pattern === "#{test.class}##{test.method_name}" return true if pattern === "#{test.class}##{test.local_name}" end false end def match_test_case_name(test, pattern) test.class.ancestors.each do |test_class| break if test_class == TestCase return true if pattern === test_class.name end false end def add_test_path(path) if /:(\d+)\z/ =~ path line = $1.to_i path = $PREMATCH add_location_filter(path, line) end @to_run << path end def add_location_filter(path, line) @filters << lambda do |test| test.class.test_defined?(:path => path, :line => line, :method_name => test.method_name) end end class StopOnFailureListener def attach_to_mediator(mediator) mediator.add_listener(TestResult::FINISHED) do |result| result.stop unless result.passed? end end end end end end require "test/unit/runner/console" require "test/unit/runner/emacs" require "test/unit/runner/xml" test-unit-3.3.9/lib/test/unit/color.rb0000644000004100000410000000571613775322563017707 0ustar www-datawww-datamodule Test module Unit class Color class Error < StandardError end class ParseError < Error end class << self def parse_256_color(string) case string when /\A([0-5])([0-5])([0-5])\z/ red, green, blue = $1, $2, $3 red.to_i * 36 + green.to_i * 6 + blue.to_i + 16 else message = "must be 'RGB' format and R, G and B " + "are in 0-5: #{string.inspect}" raise ParseError, message end end end NAMES = ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"] attr_reader :name def initialize(name, options={}) @name = name if options.has_key?(:foreground) if options[:foreground].nil? @background = false else @background = !options[:foreground] end else @background = options[:background] end @intensity = options[:intensity] @bold = options[:bold] @italic = options[:italic] @underline = options[:underline] end def foreground? not background? end def background? @background end def intensity? @intensity end def bold? @bold end def italic? @italic end def underline? @underline end def ==(other) self.class === other and [name, background?, intensity?, bold?, italic?, underline?] == [other.name, other.background?, other.intensity?, other.bold?, other.italic?, other.underline?] end def sequence sequence = [] if @name == "none" elsif @name == "reset" sequence << "0" else if NAMES.include?(@name) color_parameter = foreground? ? 3 : 4 color_parameter += 6 if intensity? color = NAMES.index(@name) sequence << "#{color_parameter}#{color}" else sequence << (foreground? ? "38" : "48") sequence << "5" sequence << self.class.parse_256_color(@name).to_s end end sequence << "1" if bold? sequence << "3" if italic? sequence << "4" if underline? sequence end def escape_sequence "\e[#{sequence.join(';')}m" end def +(other) MixColor.new([self, other]) end end class MixColor attr_reader :colors def initialize(colors) @colors = colors end def sequence @colors.inject([]) do |result, color| result + color.sequence end end def escape_sequence "\e[#{sequence.join(';')}m" end def +(other) self.class.new([self, other]) end def ==(other) self.class === other and colors == other.colors end end end end test-unit-3.3.9/lib/test/unit/util/0000755000004100000410000000000013775322563017210 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/util/output.rb0000644000004100000410000000136713775322563021104 0ustar www-datawww-datamodule Test module Unit module Util module Output ## # Returns output for standard output and standard # error as string. # # Example: # # capture_output do # puts("stdout") # warn("stderr") # end # -> ["stdout\n", "stderr\n"] def capture_output require 'stringio' output = StringIO.new error = StringIO.new stdout_save, stderr_save = $stdout, $stderr $stdout, $stderr = output, error begin yield [output.string, error.string] ensure $stdout, $stderr = stdout_save, stderr_save end end end end end end test-unit-3.3.9/lib/test/unit/util/observable.rb0000644000004100000410000000547113775322563021670 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/util/procwrapper' module Test module Unit module Util # This is a utility class that allows anything mixing # it in to notify a set of listeners about interesting # events. module Observable # We use this for defaults since nil might mean something NOTHING = "NOTHING/#{__id__}" # Adds the passed proc as a listener on the # channel indicated by channel_name. listener_key # is used to remove the listener later; if none is # specified, the proc itself is used. # # Whatever is used as the listener_key is # returned, making it very easy to use the proc # itself as the listener_key: # # listener = add_listener("Channel") { ... } # remove_listener("Channel", listener) def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value unless(block_given?) raise ArgumentError.new("No callback was passed as a listener") end key = listener_key if (listener_key == NOTHING) listener_key = listener key = ProcWrapper.new(listener) end channels[channel_name] ||= {} channels[channel_name][key] = listener return listener_key end # Removes the listener indicated by listener_key # from the channel indicated by # channel_name. Returns the registered proc, or # nil if none was found. def remove_listener(channel_name, listener_key) channel = channels[channel_name] return nil unless (channel) key = listener_key if (listener_key.instance_of?(Proc)) key = ProcWrapper.new(listener_key) end if (channel.has_key?(key)) return channel.delete(key) end return nil end # Calls all the procs registered on the channel # indicated by channel_name. If value is # specified, it is passed in to the procs, # otherwise they are called with no arguments. # #-- # # Perhaps this should be private? Would it ever # make sense for an external class to call this # method directly? def notify_listeners(channel_name, *arguments) channel = channels[channel_name] return 0 unless (channel) listeners = channel.values listeners.each { |listener| listener.call(*arguments) } return listeners.size end private def channels @channels ||= {} return @channels end end end end end test-unit-3.3.9/lib/test/unit/util/method-owner-finder.rb0000644000004100000410000000133013775322563023407 0ustar www-datawww-datamodule Test module Unit module Util module MethodOwnerFinder module_function def find(object, method_name) method = object.method(method_name) return method.owner if method.respond_to?(:owner) if /\((.+?)\)\#/ =~ method.to_s owner_name = $1 if /\A#)$/){''}.hex end def hash return @hash end def ==(other) case(other) when ProcWrapper return @a_proc == other.to_proc else return super end end alias :eql? :== def to_proc return @a_proc end end end end end test-unit-3.3.9/lib/test/unit/error.rb0000644000004100000410000000715713775322563017723 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/util/backtracefilter' module Test module Unit # Encapsulates an error in a test. Created by # Test::Unit::TestCase when it rescues an exception thrown # during the processing of a test. class Error include Util::BacktraceFilter attr_reader :test_name, :exception attr_reader :method_name SINGLE_CHARACTER = 'E' LABEL = "Error" # Creates a new Error with the given test_name and # exception. def initialize(test_name, exception, options={}) @test_name = test_name @exception = exception @method_name = options[:method_name] end # Returns a single character representation of an error. def single_character_display SINGLE_CHARACTER end def label LABEL end # Returns the message associated with the error. def message "#{@exception.class.name}: #{@exception.message}" end # Returns a brief version of the error description. def short_display "#@test_name: #{message.split("\n")[0]}" end # Returns a verbose version of the error description. def long_display backtrace_display = location.join("\n ") "#{label}:\n#@test_name:\n#{message}\n #{backtrace_display}" end def location @location ||= filter_backtrace(@exception.backtrace) end alias_method :backtrace, :location # Deprecated # Overridden to return long_display. def to_s long_display end def critical? true end end module ErrorHandler class << self def included(base) base.exception_handler(:handle_all_exception) end end NOT_PASS_THROUGH_EXCEPTIONS = [] NOT_PASS_THROUGH_EXCEPTION_NAMES = ["Timeout::Error"] PASS_THROUGH_EXCEPTIONS = [ NoMemoryError, SignalException, Interrupt, SystemExit, ] PASS_THROUGH_EXCEPTION_NAMES = [] private def handle_all_exception(exception) return false if pass_through_exception?(exception) problem_occurred add_error(exception) true end def pass_through_exception?(exception) case exception when *NOT_PASS_THROUGH_EXCEPTIONS return false end case exception.class.name when *NOT_PASS_THROUGH_EXCEPTION_NAMES return false end case exception when *PASS_THROUGH_EXCEPTIONS return true end case exception.class.name when *PASS_THROUGH_EXCEPTION_NAMES return true end false end def add_error(exception) error = Error.new(name, exception, :method_name => @method_name) current_result.add_error(error) end end module TestResultErrorSupport attr_reader :errors # Records a Test::Unit::Error. def add_error(error) @errors << error notify_fault(error) notify_changed end # Returns the number of errors this TestResult has # recorded. def error_count @errors.size end def error_occurred? not @errors.empty? end private def initialize_containers super @errors = [] @summary_generators << :error_summary @problem_checkers << :error_occurred? end def error_summary "#{error_count} errors" end end end end test-unit-3.3.9/lib/test/unit/priority.rb0000644000004100000410000001071013775322563020440 0ustar www-datawww-datarequire "fileutils" module Test module Unit module Priority class << self def included(base) base.extend(ClassMethods) base.class_eval do setup :priority_setup, :before => :prepend teardown :priority_teardown, :after => :append end end @@enabled = false def enabled? @@enabled end def enable require "fileutils" require "tmpdir" @@enabled = true end def disable @@enabled = false end @@default = :normal def default @@default || :normal end def default=(default) @@default = default end def available_values Checker.available_priorities end end class Checker class << self def have_priority?(name) singleton_class = (class << self; self; end) singleton_class.method_defined?(priority_check_method_name(name)) end def need_to_run?(test) priority = test[:priority] || Priority.default if have_priority?(priority) __send__(priority_check_method_name(priority), test) else true end end def available_priorities methods(false).collect do |name| /\Arun_priority_(.+)\?\z/ =~ name.to_s $1 end.compact end def run_priority_must?(test) true end def run_priority_important?(test) rand > 0.1 end def run_priority_high?(test) rand > 0.3 end def run_priority_normal?(test) rand > 0.5 end def run_priority_low?(test) rand > 0.75 end def run_priority_never?(test) false end private def priority_check_method_name(priority_name) "run_priority_#{priority_name}?" end end attr_reader :test def initialize(test) @test = test end def setup FileUtils.rm_f(passed_file) end def teardown if @test.__send__(:passed?) FileUtils.touch(passed_file) else FileUtils.rm_f(passed_file) end end def need_to_run? !previous_test_success? or self.class.need_to_run?(@test) end private def previous_test_success? File.exist?(passed_file) end def result_dir components = [ ".test-result", escape_class_name(@test.class.name || "AnonymousTestCase"), escaped_method_name, ] parent_directories = [File.dirname($0), Dir.pwd] if Process.respond_to?(:uid) parent_directories << File.join(Dir.tmpdir, Process.uid.to_s) end parent_directories.each do |parent_directory| dir = File.expand_path(File.join(parent_directory, *components)) begin FileUtils.mkdir_p(dir) return dir rescue Errno::EACCES end end raise Errno::EACCES, parent_directories.join(", ") end def passed_file File.join(result_dir, "passed") end def escape_class_name(class_name) escape_name(class_name) end def escaped_method_name escape_name(@test.method_name.to_s) end def escape_name(name) name.gsub(/(?:[: \/!?=])/) do |matched| case matched when ":" "_colon_" when " ", "/" "_" when "!" ".destructive" when "?" ".predicate" when "=" ".equal" end end end end module ClassMethods def priority(name, *tests) unless Checker.have_priority?(name) raise ArgumentError, "unknown priority: #{name}" end attribute(:priority, name, {:keep => true}, *tests) end end def priority_setup return unless Priority.enabled? Checker.new(self).setup end def priority_teardown return unless Priority.enabled? Checker.new(self).teardown end end end end test-unit-3.3.9/lib/test/unit/omission.rb0000644000004100000410000001114413775322563020421 0ustar www-datawww-datarequire 'test/unit/util/backtracefilter' module Test module Unit class Omission include Util::BacktraceFilter attr_reader :test_name, :location, :message attr_reader :method_name SINGLE_CHARACTER = 'O' LABEL = "Omission" # Creates a new Omission with the given location and # message. def initialize(test_name, location, message, options={}) @test_name = test_name @location = location @message = message @method_name = options[:method_name] end # Returns a single character representation of a omission. def single_character_display SINGLE_CHARACTER end def label LABEL end # Returns a brief version of the error description. def short_display "#{@test_name}: #{@message.split("\n")[0]}" end # Returns a verbose version of the error description. def long_display backtrace = filter_backtrace(location).join("\n") "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" end # Overridden to return long_display. def to_s long_display end def critical? true end end class OmittedError < StandardError end module TestCaseOmissionSupport class << self def included(base) base.class_eval do include OmissionHandler end end end # Omit the test or part of the test. # # Example: # # def test_omission # omit # # Not reached here # end # # def test_omission_with_here # omit do # # Not ran here # end # # Reached here # end def omit(message=nil, &block) message ||= "omitted." if block_given? omission = Omission.new(name, filter_backtrace(caller), message, :method_name => @method_name) add_omission(omission) else raise OmittedError.new(message) end end # Omit the test or part of the test if _condition_ is # true. # # Example: # # def test_omission # omit_if("".empty?) # # Not reached here # end # # def test_omission_with_here # omit_if(true) do # # Not ran here # end # omit_if(false) do # # Reached here # end # # Reached here too # end def omit_if(condition, *args, &block) if condition omit(*args, &block) else block.call if block end end # Omit the test or part of the test if _condition_ is # not true. # # Example: # # def test_omission # omit_unless("string".empty?) # # Not reached here # end # # def test_omission_with_here # omit_unless(true) do # # Reached here # end # omit_unless(false) do # # Not ran here # end # # Reached here too # end def omit_unless(condition, *args, &block) if condition block.call if block else omit(*args, &block) end end private def add_omission(omission) current_result.add_omission(omission) end end module OmissionHandler class << self def included(base) base.exception_handler(:handle_omitted_error) end end private def handle_omitted_error(exception) return false unless exception.is_a?(OmittedError) omission = Omission.new(name, filter_backtrace(exception.backtrace), exception.message, :method_name => @method_name) add_omission(omission) true end end module TestResultOmissionSupport attr_reader :omissions # Records a Test::Unit::Omission. def add_omission(omission) @omissions << omission notify_fault(omission) notify_changed end # Returns the number of omissions this TestResult has # recorded. def omission_count @omissions.size end private def initialize_containers super @omissions = [] @summary_generators << :omission_summary end def omission_summary "#{omission_count} omissions" end end end end test-unit-3.3.9/lib/test/unit/runner/0000755000004100000410000000000013775322563017544 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/runner/emacs.rb0000644000004100000410000000027213775322563021162 0ustar www-datawww-datamodule Test module Unit AutoRunner.register_runner(:emacs) do |auto_runner| require 'test/unit/ui/emacs/testrunner' Test::Unit::UI::Emacs::TestRunner end end end test-unit-3.3.9/lib/test/unit/runner/xml.rb0000644000004100000410000000065013775322563020672 0ustar www-datawww-datamodule Test module Unit AutoRunner.register_runner(:xml) do |auto_runner| require 'test/unit/ui/xml/testrunner' Test::Unit::UI::XML::TestRunner end AutoRunner.setup_option do |auto_runner, opts| opts.on("--output-file-descriptor=FD", Integer, "Outputs to file descriptor FD") do |fd| auto_runner.runner_options[:output_file_descriptor] = fd end end end end test-unit-3.3.9/lib/test/unit/runner/console.rb0000644000004100000410000000431413775322563021535 0ustar www-datawww-data# Copyright (C) 2008-2017 Kouhei Sutou module Test module Unit AutoRunner.register_runner(:console) do |auto_runner| require 'test/unit/ui/console/testrunner' Test::Unit::UI::Console::TestRunner end AutoRunner.setup_option do |auto_runner, opts| require 'test/unit/ui/console/outputlevel' output_levels = [ ["silent", UI::Console::OutputLevel::SILENT], ["progress", UI::Console::OutputLevel::PROGRESS_ONLY], ["important-only", UI::Console::OutputLevel::IMPORTANT_FAULTS_ONLY], ["normal", UI::Console::OutputLevel::NORMAL], ["verbose", UI::Console::OutputLevel::VERBOSE], ] opts.on('-v', '--verbose=[LEVEL]', output_levels, "Set the output level (default is verbose).", "(#{auto_runner.keyword_display(output_levels)})") do |level| level ||= output_levels.assoc("verbose")[1] auto_runner.runner_options[:output_level] = level end use_color_options = [ [:auto, :auto], ["-", false], ["no", false], ["false", false], ["+", true], ["yes", true], ["true", true], ] opts.on("--[no-]use-color=[auto]", use_color_options, "Uses color output", "(default is auto)") do |use_color| case use_color when nil use_color = true when :auto use_color = nil end auto_runner.runner_options[:use_color] = use_color end opts.on("--progress-row-max=MAX", Integer, "Uses MAX as max terminal width for progress mark", "(default is auto)") do |max| auto_runner.runner_options[:progress_row_max] = max end opts.on("--no-show-detail-immediately", "Shows not passed test details immediately.", "(default is yes)") do |boolean| auto_runner.runner_options[:show_detail_immediately] = boolean end opts.on("--[no-]reverse-output", "Shows fault details in reverse.", "(default is yes for tty output, no otherwise)") do |boolean| auto_runner.runner_options[:reverse_output] = boolean end end end end test-unit-3.3.9/lib/test/unit/collector.rb0000644000004100000410000000347213775322563020554 0ustar www-datawww-datamodule Test module Unit module Collector def initialize @filters = [] end def filter=(filters) @filters = case(filters) when Proc [filters] when Array filters end end def add_suite(destination, suite) to_delete = suite.tests.find_all do |test| test.is_a?(TestCase) and !include?(test) end suite.delete_tests(to_delete) destination << suite unless suite.empty? end def add_test_cases(suite, test_cases) children_map = {} test_cases.each do |test_case| ancestor_classes = test_case.ancestors.find_all do |ancestor| ancestor.is_a?(Class) end parent = ancestor_classes[1] children_map[parent] ||= [] children_map[parent] << test_case end root_test_cases = children_map.keys - test_cases root_test_cases.each do |root_test_case| add_test_case(suite, root_test_case, children_map) end end def include?(test) return true if(@filters.empty?) @filters.each do |filter| return false if filter[test] == false end true end def sort(suites) suites.sort_by do |suite| [suite.priority, suite.name || suite.to_s] end end private def add_test_case(suite, test_case, children_map) children = children_map[test_case] return if children.nil? sub_suites = [] children.each do |child| sub_suite = child.suite add_test_case(sub_suite, child, children_map) add_suite(sub_suites, sub_suite) end sort(sub_suites).each do |sub_suite| suite << sub_suite end end end end end test-unit-3.3.9/lib/test/unit/code-snippet-fetcher.rb0000644000004100000410000000300613775322563022567 0ustar www-datawww-datamodule Test module Unit class CodeSnippetFetcher def initialize @sources = {} end def fetch(path, line, options={}) n_context_line = options[:n_context_line] || 3 lines = source(path) return [] if lines.nil? min_line = [line - n_context_line, 1].max max_line = [line + n_context_line, lines.length].min window = min_line..max_line window.collect do |n| attributes = {:target_line? => (n == line)} [n, lines[n - 1].chomp, attributes] end end def source(path) @sources[path] ||= read_source(path) end private def read_source(path) return nil unless File.exist?(path) lines = [] File.open(path, "rb") do |file| first_line = file.gets break if first_line.nil? encoding = detect_encoding(first_line) || Encoding::UTF_8 first_line.force_encoding(encoding) lines << first_line file.each_line do |line| line.force_encoding(encoding) lines << line end end lines end def detect_encoding(first_line) return nil unless first_line.respond_to?(:ascii_only?) return nil unless first_line.ascii_only? if /\b(?:en)?coding[:=]\s*([a-z\d_-]+)/i =~ first_line begin Encoding.find($1) rescue ArgumentError nil end else nil end end end end end test-unit-3.3.9/lib/test/unit/data.rb0000644000004100000410000003076113775322563017500 0ustar www-datawww-datarequire "test/unit/data-sets" module Test module Unit module Data class << self def included(base) base.extend(ClassMethods) end end module ClassMethods # This method provides Data-Driven-Test functionality. # # Define test data in the test code. # # @overload data(label, data, options={}) # @param [String] label specify test case name. # @param data specify test data. # @param [Hash] options specify options. # @option options [Boolean] :keep whether or not to use # this data in the following test methods # # @example data(label, data) # data("empty string", [true, ""]) # data("plain string", [false, "hello"]) # def test_empty?(data) # expected, target = data # assert_equal(expected, target.empty?) # end # # @overload data(variable, patterns, options={}) # @param [Symbol] variable specify test pattern variable name. # @param [Array] patterns specify test patterns for the variable. # @param [Hash] options specify options. # @option options [Boolean] :keep whether or not to use # this data in the following test methods # @option options [Object] :group the test pattern group. # Test matrix is generated for each test pattern group separately. # # @example data(variable, patterns) # data(:x, [1, 2, 3]) # data(:y, ["a", "b"]) # def test_patterns(data) # # 3 * 2 times executed # # 3: the number of patterns of :x # # 2: the number of patterns of :y # p data # # => {:x => 1, :y => "a"} # # => {:x => 1, :y => "b"} # # => {:x => 2, :y => "a"} # # => {:x => 2, :y => "b"} # # => {:x => 3, :y => "a"} # # => {:x => 3, :y => "b"} # end # # Generates test matrix from variable and patterns pairs. # # @overload data(data_set, options={}) # @param [Hash] data_set specify test data as a Hash that # key is test label and value is test data. # @param [Hash] options specify options. # @option options [Boolean] :keep whether or not to use # this data in the following test methods # # @example data(data_set) # data("empty string" => [true, ""], # "plain string" => [false, "hello"]) # def test_empty?(data) # expected, target = data # assert_equal(expected, target.empty?) # end # # @overload data(options={}, &block) # @param [Hash] options specify options. # @option options [Boolean] :keep whether or not to use # this data in the following test methods # @yieldreturn [Hash] return test data set # as a Hash that key is test label and value is test data. # # @example data(&block) # data do # data_set = {} # data_set["empty string"] = [true, ""] # data_set["plain string"] = [false, "hello"] # data_set # end # def test_empty?(data) # expected, target = data # assert_equal(expected, target.empty?) # end # # @overload data(options={}, &block) # @param [Hash] options specify options. # @option options [Boolean] :keep whether or not to use # this data in the following test methods # @yieldreturn [Array] return test data set # as an Array of variable and patterns. # # @example data(&block) # data do # patterns = 3.times.to_a # [:x, patterns] # end # data do # patterns = [] # character = "a" # 2.times.each do # patterns << character # character = character.succ # end # [:y, patterns] # end # def test_patterns(data) # # 3 * 2 times executed # # 3: the number of patterns of :x # # 2: the number of patterns of :y # p data # # => {:x => 0, :y => "a"} # # => {:x => 0, :y => "b"} # # => {:x => 1, :y => "a"} # # => {:x => 1, :y => "b"} # # => {:x => 2, :y => "a"} # # => {:x => 2, :y => "b"} # end # # Generates test matrix from variable and patterns pairs. # def data(*arguments, &block) options = nil n_arguments = arguments.size case n_arguments when 0 raise ArgumentError, "no block is given" unless block_given? data_set = block when 1 if block_given? data_set = block options = arguments[1] else data_set = arguments[0] end when 2 case arguments[0] when String data_set = {arguments[0] => arguments[1]} when Hash data_set = arguments[0] options = arguments[1] else variable = arguments[0] patterns = arguments[1] data_set = [variable, patterns] end when 3 case arguments[0] when String data_set = {arguments[0] => arguments[1]} options = arguments[2] else variable = arguments[0] patterns = arguments[1] data_set = [variable, patterns] options = arguments[2] end else message = "wrong number arguments(#{n_arguments} for 0..3)" raise ArgumentError, message end options ||= {} data_sets = current_attribute(:data)[:value] || DataSets.new data_sets.add(data_set, options) if options[:keep] keep_hook = lambda do |attr| attr.merge(value: attr[:value].keep) end options = options.merge(keep_hook: keep_hook) end attribute(:data, data_sets, options) end # This method provides Data-Driven-Test functionality. # # Load test data from the file. This is shorthand to load # test data from file. If you want to load complex file, you # can use {#data} with block. # # @param [String] file_name full path to test data file. # File format is automatically detected from filename extension. # @raise [ArgumentError] if `file_name` is not supported file format. # @see Loader#load # # @example Load data from CSV file # load_data("/path/to/test-data.csv") # def test_empty?(data) # assert_equal(data["expected"], data["target"].empty?) # end # def load_data(file_name) loader = Loader.new(self) loader.load(file_name) end class Loader # @api private def initialize(test_case) @test_case = test_case end # Load data from file. # # @param [String] file_name full path to test data file. # File format is automatically detected from filename extension. # @raise [ArgumentError] if `file_name` is not supported file format. # @see #load_csv # @see #load_tsv # @api private def load(file_name) case File.extname(file_name).downcase when ".csv" load_csv(file_name) when ".tsv" load_tsv(file_name) else raise ArgumentError, "unsupported file format: <#{file_name}>" end end # Load data from CSV file. # # There are 2 types of CSV file as following examples. # First, there is a header on first row and it's first column is "label". # Another, there is no header in the file. # # @example Load data from CSV file with header # # test-data.csv: # # label,expected,target # # empty string,true,"" # # plain string,false,hello # # # load_data("/path/to/test-data.csv") # def test_empty?(data) # assert_equal(data["expected"], data["target"].empty?) # end # # @example Load data from CSV file without header # # test-data-without-header.csv: # # empty string,true,"" # # plain string,false,hello # # # load_data("/path/to/test-data-without-header.csv") # def test_empty?(data) # expected, target = data # assert_equal(expected, target.empty?) # end # # @api private def load_csv(file_name) require 'csv' first_row = true header = nil CSV.foreach(file_name) do |row| if first_row first_row = false if row.first == "label" header = row[1..-1] next end end set_test_data(header, row) end end # Load data from TSV file. # # There are 2 types of TSV file as following examples. # First, there is a header on first row and it's first column is "label". # Another, there is no header in the file. # # @example Load data from TSV file with header # # test-data.tsv: # # label expected target # # empty string true "" # # plain string false hello # # # load_data("/path/to/test-data.tsv") # def test_empty?(data) # assert_equal(data["expected"], data["target"].empty?) # end # # @example Load data from TSV file without header # # test-data-without-header.tsv: # # empty string true "" # # plain string false hello # # # load_data("/path/to/test-data-without-header.tsv") # def test_empty?(data) # expected, target = data # assert_equal(expected, target.empty?) # end # # @api private def load_tsv(file_name) require "csv" if CSV.const_defined?(:VERSION) first_row = true header = nil CSV.foreach(file_name, :col_sep => "\t") do |row| if first_row first_row = false if row.first == "label" header = row[1..-1] next end end set_test_data(header, row) end else # for old CSV library first_row = true header = nil CSV.open(file_name, "r", "\t") do |row| if first_row first_row = false if row.first == "label" header = row[1..-1] next end end set_test_data(header, row) end end end private def normalize_value(value) return true if value == "true" return false if value == "false" begin Integer(value) rescue ArgumentError begin Float(value) rescue ArgumentError value end end end def set_test_data(header, row) label = row.shift if header data = {} header.each_with_index do |key, i| data[key] = normalize_value(row[i]) end else data = row.collect do |cell| normalize_value(cell) end end @test_case.data(label, data) end end end end end end test-unit-3.3.9/lib/test/unit/exception-handler.rb0000644000004100000410000000531113775322563022171 0ustar www-datawww-datamodule Test module Unit module ExceptionHandler @@exception_handlers = [] class << self def exception_handlers @@exception_handlers end def included(base) base.extend(ClassMethods) observer = Proc.new do |test_case, _, _, value, method_name| if value @@exception_handlers.unshift(method_name) else @@exception_handlers.delete(method_name) end end base.register_attribute_observer(:exception_handler, &observer) end end module ClassMethods def exception_handlers ExceptionHandler.exception_handlers end # @overload exception_handler(method_name) # Add an exception handler method. # # @param method_name [Symbol] # The method name that handles exception raised in tests. # @return [void] # # @overload exception_handler(&callback) # Add an exception handler. # # @yield [test, exception] # Gives the test and the exception. # @yieldparam test [Test::Unit::TestCase] # The test where the exception is raised. # @yieldparam exception [Exception] # The exception that is raised in running the test. # @yieldreturn [Boolean] # Whether the handler handles the exception or not. # The handler must return _true_ if the handler handles # test exception, _false_ otherwise. # @return [void] # # This is a public API for developers who extend test-unit. def exception_handler(*method_name_or_handlers, &block) if block_given? exception_handlers.unshift(block) else method_name_or_handlers.each do |method_name_or_handler| if method_name_or_handler.respond_to?(:call) handler = method_name_or_handler exception_handlers.unshift(handler) else method_name = method_name_or_handler attribute(:exception_handler, true, {}, method_name) end end end end def unregister_exception_handler(*method_name_or_handlers) method_name_or_handlers.each do |method_name_or_handler| if method_name_or_handler.respond_to?(:call) handler = method_name_or_handler exception_handlers.delete(handler) else method_name = method_name_or_handler attribute(:exception_handler, false, {}, method_name) end end end end end end end test-unit-3.3.9/lib/test/unit/ui/0000755000004100000410000000000013775322563016650 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/ui/xml/0000755000004100000410000000000013775322563017450 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/ui/xml/testrunner.rb0000644000004100000410000001575513775322563022223 0ustar www-datawww-data#-- # # Author:: Kouhei Sutou # Copyright:: # * Copyright (c) 2011 Kouhei Sutou # License:: Ruby license. require 'erb' require 'time' require 'test/unit/ui/testrunner' require 'test/unit/ui/testrunnermediator' module Test module Unit module UI module XML # Runs a Test::Unit::TestSuite and outputs XML. class TestRunner < UI::TestRunner include ERB::Util # Creates a new TestRunner for running the passed # suite. :output option specifies where runner # output should go to; defaults to STDOUT. def initialize(suite, options={}) super @output = @options[:output] || STDOUT if @options[:output_file_descriptor] @output = IO.new(@options[:output_file_descriptor], "w") end @already_outputted = false @indent = 0 @top_level = true @current_test = nil @current_test_suite = nil @already_outputted = false end private def attach_to_mediator @mediator.add_listener(TestResult::PASS_ASSERTION, &method(:result_pass_assertion)) @mediator.add_listener(TestResult::FAULT, &method(:result_fault)) @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) @mediator.add_listener(TestCase::STARTED_OBJECT, &method(:test_started)) @mediator.add_listener(TestCase::FINISHED_OBJECT, &method(:test_finished)) @mediator.add_listener(TestSuite::STARTED_OBJECT, &method(:test_suite_started)) @mediator.add_listener(TestSuite::FINISHED_OBJECT, &method(:test_suite_finished)) end def result_pass_assertion(result) open_tag("pass-assertion") do output_test(@current_test) end end def result_fault(fault) open_tag("test-result") do open_tag("result") do output_test_suite(@current_test_suite) output_test(@current_test) open_tag("backtrace") do fault.location.each do |entry| file, line, info = entry.split(/:/, 3) open_tag("entry") do add_content("file", file) add_content("line", line) add_content("info", info) end end end if fault.respond_to?(:expected) add_content("expected", fault.expected) end if fault.respond_to?(:actual) add_content("actual", fault.actual) end add_content("detail", fault.message) add_content("status", fault.label.downcase) end end @already_outputted = true if fault.critical? end def started(result) @result = result output_started end def output_started open_tag("stream") end def finished(elapsed_time) add_content("success", @result.passed?) close_tag("stream") end def test_started(test) @already_outputted = false @current_test = test open_tag("start-test") do output_test(test) end end def test_finished(test) unless @already_outputted open_tag("test-result") do output_test(test) open_tag("result") do output_test_suite(@current_test_suite) output_test(test) add_content("status", "success") end end end open_tag("complete-test") do output_test(test) add_content("success", test.passed?) end @current_test = nil end def test_suite_started(suite) @current_test_suite = suite if suite.test_case.nil? open_tag("ready-test-suite") do add_content("n-tests", suite.size) end open_tag("start-test-suite") do output_test_suite(suite) end else open_tag("ready-test-case") do output_test_suite(suite) add_content("n-tests", suite.size) end open_tag("start-test-case") do output_test_suite(suite) end end end def test_suite_finished(suite) if suite.test_case.nil? open_tag("complete-test-suite") do output_test_suite(suite) add_content("success", suite.passed?) end else open_tag("complete-test-case") do output_test_suite(suite) add_content("success", suite.passed?) end end @current_test_suite = nil end def indent " " * @indent end def open_tag(name) @output.puts("#{indent}<#{name}>") @indent += 2 if block_given? yield close_tag(name) end end def add_content(name, content) return if content.nil? case content when Time content = content.iso8601 end @output.puts("#{indent}<#{name}>#{h(content)}") end def close_tag(name) @indent -= 2 @output.puts("#{indent}") end def output_test(test) open_tag("test") do add_content("name", test.method_name) add_content("start-time", test.start_time) add_content("elapsed", test.elapsed_time) end end def output_test_suite(test_suite) test_case = test_suite.test_case if test_case.nil? open_tag("test-suite") do add_content("name", test_suite.name) add_content("start-time", test_suite.start_time) add_content("elapsed", test_suite.elapsed_time) end else open_tag("test-case") do add_content("name", test_suite.name) add_content("start-time", test_suite.start_time) add_content("elapsed", test_suite.elapsed_time) end end end end end end end end test-unit-3.3.9/lib/test/unit/ui/testrunnerutilities.rb0000644000004100000410000000204413775322563023342 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. module Test module Unit module UI # Provides some utilities common to most, if not all, # TestRunners. # #-- # # Perhaps there ought to be a TestRunner superclass? There # seems to be a decent amount of shared code between test # runners. module TestRunnerUtilities # Creates a new TestRunner and runs the suite. def run(suite, options={}) return new(suite, options).start end # Takes care of the ARGV parsing and suite # determination necessary for running one of the # TestRunners from the command line. def start_command_line_test if ARGV.empty? puts "You should supply the name of a test suite file to the runner" exit end require ARGV[0].gsub(/.+::/, '') new(eval(ARGV[0])).start end end end end end test-unit-3.3.9/lib/test/unit/ui/console/0000755000004100000410000000000013775322563020312 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/ui/console/testrunner.rb0000644000004100000410000005616313775322563023063 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: # * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # * Copyright (c) 2008-2017 Kouhei Sutou # License:: Ruby license. begin require 'io/console' rescue LoadError end require 'test/unit/color-scheme' require 'test/unit/code-snippet-fetcher' require 'test/unit/fault-location-detector' require 'test/unit/diff' require 'test/unit/ui/testrunner' require 'test/unit/ui/testrunnermediator' require 'test/unit/ui/console/outputlevel' module Test module Unit module UI module Console # Runs a Test::Unit::TestSuite on the console. class TestRunner < UI::TestRunner include OutputLevel # Creates a new TestRunner for running the passed # suite. If quiet_mode is true, the output while # running is limited to progress dots, errors and # failures, and the final result. io specifies # where runner output should go to; defaults to # STDOUT. def initialize(suite, options={}) super @output_level = @options[:output_level] || NORMAL @output = @options[:output] || STDOUT @use_color = @options[:use_color] @use_color = guess_color_availability if @use_color.nil? @color_scheme = @options[:color_scheme] || ColorScheme.default @reset_color = Color.new("reset") @progress_row = 0 @progress_row_max = @options[:progress_row_max] @progress_row_max ||= guess_progress_row_max @show_detail_immediately = @options[:show_detail_immediately] @show_detail_immediately = true if @show_detail_immediately.nil? @already_outputted = false @indent = 0 @top_level = true @current_output_level = NORMAL @faults = [] @code_snippet_fetcher = CodeSnippetFetcher.new @test_suites = [] end private def change_output_level(level) old_output_level = @current_output_level @current_output_level = level yield @current_output_level = old_output_level end def setup_mediator super output_setup_end end def output_setup_end suite_name = @suite.to_s suite_name = @suite.name if @suite.kind_of?(Module) output("Loaded suite #{suite_name}") end def attach_to_mediator @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) @mediator.add_listener(TestCase::STARTED_OBJECT, &method(:test_started)) @mediator.add_listener(TestCase::FINISHED_OBJECT, &method(:test_finished)) @mediator.add_listener(TestSuite::STARTED_OBJECT, &method(:test_suite_started)) @mediator.add_listener(TestSuite::FINISHED_OBJECT, &method(:test_suite_finished)) end def add_fault(fault) @faults << fault output_progress(fault.single_character_display, fault_marker_color(fault)) output_progress_in_detail(fault) if @show_detail_immediately @already_outputted = true if fault.critical? end def started(result) @result = result output_started end def output_started output("Started") end def finished(elapsed_time) unless @show_detail_immediately nl if output?(NORMAL) and !output?(VERBOSE) output_faults end nl(PROGRESS_ONLY) change_output_level(IMPORTANT_FAULTS_ONLY) do output_statistics(elapsed_time) end end def output_faults categorized_faults = categorize_faults change_output_level(IMPORTANT_FAULTS_ONLY) do output_faults_in_detail(categorized_faults[:need_detail_faults]) end output_faults_in_short("Omissions", Omission, categorized_faults[:omissions]) output_faults_in_short("Notifications", Notification, categorized_faults[:notifications]) end def max_digit(max_number) (Math.log10(max_number) + 1).truncate end def output_faults_in_detail(faults) return if faults.nil? digit = max_digit(faults.size) faults.each_with_index do |fault, index| nl output_single("%#{digit}d) " % (index + 1)) output_fault_in_detail(fault) end end def output_faults_in_short(label, fault_class, faults) return if faults.nil? digit = max_digit(faults.size) nl output_single(label, fault_class_color(fault_class)) output(":") faults.each_with_index do |fault, index| output_single("%#{digit}d) " % (index + 1)) output_fault_in_short(fault) end end def categorize_faults faults = {} @faults.each do |fault| category = categorize_fault(fault) faults[category] ||= [] faults[category] << fault end faults end def categorize_fault(fault) case fault when Omission :omissions when Notification :notifications else :need_detail_faults end end def output_fault_in_detail(fault) if fault.is_a?(Failure) and fault.inspected_expected and fault.inspected_actual output_single("#{fault.label}: ") output(fault.test_name, fault_color(fault)) output_fault_backtrace(fault) output_failure_message(fault) else output_single("#{fault.label}: ") output_single(fault.test_name, fault_color(fault)) output_fault_message(fault) output_fault_backtrace(fault) end end def output_fault_message(fault) message = fault.message return if message.nil? if message.include?("\n") output(":") message.each_line do |line| output(" #{line.chomp}") end else output(": #{message}") end end def output_fault_backtrace(fault) detector = FaultLocationDetector.new(fault, @code_snippet_fetcher) backtrace = fault.location # workaround for test-spec. :< # see also GitHub:#22 backtrace ||= [] code_snippet_backtrace_index = nil code_snippet_lines = nil backtrace.each_with_index do |entry, i| next unless detector.target?(entry) file, line_number, = detector.split_backtrace_entry(entry) lines = fetch_code_snippet(file, line_number) unless lines.empty? code_snippet_backtrace_index = i code_snippet_lines = lines break end end backtrace.each_with_index do |entry, i| output(entry) if i == code_snippet_backtrace_index output_code_snippet(code_snippet_lines, fault_color(fault)) end end end def fetch_code_snippet(file, line_number) @code_snippet_fetcher.fetch(file, line_number) end def output_code_snippet(lines, target_line_color=nil) max_n = lines.collect {|n, line, attributes| n}.max digits = (Math.log10(max_n) + 1).truncate lines.each do |n, line, attributes| if attributes[:target_line?] line_color = target_line_color current_line_mark = "=>" else line_color = nil current_line_mark = "" end output(" %2s %*d: %s" % [current_line_mark, digits, n, line], line_color) end end def output_failure_message(failure) if failure.expected.respond_to?(:encoding) and failure.actual.respond_to?(:encoding) and failure.expected.encoding != failure.actual.encoding need_encoding = true else need_encoding = false end output(failure.user_message) if failure.user_message output_single("<") output_single(failure.inspected_expected, color("pass")) output_single(">") if need_encoding output_single("(") output_single(failure.expected.encoding.name, color("pass")) output_single(")") end output(" expected but was") output_single("<") output_single(failure.inspected_actual, color("failure")) output_single(">") if need_encoding output_single("(") output_single(failure.actual.encoding.name, color("failure")) output_single(")") end output("") from, to = prepare_for_diff(failure.expected, failure.actual) if from and to if need_encoding unless from.valid_encoding? from = from.dup.force_encoding("ASCII-8BIT") end unless to.valid_encoding? to = to.dup.force_encoding("ASCII-8BIT") end end from_lines = from.split(/\r?\n/) to_lines = to.split(/\r?\n/) if need_encoding from_lines << "" to_lines << "" from_lines << "Encoding: #{failure.expected.encoding.name}" to_lines << "Encoding: #{failure.actual.encoding.name}" end differ = ColorizedReadableDiffer.new(from_lines, to_lines, self) if differ.need_diff? output("") output("diff:") differ.diff end end end def output_fault_in_short(fault) output_single("#{fault.label}: ") output_single(fault.message, fault_color(fault)) output(" [#{fault.test_name}]") output(fault.location.first) end def format_fault(fault) fault.long_display end def output_statistics(elapsed_time) output("Finished in #{elapsed_time} seconds.") output_summary_marker output(@result) output("%g%% passed" % @result.pass_percentage) unless elapsed_time.zero? output_summary_marker test_throughput = @result.run_count / elapsed_time assertion_throughput = @result.assertion_count / elapsed_time throughput = [ "%.2f tests/s" % test_throughput, "%.2f assertions/s" % assertion_throughput, ] output(throughput.join(", ")) end end def output_summary_marker if @progress_row_max > 0 output("-" * @progress_row_max, summary_marker_color) else nl end end def test_started(test) return unless output?(VERBOSE) tab_width = 8 name = test.local_name separator = ":" left_used = indent.size + name.size + separator.size right_space = tab_width * 2 left_space = @progress_row_max - right_space if (left_used % tab_width).zero? left_space -= left_used n_tabs = 0 else left_space -= ((left_used / tab_width) + 1) * tab_width n_tabs = 1 end n_tabs += [left_space, 0].max / tab_width tab_stop = "\t" * n_tabs output_single("#{indent}#{name}#{separator}#{tab_stop}", nil, VERBOSE) @test_start = Time.now end def test_finished(test) unless @already_outputted output_progress(".", color("pass-marker")) end @already_outputted = false return unless output?(VERBOSE) output(": (%f)" % (Time.now - @test_start), nil, VERBOSE) end def suite_name(prefix, suite) name = suite.name if name.nil? "(anonymous)" else name.sub(/\A#{Regexp.escape(prefix)}/, "") end end def test_suite_started(suite) last_test_suite = @test_suites.last @test_suites << suite if @top_level @top_level = false return end output_single(indent, nil, VERBOSE) if suite.test_case.nil? _color = color("suite") else _color = color("case") end prefix = "#{last_test_suite.name}::" output_single(suite_name(prefix, suite), _color, VERBOSE) output(": ", nil, VERBOSE) @indent += 2 end def test_suite_finished(suite) @indent -= 2 @test_suites.pop end def indent if output?(VERBOSE) " " * @indent else "" end end def nl(level=nil) output("", nil, level) end def output(something, color=nil, level=nil) return unless output?(level) output_single(something, color, level) @output.puts end def output_single(something, color=nil, level=nil) return false unless output?(level) if @use_color and color something = "%s%s%s" % [color.escape_sequence, something, @reset_color.escape_sequence] end @output.write(something) @output.flush true end def output_progress(mark, color=nil) if output_single(mark, color, PROGRESS_ONLY) return unless @progress_row_max > 0 @progress_row += mark.size if @progress_row >= @progress_row_max nl unless @output_level == VERBOSE @progress_row = 0 end end end def output_progress_in_detail_marker(fault) if @progress_row_max > 0 output("=" * @progress_row_max) else nl end end def output_progress_in_detail(fault) return if @output_level == SILENT nl output_progress_in_detail_marker(fault) if categorize_fault(fault) == :need_detail_faults output_fault_in_detail(fault) else output_fault_in_short(fault) end output_progress_in_detail_marker(fault) @progress_row = 0 end def output?(level) (level || @current_output_level) <= @output_level end def color(name) _color = @color_scheme[name] _color ||= @color_scheme["success"] if name == "pass" _color ||= ColorScheme.default[name] _color end def fault_class_color_name(fault_class) fault_class.name.split(/::/).last.downcase end def fault_class_color(fault_class) color(fault_class_color_name(fault_class)) end def fault_color(fault) fault_class_color(fault.class) end def fault_marker_color(fault) color("#{fault_class_color_name(fault.class)}-marker") end def summary_marker_color color("#{@result.status}-marker") end TERM_COLOR_SUPPORT = / color| # explicitly claims color support in the name direct| # explicitly claims "direct color" (24 bit) support #{ColorScheme::TERM_256}| \Acygwin| \Alinux| \Ansterm-bce| \Ansterm-c-| \Aputty| \Arxvt| \Ascreen| \Atmux| \Axterm /x def guess_color_availability return false unless @output.tty? return true if windows? and ruby_2_0_or_later? case ENV["TERM"] when /(?:term|screen)(?:-(?:256)?color)?\z/ true when TERM_COLOR_SUPPORT true else return true if ENV["EMACS"] == "t" false end end def windows? /mswin|mingw/ === RUBY_PLATFORM end def ruby_2_0_or_later? RUBY_VERSION >= "2.0.0" end def guess_progress_row_max term_width = guess_term_width if term_width.zero? if ENV["EMACS"] == "t" -1 else 79 end else term_width end end def guess_term_width guess_term_width_from_io || guess_term_width_from_env || 0 end def guess_term_width_from_io if @output.respond_to?(:winsize) begin @output.winsize[1] rescue SystemCallError nil end else nil end end def guess_term_width_from_env env = ENV["COLUMNS"] || ENV["TERM_WIDTH"] return nil if env.nil? begin Integer(env) rescue ArgumentError nil end end end class ColorizedReadableDiffer < Diff::ReadableDiffer def initialize(from, to, runner) @runner = runner super(from, to) end def need_diff?(options={}) return false if one_line_all_change? operations.each do |tag,| return true if [:replace, :equal].include?(tag) end false end private def one_line_all_change? return false if operations.size != 1 tag, from_start, from_end, to_start, to_end = operations.first return false if tag != :replace return false if [from_start, from_end] != [0, 1] return false if [from_start, from_end] != [to_start, to_end] _, _, _line_operations = line_operations(@from.first, @to.first) _line_operations.size == 1 end def output_single(something, color=nil) @runner.__send__(:output_single, something, color) end def output(something, color=nil) @runner.__send__(:output, something, color) end def color(name) @runner.__send__(:color, name) end def cut_off_ratio 0 end def default_ratio 0 end def tag(mark, color_name, contents) _color = color(color_name) contents.each do |content| output_single(mark, _color) output_single(" ") output(content) end end def tag_deleted(contents) tag("-", "diff-deleted-tag", contents) end def tag_inserted(contents) tag("+", "diff-inserted-tag", contents) end def tag_equal(contents) tag(" ", "normal", contents) end def tag_difference(contents) tag("?", "diff-difference-tag", contents) end def diff_line(from_line, to_line) to_operations = [] from_line, to_line, _operations = line_operations(from_line, to_line) no_replace = true _operations.each do |tag,| if tag == :replace no_replace = false break end end output_single("?", color("diff-difference-tag")) output_single(" ") _operations.each do |tag, from_start, from_end, to_start, to_end| from_width = compute_width(from_line, from_start, from_end) to_width = compute_width(to_line, to_start, to_end) case tag when :replace output_single(from_line[from_start...from_end], color("diff-deleted")) if (from_width < to_width) output_single(" " * (to_width - from_width)) end to_operations << Proc.new do output_single(to_line[to_start...to_end], color("diff-inserted")) if (to_width < from_width) output_single(" " * (from_width - to_width)) end end when :delete output_single(from_line[from_start...from_end], color("diff-deleted")) unless no_replace to_operations << Proc.new {output_single(" " * from_width)} end when :insert if no_replace output_single(to_line[to_start...to_end], color("diff-inserted")) else output_single(" " * to_width) to_operations << Proc.new do output_single(to_line[to_start...to_end], color("diff-inserted")) end end when :equal output_single(from_line[from_start...from_end]) unless no_replace to_operations << Proc.new {output_single(" " * to_width)} end else raise "unknown tag: #{tag}" end end output("") unless to_operations.empty? output_single("?", color("diff-difference-tag")) output_single(" ") to_operations.each do |operation| operation.call end output("") end end end end end end end test-unit-3.3.9/lib/test/unit/ui/console/outputlevel.rb0000644000004100000410000000040013775322563023221 0ustar www-datawww-datamodule Test module Unit module UI module Console module OutputLevel SILENT = 0 PROGRESS_ONLY = 1 IMPORTANT_FAULTS_ONLY = 2 NORMAL = 3 VERBOSE = 4 end end end end end test-unit-3.3.9/lib/test/unit/ui/testrunnermediator.rb0000644000004100000410000000651613775322563023143 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/util/observable' require 'test/unit/testresult' module Test module Unit module UI # Provides an interface to write any given UI against, # hopefully making it easy to write new UIs. class TestRunnerMediator RESET = name + "::RESET" STARTED = name + "::STARTED" FINISHED = name + "::FINISHED" include Util::Observable # Creates a new TestRunnerMediator initialized to run # the passed suite. def initialize(suite) @suite = suite end # Runs the suite the TestRunnerMediator was created # with. def run AutoRunner.need_auto_run = false result = create_result Test::Unit.run_at_start_hooks start_time = Time.now begin catch do |stop_tag| result.stop_tag = stop_tag with_listener(result) do notify_listeners(RESET, @suite.size) notify_listeners(STARTED, result) run_suite(result) end end ensure elapsed_time = Time.now - start_time notify_listeners(FINISHED, elapsed_time) end Test::Unit.run_at_exit_hooks result end # Just for backward compatibility for NetBeans. # NetBeans should not use monkey patching. NetBeans # should use runner change public API. # # See GitHub#38 # https://github.com/test-unit/test-unit/issues/38 def run_suite(result=nil) if result.nil? run else @suite.run(result) do |channel, value| notify_listeners(channel, value) end end end private # A factory method to create the result the mediator # should run with. Can be overridden by subclasses if # one wants to use a different result. def create_result TestResult.new end def measure_time begin_time = Time.now yield Time.now - begin_time end def with_listener(result) finished_listener = result.add_listener(TestResult::FINISHED) do |*args| notify_listeners(TestResult::FINISHED, *args) end changed_listener = result.add_listener(TestResult::CHANGED) do |*args| notify_listeners(TestResult::CHANGED, *args) end pass_assertion_listener = result.add_listener(TestResult::PASS_ASSERTION) do |*args| notify_listeners(TestResult::PASS_ASSERTION, *args) end fault_listener = result.add_listener(TestResult::FAULT) do |*args| notify_listeners(TestResult::FAULT, *args) end begin yield ensure result.remove_listener(TestResult::FAULT, fault_listener) result.remove_listener(TestResult::CHANGED, changed_listener) result.remove_listener(TestResult::FINISHED, finished_listener) result.remove_listener(TestResult::PASS_ASSERTION, pass_assertion_listener) end end end end end end test-unit-3.3.9/lib/test/unit/ui/testrunner.rb0000644000004100000410000000224513775322563021411 0ustar www-datawww-datarequire 'test/unit/ui/testrunnerutilities' module Test module Unit module UI class TestRunner extend TestRunnerUtilities attr_reader :listeners def initialize(suite, options={}) if suite.respond_to?(:suite) @suite = suite.suite else @suite = suite end @options = options @listeners = @options[:listeners] || [] end # Begins the test run. def start setup_mediator attach_to_mediator attach_listeners start_mediator end private def setup_mediator @mediator = TestRunnerMediator.new(@suite) end def attach_listeners @listeners.each do |listener| listener.attach_to_mediator(@mediator) end end def start_mediator @mediator.run end def diff_target_string?(string) Assertions::AssertionMessage.diff_target_string?(string) end def prepare_for_diff(from, to) Assertions::AssertionMessage.prepare_for_diff(from, to) end end end end end test-unit-3.3.9/lib/test/unit/ui/emacs/0000755000004100000410000000000013775322563017740 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/ui/emacs/testrunner.rb0000644000004100000410000000253213775322563022500 0ustar www-datawww-datarequire 'test/unit/ui/console/testrunner' module Test module Unit module UI module Emacs class TestRunner < Console::TestRunner private def output_setup_end end def output_started end def format_fault(fault) return super unless fault.respond_to?(:label) format_method_name = "format_fault_#{fault.label.downcase}" if respond_to?(format_method_name, true) __send__(format_method_name, fault) else super end end def format_fault_failure(failure) if failure.location.size == 1 location = failure.location[0] location_display = location.sub(/\A(.+:\d+).*/, ' [\\1]') else location_display = "\n" + failure.location.join("\n") end result = "#{failure.label}:\n" result += "#{failure.test_name}#{location_display}:\n" result += failure.message result end def format_fault_error(error) result = "#{error.label}:\n" result += "#{error.test_name}:\n" result += "#{error.message}\n" result += error.backtrace.join("\n") result end end end end end end test-unit-3.3.9/lib/test/unit/assertion-failed-error.rb0000644000004100000410000000135413775322563023143 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. module Test module Unit # Thrown by Test::Unit::Assertions when an assertion fails. class AssertionFailedError < StandardError attr_accessor :expected, :actual, :user_message attr_accessor :inspected_expected, :inspected_actual def initialize(message=nil, options=nil) options ||= {} @expected = options[:expected] @actual = options[:actual] @inspected_expected = options[:inspected_expected] @inspected_actual = options[:inspected_actual] @user_message = options[:user_message] super(message) end end end end test-unit-3.3.9/lib/test/unit/assertions.rb0000644000004100000410000022447513775322563020770 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # Copyright (c) 2009-2013 Kouhei Sutou. All rights reserved. # License:: Ruby license. require 'test/unit/assertion-failed-error' require 'test/unit/util/backtracefilter' require 'test/unit/util/method-owner-finder' require 'test/unit/diff' begin require 'power_assert' rescue LoadError, SyntaxError end module Test module Unit ## # Test::Unit::Assertions contains the standard Test::Unit assertions. # Assertions is included in Test::Unit::TestCase. # # To include it in your own code and use its functionality, you simply # need to rescue Test::Unit::AssertionFailedError. Additionally you may # override add_assertion to get notified whenever an assertion is made. # # Notes: # # * The message to each assertion, if given, will be propagated with the # failure. # * It is easy to add your own assertions based on assert_block(). # # @example Example Custom Assertion # # def deny(boolean, message=nil) # message = build_message(message, ' is not false or nil.', boolean) # assert_block(message) do # not boolean # end # end module Assertions ## # The assertion upon which all other assertions are based. Passes if the # block yields true. # # @example # assert_block "Couldn't do the thing" do # do_the_thing # end def assert_block(message="assert_block failed.") _wrap_assertion do if (! yield) options = {} if message.respond_to?(:user_message) options[:user_message] = message.user_message end raise AssertionFailedError.new(message.to_s, options) end end end # @private NOT_SPECIFIED = Object.new # @overload assert(object, message=nil) # # Asserts that `object` is not false nor nil. # # Normally, you don't need to use this assertion. Use more # specific assertions such as #assert_equal and # #assert_include. # # @example Pass patterns # assert(true) # => pass # assert([1, 2].include?(1)) # => pass # # @example Failure patterns # assert(nil) # => failure # assert(false) # => failure # assert([1, 2].include?(5)) # => failure # # @param [Object] object The check target. # @param [String] message The additional user message. It is # showed when the assertion is failed. # @return [void] # # @overload assert(message=nil) {} # # Asserts that the givens block returns not false nor nil. # # This style uses Power Assert. It means that you can see each # object values in method chains on failure. See the following # example about Power Assert. # # @example Power Assert # coins = [1, 5, 50] # target_coin = 10 # assert do # coins.include?(target_coin) # end # # => # # coins.include?(target_coin) # # | | | # # | | 10 # # | false # # [1, 5, 50] # # We recommend you to use Power Assert for predicate method # checks rather than existing assertions such as # #assert_include and #assert_predicate. Power Assert shows # useful message for debugging. # # We don't recommend you use Power Assert for equality # check. You should use #assert_equal for the case. Because # #assert_equal shows more useful message for debugging. # # @example Pass patterns # assert {true} # => pass # assert {[1, 2].include?(1)} # => pass # # @example Failure patterns # assert {nil} # => failure # assert {false} # => failure # assert {[1, 2].include?(5)} # => failure # # @param [String] message The additional user message. It is # showed when the assertion is failed. # @yield [] Given no parameters to the block. # @yieldreturn [Object] The checked object. # @return [void] def assert(object=NOT_SPECIFIED, message=nil, &block) _wrap_assertion do have_object = !NOT_SPECIFIED.equal?(object) if block message = object if have_object if defined?(PowerAssert) PowerAssert.start(block, :assertion_method => __callee__) do |pa| pa_message = AssertionMessage.delayed_literal(&pa.message_proc) assertion_message = build_message(message, "?", pa_message) assert_block(assertion_message) do pa.yield end end else assert(yield, message) end else unless have_object raise ArgumentError, "wrong number of arguments (0 for 1..2)" end assertion_message = nil case message when nil, String, Proc when AssertionMessage assertion_message = message else error_message = "assertion message must be String, Proc or " error_message += "#{AssertionMessage}: " error_message += "<#{message.inspect}>(<#{message.class}>)" raise ArgumentError, error_message, filter_backtrace(caller) end assertion_message ||= build_message(message, " is not true.", object) assert_block(assertion_message) do object end end end end # Asserts that `object` is false or nil. # # @note Just for minitest compatibility. :< # # @param [Object] object The object to be asserted. # @return [void] # # @example Pass patterns # refute(false) # => pass # refute(nil) # => pass # # @example Failure patterns # refute(true) # => failure # refute("string") # => failure # # @since 2.5.3 def refute(object, message=nil) _wrap_assertion do assertion_message = nil case message when nil, String, Proc when AssertionMessage assertion_message = message else error_message = "assertion message must be String, Proc or " error_message += "#{AssertionMessage}: " error_message += "<#{message.inspect}>(<#{message.class}>)" raise ArgumentError, error_message, filter_backtrace(caller) end assert_block("refute should not be called with a block.") do !block_given? end assertion_message ||= build_message(message, " is neither nil or false.", object) assert_block(assertion_message) do not object end end end ## # Passes if `expected` == `actual`. # # Note that the ordering of arguments is important, since a helpful # error message is generated when this one fails that tells you the # values of expected and actual. # # @example # assert_equal 'MY STRING', 'my string'.upcase def assert_equal(expected, actual, message=nil) diff = AssertionMessage.delayed_diff(expected, actual) if expected.respond_to?(:encoding) and actual.respond_to?(:encoding) and expected.encoding != actual.encoding format = <(?) expected but was (?).? EOT full_message = build_message(message, format, expected, expected.encoding.name, actual, actual.encoding.name, diff) else full_message = build_message(message, < expected but was .? EOT end begin assert_block(full_message) { expected == actual } rescue AssertionFailedError => failure _set_failed_information(failure, expected, actual) raise failure # For JRuby. :< end end ## # Passes if the block raises one of the expected # exceptions. When an expected exception is an Exception # object, passes if expected_exception == actual_exception. # # @example # assert_raise(RuntimeError, LoadError) do # raise 'Boom!!!' # end # -> pass # # assert_raise do # raise Exception, 'Any exception should be raised!!!' # end # -> pass # # assert_raise(RuntimeError.new("XXX")) {raise "XXX"} # -> pass # assert_raise(MyError.new("XXX")) {raise "XXX"} # -> fail # assert_raise(RuntimeError.new("ZZZ")) {raise "XXX"} # -> fail def assert_raise(*args, &block) assert_expected_exception = Proc.new do |*_args| message, assert_exception_helper, actual_exception = _args expected = assert_exception_helper.expected_exceptions diff = AssertionMessage.delayed_diff(expected, actual_exception) full_message = build_message(message, " exception expected but was\n.?", expected, actual_exception, diff) begin assert_block(full_message) do expected == [] or assert_exception_helper.expected?(actual_exception) end rescue AssertionFailedError => failure _set_failed_information(failure, expected, actual_exception) raise failure # For JRuby. :< end end _assert_raise(assert_expected_exception, *args, &block) end # Just for minitest compatibility. :< alias_method :assert_raises, :assert_raise ## # Passes if the block raises one of the given # exceptions or sub exceptions of the given exceptions. # # @example # assert_raise_kind_of(SystemCallError) do # raise Errno::EACCES # end def assert_raise_kind_of(*args, &block) assert_expected_exception = Proc.new do |*_args| message, assert_exception_helper, actual_exception = _args expected = assert_exception_helper.expected_exceptions full_message = build_message(message, " family exception expected " + "but was\n.", expected, actual_exception) assert_block(full_message) do assert_exception_helper.expected?(actual_exception, :kind_of?) end end _assert_raise(assert_expected_exception, *args, &block) end ## # Passes if `object`.instance_of?(`klass`). When `klass` is # an array of classes, it passes if any class # satisfies +object.instance_of?(class). # # @example # assert_instance_of(String, 'foo') # -> pass # assert_instance_of([Fixnum, NilClass], 100) # -> pass # assert_instance_of([Numeric, NilClass], 100) # -> fail def assert_instance_of(klass, object, message=nil) _wrap_assertion do if klass.is_a?(Array) klasses = klass else klasses = [klass] end assert_block("The first parameter to assert_instance_of should be " + "a Class or an Array of Class.") do klasses.all? {|k| k.is_a?(Class)} end klass_message = AssertionMessage.maybe_container(klass) do |value| "<#{value}>" end full_message = build_message(message, < was expected to be instance_of\\? ? but was . EOT assert_block(full_message) do klasses.any? {|k| object.instance_of?(k)} end end end ## # Passes if `object`.instance_of?(`klass`) does not hold. # When `klass` is an array of classes, it passes if no class # satisfies +object.instance_of?(class). # # @example # assert_not_instance_of(String, 100) # -> pass # assert_not_instance_of([Fixnum, NilClass], '100') # -> pass # assert_not_instance_of([Numeric, NilClass], 100) # -> fail # # @since 3.0.0 def assert_not_instance_of(klass, object, message=nil) _wrap_assertion do if klass.is_a?(Array) klasses = klass else klasses = [klass] end assert_block("The first parameter to assert_not_instance_of should be " + "a Class or an Array of Class.") do klasses.all? {|k| k.is_a?(Class)} end klass_message = AssertionMessage.maybe_container(klass) do |value| "<#{value}>" end full_message = build_message(message, " was expected to not be instance_of\\?\n" + "? but was.", object, klass_message) assert_block(full_message) do klasses.none? {|k| object.instance_of?(k)} end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_instance_of, :assert_not_instance_of ## # Passes if `object` is nil. # # @example # assert_nil [1, 2].uniq! def assert_nil(object, message=nil) full_message = build_message(message, < was expected to be nil. EOT assert_block(full_message) { object.nil? } end ## # Passes if `object`.kind_of?(`klass`). When `klass` is # an array of classes or modules, it passes if any # class or module satisfies +object.kind_of?(class_or_module). # # @example # assert_kind_of(Object, 'foo') # -> pass # assert_kind_of([Fixnum, NilClass], 100) # -> pass # assert_kind_of([Fixnum, NilClass], "string") # -> fail def assert_kind_of(klass, object, message=nil) _wrap_assertion do if klass.is_a?(Array) klasses = klass else klasses = [klass] end assert_block("The first parameter to assert_kind_of should be " + "a kind_of Module or an Array of a kind_of Module.") do klasses.all? {|k| k.kind_of?(Module)} end klass_message = AssertionMessage.maybe_container(klass) do |value| "<#{value}>" end full_message = build_message(message, " was expected to be kind_of\\?\n" + "? but was\n" + ".", object, klass_message, object.class) assert_block(full_message) do klasses.any? {|k| object.kind_of?(k)} end end end ## # Passes if `object`.kind_of?(`klass`) does not hold. # When `klass` is an array of classes or modules, it passes only if all # classes (and modules) do not satisfy +object.kind_of?(class_or_module). # # @example # assert_not_kind_of(Fixnum, 'foo') # -> pass # assert_not_kind_of([Fixnum, NilClass], '0') # -> pass # assert_not_kind_of([Fixnum, NilClass], 100) # -> fail # # @since 3.0.0 def assert_not_kind_of(klass, object, message=nil) _wrap_assertion do if klass.is_a?(Array) klasses = klass else klasses = [klass] end assert_block("The first parameter to assert_not_kind_of should be " + "a kind_of Module or an Array of a kind_of Module.") do klasses.all? {|k| k.kind_of?(Module)} end klass_message = AssertionMessage.maybe_container(klass) do |value| "<#{value}>" end full_message = build_message(message, " was expected to not be kind_of\\?\n" + "? but was.", object, klass_message) assert_block(full_message) do klasses.none? {|k| object.kind_of?(k)} end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_kind_of, :assert_not_kind_of ## # Passes if `object` .respond_to? `method` # # @example # assert_respond_to 'bugbear', :slice def assert_respond_to(object, method, message=nil) _wrap_assertion do full_message = build_message(message, ".kind_of\\?(Symbol) or\n" + ".respond_to\\?(:to_str) expected", method, method) assert_block(full_message) do method.kind_of?(Symbol) or method.respond_to?(:to_str) end full_message = build_message(message, ".respond_to\\?(?) expected\n" + "(Class: )", object, method, object.class) assert_block(full_message) {object.respond_to?(method)} end end ## # Passes if `object` does not .respond_to? `method`. # # @example # assert_not_respond_to('bugbear', :nonexistence) # -> pass # assert_not_respond_to('bugbear', :size) # -> fail def assert_not_respond_to(object, method, message=nil) _wrap_assertion do full_message = build_message(message, ".kind_of\\?(Symbol) or\n" + ".respond_to\\?(:to_str) expected", method, method) assert_block(full_message) do method.kind_of?(Symbol) or method.respond_to?(:to_str) end full_message = build_message(message, "!.respond_to\\?(?) expected\n" + "(Class: )", object, method, object.class) assert_block(full_message) {!object.respond_to?(method)} end end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_respond_to, :assert_not_respond_to ## # Passes if `pattern` =~ `string`. # # @example # assert_match(/\d+/, 'five, 6, seven') def assert_match(pattern, string, message=nil) _wrap_assertion do pattern = Regexp.new(Regexp.escape(pattern)) if pattern.is_a?(String) full_message = build_message(message, " was expected to be =~\n.", pattern, string) assert_block(full_message) { pattern =~ string } end end ## # Passes if `actual` .equal? `expected` (i.e. they are the same # instance). # # @example # o = Object.new # assert_same o, o def assert_same(expected, actual, message=nil) full_message = build_message(message, < with id was expected to be equal\\? to with id . EOT assert_block(full_message) { actual.equal?(expected) } end ## # Compares the `object1` with `object2` using `operator`. # # Passes if object1.__send__(operator, object2) is true. # # @example # assert_operator 5, :>=, 4 def assert_operator(object1, operator, object2, message=nil) _wrap_assertion do full_message = build_message(nil, "\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\?(:to_str).", operator) assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)} full_message = build_message(message, < was expected to be ? . EOT assert_block(full_message) { object1.__send__(operator, object2) } end end ## # Compares the `object1` with `object2` using `operator`. # # Passes if object1.__send__(operator, object2) is not true. # # @example # assert_not_operator(5, :<, 4) # => pass # assert_not_operator(5, :>, 4) # => fail # # @since 3.0.0 def assert_not_operator(object1, operator, object2, message=nil) _wrap_assertion do full_message = build_message(nil, "\ngiven as the operator for #assert_not_operator must be a Symbol or #respond_to\\?(:to_str).", operator) assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)} full_message = build_message(message, < was expected to not be ? . EOT assert_block(full_message) { ! object1.__send__(operator, object2) } end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_operator, :assert_not_operator ## # Passes if block does not raise an exception. # # @example # assert_nothing_raised do # [1, 2].uniq # end def assert_nothing_raised(*args) _wrap_assertion do if args.last.is_a?(String) message = args.pop else message = "" end assert_exception_helper = AssertExceptionHelper.new(self, args) begin yield rescue Exception => e if ((args.empty? && !e.instance_of?(AssertionFailedError)) || assert_exception_helper.expected?(e)) failure_message = build_message(message, "Exception raised:\n?", e) assert_block(failure_message) {false} else raise end end end end ## # Flunk always fails. # # @example # flunk 'Not done testing yet.' def flunk(message="Flunked") assert_block(build_message(message)){false} end ## # Passes if ! `actual` .equal? `expected` # # @example # assert_not_same Object.new, Object.new def assert_not_same(expected, actual, message=nil) full_message = build_message(message, < with id was expected to not be equal\\? to with id . EOT assert_block(full_message) { !actual.equal?(expected) } end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_same, :assert_not_same ## # Passes if `expected` != `actual` # # @example # assert_not_equal 'some string', 5 def assert_not_equal(expected, actual, message=nil) full_message = build_message(message, " was expected to be != to\n.", expected, actual) assert_block(full_message) { expected != actual } end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_equal, :assert_not_equal ## # Passes if ! `object` .nil? # # @example # assert_not_nil '1 two 3'.sub!(/two/, '2') def assert_not_nil(object, message=nil) full_message = build_message(message, " was expected to not be nil.", object) assert_block(full_message){!object.nil?} end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_nil, :assert_not_nil ## # Passes if `regexp` !~ `string` # # @example # assert_not_match(/two/, 'one 2 three') # -> pass # assert_not_match(/three/, 'one 2 three') # -> fail def assert_not_match(pattern, string, message=nil) _wrap_assertion do pattern = Regexp.new(Regexp.escape(pattern)) if pattern.is_a?(String) full_message = build_message(message, " was expected to not match\n.", pattern, string) assert_block(full_message) { pattern !~ string } end end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_match, :assert_not_match ## # Deprecated. Use #assert_not_match instead. # # Passes if `regexp` !~ `string` # # @example # assert_no_match(/two/, 'one 2 three') # -> pass # assert_no_match(/three/, 'one 2 three') # -> fail def assert_no_match(regexp, string, message="") _wrap_assertion do assert_instance_of(Regexp, regexp, "The first argument to assert_no_match " + "should be a Regexp.") assert_not_match(regexp, string, message) end end # @private class ThrowTagExtractor @@have_uncaught_throw_error = const_defined?(:UncaughtThrowError) UncaughtThrowPatterns = { NameError => /^uncaught throw `(.+)'$/, ArgumentError => /^uncaught throw (`.+'|.+)$/, ThreadError => /^uncaught throw `(.+)' in thread /, } def initialize(error) @error = error end def extract_tag tag = nil if @@have_uncaught_throw_error return nil unless @error.is_a?(UncaughtThrowError) tag = @error.tag else pattern = UncaughtThrowPatterns[@error.class] return nil if pattern.nil? return nil unless pattern =~ @error.message tag = $1 end normalize_tag(tag) end private def normalize_tag(tag) case tag when /\A:/ tag[1..-1].intern when /\A`(.+)'\z/ $1.intern when String tag.intern else tag end end end ## # Passes if the block throws `expected_object` # # @example # assert_throw(:done) do # throw(:done) # end def assert_throw(expected_object, message=nil, &proc) _wrap_assertion do begin catch([]) {} rescue TypeError assert_instance_of(Symbol, expected_object, "assert_throws expects the symbol that should be thrown for its first argument") end assert_block("Should have passed a block to assert_throw.") do block_given? end caught = true begin catch(expected_object) do proc.call caught = false end full_message = build_message(message, " should have been thrown.", expected_object) assert_block(full_message) {caught} rescue => error extractor = ThrowTagExtractor.new(error) tag = extractor.extract_tag raise if tag.nil? full_message = build_message(message, " was expected to be thrown but\n" + " was thrown.", expected_object, tag) flunk(full_message) end end end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :assert_throws, :assert_throw ## # Passes if block does not throw anything. # # @example # assert_nothing_thrown do # [1, 2].uniq # end def assert_nothing_thrown(message=nil, &proc) _wrap_assertion do assert(block_given?, "Should have passed a block to assert_nothing_thrown") begin proc.call rescue => error extractor = ThrowTagExtractor.new(error) tag = extractor.extract_tag raise if tag.nil? full_message = build_message(message, " was thrown when nothing was expected", tag) flunk(full_message) end assert(true, "Expected nothing to be thrown") end end ## # Passes if `expected_float` and `actual_float` are equal # within `delta` tolerance. # # @example # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 def assert_in_delta(expected_float, actual_float, delta=0.001, message="") _wrap_assertion do _assert_in_delta_validate_arguments(expected_float, actual_float, delta) full_message = _assert_in_delta_message(expected_float, actual_float, delta, message) assert_block(full_message) do (expected_float.to_f - actual_float.to_f).abs <= delta.to_f end end end ## # Passes if `expected_float` and `actual_float` are # not equal within `delta` tolerance. # # @example # assert_not_in_delta(0.05, (50000.0 / 10**6), 0.00002) # -> pass # assert_not_in_delta(0.05, (50000.0 / 10**6), 0.00001) # -> fail def assert_not_in_delta(expected_float, actual_float, delta=0.001, message="") _wrap_assertion do _assert_in_delta_validate_arguments(expected_float, actual_float, delta) full_message = _assert_in_delta_message(expected_float, actual_float, delta, message, :negative_assertion => true) assert_block(full_message) do (expected_float.to_f - actual_float.to_f).abs > delta.to_f end end end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :refute_in_delta, :assert_not_in_delta private def _assert_in_delta_validate_arguments(expected_float, actual_float, delta) { expected_float => "first float", actual_float => "second float", delta => "delta" }.each do |float, name| assert_respond_to(float, :to_f, "The arguments must respond to to_f; " + "the #{name} did not") end delta = delta.to_f assert_operator(delta, :>=, 0.0, "The delta should not be negative") end def _assert_in_delta_message(expected_float, actual_float, delta, message, options={}) if options[:negative_assertion] format = <<-EOT -/+ was expected to not include . EOT else format = <<-EOT -/+ was expected to include . EOT end arguments = [expected_float, delta, actual_float] normalized_expected = expected_float.to_f normalized_actual = actual_float.to_f normalized_delta = delta.to_f relation_format = nil relation_arguments = nil if normalized_actual < normalized_expected - normalized_delta relation_format = "< < -[?] <= +[?]>" relation_arguments = [actual_float, expected_float, delta, normalized_expected - normalized_delta, expected_float, delta, normalized_expected + normalized_delta] elsif normalized_actual <= normalized_expected + normalized_delta relation_format = "<-[?] <= <= +[?]>" relation_arguments = [expected_float, delta, normalized_expected - normalized_delta, actual_float, expected_float, delta, normalized_expected + normalized_delta] else relation_format = "<-[?] <= +[?] < >" relation_arguments = [expected_float, delta, normalized_expected - normalized_delta, expected_float, delta, normalized_expected + normalized_delta, actual_float] end if relation_format format += <<-EOT Relation: #{relation_format} EOT arguments.concat(relation_arguments) end build_message(message, format, *arguments) end public ## # Passes if `expected_float` and `actual_float` are equal # within `epsilon` relative error of `expected_float`. # # @example # assert_in_epsilon(10000.0, 9900.0, 0.1) # -> pass # assert_in_epsilon(10000.0, 9899.0, 0.1) # -> fail def assert_in_epsilon(expected_float, actual_float, epsilon=0.001, message="") _wrap_assertion do _assert_in_epsilon_validate_arguments(expected_float, actual_float, epsilon) full_message = _assert_in_epsilon_message(expected_float, actual_float, epsilon, message) assert_block(full_message) do normalized_expected_float = expected_float.to_f if normalized_expected_float.zero? delta = epsilon.to_f ** 2 else delta = normalized_expected_float * epsilon.to_f end delta = delta.abs (normalized_expected_float - actual_float.to_f).abs <= delta end end end ## # Passes if `expected_float` and `actual_float` are # not equal within `epsilon` relative error of # `expected_float`. # # @example # assert_not_in_epsilon(10000.0, 9900.0, 0.1) # -> fail # assert_not_in_epsilon(10000.0, 9899.0, 0.1) # -> pass def assert_not_in_epsilon(expected_float, actual_float, epsilon=0.001, message="") _wrap_assertion do _assert_in_epsilon_validate_arguments(expected_float, actual_float, epsilon) full_message = _assert_in_epsilon_message(expected_float, actual_float, epsilon, message, :negative_assertion => true) assert_block(full_message) do normalized_expected_float = expected_float.to_f delta = normalized_expected_float * epsilon.to_f (normalized_expected_float - actual_float.to_f).abs > delta end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_in_epsilon, :assert_not_in_epsilon private def _assert_in_epsilon_validate_arguments(expected_float, actual_float, epsilon) { expected_float => "first float", actual_float => "second float", epsilon => "epsilon" }.each do |float, name| assert_respond_to(float, :to_f, "The arguments must respond to to_f; " + "the #{name} did not") end epsilon = epsilon.to_f assert_operator(epsilon, :>=, 0.0, "The epsilon should not be negative") end def _assert_in_epsilon_message(expected_float, actual_float, epsilon, message, options={}) normalized_expected = expected_float.to_f normalized_actual = actual_float.to_f normalized_epsilon = epsilon.to_f delta = normalized_expected * normalized_epsilon if options[:negative_assertion] format = <<-EOT -/+ ( * )[?] was expected to not include . EOT else format = <<-EOT -/+ ( * )[?] was expected to include . EOT end arguments = [expected_float, expected_float, epsilon, delta, actual_float] relation_format = nil relation_arguments = nil if normalized_actual < normalized_expected - delta relation_format = "< < -(*)[?] <= +(*)[?]>" relation_arguments = [actual_float, expected_float, expected_float, epsilon, normalized_expected - delta, expected_float, expected_float, epsilon, normalized_expected + delta] elsif normalized_actual <= normalized_expected + delta relation_format = "<-(*)[?] <= <= +(*)[?]>" relation_arguments = [expected_float, expected_float, epsilon, normalized_expected - delta, actual_float, expected_float, expected_float, epsilon, normalized_expected + delta] else relation_format = "<-(*)[?] <= +(*)[?] < >" relation_arguments = [expected_float, expected_float, epsilon, normalized_expected - delta, expected_float, expected_float, epsilon, normalized_expected + delta, actual_float] end if relation_format format += <<-EOT Relation: #{relation_format} EOT arguments.concat(relation_arguments) end build_message(message, format, *arguments) end public ## # Passes if the method send returns a true value. # # `send_array` is composed of: # * A receiver # * A method # * Arguments to the method # # @example # assert_send([[1, 2], :member?, 1]) # -> pass # assert_send([[1, 2], :member?, 4]) # -> fail def assert_send(send_array, message=nil) _wrap_assertion do assert_instance_of(Array, send_array, "assert_send requires an array " + "of send information") assert_operator(send_array.size, :>=, 2, "assert_send requires at least a receiver " + "and a message name") format = < was expected to respond to with a true value but was . EOT receiver, message_name, *arguments = send_array result = nil full_message = build_message(message, format, receiver, AssertionMessage.literal(message_name.to_s), arguments, AssertionMessage.delayed_literal {result}) assert_block(full_message) do result = receiver.__send__(message_name, *arguments) result end end end ## # Passes if the method send doesn't return a true value. # # `send_array` is composed of: # * A receiver # * A method # * Arguments to the method # # @example # assert_not_send([[1, 2], :member?, 1]) # -> fail # assert_not_send([[1, 2], :member?, 4]) # -> pass def assert_not_send(send_array, message=nil) _wrap_assertion do assert_instance_of(Array, send_array, "assert_not_send requires an array " + "of send information") assert_operator(send_array.size, :>=, 2, "assert_not_send requires at least a receiver " + "and a message name") format = < was expected to respond to with not a true value but was . EOT receiver, message_name, *arguments = send_array result = nil full_message = build_message(message, format, receiver, AssertionMessage.literal(message_name.to_s), arguments, AssertionMessage.delayed_literal {result}) assert_block(full_message) do result = receiver.__send__(message_name, *arguments) not result end end end ## # Passes if `actual` is a boolean value. # # @example # assert_boolean(true) # -> pass # assert_boolean(nil) # -> fail def assert_boolean(actual, message=nil) _wrap_assertion do assert_block(build_message(message, " or expected but was\n", actual)) do [true, false].include?(actual) end end end ## # Passes if `actual` is true. # # @example # assert_true(true) # -> pass # assert_true(:true) # -> fail def assert_true(actual, message=nil) _wrap_assertion do assert_block(build_message(message, " expected but was\n", actual)) do actual == true end end end ## # Passes if `actual` is false. # # @example # assert_false(false) # -> pass # assert_false(nil) # -> fail def assert_false(actual, message=nil) _wrap_assertion do assert_block(build_message(message, " expected but was\n", actual)) do actual == false end end end ## # Passes if expression "`expected` `operator` # `actual`" is true. # # @example # assert_compare(1, "<", 10) # -> pass # assert_compare(1, ">=", 10) # -> fail def assert_compare(expected, operator, actual, message=nil) _wrap_assertion do assert_send([["<", "<=", ">", ">="], :include?, operator.to_s]) case operator.to_s when "<" operator_description = "less than" when "<=" operator_description = "less than or equal to" when ">" operator_description = "greater than" when ">=" operator_description = "greater than or equal to" end template = <<-EOT #{operator} should be true was expected to be #{operator_description} . EOT full_message = build_message(message, template, expected, actual, expected, actual) assert_block(full_message) do expected.__send__(operator, actual) end end end ## # Passes if assertion is failed in block. # # @example # assert_fail_assertion {assert_equal("A", "B")} # -> pass # assert_fail_assertion {assert_equal("A", "A")} # -> fail def assert_fail_assertion(message=nil) _wrap_assertion do full_message = build_message(message, "Failed assertion was expected.") assert_block(full_message) do begin yield false rescue AssertionFailedError true end end end end ## # Passes if an exception is raised in block and its # message is `expected`. # # @example # assert_raise_message("exception") {raise "exception"} # -> pass # assert_raise_message(/exc/i) {raise "exception"} # -> pass # assert_raise_message("exception") {raise "EXCEPTION"} # -> fail # assert_raise_message("exception") {} # -> fail def assert_raise_message(expected, message=nil) _wrap_assertion do full_message = build_message(message, " exception message was expected " + "but none was thrown.", expected) exception = nil assert_block(full_message) do begin yield false rescue Exception => exception true end end actual = exception.message diff = AssertionMessage.delayed_diff(expected, actual) full_message = build_message(message, " exception message expected but was\n" + ".?", expected, actual, diff) assert_block(full_message) do if expected.is_a?(Regexp) expected =~ actual else expected == actual end end end end ## # Passes if `object`.const_defined?(`constant_name`) # # @example # assert_const_defined(Test, :Unit) # -> pass # assert_const_defined(Object, :Nonexistent) # -> fail def assert_const_defined(object, constant_name, message=nil) _wrap_assertion do full_message = build_message(message, ".const_defined\\?() expected.", object, constant_name) assert_block(full_message) do object.const_defined?(constant_name) end end end ## # Passes if !`object`.const_defined?(`constant_name`) # # @example # assert_not_const_defined(Object, :Nonexistent) # -> pass # assert_not_const_defined(Test, :Unit) # -> fail def assert_not_const_defined(object, constant_name, message=nil) _wrap_assertion do full_message = build_message(message, "!.const_defined\\?() expected.", object, constant_name) assert_block(full_message) do !object.const_defined?(constant_name) end end end ## # Passes if `object`.`predicate` is _true_. # # @example # assert_predicate([], :empty?) # -> pass # assert_predicate([1], :empty?) # -> fail def assert_predicate(object, predicate, message=nil) _wrap_assertion do assert_respond_to(object, predicate, message) actual = object.__send__(predicate) full_message = build_message(message, ".? is true value expected but was\n" + "", object, AssertionMessage.literal(predicate), actual) assert_block(full_message) do actual end end end ## # Passes if `object`.`predicate` is not _true_. # # @example # assert_not_predicate([1], :empty?) # -> pass # assert_not_predicate([], :empty?) # -> fail def assert_not_predicate(object, predicate, message=nil) _wrap_assertion do assert_respond_to(object, predicate, message) actual = object.__send__(predicate) full_message = build_message(message, ".? is false value expected but was\n" + "", object, AssertionMessage.literal(predicate), actual) assert_block(full_message) do not actual end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_predicate, :assert_not_predicate ## # Passes if `object`#`alias_name` is an alias method of # `object`#`original_name`. # # @example # assert_alias_method([], :length, :size) # -> pass # assert_alias_method([], :size, :length) # -> pass # assert_alias_method([], :each, :size) # -> fail def assert_alias_method(object, alias_name, original_name, message=nil) _wrap_assertion do find_method_failure_message = Proc.new do |method_name| build_message(message, ".? doesn't exist\n" + "(Class: )", object, AssertionMessage.literal(method_name), object.class) end alias_method = original_method = nil assert_block(find_method_failure_message.call(alias_name)) do begin alias_method = object.method(alias_name) true rescue NameError false end end assert_block(find_method_failure_message.call(original_name)) do begin original_method = object.method(original_name) true rescue NameError false end end full_message = build_message(message, " is alias of\n" + " expected", alias_method, original_method) assert_block(full_message) do alias_method == original_method end end end ## # Passes if `path` exists. # # @example # assert_path_exist("/tmp") # -> pass # assert_path_exist("/bin/sh") # -> pass # assert_path_exist("/nonexistent") # -> fail def assert_path_exist(path, message=nil) _wrap_assertion do failure_message = build_message(message, " was expected to exist", path) assert_block(failure_message) do File.exist?(path) end end end ## # Passes if `path` doesn't exist. # # @example # assert_path_not_exist("/nonexistent") # -> pass # assert_path_not_exist("/tmp") # -> fail # assert_path_not_exist("/bin/sh") # -> fail def assert_path_not_exist(path, message=nil) _wrap_assertion do failure_message = build_message(message, " was expected to not exist", path) assert_block(failure_message) do not File.exist?(path) end end end ## # Passes if `collection` includes `object`. # # @example # assert_include([1, 10], 1) # -> pass # assert_include(1..10, 5) # -> pass # assert_include([1, 10], 5) # -> fail # assert_include(1..10, 20) # -> fail def assert_include(collection, object, message=nil) _wrap_assertion do assert_respond_to(collection, :include?, "The collection must respond to :include?.") full_message = build_message(message, " was expected to include\n.", collection, object) assert_block(full_message) do collection.include?(object) end end end # Just for minitest compatibility. :< # # @since 2.5.3 alias_method :assert_includes, :assert_include ## # Passes if `collection` doesn't include `object`. # # @example # assert_not_include([1, 10], 5) # -> pass # assert_not_include(1..10, 20) # -> pass # assert_not_include([1, 10], 1) # -> fail # assert_not_include(1..10, 5) # -> fail def assert_not_include(collection, object, message=nil) _wrap_assertion do assert_respond_to(collection, :include?, "The collection must respond to :include?.") full_message = build_message(message, " was expected to not include\n.", collection, object) assert_block(full_message) do not collection.include?(object) end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :assert_not_includes, :assert_not_include # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_includes, :assert_not_include ## # Passes if `object` is empty. # # @example # assert_empty("") # -> pass # assert_empty([]) # -> pass # assert_empty({}) # -> pass # assert_empty(" ") # -> fail # assert_empty([nil]) # -> fail # assert_empty({1 => 2}) # -> fail def assert_empty(object, message=nil) _wrap_assertion do assert_respond_to(object, :empty?, "The object must respond to :empty?.") full_message = build_message(message, " was expected to be empty.", object) assert_block(full_message) do object.empty? end end end ## # Passes if `object` is not empty. # # @example # assert_not_empty(" ") # -> pass # assert_not_empty([nil]) # -> pass # assert_not_empty({1 => 2}) # -> pass # assert_not_empty("") # -> fail # assert_not_empty([]) # -> fail # assert_not_empty({}) # -> fail def assert_not_empty(object, message=nil) _wrap_assertion do assert_respond_to(object, :empty?, "The object must respond to :empty?.") full_message = build_message(message, " was expected to not be empty.", object) assert_block(full_message) do not object.empty? end end end # Just for minitest compatibility. :< # # @since 3.0.0 alias_method :refute_empty, :assert_not_empty ## # Builds a failure message. `user_message` is added before the # `template` and `arguments` replaces the '?'s positionally in # the template. def build_message(user_message, template=nil, *arguments) template &&= template.chomp return AssertionMessage.new(user_message, template, arguments) end private def _wrap_assertion(&block) @_assertion_wrapped ||= false if @_assertion_wrapped block.call else @_assertion_wrapped = true begin add_assertion block.call ensure @_assertion_wrapped = false end end end public # Called whenever an assertion is made. Define this in classes # that include Test::Unit::Assertions to record assertion # counts. # # This is a public API for developers who extend test-unit. # # @return [void] def add_assertion end ## # Select whether or not to use the pretty-printer. If this option is set # to false before any assertions are made, pp.rb will not be required. def self.use_pp=(value) AssertionMessage.use_pp = value end private def _assert_raise(assert_expected_exception, *args, &block) _wrap_assertion do if args.last.is_a?(String) message = args.pop else message = "" end assert_exception_helper = AssertExceptionHelper.new(self, args) expected = assert_exception_helper.expected_exceptions actual_exception = nil full_message = build_message(message, " exception was expected " + "but none was thrown.", expected) assert_block(full_message) do begin yield false rescue Exception => actual_exception true end end assert_expected_exception.call(message, assert_exception_helper, actual_exception) actual_exception end end def _set_failed_information(failure, expected, actual) failure.expected = expected failure.actual = actual failure.inspected_expected = AssertionMessage.convert(expected) failure.inspected_actual = AssertionMessage.convert(actual) end class AssertionMessage @use_pp = true class << self attr_accessor :use_pp def literal(value) Literal.new(value) end def delayed_literal(&block) DelayedLiteral.new(block) end def maybe_container(value, &formatter) MaybeContainer.new(value, &formatter) end MAX_DIFF_TARGET_STRING_SIZE = 1000 def max_diff_target_string_size return @@max_diff_target_string_size if @@max_diff_target_string_size size = ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] if size begin size = Integer(size) rescue ArgumentError size = nil end end size || MAX_DIFF_TARGET_STRING_SIZE end @@max_diff_target_string_size = nil def max_diff_target_string_size=(size) @@max_diff_target_string_size = size end def diff_target_string?(string) if string.respond_to?(:bytesize) string.bytesize < max_diff_target_string_size else string.size < max_diff_target_string_size end end def ensure_diffable_string(string) if string.respond_to?(:encoding) and !string.encoding.ascii_compatible? string = string.dup.force_encoding("ASCII-8BIT") end string end def prepare_for_diff(from, to) if !from.is_a?(String) or !to.is_a?(String) from = convert(from) to = convert(to) end if diff_target_string?(from) and diff_target_string?(to) from = ensure_diffable_string(from) to = ensure_diffable_string(to) [from, to] else [nil, nil] end end def delayed_diff(from, to) delayed_literal do from, to = prepare_for_diff(from, to) diff = "" if from.nil? or to.nil? diff ||= Diff.readable(from, to) if /^[-+]/ !~ diff diff = "" elsif /^[ ?]/ =~ diff or /(?:.*\n){2,}/ =~ diff diff = "\n\ndiff:\n#{diff}" else diff = "" end if Diff.need_fold?(diff) folded_diff = Diff.folded_readable(from, to) diff += "\n\nfolded diff:\n#{folded_diff}" end diff end end def convert(object) if object.is_a?(Exception) object = AssertExceptionHelper::WrappedException.new(object) end inspector = Inspector.new(object) if use_pp begin require "pp" unless defined?(PP) begin return PP.pp(inspector, String.new).chomp rescue NameError end rescue LoadError self.use_pp = false end end inspector.inspect end end class Inspector include Comparable class << self def cached_new(object, inspected_objects) inspected_objects[object.object_id] ||= new(object, inspected_objects) end @@inspector_classes = [] def inspector_classes @@inspector_classes end def register_inspector_class(inspector_class) @@inspector_classes << inspector_class end def unregister_inspector_class(inspector_class) @@inspector_classes.delete(inspector_class) end end attr_reader :object def initialize(object, inspected_objects={}) @inspected_objects = inspected_objects @object = object @inspected_objects[@object.object_id] = self @inspect_target = inspect_target end alias_method :native_inspect, :inspect def inspect @inspect_target.inspect end def pretty_print(q) @inspect_target.pretty_print(q) end def pretty_print_cycle(q) @inspect_target.pretty_print_cycle(q) end def <=>(other) if other.is_a?(self.class) @object <=> other.object else @object <=> other end end private def inspect_target self.class.inspector_classes.each do |inspector_class| if inspector_class.target?(@object) return inspector_class.new(@object, @inspected_objects) end end @object end end class NumericInspector Inspector.register_inspector_class(self) class << self def target?(object) object.is_a?(Numeric) end end def initialize(numeric, inspected_objects) @inspected_objects = inspected_objects @numeric = numeric end def inspect @numeric.to_s end def pretty_print(q) q.text(@numeric.to_s) end def pretty_print_cycle(q) q.text(@numeric.to_s) end end class HashInspector Inspector.register_inspector_class(self) class << self def target?(object) object.is_a?(Hash) or ENV.equal?(object) end end def initialize(hash, inspected_objects) @inspected_objects = inspected_objects @hash = {} hash.each do |key, value| key = Inspector.cached_new(key, @inspected_objects) value = Inspector.cached_new(value, @inspected_objects) @hash[key] = value end end def inspect @hash.inspect end def pretty_print(q) q.group(1, '{', '}') do q.seplist(self, nil, :each_pair) do |k, v| q.group do q.pp(k) q.text('=>') q.group(1) do q.breakable('') q.pp(v) end end end end end def pretty_print_cycle(q) @hash.pretty_print_cycle(q) end def each_pair keys = @hash.keys begin keys = keys.sort # FIXME: more cleverly rescue ArgumentError end keys.each do |key| yield(key, @hash[key]) end end end class ArrayInspector Inspector.register_inspector_class(self) class << self def target?(object) object.is_a?(Array) end end def initialize(array, inspected_objects) @inspected_objects = inspected_objects @array = array.collect do |element| Inspector.cached_new(element, @inspected_objects) end end def inspect @array.inspect end def pretty_print(q) q.group(1, '[', ']') do q.seplist(self) do |v| q.pp(v) end end end def pretty_print_cycle(q) @array.pretty_print_cycle(q) end def each(&block) @array.each(&block) end end class Literal def initialize(value) @value = value end def inspect @value.to_s end end class DelayedLiteral def initialize(value) @value = value end def inspect @value.call.to_s end end class MaybeContainer def initialize(value, &formatter) @value = value @formatter = formatter end def inspect if @value.is_a?(Array) values = @value.collect do |value| @formatter.call(AssertionMessage.convert(value)) end "[#{values.join(', ')}]" else @formatter.call(AssertionMessage.convert(@value)) end end end class Template def self.create(string) parts = (string ? string.scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/m) : []) self.new(parts) end attr_reader :count def initialize(parts) @parts = parts @count = parts.find_all{|e| e == '?'}.size end def result(parameters) raise "The number of parameters does not match the number of substitutions." if(parameters.size != count) params = parameters.dup expanded_template = "" @parts.each do |part| if part == '?' param = params.shift if Object.const_defined?(:Encoding) expanded_template += concatenatable(param, expanded_template.encoding) else expanded_template += param end else expanded_template += part.gsub(/\\\?/m, '?') end end expanded_template end private def concatenatable(text, encoding) if Encoding.compatible?(text, encoding) text else text.dup.force_encoding(encoding) end end end include Util::BacktraceFilter def initialize(user_message, template_string, parameters) @user_message = user_message @template_string = template_string @parameters = parameters end def convert(object) self.class.convert(object) end def template @template ||= Template.create(@template_string) end def user_message return nil unless @user_message message = @user_message message = message.call if message.respond_to?(:call) message.to_s end def to_s message_parts = [] head = user_message if head and not head.empty? message_parts << add_period(head) end tail = template.result(@parameters.collect{|e| convert(e)}) message_parts << tail unless(tail.empty?) message_parts.join("\n") end private def add_period(string) (string =~ /\.\Z/ ? string : string + '.') end end class AssertExceptionHelper class WrappedException attr_reader :exception def initialize(exception) @exception = exception end def inspect if default_inspect? inspected = "#{@exception.class.inspect}(<#{@exception.message}>)" unless (@exception.backtrace || []).empty? inspected += "\n" @exception.backtrace.each do |trace| inspected << "#{trace}\n" end end inspected else @exception.inspect end end def method_missing(name, *args, &block) @exception.__send__(name, *args, &block) end private def default_inspect? inspect_method = @exception.method(:inspect) if inspect_method.respond_to?(:owner) and inspect_method.owner == Exception true else default_inspect_method = Exception.instance_method(:inspect) default_inspect_method.bind(@exception).call == @exception.inspect end end end def initialize(test_case, expected_exceptions) @test_case = test_case @expected_exceptions = expected_exceptions @expected_classes, @expected_modules, @expected_objects = split_expected_exceptions(expected_exceptions) end def expected_exceptions exceptions = @expected_exceptions.collect do |exception| if exception.is_a?(Exception) WrappedException.new(exception) else exception end end if exceptions.size == 1 exceptions[0] else exceptions end end def expected?(actual_exception, equality=nil) equality ||= :instance_of? expected_class?(actual_exception, equality) or expected_module?(actual_exception) or expected_object?(actual_exception) end private def split_expected_exceptions(expected_exceptions) exception_modules = [] exception_objects = [] exception_classes = [] expected_exceptions.each do |exception_type| if exception_type.instance_of?(Module) exception_modules << exception_type elsif exception_object?(exception_type) exception_objects << exception_type elsif exception_class?(exception_type) exception_classes << exception_type else full_message = @test_case.__send__(:build_message, nil, " must be " + "a subclass of Exception, " + "an object of Exception subclasses " + "or a Module", exception_type) @test_case.flunk(full_message) end end [exception_classes, exception_modules, exception_objects] end def exception_object?(exception_type) return true if exception_type.is_a?(Exception) if Object.const_defined?(:Java) return true if exception_type.is_a?(Java::JavaLang::Throwable) end false end def exception_class?(exception_type) return true if exception_type <= Exception if Object.const_defined?(:Java) return true if exception_type <= Java::JavaLang::Throwable end false end def expected_class?(actual_exception, equality) @expected_classes.any? do |expected_class| actual_exception.__send__(equality, expected_class) end end def expected_module?(actual_exception) @expected_modules.any? do |expected_module| actual_exception.is_a?(expected_module) end end def expected_object?(actual_exception) @expected_objects.any? do |expected_object| expected_object == actual_exception or fallback_exception_object_equal(expected_object, actual_exception) end end def fallback_exception_object_equal(expected_object, actual_exception) owner = Util::MethodOwnerFinder.find(expected_object, :==) if owner == Kernel or owner == Exception expected_object.class == actual_exception.class and expected_object.message == actual_exception.message else false end end end # :startdoc: end end end test-unit-3.3.9/lib/test/unit/testcase.rb0000644000004100000410000006153413775322563020404 0ustar www-datawww-data#-- # # Author:: Nathaniel Talbott. # Copyright:: # * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # * Copyright (c) 2008-2012 Kouhei Sutou # License:: Ruby license. require 'test/unit/attribute' require 'test/unit/fixture' require 'test/unit/exception-handler' require 'test/unit/assertions' require 'test/unit/failure' require 'test/unit/error' require 'test/unit/pending' require 'test/unit/omission' require 'test/unit/notification' require 'test/unit/priority' require 'test/unit/data' require 'test/unit/testsuite' require 'test/unit/test-suite-creator' require 'test/unit/assertion-failed-error' require 'test/unit/auto-runner-loader' require 'test/unit/util/backtracefilter' require 'test/unit/util/output' require 'test/unit/util/method-owner-finder' module Test module Unit # Ties everything together. If you subclass and add your own # test methods, it takes care of making them into tests and # wrapping those tests into a suite. It also does the # nitty-gritty of actually running an individual test and # collecting its results into a Test::Unit::TestResult object. # # You can run two hooks before/after a TestCase run. # # Example: # # class TestMyClass < Test::Unit::TestCase # class << self # def startup # ... # end # # def shutdown # ... # end # end # # def setup # ... # end # # def cleanup # ... # end # # def teardown # ... # end # # def test_my_method1 # ... # end # # def test_my_method2 # ... # end # end # # Here is a call order: # # 1. startup # 1. setup # 1. test_my_method1 # 1. cleanup # 1. teardown # 1. setup # 1. test_my_method2 # 1. cleanup # 1. teardown # 1. shutdown # # You can set an attribute to each test. # # Example: # # class TestMyClass < Test::Unit::TestCase # attribute :speed, :fast # def test_my_fast_method # # You can get the attribute via `self[]` # self[:speed] # => :fast # ... # end # # attribute :speed, :slow # def test_my_slow_method # self[:speed] # => :slow # ... # end # end class TestCase include Attribute include Fixture include ExceptionHandler include ErrorHandler include FailureHandler include TestCasePendingSupport include TestCaseOmissionSupport include TestCaseNotificationSupport include Priority include Data include Assertions include Util::BacktraceFilter include Util::Output STARTED = name + "::STARTED" # :nodoc: FINISHED = name + "::FINISHED" # :nodoc: STARTED_OBJECT = name + "::STARTED::OBJECT" # :nodoc: FINISHED_OBJECT = name + "::FINISHED::OBJECT" # :nodoc: DESCENDANTS = [] # :nodoc: AVAILABLE_ORDERS = [:alphabetic, :random, :defined] # :nodoc: class << self def inherited(sub_class) # :nodoc: DESCENDANTS << sub_class super end def include(*modules, &block) # :nodoc: super modules.each do |mod| mod.public_instance_methods(false).each do |method_name| AutoRunnerLoader.check(self, method_name.to_s) end end end @@added_method_names = {} def method_added(name) # :nodoc: super added_method_names = (@@added_method_names[self] ||= {}) stringified_name = name.to_s if added_method_names.key?(stringified_name) attribute(:redefined, {:backtrace => caller}, {}, stringified_name) end source_location = find_attribute(stringified_name, :source_location) if source_location path, line = source_location elsif respond_to?(:caller_locations, true) location = caller_locations(1, 1)[0] path = location.absolute_path || location.path line = location.lineno else # TODO: Remove me when Ruby 1.9 support is dropped path, line, = caller[0].split(/:(\d+)/, 2) line = line.to_i if line end location = { :method_name => stringified_name, :path => File.expand_path(path), :line => line, } add_method_location(location) added_method_names[stringified_name] = true AutoRunnerLoader.check(self, stringified_name) end def added_method_names # :nodoc: (@@added_method_names[self] ||= {}).keys end # Rolls up all of the test* methods in the fixture into # one suite, creating a new instance of the fixture for # each method. def suite suite_creator = TestSuiteCreator.new(self) suite_creator.create end # Called before every test case runs. Can be used # to set up fixture information used in test case # scope. # # Here is an example test case: # # class TestMyClass < Test::Unit::TestCase # class << self # def startup # ... # end # end # # def setup # ... # end # # def test_my_class1 # ... # end # # def test_my_class2 # ... # end # end # # Here is a call order: # # * startup # * setup # * test_my_class1 (or test_my_class2) # * setup # * test_my_class2 (or test_my_class1) # # Note that you should not assume test order. Tests # should be worked in any order. def startup end # Called after every test case runs. Can be used to tear # down fixture information used in test case scope. # # Here is an example test case: # # class TestMyClass < Test::Unit::TestCase # class << self # def shutdown # ... # end # end # # def teardown # ... # end # # def test_my_class1 # ... # end # # def test_my_class2 # ... # end # end # # Here is a call order: # # * test_my_class1 (or test_my_class2) # * teardown # * test_my_class2 (or test_my_class1) # * teardown # * shutdown # # Note that you should not assume test order. Tests # should be worked in any order. def shutdown end @@test_orders = {} # Returns the current test order. This returns # `:alphabetic` by default. def test_order ancestors.each do |ancestor| order = @@test_orders[ancestor] return order if order end AVAILABLE_ORDERS.first end # Sets the current test order. # # Here are the available _order_: # # :alphabetic # : Default. Tests are sorted in alphabetic order. # # :random # : Tests are sorted in random order. # # :defined # : Tests are sorted in defined order. def test_order=(order) @@test_orders[self] = order end # Defines a test in declarative syntax or marks # following method as a test method. # # In declarative syntax usage, the following two # test definitions are the almost same: # # description "register user" # def test_register_user # ... # end # # test "register user" do # ... # end # # In test method mark usage, the "my_test_method" is # treated as a test method: # # test # def my_test_method # assert_equal("call me", ...) # end def test(*test_description_or_targets, &block) if block_given? test_description = test_description_or_targets.first if test_description.nil? raise ArgumentError, "test description is missing" end n_arguments = test_description_or_targets.size if n_arguments > 1 message = "wrong number of arguments (#{n_arguments} for 1)" raise ArgumentError, message end method_name = "test: #{test_description}" description(test_description, method_name) attribute(:test, true, {}, method_name) if block.respond_to?(:source_location) attribute(:source_location, block.source_location, {}, method_name) end define_method(method_name, &block) else targets = test_description_or_targets attribute(:test, true, {}, *targets) targets.each do |target| AutoRunnerLoader.check(self, target) end end end # Describes a test. # # The following example associates "register a # normal user" description with "test_register" # test. # # description "register a normal user" # def test_register # ... # end def description(value, target=nil) targets = [target].compact attribute(:description, value, {}, *targets) end # Defines a sub test case. # # This is a syntax sugar. The both of the following codes are # the same in meaning: # # Standard: # # class TestParent < Test::Unit::TestCase # class TestChild < self # def test_in_child # end # end # end # # Syntax sugar: # # class TestParent < Test::Unit::TestCase # sub_test_case("TestChild") do # def test_in_child # end # end # end # # The difference of them are the following: # # * Test case created by {sub_test_case} is an anonymous class. # So you can't refer the test case by name. # * The class name of class style must follow # constant naming rule in Ruby. But the name of test case # created by {sub_test_case} doesn't need to follow the rule. # For example, you can use a space in name such as "child test". # # @param name [String] The name of newly created sub test case. # @yield # The block is evaluated under the newly created sub test # case class context. # @return [Test::Unit::TestCase] Created sub test case class. def sub_test_case(name, &block) parent_test_case = self sub_test_case = Class.new(self) do singleton_class = class << self; self; end singleton_class.__send__(:define_method, :name) do [parent_test_case.name, name].compact.join("::") end end sub_test_case.class_eval(&block) sub_test_case end # Checks whether a test that is matched the query is # defined. # # @option query [String] :path (nil) # the path where a test is defined in. # @option query [Numeric] :line (nil) # the line number where a test is defined at. # @option query [String] :method_name (nil) # the method name for a test. def test_defined?(query) locations = find_locations(query) not locations.empty? end def find_locations(query) query_path = query[:path] query_line = query[:line] query_method_name = query[:method_name] available_locations = target_method_locations(query_path) if query_line available_locations = available_locations.sort_by do |location| -location[:line] end available_location = available_locations.find do |location| query_line >= location[:line] end return [] if available_location.nil? return [] if available_location[:test_case] != self available_locations = [available_location] end if query_method_name available_location = available_locations.find do |location| location[:test_case] == self and query_method_name == location[:method_name] end return [] if available_location.nil? available_locations = [available_location] end available_locations end private # @private @@method_locations = {} # @private @@method_location_mutex = Mutex.new # @private def method_locations @@method_locations[self] ||= [] end # @private def add_method_location(location) @@method_location_mutex.synchronize do method_locations << location end end # @private def target_method_locations(path) @@method_location_mutex.synchronize do if path.nil? self_location = method_locations.first path = self_location[:path] if self_location end return [] if path.nil? target_locations = [] @@method_locations.each do |test_case, locations| locations.each do |location| absolete_path = File.expand_path(path) location_path = location[:path] location_basename = File.basename(location_path) if location_path == absolete_path or location_basename == path target_locations << location.merge(:test_case => test_case) end end end target_locations end end end attr_reader :method_name # Creates a new instance of the fixture for running the # test represented by test_method_name. def initialize(test_method_name) @method_name = test_method_name @internal_data = InternalData.new end # Assigns test data to the test. It is used in internal. def assign_test_data(label, data) # :nodoc: @internal_data.assign_test_data(label, data) end # Returns the test is valid test. It is used in internal. def valid? # :nodoc: return false unless respond_to?(@method_name) test_method = method(@method_name) unless @internal_data.have_test_data? return false unless test_method.arity <= 0 end owner = Util::MethodOwnerFinder.find(self, @method_name) if owner.class != Module and self.class != owner return false end true end # Runs the individual test method represented by this # instance of the fixture, collecting statistics, failures # and errors in result. def run(result) begin @_result = result @internal_data.test_started yield(STARTED, name) yield(STARTED_OBJECT, self) processed_exception_in_setup = false begin catch do |tag| run_setup do begin run_test run_cleanup add_pass rescue Exception @internal_data.interrupted unless handle_exception($!) processed_exception_in_setup = true raise end throw(tag) end end end rescue Exception if processed_exception_in_setup raise else @internal_data.interrupted raise unless handle_exception($!) end ensure begin run_teardown rescue Exception raise unless handle_exception($!) end end @internal_data.test_finished result.add_run yield(FINISHED, name) yield(FINISHED_OBJECT, self) ensure # @_result = nil # For test-spec's after_all :< end end # Called before every test method runs. Can be used # to set up fixture information. # # You can add additional setup tasks by the following # code: # # class TestMyClass < Test::Unit::TestCase # def setup # ... # end # # setup # def my_setup1 # ... # end # # setup do # ... # setup callback1 # end # # setup # def my_setup2 # ... # end # # setup do # ... # setup callback2 # end # # def test_my_class # ... # end # end # # Here is a call order: # # * setup # * my_setup1 # * setup callback1 # * my_setup2 # * setup callback2 # * test_my_class def setup end # Called after every test method runs but the test # method isn't marked as 'passed'. Can be used to # clean up and/or verify tested condition. # e.g. Can be used to verify mock. # # You can add additional cleanup tasks by the following # code: # # class TestMyClass < Test::Unit::TestCase # def cleanup # ... # end # # cleanup # def my_cleanup1 # ... # end # # cleanup do # ... # cleanup callback1 # end # # cleanup # def my_cleanup2 # ... # end # # cleanup do # ... # cleanup callback2 # end # # def test_my_class # ... # end # end # # Here is a call order: # # * test_my_class # * cleanup callback2 # * my_cleanup2 # * cleanup callback1 # * my_cleanup1 # * cleanup def cleanup end # Called after every test method runs. Can be used to tear # down fixture information. # # You can add additional teardown tasks by the following # code: # # class TestMyClass < Test::Unit::TestCase # def teardown # ... # end # # teardown # def my_teardown1 # ... # end # # teardown do # ... # teardown callback1 # end # # teardown # def my_teardown2 # ... # end # # teardown do # ... # teardown callback2 # end # # def test_my_class # ... # end # end # # Here is a call order: # # * test_my_class # * teardown callback2 # * my_teardown2 # * teardown callback1 # * my_teardown1 # * teardown def teardown end def default_test flunk("No tests were specified") end def size 1 end # Returns a label of test data for the test. If the # test isn't associated with any test data, it returns # `nil`. def data_label @internal_data.test_data_label end # Returns test data for the test. If the test isn't associated # with any test data, it returns `nil`. def data @internal_data.test_data end # Returns a human-readable name for the specific test that # this instance of TestCase represents. def name "#{local_name}(#{self.class.name})" end # Returns a human-readable name for the specific test that this # instance of TestCase represents. # # `#local_name` doesn't include class name. `#name` includes # class name. def local_name if @internal_data.have_test_data? "#{@method_name}[#{data_label}]" else @method_name.to_s end end # Returns a description for the test. A description # will be associated by Test::Unit::TestCase.test or # Test::Unit::TestCase.description. # # Returns a name for the test for no description test. def description self[:description] || name end # Overridden to return #name. def to_s name end # It's handy to be able to compare TestCase instances. def ==(other) return false unless other.kind_of?(self.class) return false unless @method_name == other.method_name return false unless data_label == other.data_label self.class == other.class end # Returns a Time at the test was started. def start_time @internal_data.start_time end # Returns elapsed time for the test was ran. def elapsed_time @internal_data.elapsed_time end # Returns whether the test is interrupted. def interrupted? @internal_data.interrupted? end # Returns whether this individual test passed or # not. Primarily for use in teardown so that artifacts # can be left behind if the test fails. def passed? @internal_data.passed? end # Notify that a problem is occurred in the test. It means that # the test is a failed test. If any failed tests exist in test # suites, the test process exits with failure exit status. # # This is a public API for developers who extend test-unit. # # @return [void] def problem_occurred @internal_data.problem_occurred end # Notify that the test is passed. Normally, it is not needed # because #run calls it automatically. If you want to override # #run, it is not a good idea. Please contact test-unit # developers. We will help you without your custom #run. For # example, we may add a new hook in #run. # # This is a public API for developers who extend test-unit. # # @return [void] def add_pass current_result.add_pass end private def current_result @_result end def run_test signature = "#{self.class}\##{@method_name}" redefined_info = self[:redefined] if redefined_info notify("<#{signature}> was redefined", :backtrace => redefined_info[:backtrace]) end if @internal_data.have_test_data? test_method = method(@method_name) arity = test_method.arity if arity.zero? __send__(@method_name) else __send__(@method_name, @internal_data.test_data) end else __send__(@method_name) end end def handle_exception(exception) self.class.exception_handlers.each do |handler| if handler.respond_to?(:call) handled = handler.call(self, exception) else handled = __send__(handler, exception) end return true if handled end false end def add_assertion current_result.add_assertion end class InternalData attr_reader :start_time, :elapsed_time attr_reader :test_data_label, :test_data def initialize @start_time = nil @elapsed_time = nil @passed = true @interrupted = false @test_data_label = nil @test_data = nil end def passed? @passed end def interrupted? @interrupted end def assign_test_data(label, data) @test_data_label = label @test_data = data end def have_test_data? not @test_data_label.nil? end def test_started @start_time = Time.now end def test_finished @elapsed_time = Time.now - @start_time end def problem_occurred @passed = false end def interrupted @interrupted = true end end end end end test-unit-3.3.9/lib/test/unit/data-sets.rb0000644000004100000410000000576713775322563020464 0ustar www-datawww-datamodule Test module Unit class DataSets def initialize @variables = [] @procs = [] @value_sets = [] end def add(data_set, options=nil) options ||= {} if data_set.respond_to?(:call) @procs << [data_set, options] elsif data_set.is_a?(Array) @variables << [data_set, options] else @value_sets << [data_set, options] end end def <<(data_set) add(data_set) end def keep new_data_sets = self.class.new all_data_sets = Enumerator.new do |yielder| block = lambda do |(data_set, options)| yielder << [data_set, options] end @procs.each(&block) @variables.each(&block) @value_sets.each(&block) end all_data_sets.each do |data_set, options| next if options.nil? next unless options[:keep] new_data_sets.add(data_set, options) end new_data_sets end def each variables = @variables value_sets = @value_sets @procs.each do |proc, options| data_set = proc.call case data_set when Array variables += [[data_set, options]] else value_sets += [[data_set, options]] end end value_sets.each do |values, _options| values.each do |label, data| yield(label, data) end end each_pattern(variables) do |label, data| yield(label, data) end end def ==(other) @variables == other.instance_variable_get(:@variables) and @procs == other.instance_variable_get(:@procs) and @value_sets == other.instance_variable_get(:@value_sets) end def eql?(other) self == other end def hash [@variables, @procs, @value_sets].hash end private def each_pattern(variables) grouped_variables = variables.group_by do |_, options| options[:group] end grouped_variables.each do |group, group_variables| each_raw_pattern(group_variables) do |cell| label = String.new label << "group: #{group.inspect}" unless group.nil? data = {} cell.each do |variable, pattern| label << ", " unless label.empty? label << "#{variable}: #{pattern.inspect}" data[variable] = pattern end yield(label, data) end end end def each_raw_pattern(variables, &block) return if variables.empty? sorted_variables = variables.sort_by do |(variable, _), _| variable end all_patterns = sorted_variables.collect do |(variable, patterns), _| patterns.collect do |pattern| [variable, pattern] end end all_patterns[0].product(*all_patterns[1..-1], &block) end end end end test-unit-3.3.9/lib/test/unit/fixture.rb0000644000004100000410000002203713775322563020252 0ustar www-datawww-datamodule Test module Unit module Fixture class << self def included(base) base.extend(ClassMethods) [:setup, :cleanup, :teardown].each do |type| observer = lambda do |test_case, _, _, value, callback| if value.nil? test_case.fixture[type].unregister(callback) else test_case.fixture[type].register(callback, value) end end base.register_attribute_observer(type, &observer) end end end class Fixture attr_reader :setup attr_reader :cleanup attr_reader :teardown def initialize(test_case) @test_case = test_case @setup = HookPoint.new(@test_case, :setup, :after => :append) @cleanup = HookPoint.new(@test_case, :cleanup, :before => :prepend) @teardown = HookPoint.new(@test_case, :teardown, :before => :prepend) @cached_before_callbacks = {} @cached_after_callbacks = {} end def [](type) case type when :setup @setup when :cleanup @cleanup when :teardown @teardown end end def before_callbacks(type) @cached_before_callbacks[type] ||= collect_before_callbacks(type) end def after_callbacks(type) @cached_after_callbacks[type] ||= collect_after_callbacks(type) end private def target_test_cases @cached_target_test_cases ||= collect_target_test_cases end def collect_before_callbacks(type) prepend_callbacks = [] append_callbacks = [] target_test_cases.each do |ancestor| prepend_callbacks << ancestor.fixture[type].before_prepend_callbacks append_callbacks << ancestor.fixture[type].before_append_callbacks end merge_callbacks(prepend_callbacks, append_callbacks) end def collect_after_callbacks(type) prepend_callbacks = [] append_callbacks = [] target_test_cases.each do |ancestor| prepend_callbacks << ancestor.fixture[type].after_prepend_callbacks append_callbacks << ancestor.fixture[type].after_append_callbacks end merge_callbacks(prepend_callbacks, append_callbacks) end def collect_target_test_cases ancestors = @test_case.ancestors base_index = ancestors.index(::Test::Unit::Fixture) interested_ancestors = ancestors[0, base_index].find_all do |ancestor| ancestor.is_a?(Class) end interested_ancestors.reverse end def merge_callbacks(prepend_callbacks, append_callbacks) all_callbacks = [] prepend_callbacks.reverse_each do |callbacks| all_callbacks.concat(callbacks) end append_callbacks.each do |callbacks| all_callbacks.concat(callbacks) end all_callbacks end end class HookPoint def initialize(test_case, type, default_options) @test_case = test_case @type = type @default_options = default_options @before_prepend_callbacks = [] @before_append_callbacks = [] @after_prepend_callbacks = [] @after_append_callbacks = [] @unregistered_callbacks = [] end def register(method_name_or_callback, options=nil) options ||= {} unless valid_register_options?(options) message = "must be {:before => :prepend}, " + "{:before => :append}, {:after => :prepend} or " + "{:after => :append}: #{options.inspect}" raise ArgumentError, message end if options.empty? options = @default_options end before_how = options[:before] after_how = options[:after] if method_name_or_callback.respond_to?(:call) callback = method_name_or_callback method_name = callback_method_name(callback) @test_case.attribute(:source_location, callback.source_location, method_name) @test_case.__send__(:define_method, method_name, &callback) else method_name = method_name_or_callback end add_callback(method_name, before_how, after_how) end def unregister(method_name_or_callback) if method_name_or_callback.respond_to?(:call) callback = method_name_or_callback method_name = callback_method_name(callback) else method_name = method_name_or_callback end @unregistered_callbacks << method_name end def before_prepend_callbacks @before_prepend_callbacks - @unregistered_callbacks end def before_append_callbacks @before_append_callbacks - @unregistered_callbacks end def after_prepend_callbacks @after_prepend_callbacks - @unregistered_callbacks end def after_append_callbacks @after_append_callbacks - @unregistered_callbacks end private def valid_register_options?(options) return true if options.empty? return false if options.size > 1 key = options.keys.first [:before, :after].include?(key) and [:prepend, :append].include?(options[key]) end def callback_method_name(callback) "#{@type}_#{callback.object_id}" end def add_callback(method_name_or_callback, before_how, after_how) case before_how when :prepend @before_prepend_callbacks = [method_name_or_callback] | @before_prepend_callbacks when :append @before_append_callbacks |= [method_name_or_callback] else case after_how when :prepend @after_prepend_callbacks = [method_name_or_callback] | @after_prepend_callbacks when :append @after_append_callbacks |= [method_name_or_callback] end end end end module ClassMethods def fixture @fixture ||= Fixture.new(self) end def setup(*method_names, &callback) register_fixture(:setup, *method_names, &callback) end def unregister_setup(*method_names_or_callbacks) unregister_fixture(:setup, *method_names_or_callbacks) end def cleanup(*method_names, &callback) register_fixture(:cleanup, *method_names, &callback) end def unregister_cleanup(*method_names_or_callbacks) unregister_fixture(:cleanup, *method_names_or_callbacks) end def teardown(*method_names, &callback) register_fixture(:teardown, *method_names, &callback) end def unregister_teardown(*method_names_or_callbacks) unregister_fixture(:teardown, *method_names_or_callbacks) end private def register_fixture(fixture, *method_names, &callback) options = {} options = method_names.pop if method_names.last.is_a?(Hash) callbacks = method_names callbacks << callback if callback attribute(fixture, options, *callbacks) end def unregister_fixture(fixture, *method_names_or_callbacks) attribute(fixture, nil, *method_names_or_callbacks) end end private def run_fixture(type, options={}, &block) fixtures = [ self.class.fixture.before_callbacks(type), type, self.class.fixture.after_callbacks(type), ].flatten if block runner = create_fixtures_runner(fixtures, options, &block) runner.call else fixtures.each do |method_name| run_fixture_callback(method_name, options) end end end def create_fixtures_runner(fixtures, options, &block) if fixtures.empty? block else last_fixture = fixtures.pop create_fixtures_runner(fixtures, options) do block_is_called = false run_fixture_callback(last_fixture, options) do block_is_called = true block.call end block.call unless block_is_called end end end def run_fixture_callback(method_name, options, &block) return unless respond_to?(method_name, true) begin __send__(method_name, &block) rescue Exception raise unless options[:handle_exception] raise unless handle_exception($!) end end def run_setup(&block) run_fixture(:setup, &block) end def run_cleanup run_fixture(:cleanup) end def run_teardown run_fixture(:teardown, :handle_exception => true) end end end end test-unit-3.3.9/lib/test/unit/test-suite-creator.rb0000644000004100000410000000607513775322563022333 0ustar www-datawww-data#-- # # Author:: Kouhei Sutou # Copyright:: # * Copyright (c) 2011 Kouhei Sutou # License:: Ruby license. require "test/unit/data-sets" module Test module Unit class TestSuiteCreator # :nodoc: class << self def test_method?(test_case, method_name) /\Atest./ =~ method_name.to_s or test_case.find_attribute(method_name, :test) end end def initialize(test_case) @test_case = test_case end def create suite = TestSuite.new(@test_case.name, @test_case) collect_test_names.each do |test_name| data_sets = extract_data_sets(test_name) if data_sets data_sets.each do |label, data| append_test(suite, test_name) do |test| test.assign_test_data(label, data) end end else append_test(suite, test_name) end end append_test(suite, "default_test") if suite.empty? suite end private def extract_data_sets(test_name) data_sets = @test_case.find_attribute(test_name, :data, :recursive => false) data_method_name = "data_#{test_name}" test = @test_case.new(test_name) if test.respond_to?(data_method_name) data_method = test.method(data_method_name) if data_method.arity <= 0 data_sets ||= DataSets.new data_sets << data_method end end data_sets end def append_test(suite, test_name) test = @test_case.new(test_name) yield(test) if block_given? suite << test if test.valid? end def collect_test_names methods = @test_case.public_instance_methods(true) super_test_case = @test_case.superclass methods -= super_test_case.public_instance_methods(true) methods |= @test_case.public_instance_methods(false) method_names = methods.collect(&:to_s) test_names = method_names.find_all do |method_name| self.class.test_method?(@test_case, method_name) end __send__("sort_test_names_in_#{@test_case.test_order}_order", test_names) end def sort_test_names_in_alphabetic_order(test_names) test_names.sort end def sort_test_names_in_random_order(test_names) test_names.sort_by {rand(test_names.size)} end def sort_test_names_in_defined_order(test_names) added_method_names = @test_case.added_method_names test_names.sort do |test1, test2| test1_defined_order = added_method_names.index(test1) test2_defined_order = added_method_names.index(test2) if test1_defined_order and test2_defined_order test1_defined_order <=> test2_defined_order elsif test1_defined_order 1 elsif test2_defined_order -1 else test1 <=> test2 end end end end end end test-unit-3.3.9/lib/test/unit/collector/0000755000004100000410000000000013775322563020221 5ustar www-datawww-datatest-unit-3.3.9/lib/test/unit/collector/objectspace.rb0000644000004100000410000000142313775322563023030 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit/collector' module Test module Unit module Collector class ObjectSpace include Collector NAME = 'collected from the ObjectSpace' def initialize(source=::ObjectSpace) super() @source = source end def collect(name=NAME) suite = TestSuite.new(name) sub_suites = [] @source.each_object(Class) do |klass| if(Test::Unit::TestCase > klass) add_suite(sub_suites, klass.suite) end end sort(sub_suites).each{|s| suite << s} suite end end end end end test-unit-3.3.9/lib/test/unit/collector/xml.rb0000644000004100000410000001650413775322563021354 0ustar www-datawww-data#-- # # Author:: Kouhei Sutou # Copyright:: # * Copyright (c) 2011 Kouhei Sutou # License:: Ruby license. # just test!!! don't use it yet!!! require 'test/unit/collector' require 'rexml/document' require 'rexml/streamlistener' module Test module Unit module Collector class XML include Collector def collect(xml_log_path) listener = Listener.new File.open(xml_log_path) do |xml_log| parser = REXML::Parsers::StreamParser.new(xml_log, listener) parser.parse end suite = TestSuite.new("tests in #{xml_log_path}") suites = listener.test_suites sort(suites).each {|s| add_suite(suite, s)} suite end class Listener include REXML::StreamListener attr_reader :test_suites def initialize @ns_stack = [{"xml" => :xml}] @tag_stack = [["", :root]] @text_stack = [''] @state_stack = [:root] @values = {} @test_suites = [] end def tag_start(name, attributes) @text_stack.push('') ns = @ns_stack.last.dup attrs = {} attributes.each do |n, v| if /\Axmlns(?:\z|:)/ =~ n ns[$POSTMATCH] = v else attrs[n] = v end end @ns_stack.push(ns) _parent_tag = parent_tag prefix, local = split_name(name) uri = _ns(ns, prefix) @tag_stack.push([uri, local]) state = next_state(@state_stack.last, uri, local) @state_stack.push(state) @values = {} case state when :test_suite, :test_case # do nothing when :test @n_pass_assertions = 0 if _parent_tag == "start-test" when :backtrace @backtrace = [] @values_backup = @values end end def tag_end(name) state = @state_stack.pop text = @text_stack.pop uri, local = @tag_stack.pop no_action_states = [:root, :stream] case state when *no_action_states # do nothing when :test_suite test_suite_end when :complete_test_case @test_suites.last << @test_case.suite when :test_case test_case_end when :result @result = @values when :test test_end when :pass_assertion @n_pass_assertions += 1 when :backtrace @values = @values_backup @values["backtrace"] = @backtrace when :entry file = @values['file'] line = @values['line'] info = @values['info'] @backtrace << "#{file}:#{line}: #{info}" @values = {} else local = normalize_local(local) @values[local] = text end @ns_stack.pop end def text(data) @text_stack.last << data end private def _ns(ns, prefix) ns.fetch(prefix, "") end NAME_SPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/ def split_name(name) name =~ NAME_SPLIT [$1 || '', $2] end STATE_TABLE = { :root => [:stream], :stream => [:ready_test_suite, :start_test_suite, :ready_test_case, :start_test_case, :start_test, :pass_assertion, :test_result, :complete_test, :complete_test_case, :complete_test_suite, :success], :ready_test_suite => [:n_tests], :start_test_suite => [:test_suite], :ready_test_case => [:test_case, :n_tests], :start_test_case => [:test_case], :start_test => [:test], :pass_assertion => [:test], :complete_test => [:test, :success], :complete_test_case => [:test_case, :elapsed, :success], :complete_test_suite => [:test_suite, :success], :test_suite => [:start_time, :elapsed], :test_case => [:name, :start_time, :elapsed], :test => [:name, :start_time, :elapsed], :test_result => [:test, :result], :result => [:test_case, :test, :status, :backtrace, :detail], :backtrace => [:entry], :entry => [:file, :line, :info], } def next_state(current_state, uri, local) local = normalize_local(local) valid_elements = STATE_TABLE[current_state] if valid_elements.nil? raise "unexpected element: #{current_path}" end next_state = local.to_sym unless valid_elements.include?(next_state) raise "unexpected element: #{current_path}" end next_state end def current_path locals = @tag_stack.collect do |uri, local| local end ["", *locals].join("/") end def normalize_local(local) local.gsub(/-/, "_") end def parent_tag @tag_stack.last[1] end def test_suite_end return unless parent_tag == "start-test-suite" suite = TestSuite.new ["start_time", "elapsed_time", "n_tests"].each do |key| if @values.has_key?(key) suite.instance_variable_set("@#{key}", @values[key]) end end @test_suites << suite end def test_case_end return unless parent_tag == "start-test-case" name = @values["name"] @test_case = Class.new(TestCase) do define_method(:name) do name end end end def test_end return unless parent_tag == "complete-test" name = @values["name"] n_pass_assertions = @n_pass_assertions result = @result @test_case.module_eval do test define_method(name) do n_pass_assertions.times do add_assertion end case result["status"] when "omission" add_omission(Omission.new(name, result["backtrace"], result["detail"])) end end end end end end end end end test-unit-3.3.9/lib/test/unit/collector/dir.rb0000644000004100000410000000631413775322563021330 0ustar www-datawww-datarequire 'test/unit/testsuite' require 'test/unit/collector' module Test module Unit module Collector class Dir include Collector attr_reader :pattern, :exclude attr_accessor :base def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil) super() @dir = dir @file = file @object_space = object_space @req = req @pattern = [/\btest_.*\.rb\Z/m] @exclude = [] @base = nil end def collect(*from) basedir = @base $:.push(basedir) if basedir if(from.empty?) recursive_collect('.', find_test_cases) elsif(from.size == 1) recursive_collect(from.first, find_test_cases) else suites = [] from.each do |f| suite = recursive_collect(f, find_test_cases) suites << suite unless(suite.tests.empty?) end suite = TestSuite.new("[#{from.join(', ')}]") sort(suites).each{|s| suite << s} suite end ensure $:.delete_at($:.rindex(basedir)) if basedir end def find_test_cases(ignore=[]) cases = [] @object_space.each_object(Class) do |c| cases << c if(c < TestCase && !ignore.include?(c)) end ignore.concat(cases) cases end def recursive_collect(name, already_gathered) sub_suites = [] path = realdir(name) if @file.directory?(path) dir_name = name unless name == '.' @dir.entries(path).each do |e| next if(e == '.' || e == '..') e_name = dir_name ? @file.join(dir_name, e) : e if @file.directory?(realdir(e_name)) next if /\A(?:CVS|\.svn|\.git)\z/ =~ e sub_suite = recursive_collect(e_name, already_gathered) sub_suites << sub_suite unless(sub_suite.empty?) else next if /~\z/ =~ e_name or /\A\.\#/ =~ e if @pattern and !@pattern.empty? next unless @pattern.any? {|pat| pat =~ e_name} end if @exclude and !@exclude.empty? next if @exclude.any? {|pat| pat =~ e_name} end collect_file(e_name, sub_suites, already_gathered) end end else collect_file(name, sub_suites, already_gathered) end suite = TestSuite.new(@file.basename(name)) sort(sub_suites).each{|s| suite << s} suite end def collect_file(name, suites, already_gathered) dir = @file.dirname(@file.expand_path(name, @base)) $:.unshift(dir) if(@req) @req.require(name) else require(name) end find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)} ensure $:.delete_at($:.rindex(dir)) if(dir) end def realdir(path) if @base @file.join(@base, path) else path end end end end end end test-unit-3.3.9/lib/test/unit/collector/descendant.rb0000644000004100000410000000056013775322563022657 0ustar www-datawww-datarequire 'test/unit/collector' module Test module Unit module Collector class Descendant include Collector NAME = 'collected from the subclasses of TestCase' def collect(name=NAME) suite = TestSuite.new(name) add_test_cases(suite, TestCase::DESCENDANTS) suite end end end end end test-unit-3.3.9/lib/test/unit/collector/load.rb0000644000004100000410000001335513775322563021474 0ustar www-datawww-datarequire 'pathname' require 'test/unit/testsuite' require 'test/unit/collector' module Test module Unit module Collector class Load include Collector attr_reader :patterns, :excludes, :base attr_reader :default_test_paths def initialize super @system_excludes = [/~\z/, /\A\.\#/] @system_directory_excludes = [/\A(?:CVS|\.svn|\.git)\z/] @patterns = [/\Atest[_\-].+\.rb\z/m, /[_\-]test\.rb\z/] @excludes = [] @base = nil @default_test_paths = [] @require_failed_infos = [] end def base=(base) base = Pathname(base) unless base.nil? @base = base end def default_test_paths=(paths) @default_test_paths = paths.collect do |path| Pathname(path) end end def collect(*froms) add_load_path(@base) do froms = @default_test_paths if froms.empty? froms = ["."] if froms.empty? test_suites = [] already_gathered = find_test_cases froms.each do |from| from = resolve_path(from) if from.directory? test_suite = collect_recursive(from, already_gathered) test_suites << test_suite unless test_suite.tests.empty? else collect_file(from, test_suites, already_gathered) end end add_require_failed_test_suite(test_suites) if test_suites.size > 1 test_suite = TestSuite.new("[#{froms.join(', ')}]") sort(test_suites).each do |sub_test_suite| test_suite << sub_test_suite end else test_suite = test_suites.first end test_suite end end def find_test_cases(ignore=[]) test_cases = [] TestCase::DESCENDANTS.each do |test_case| test_cases << test_case unless ignore.include?(test_case) end ignore.concat(test_cases) test_cases end private def collect_recursive(path, already_gathered) sub_test_suites = [] if path.directory? directories, files = path.children.partition do |child| child.directory? end files.each do |child| next if excluded_file?(child.basename.to_s) collect_file(child, sub_test_suites, already_gathered) end directories.each do |child| next if excluded_directory?(child.basename.to_s) sub_test_suite = collect_recursive(child, already_gathered) sub_test_suites << sub_test_suite unless sub_test_suite.empty? end else unless excluded_file?(path.basename.to_s) collect_file(path, sub_test_suites, already_gathered) end end test_suite = TestSuite.new(path.basename.to_s) sort(sub_test_suites).each do |sub_test_suite| test_suite << sub_test_suite end test_suite end def collect_file(path, test_suites, already_gathered) @program_file ||= File.expand_path($0) expanded_path = path.expand_path return if @program_file == expanded_path.to_s add_load_path(expanded_path.dirname) do begin require(expanded_path.to_s) rescue LoadError @require_failed_infos << {:path => expanded_path, :exception => $!} end add_test_cases(test_suites, find_test_cases(already_gathered)) end end def resolve_path(path) if @base @base + path else Pathname(path) end end def add_load_path(path) return yield if path.nil? path = path.to_s begin $LOAD_PATH.unshift(path) yield ensure index = $LOAD_PATH.index(path) $LOAD_PATH.delete_at(index) if index end end def excluded_directory?(base) @system_directory_excludes.any? {|pattern| pattern =~ base} end def excluded_file?(base) return true if @system_excludes.any? {|pattern| pattern =~ base} patterns = @patterns || [] unless patterns.empty? return true unless patterns.any? {|pattern| pattern =~ base} end excludes = @excludes || [] unless excludes.empty? return true if excludes.any? {|pattern| pattern =~ base} end false end def add_require_failed_test_suite(test_suites) return if @require_failed_infos.empty? require_failed_infos = @require_failed_infos require_failed_errors = Class.new(Test::Unit::TestCase) require_failed_errors.class_eval do class << self def name "RequireFailedErrors" end end require_failed_infos.each do |info| path = info[:path] normalized_path = path.to_s.gsub(/[^a-z0-9\_]+/i, '_') normalized_path = normalized_path.gsub(/\A_+/, '') exception = info[:exception] define_method("test_require_#{normalized_path}") do raise(exception.class, "failed to load <#{path}>: #{exception.message}", exception.backtrace) end end def priority 100 end end add_suite(test_suites, require_failed_errors.suite) end end end end end test-unit-3.3.9/lib/test/unit/notification.rb0000644000004100000410000000657013775322563021256 0ustar www-datawww-datarequire 'test/unit/util/backtracefilter' module Test module Unit class Notification include Util::BacktraceFilter attr_reader :test_name, :location, :message attr_reader :method_name SINGLE_CHARACTER = 'N' LABEL = "Notification" # Creates a new Notification with the given location and # message. def initialize(test_name, location, message, options={}) @test_name = test_name @location = location @message = message @method_name = options[:method_name] end # Returns a single character representation of a notification. def single_character_display SINGLE_CHARACTER end def label LABEL end # Returns a brief version of the error description. def short_display "#{@test_name}: #{@message.split("\n")[0]}" end # Returns a verbose version of the error description. def long_display backtrace = filter_backtrace(location).join("\n") "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" end # Overridden to return long_display. def to_s long_display end def critical? false end end class NotifiedError < StandardError end module TestCaseNotificationSupport class << self def included(base) base.class_eval do include NotificationHandler end end end # Notify some information. # # Example: # # def test_notification # notify("I'm here!") # # Reached here # notify("Special!") if special_case? # # Reached here too # end # # options: # # :backtrace override backtrace. def notify(message, options={}, &block) backtrace = filter_backtrace(options[:backtrace] || caller) notification = Notification.new(name, backtrace, message, :method_name => @method_name) add_notification(notification) end private def add_notification(notification) current_result.add_notification(notification) end end module NotificationHandler class << self def included(base) base.exception_handler(:handle_notified_error) end end private def handle_notified_error(exception) return false unless exception.is_a?(NotifiedError) notification = Notification.new(name, filter_backtrace(exception.backtrace), exception.message) add_notification(notification) true end end module TestResultNotificationSupport attr_reader :notifications # Records a Test::Unit::Notification. def add_notification(notification) @notifications << notification notify_fault(notification) notify_changed end # Returns the number of notifications this TestResult has # recorded. def notification_count @notifications.size end private def initialize_containers super @notifications = [] @summary_generators << :notification_summary end def notification_summary "#{notification_count} notifications" end end end end test-unit-3.3.9/lib/test/unit/auto-runner-loader.rb0000644000004100000410000000057313775322563022310 0ustar www-datawww-datarequire "test/unit/test-suite-creator" module Test module Unit module AutoRunnerLoader @loaded = false class << self def check(test_case, method_name) return if @loaded return unless TestSuiteCreator.test_method?(test_case, method_name) require "test/unit" @loaded = true end end end end end test-unit-3.3.9/lib/test/unit/attribute-matcher.rb0000644000004100000410000000065713775322563022214 0ustar www-datawww-datamodule Test module Unit class AttributeMatcher def initialize(test) @test = test end def match?(expression) matched = instance_eval(expression) if matched.nil? false else matched end end def method_missing(name, *args) if args.empty? @test[name] else super end end end end end test-unit-3.3.9/lib/test/unit.rb0000644000004100000410000004015713775322563016567 0ustar www-datawww-datarequire 'test/unit/testcase' require 'test/unit/autorunner' module Test # :nodoc: # # # Test::Unit - Ruby Unit Testing Framework # # ## Introduction # # Unit testing is making waves all over the place, largely due to the # fact that it is a core practice of XP. While XP is great, unit testing # has been around for a long time and has always been a good idea. One # of the keys to good unit testing, though, is not just writing tests, # but having tests. What's the difference? Well, if you just _write_ a # test and throw it away, you have no guarantee that something won't # change later which breaks your code. If, on the other hand, you _have_ # tests (obviously you have to write them first), and run them as often # as possible, you slowly build up a wall of things that cannot break # without you immediately knowing about it. This is when unit testing # hits its peak usefulness. # # Enter Test::Unit, a framework for unit testing in Ruby, helping you to # design, debug and evaluate your code by making it easy to write and # have tests for it. # # # ## Notes # # Test::Unit has grown out of and superceded Lapidary. # # # ## Feedback # # I like (and do my best to practice) XP, so I value early releases, # user feedback, and clean, simple, expressive code. There is always # room for improvement in everything I do, and Test::Unit is no # exception. Please, let me know what you think of Test::Unit as it # stands, and what you'd like to see expanded/changed/improved/etc. If # you find a bug, let me know ASAP; one good way to let me know what the # bug is is to submit a new test that catches it :-) Also, I'd love to # hear about any successes you have with Test::Unit, and any # documentation you might add will be greatly appreciated. My contact # info is below. # # # ## Contact Information # # * [GitHub issues on # test-unit/test-unit](https://github.com/test-unit/test-unit/issues): # If you have any issues, please report them to here. # # * [GitHub pull requests on # test-unit/test-unit](https://github.com/test-unit/test-unit/pulls): # If you have any patches, please report them to here. # # * [ruby-talk mailing # list](https://www.ruby-lang.org/en/community/mailing-lists/): # If you have any questions, you can ask them here. # # # ## Credits # # I'd like to thank... # # Matz, for a great language! # # Masaki Suketa, for his work on RubyUnit, which filled a vital need in # the Ruby world for a very long time. I'm also grateful for his help in # polishing Test::Unit and getting the RubyUnit compatibility layer # right. His graciousness in allowing Test::Unit to supercede RubyUnit # continues to be a challenge to me to be more willing to defer my own # rights. # # Ken McKinlay, for his interest and work on unit testing, and for his # willingness to dialog about it. He was also a great help in pointing # out some of the holes in the RubyUnit compatibility layer. # # Dave Thomas, for the original idea that led to the extremely simple # "require 'test/unit'", plus his code to improve it even more by # allowing the selection of tests from the command-line. Also, without # RDoc, the documentation for Test::Unit would stink a lot more than it # does now. # # Everyone who's helped out with bug reports, feature ideas, # encouragement to continue, etc. It's a real privilege to be a part of # the Ruby community. # # The guys at RoleModel Software, for putting up with me repeating, "But # this would be so much easier in Ruby!" whenever we're coding in Java. # # My Creator, for giving me life, and giving it more abundantly. # # # ## License # # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free # software, and is distributed under the Ruby license. See the COPYING # file. # # Exception: lib/test/unit/diff.rb is copyright (c) # 2008-2010 Kouhei Sutou and 2001-2008 Python Software # Foundation. It is free software, and is distributed # under the Ruby license and/or the PSF license. See the # COPYING file and PSFL file. # # ## Warranty # # This software is provided "as is" and without any express or # implied warranties, including, without limitation, the implied # warranties of merchantibility and fitness for a particular # purpose. # # # ## Author # # Nathaniel Talbott. # Copyright (c) 2000-2003, Nathaniel Talbott # # ---- # # # Usage # # The general idea behind unit testing is that you write a _test_ # _method_ that makes certain _assertions_ about your code, working # against a _test_ _fixture_. A bunch of these _test_ _methods_ are # bundled up into a _test_ _suite_ and can be run any time the # developer wants. The results of a run are gathered in a _test_ # _result_ and displayed to the user through some UI. So, lets break # this down and see how Test::Unit provides each of these necessary # pieces. # # # ## Assertions # # These are the heart of the framework. Think of an assertion as a # statement of expected outcome, i.e. "I assert that x should be equal # to y". If, when the assertion is executed, it turns out to be # correct, nothing happens, and life is good. If, on the other hand, # your assertion turns out to be false, an error is propagated with # pertinent information so that you can go back and make your # assertion succeed, and, once again, life is good. For an explanation # of the current assertions, see Test::Unit::Assertions. # # # ## Test Method & Test Fixture # # Obviously, these assertions have to be called within a context that # knows about them and can do something meaningful with their # pass/fail value. Also, it's handy to collect a bunch of related # tests, each test represented by a method, into a common test class # that knows how to run them. The tests will be in a separate class # from the code they're testing for a couple of reasons. First of all, # it allows your code to stay uncluttered with test code, making it # easier to maintain. Second, it allows the tests to be stripped out # for deployment, since they're really there for you, the developer, # and your users don't need them. Third, and most importantly, it # allows you to set up a common test fixture for your tests to run # against. # # What's a test fixture? Well, tests do not live in a vacuum; rather, # they're run against the code they are testing. Often, a collection # of tests will run against a common set of data, also called a # fixture. If they're all bundled into the same test class, they can # all share the setting up and tearing down of that data, eliminating # unnecessary duplication and making it much easier to add related # tests. # # Test::Unit::TestCase wraps up a collection of test methods together # and allows you to easily set up and tear down the same test fixture # for each test. This is done by overriding #setup and/or #teardown, # which will be called before and after each test method that is # run. The TestCase also knows how to collect the results of your # assertions into a Test::Unit::TestResult, which can then be reported # back to you... but I'm getting ahead of myself. To write a test, # follow these steps: # # * Make sure Test::Unit is in your library path. # * require 'test/unit' in your test script. # * Create a class that subclasses Test::Unit::TestCase. # * Add a method that begins with "test" to your class. # * Make assertions in your test method. # * Optionally define #setup and/or #teardown to set up and/or tear # down your common test fixture. # * You can now run your test as you would any other Ruby # script... try it and see! # # A really simple test might look like this (#setup and #teardown are # commented out to indicate that they are completely optional): # # require 'test/unit' # # class MyTest < Test::Unit::TestCase # # def setup # # end # # # def teardown # # end # # def test_fail # assert(false, 'Assertion was false.') # end # end # # # ## Test Runners # # So, now you have this great test class, but you still # need a way to run it and view any failures that occur # during the run. There are some test runner; console test # runner, GTK+ test runner and so on. The console test # runner is automatically invoked for you if you require # 'test/unit' and simply run the file. To use another # runner simply set default test runner ID to # Test::Unit::AutoRunner: # # require 'test/unit' # Test::Unit::AutoRunner.default_runner = "gtk2" # # ## Test Suite # # As more and more unit tests accumulate for a given project, it # becomes a real drag running them one at a time, and it also # introduces the potential to overlook a failing test because you # forget to run it. Suddenly it becomes very handy that the # TestRunners can take any object that returns a Test::Unit::TestSuite # in response to a suite method. The TestSuite can, in turn, contain # other TestSuites or individual tests (typically created by a # TestCase). In other words, you can easily wrap up a group of # TestCases and TestSuites. # # Test::Unit does a little bit more for you, by wrapping # these up automatically when you require # 'test/unit'. What does this mean? It means you could # write the above test case like this instead: # # require 'test/unit' # require 'test_myfirsttests' # require 'test_moretestsbyme' # require 'test_anothersetoftests' # # Test::Unit is smart enough to find all the test cases existing in # the ObjectSpace and wrap them up into a suite for you. It then runs # the dynamic suite using the console TestRunner. # # # ## Configuration file # # Test::Unit reads 'test-unit.yml' in the current working # directory as Test::Unit's configuration file. It can # contain the following configurations: # # * color scheme definitions # * test runner to be used # * test runner options # * test collector to be used # # Except color scheme definitions, all of them are # specified by command line option. # # Here are sample color scheme definitions: # # color_schemes: # inverted: # success: # name: red # bold: true # failure: # name: green # bold: true # other_scheme: # ... # # Here are the syntax of color scheme definitions: # # color_schemes: # SCHEME_NAME: # EVENT_NAME: # name: COLOR_NAME # intensity: BOOLEAN # bold: BOOLEAN # italic: BOOLEAN # underline: BOOLEAN # ... # ... # # SCHEME_NAME # : the name of the color scheme # # EVENT_NAME # : one of [success, failure, pending, omission, notification, error] # # COLOR_NAME # : one of [black, red, green, yellow, blue, magenta, cyan, white] # # BOOLEAN # : true or false # # You can use the above 'inverted' color scheme with the # following configuration: # # runner: console # console_options: # color_scheme: inverted # color_schemes: # inverted: # success: # name: red # bold: true # failure: # name: green # bold: true # # ## Questions? # # I'd really like to get feedback from all levels of Ruby # practitioners about typos, grammatical errors, unclear statements, # missing points, etc., in this document (or any other). # module Unit class << self # Set true when Test::Unit has run. If set to true Test::Unit # will not automatically run at exit. # # @deprecated Use Test::Unit::AutoRunner.need_auto_run= instead. def run=(have_run) AutoRunner.need_auto_run = (not have_run) end # Already tests have run? # # @deprecated Use Test::Unit::AutoRunner.need_auto_run? instead. def run? not AutoRunner.need_auto_run? end # @api private @@at_start_hooks = [] # Regsiter a hook that is run before running tests. # To register multiple hooks, call this method multiple times. # # Here is an example test case: # # Test::Unit.at_start do # # ... # end # # class TestMyClass1 < Test::Unit::TestCase # class << self # def startup # # ... # end # end # # def setup # # ... # end # # def test_my_class1 # # ... # end # # def test_my_class2 # # ... # end # end # # class TestMyClass2 < Test::Unit::TestCase # class << self # def startup # # ... # end # end # # def setup # # ... # end # # def test_my_class1 # # ... # end # # def test_my_class2 # # ... # end # end # # Here is a call order: # # * at_start # * TestMyClass1.startup # * TestMyClass1#setup # * TestMyClass1#test_my_class1 # * TestMyClass1#setup # * TestMyClass1#test_my_class2 # * TestMyClass2#setup # * TestMyClass2#test_my_class1 # * TestMyClass2#setup # * TestMyClass2#test_my_class2 # # @example # Test::Unit.at_start do # puts "Start!" # end # # @yield A block that is run before running tests. # @yieldreturn [void] # @return [void] # # @since 2.5.2 def at_start(&hook) @@at_start_hooks << hook end # @api private def run_at_start_hooks @@at_start_hooks.each do |hook| hook.call end end # @api private @@at_exit_hooks = [] # Regsiter a hook that is run after running tests. # To register multiple hooks, call this method multiple times. # # Here is an example test case: # # Test::Unit.at_exit do # # ... # end # # class TestMyClass1 < Test::Unit::TestCase # class << self # def shutdown # # ... # end # end # # def teardown # # ... # end # # def test_my_class1 # # ... # end # # def test_my_class2 # # ... # end # end # # class TestMyClass2 < Test::Unit::TestCase # class << self # def shutdown # # ... # end # end # # def teardown # # ... # end # # def test_my_class1 # # ... # end # # def test_my_class2 # # ... # end # end # # Here is a call order: # # * TestMyClass1#test_my_class1 # * TestMyClass1#teardown # * TestMyClass1#test_my_class2 # * TestMyClass1#teardown # * TestMyClass1.shutdown # * TestMyClass2#test_my_class1 # * TestMyClass2#teardown # * TestMyClass2#test_my_class2 # * TestMyClass2#teardown # * TestMyClass2.shutdown # * at_exit # # @example # Test::Unit.at_exit do # puts "Exit!" # end # # @yield A block that is run after running tests. # @yieldreturn [void] # @return [void] # # @since 2.5.2 def at_exit(&hook) @@at_exit_hooks << hook end # @api private def run_at_exit_hooks @@at_exit_hooks.each do |hook| hook.call end end end end end Module.new do at_exit do if $!.nil? and Test::Unit::AutoRunner.need_auto_run? exit Test::Unit::AutoRunner.run end end end test-unit-3.3.9/lib/test-unit.rb0000644000004100000410000000065413775322563016563 0ustar www-datawww-data# Copyright (C) 2012-2015 Kouhei Sutou module Test module Unit autoload :TestCase, "test/unit/testcase" autoload :AutoRunner, "test/unit/autorunner" end end unless respond_to?(:run_test, true) # experimental. It is for "ruby -rtest-unit -e run_test test/test_*.rb". # Is this API OK or dirty? def run_test self.class.send(:undef_method, :run_test) require "test/unit" end end test-unit-3.3.9/doc/0000755000004100000410000000000013775322563014274 5ustar www-datawww-datatest-unit-3.3.9/doc/text/0000755000004100000410000000000013775322563015260 5ustar www-datawww-datatest-unit-3.3.9/doc/text/getting-started.md0000644000004100000410000001134413775322563020712 0ustar www-datawww-data## 1. First step of the `test-unit` Let's getting start `test-unit`. This document creates an example gem package called `sample` with the `test-unit` testing framework. ## 2. Install bundler and test-unit. * First, install the `bundler` gem for generating gem template. * Second, install the `test-unit` itself. ~~~ !!!plain gem install bundler gem install test-unit ~~~ The `gem list` command output installed packages. You will find the following lines. ~~~ !!!plain gem list ... bundler (1.14.6) ... test-unit (3.2.3) ~~~ ## 3. Create gem template. Next, create a gem template using `bundler` command. This command generates package skeleton with a testing framework. However, this command can't generate test templates for `test-unit`. So, First create gem template with the `minitest` testing framework. (It's similar to `unit-test`). After that, replace some files for `test-unit`. The `bundle gem -t minitest sample` command will generate the following files. ~~~ !!!plain . |-- Gemfile |-- README.md |-- Rakefile |-- bin | |-- console | `-- setup |-- lib | |-- sample | | `-- version.rb | `-- sample.rb |-- sample.gemspec # <- Modify `-- test |-- sample_test.rb # <- Modify `-- test_helper.rb # <- Modify ~~~ ## 4. Edit files for `test-unit` ### 4.1. Edit gemspec Edit `sample.gemspec` like the below. Replace `minitest` line to `test-unit`. Before ~~~ !!!ruby spec.add_development_dependency "minitest", "~> 5.0" ~~~ After ~~~ !!!ruby spec.add_development_dependency "test-unit", "~> 3.2.3" ~~~ ### 4.2. Edit `test/test_helper.rb` Next, edit the `test/test_helper.rb` file. Before ~~~ !!!ruby $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'sample' require 'minitest/autorun' # <-- Modify this line. ~~~ After ~~~ !!!ruby $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'sample' require 'test/unit' # <-- After modification. ~~~ ### 4.3 Rakefile (No edit) This file doesn't need to modify. The output is the below. ~~~ !!!ruby require "bundler/gem_tasks" require "rake/testtask" Rake::TestTask.new(:test) do |t| t.libs << "test" t.libs << "lib" t.test_files = FileList['test/**/*_test.rb'] end task :default => :test ~~~ ### 4.4 Edit `test/sample_test.rb` The bundler generate the file `test/sample_test.rb`. This file originally templates for `minitest`. Let's modify this file for `test-unit` before ~~~ !!!ruby require 'test_helper' class SampleTest < Minitest::Test # <- Modify here def test_that_it_has_a_version_number refute_nil ::Sample::VERSION end def test_it_does_something_useful assert false end end ~~~ After ~~~ !!!ruby require 'test_helper' class SampleTest < Test::Unit::TestCase # <- After modification def test_that_it_has_a_version_number refute_nil ::Sample::VERSION end def test_it_does_something_useful assert false end end ~~~ ## 5. Execute test. The `rake test` command execute test scenarios in the `test` directory. Now it tries to two tests. One will success the other one fails. ~~~ !!!plain rake test Loaded suite /path/to/ruby/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/rake_test_loader Started F ================================================================================ Failure: is not true. test_it_does_something_useful(SampleTest) /path/to/sample/test/sample_test.rb:9:in `test_it_does_something_useful' 6: end 7: 8: def test_it_does_something_useful => 9: assert false 10: end 11: end ================================================================================ . Finished in 0.011521 seconds. -------------------------------------------------------------------------------- 2 tests, 2 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 50% passed -------------------------------------------------------------------------------- 173.60 tests/s, 173.60 assertions/s rake aborted! Command failed with status (1) Tasks: TOP => test (See full trace by running task with --trace) ~~~ ## 6. Create original tests. Let's create your original tests with the following rules. * Create a test file in the `test` directory. * The file needs suffix `xxx_test.rb`. * You can put test file into the subdirectory like `test/sub`. Example directory layout. ~~~ !!!plain test |-- sample_test.rb |-- sub | `-- sample2_test.rb `-- test_helper.rb ~~~ Example test file in the sub directory. ~~~ !!!ruby require 'test_helper' module Sub class Sample2Test < Test::Unit::TestCase def test_that_it_has_a_version_number refute_nil ::Sample::VERSION end def test_it_does_something_useful assert false end end end ~~~ ## 7. For more inforomation Let's read the official document. * [test-unit](http://test-unit.github.io/index.html) test-unit-3.3.9/doc/text/how-to.md0000644000004100000410000000426113775322563017022 0ustar www-datawww-data# How To ## Run all tests To make it easy to run all your tests, you can add a `run_test.rb` script to your `test` directory. A simple example might look like: base_dir = File.expand_path(File.join(File.dirname(__FILE__), "..")) lib_dir = File.join(base_dir, "lib") test_dir = File.join(base_dir, "test") $LOAD_PATH.unshift(lib_dir) require 'test/unit' exit Test::Unit::AutoRunner.run(true, test_dir) Then it's easy to run tests via the command line with, $ ruby test/run_test.rb ## Change test runner via the command line The output format can be changed via the command line with the `--runner` option. Simply tack it to the end: ruby test/run_test.rb --runner tap ## Configure test-unit per-project Test::Unit reads `test-unit.yml` or `.test-unit.yml` in the current working directory as Test::Unit's configuration file. It can contain the following settings: * color scheme definitions * test runner to be used * test runner options * test collector to be used Except color scheme definitions, all of them can be specified by command line option. Here are sample color scheme definitions: color_schemes: inverted: success: name: red bold: true failure: name: green bold: true other_scheme: ... Here are the syntax of color scheme definitions: color_schemes: SCHEME_NAME: EVENT_NAME: name: COLOR_NAME intensity: BOOLEAN bold: BOOLEAN italic: BOOLEAN underline: BOOLEAN ... ... | Definition | Description | |-------------|------------------------------| | SCHEME_NAME | the name of the color scheme | | EVENT_NAME | success, failure, pending, omission, notification, error | | COLOR_NAME | black, red, green, yellow, blue, magenta, cyan, white | | BOOLEAN | true or false | You can use the above 'inverted' color scheme with the following configuration: runner: console console_options: color_scheme: inverted color_schemes: inverted: success: name: red bold: true failure: name: green bold: true test-unit-3.3.9/doc/text/news.md0000644000004100000410000011233313775322563016561 0ustar www-datawww-data# News ## 3.3.9 - 2020-12-29 {#version-3-3-9} ### Improvements * `assert_not_match`: Add support for `String` as pattern. [GitHub#178][Patch by David Rodríguez] ### Thanks * David Rodríguez ## 3.3.8 - 2020-12-25 {#version-3-3-8} ### Improvements * [UI][console]: Removed reverse mode because Ruby 3.0 reverts reverse backtrace. ## 3.3.7 - 2020-11-18 {#version-3-3-7} ### Improvements * Improved TruffleRuby support. [GitHub#171][Reported by Benoit Daloze] * Removed needless `to_sym`. [GitHub#177][Patch by icm7216] * `assert_raise`: Added backtrace for actual error. * Improved terminal color availability detection. [GitHub#175][Patch by nicholas a. evans] * Changed license to the new Ruby's. [GitHub#174] ### Fixes * Fixed a typo in `--help` output: [GitHub#176][Patch by icm7216] ### Thanks * Benoit Daloze * icm7216 * nicholas a. evans ## 3.3.6 - 2020-06-10 {#version-3-3-6} ### Improvements * `name`, `--ignore-name`: * Added support for regular expression options. * Added support for matching with class name in exact match mode. [Reported by Jun Aruga] * Updated ruby-talk mailing list information [GitHub#168][Patch by Chris Kampmeier] ### Thanks * Chris Kampmeier * Jun Aruga ## 3.3.5 - 2020-01-10 {#version-3-3-5} ### Improvements * Improved code snippet showing with different default external encoding. [GitHub#166][Patch by Yuta Iwama] ### Thanks * Yuta Iwama ## 3.3.4 - 2019-09-30 {#version-3-3-4} ### Improvements * Converted markup format to Markdown from RDoc. [GitHub#164][Patch by OGAWA KenIchi] * test: Stopped to depend on `Time#inspect` format. [GitHub#165][Reported by Benoit Daloze] ### Thanks * OGAWA KenIchi * Benoit Daloze ## 3.3.3 - 2019-05-10 {#version-3-3-3} ### Fixed * Fixed a bug that priority mode with test case name that uses special characters such as `?` can't be used on Windows. ## 3.3.2 - 2019-04-11 {#version-3-3-2} ### Fixes * Fixed a bug that `Test::Unit::Collector::Load` doesn't load test files under sub directories when these files have the same base name as test files in upper directories. [Reported by Kenta Murata] ### Thanks * Kenta Murata ## 3.3.1 - 2019-03-27 {#version-3-3-1} ### Improvements * Added support for `Test::Unit::AssertionFailedError#user_message` for not only `assert_equal` and `assert_raise` but also all assertions. [GitHub#162][Reported by xgraffm] ### Thanks * xgraffm ## 3.3.0 - 2019-01-23 {#version-3-3-0} ### Improvements * Added support for auto test run when all tests are defined in modules. * Added support for defining methods to test case class in multiple threads. [GitHub#159][Reported by Charles Oliver Nutter] * Suppressed warnings on Ruby 2.5. [GitHub#160][Reported by Daniel Berger] * Suppressed warnings on Ruby 2.7. ### Fixes * Fixed a code snippet fetch failure when source code isn't UTF-8 and the default external encoding is set to not UTF-8. [GitHub#161][Reported by masa kunikata] ### Thanks * Charles Oliver Nutter * Daniel Berger * masa kunikata ## 3.2.9 - 2018-12-01 {#version-3-2-9} ### Improvements * Added support for data generation by method. `data_#{test_name}` is called to generate data for `test_name` test. * Added support for data matrix generation. Example: ```ruby data(:a, [0, 1, 2]) data(:b, [:x, :y]) def test_data(data) end ``` This example generates the following data matrix: * label: `"a: 0, b: :x"`, data: `{a: 0, b: :x}` * label: `"a: 0, b: :y"`, data: `{a: 0, b: :y}` * label: `"a: 1, b: :x"`, data: `{a: 1, b: :x}` * label: `"a: 1, b: :y"`, data: `{a: 1, b: :y}` * label: `"a: 2, b: :x"`, data: `{a: 2, b: :x}` * label: `"a: 2, b: :y"`, data: `{a: 2, b: :y}` * Added `Test::Unit::TestCase#data` that returns the current data. * Added support for using test method that doesn't have no parameters as data driven test. Example: ```ruby data("label", :value) def test_data # Available since this release p data # :value end ``` * Added support for `:keep` option to `Test::Unit::TestCase.data`. * Added support for `:group` option to `Test::Unit::TestCase.data`. It's useful to generate multiple data matrix groups. ```ruby # Group1 data(:a, [0, 1, 2], group: :g1) data(:b, [:x, :y], group: :g1) # Group2 data(:a, [:x, :y], group: :g2) data(:c, [-1, -2], group: :g2) def test_data(data) end ``` This example generates the following data matrix: * label: `"group: :g1, a: 0, b: :x"`, data: `{a: 0, b: :x}` * label: `"group: :g1, a: 0, b: :y"`, data: `{a: 0, b: :y}` * label: `"group: :g1, a: 1, b: :x"`, data: `{a: 1, b: :x}` * label: `"group: :g1, a: 1, b: :y"`, data: `{a: 1, b: :y}` * label: `"group: :g1, a: 2, b: :x"`, data: `{a: 2, b: :x}` * label: `"group: :g1, a: 2, b: :y"`, data: `{a: 2, b: :y}` * label: `"group: :g2, a: :x, b: -1"`, data: `{a: :x, b: -1}` * label: `"group: :g2, a: :x, b: -2"`, data: `{a: :x, b: -2}` * label: `"group: :g2, a: :y, b: -1"`, data: `{a: :y, b: -1}` * label: `"group: :g2, a: :y, b: -2"`, data: `{a: :y, b: -2}` ## 3.2.8 - 2018-05-13 {#version-3-2-8} ### Improvements * [UI][console]: Changed to put code snippet before backtrace on reverse mode. ## 3.2.7 - 2017-12-12 {#version-3-2-7} ### Improvements * Added source code link to gemspec. [GitHub#157][Patch by Grey Baker] * Changed to use SVG image for badges in README. [GitHub#158][Patch by Olle Jonsson] * [UI][console]: Added `--reverse-output` option to output fault details in reverse like Ruby 2.5. It's enabled by default only for tty output. ### Fixes * Fixed a typo. [GitHub#156][Patch by masa kunikata] * [UI][console]: Fixed a bug that broken align in verbose mode. ### Thanks * masa kunikata * Grey Baker * Olle Jonsson ## 3.2.6 - 2017-09-21 {#version-3-2-6} ### Improvements * Changed test file require failure to error from omission. [GitHub#154][Patch by naofumi-fujii] ### Thanks * naofumi-fujii ## 3.2.5 - 2017-06-24 {#version-3-2-5} ### Improvements * Supported `--enable-frozen-string-literal` `ruby` option. [GitHub#149][Reported by Pat Allan] ### Thanks * Pat Allan ## 3.2.4 - 2017-05-23 {#version-3-2-4} ### Improvements * Updated tests for Ruby 2.4. [GitHUb#136][Patch by Kazuki Tsujimoto] * Supported power\_assert 1.0.0. [GitHub#137][Patch by Kazuki Tsujimoto] * Added the getting started document. [GitHub#139][GitHub#141][Patch by Hiroyuki Sato] * Added the document for `attribute`. [GitHub#143][Patch by Fumiaki MATSUSHIMA] * Improved a link for GitHub. [GitHub#144][Patch by rochefort] * Updated `.travis.yml`. [GitHub#145][Patch by Jun Aruga] ### Fixes * Fixed a contributor name. [GitHub#131][Patch by Akira Matsuda] * Fixed typos in document. [GitHub#132][Patch by Akira Matsuda] * Fixed typos in document. [GitHub#134][Patch by Yuji Yaginuma] * Fixed a bug that data label with "(" isn't supported. [GitHub#135][Reported by Kazuki Tsujimoto] * Fixed assertion message in English. [GitHub#133][Reported by Khalil Fazal] * Fixed a typo in typo fix. [GitHub#138][Patch by kami] * Fixed a bug that target location finder may return wrong location. [GitHub#146][Patch by Yuki Ito] * Fixed a bug that `--no-show-detail-immediately` raises an error. [GitHub#147][Reported by MSP-Greg] ### Thanks * Akira Matsuda * Yuji Yaginuma * Kazuki Tsujimoto * Khalil Fazal * kami * Hiroyuki Sato * Fumiaki MATSUSHIMA * rochefort * Jun Aruga * Yuki Ito * MSP-Greg ## 3.2.3 - 2016-11-25 {#version-3-2-3} ### Fixes * Fixed a bug that `--order` isn't applied. [GitHub#129][Reported by Vít Ondruch] ### Thanks * Vít Ondruch ## 3.2.2 - 2016-11-02 {#version-3-2-2} ### Improvements * Improved Travis CI configuration. [GitHub#123][Patch by Ryunosuke Sato] * Supported Java native exception. [GitHub#126][Reported by Bob Saveland] ### Fixes * doc: Fixed markup. [GitHub#127][Patch by Tomohiro Hashidate] * Fixed a bug that `--location=LINE` may not detect a test when fixtures are defined before any tests: 1 class MyTestCase < Test::Unit::TestCase 2 setup do 3 end 4 5 test "xxx" do 6 end 7 end `--location=5` couldn't find the `xxx` test. [Reported by Ryota Sasabe] ### Thanks * Ryunosuke Sato * Tomohiro Hashidate * Bob Saveland * Ryota Sasabe ## 3.2.1 - 2016-07-19 {#version-3-2-1} ### Improvements * Clarified lib/test/unit/diff.rb license. It's a triple license of the Ruby license, PSF license and LGPLv2.1 or later. [Reported by Luisa Pace] * Reported norification when data driven test doesn't have parameter. [GitHub#122][Reported by Satoshi "Moris" Tagomori] ### Thanks * Luisa Pace * Satoshi "Moris" Tagomori ## 3.2.0 - 2016-06-12 {#version-3-2-0} ### Improvements * Supported rxvt family terminals as color available terminals. [GitHub#121][Reported by Ippei Kishida] ### Thanks * Ippei Kishida ## 3.1.9 - 2016-05-20 {#version-3-1-9} ### Fixes * Fixed conflict with test-unit-power_assert. [GitHub#120][Patch by Kazuki Tsujimoto] * Fixed a bug that path in `$LOAD_PATH` may be removed. ### Thanks * Kazuki Tsujimoto ## 3.1.8 - 2016-03-19 {#version-3-1-8} ### Improvements * Added `--stop-on-failure` command line option. With this option, running test suite is stopped immediately when one test is failed or an error is raised in one test. ## 3.1.7 - 2016-01-17 {#version-3-1-7} ### Fixes * Added a missing require. ## 3.1.6 - 2016-01-17 {#version-3-1-6} It's a Ruby on Rails integration improvement release. ### Improvements * Filtered backtrace of power\_assert. [GitHub#114] * Improved performance to retrieve test defined location. * Improved performance to run fixtures in a test. * Supported running a test by `yield` in `setup`: Before: def setup @file = File.open("x") end def teardown @file.close end After: def setup File.open("x") do |file| @file = file yield end end * Added `--default-test-path` option that specifies the default path that has tests. * Made auto runner registration more lazily. Auto runner isn't registered automatically until user defines a test. In the previous releases, auto runner is registered automatically when user defines a test case. * Supported specifying a test by location in command line. For example, the following command line runs a test that is defined in /tmp/test_a.rb at line 10: % ruby -r test-unit -e run_test /tmp/test_a.rb:10 ### Fixes * Fixed a bug that test isn't ran. The test has the same name as data driven test that is defined in parent test case. [GitHub#115] ## 3.1.5 - 2015-10-09 {#version-3-1-5} It's a Rack integration improvement release. ### Improvements * Renamed experimental top-level `run` method to `run_test` method because `run` is conflicted with Rack. [GitHub#32][GitHub:basecamp/pow#303] [Reported by Yevhen Viktorov] ### Thanks * Yevhen Viktorov ## 3.1.4 - 2015-09-26 {#version-3-1-4} It's a minor improvement release. ### Improvements * Updated sample code. [GitHub#109][Patch by takiy33] * Updated .travis.yml. [GitHub#110][Patch by takiy33] * document: Added table header in how to document. [GitHub#111][Patch by takiy33] * Removed duplicated code. [GitHub#112][Patch by takiy33] * Removed needless encoding conversion in fetching code snippet. [GitHub#113][Patch by NARUSE, Yui] ### Thanks * takiy33 * NARUSE, Yui ## 3.1.3 - 2015-07-26 {#version-3-1-3} It's a bug fix release. ### Improvements * Removed unused `TODO` file. [GitHub#108][Patch by takiy33] ### Fixes * `--location`: Fixed a bug that `--location LINE` doesn't work when test script is specified as relative path. [Reported by TOMITA Masahiro] The following doesn't work: % ruby ./test.rb --location 10 The following works: % ruby test.rb --location 10 ### Thanks * takiy33 * TOMITA Masahiro ## 3.1.2 - 2015-06-09 {#version-3-1-2} It's command line option improvements fix release. ### Improvements * `--location`: Made path match rule more strict. [Suggested by kimura wataru] * Before: * If test defined path ends with the specified path, the test is matched. * After: * If base name of test defined path equals to the specified path, the test is matched. * If relative path of test defined path equals to the specified path, the test is matched. * If the specified path is absolute path and test defined path equals to the specified path, the test is matched. * `--pattern`: If the option is specified, the default patterns aren't used. In the earlier versions, both the default patterns and the specified patterns are used. [Suggested by kimura wataru] ### Thanks * kimura wataru ## 3.1.1 - 2015-05-29 {#version-3-1-1} It's a bug fix release. ### Fixes * Fixed a bug that `--location` detects tests not only in sub test case but also parent test case. [GitHub#105][Reported by wanabe] ### Thanks * wanabe ## 3.1.0 - 2015-05-28 {#version-3-1-0} It's a bug fix release. ### Improvements * [ui][console] Removed needless new line. ### Fixes * Fixed a bug that priority mode can't be used on Windows. [GitHub#95][Reported by Daniel Berger] * Fixed a homepage URL RubyGems spec. [GitHub#96][Patch by Masayoshi Takahashi] supported.) [GitHub#89][Patch by Aaron Stone] * Fixed a bug that shutdown hook isn't called when pass throw exception such as `Interrupt` is raised. [GitHub#98][Reported by jeremiahishere.] * Fixed typos in documents. [GitHub#100][Reported by scivola] [GitHub#102][GitHub#103][Patch by Masafumi Yokoyama] * Fixed a bug that the same name test isn't executed in sub test case. [GitHub#104][Reported by wanabe] ### Thanks * Daniel Berger * Masayoshi Takahashi * jeremiahishere * scivola * Masafumi Yokoyama * wanabe ## 3.0.9 - 2014-12-31 {#version-3-0-9} It's a release that improves colors. ### Improvements * Added a work around for Ruby 1.8. (Note: Ruby 1.8 isn't supported.) [GitHub#89][Patch by Aaron Stone] * Supported colorized output on Windows. [GitHub#90][Patch by usa] * Improved colorized output. http://www.a-k-r.org/d/2014-12.html#a2014_12_27_1 [Suggested by Tanaka Akira] ### Thanks * Aaron Stone * usa * Tanaka Akira ## 3.0.8 - 2014-12-12 {#version-3-0-8} It's a release that supports Ruby 2.2.0 preview2. ### Improvements * Added a link for YARD in README. [GitHub:test-unit.github.io#2][Reported by sunnyone] * Added description about "/PATTERN/" style value in auto runner usage. [GitHub#86][Suggested by sunnyone] * Supported Ruby 2.2.0 preview2 in `assert_throw` and `assert_nothing_thrown`. ### Fixes * Fixed a bug that error report is failed when source encoding and locale encoding are different. [GitHub#87][Reported by scivola] ### Thanks * sunnyone * scivola ## 3.0.7 - 2014-11-14 {#version-3-0-7} It's a minor update release. ### Fixes * Fixed a bug that teardown blocks aren't called with sub class to parent class order. [GitHub#85][Reported by TOMITA Masahiro] ### Thanks * TOMITA Masahiro ## 3.0.6 - 2014-11-09 {#version-3-0-6} It's a minor update release. ### Improvements * Improved code snippet location. [GitHub#84][Patch by Yuki Kurihara] ### Thanks * Yuki Kurihara ## 3.0.5 - 2014-11-08 {#version-3-0-5} It's a minor update release. ### Fixes * Fixed a bug that startup/shutdown of parent test case isn't called when the test case includes one or more modules. [GitHub#83][Reported by Chadderton Odwazny] ### Thanks * Chadderton Odwazny ## 3.0.4 - 2014-11-01 {#version-3-0-4} It's a minor update release. ### Improvements * Stopped to remove JRuby and Rubinius internal backtrace entries from backtrace on failure/error. [GitHub#82][Patch by Charles Oliver Nutter] ### Thanks * Charles Oliver Nutter ## 3.0.3 - 2014-10-29 {#version-3-0-3} It's a minor update release. ### Improvements * Improved `Test::Unit::TestCase.test` performance. 100 times faster. * Supported `Proc` for user message. [Sugested by Nobuyoshi Nakada] ### Fixes * Fixed markup in document. [GitHub#81][Patch by Masafumi Yokoyama] ### Thanks * Masafumi Yokoyama * Nobuyoshi Nakada ## 3.0.2 - 2014-10-15 {#version-3-0-2} It's a minor update release. ### Improvements * Supported broken `==` implementation. `==` implementation should be fixed but it's not work of test-unit. :< [GitHub#71][Reported by Emily] * [UI][console]: Accepted no message failure. [GitHub#66][Reported by Brian Tatnall] * Updated gem description. [GitHub#74][Patch by Vít Ondruch] * Updated GPL text. [GitHub#78][Patch by Vít Ondruch] ### Fixes * Removed needless executable bit from README file. [GitHub#79][Patch by Vít Ondruch] ### Thanks * Emily * Brian Tatnall * Vít Ondruch ## 3.0.1 - 2014-08-05 {#version-3-0-1} It's a minor update release. ### Improvements * Improved Ruby 1.8.7 support. Note that we don't support Ruby 1.8.7 actively. We just support if its support is painless. [GitHub#71][Patch by estolfo] ### Thanks * estolfo ## 3.0.0 - 2014-08-03 {#version-3-0-0} It's Power Assert supported release! ### Improvements * Improved Rubinius support. [Ryo Onodera] * Updated RR repository link. [GitHub#56][Patch by Kenichi Kamiya] * Added some minitest compatible assertions. We don't recommend using these assertions. They are just for migrating from minitest. [GitHub#57][Patch by Karol Bucek] * {Test::Unit::Assertions#refute} * {Test::Unit::Assertions#refute_predicate} * {Test::Unit::Assertions#refute_empty} * {Test::Unit::Assertions#assert_not_includes} * {Test::Unit::Assertions#refute_includes} * {Test::Unit::Assertions#assert_not_instance_of} * {Test::Unit::Assertions#refute_instance_of} * {Test::Unit::Assertions#assert_not_kind_of} * {Test::Unit::Assertions#refute_kind_of} * {Test::Unit::Assertions#assert_not_operator} * {Test::Unit::Assertions#refute_operator} * Improved code readability. [Suggested by Kenichi Kamiya] * Made license field in RubyGems parseable. [GitHub#60][Patch by Michael Grosser] * Improved test case match feature by `--testcase` and `--ignore-testcase` options. They also checks parent class names. * Made inspected representation of Numeric objects especially BigDecimal more readable. [GitHub#64][Reported by Byron Appelt] * Added badges for Traivs CI and RubyGems. [GitHub#65][Patch by Byron Appelt] * Supported Power Assert. You can use Power Assert with {Test::Unit::Assertions#assert} with block. See method document for details. We recommend using Power Assert for predicate method checks. For example, we recommend Power Assert rather than {Test::Unit::Assertions#assert_true}, {Test::Unit::Assertions#assert_predicate} and so on. We don't recommend using Power Assert for equality check assertion. {Test::Unit::Assertions#assert_equal} should be used for the case. [Kazuki Tsujimoto] ### Fixes * Fixed a bug that test case defined by block has wrong location. [GitHub#58][Patch by Narihiro Nakamura] * Fixed a bug that test methods defined in included modules in super-class are also collected. [GitHub#62][GitHub#63][Patch by Karol Bucek] ### Thanks * Ryo Onodera * Kenichi Kamiya * Karol Bucek * Narihiro Nakamura * Michael Grosser * Byron Appelt * Kazuki Tsujimoto ## 2.5.5 - 2013-05-18 {#version-2-5-5} It's Ruby 2.0.0 supported release! ### Improvements * Supported Ruby 2.0.0. [GitHub#54] [Reported by mtasaka] * Accepted screen-256color TERM as 256 colors available environment. [GitHub#55] [Reported by Tom Miller] ### Fixes * Fixed a typo in document. [GitHub#53] [Patch by Baptiste Fontaine] * Fixed a bug in {Test::Unit::Assertions#assert_in_epsilon}. It doesn't work as expected if expected value is negative value. [Ruby Bug #8317] [Reported by Nobuhiro IMAI] ### Thanks * Baptiste Fontaine * mtasaka * Tom Miller * Nobuhiro IMAI ## 2.5.4 - 2013-01-23 {#version-2-5-4} It's a bug fix release. ### Improvements * Added documents for data driven test functionality. * Added TSV support for data driven test functionality. * Support tag inspection on JRuby. ### Fixes * Fixed a bug. It is too slow to filter tests when there are many tests. [GitHub#46] * Accept anonymous test suite. [GitHub:#49] [Reported by Matthew Rudy Jacobs] ### Thanks * Matthew Rudy Jacobs ## 2.5.3 - 2012-11-28 {#version-2-5-3} It's a release for minitest compatibility and bug fix. ### Improvements * Supported diff in invalid encoding. * Added some assersion methods just for minitest compatibility. Added methods are assert_includes(), refute_*() and refute(). If you are test-unit user, please don't use them. [GitHub#40] [Suggested by Michael Grosser] * Added --attribute option to select target tests by attribute. [test-unit-users-en:00098] [Suggested by Piotr Nestorow] ### Fixes * Allowed use of test for inheritance in ActionController::TestCase. [GitHub#42] [Patch by David Rasch] * Ensured evaluating at_exit block in top level. In IRB context, exit() specifies irb_exit(). [test-unit-users-en:00089] [Reported by Daniel Berger] * Fixed a bug that decoration style description is ignored. "decoration style description" are using description method above "def test_name" or with Symbol specifying test_name. [GitHub#45] [Reported by Piotr Nestorow] ### Thanks * Michael Grosser * David Rasch * Daniel Berger * Piotr Nestorow ## 2.5.2 - 2012-08-29 {#version-2-5-2} It's an improvement release for tmtms. `--location` is a similar feature to `--line_number` in RSpec. `sub_test_case` is a similar feature to `context` in shoulda-context and RSpec. ### Improvements * Cleaned up tests. [GitHub#34] [Patch by Michael Grosser] * Added missing background color for 8 color environment. * Added workaround for NetBeans. [GitHub#38] [Reported by Marc Cooper] * Added `--location` command line option that selects target tests by test defined location. * Created sub test suite for each subclassed test case. * [ui][console] Supported nested test suites. * Added {Test::Unit.at_start} and {Test::Unit.at_exit} hooks that are run before/after all tests are run. [Good hook name is suggested by kdmsnr] * Improved code snippet target on failure. Test method is always used for code snippet target. [GitHub#39] [Suggested by Michael Grosser] * Added {Test::Unit::TestCase.sub_test_case} that creates sub test case. The sub test case name isn't limited Ruby's constant name rule. You can specify the sub test case name in free form. ### Thanks * Michael Grosser * Marc Cooper * kdmsnr ## 2.5.1 - 2012-07-05 {#version-2-5-1} It's a bug fix release. ### Improvements * Supported installing from GitHub. [GitHub#29] [Suggested by Michael Grosser] * Supported ActiveSupport::TestCase. [GitHub#30] [Reported by Michael Grosser] * [ui][console] Improved multiline falut message display. ### Fixes * [ui][console] Fixed a bug that expected and actual values are empty. [GitHub#31][GitHub#33] [Reported by Kendall Buchanan][Reported by Mathieu Martin] [Hinted by Michael Grosser] * Fixed a bug that .gemspec can't be loaded on LANG=C. [RubyForge#29595] [Reported by Jean-Denis Koeck] ### Thanks * Michael Grosser * Kendall Buchanan * Mathieu Martin * Jean-Denis Koeck ## 2.5.0 - 2012-06-06 {#version-2-5-0} It's a bug fix release. ### Fixes * Fixed a backward incompatibility of `TestUnitMediator#run_suite` introduced in 2.4.9. [GitHub#28] [Reported by Vladislav Rassokhin] ### Thanks * Vladislav Rassokhin ## 2.4.9 - 2012-06-03 {#version-2-4-9} It's a bug fix release. ### Improvements * `Test::Unit.run?` -> `Test::Unit::AutoRunner.need_auto_run?`. `Test::Unit.run?` is marked as deprecated but it is still available. * [experimental] Added top level "run" method for `"ruby -rtest-unit -e run test/test_*.rb"`. Is this API OK or dirty? * Made failure output more readable on no color mode. * Supported showing ASCII-8BIT diff in failure message. * [ui][console] Supported `ENV["TERM"] == "xterm-256color"` as color available terminal. [GitHub#26] [Reported by Michael Grosser] * [ui][console] Supported "-256color" suffix `ENV["TERM"]` terminal as 256 color supported terminal. ### Fixes * Fixed a bug that `--workdir` doesn't work. * Consumed processed command line parameters in `ARGV` as `--help` says. [RubyForge#29554] [Reported by Bob Saveland] * Added missing `require "test/unit/diff"`. [GitHub#25] [Reported by Stephan Kulow] ### Thanks * Bob Saveland * Stephan Kulow * Michael Grosser ## 2.4.8 - 2012-3-6 {#version-2-4-8} It's a bug fix release. ### Improvements * Delayed at_exit registration until Test::Unit is used. [GitHub:#21] [Reported by Jason Lunn] * Added workaround for test-spec. [GitHub:#22] [Reported by Cédric Boutillier] ### Fixes * Fixed an error on code snippet display on JRuby. [GitHub:#19][GitHub:#20] [Reported by Jørgen P. Tjernø][Patch by Junegunn Choi] ### Thanks * Jørgen P. Tjernø * Junegunn Choi * Jason Lunn ## 2.4.7 - 2012-2-10 {#version-2-4-7} It's a code snippet improvement release. ### Improvements * Supported code snippet display on all faults. ## 2.4.6 - 2012-2-9 {#version-2-4-6} It's a TAP runner separated release. ### Improvements * Moved TAP runner to test-unit-runner-tap gem from test-unit gem. * Supported code snippet display on failure. ## 2.4.5 - 2012-1-16 {#version-2-4-5} It's a failure message readability improvement release. ### Improvements * Removed needless information from exception inspected text on failure. It's for easy to read. * Supported custom inspector. ## 2.4.4 - 2012-1-2 {#version-2-4-4} It's a Rails integration improved release. ### Improvements * [ui][console] Don't break progress display when a test is failed. * [ui][console] Added markers betwen a failure detail message in progress to improve visibility. * [travis] Dropped Ruby 1.8.6 as a test target. [GitHub:#13] [Patch by Josh Kalderimis] * Supported expected value == 0 case in assert_in_epsilon. [RubyForge#29485] [Reported by Syver Enstad] * Supported a block style setup/teardown/cleanup. ### Thanks * Josh Kalderimis * Syver Enstad ## 2.4.3 - 2011-12-11 {#version-2-4-3} ### Improvements * Improved SimpleCov integration by stopping to modify `ARGV` in auto runner. [GitHub:#12] [Reported by Nikos Dimitrakopoulos] * Improved JRuby integration by removing JRuby internal backtrace. ### Thanks * Nikos Dimitrakopoulos ## 2.4.2 - 2011-11-26 {#version-2-4-2} ### Improvements * `--name` supported data label. ## 2.4.1 - 2011-11-09 ### Improvements * Accepted AssertionMessage as assertion's user message. It is used in assert_select in actionpack. [Reported by David Heath] ### Fixes * Fixed test failure on LANG=C. #11 [Reported by boutil] * Suppress warnings on Ruby 1.9.2. ### Thanks * boutil * David Heath ## 2.4.0 - 2011-09-18 ### Improvements * Supported Travis CI. #5 [Suggested by James Mead] * Added Gemfile. #6 [Suggested by James Mead] * [ui][console] Supported notification in show-detail-immediately. * [ui][console] enable --show-detail-immediately by default. * [ui] Added --max-diff-target-string-size option. * [ui][console] Supported 256 colors. ### Fixes * Added missing fixture file. #7 [Reported by grafi-tt] * [ui][console] Added missing the last newline for progress level. * Supported correct backtrace for redefined notification. * Don't handle Timeout::Error as pass through exception on Ruby 1.8. #8 [Reported by Marc Seeger (Acquia)] ### Thanks * James Mead * grafi-tt * Marc Seeger (Acquia) ## 2.3.2 - 2011-08-15 A bug fix release. ### Improvements * [ui][console] Added some newlines to improve readability. ### Fixes * [ui][console] Worked --verbose again. * Re-supported Ruby 1.8.6. [Reported by James Mead] ### Thanks * James Mead ## 2.3.1 - 2011-08-06 {#version-2-3-1} Output improvement release! ### Improvements * [ui][console] Outputs omissions and notifications in short. * [ui][console] Added "important-only" verbose level. * Intelligence diff supports recursive references. * [rubyforge #29325] Supported Ruby Enterprise Edition. [Reported by Hans de Graaff] * [rubyforge #29326] Supported JRuby. [Reported by Hans de Graaff] * Added --show-detail-immediately option that shows fault details when a fault is occurred. ### Fixes * [pull request #1] Fixed a problem that load collector can't load a test file on Ruby 1.9. [Patch by grafi-tt] * [issue #3] Fixed a problem that implicit method name override by declarative style test definition. [Reported by Jeremy Stephens] ### Thanks * grafi-tt * Jeremy Stephens * Hans de Graaff ## 2.3.0 / 2011-04-17 * 13 enhancements * improve Hash key sorting for diff. * [#28928] support any characters in declarative style description. [Daniel Berger] * add Error#location and make #backtrace deprecated. * make TestCase#passed? public. * add result finished and pass assertion notifications. * add TestSuite#passed? public. * add XML test runner. * add --output-file-descriptor option. * measure elapsed time for each test. * add --collector option. * support test driven test. [Haruka Yoshihara] * add cleanup hook it runs between after test and before teardown. * support recursive collection sort for diff. * Thanks * Daniel Berger * Haruka Yoshihara ## 2.2.0 / 2011-02-14 * 22 enhancements * [#28808] accept String as delta for assert_in_delta. [Daniel Berger] * [test-unit-users-en:00035] make GC-able finished tests. [Daniel Berger] * use also COLUMNS environment variable to guess terminal width. * make delta for assert_in_delta optional. [Nobuyoshi Nakada] * add assert_not_respond_to. [Nobuyoshi Nakada] * add assert_not_match. assert_no_match is deprecated. [Nobuyoshi Nakada] * add assert_not_in_delta. [Nobuyoshi Nakada] * add assert_in_epsilon. [Nobuyoshi Nakada] * add assert_not_in_epsilon. [Nobuyoshi Nakada] * add assert_include. [Nobuyoshi Nakada] * add assert_not_include. [Nobuyoshi Nakada] * add assert_empty. [Nobuyoshi Nakada] * add assert_not_empty. [Nobuyoshi Nakada] * notify require failed paths. * validate message value for assert. * show throughputs at the last. * support not ASCII compatible string diff. * support colorized diff on encoding different string. * normalize entry order of Hash for readable diff. * add --ignore-name option. * add --ignore-testcase option. * add assert_not_send. * Thanks * Daniel Berger * Nobuyoshi Nakada ## 2.1.2 / 2010-11-25 * 1 enhancement * support auto runner prepare hook. ## 2.1.1 / 2010-07-29 * 1 bug fix * [test-unit-users-en:00026] re-work tap runner. [Daniel Berger] * Thanks * Daniel Berger === 2.1.0 / 2010-07-17 * 1 bug fix * [#28267] global config file ignored [Daniel Berger] * Thanks * Daniel Berger ## 2.0.8 / 2010-06-02 * 5 major enchancements * collect *_test.rb and *-test.rb files as test files. * [#28181] improve assert_in_delta message. [Suggested by David MARCHALAND] * show string encoding in assert_equal failure message if they are different. * change default color scheme: * success: green back + white * failure: red back + white * add capture_output. * 2 bug fixes * fix a bug that console runner on verbose mode causes an error for long test name (>= 61). * [#28093] Autorunner ignores all files in a directory named test by default [Reported by Florian Frank] * Thanks * Florian Frank * David MARCHALAND ## 2.0.7 / 2010-03-09 * 4 major enhancements * detect redefined test methods. * [INTERFACE IMCOMPATIBLE] multiple --name and --testcase options narrow down targets instead of adding targets. * [#27764] accept custom test_order for each test case. [Suggested by David MARCHALAND] * [#27790] ignore omitted tests from 'n% passed' report. [Suggested by Daniel Berger] * 2 minor enchancements * [#27832] ignore .git directory. [Suggested by Daniel Berger] * [#27792] require 'fileutils' and 'tmpdir' lazily for non-priority mode users. [Suggested by David MARCHALAND] * 2 bug fixes * [#27892] modify processed arguments array destructively. [Reported by Bob Saveland] * work without HOME environment variable. [Reported by Champak Ch] * Thanks * David MARCHALAND * Daniel Berger * Bob Saveland * Champak Ch ## 2.0.6 / 2010-01-09 * 3 major enhancements * [#27380] Declarative syntax? [Daniel Berger] support declarative syntax: test "test description in natural language" do ... end * support test description: description "test description in natural language" def test_my_test ... end * make max diff target string size customizable by TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE environment variable. * 2 bug fixes * [#27374] omit_if unexpected behavior [David MARCHALAND] * fix a bug that tests in sub directories aren't load with --basedir. [Daniel Berger] * Thanks * David MARCHALAND * Daniel Berger ## 2.0.5 / 2009-10-18 * 1 bug fixes * [#27314] fix diff may raise an exception. [Erik Hollensbe] * Thanks * Erik Hollensbe ## 2.0.4 / 2009-10-17 * 4 major enhancements * use ~/.test-unit.yml as global configuration file. * add TAP runner. (--runner tap) * support colorized diff: http://test-unit.github.io/color-diff.png * add Test::Unit::AutoRunner.default_runner= to specify default test runner. * 4 minor enhancements * improve verbose mode output format. (use indent) * support `NOT_PASS_THROUGH_EXCEPTIONS`. * support arguments option in `#{runner}_options`. * TC_ -> Test in sample test case name. * 1 bug fixes * [#27195] test-unit-2.0.3 + ruby-1.9.1 cannot properly test DelegateClass subclasses [Mike Pomraning] * Thanks * Mike Pomraning ## 2.0.3 / 2009-07-19 * 6 major enhancements * add assert_predicate. * add assert_not_predicate. * [#24210] assert_kind_of supports an array of classes or modules. [Daniel Berger] * assert_instance_of supports an array of classes or modules. * add --default-priority option. * [#26627] add --order option. [Daniel Berger] * 4 minor enhancements * use yellow foreground + black background for error. * don't show diff for long string. * accept "*term-color" TERM environment as colorizable terminal. (e.g. Apple's Terminal) * [#26268] add a workaround for test-spec's after_all. [Angelo Lakra] * 1 bug fix * [#23586] re-support ruby 1.9.1. [Diego Pettenò] * Thanks * Diego Pettenò * Daniel Berger * Angelo Lakra ## 2.0.2 / 2008-12-21 * 2 major enhancements * re-support ruby 1.8.5. * improve exception object comparison. * 3 bug fixes * [#22723]: collector fails on anonymous classes * [#22986]: Test names with '?' blow up on Windows * [#22988]: don't create .test-result on non-priority mode. * Thanks * Erik Hollensbe * Daniel Berger * Bill Lear ## 2.0.1 / 2008-11-09 * 19 major enhancements * support ruby 1.9.1. * add run_test method to be extensible. * improve priority-mode auto off. * improve startup/shutdown RDoc. [Daniel Berger] * add assert_compare. [#20851] [Designing Patterns] * add assert_fail_assertion. [#20851] [Designing Patterns] * add assert_raise_message. [#20851] [Designing Patterns] * support folded diff. * add assert_raise_kind_of. [Daniel Berger] * ingore inherited test for nested test case. * add assert_const_defined. * add assert_not_const_defined. * support assert_raise with an exception object. * support assert_raise with no arguments that asserts any exception is raised. [#22602] [Daniel Berger] * support folded dot progress. * add --progress-row-max option. * support color scheme customize. * support configuration file. (YAML) * recognize test-XXX.rb files as test files not only test_XXX.rb * Thanks * Daniel Berger * Designing Patterns ## 2.0.0 / 2008-06-18 * 15 major enhancements * support startup/shutdown. (test case level setup/teardown) * support multiple setup/teardown. * support pending. * support omission. * support notification. * support colorize. * support diff. * support test attribute. * add assert_boolean. * add assert_true. * add assert_false. * add --priority-mode option. * don't use ObjectSpace to collect test cases. * make more customizable. (additional options, exception handling and so on) * improve Emacs integration. * 4 major changes * remove GTK+1 support. * split GTK+ runner as another gem. * split FOX runner as another gem. * split Tk runner as another gem. ## 1.2.3 / 2008-02-25 * 1 major enhancement * Birthday (as a gem)! test-unit-3.3.9/BSDL0000644000004100000410000000257113775322563014203 0ustar www-datawww-dataCopyright (C) 2003-2007 Nathaniel Talbott. All rights reserved. Copyright (C) 2008 Ryan Davis. All rights reserved. Copyright (C) 2008-2020 Sutou Kouhei. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. test-unit-3.3.9/sample/0000755000004100000410000000000013775322563015010 5ustar www-datawww-datatest-unit-3.3.9/sample/test_adder.rb0000644000004100000410000000061313775322563017453 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' require_relative 'adder' class TestAdder < Test::Unit::TestCase def setup @adder = Adder.new(5) end def test_add assert_equal(7, @adder.add(2), "Should have added correctly") end def teardown @adder = nil end end test-unit-3.3.9/sample/adder.rb0000644000004100000410000000037113775322563016415 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. class Adder def initialize(number) @number = number end def add(number) @number + number end end test-unit-3.3.9/sample/test_user.rb0000644000004100000410000000055213775322563017354 0ustar www-datawww-data# nested test case example. require 'test/unit' class UserTest < Test::Unit::TestCase def setup @user = "me" end def test_full_name assert_equal("me", @user) end class ProfileTest < UserTest setup def setup_profile @user += ": profile" end def test_has_profile assert_match(/: profile/, @user) end end end test-unit-3.3.9/sample/test_subtracter.rb0000644000004100000410000000067013775322563020555 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. require 'test/unit' require_relative 'subtracter' class TestSubtracter < Test::Unit::TestCase def setup @subtracter = Subtracter.new(5) end def test_subtract assert_equal(3, @subtracter.subtract(2), "Should have subtracted correctly") end def teardown @subtracter = nil end end test-unit-3.3.9/sample/subtracter.rb0000644000004100000410000000040213775322563017507 0ustar www-datawww-data# Author:: Nathaniel Talbott. # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. # License:: Ruby license. class Subtracter def initialize(number) @number = number end def subtract(number) @number - number end end