Skip to content

Instantly share code, notes, and snippets.

@nobu
Created February 11, 2011 13:19
Show Gist options
  • Save nobu/822325 to your computer and use it in GitHub Desktop.
Save nobu/822325 to your computer and use it in GitHub Desktop.
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