Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spec/std/socket_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe Socket::Addrinfo do
end

it "eventually raises returned error" do
expect_raises(Socket::Error) do |addrinfo|
expect_raises(Socket::Error) do
Socket::Addrinfo.resolve("localhost", 80, type: Socket::Type::DGRAM) do |addrinfo|
Socket::Error.new("please fail")
end
Expand Down
60 changes: 25 additions & 35 deletions src/spec/expectations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,8 @@ module Spec
end

# Creates an `Expectation` that passes if actual is of type *type* (`is_a?`).
macro be_a(type)
Spec::BeAExpectation({{type}}).new
end

# Runs the block and passes if it raises an exception of type *klass*.
#
# It returns the rescued exception.
macro expect_raises(klass)
expect_raises({{klass}}, nil) do
{{yield}}
end
def be_a(type : T.class) forall T
Spec::BeAExpectation(T).new
end

# Runs the block and passes if it raises an exception of type *klass* and the error message matches.
Expand All @@ -286,41 +277,40 @@ module Spec
# If *message* is a regular expression, it is used to match the error message.
#
# It returns the rescued exception.
macro expect_raises(klass, message, file = __FILE__, line = __LINE__)
%failed = false
def expect_raises(klass : T.class, message = nil, file = __FILE__, line = __LINE__) forall T
failed = false
begin
{{yield}}
%failed = true
fail "Expected {{klass.id}} but nothing was raised", {{file}}, {{line}}
rescue %ex : {{klass.id}}
yield
failed = true

@RX14 RX14 Jan 26, 2018

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we skip this failed hackery and implement it with an else clause in the begin block? Then we could attach the raise and else to the method and remove the begin/end.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but what about:

        fail "Expected #{klass} but nothing was raised", file, line

we want to ignore that exception

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done!

fail "Expected #{klass} but nothing was raised", file, line
rescue ex : T
# We usually bubble Spec::AssertaionFailed, unless this is the expected exception
if %ex.class == Spec::AssertionFailed && {{klass}} != Spec::AssertionFailed
raise %ex
if ex.is_a?(Spec::AssertionFailed) && klass != Spec::AssertionFailed
raise ex
end

%msg = {{message}}
%ex_to_s = %ex.to_s
case %msg
ex_to_s = ex.to_s
case message
when Regex
unless (%ex_to_s =~ %msg)
backtrace = %ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected {{klass.id}} with message matching #{ %msg.inspect }, got #<#{ %ex.class }: #{ %ex_to_s }> with backtrace:\n#{backtrace}", {{file}}, {{line}}
unless (ex_to_s =~ message)
backtrace = ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected #{klass} with message matching #{message.inspect}, got #<#{ex.class}: #{ex_to_s}> with backtrace:\n#{backtrace}", file, line
end
when String
unless %ex_to_s.includes?(%msg)
backtrace = %ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected {{klass.id}} with #{ %msg.inspect }, got #<#{ %ex.class }: #{ %ex_to_s }> with backtrace:\n#{backtrace}", {{file}}, {{line}}
unless ex_to_s.includes?(message)
backtrace = ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected #{klass} with #{message.inspect}, got #<#{ex.class}: #{ex_to_s}> with backtrace:\n#{backtrace}", file, line
end
end

%ex
rescue %ex
if %failed
raise %ex
ex
rescue ex
if failed
raise ex
else
%ex_to_s = %ex.to_s
backtrace = %ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected {{klass.id}}, got #<#{ %ex.class }: #{ %ex_to_s }> with backtrace:\n#{backtrace}", {{file}}, {{line}}
ex_to_s = ex.to_s
backtrace = ex.backtrace.map { |f| " # #{f}" }.join "\n"
fail "Expected #{klass}, got #<#{ex.class}: #{ex_to_s}> with backtrace:\n#{backtrace}", file, line
end
end
end
Expand Down