Reduce nesting by collapsing modules with ::

This commit is contained in:
Michael Miller 2018-09-27 16:20:55 -06:00
parent 0d282d3d50
commit 77b4c71c2a
14 changed files with 440 additions and 468 deletions

View file

@ -1,65 +1,63 @@
module Spectator module Spectator::DSL
module DSL module Builder
module Builder extend self
extend self
@@group_stack = [::Spectator::DSL::ExampleGroupBuilder.new("ROOT")] @@group_stack = [::Spectator::DSL::ExampleGroupBuilder.new("ROOT")]
private def root_group private def root_group
@@group_stack.first @@group_stack.first
end end
private def current_group private def current_group
@@group_stack.last @@group_stack.last
end end
private def push_group(group : ExampleGroupBuilder) private def push_group(group : ExampleGroupBuilder)
current_group.add_child(group) current_group.add_child(group)
@@group_stack.push(group) @@group_stack.push(group)
end end
def start_group(*args) : Nil def start_group(*args) : Nil
group = ::Spectator::DSL::ExampleGroupBuilder.new(*args) group = ::Spectator::DSL::ExampleGroupBuilder.new(*args)
push_group(group) push_group(group)
end end
def start_given_group(*args) : Nil def start_given_group(*args) : Nil
group = ::Spectator::DSL::GivenExampleGroupBuilder.new(*args) group = ::Spectator::DSL::GivenExampleGroupBuilder.new(*args)
push_group(group) push_group(group)
end end
def end_group : Nil def end_group : Nil
@@group_stack.pop @@group_stack.pop
end end
def add_example(example_type : Example.class) : Nil def add_example(example_type : Example.class) : Nil
factory = ::Spectator::DSL::ExampleFactory.new(example_type) factory = ::Spectator::DSL::ExampleFactory.new(example_type)
current_group.add_child(factory) current_group.add_child(factory)
end end
def add_before_all_hook(&block : ->) : Nil def add_before_all_hook(&block : ->) : Nil
current_group.add_before_all_hook(block) current_group.add_before_all_hook(block)
end end
def add_before_each_hook(&block : ->) : Nil def add_before_each_hook(&block : ->) : Nil
current_group.add_before_each_hook(block) current_group.add_before_each_hook(block)
end end
def add_after_all_hook(&block : ->) : Nil def add_after_all_hook(&block : ->) : Nil
current_group.add_after_all_hook(block) current_group.add_after_all_hook(block)
end end
def add_after_each_hook(&block : ->) : Nil def add_after_each_hook(&block : ->) : Nil
current_group.add_after_each_hook(block) current_group.add_after_each_hook(block)
end end
def add_around_each_hook(&block : Proc(Nil) ->) : Nil def add_around_each_hook(&block : Proc(Nil) ->) : Nil
current_group.add_around_each_hook(block) current_group.add_around_each_hook(block)
end end
protected def build : ExampleGroup protected def build : ExampleGroup
root_group.build(nil, Internals::SampleValues.empty) root_group.build(nil, Internals::SampleValues.empty)
end
end end
end end
end end

View file

@ -1,17 +1,15 @@
require "./matcher_dsl" require "./matcher_dsl"
module Spectator module Spectator::DSL
module DSL module ExampleDSL
module ExampleDSL include MatcherDSL
include MatcherDSL
macro is_expected macro is_expected
expect(subject) expect(subject)
end end
macro expect(actual) macro expect(actual)
::Spectator::Expectation.new({{actual.stringify}}, {{actual}}) ::Spectator::Expectation.new({{actual.stringify}}, {{actual}})
end
end end
end end
end end

View file

@ -1,12 +1,10 @@
module Spectator module Spectator::DSL
module DSL class ExampleFactory
class ExampleFactory def initialize(@example_type : Example.class)
def initialize(@example_type : Example.class) end
end
def build(group : ExampleGroup, sample_values : Internals::SampleValues) : Example def build(group : ExampleGroup, sample_values : Internals::SampleValues) : Example
@example_type.new(group, sample_values) @example_type.new(group, sample_values)
end
end end
end end
end end

View file

@ -1,60 +1,58 @@
module Spectator module Spectator::DSL
module DSL class ExampleGroupBuilder
class ExampleGroupBuilder alias Child = ExampleFactory | ExampleGroupBuilder
alias Child = ExampleFactory | ExampleGroupBuilder
@children = [] of Child @children = [] of Child
@before_all_hooks = [] of -> @before_all_hooks = [] of ->
@before_each_hooks = [] of -> @before_each_hooks = [] of ->
@after_all_hooks = [] of -> @after_all_hooks = [] of ->
@after_each_hooks = [] of -> @after_each_hooks = [] of ->
@around_each_hooks = [] of Proc(Nil) -> @around_each_hooks = [] of Proc(Nil) ->
def initialize(@what : String) def initialize(@what : String)
end end
def add_child(child : Child) : Nil def add_child(child : Child) : Nil
@children << child @children << child
end end
def add_before_all_hook(block : ->) : Nil def add_before_all_hook(block : ->) : Nil
@before_all_hooks << block @before_all_hooks << block
end end
def add_before_each_hook(block : ->) : Nil def add_before_each_hook(block : ->) : Nil
@before_each_hooks << block @before_each_hooks << block
end end
def add_after_all_hook(block : ->) : Nil def add_after_all_hook(block : ->) : Nil
@after_all_hooks << block @after_all_hooks << block
end end
def add_after_each_hook(block : ->) : Nil def add_after_each_hook(block : ->) : Nil
@after_each_hooks << block @after_each_hooks << block
end end
def add_around_each_hook(block : Proc(Nil) ->) : Nil def add_around_each_hook(block : Proc(Nil) ->) : Nil
@around_each_hooks << block @around_each_hooks << block
end end
def build(parent : ExampleGroup?, sample_values : Internals::SampleValues) : ExampleGroup def build(parent : ExampleGroup?, sample_values : Internals::SampleValues) : ExampleGroup
ExampleGroup.new(@what, parent, build_hooks).tap do |group| ExampleGroup.new(@what, parent, build_hooks).tap do |group|
children = @children.map do |child| children = @children.map do |child|
child.build(group, sample_values).as(ExampleGroup::Child) child.build(group, sample_values).as(ExampleGroup::Child)
end
group.children = children
end end
group.children = children
end end
end
private def build_hooks private def build_hooks
ExampleHooks.new( ExampleHooks.new(
@before_all_hooks, @before_all_hooks,
@before_each_hooks, @before_each_hooks,
@after_all_hooks, @after_all_hooks,
@after_each_hooks, @after_each_hooks,
@around_each_hooks @around_each_hooks
) )
end
end end
end end
end end

View file

@ -1,27 +1,25 @@
require "./example_group_builder" require "./example_group_builder"
module Spectator module Spectator::DSL
module DSL class GivenExampleGroupBuilder(T) < ExampleGroupBuilder
class GivenExampleGroupBuilder(T) < ExampleGroupBuilder
def initialize(what : String, @collection : Array(T), @symbol : Symbol) def initialize(what : String, @collection : Array(T), @symbol : Symbol)
super(what) super(what)
end end
def build(parent : ExampleGroup?, sample_values : Internals::SampleValues) : ExampleGroup def build(parent : ExampleGroup?, sample_values : Internals::SampleValues) : ExampleGroup
ExampleGroup.new(@what, parent, build_hooks).tap do |group| ExampleGroup.new(@what, parent, build_hooks).tap do |group|
group.children = @collection.map do |value| group.children = @collection.map do |value|
build_sub_group(group, sample_values, value).as(ExampleGroup::Child) build_sub_group(group, sample_values, value).as(ExampleGroup::Child)
end
end end
end end
end
private def build_sub_group(parent : ExampleGroup, sample_values : Internals::SampleValues, value : T) : ExampleGroup private def build_sub_group(parent : ExampleGroup, sample_values : Internals::SampleValues, value : T) : ExampleGroup
sub_values = sample_values.add(@symbol, @symbol.to_s, value) sub_values = sample_values.add(@symbol, @symbol.to_s, value)
ExampleGroup.new(value.to_s, parent, ExampleHooks.empty).tap do |group| ExampleGroup.new(value.to_s, parent, ExampleHooks.empty).tap do |group|
group.children = @children.map do |child| group.children = @children.map do |child|
child.build(group, sub_values).as(ExampleGroup::Child) child.build(group, sub_values).as(ExampleGroup::Child)
end
end end
end end
end end

View file

@ -1,11 +1,9 @@
require "../matchers" require "../matchers"
module Spectator module Spectator::DSL
module DSL module MatcherDSL
module MatcherDSL macro eq(expected)
macro eq(expected) ::Spectator::Matchers::EqualityMatcher.new({{expected.stringify}}, {{expected}})
::Spectator::Matchers::EqualityMatcher.new({{expected.stringify}}, {{expected}})
end
end end
end end
end end

View file

@ -1,198 +1,196 @@
require "../example_group" require "../example_group"
module Spectator module Spectator::DSL
module DSL module StructureDSL
module StructureDSL
def initialize(sample_values : Internals::SampleValues) def initialize(sample_values : Internals::SampleValues)
end
macro describe(what, &block)
context({{what}}) {{block}}
end
macro context(what, &block)
module Group%group
include {{@type.id}}
{% if what.is_a?(Path) || what.is_a?(Generic) %}
_spectator_described_class {{what}}
{% end %}
::Spectator::DSL::Builder.start_group(
{{what.is_a?(StringLiteral) ? what : what.stringify}}
)
{{block.body}}
::Spectator::DSL::Builder.end_group
end end
end
macro describe(what, &block) macro given(collection, &block)
context({{what}}) {{block}} module Group%group
end include {{@type.id}}
macro context(what, &block) def %collection
module Group%group {{collection}}
include {{@type.id}}
{% if what.is_a?(Path) || what.is_a?(Generic) %}
_spectator_described_class {{what}}
{% end %}
::Spectator::DSL::Builder.start_group(
{{what.is_a?(StringLiteral) ? what : what.stringify}}
)
{{block.body}}
::Spectator::DSL::Builder.end_group
end end
end
macro given(collection, &block) @%wrapper : ::Spectator::Internals::ValueWrapper
module Group%group
include {{@type.id}}
def %collection def {{block.args.empty? ? "value".id : block.args.first}}
{{collection}} @%wrapper.as(::Spectator::Internals::TypedValueWrapper(typeof(%collection.first))).value
end
@%wrapper : ::Spectator::Internals::ValueWrapper
def {{block.args.empty? ? "value".id : block.args.first}}
@%wrapper.as(::Spectator::Internals::TypedValueWrapper(typeof(%collection.first))).value
end
def initialize(sample_values : ::Spectator::Internals::SampleValues)
super
@%wrapper = sample_values.get_wrapper(:%group)
end
_spectator_given_collection Collection%collection, %to_a, %collection
%to_a = Collection%collection.new.%to_a
::Spectator::DSL::Builder.start_given_group(
{{collection.stringify}},
%to_a,
:%group
)
{{block.body}}
::Spectator::DSL::Builder.end_group
end end
def initialize(sample_values : ::Spectator::Internals::SampleValues)
super
@%wrapper = sample_values.get_wrapper(:%group)
end
_spectator_given_collection Collection%collection, %to_a, %collection
%to_a = Collection%collection.new.%to_a
::Spectator::DSL::Builder.start_given_group(
{{collection.stringify}},
%to_a,
:%group
)
{{block.body}}
::Spectator::DSL::Builder.end_group
end end
end
macro subject(&block) macro subject(&block)
let(:subject) {{block}} let(:subject) {{block}}
end end
macro let(name, &block) macro let(name, &block)
let!(%value) {{block}} let!(%value) {{block}}
@%wrapper : ::Spectator::Internals::ValueWrapper? @%wrapper : ::Spectator::Internals::ValueWrapper?
def {{name.id}} def {{name.id}}
if (wrapper = @%wrapper) if (wrapper = @%wrapper)
wrapper.unsafe_as(::Spectator::Internals::TypedValueWrapper(typeof(%value))).value wrapper.unsafe_as(::Spectator::Internals::TypedValueWrapper(typeof(%value))).value
else else
%value.tap do |value| %value.tap do |value|
@%wrapper = ::Spectator::Internals::TypedValueWrapper(typeof(%value)).new(value) @%wrapper = ::Spectator::Internals::TypedValueWrapper(typeof(%value)).new(value)
end
end end
end end
end end
end
macro let!(name, &block) macro let!(name, &block)
def {{name.id}} def {{name.id}}
{{block.body}}
end
end
macro before_all(&block)
::Spectator::DSL::Builder.add_before_all_hook {{block}}
end
macro before_each(&block)
::Spectator::DSL::Builder.add_before_each_hook {{block}}
end
macro after_all(&block)
::Spectator::DSL::Builder.add_after_all_hook {{block}}
end
macro after_each(&block)
::Spectator::DSL::Builder.add_after_each_hook {{block}}
end
macro around_each(&block)
::Spectator::DSL::Builder.add_around_each_hook {{block}}
end
def include_examples
raise NotImplementedError.new("Spectator::DSL#include_examples")
end
macro it(description, &block)
_spectator_example_wrapper(Wrapper%example, %run) {{block}}
_spectator_example(Example%example, Wrapper%example, ::Spectator::RunnableExample, {{description}}) do
protected def run_instance
@instance.%run
end
end
::Spectator::DSL::Builder.add_example(Example%example)
end
macro pending(description, &block)
_spectator_example_wrapper(Wrapper%example, %run) {{block}}
_spectator_example(Example%example, Wrapper%example, ::Spectator::PendingExample, {{description}})
::Spectator::DSL::Builder.add_example(Example%example)
end
macro it_behaves_like
{% raise NotImplementedError.new("it_behaves_like functionality is not implemented") %}
end
private macro _spectator_described_class(what)
def described_class
{{what}}.tap do |thing|
raise "#{thing} must be a type name to use #described_class or #subject,\
but it is a #{typeof(thing)}" unless thing.is_a?(Class)
end
end
_spectator_implicit_subject
end
private macro _spectator_implicit_subject
def subject
described_class.new
end
end
private macro _spectator_given_collection(class_name, to_a_method_name, collection_method_name)
class {{class_name.id}}
include {{@type.id}}
def {{to_a_method_name.id}}
{{collection_method_name.id}}.to_a
end
end
end
private macro _spectator_example_wrapper(class_name, run_method_name, &block)
class {{class_name.id}}
include ::Spectator::DSL::ExampleDSL
include {{@type.id}}
def initialize(sample_values : ::Spectator::Internals::SampleValues)
super
end
def {{run_method_name.id}}
{{block.body}} {{block.body}}
end end
end end
end
macro before_all(&block) private macro _spectator_example(example_class_name, wrapper_class_name, base_class, description, &block)
::Spectator::DSL::Builder.add_before_all_hook {{block}} class {{example_class_name.id}} < {{base_class.id}}
end def initialize(group : ::Spectator::ExampleGroup, sample_values : ::Spectator::Internals::SampleValues)
super
macro before_each(&block) @instance = {{wrapper_class_name.id}}.new(sample_values)
::Spectator::DSL::Builder.add_before_each_hook {{block}}
end
macro after_all(&block)
::Spectator::DSL::Builder.add_after_all_hook {{block}}
end
macro after_each(&block)
::Spectator::DSL::Builder.add_after_each_hook {{block}}
end
macro around_each(&block)
::Spectator::DSL::Builder.add_around_each_hook {{block}}
end
def include_examples
raise NotImplementedError.new("Spectator::DSL#include_examples")
end
macro it(description, &block)
_spectator_example_wrapper(Wrapper%example, %run) {{block}}
_spectator_example(Example%example, Wrapper%example, ::Spectator::RunnableExample, {{description}}) do
protected def run_instance
@instance.%run
end
end end
::Spectator::DSL::Builder.add_example(Example%example) {% if block.is_a?(Block) %}
end {{block.body}}
{% end %}
macro pending(description, &block) def description
_spectator_example_wrapper(Wrapper%example, %run) {{block}} {{description.is_a?(StringLiteral) ? description : description.stringify}}
_spectator_example(Example%example, Wrapper%example, ::Spectator::PendingExample, {{description}})
::Spectator::DSL::Builder.add_example(Example%example)
end
macro it_behaves_like
{% raise NotImplementedError.new("it_behaves_like functionality is not implemented") %}
end
private macro _spectator_described_class(what)
def described_class
{{what}}.tap do |thing|
raise "#{thing} must be a type name to use #described_class or #subject,\
but it is a #{typeof(thing)}" unless thing.is_a?(Class)
end
end
_spectator_implicit_subject
end
private macro _spectator_implicit_subject
def subject
described_class.new
end
end
private macro _spectator_given_collection(class_name, to_a_method_name, collection_method_name)
class {{class_name.id}}
include {{@type.id}}
def {{to_a_method_name.id}}
{{collection_method_name.id}}.to_a
end
end
end
private macro _spectator_example_wrapper(class_name, run_method_name, &block)
class {{class_name.id}}
include ::Spectator::DSL::ExampleDSL
include {{@type.id}}
def initialize(sample_values : ::Spectator::Internals::SampleValues)
super
end
def {{run_method_name.id}}
{{block.body}}
end
end
end
private macro _spectator_example(example_class_name, wrapper_class_name, base_class, description, &block)
class {{example_class_name.id}} < {{base_class.id}}
def initialize(group : ::Spectator::ExampleGroup, sample_values : ::Spectator::Internals::SampleValues)
super
@instance = {{wrapper_class_name.id}}.new(sample_values)
end
{% if block.is_a?(Block) %}
{{block.body}}
{% end %}
def description
{{description.is_a?(StringLiteral) ? description : description.stringify}}
end
end end
end end
end end

View file

@ -1,120 +1,118 @@
require "./formatter" require "./formatter"
require "colorize" require "colorize"
module Spectator module Spectator::Formatters
module Formatters class DefaultFormatter < Formatter
class DefaultFormatter < Formatter SUCCESS_COLOR = :green
SUCCESS_COLOR = :green FAILURE_COLOR = :red
FAILURE_COLOR = :red ERROR_COLOR = :magenta
ERROR_COLOR = :magenta PENDING_COLOR = :yellow
PENDING_COLOR = :yellow
SUCCESS_CHAR = '.'.colorize(SUCCESS_COLOR) SUCCESS_CHAR = '.'.colorize(SUCCESS_COLOR)
FAILURE_CHAR = 'F'.colorize(FAILURE_COLOR) FAILURE_CHAR = 'F'.colorize(FAILURE_COLOR)
ERROR_CHAR = 'E'.colorize(ERROR_COLOR) ERROR_CHAR = 'E'.colorize(ERROR_COLOR)
PENDING_CHAR = '*'.colorize(PENDING_COLOR) PENDING_CHAR = '*'.colorize(PENDING_COLOR)
def start_suite def start_suite
end end
def end_suite(results : TestResults) def end_suite(results : TestResults)
puts
puts
display_failures(results)
display_errors(results)
display_summary(results)
end
private def display_failures(results)
failures = results.failures
if failures.any?
puts "Failures:"
puts puts
puts failures.each_with_index do |failure, index|
display_failures(results) display_failure(failure.as(FailedResult), index + 1)
display_errors(results)
display_summary(results)
end
private def display_failures(results)
failures = results.failures
if failures.any?
puts "Failures:"
puts
failures.each_with_index do |failure, index|
display_failure(failure.as(FailedResult), index + 1)
end
end end
end end
end
private def display_failure(failure, number) private def display_failure(failure, number)
expected = "TODO" expected = "TODO"
actual = "TODO" actual = "TODO"
puts " #{number}) #{failure.example}" puts " #{number}) #{failure.example}"
puts " Failure: #{failure.error.message}" puts " Failure: #{failure.error.message}"
puts puts
puts " Expected: #{expected}" puts " Expected: #{expected}"
puts " got: #{actual}" puts " got: #{actual}"
puts puts
end
private def display_errors(results)
end
private def display_summary(results)
puts finish_time_string(results)
puts result_string(results)
end
def start_example(example : Example)
end
def end_example(result : Result)
print result_char(result)
end
private def result_char(result : Result)
case result
when SuccessfulResult
SUCCESS_CHAR
when PendingResult
PENDING_CHAR
when ErroredResult
ERROR_CHAR
when FailedResult
FAILURE_CHAR
end end
end
private def display_errors(results) private def finish_time_string(results)
"Finished in #{human_time(results.runtime)}"
end
private def result_string(results)
examples = results.examples
failures = results.failed_examples
errors = results.errored_examples
pending = results.pending_examples
string = "#{examples} examples, #{failures} failures, #{errors} errors, #{pending} pending"
if failures > 0 || errors > 0
string.colorize(FAILURE_COLOR)
elsif pending != examples
string.colorize(PENDING_COLOR)
else
string.colorize(SUCCESS_COLOR)
end end
end
private def display_summary(results) private def human_time(span : Time::Span)
puts finish_time_string(results) millis = span.total_milliseconds
puts result_string(results) return "#{(millis * 1000).round.to_i} microseconds" if millis < 1
end
def start_example(example : Example) seconds = span.total_seconds
end return "#{millis.round(2)} milliseconds" if seconds < 1
return "#{seconds.round(2)} seconds" if seconds < 60
def end_example(result : Result) int_seconds = seconds.to_i
print result_char(result) minutes = int_seconds / 60
end int_seconds %= 60
return sprintf("%i:%02i", minutes, int_seconds) if minutes < 60
private def result_char(result : Result) hours = minutes / 60
case result minutes %= 60
when SuccessfulResult return sprintf("%i:%02i:%02i", hours, minutes, int_seconds) if hours < 24
SUCCESS_CHAR
when PendingResult
PENDING_CHAR
when ErroredResult
ERROR_CHAR
when FailedResult
FAILURE_CHAR
end
end
private def finish_time_string(results) days = hours / 24
"Finished in #{human_time(results.runtime)}" hours %= 24
end return sprintf("%i days %i:%02i:%02i", days, hours, minutes, int_seconds)
private def result_string(results)
examples = results.examples
failures = results.failed_examples
errors = results.errored_examples
pending = results.pending_examples
string = "#{examples} examples, #{failures} failures, #{errors} errors, #{pending} pending"
if failures > 0 || errors > 0
string.colorize(FAILURE_COLOR)
elsif pending != examples
string.colorize(PENDING_COLOR)
else
string.colorize(SUCCESS_COLOR)
end
end
private def human_time(span : Time::Span)
millis = span.total_milliseconds
return "#{(millis * 1000).round.to_i} microseconds" if millis < 1
seconds = span.total_seconds
return "#{millis.round(2)} milliseconds" if seconds < 1
return "#{seconds.round(2)} seconds" if seconds < 60
int_seconds = seconds.to_i
minutes = int_seconds / 60
int_seconds %= 60
return sprintf("%i:%02i", minutes, int_seconds) if minutes < 60
hours = minutes / 60
minutes %= 60
return sprintf("%i:%02i:%02i", hours, minutes, int_seconds) if hours < 24
days = hours / 24
hours %= 24
return sprintf("%i days %i:%02i:%02i", days, hours, minutes, int_seconds)
end
end end
end end
end end

View file

@ -1,10 +1,8 @@
module Spectator module Spectator::Formatters
module Formatters abstract class Formatter
abstract class Formatter abstract def start_suite
abstract def start_suite abstract def end_suite(results : TestResults)
abstract def end_suite(results : TestResults) abstract def start_example(example : Example)
abstract def start_example(example : Example) abstract def end_example(result : Result)
abstract def end_example(result : Result)
end
end end
end end

View file

@ -1,27 +1,25 @@
require "./value_wrapper" require "./value_wrapper"
module Spectator module Spectator::Internals
module Internals struct SampleValues
struct SampleValues private record Entry, name : String, wrapper : ValueWrapper
private record Entry, name : String, wrapper : ValueWrapper
def self.empty def self.empty
new({} of Symbol => Entry) new({} of Symbol => Entry)
end end
protected def initialize(@values = {} of Symbol => Entry) protected def initialize(@values = {} of Symbol => Entry)
end end
def add(id : Symbol, name : String, value : T) : SampleValues forall T def add(id : Symbol, name : String, value : T) : SampleValues forall T
wrapper = TypedValueWrapper(T).new(value) wrapper = TypedValueWrapper(T).new(value)
SampleValues.new(@values.merge({ SampleValues.new(@values.merge({
id => Entry.new(name, wrapper) id => Entry.new(name, wrapper)
})) }))
end end
def get_wrapper(id : Symbol) def get_wrapper(id : Symbol)
@values[id].wrapper @values[id].wrapper
end
end end
end end
end end

View file

@ -1,12 +1,10 @@
require "./value_wrapper" require "./value_wrapper"
module Spectator module Spectator::Internals
module Internals class TypedValueWrapper(T) < ValueWrapper
class TypedValueWrapper(T) < ValueWrapper getter value : T
getter value : T
def initialize(@value : T) def initialize(@value : T)
end
end end
end end
end end

View file

@ -1,11 +1,9 @@
module Spectator module Spectator::Internals
module Internals # Base class for proxying test values to examples.
# Base class for proxying test values to examples. # This abstraction is required for inferring types.
# This abstraction is required for inferring types. # The `DSL#let` macro makes heavy use of this.
# The `DSL#let` macro makes heavy use of this. abstract class ValueWrapper
abstract class ValueWrapper # Retrieves the underlying value.
# Retrieves the underlying value. abstract def value
abstract def value
end
end end
end end

View file

@ -1,23 +1,21 @@
require "./matcher" require "./matcher"
module Spectator module Spectator::Matchers
module Matchers class EqualityMatcher(T) < Matcher
class EqualityMatcher(T) < Matcher def initialize(label, @expected : T)
def initialize(label, @expected : T) super(label)
super(label) end
end
def match?(expectation : Expectation) def match?(expectation : Expectation)
expectation.actual == @expected expectation.actual == @expected
end end
def message(expectation : Expectation) : String def message(expectation : Expectation) : String
"Expected #{expectation.label} to equal #{label} (using ==)" "Expected #{expectation.label} to equal #{label} (using ==)"
end end
def negated_message(expectation : Expectation) : String def negated_message(expectation : Expectation) : String
"Expected #{expectation.label} to not equal #{label} (using ==)" "Expected #{expectation.label} to not equal #{label} (using ==)"
end
end end
end end
end end

View file

@ -1,14 +1,12 @@
module Spectator module Spectator::Matchers
module Matchers abstract class Matcher
abstract class Matcher private getter label : String
private getter label : String
private def initialize(@label : String) private def initialize(@label : String)
end
abstract def match?(expectation : Expectation)
abstract def message(expectation : Expectation) : String
abstract def negated_message(expectation : Expectation) : String
end end
abstract def match?(expectation : Expectation)
abstract def message(expectation : Expectation) : String
abstract def negated_message(expectation : Expectation) : String
end end
end end