mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Add block expression
This commit is contained in:
parent
fbe9f22e02
commit
950f6b3424
2 changed files with 75 additions and 0 deletions
53
src/spectator/block.cr
Normal file
53
src/spectator/block.cr
Normal file
|
@ -0,0 +1,53 @@
|
|||
require "./abstract_expression"
|
||||
require "./label"
|
||||
require "./wrapper"
|
||||
|
||||
module Spectator
|
||||
# Represents a block from a test.
|
||||
# This is typically captured by an `expect` macro.
|
||||
# It consists of a label and parameterless block.
|
||||
# The label should be a string recognizable by the user,
|
||||
# or nil if one isn't available.
|
||||
class Block(T) < AbstractExpression
|
||||
# Cached value returned from the block.
|
||||
# Is nil if the block hasn't been called.
|
||||
@wrapper : Wrapper(T)?
|
||||
|
||||
# Creates the block expression from a proc.
|
||||
# The *proc* will be called to evaluate the value of the expression.
|
||||
# The *label* is usually the Crystal code for the *proc*.
|
||||
# It can be nil if it isn't available.
|
||||
def initialize(@block : -> T, label : Label)
|
||||
super(label)
|
||||
end
|
||||
|
||||
# Creates the block expression by capturing a block as a proc.
|
||||
# The block will be called to evaluate the value of the expression.
|
||||
# The *label* is usually the Crystal code for the *block*.
|
||||
# It can be nil if it isn't available.
|
||||
def initialize(label : Label, &@block : -> T)
|
||||
super(label)
|
||||
end
|
||||
|
||||
# Retrieves the value of the block expression.
|
||||
# This will be the return value of the block.
|
||||
# The block is lazily evaluated and the value retrieved only once.
|
||||
# Afterwards, the value is cached and returned by successive calls to this method.
|
||||
def value
|
||||
if (wrapper = @wrapper)
|
||||
wrapper.value
|
||||
else
|
||||
call.tap do |value|
|
||||
@wrapper = Wrapper.new(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Evaluates the block and returns the value from it.
|
||||
# This method _does not_ cache the resulting value like `#value` does.
|
||||
# Successive calls to this method may return different values.
|
||||
def call : T
|
||||
@block.call
|
||||
end
|
||||
end
|
||||
end
|
22
src/spectator/wrapper.cr
Normal file
22
src/spectator/wrapper.cr
Normal file
|
@ -0,0 +1,22 @@
|
|||
module Spectator
|
||||
# Wrapper for a value.
|
||||
# This is intended to be used as a union with nil.
|
||||
# It allows storing (caching) a nillable value.
|
||||
# ```
|
||||
# if (wrapper = @wrapper)
|
||||
# wrapper.value
|
||||
# else
|
||||
# value = 42
|
||||
# @wrapper = Wrapper.new(value)
|
||||
# value
|
||||
# end
|
||||
# ```
|
||||
struct Wrapper(T)
|
||||
# Original value.
|
||||
getter value : T
|
||||
|
||||
# Creates the wrapper.
|
||||
def initialize(@value : T)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue