mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* test/testunit/*: Added.
* lib/test/unit.rb: Documentation update. * lib/test/unit/ui/console/testrunner.rb (TestRunner#initialize): Ditto. * lib/test/unit.rb: Factored out an ObjectSpace collector. * lib/test/unit/collector/objectspace.rb: Ditto. * sample/testunit/*: Added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
50cd24f1cf
commit
65fe176ea4
17 changed files with 1448 additions and 24 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Fri Sep 19 11:39:00 2003 Nathaniel Talbott <ntalbott@ruby-lang.org>
|
||||
|
||||
* test/testunit/*: Added.
|
||||
|
||||
* lib/test/unit.rb: Documentation update.
|
||||
|
||||
* lib/test/unit/ui/console/testrunner.rb (TestRunner#initialize):
|
||||
Ditto.
|
||||
|
||||
* lib/test/unit.rb: Factored out an ObjectSpace collector.
|
||||
|
||||
* lib/test/unit/collector/objectspace.rb: Ditto.
|
||||
|
||||
* sample/testunit/*: Added.
|
||||
|
||||
Fri Sep 19 01:00:48 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
* lib/webrick/log.rb (BasicLog#log): get rid of as ineffectual
|
||||
|
|
156
lib/test/unit.rb
156
lib/test/unit.rb
|
@ -1,4 +1,119 @@
|
|||
# :include: ../../../../README
|
||||
# = 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.
|
||||
#
|
||||
#
|
||||
# == Installation
|
||||
#
|
||||
# Run:
|
||||
# * ruby setup.rb config
|
||||
# * ruby setup.rb setup
|
||||
# * ruby setup.rb install
|
||||
#
|
||||
# Note that the runit compatibility layer will *not* be installed if you
|
||||
# already have RubyUnit installed.
|
||||
#
|
||||
# Mac OS X users should also note that setup.rb will fail unless they
|
||||
# execute 'unlimit stacksize' before running 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
|
||||
#
|
||||
# A lot of discussion happens about Ruby in general on the ruby-talk
|
||||
# mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask
|
||||
# any questions you might have there. I monitor the list, as do many
|
||||
# other helpful Rubyists, and you're sure to get a quick answer. Of
|
||||
# course, you're also welcome to email me (Nathaniel Talbott) directly
|
||||
# at mailto:testunit@talbott.ws, and I'll do my best to help you out.
|
||||
#
|
||||
#
|
||||
# == 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 in the standard Ruby distribution for details.
|
||||
#
|
||||
#
|
||||
# == 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
|
||||
#
|
||||
# ----
|
||||
#
|
||||
|
@ -158,20 +273,13 @@
|
|||
|
||||
require 'test/unit/testcase'
|
||||
require 'test/unit/ui/testrunnermediator'
|
||||
require 'test/unit/collector/objectspace'
|
||||
|
||||
at_exit {
|
||||
# We can't debug tests run with at_exit unless we add the following:
|
||||
set_trace_func DEBUGGER__.context.method(:trace_func).to_proc if (defined? DEBUGGER__)
|
||||
|
||||
if (!Test::Unit::UI::TestRunnerMediator.run?)
|
||||
suite_name = $0.sub(/\.rb$/, '')
|
||||
suite = Test::Unit::TestSuite.new(suite_name)
|
||||
test_classes = []
|
||||
ObjectSpace.each_object(Class) {
|
||||
| klass |
|
||||
test_classes << klass if (Test::Unit::TestCase > klass)
|
||||
}
|
||||
|
||||
runners = {
|
||||
'--console' => proc do |suite|
|
||||
require 'test/unit/ui/console/testrunner'
|
||||
|
@ -194,22 +302,26 @@ at_exit {
|
|||
end
|
||||
runner = runners['--console'] if (runner.nil?)
|
||||
|
||||
if ARGV.empty?
|
||||
test_classes.each { |klass| suite << klass.suite }
|
||||
else
|
||||
tests = test_classes.map { |klass| klass.suite.tests }.flatten
|
||||
collector = Test::Unit::Collector::ObjectSpace::new
|
||||
|
||||
unless ARGV.empty?
|
||||
criteria = ARGV.map { |arg| (arg =~ %r{^/(.*)/$}) ? Regexp.new($1) : arg }
|
||||
criteria.each {
|
||||
filters = []
|
||||
criteria.each do
|
||||
| criterion |
|
||||
if (criterion.instance_of?(Regexp))
|
||||
tests.each { |test| suite << test if (criterion =~ test.name) }
|
||||
elsif (/^A-Z/ =~ criterion)
|
||||
tests.each { |test| suite << test if (criterion == test.class.name) }
|
||||
else
|
||||
tests.each { |test| suite << test if (criterion == test.method_name) }
|
||||
case criterion
|
||||
when Regexp
|
||||
filters << proc{|test| criterion =~ test.name}
|
||||
when /^A-Z/
|
||||
filters << proc{|test| criterion == test.class.name}
|
||||
else
|
||||
filters << proc{|test| criterion == test.method_name}
|
||||
end
|
||||
}
|
||||
end
|
||||
collector.filter = filters
|
||||
end
|
||||
runner.call(suite)
|
||||
|
||||
suite_name = $0.sub(/\.rb$/, '')
|
||||
runner.call(collector.collect(suite_name))
|
||||
end
|
||||
}
|
||||
|
|
44
lib/test/unit/collector/objectspace.rb
Normal file
44
lib/test/unit/collector/objectspace.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
module Collector
|
||||
class ObjectSpace
|
||||
NAME = 'collected from the ObjectSpace'
|
||||
|
||||
def initialize(source=::ObjectSpace)
|
||||
@source = source
|
||||
end
|
||||
|
||||
def collect(name=NAME)
|
||||
suite = TestSuite.new(name)
|
||||
tests = []
|
||||
@source.each_object(Class) do |klass|
|
||||
tests.concat(klass.suite.tests) if(Test::Unit::TestCase > klass)
|
||||
end
|
||||
tests.each{|test| suite << test if(include(test))}
|
||||
suite
|
||||
end
|
||||
|
||||
def include(test)
|
||||
return true unless(@filters)
|
||||
@filters.each do |filter|
|
||||
return true if(filter.call(test))
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def filter=(filters)
|
||||
@filters = case(filters)
|
||||
when Proc
|
||||
[filters]
|
||||
when Array
|
||||
filters
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
# :nodoc:
|
||||
#
|
||||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/ui/testrunnermediator'
|
||||
|
@ -31,7 +31,7 @@ module Test
|
|||
# running is limited to progress dots, errors and
|
||||
# failures, and the final result. io specifies
|
||||
# where runner output should go to; defaults to
|
||||
# STDERR.
|
||||
# STDOUT.
|
||||
def initialize(suite, output_level=NORMAL, io=STDOUT)
|
||||
if (suite.respond_to?(:suite))
|
||||
@suite = suite.suite
|
||||
|
|
13
sample/testunit/adder.rb
Normal file
13
sample/testunit/adder.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# 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)
|
||||
return @number + number
|
||||
end
|
||||
end
|
||||
|
12
sample/testunit/subtracter.rb
Normal file
12
sample/testunit/subtracter.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# 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)
|
||||
return @number - number
|
||||
end
|
||||
end
|
18
sample/testunit/tc_adder.rb
Normal file
18
sample/testunit/tc_adder.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit'
|
||||
require 'adder'
|
||||
|
||||
class TC_Adder < 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
|
18
sample/testunit/tc_subtracter.rb
Normal file
18
sample/testunit/tc_subtracter.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit'
|
||||
require 'subtracter'
|
||||
|
||||
class TC_Subtracter < 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
|
7
sample/testunit/ts_examples.rb
Normal file
7
sample/testunit/ts_examples.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit'
|
||||
require 'tc_adder'
|
||||
require 'tc_subtracter'
|
74
test/testunit/collector/test_objectspace.rb
Normal file
74
test/testunit/collector/test_objectspace.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/collector/objectspace'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
module Collector
|
||||
class TC_ObjectSpace < TestCase
|
||||
def setup
|
||||
@tc1 = Class.new(TestCase) do
|
||||
def test_1
|
||||
end
|
||||
def test_2
|
||||
end
|
||||
end
|
||||
|
||||
@tc2 = Class.new(TestCase) do
|
||||
def test_3
|
||||
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
|
||||
end
|
||||
|
||||
def test_basic_collection
|
||||
expected = TestSuite.new("name")
|
||||
expected << @tc1.new('test_1')
|
||||
expected << @tc1.new('test_2')
|
||||
expected << @tc2.new('test_3')
|
||||
assert_equal(expected, ObjectSpace.new(@object_space).collect("name"))
|
||||
end
|
||||
|
||||
def test_filtered_collection
|
||||
expected = TestSuite.new(ObjectSpace::NAME)
|
||||
collector = ObjectSpace.new(@object_space)
|
||||
collector.filter = proc{|test| false}
|
||||
assert_equal(expected, collector.collect)
|
||||
|
||||
expected = TestSuite.new(ObjectSpace::NAME)
|
||||
expected << @tc1.new('test_1')
|
||||
expected << @tc1.new('test_2')
|
||||
expected << @tc2.new('test_3')
|
||||
collector = ObjectSpace.new(@object_space)
|
||||
collector.filter = proc{|test| true}
|
||||
assert_equal(expected, collector.collect)
|
||||
|
||||
expected = TestSuite.new(ObjectSpace::NAME)
|
||||
expected << @tc1.new('test_1')
|
||||
expected << @tc2.new('test_3')
|
||||
collector = ObjectSpace.new(@object_space)
|
||||
collector.filter = proc{|test| ['test_1', 'test_3'].include?(test.method_name)}
|
||||
assert_equal(expected, collector.collect)
|
||||
|
||||
expected = TestSuite.new(ObjectSpace::NAME)
|
||||
expected << @tc1.new('test_1')
|
||||
expected << @tc2.new('test_3')
|
||||
collector = ObjectSpace.new(@object_space)
|
||||
collector.filter = [proc{|test| test.method_name == 'test_1'}, proc{|test| test.method_name == 'test_3'}]
|
||||
assert_equal(expected, collector.collect)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
484
test/testunit/test_assertions.rb
Normal file
484
test/testunit/test_assertions.rb
Normal file
|
@ -0,0 +1,484 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/testcase'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class TC_Assertions < TestCase
|
||||
def check(value, message="")
|
||||
add_assertion
|
||||
if (!value)
|
||||
raise AssertionFailedError.new(message)
|
||||
end
|
||||
end
|
||||
|
||||
def check_assertions(expect_fail, expected_message="", return_value_expected=false)
|
||||
@actual_assertion_count = 0
|
||||
failed = true
|
||||
actual_message = nil
|
||||
@catch_assertions = true
|
||||
return_value = nil
|
||||
begin
|
||||
return_value = yield
|
||||
failed = false
|
||||
rescue AssertionFailedError => error
|
||||
actual_message = error.message
|
||||
end
|
||||
@catch_assertions = false
|
||||
check(expect_fail == failed, (expect_fail ? "Should have failed, but didn't" : "Should not have failed, but did with message\n<#{actual_message}>"))
|
||||
check(1 == @actual_assertion_count, "Should have made one assertion but made <#{@actual_assertion_count}>")
|
||||
if (expect_fail)
|
||||
case expected_message
|
||||
when String
|
||||
check(actual_message == expected_message, "Should have the correct message.\n<#{expected_message.inspect}> expected but was\n<#{actual_message.inspect}>")
|
||||
when Regexp
|
||||
check(actual_message =~ expected_message, "The message should match correctly.\n</#{expected_message.source}/> expected to match\n<#{actual_message.inspect}>")
|
||||
else
|
||||
check(false, "Incorrect expected message type in assert_nothing_failed")
|
||||
end
|
||||
else
|
||||
if (!return_value_expected)
|
||||
check(return_value.nil?, "Should not return a value but returned <#{return_value}>")
|
||||
else
|
||||
check(!return_value.nil?, "Should return a value")
|
||||
end
|
||||
end
|
||||
return return_value
|
||||
end
|
||||
|
||||
def check_nothing_fails(return_value_expected=false, &proc)
|
||||
check_assertions(false, "", return_value_expected, &proc)
|
||||
end
|
||||
|
||||
def check_fails(expected_message="", &proc)
|
||||
check_assertions(true, expected_message, &proc)
|
||||
end
|
||||
|
||||
def test_assert_block
|
||||
check_nothing_fails {
|
||||
assert_block {true}
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_block("successful assert_block") {true}
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_block("successful assert_block") {true}
|
||||
}
|
||||
check_fails {
|
||||
assert_block {false}
|
||||
}
|
||||
check_fails("failed assert_block") {
|
||||
assert_block("failed assert_block") {false}
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert
|
||||
check_nothing_fails {
|
||||
assert(true)
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert(true, "successful assert")
|
||||
}
|
||||
check_fails {
|
||||
assert(false)
|
||||
}
|
||||
check_fails("failed assert") {
|
||||
assert(false, "failed assert")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_equal
|
||||
check_nothing_fails {
|
||||
assert_equal("string1", "string1")
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_equal( "string1", "string1", "successful assert_equal")
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_equal("string1", "string1", "successful assert_equal")
|
||||
}
|
||||
check_fails("<string1> expected but was\n<string2>") {
|
||||
assert_equal("string1", "string2")
|
||||
}
|
||||
check_fails("failed assert_equal.\n<string1> expected but was\n<string2>") {
|
||||
assert_equal("string1", "string2", "failed assert_equal")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_raises
|
||||
return_value = nil
|
||||
check_nothing_fails(true) {
|
||||
return_value = assert_raises(RuntimeError) {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
check(return_value.kind_of?(Exception), "Should have returned the exception from a successful assert_raises")
|
||||
check(return_value.message == "Error", "Should have returned the correct exception from a successful assert_raises")
|
||||
check_nothing_fails(true) {
|
||||
assert_raises(ArgumentError, "successful assert_raises") {
|
||||
raise ArgumentError.new("Error")
|
||||
}
|
||||
}
|
||||
check_nothing_fails(true) {
|
||||
assert_raises(RuntimeError) {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
check_nothing_fails(true) {
|
||||
assert_raises(RuntimeError, "successful assert_raises") {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
check_fails("<RuntimeError> exception expected but none was thrown") {
|
||||
assert_raises(RuntimeError) {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
check_fails(%r{^failed assert_raises.\n<ArgumentError> exception expected but was\nClass: <RuntimeError>\nMessage: <Error>\n---Backtrace---\n.+\n---------------$}m) {
|
||||
assert_raises(ArgumentError, "failed assert_raises") {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
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_fails("<string> expected to be an instance of\n<Hash> but was\n<String>") {
|
||||
assert_instance_of(Hash, "string")
|
||||
}
|
||||
check_fails("failed assert_instance_of.\n<string> expected to be an instance of\n<Hash> but was\n<String>") {
|
||||
assert_instance_of(Hash, "string", "failed assert_instance_of")
|
||||
}
|
||||
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_fails("<nil> expected but was\n<string>") {
|
||||
assert_nil("string")
|
||||
}
|
||||
check_fails("failed assert_nil.\n<nil> expected but was\n<string>") {
|
||||
assert_nil("string", "failed assert_nil")
|
||||
}
|
||||
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(Object, "string", "successful assert_kind_of")
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_kind_of(Comparable, 1)
|
||||
}
|
||||
check_fails("<string>\nexpected to be kind_of?<Class>") {
|
||||
assert_kind_of(Class, "string")
|
||||
}
|
||||
check_fails("failed assert_kind_of.\n<string>\nexpected to be kind_of?<Class>") {
|
||||
assert_kind_of(Class, "string", "failed assert_kind_of")
|
||||
}
|
||||
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_fails("<string> expected to be =~\n</slin./>") {
|
||||
assert_match(/slin./, "string")
|
||||
}
|
||||
check_fails("<string> expected to be =~\n<slin>") {
|
||||
assert_match("slin", "string")
|
||||
}
|
||||
check_fails("failed assert_match.\n<string> expected to be =~\n</slin./>") {
|
||||
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"
|
||||
check_fails("<#{thing}:#{thing.__id__}> expected to be equal? to\n<#{thing2}:#{thing2.__id__}>") {
|
||||
assert_same(thing, thing2)
|
||||
}
|
||||
check_fails("failed assert_same.\n<#{thing}:#{thing.__id__}> expected to be equal? to\n<#{thing2}:#{thing2.__id__}>") {
|
||||
assert_same(thing, thing2, "failed assert_same")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_nothing_raised
|
||||
check_nothing_fails {
|
||||
assert_nothing_raised {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_nothing_raised("successful assert_nothing_raised") {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_nothing_raised("successful assert_nothing_raised") {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
check_nothing_fails {
|
||||
begin
|
||||
assert_nothing_raised(RuntimeError, StandardError, "successful assert_nothing_raised") {
|
||||
raise ZeroDivisionError.new("ArgumentError")
|
||||
}
|
||||
rescue ZeroDivisionError
|
||||
end
|
||||
}
|
||||
check_fails(%r{^Exception raised:\nClass: <RuntimeError>\nMessage: <Error>\n---Backtrace---\n.+\n---------------$}m) {
|
||||
assert_nothing_raised {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
check_fails(%r{^failed assert_nothing_raised\.\nException raised:\nClass: <RuntimeError>\nMessage: <Error>\n---Backtrace---\n.+\n---------------$}m) {
|
||||
assert_nothing_raised("failed assert_nothing_raised") {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
check_fails(%r{^Exception raised:\nClass: <RuntimeError>\nMessage: <Error>\n---Backtrace---\n.+\n---------------$}m) {
|
||||
assert_nothing_raised(StandardError, RuntimeError) {
|
||||
raise "Error"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_flunk
|
||||
check_fails {
|
||||
flunk
|
||||
}
|
||||
check_fails("flunk message") {
|
||||
flunk("flunk message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_not_same
|
||||
thing = "thing"
|
||||
thing2 = "thing"
|
||||
check_nothing_fails {
|
||||
assert_not_same(thing, thing2)
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_not_same(thing, thing2, "message")
|
||||
}
|
||||
check_fails("<#{thing}:#{thing.__id__}> expected to not be equal? to\n<#{thing}:#{thing.__id__}>") {
|
||||
assert_not_same(thing, thing)
|
||||
}
|
||||
check_fails("message.\n<#{thing}:#{thing.__id__}> expected to not be equal? to\n<#{thing}:#{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_fails("<string> expected to be != to\n<string>") {
|
||||
assert_not_equal("string", "string")
|
||||
}
|
||||
check_fails("message.\n<string> expected to be != to\n<string>") {
|
||||
assert_not_equal("string", "string", "message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_not_nil
|
||||
check_nothing_fails {
|
||||
assert_not_nil("string")
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_not_nil("string", "message")
|
||||
}
|
||||
check_fails("<nil> expected to not be nil") {
|
||||
assert_not_nil(nil)
|
||||
}
|
||||
check_fails("message.\n<nil> expected to not be nil") {
|
||||
assert_not_nil(nil, "message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_no_match
|
||||
check_nothing_fails {
|
||||
assert_no_match(/sling/, "string")
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_no_match(/sling/, "string", "message")
|
||||
}
|
||||
check_fails("</string/> expected to not match\n <string>") {
|
||||
assert_no_match(/string/, "string")
|
||||
}
|
||||
check_fails("message.\n</string/> expected to not match\n <string>") {
|
||||
assert_no_match(/string/, "string", "message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_throws
|
||||
check_nothing_fails {
|
||||
assert_throws(:thing, "message") {
|
||||
throw :thing
|
||||
}
|
||||
}
|
||||
check_fails("message.\n<:thing> expected to be thrown but\n<:thing2> was thrown") {
|
||||
assert_throws(:thing, "message") {
|
||||
throw :thing2
|
||||
}
|
||||
}
|
||||
check_fails("message.\n<:thing> should have been thrown") {
|
||||
assert_throws(:thing, "message") {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_nothing_thrown
|
||||
check_nothing_fails {
|
||||
assert_nothing_thrown("message") {
|
||||
1 + 1
|
||||
}
|
||||
}
|
||||
check_fails("message.\n<:thing> was thrown when nothing was expected") {
|
||||
assert_nothing_thrown("message") {
|
||||
throw :thing
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_operator
|
||||
check_nothing_fails {
|
||||
assert_operator("thing", :==, "thing", "message")
|
||||
}
|
||||
check_fails("message.\n<thing1> expected to be\n==\n<thing2>") {
|
||||
assert_operator("thing1", :==, "thing2", "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_fails("The method argument to #assert_respond_to should be specified as a Symbol or a String.") {
|
||||
assert_respond_to("thing", 0.15)
|
||||
}
|
||||
check_fails("message.\n<symbol>\nof type <Symbol>\nexpected to respond_to?<non_existent>") {
|
||||
assert_respond_to(:symbol, :non_existent, "message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_in_delta
|
||||
check_nothing_fails {
|
||||
assert_in_delta(1.4, 1.4, 0)
|
||||
}
|
||||
check_nothing_fails {
|
||||
assert_in_delta(0.5, 0.4, 0.1, "message")
|
||||
}
|
||||
check_nothing_fails {
|
||||
float_thing = Object.new
|
||||
def float_thing.to_f
|
||||
0.2
|
||||
end
|
||||
assert_in_delta(0.1, float_thing, 0.1)
|
||||
}
|
||||
check_fails("message.\n<0.5> and\n<0.4> expected to be within\n<0.05> of each other") {
|
||||
assert_in_delta(0.5, 0.4, 0.05, "message")
|
||||
}
|
||||
check_fails(%r{The arguments must respond to to_f; the first float did not\.\n<.+>\nof type <Object>\nexpected to respond_to\?<to_f>}) {
|
||||
assert_in_delta(Object.new, 0.4, 0.1)
|
||||
}
|
||||
check_fails("The delta should not be negative.\n<-0.1> expected to be\n>=\n<0.0>") {
|
||||
assert_in_delta(0.5, 0.4, -0.1, "message")
|
||||
}
|
||||
end
|
||||
|
||||
def test_assert_send
|
||||
object = Object.new
|
||||
class << object
|
||||
private
|
||||
def return_argument(argument, bogus)
|
||||
return argument
|
||||
end
|
||||
end
|
||||
check_nothing_fails {
|
||||
assert_send([object, :return_argument, true, "bogus"], "message")
|
||||
}
|
||||
check_fails(%r{message\.\n<.+> expected to respond to\n<return_argument\(\[false, "bogus"\]\)> with true}) {
|
||||
assert_send([object, :return_argument, false, "bogus"], "message")
|
||||
}
|
||||
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 {
|
||||
assert_equal(object, object, "message")
|
||||
}
|
||||
end
|
||||
|
||||
def add_failure(message, location=caller)
|
||||
if (!@catch_assertions)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def add_assertion
|
||||
if (!@catch_assertions)
|
||||
super
|
||||
else
|
||||
@actual_assertion_count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
test/testunit/test_error.rb
Normal file
30
test/testunit/test_error.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/error'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class TC_Error < TestCase
|
||||
def setup
|
||||
@old_load_path = $:.dup
|
||||
$:.replace(['C:\some\old\path'])
|
||||
end
|
||||
|
||||
def test_backtrace_filtering
|
||||
backtrace = [%q{tc_thing.rb:4:in '/'}]
|
||||
|
||||
backtrace.concat([%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{tc_thing.rb:3}])
|
||||
assert_equal([backtrace[0..1], backtrace[-1]].flatten, Error.filter(backtrace), "Should filter out all TestUnit-specific lines")
|
||||
end
|
||||
|
||||
def teardown
|
||||
$:.replace(@old_load_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
239
test/testunit/test_testcase.rb
Normal file
239
test/testunit/test_testcase.rb
Normal file
|
@ -0,0 +1,239 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/testcase'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class TC_TestCase < TestCase
|
||||
def test_creation
|
||||
tc = Class.new(TestCase) do
|
||||
def test_with_arguments(arg1, arg2)
|
||||
end
|
||||
end
|
||||
|
||||
caught = true
|
||||
catch(:invalid_test) do
|
||||
tc.new(:test_with_arguments)
|
||||
caught = false
|
||||
end
|
||||
check("Should have caught an invalid test when there are arguments", caught)
|
||||
|
||||
caught = true
|
||||
catch(:invalid_test) do
|
||||
tc.new(:non_existent_test)
|
||||
caught = false
|
||||
end
|
||||
check("Should have caught an invalid test when the method does not exist", caught)
|
||||
end
|
||||
|
||||
def setup
|
||||
@tc_failure_error = Class.new(TestCase) do
|
||||
def test_failure
|
||||
assert_block("failure") { false }
|
||||
end
|
||||
def test_error
|
||||
1 / 0
|
||||
end
|
||||
def return_passed?
|
||||
return passed?
|
||||
end
|
||||
end
|
||||
|
||||
def @tc_failure_error.name
|
||||
"TC_FailureError"
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_failed_assertion
|
||||
test_case = @tc_failure_error.new(:test_failure)
|
||||
check("passed? should start out true", test_case.return_passed?)
|
||||
result = TestResult.new
|
||||
called = false
|
||||
result.add_listener(TestResult::FAULT) {
|
||||
| fault |
|
||||
check("Should have a Failure", fault.instance_of?(Failure))
|
||||
check("The Failure should have the correct message", "failure" == fault.message)
|
||||
check("The Failure should have the correct location (was <#{fault.location}>)", fault.location =~ /test_failure\(TC_FailureError\) \[.*#{File.basename(__FILE__)}:\d+\]/)
|
||||
called = true
|
||||
}
|
||||
progress = []
|
||||
test_case.run(result) { |*arguments| progress << arguments }
|
||||
check("The failure should have triggered the listener", called)
|
||||
check("The failure should have set passed?", !test_case.return_passed?)
|
||||
check("The progress block should have been updated correctly", [[TestCase::STARTED, test_case.name], [TestCase::FINISHED, test_case.name]] == progress)
|
||||
end
|
||||
|
||||
def test_add_error
|
||||
test_case = @tc_failure_error.new(:test_error)
|
||||
check("passed? should start out true", test_case.return_passed?)
|
||||
result = TestResult.new
|
||||
called = false
|
||||
result.add_listener(TestResult::FAULT) {
|
||||
| fault |
|
||||
check("Should have a TestError", fault.instance_of?(Error))
|
||||
check("The Error should have the correct message", "ZeroDivisionError: divided by 0" == fault.message)
|
||||
check("The Error should have the correct location", "test_error(TC_FailureError)" == fault.location)
|
||||
check("The Error should have the correct exception", fault.exception.instance_of?(ZeroDivisionError))
|
||||
called = true
|
||||
}
|
||||
test_case.run(result) {}
|
||||
check("The error should have triggered the listener", called)
|
||||
check("The error should have set passed?", !test_case.return_passed?)
|
||||
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 check(message, passed)
|
||||
@_result.add_assertion
|
||||
if ! passed
|
||||
raise AssertionFailedError.new(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
104
test/testunit/test_testresult.rb
Normal file
104
test/testunit/test_testresult.rb
Normal file
|
@ -0,0 +1,104 @@
|
|||
# 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()
|
||||
@my_result.add_failure("")
|
||||
@my_result.add_error("")
|
||||
end
|
||||
def test_result_changed_notification
|
||||
called1 = false
|
||||
@my_result.add_listener( TestResult::CHANGED) {
|
||||
|result|
|
||||
assert_block("The result should be correct") { result == @my_result }
|
||||
called1 = true
|
||||
}
|
||||
@my_result.add_assertion
|
||||
assert_block("Should have been notified when the assertion happened") { called1 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_listener( TestResult::CHANGED) {
|
||||
|result|
|
||||
assert_block("The result should be correct") { result == @my_result }
|
||||
called2 = true
|
||||
}
|
||||
@my_result.add_assertion
|
||||
assert_block("Both listeners should have been notified for a success") { called1 && called2 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_failure("")
|
||||
assert_block("Both listeners should have been notified for a failure") { called1 && called2 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_error("")
|
||||
assert_block("Both listeners should have been notified for an error") { called1 && called2 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_run
|
||||
assert_block("Both listeners should have been notified for a run") { called1 && called2 }
|
||||
end
|
||||
def test_fault_notification
|
||||
called1 = false
|
||||
fault = "fault"
|
||||
@my_result.add_listener(TestResult::FAULT) {
|
||||
| passed_fault |
|
||||
assert_block("The fault should be correct") { passed_fault == fault }
|
||||
called1 = true
|
||||
}
|
||||
|
||||
@my_result.add_assertion
|
||||
assert_block("Should not have been notified when the assertion happened") { !called1 }
|
||||
|
||||
@my_result.add_failure(fault)
|
||||
assert_block("Should have been notified when the failure happened") { called1 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_listener(TestResult::FAULT) {
|
||||
| passed_fault |
|
||||
assert_block("The fault should be correct") { passed_fault == fault }
|
||||
called2 = true
|
||||
}
|
||||
|
||||
@my_result.add_assertion
|
||||
assert_block("Neither listener should have been notified for a success") { !(called1 || called2) }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_failure(fault)
|
||||
assert_block("Both listeners should have been notified for a failure") { called1 && called2 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_error(fault)
|
||||
assert_block("Both listeners should have been notified for an error") { called1 && called2 }
|
||||
|
||||
called1, called2 = false, false
|
||||
@my_result.add_run
|
||||
assert_block("Neither listener should have been notified for a run") { !(called1 || called2) }
|
||||
end
|
||||
def test_passed?
|
||||
result = TestResult.new
|
||||
assert(result.passed?, "An empty result should have passed")
|
||||
|
||||
result.add_assertion
|
||||
assert(result.passed?, "Adding an assertion should not cause the result to not pass")
|
||||
|
||||
result.add_run
|
||||
assert(result.passed?, "Adding a run should not cause the result to not pass")
|
||||
|
||||
result.add_failure("")
|
||||
assert(!result.passed?, "Adding a failed assertion should cause the result to not pass")
|
||||
|
||||
result = TestResult.new
|
||||
result.add_error("")
|
||||
assert(!result.passed?, "Adding an error should cause the result to not pass")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
116
test/testunit/test_testsuite.rb
Normal file
116
test/testunit/test_testsuite.rb
Normal file
|
@ -0,0 +1,116 @@
|
|||
# Author:: Nathaniel Talbott.
|
||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||
# License:: Ruby license.
|
||||
|
||||
require 'test/unit/testcase'
|
||||
require 'test/unit/testsuite'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class TC_TestSuite < 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_size
|
||||
assert_block("The count should be correct") do
|
||||
suite = TestSuite.new
|
||||
suite2 = TestSuite.new
|
||||
suite2 << self.class.new("test_size")
|
||||
suite << suite2
|
||||
suite << self.class.new("test_size")
|
||||
suite.size == 2
|
||||
end
|
||||
end
|
||||
|
||||
def test_run
|
||||
progress = []
|
||||
suite = @testcase1.suite
|
||||
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],
|
||||
[TestCase::STARTED, "test_fail(#{suite.name})"],
|
||||
[TestCase::FINISHED, "test_fail(#{suite.name})"],
|
||||
[TestCase::STARTED, "test_succeed1(#{suite.name})"],
|
||||
[TestCase::FINISHED, "test_succeed1(#{suite.name})"],
|
||||
[TestSuite::FINISHED, suite.name]],
|
||||
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(14, 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
|
102
test/testunit/util/test_observable.rb
Normal file
102
test/testunit/util/test_observable.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# 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
|
36
test/testunit/util/test_procwrapper.rb
Normal file
36
test/testunit/util/test_procwrapper.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# 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_not_equal(@original.hash, @munged.hash, "The original and munged procs should not have the same hash")
|
||||
|
||||
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_not_nil(a_hash[@wrapped_original], "Should be able to access the wrapper in the hash")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue