2020-09-06 16:31:23 +00:00
|
|
|
require "./example_context_delegate"
|
2020-09-05 21:01:22 +00:00
|
|
|
require "./example_group"
|
2020-09-06 01:54:55 +00:00
|
|
|
require "./example_node"
|
2020-11-08 03:56:30 +00:00
|
|
|
require "./harness"
|
2020-10-17 20:56:31 +00:00
|
|
|
require "./pending_result"
|
2020-09-05 21:01:22 +00:00
|
|
|
require "./result"
|
|
|
|
require "./source"
|
2018-10-14 23:10:12 +00:00
|
|
|
|
2018-08-19 07:15:32 +00:00
|
|
|
module Spectator
|
2020-09-05 21:01:22 +00:00
|
|
|
# Standard example that runs a test case.
|
2020-09-06 01:54:55 +00:00
|
|
|
class Example < ExampleNode
|
2020-11-08 03:56:30 +00:00
|
|
|
# Currently running example.
|
|
|
|
class_getter! current : Example
|
|
|
|
|
2020-09-05 21:01:22 +00:00
|
|
|
# Indicates whether the example already ran.
|
|
|
|
getter? finished : Bool = false
|
|
|
|
|
|
|
|
# Retrieves the result of the last time the example ran.
|
2020-10-17 20:56:31 +00:00
|
|
|
getter result : Result = PendingResult.new
|
2020-09-05 21:01:22 +00:00
|
|
|
|
|
|
|
# Creates the example.
|
2020-11-08 22:06:49 +00:00
|
|
|
# An instance to run the test code in is given by *context*.
|
|
|
|
# The *entrypoint* defines the test code (typically inside *context*).
|
2020-09-05 21:01:22 +00:00
|
|
|
# The *name* describes the purpose of the example.
|
|
|
|
# It can be a `Symbol` to describe a type.
|
|
|
|
# The *source* tracks where the example exists in source code.
|
|
|
|
# The example will be assigned to *group* if it is provided.
|
2020-11-08 22:06:49 +00:00
|
|
|
def initialize(@context : Context, @entrypoint : ExampleContextMethod,
|
2020-09-27 00:14:59 +00:00
|
|
|
name : String? = nil, source : Source? = nil, group : ExampleGroup? = nil)
|
2020-09-05 21:01:22 +00:00
|
|
|
super(name, source, group)
|
|
|
|
end
|
|
|
|
|
2020-11-07 21:43:59 +00:00
|
|
|
# Creates a dynamic example.
|
|
|
|
# A block provided to this method will be called as-if it were the test code for the example.
|
|
|
|
# The block will be given this example instance as an argument.
|
|
|
|
# The *name* describes the purpose of the example.
|
|
|
|
# It can be a `Symbol` to describe a type.
|
|
|
|
# The *source* tracks where the example exists in source code.
|
|
|
|
# The example will be assigned to *group* if it is provided.
|
|
|
|
def initialize(name : String? = nil, source : Source? = nil, group : ExampleGroup? = nil, &block : Example -> _)
|
2020-11-08 22:06:49 +00:00
|
|
|
@context = NullContext.new
|
|
|
|
@entrypoint = block
|
2020-11-07 21:43:59 +00:00
|
|
|
end
|
|
|
|
|
2020-09-05 21:01:22 +00:00
|
|
|
# Executes the test case.
|
|
|
|
# Returns the result of the execution.
|
|
|
|
# The result will also be stored in `#result`.
|
2018-10-10 19:05:17 +00:00
|
|
|
def run : Result
|
2020-11-08 03:56:30 +00:00
|
|
|
@@current = self
|
|
|
|
Log.debug { "Running example #{self}" }
|
2020-11-08 22:06:49 +00:00
|
|
|
Log.warn { "Example #{self} already ran" } if @finished
|
|
|
|
@result = Harness.run { @entrypoint.call(self, @context) }
|
2020-11-08 03:56:30 +00:00
|
|
|
ensure
|
|
|
|
@@current = nil
|
2020-10-17 20:56:31 +00:00
|
|
|
@finished = true
|
2019-03-23 03:29:20 +00:00
|
|
|
end
|
2020-09-06 01:54:55 +00:00
|
|
|
|
2020-11-08 22:06:49 +00:00
|
|
|
# Executes code within the example's test context.
|
|
|
|
# This is an advanced method intended for internal usage only.
|
|
|
|
#
|
|
|
|
# The *klass* defines the type of the test context.
|
|
|
|
# This is typically only known by the code constructing the example.
|
|
|
|
# An error will be raised if *klass* doesn't match the test context's type.
|
|
|
|
# The block given to this method will be executed within the test context.
|
|
|
|
#
|
|
|
|
# TODO: Benchmark compiler performance using this method versus client-side casting in a proc.
|
|
|
|
def with_context(klass)
|
|
|
|
context = klass.cast(@delegate.context)
|
|
|
|
with context yield
|
|
|
|
end
|
|
|
|
|
2020-09-06 01:54:55 +00:00
|
|
|
# Exposes information about the example useful for debugging.
|
|
|
|
def inspect(io)
|
2020-10-17 17:51:16 +00:00
|
|
|
# Full example name.
|
|
|
|
io << '"'
|
|
|
|
to_s(io)
|
|
|
|
io << '"'
|
|
|
|
|
|
|
|
# Add source if it's available.
|
2020-11-07 22:24:22 +00:00
|
|
|
if (source = self.source)
|
2020-10-17 17:51:16 +00:00
|
|
|
io << " @ "
|
2020-11-07 20:47:39 +00:00
|
|
|
io << source
|
2020-10-17 17:51:16 +00:00
|
|
|
end
|
|
|
|
|
2020-10-17 20:56:31 +00:00
|
|
|
io << result
|
2020-09-06 01:54:55 +00:00
|
|
|
end
|
2018-08-19 07:15:32 +00:00
|
|
|
end
|
|
|
|
end
|