From 1e1503331ee51dfc492f1a3af2073dc9e1e01a3d Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sat, 23 Feb 2019 21:52:10 -0700 Subject: [PATCH] Initial change to MatchData --- src/spectator/expectations/expectation.cr | 21 +++------ .../expectations/expectation_partial.cr | 4 +- src/spectator/matchers/match_data.cr | 27 ++++++++++++ src/spectator/matchers/matcher.cr | 10 +---- src/spectator/matchers/nil_matcher.cr | 44 +++++++++++++------ 5 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 src/spectator/matchers/match_data.cr diff --git a/src/spectator/expectations/expectation.cr b/src/spectator/expectations/expectation.cr index a4f6843..f88b4b6 100644 --- a/src/spectator/expectations/expectation.cr +++ b/src/spectator/expectations/expectation.cr @@ -6,10 +6,9 @@ module Spectator::Expectations # The *negated* flag should be true if the expectation is inverted. # These options are mutually-exclusive in this context. # Don't flip the value of *matched* because *negated* is true. - # The *partial* and the *matcher* arguments should reference - # the actual and expected result respectively. - def initialize(@matched : Bool, @negated : Bool, - @partial : ExpectationPartial, @matcher : Matchers::Matcher) + # The *match_data* is the value returned by `Spectator::Matcher#match` + # when the expectation was evaluated. + def initialize(@matched : Bool, @negated : Bool, @match_data : MatchData) end # Indicates whether the expectation was satisifed. @@ -22,22 +21,12 @@ module Spectator::Expectations # Text that indicates the condition that must be met for the expectation to be satisifed. def expected_message - @negated ? negated_message : message + @negated ? @match_data.negated_message : @match_data.message end # Text that indicates what the outcome was. def actual_message - satisfied? ? message : negated_message - end - - # Describes the condition that must be met for the expectation to be satisifed. - private def message - @matcher.message(@partial) - end - - # Describes the condition under which the expectation won't be satisifed. - private def negated_message - @matcher.negated_message(@partial) + satisfied? ? @match_data.message : @match_data.negated_message end end end diff --git a/src/spectator/expectations/expectation_partial.cr b/src/spectator/expectations/expectation_partial.cr index 3e9483f..9265178 100644 --- a/src/spectator/expectations/expectation_partial.cr +++ b/src/spectator/expectations/expectation_partial.cr @@ -44,8 +44,8 @@ module Spectator::Expectations # Evaluates the expectation and returns it. private def eval(matcher, negated = false) - matched = matcher.match?(self) - Expectation.new(matched, negated, self, matcher) + match_data = matcher.match(self) + Expectation.new(matched, negated, match_data) end # Reports an expectation to the current harness. diff --git a/src/spectator/matchers/match_data.cr b/src/spectator/matchers/match_data.cr new file mode 100644 index 0000000..05a169f --- /dev/null +++ b/src/spectator/matchers/match_data.cr @@ -0,0 +1,27 @@ +module Spectator::Matchers + # Information regarding a expectation parial and matcher. + # `Matcher#match` will return a sub-type of this. + abstract struct MatchData + # Indicates whether the matcher was satisified with the expectation partial. + getter? matched : Bool + + # Creates the base of the match data. + # The *matched* argument indicates + # whether the matcher was satisified with the expectation partial. + def initialize(@matched) + end + + # Information about the match. + # Returned value and type will differ by sub-type, + # but all will return a set of key-value pairs. + abstract def values + + # Describes the condition that satisfies the matcher. + # This is informational and displayed to the end-user. + abstract def message : String + + # Describes the condition that won't satsify the matcher. + # This is informational and displayed to the end-user. + abstract def negated_message : String + end +end diff --git a/src/spectator/matchers/matcher.cr b/src/spectator/matchers/matcher.cr index 7028fbf..dad3229 100644 --- a/src/spectator/matchers/matcher.cr +++ b/src/spectator/matchers/matcher.cr @@ -14,14 +14,6 @@ module Spectator::Matchers # Determines whether the matcher is satisfied with the value given to it. # True is returned if the match was successful, false otherwise. - abstract def match?(partial) : Bool - - # Describes the condition that satisfies the matcher. - # This is informational and displayed to the end-user. - abstract def message(partial) : String - - # Describes the condition that won't satsify the matcher. - # This is informational and displayed to the end-user. - abstract def negated_message(partial) : String + abstract def match(partial) : MatchData end end diff --git a/src/spectator/matchers/nil_matcher.cr b/src/spectator/matchers/nil_matcher.cr index 5c5537d..67a67b5 100644 --- a/src/spectator/matchers/nil_matcher.cr +++ b/src/spectator/matchers/nil_matcher.cr @@ -9,22 +9,40 @@ module Spectator::Matchers super("nil?") end - # Determines whether the matcher is satisfied with the value given to it. - # True is returned if the match was successful, false otherwise. - def match?(partial) - partial.actual.nil? + # Determines whether the matcher is satisfied with the partial given to it. + # `MatchData` is returned that contains information about the match. + def match(partial) + actual = partial.actual + matched = actual.nil? + MatchData.new(matched, actual, partial.label) end - # Describes the condition that satisfies the matcher. - # This is informational and displayed to the end-user. - def message(partial) - "Expected #{partial.label} to be nil" - end + # Match data specific to this matcher. + private struct MatchData(T) < MatchData + # Creates the match data. + def initialize(matched, @actual : T, @expected_label : String) + super(matched) + end - # Describes the condition that won't satsify the matcher. - # This is informational and displayed to the end-user. - def negated_message(partial) - "Expected #{partial.label} to not be nil" + # Information about the match. + def values + { + expected: nil, + actual: @actual, + } + end + + # Describes the condition that satisfies the matcher. + # This is informational and displayed to the end-user. + def message + "#{@expected_label} is nil" + end + + # Describes the condition that won't satsify the matcher. + # This is informational and displayed to the end-user. + def negated_message + "#{@expected_label} is not nil" + end end end end