mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/mspec@e3abf6b
This commit is contained in:
parent
5a79d8e050
commit
f4502b001a
8 changed files with 97 additions and 38 deletions
|
@ -12,6 +12,14 @@ def bignum_value(plus = 0)
|
|||
0x8000_0000_0000_0000 + plus
|
||||
end
|
||||
|
||||
def max_long
|
||||
2**(0.size * 8 - 1) - 1
|
||||
end
|
||||
|
||||
def min_long
|
||||
-(2**(0.size * 8 - 1))
|
||||
end
|
||||
|
||||
# This is a bit hairy, but we need to be able to write specs that cover the
|
||||
# boundary between Fixnum and Bignum for operations like Fixnum#<<. Since
|
||||
# this boundary is implementation-dependent, we use these helpers to write
|
||||
|
|
|
@ -6,34 +6,43 @@ class RaiseErrorMatcher
|
|||
@actual = nil
|
||||
end
|
||||
|
||||
# This #matches? method is unusual because it doesn't always return a boolean but instead
|
||||
# re-raises the original exception if proc.call raises an exception and #matching_exception? is false.
|
||||
# The reasoning is the original exception class matters and we don't want to change it by raising another exception,
|
||||
# so instead we attach the #failure_message and extract it in ExceptionState#message.
|
||||
def matches?(proc)
|
||||
@result = proc.call
|
||||
return false
|
||||
rescue Exception => actual
|
||||
@actual = actual
|
||||
|
||||
if matching_exception?(actual)
|
||||
# The block has its own expectations and will throw an exception if it fails
|
||||
@block[actual] if @block
|
||||
|
||||
return true
|
||||
else
|
||||
actual.instance_variable_set(:@mspec_raise_error_message, failure_message)
|
||||
raise actual
|
||||
end
|
||||
end
|
||||
|
||||
def matching_exception?(exc)
|
||||
return false unless @exception === exc
|
||||
def matching_class?(exc)
|
||||
@exception === exc
|
||||
end
|
||||
|
||||
if @message then
|
||||
case @message
|
||||
when String
|
||||
return false if @message != exc.message
|
||||
when Regexp
|
||||
return false if @message !~ exc.message
|
||||
end
|
||||
def matching_message?(exc)
|
||||
case @message
|
||||
when String
|
||||
@message == exc.message
|
||||
when Regexp
|
||||
@message =~ exc.message
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
def matching_exception?(exc)
|
||||
matching_class?(exc) and matching_message?(exc)
|
||||
end
|
||||
|
||||
def exception_class_and_message(exception_class, message)
|
||||
|
@ -56,7 +65,7 @@ class RaiseErrorMatcher
|
|||
message = ["Expected #{format_expected_exception}"]
|
||||
|
||||
if @actual
|
||||
message << "but got #{format_exception(@actual)}"
|
||||
message << "but got: #{format_exception(@actual)}"
|
||||
else
|
||||
message << "but no exception was raised (#{MSpec.format(@result)} was returned)"
|
||||
end
|
||||
|
@ -67,7 +76,7 @@ class RaiseErrorMatcher
|
|||
def negative_failure_message
|
||||
message = ["Expected to not get #{format_expected_exception}", ""]
|
||||
unless @actual.class == @exception
|
||||
message[1] = "but got #{format_exception(@actual)}"
|
||||
message[1] = "but got: #{format_exception(@actual)}"
|
||||
end
|
||||
message
|
||||
end
|
||||
|
|
|
@ -49,6 +49,7 @@ class LeakChecker
|
|||
check_env
|
||||
check_argv
|
||||
check_encodings
|
||||
check_tracepoints
|
||||
GC.start if !@leaks.empty?
|
||||
@leaks.empty?
|
||||
end
|
||||
|
@ -259,6 +260,14 @@ class LeakChecker
|
|||
@encoding_info = [new_internal, new_external]
|
||||
end
|
||||
|
||||
def check_tracepoints
|
||||
ObjectSpace.each_object(TracePoint) do |tp|
|
||||
if tp.enabled?
|
||||
leak "TracePoint is still enabled: #{tp.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def leak(message)
|
||||
if @leaks.empty?
|
||||
$stderr.puts "\n"
|
||||
|
|
|
@ -37,7 +37,7 @@ class TimeoutAction
|
|||
if elapsed > @timeout
|
||||
STDERR.puts "\n#{@current_state.description}"
|
||||
STDERR.flush
|
||||
abort "Example took #{now - @started}s, which is longer than the timeout of #{@timeout}s"
|
||||
abort "Example took longer than the configured timeout of #{@timeout}s"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ class ExceptionState
|
|||
|
||||
def initialize(state, location, exception)
|
||||
@exception = exception
|
||||
@failure = exception.class == SpecExpectationNotMetError || exception.class == SpecExpectationNotFoundError
|
||||
|
||||
@description = location ? "An exception occurred during: #{location}" : ""
|
||||
if state
|
||||
|
@ -19,25 +20,26 @@ class ExceptionState
|
|||
end
|
||||
|
||||
def failure?
|
||||
[SpecExpectationNotMetError, SpecExpectationNotFoundError].any? { |e| @exception.is_a? e }
|
||||
@failure
|
||||
end
|
||||
|
||||
def message
|
||||
if @exception.message.empty?
|
||||
"<No message>"
|
||||
elsif @exception.class == SpecExpectationNotMetError ||
|
||||
@exception.class == SpecExpectationNotFoundError
|
||||
@exception.message
|
||||
message = @exception.message
|
||||
message = "<No message>" if message.empty?
|
||||
|
||||
if @failure
|
||||
message
|
||||
elsif raise_error_message = @exception.instance_variable_get(:@mspec_raise_error_message)
|
||||
raise_error_message.join("\n")
|
||||
else
|
||||
"#{@exception.class}: #{@exception.message}"
|
||||
"#{@exception.class}: #{message}"
|
||||
end
|
||||
end
|
||||
|
||||
def backtrace
|
||||
@backtrace_filter ||= MSpecScript.config[:backtrace_filter]
|
||||
@backtrace_filter ||= MSpecScript.config[:backtrace_filter] || %r{(?:/bin/mspec|/lib/mspec/)}
|
||||
|
||||
bt = @exception.backtrace || []
|
||||
|
||||
bt.select { |line| $MSPEC_DEBUG or @backtrace_filter !~ line }.join("\n")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,11 @@ end
|
|||
|
||||
module MSpec
|
||||
def self.format(obj)
|
||||
obj.pretty_inspect.chomp
|
||||
if String === obj and obj.include?("\n")
|
||||
"\n#{obj.inspect.gsub('\n', "\n")}"
|
||||
else
|
||||
obj.pretty_inspect.chomp
|
||||
end
|
||||
rescue => e
|
||||
"#<#{obj.class}>(#pretty_inspect raised #{e.inspect})"
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ describe RaiseErrorMatcher do
|
|||
matcher.matches?(proc).should == true
|
||||
end
|
||||
|
||||
it "executes it's optional block if matched" do
|
||||
it "executes its optional block if matched" do
|
||||
run = false
|
||||
proc = Proc.new { raise ExpectedException }
|
||||
matcher = RaiseErrorMatcher.new(ExpectedException, nil) { |error|
|
||||
|
@ -62,16 +62,21 @@ describe RaiseErrorMatcher do
|
|||
matcher.matches?(proc).should == false
|
||||
end
|
||||
|
||||
it "provides a useful failure message" do
|
||||
exc = UnexpectedException.new("unexpected")
|
||||
matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
|
||||
it "provides a useful failure message when the exception class differs" do
|
||||
exc = UnexpectedException.new("message")
|
||||
matcher = RaiseErrorMatcher.new(ExpectedException, "message")
|
||||
|
||||
matcher.matching_exception?(exc).should == false
|
||||
lambda {
|
||||
begin
|
||||
matcher.matches?(Proc.new { raise exc })
|
||||
}.should raise_error(UnexpectedException)
|
||||
matcher.failure_message.should ==
|
||||
["Expected ExpectedException (expected)", "but got UnexpectedException (unexpected)"]
|
||||
rescue UnexpectedException => e
|
||||
matcher.failure_message.should ==
|
||||
["Expected ExpectedException (message)", "but got: UnexpectedException (message)"]
|
||||
ExceptionState.new(nil, nil, e).message.should ==
|
||||
"Expected ExpectedException (message)\nbut got: UnexpectedException (message)"
|
||||
else
|
||||
raise "no exception"
|
||||
end
|
||||
end
|
||||
|
||||
it "provides a useful failure message when the proc raises the expected exception with an unexpected message" do
|
||||
|
@ -79,11 +84,33 @@ describe RaiseErrorMatcher do
|
|||
matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
|
||||
|
||||
matcher.matching_exception?(exc).should == false
|
||||
lambda {
|
||||
begin
|
||||
matcher.matches?(Proc.new { raise exc })
|
||||
}.should raise_error(ExpectedException)
|
||||
matcher.failure_message.should ==
|
||||
["Expected ExpectedException (expected)", "but got ExpectedException (unexpected)"]
|
||||
rescue ExpectedException => e
|
||||
matcher.failure_message.should ==
|
||||
["Expected ExpectedException (expected)", "but got: ExpectedException (unexpected)"]
|
||||
ExceptionState.new(nil, nil, e).message.should ==
|
||||
"Expected ExpectedException (expected)\nbut got: ExpectedException (unexpected)"
|
||||
else
|
||||
raise "no exception"
|
||||
end
|
||||
end
|
||||
|
||||
it "provides a useful failure message when both the exception class and message differ" do
|
||||
exc = UnexpectedException.new("unexpected")
|
||||
matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
|
||||
|
||||
matcher.matching_exception?(exc).should == false
|
||||
begin
|
||||
matcher.matches?(Proc.new { raise exc })
|
||||
rescue UnexpectedException => e
|
||||
matcher.failure_message.should ==
|
||||
["Expected ExpectedException (expected)", "but got: UnexpectedException (unexpected)"]
|
||||
ExceptionState.new(nil, nil, e).message.should ==
|
||||
"Expected ExpectedException (expected)\nbut got: UnexpectedException (unexpected)"
|
||||
else
|
||||
raise "no exception"
|
||||
end
|
||||
end
|
||||
|
||||
it "provides a useful failure message when no exception is raised" do
|
||||
|
@ -127,6 +154,6 @@ describe RaiseErrorMatcher do
|
|||
matcher = RaiseErrorMatcher.new(Exception, nil)
|
||||
matcher.matches?(proc)
|
||||
matcher.negative_failure_message.should ==
|
||||
["Expected to not get Exception", "but got UnexpectedException (unexpected)"]
|
||||
["Expected to not get Exception", "but got: UnexpectedException (unexpected)"]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -93,7 +93,7 @@ describe ExceptionState, "#message" do
|
|||
|
||||
it "returns <No message> if the exception message is empty" do
|
||||
exc = ExceptionState.new @state, "", Exception.new("")
|
||||
exc.message.should == "<No message>"
|
||||
exc.message.should == "Exception: <No message>"
|
||||
end
|
||||
|
||||
it "returns the message without exception class when the exception is an SpecExpectationNotMetError" do
|
||||
|
|
Loading…
Reference in a new issue