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 module Spectator::DSL
# DSL methods for defining test values (subjects). # DSL methods for defining test values (subjects).
module Values 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) macro let(name, &block)
{% raise "Block required for 'let'" unless block %} {% raise "Block required for 'let'" unless block %}
{% raise "Cannot use 'let' inside of a test block" if @def %}
@%value = ::Spectator::LazyWrapper.new @%value = ::Spectator::LazyWrapper.new
@ -12,49 +17,69 @@ module Spectator::DSL
@%value.get {{block}} @%value.get {{block}}
end end
end end
end
macro let!(name, &block) # Defines a memoized getter.
@%wrapper : ::Spectator::ValueWrapper? # 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 let({{name}}) {{block}}
{{block.body}} before_each { {{name.id}} }
end
before_each do
@%wrapper = ::Spectator::TypedValueWrapper.new(%wrapper)
end
def {{name.id}}
@%wrapper.as(::Spectator::TypedValueWrapper(typeof(%wrapper))).value
end
end end
macro subject(&block) # Explicitly defines the subject of the tests.
{% if block.is_a?(Nop) %} # Creates a memoized getter for the subject.
self.subject # The block is evaluated only the first time the subject is referenced
{% else %} # and the return value is saved for subsequent calls.
let(:subject) {{block}} 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 %}
end end
macro subject(name, &block) # Explicitly defines the subject of the tests.
let({{name.id}}) {{block}} # 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 let!(subject) {{block}}
{{name.id}}
end
end end
macro subject!(&block) # Explicitly defines the subject of the tests.
let!(:subject) {{block}} # Creates a memoized getter for the subject.
end # 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) {% if name.id != :subject.id %}
let!({{name.id}}) {{block}} def {{name.id}}
subject
def subject end
{{name.id}} {% end %}
end
end end
end
end end