diff --git a/src/spectator/dsl.cr b/src/spectator/dsl.cr index d739a45..fcb6587 100644 --- a/src/spectator/dsl.cr +++ b/src/spectator/dsl.cr @@ -9,6 +9,6 @@ module Spectator module DSL # Keywords that cannot be used in specs using the DSL. # These are either problematic or reserved for internal use. - RESERVED_KEYWORDS = %i[initialize _spectator_double_name _spectator_find_stub] + RESERVED_KEYWORDS = %i[initialize _spectator_stubbed_name _spectator_find_stub] end end diff --git a/src/spectator/dsl/mocks.cr b/src/spectator/dsl/mocks.cr index cb850a2..fba9629 100644 --- a/src/spectator/dsl/mocks.cr +++ b/src/spectator/dsl/mocks.cr @@ -52,7 +52,7 @@ module Spectator::DSL # This is important for constructing an instance of the double later. ::Spectator::DSL::Mocks::DOUBLES << {name_symbol, context_type_name, double_type_name} %} - ::Spectator::Double.define({{double_type_name}}, {{value_methods.double_splat}}) do + ::Spectator::Double.define({{double_type_name}}, {{name}}, {{value_methods.double_splat}}) do {{block.body}} end {% end %} diff --git a/src/spectator/mocks/double.cr b/src/spectator/mocks/double.cr index b0e1cbf..2a4754e 100644 --- a/src/spectator/mocks/double.cr +++ b/src/spectator/mocks/double.cr @@ -1,12 +1,17 @@ -require "./unexpected_message" -require "./stub" -require "./stubable" -require "./value_stub" require "./arguments" require "./method_call" +require "./stub" +require "./stubable" +require "./unexpected_message" +require "./value_stub" module Spectator - annotation DoubleName; end + # Defines the name of a double or mock. + # + # When present on a stubbed type, this annotation indicates its name in output such as exceptions. + # Must have one argument - the name of the double or mock. + # This can be a symbol, string literal, or type name. + annotation StubbedName; end # Stands in for an object for testing that a SUT calls expected methods. # @@ -16,7 +21,7 @@ module Spectator include Stubable macro define(type_name, name = nil, **value_methods, &block) - {% if name %}@[DoubleName({{name}})]{% end %} + {% if name %}@[::Spectator::StubbedName({{name}})]{% end %} class {{type_name.id}} < {{@type.name}} {% for key, value in value_methods %} inject_stub def {{key.id}} @@ -35,9 +40,9 @@ module Spectator end # Utility returning the double's name as a string. - private def _spectator_double_name : String - {% if anno = @type.annotation(DoubleName) %} - "#" {% else %} "#" {% end %} @@ -51,9 +56,9 @@ module Spectator # Handle all methods but only respond to configured messages. # Raises an `UnexpectedMessage` error for non-configures messages. macro method_missing(call) - arguments = ::Spectator::Arguments.capture({{call.args.splat(", ")}}{% if call.named_args %}{{call.named_args.splat}}{% end %}) - call = ::Spectator::MethodCall.new({{call.name.symbolize}}, arguments) - raise ::Spectator::UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{call.name}} with #{arguments}") + args = ::Spectator::Arguments.capture({{call.args.splat(", ")}}{% if call.named_args %}{{call.named_args.splat}}{% end %}) + call = ::Spectator::MethodCall.new({{call.name.symbolize}}, args) + raise ::Spectator::UnexpectedMessage.new("#{_spectator_stubbed_name} received unexpected message :{{call.name}} with #{args}") nil # Necessary for compiler to infer return type as nil. Avoids runtime "can't execute ... `x` has no type errors". end end diff --git a/src/spectator/mocks/stubable.cr b/src/spectator/mocks/stubable.cr index 5a3705e..fdcca45 100644 --- a/src/spectator/mocks/stubable.cr +++ b/src/spectator/mocks/stubable.cr @@ -32,7 +32,7 @@ module Spectator else {% if method.abstract? %} # Response not configured for this method/message. - raise ::Spectator::UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{method.name}} with #{%args}") + raise ::Spectator::UnexpectedMessage.new("#{_spectator_stubbed_name} received unexpected message :{{method.name}} with #{%args}") {% else %} {{original}} {% end %} @@ -67,7 +67,7 @@ module Spectator {% end %} else # Response not configured for this method/message. - raise ::Spectator::UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{method.name}} with #{%args}") + raise ::Spectator::UnexpectedMessage.new("#{_spectator_stubbed_name} received unexpected message :{{method.name}} with #{%args}") end end end