Created
February 11, 2011 13:19
-
-
Save nobu/822325 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: lib/test/unit/assertions.rb | |
=================================================================== | |
--- lib/test/unit/assertions.rb (revision 401) | |
+++ lib/test/unit/assertions.rb (working copy) | |
@@ -10,6 +10,7 @@ | |
module Test | |
module Unit | |
+ DEFAULT_DIR = File.expand_path('..', __FILE__) | |
## | |
# Test::Unit::Assertions contains the standard Test::Unit assertions. | |
@@ -45,7 +46,7 @@ | |
# end | |
public | |
- def assert_block(message="assert_block failed.") # :yields: | |
+ def assert_block(message="assert_block failed.") # :yields: | |
_wrap_assertion do | |
if (! yield) | |
raise AssertionFailedError.new(message.to_s) | |
@@ -60,8 +61,15 @@ | |
# assert [1, 2].include?(5) | |
public | |
- def assert(boolean, message=nil) | |
+ def assert(boolean, message=(no_message=true;nil)) | |
_wrap_assertion do | |
+ unless no_message | |
+ case message | |
+ when String, Proc | |
+ else | |
+ raise ArgumentError, "assertion message must be String or Proc, but #{message.class} was given." | |
+ end | |
+ end | |
assert_block("assert should not be called with a block.") { !block_given? } | |
assert_block(build_message(message, "<?> is not true.", boolean)) { boolean } | |
end | |
@@ -298,6 +306,30 @@ | |
end | |
## | |
+ # Passes if +object+ does not .respond_to? +method+ | |
+ # | |
+ # Example: | |
+ # assert_not_respond_to 'bugbear', :foobar | |
+ | |
+ public | |
+ def assert_not_respond_to(object, method, message="") | |
+ _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¥¥?(?) not expected¥n" + | |
+ "(Class: <?>)", | |
+ object, method, object.class) | |
+ assert_block(full_message) {!object.respond_to?(method)} | |
+ end | |
+ end | |
+ | |
+ ## | |
# Passes if +string+ =~ +pattern+. | |
# | |
# Example: | |
@@ -457,12 +489,13 @@ | |
assert_block(full_message) { regexp !~ string } | |
end | |
end | |
+ alias assert_not_match assert_no_match | |
UncaughtThrow = { | |
- NameError => /^uncaught throw ¥`(.+)¥'$/, | |
+ NameError => /^uncaught throw ¥`(.+)¥'$/, #` | |
ArgumentError => /^uncaught throw (.+)$/, | |
- ThreadError => /^uncaught throw ¥`(.+)¥' in thread / | |
- } #` | |
+ ThreadError => /^uncaught throw ¥`(.+)¥' in thread /, #` | |
+ } | |
## | |
# Passes if the block throws +expected_object+ | |
@@ -550,7 +583,7 @@ | |
# assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 | |
public | |
- def assert_in_delta(expected_float, actual_float, delta, message="") | |
+ def assert_in_delta(expected_float, actual_float, delta=0.001, message="") | |
_wrap_assertion do | |
_assert_in_delta_validate_arguments(expected_float, | |
actual_float, | |
@@ -565,6 +598,51 @@ | |
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.00001 | |
+ | |
+ public | |
+ 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) | |
+ 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+ have a relative | |
+ # error less than +epsilon+. | |
+ # | |
+ # Example: | |
+ # assert_in_epsilon 0.05, (50000.0 / 10**6), 0.00001 | |
+ def assert_in_epsilon(expected_float, actual_float, epsilon=0.001, message="") | |
+ delta = [expected_float.abs, actual_float.abs].min * epsilon, | |
+ assert_in_delta(expected_float, actual_float, delta, message) | |
+ end | |
+ | |
+ ## | |
+ # Passes if +expected_float+ and +actual_float+ don't have a | |
+ # relative error less than +epsilon+. | |
+ # | |
+ # Example: | |
+ # assert_not_in_epsilon 0.05, (50000.0 / 10**6), 0.00001 | |
+ def assert_not_in_epsilon(expected_float, actual_float, epsilon=0.001, message="") | |
+ delta = [expected_float.abs, actual_float.abs].min * epsilon, | |
+ assert_not_in_delta(expected_float, actual_float, delta, message) | |
+ end | |
+ | |
# :stopdoc: | |
private | |
def _assert_in_delta_validate_arguments(expected_float, | |
@@ -850,7 +928,7 @@ | |
end | |
## | |
- # Passes if +object+.+predicate+ | |
+ # Passes unless +object+.+predicate+ | |
# | |
# Example: | |
# assert_not_predicate([1], :empty?) # -> pass | |
@@ -956,6 +1034,74 @@ | |
end | |
## | |
+ # Passes if +collection+ includes +object+. | |
+ # | |
+ # Example: | |
+ # assert_includes([1, 10], 1) # -> pass | |
+ # assert_includes(1..10, 5) # -> pass | |
+ # assert_includes([1, 10], 5) # -> fail | |
+ # assert_includes(1..10, 20) # -> fail | |
+ def assert_includes(collection, object, message=nil) | |
+ _wrap_assertion do | |
+ assert_respond_to(collection, :include?) | |
+ full_message = build_message(message, "<?> expected to include¥n<?>.", collection, object) | |
+ assert_block(full_message) {collection.include?(object)} | |
+ end | |
+ end | |
+ | |
+ ## | |
+ # Passes if +collection+ doesn't include +object+. | |
+ # | |
+ # Example: | |
+ # assert_includes([1, 10], 1) # -> pass | |
+ # assert_includes(1..10, 5) # -> pass | |
+ # assert_includes([1, 10], 5) # -> fail | |
+ # assert_includes(1..10, 20) # -> fail | |
+ def assert_not_includes(collection, object, message=nil) | |
+ _wrap_assertion do | |
+ assert_respond_to(collection, :include?) | |
+ full_message = build_message(message, "<?> expected to include¥n<?>.", collection, object) | |
+ assert_block(full_message) {!collection.include?(object)} | |
+ end | |
+ end | |
+ | |
+ ## | |
+ # 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?) | |
+ full_message = build_message(message, "<?> expected to be empty", object) | |
+ assert_block(full_message) {object.empty?} | |
+ end | |
+ end | |
+ | |
+ ## | |
+ # Passes if +object+ is not 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_not_empty(object, message=nil) | |
+ _wrap_assertion do | |
+ assert_respond_to(object, :empty?) | |
+ full_message = build_message(message, "<?> expected to be empty", object) | |
+ assert_block(full_message) {!object.empty?} | |
+ end | |
+ end | |
+ | |
+ ## | |
# Builds a failure message. +head+ is added before the +template+ and | |
# +arguments+ replaces the '?'s positionally in the template. | |
@@ -966,21 +1112,32 @@ | |
end | |
private | |
- def _wrap_assertion | |
- @_assertion_wrapped ||= false | |
- unless (@_assertion_wrapped) | |
- @_assertion_wrapped = true | |
- begin | |
- add_assertion | |
- return yield | |
- ensure | |
- @_assertion_wrapped = false | |
+ wrap_assertion = proc do |block| | |
+ begin | |
+ @_assertion_wrapped ||= false | |
+ unless (@_assertion_wrapped) | |
+ @_assertion_wrapped = true | |
+ begin | |
+ add_assertion | |
+ return block.call | |
+ ensure | |
+ @_assertion_wrapped = false | |
+ end | |
+ else | |
+ return block.call | |
end | |
- else | |
- return yield | |
+ rescue => e | |
+ e.backtrace.reject! {|s| s.rindex(DEFAULT_DIR, 0)} | |
+ raise | |
end | |
end | |
- | |
+ define_method(:_wrap_assertion_safe0, wrap_assertion) | |
+ | |
+ private | |
+ def _wrap_assertion(&block) | |
+ _wrap_assertion_safe0(block) | |
+ end | |
+ | |
## | |
# Called whenever an assertion is made. Define this in classes that | |
# include Test::Unit::Assertions to record assertion counts. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment