Fix existing mock DSL macros

Initial code for mock DSL.
This commit is contained in:
Michael Miller 2022-05-28 09:18:49 -06:00
parent 6060b3cd10
commit 03754321b5
No known key found for this signature in database
GPG key ID: AC78B32D30CE34A2
2 changed files with 51 additions and 4 deletions

View file

@ -0,0 +1,38 @@
require "../../../spec_helper"
Spectator.describe "Mock DSL", :smoke do
context "with a concrete class" do
class ConcreteClass
def method1
"original"
end
def method2 : Symbol
:original
end
end
context "specifying methods as keyword args" do
mock(ConcreteClass, method1: "stubbed", method2: :stubbed)
subject(fake) { mock(ConcreteClass) }
it "defines a mock with methods" do
aggregate_failures do
expect(fake.method1).to eq("stubbed")
expect(fake.method2).to eq(:stubbed)
end
end
it "defines a subclass" do
expect(fake).to be_a(ConcreteClass)
end
it "compiles types without unions" do
aggregate_failures do
expect(fake.method1).to compile_as(String)
expect(fake.method2).to compile_as(Symbol)
end
end
end
end
end

View file

@ -128,16 +128,25 @@ module Spectator::DSL
::Spectator::LazyDouble.new({{**value_methods}})
end
private macro def_mock(type, **value_methods, &block)
private macro def_mock(type, name = nil, **value_methods, &block)
{% # Construct a unique type name for the mock by using the number of defined types.
index = ::Spectator::DSL::Mocks::TYPES.size
mock_type_name = "Mock#{index}".id
# Store information about how the mock is defined and its context.
# This is important for constructing an instance of the mock later.
::Spectator::DSL::Mocks::TYPES << {type.id.symbolize, @type.name(generic_args: false).symbolize, mock_type_name.symbolize} %}
::Spectator::DSL::Mocks::TYPES << {type.id.symbolize, @type.name(generic_args: false).symbolize, mock_type_name.symbolize}
::Spectator::Mock.define({{type.id}}, {{**value_methods}}){% if block %} do
resolved = type.resolve
base = if resolved.class?
:class
elsif resolved.struct?
:struct
else
:module
end %}
::Spectator::Mock.define_subtype({{base}}, {{type.id}}, {{mock_type_name}}, {{name}}, {{**value_methods}}){% if block %} do
{% block.body %}
end{% end %}
end
@ -177,7 +186,7 @@ module Spectator::DSL
macro mock(type, **value_methods, &block)
{% begin %}
{% if @def %}new_mock{% else %}def_mock{% end %}({{name}}, {{**value_methods}}){% if block %} do
{% if @def %}new_mock{% else %}def_mock{% end %}({{type}}, {{**value_methods}}){% if block %} do
{{block.body}}
end{% end %}
{% end %}