From f29aba42d2abeda6419488139da77a4ab63314ce Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Wed, 6 Mar 2019 13:04:18 -0700 Subject: [PATCH] Update TruthyMatcher to use MatchData --- spec/matchers/truthy_matcher_spec.cr | 380 ++++++++++++++++------- src/spectator/matchers/truthy_matcher.cr | 56 +++- 2 files changed, 300 insertions(+), 136 deletions(-) diff --git a/spec/matchers/truthy_matcher_spec.cr b/spec/matchers/truthy_matcher_spec.cr index cf4c5a9..70207a8 100644 --- a/spec/matchers/truthy_matcher_spec.cr +++ b/spec/matchers/truthy_matcher_spec.cr @@ -16,137 +16,279 @@ def be_comparison end describe Spectator::Matchers::TruthyMatcher do - context "truthy" do - describe "#match?" do - context "with a truthy value" do - it "is true" do - value = 42 - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.match?(partial).should be_true + describe "#match" do + context "returned MatchData" do + context "truthy" do + describe "#matched?" do + context "with a truthy value" do + it "is true" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.matched?.should be_true + end + end + + context "with false" do + it "is false" do + value = false + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.matched?.should be_false + end + end + + context "with nil" do + it "is false" do + value = nil + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.matched?.should be_false + end + end + end + + describe "#values" do + context "expected" do + it "contains the definition of falsey" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:expected].should match(/false or nil/i) + end + + it "is prefixed with \"Not\"" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:expected].should start_with(/not/i) + end + end + + context "actual" do + it "is the actual value" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:actual].should eq(value) + end + end + + context "truthy" do + context "when the actual value is truthy" do + it "is true" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_true + end + end + + context "when the actual value is false" do + it "is false" do + value = false + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_false + end + end + + context "when the actual value is nil" do + it "is false" do + value = nil + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_false + end + end + end + end + + describe "#message" do + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.message.should contain(label) + end + + it "contains the \"truthy\"" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.message.should contain("truthy") + end + end + + describe "#negated_message" do + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.negated_message.should contain(label) + end + + it "contains the \"truthy\"" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(true) + match_data = matcher.match(partial) + match_data.negated_message.should contain("truthy") + end end end - context "with false" do - it "is false" do - value = false - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.match?(partial).should be_false + context "falsey" do + describe "#matched?" do + context "with a truthy value" do + it "is false" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.matched?.should be_false + end + end + + context "with false" do + it "is true" do + value = false + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.matched?.should be_true + end + end + + context "with nil" do + it "is true" do + value = nil + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.matched?.should be_true + end + end end - end - context "with nil" do - it "is false" do - value = nil - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.match?(partial).should be_false + describe "#values" do + context "expected" do + it "contains the definition of falsey" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:expected].should match(/false or nil/i) + end + + it "is not prefixed with \"Not\"" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:expected].should_not start_with(/not/i) + end + end + + context "actual" do + it "is the actual value" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:actual].should eq(value) + end + end + + context "truthy" do + context "when the actual value is truthy" do + it "is true" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_true + end + end + + context "when the actual value is false" do + it "is false" do + value = false + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_false + end + end + + context "when the actual value is nil" do + it "is false" do + value = nil + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.values[:truthy].should be_false + end + end + end end - end - end - describe "#message" do - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.message(partial).should contain(label) - end + describe "#message" do + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.message.should contain(label) + end - it "contains the \"truthy\"" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.message(partial).should contain("truthy") - end - end - - describe "#negated_message" do - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.negated_message(partial).should contain(label) - end - - it "contains the \"truthy\"" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(true) - matcher.negated_message(partial).should contain("truthy") - end - end - end - - context "falsey" do - describe "#match?" do - context "with a truthy value" do - it "is false" do - value = 42 - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.match?(partial).should be_false + it "contains the \"falsey\"" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.message.should contain("falsey") + end end - end - context "with false" do - it "is true" do - value = false - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.match?(partial).should be_true + describe "#negated_message" do + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.negated_message.should contain(label) + end + + it "contains the \"falsey\"" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::TruthyMatcher.new(false) + match_data = matcher.match(partial) + match_data.negated_message.should contain("falsey") + end end end - - context "with nil" do - it "is true" do - value = nil - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.match?(partial).should be_true - end - end - end - - describe "#message" do - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.message(partial).should contain(label) - end - - it "contains the \"falsey\"" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.message(partial).should contain("falsey") - end - end - - describe "#negated_message" do - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.negated_message(partial).should contain(label) - end - - it "contains the \"falsey\"" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::TruthyMatcher.new(false) - matcher.negated_message(partial).should contain("falsey") - end end end diff --git a/src/spectator/matchers/truthy_matcher.cr b/src/spectator/matchers/truthy_matcher.cr index 3975416..81f3449 100644 --- a/src/spectator/matchers/truthy_matcher.cr +++ b/src/spectator/matchers/truthy_matcher.cr @@ -21,28 +21,16 @@ module Spectator::Matchers 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) + private def match?(actual) # Cast value to truthy value and compare. - @truthy == !!partial.actual + @truthy == !!actual end # Determines whether the matcher is satisfied with the partial given to it. # `MatchData` is returned that contains information about the match. - def match(partial) : MatchData - raise NotImplementedError.new("#match") - 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 #{label}" - 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 #{label}" + def match(partial) + actual = partial.actual + MatchData.new(match?(actual), @truthy, actual, partial.label) end # Creates a matcher that checks if a value is less than an expected value. @@ -98,5 +86,39 @@ module Spectator::Matchers def !=(expected : ExpectedType) forall ExpectedType InequalityMatcher.new(expected) end + + # Match data specific to this matcher. + private struct MatchData(ActualType) < MatchData + # Creates the match data. + def initialize(matched, @truthy : Bool, @actual : ActualType, @actual_label : String) + super(matched) + end + + # Information about the match. + def values + { + expected: @truthy ? "Not false or nil" : "false or nil", + actual: @actual, + truthy: !!@actual, + } + end + + # Describes the condition that satisfies the matcher. + # This is informational and displayed to the end-user. + def message + "#{@actual_label} is #{expected_label}" + end + + # Describes the condition that won't satsify the matcher. + # This is informational and displayed to the end-user. + def negated_message + "#{@actual_label} is not #{expected_label}" + end + + # Textual representation of what the matcher expects. + private def expected_label + @truthy ? "truthy" : "falsey" + end + end end end