Implement remaining value DSL macros

This commit is contained in:
Michael Miller 2021-01-09 17:36:50 -07:00
parent 391325d431
commit 122395837f
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD

View file

@ -3,8 +3,13 @@ require "../lazy_wrapper"
module Spectator::DSL
# DSL methods for defining test values (subjects).
module Values
# Defines a memoized getter.
# The *name* is the name of the getter method.
# The block is evaluated only on the first time the getter is used
# and the return value is saved for subsequent calls.
macro let(name, &block)
{% raise "Block required for 'let'" unless block %}
{% raise "Cannot use 'let' inside of a test block" if @def %}
@%value = ::Spectator::LazyWrapper.new
@ -12,49 +17,69 @@ module Spectator::DSL
@%value.get {{block}}
end
end
end
macro let!(name, &block)
@%wrapper : ::Spectator::ValueWrapper?
# Defines a memoized getter.
# The *name* is the name of the getter method.
# The block is evaluated once before the example runs
# and the return value is saved.
macro let!(name, &block)
{% raise "Block required for 'let!'" unless block %}
{% raise "Cannot use 'let!' inside of a test block" if @def %}
def %wrapper
{{block.body}}
end
before_each do
@%wrapper = ::Spectator::TypedValueWrapper.new(%wrapper)
end
def {{name.id}}
@%wrapper.as(::Spectator::TypedValueWrapper(typeof(%wrapper))).value
end
let({{name}}) {{block}}
before_each { {{name.id}} }
end
macro subject(&block)
{% if block.is_a?(Nop) %}
self.subject
{% else %}
let(:subject) {{block}}
# Explicitly defines the subject of the tests.
# Creates a memoized getter for the subject.
# The block is evaluated only the first time the subject is referenced
# and the return value is saved for subsequent calls.
macro subject(&block)
{% raise "Block required for 'subject'" unless block %}
{% raise "Cannot use 'subject' inside of a test block" if @def %}
let(subject) {{block}}
end
# Explicitly defines the subject of the tests.
# Creates a memoized getter for the subject.
# The subject can be referenced by using `subject` or *name*.
# The block is evaluated only the first time the subject is referenced
# and the return value is saved for subsequent calls.
macro subject(name, &block)
subject {{block}}
{% if name.id != :subject.id %}
def {{name.id}}
subject
end
{% end %}
end
macro subject(name, &block)
let({{name.id}}) {{block}}
# Explicitly defines the subject of the tests.
# Creates a memoized getter for the subject.
# The block is evaluated once before the example runs
# and the return value is saved for subsequent calls.
macro subject!(&block)
{% raise "Block required for 'subject!'" unless block %}
{% raise "Cannot use 'subject!' inside of a test block" if @def %}
def subject
{{name.id}}
end
let!(subject) {{block}}
end
macro subject!(&block)
let!(:subject) {{block}}
end
# Explicitly defines the subject of the tests.
# Creates a memoized getter for the subject.
# The subject can be referenced by using `subject` or *name*.
# The block is evaluated once before the example runs
# and the return value is saved for subsequent calls.
macro subject!(name, &block)
subject! {{block}}
macro subject!(name, &block)
let!({{name.id}}) {{block}}
def subject
{{name.id}}
end
{% if name.id != :subject.id %}
def {{name.id}}
subject
end
{% end %}
end
end
end