mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge branch 'let-assignment-variant' into 'release/0.8'
Implement assignment variant of let keyword See merge request arctic-fox/spectator!11
This commit is contained in:
commit
31fb1c3e81
1 changed files with 81 additions and 23 deletions
|
@ -789,7 +789,54 @@ module Spectator::DSL
|
||||||
# The name can be used in examples to retrieve the value (basically a method).
|
# The name can be used in examples to retrieve the value (basically a method).
|
||||||
# This can be used to define a value once and reuse it in multiple examples.
|
# This can be used to define a value once and reuse it in multiple examples.
|
||||||
#
|
#
|
||||||
# This macro expects a name and a block.
|
# There are two variants - assignment and block.
|
||||||
|
# Both must be given a name.
|
||||||
|
#
|
||||||
|
# For the assignment variant:
|
||||||
|
# ```
|
||||||
|
# let string = "foobar"
|
||||||
|
#
|
||||||
|
# it "isn't empty" do
|
||||||
|
# expect(string.empty?).to be_false
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it "is six characters" do
|
||||||
|
# expect(string.size).to eq(6)
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# The value is evaluated and stored immediately.
|
||||||
|
# This is different from other `#let` variants that lazily-evaluate.
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# let current_time = Time.utc
|
||||||
|
# let(lazy_time) { Time.utc }
|
||||||
|
#
|
||||||
|
# it "lazy evaluates" do
|
||||||
|
# now = current_time
|
||||||
|
# sleep 5
|
||||||
|
# expect(lazy_time).to_not eq(now)
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# However, the value is not reused across tests.
|
||||||
|
# It will be reconstructed when the next test starts.
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# let array = [0, 1, 2]
|
||||||
|
#
|
||||||
|
# it "modifies the array" do
|
||||||
|
# array[0] = 42
|
||||||
|
# expect(array).to eq([42, 1, 2])
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it "doesn't carry across tests" do
|
||||||
|
# array[1] = 777
|
||||||
|
# expect(array).to eq([0, 777, 2])
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# The block variant expects a name and a block.
|
||||||
# The name can be a symbol or a literal - same as `Object#getter`.
|
# The name can be a symbol or a literal - same as `Object#getter`.
|
||||||
# The block should return the value.
|
# The block should return the value.
|
||||||
#
|
#
|
||||||
|
@ -838,32 +885,43 @@ module Spectator::DSL
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
macro let(name, &block)
|
macro let(name, &block)
|
||||||
# Create a block that returns the value.
|
{% if block.is_a?(Nop) %}
|
||||||
let!(%value) {{block}}
|
# Assignment variant.
|
||||||
|
@%value = {{name.value}}
|
||||||
|
|
||||||
# Wrapper to hold the value.
|
def {{name.target}}
|
||||||
# This will be nil if the value hasn't been referenced yet.
|
@%value
|
||||||
# After being referenced, the cached value will be stored in a wrapper.
|
end
|
||||||
@%wrapper : ::Spectator::Internals::ValueWrapper?
|
{% else %}
|
||||||
|
# Block variant.
|
||||||
|
|
||||||
# Method for returning the value.
|
# Create a block that returns the value.
|
||||||
def {{name.id}}
|
let!(%value) {{block}}
|
||||||
# Check if the value is cached.
|
|
||||||
# The wrapper will be nil if it isn't.
|
# Wrapper to hold the value.
|
||||||
if (wrapper = @%wrapper)
|
# This will be nil if the value hasn't been referenced yet.
|
||||||
# It is cached, return that value.
|
# After being referenced, the cached value will be stored in a wrapper.
|
||||||
# Unwrap it from the wrapper variable.
|
@%wrapper : ::Spectator::Internals::ValueWrapper?
|
||||||
# Here we use typeof to get around the issue
|
|
||||||
# that the macro has no idea what type the value is.
|
# Method for returning the value.
|
||||||
wrapper.unsafe_as(::Spectator::Internals::TypedValueWrapper(typeof(%value))).value
|
def {{name.id}}
|
||||||
else
|
# Check if the value is cached.
|
||||||
# The value isn't cached,
|
# The wrapper will be nil if it isn't.
|
||||||
# Construct it and store it in the wrapper.
|
if (wrapper = @%wrapper)
|
||||||
%value.tap do |value|
|
# It is cached, return that value.
|
||||||
@%wrapper = ::Spectator::Internals::TypedValueWrapper(typeof(%value)).new(value)
|
# Unwrap it from the wrapper variable.
|
||||||
|
# Here we use typeof to get around the issue
|
||||||
|
# that the macro has no idea what type the value is.
|
||||||
|
wrapper.unsafe_as(::Spectator::Internals::TypedValueWrapper(typeof(%value))).value
|
||||||
|
else
|
||||||
|
# The value isn't cached,
|
||||||
|
# Construct it and store it in the wrapper.
|
||||||
|
%value.tap do |value|
|
||||||
|
@%wrapper = ::Spectator::Internals::TypedValueWrapper(typeof(%value)).new(value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
||||||
# The noisier sibling to `#let`.
|
# The noisier sibling to `#let`.
|
||||||
|
|
Loading…
Reference in a new issue