2021-05-08 02:09:33 +00:00
|
|
|
require "./label"
|
|
|
|
require "./location"
|
2021-06-12 22:45:45 +00:00
|
|
|
require "./metadata"
|
2021-05-08 02:09:33 +00:00
|
|
|
|
|
|
|
module Spectator
|
|
|
|
# A single item in a test spec.
|
|
|
|
# This is commonly an `Example` or `ExampleGroup`,
|
|
|
|
# but can be anything that should be iterated over when running the spec.
|
|
|
|
abstract class Node
|
2021-06-12 01:29:29 +00:00
|
|
|
# Default text used if none was given by the user for skipping a node.
|
|
|
|
DEFAULT_PENDING_REASON = "No reason given"
|
|
|
|
|
2021-05-08 02:09:33 +00:00
|
|
|
# Location of the node in source code.
|
|
|
|
getter! location : Location
|
|
|
|
|
|
|
|
# User-provided name or description of the node.
|
|
|
|
# This does not include the group name or descriptions.
|
|
|
|
# Use `#to_s` to get the full name.
|
|
|
|
#
|
|
|
|
# This value will be nil if no name was provided.
|
|
|
|
# In this case, and the node is a runnable example,
|
|
|
|
# the name should be set to the description
|
|
|
|
# of the first matcher that runs in the test case.
|
|
|
|
#
|
|
|
|
# If this value is a `Symbol`, the user specified a type for the name.
|
|
|
|
getter! name : Label
|
|
|
|
|
|
|
|
# Updates the name of the node.
|
|
|
|
protected def name=(@name : String)
|
|
|
|
end
|
|
|
|
|
2021-06-12 22:45:45 +00:00
|
|
|
# User-defined tags and values used for filtering and behavior modification.
|
|
|
|
getter metadata : Metadata
|
2021-05-08 02:09:33 +00:00
|
|
|
|
|
|
|
# Creates the node.
|
|
|
|
# The *name* describes the purpose of the node.
|
|
|
|
# It can be a `Symbol` to describe a type.
|
|
|
|
# The *location* tracks where the node exists in source code.
|
2021-06-12 22:45:45 +00:00
|
|
|
# A set of *metadata* can be used for filtering and modifying example behavior.
|
|
|
|
def initialize(@name : Label = nil, @location : Location? = nil, @metadata : Metadata = Metadata.new)
|
2021-05-08 02:09:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Indicates whether the node has completed.
|
|
|
|
abstract def finished? : Bool
|
|
|
|
|
|
|
|
# Checks if the node has been marked as pending.
|
|
|
|
# Pending items should be skipped during execution.
|
|
|
|
def pending?
|
2021-06-12 22:45:45 +00:00
|
|
|
metadata.has_key?(:pending) || metadata.has_key?(:skip)
|
2021-05-08 02:09:33 +00:00
|
|
|
end
|
|
|
|
|
2021-06-12 01:29:29 +00:00
|
|
|
# Gets the reason the node has been marked as pending.
|
|
|
|
def pending_reason
|
2021-06-12 22:45:45 +00:00
|
|
|
metadata[:pending]? || metadata[:skip]? || metadata[:reason]? || DEFAULT_PENDING_REASON
|
|
|
|
end
|
|
|
|
|
|
|
|
# Retrieves just the tag names applied to the node.
|
|
|
|
def tags
|
|
|
|
Tags.new(metadata.keys)
|
2021-06-12 01:29:29 +00:00
|
|
|
end
|
|
|
|
|
2021-05-08 02:09:33 +00:00
|
|
|
# Constructs the full name or description of the node.
|
|
|
|
# This prepends names of groups this node is part of.
|
|
|
|
def to_s(io)
|
2021-05-08 03:04:17 +00:00
|
|
|
(@name || "<anonymous>").to_s(io)
|
2021-05-08 02:09:33 +00:00
|
|
|
end
|
2021-05-08 19:22:13 +00:00
|
|
|
|
|
|
|
# Exposes information about the node useful for debugging.
|
|
|
|
def inspect(io)
|
|
|
|
# Full node name.
|
2021-05-30 20:21:42 +00:00
|
|
|
io << '"' << self << '"'
|
2021-05-08 19:22:13 +00:00
|
|
|
|
|
|
|
# Add location if it's available.
|
|
|
|
if (location = self.location)
|
2021-05-30 20:21:42 +00:00
|
|
|
io << " @ " << location
|
2021-05-08 19:22:13 +00:00
|
|
|
end
|
|
|
|
end
|
2021-05-08 02:09:33 +00:00
|
|
|
end
|
|
|
|
end
|