Split #expect macro

TIL Crystal supports macro overloading, the argument count must be
different.
This commit is contained in:
Michael Miller 2019-01-23 16:42:17 -07:00
parent 046d946669
commit 17c66dd732

View file

@ -33,16 +33,39 @@ module Spectator::DSL
# expect(&.size).to eq(5) # expect(&.size).to eq(5)
# ``` # ```
# The method passed will always be evaluated on `#subject`. # The method passed will always be evaluated on `#subject`.
macro expect(*actual, &block) macro expect(*actual)
# The signature for this macro is strange because of how it can be used.
# If no block is provided, then the base case is used.
{% if block.is_a?(Nop) %}
# Loop over every "actual" to check - this is typically just one item. # Loop over every "actual" to check - this is typically just one item.
{% for item in actual %} {% for item in actual %}
::Spectator::Expectations::ValueExpectationPartial.new({{item.stringify}}, {{item}}) ::Spectator::Expectations::ValueExpectationPartial.new({{item.stringify}}, {{item}})
{% end %} {% end %}
{% else %} end
# A block was provided.
# Starts an expectation on a block of code.
# This should be followed up with `to` or `to_not`.
# The block passed in, or its return value, will be checked
# to see if it satisfies the conditions specified.
#
# This method should be used like so:
# ```
# expect { raise "foo" }.to raise_error
# ```
# The block of code is passed along for validation to the matchers.
#
# The short, one argument syntax used for passing methods to blocks can be used.
# So instead of doing this:
# ```
# expect(subject.size).to eq(5)
# ```
# The following syntax can be used instead:
# ```
# expect(&.size).to eq(5)
# ```
# The method passed will always be evaluated on `#subject`.
macro expect(&block)
{% if block.is_a?(Nop) %}
{% raise "Argument or block must be provided to expect" %}
{% end %}
# Check if the short-hand method syntax is used. # Check if the short-hand method syntax is used.
# This is a hack, since macros don't get this as a "literal" or something similar. # This is a hack, since macros don't get this as a "literal" or something similar.
# The Crystal compiler will translate `&.foo` to `{ |__arg0| __arg0.foo }`. # The Crystal compiler will translate `&.foo` to `{ |__arg0| __arg0.foo }`.
@ -58,7 +81,6 @@ module Spectator::DSL
# Just drop in the block as-is. # Just drop in the block as-is.
::Spectator::Expectations::ValueExpectationPartial.new({{block.body.stringify}}, {{block.body}}) ::Spectator::Expectations::ValueExpectationPartial.new({{block.body.stringify}}, {{block.body}})
{% end %} {% end %}
{% end %}
end end
# Starts an expectation. # Starts an expectation.