shard-spectator/src/spectator/dsl/structure_dsl.cr

205 lines
5.5 KiB
Crystal
Raw Normal View History

2018-09-15 17:21:23 +00:00
require "../example_group"
module Spectator
module DSL
module StructureDSL
def initialize(locals : Hash(Symbol, ::Spectator::ValueWrapper))
end
macro describe(what, &block)
context({{what}}) {{block}}
2018-09-15 17:21:23 +00:00
end
macro context(what, &block)
module Group%group
include {{@type.id}}
2018-09-15 17:21:23 +00:00
2018-09-20 01:29:33 +00:00
{% if what.is_a?(Path) || what.is_a?(Generic) %}
2018-09-23 22:07:03 +00:00
_spectator_described_class {{what}}
2018-09-20 01:29:33 +00:00
{% end %}
2018-09-15 17:21:23 +00:00
::Spectator::DSL::Builder.start_group(
{{what.is_a?(StringLiteral) ? what : what.stringify}}
)
2018-09-15 17:21:23 +00:00
{{block.body}}
::Spectator::DSL::Builder.end_group
2018-09-15 17:21:23 +00:00
end
end
macro given(collection, &block)
module Group%group
include {{@type.id}}
def %collection
{{collection}}
end
2018-09-23 18:05:19 +00:00
@%wrapper : ::Spectator::ValueWrapper
def {{block.args.empty? ? "value".id : block.args.first}}
2018-09-23 22:07:03 +00:00
@%wrapper.as(::Spectator::TypedValueWrapper(typeof(%collection.first))).value
end
2018-09-23 18:05:19 +00:00
def initialize(locals : Hash(Symbol, ::Spectator::ValueWrapper))
super
@%wrapper = locals[:%group]
end
2018-09-23 22:07:03 +00:00
_spectator_given_collection Collection%collection, %to_a, %collection
%to_a = Collection%collection.new.%to_a
2018-09-15 17:21:23 +00:00
::Spectator::DSL::Builder.start_given_group(
{{collection.stringify}},
%to_a,
:%group
)
{{block.body}}
::Spectator::DSL::Builder.end_group
end
end
2018-09-15 17:21:23 +00:00
macro subject(&block)
let(:subject) {{block}}
end
macro let(name, &block)
let!(%value) {{block}}
2018-09-23 18:05:19 +00:00
@%wrapper : ::Spectator::ValueWrapper?
2018-09-15 17:21:23 +00:00
def {{name.id}}
if (wrapper = @%wrapper)
2018-09-23 18:05:19 +00:00
wrapper.unsafe_as(::Spectator::TypedValueWrapper(typeof(%value))).value
2018-09-15 17:21:23 +00:00
else
%value.tap do |value|
2018-09-23 18:05:19 +00:00
@%wrapper = ::Spectator::TypedValueWrapper(typeof(%value)).new(value)
2018-09-15 17:21:23 +00:00
end
end
end
end
macro let!(name, &block)
def {{name.id}}
{{block.body}}
end
end
macro before_all(&block)
::Spectator::DSL::Builder.add_before_all_hook {{block}}
2018-09-15 17:21:23 +00:00
end
macro before_each(&block)
::Spectator::DSL::Builder.add_before_each_hook {{block}}
2018-09-15 17:21:23 +00:00
end
macro after_all(&block)
::Spectator::DSL::Builder.add_after_all_hook {{block}}
2018-09-15 17:21:23 +00:00
end
macro after_each(&block)
::Spectator::DSL::Builder.add_after_each_hook {{block}}
2018-09-15 17:21:23 +00:00
end
macro around_each(&block)
::Spectator::DSL::Builder.add_around_each_hook {{block}}
2018-09-15 17:21:23 +00:00
end
def include_examples
raise NotImplementedError.new("Spectator::DSL#include_examples")
end
macro it(description, &block)
2018-09-23 22:07:03 +00:00
_spectator_example_wrapper(Wrapper%example, %run) {{block}}
2018-09-23 22:07:03 +00:00
_spectator_example(Example%example, Wrapper%example, ::Spectator::RunnableExample, {{description}}) do
2018-09-15 17:21:23 +00:00
protected def run_instance
@instance.%run
2018-09-15 17:21:23 +00:00
end
end
2018-09-20 01:32:59 +00:00
2018-09-23 18:05:19 +00:00
::Spectator::DSL::Builder.add_example(Example%example)
2018-09-15 17:21:23 +00:00
end
macro pending(description, &block)
2018-09-23 22:07:03 +00:00
_spectator_example_wrapper(Wrapper%example, %run) {{block}}
2018-09-23 22:07:03 +00:00
_spectator_example(Example%example, Wrapper%example, ::Spectator::PendingExample, {{description}})
::Spectator::DSL::Builder.add_example(Example%example)
end
2018-09-15 17:21:23 +00:00
def it_behaves_like
raise NotImplementedError.new("Spectator::DSL#it_behaves_like")
end
2018-09-15 17:21:23 +00:00
2018-09-23 22:07:58 +00:00
private macro _spectator_described_class(what)
2018-09-20 01:29:33 +00:00
def described_class
{{what}}.tap do |thing|
raise "#{thing} must be a type name to use #described_class or #subject,\
but it is a #{typeof(thing)}" unless thing.is_a?(Class)
2018-09-15 17:21:23 +00:00
end
2018-09-20 01:29:33 +00:00
end
2018-09-15 17:21:23 +00:00
2018-09-23 22:07:03 +00:00
_spectator_implicit_subject
2018-09-15 17:21:23 +00:00
end
2018-09-23 22:07:58 +00:00
private macro _spectator_implicit_subject
def subject
described_class.new
end
2018-09-15 17:21:23 +00:00
end
2018-09-23 22:07:03 +00:00
2018-09-23 22:07:58 +00:00
private macro _spectator_given_collection(class_name, to_a_method_name, collection_method_name)
2018-09-23 22:07:03 +00:00
class {{class_name.id}}
include {{@type.id}}
def {{to_a_method_name.id}}
Array(::Spectator::ValueWrapper).new.tap do |array|
{{collection_method_name.id}}.each do |item|
array << ::Spectator::TypedValueWrapper(typeof(item)).new(item)
end
end
end
end
end
2018-09-23 22:07:58 +00:00
private macro _spectator_example_wrapper(class_name, run_method_name, &block)
2018-09-23 22:07:03 +00:00
class {{class_name.id}}
include ::Spectator::DSL::ExampleDSL
include {{@type.id}}
def initialize(locals : Hash(Symbol, ::Spectator::ValueWrapper))
super
end
def {{run_method_name.id}}
{{block.body}}
end
end
end
2018-09-23 22:07:58 +00:00
private macro _spectator_example(example_class_name, wrapper_class_name, base_class, description, &block)
2018-09-23 22:07:03 +00:00
class {{example_class_name.id}} < {{base_class.id}}
def initialize(group : ::Spectator::ExampleGroup, locals : Hash(Symbol, ::Spectator::ValueWrapper))
super
@instance = {{wrapper_class_name.id}}.new(locals)
end
{% if block.is_a?(Block) %}
{{block.body}}
{% end %}
def description
{{description.is_a?(StringLiteral) ? description : description.stringify}}
end
end
end
2018-09-15 17:21:23 +00:00
end
end
end