diff --git a/spec/matchers/greater_than_equal_matcher_spec.cr b/spec/matchers/greater_than_equal_matcher_spec.cr index 64e003d..866cad8 100644 --- a/spec/matchers/greater_than_equal_matcher_spec.cr +++ b/spec/matchers/greater_than_equal_matcher_spec.cr @@ -1,111 +1,183 @@ require "../spec_helper" describe Spectator::Matchers::GreaterThanEqualMatcher do - describe "#match?" do + describe "#match" do it "compares using #>=" do spy = SpySUT.new partial = new_partial(spy) matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(42) - matcher.match?(partial).should be_true + matcher.match(partial) spy.ge_call_count.should be > 0 end - context "with a larger value" do - it "is false" do - actual = 42 - expected = 777 - partial = new_partial(actual) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) - matcher.match?(partial).should be_false + context "returned MatchData" do + describe "#matched?" do + context "with a larger value" do + it "is false" do + actual = 42 + expected = 777 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.matched?.should be_false + end + end + + context "with a smaller value" do + it "is true" do + actual = 777 + expected = 42 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.matched?.should be_true + end + end + + context "with an equal value" do + it "is true" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) + match_data = matcher.match(partial) + match_data.matched?.should be_true + end + end end - end - context "with a smaller value" do - it "is true" do - actual = 777 - expected = 42 - partial = new_partial(actual) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) - matcher.match?(partial).should be_true + describe "#values" do + context "expected" do + it "is the expected value" do + actual = 777 + expected = 42 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.values[:expected].value.should eq(expected) + end + + it "is prefixed with >=" do + actual = 777 + expected = 42 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.values[:expected].to_s.should start_with(">=") + end + end + + context "actual" do + it "is the actual value" do + actual = 777 + expected = 42 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.values[:actual].value.should eq(actual) + end + + context "when #matched? is true" do + it "is prefixed with >=" do + actual = 777 + expected = 42 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.matched?.should be_true # Sanity check. + match_data.values[:actual].to_s.should start_with(">=") + end + end + + context "when #matched? is false" do + it "is prefixed with <" do + actual = 42 + expected = 777 + partial = new_partial(actual) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(expected) + match_data = matcher.match(partial) + match_data.matched?.should be_false # Sanity check. + match_data.values[:actual].to_s.should start_with("<") + end + end + end end - end - context "with an equal value" do - it "is true" do - value = 42 - partial = new_partial(value) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) - matcher.match?(partial).should be_true + describe "#message" do + it "mentions >=" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) + match_data = matcher.match(partial) + match_data.message.should contain(">=") + end + + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) + match_data = matcher.match(partial) + match_data.message.should contain(label) + end + + it "contains the expected label" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value, label) + match_data = matcher.match(partial) + match_data.message.should contain(label) + end + + context "when expected label is omitted" do + it "contains stringified form of expected value" do + value1 = 42 + value2 = 777 + partial = new_partial(value1) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value2) + match_data = matcher.match(partial) + match_data.message.should contain(value2.to_s) + end + end end - end - end - describe "#message" do - it "mentions >=" do - value = 42 - partial = new_partial(value) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) - matcher.message(partial).should contain(">=") - end + describe "#negated_message" do + it "mentions >=" do + value = 42 + partial = new_partial(value) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) + match_data = matcher.match(partial) + match_data.negated_message.should contain(">=") + end - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) - matcher.message(partial).should contain(label) - end + it "contains the actual label" do + value = 42 + label = "everything" + partial = new_partial(value, label) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) + match_data = matcher.match(partial) + match_data.negated_message.should contain(label) + end - it "contains the expected label" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value, label) - matcher.message(partial).should contain(label) - end + it "contains the expected label" do + value = 42 + label = "everything" + partial = new_partial(value) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value, label) + match_data = matcher.match(partial) + match_data.negated_message.should contain(label) + end - context "when expected label is omitted" do - it "contains stringified form of expected value" do - value1 = 42 - value2 = 777 - partial = new_partial(value1) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value2) - matcher.message(partial).should contain(value2.to_s) - end - end - end - - describe "#negated_message" do - it "mentions >=" do - value = 42 - partial = new_partial(value) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) - matcher.negated_message(partial).should contain(">=") - end - - it "contains the actual label" do - value = 42 - label = "everything" - partial = new_partial(value, label) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value) - matcher.negated_message(partial).should contain(label) - end - - it "contains the expected label" do - value = 42 - label = "everything" - partial = new_partial(value) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value, label) - matcher.negated_message(partial).should contain(label) - end - - context "when expected label is omitted" do - it "contains stringified form of expected value" do - value1 = 42 - value2 = 777 - partial = new_partial(value1) - matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value2) - matcher.negated_message(partial).should contain(value2.to_s) + context "when expected label is omitted" do + it "contains stringified form of expected value" do + value1 = 42 + value2 = 777 + partial = new_partial(value1) + matcher = Spectator::Matchers::GreaterThanEqualMatcher.new(value2) + match_data = matcher.match(partial) + match_data.negated_message.should contain(value2.to_s) + end + end end end end diff --git a/src/spectator/matchers/greater_than_equal_matcher.cr b/src/spectator/matchers/greater_than_equal_matcher.cr index 4282d6c..2983dd3 100644 --- a/src/spectator/matchers/greater_than_equal_matcher.cr +++ b/src/spectator/matchers/greater_than_equal_matcher.cr @@ -5,27 +5,48 @@ module Spectator::Matchers # The values are compared with the >= operator. struct GreaterThanEqualMatcher(ExpectedType) < ValueMatcher(ExpectedType) # 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 >= expected + private def match?(actual) + actual >= expected 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") + def match(partial) + values = ExpectedActual.new(partial, self) + MatchData.new(match?(values.actual), values) 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 greater than or equal to #{label} (using >=)" - end + # Match data specific to this matcher. + private struct MatchData(ExpectedType, ActualType) < MatchData + # Creates the match data. + def initialize(matched, @values : ExpectedActual(ExpectedType, ActualType)) + 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 greater than or equal to #{label} (using >=)" + # Information about the match. + def values + { + expected: PrefixedValue.new(">=", @values.expected), + actual: PrefixedValue.new(actual_operator, @values.actual), + } + end + + # Textual operator for the actual value. + private def actual_operator + matched? ? ">=" : "<" + end + + # Describes the condition that satisfies the matcher. + # This is informational and displayed to the end-user. + def message + "#{@values.actual_label} is greater than or equal to #{@values.expected_label} (using >=)" + end + + # Describes the condition that won't satsify the matcher. + # This is informational and displayed to the end-user. + def negated_message + "#{@values.actual_label} is less than #{@values.expected_label} (using >=)" + end end end end diff --git a/src/spectator/matchers/prefixed_value.cr b/src/spectator/matchers/prefixed_value.cr new file mode 100644 index 0000000..ffeddfc --- /dev/null +++ b/src/spectator/matchers/prefixed_value.cr @@ -0,0 +1,18 @@ +module Spectator::Matchers + # Prefixes (for output formatting) an actual or expected value. + private struct PrefixedValue(T) + # Value being prefixed. + getter value : T + + # Creates the prefixed value. + def initialize(@prefix : String, @value : T) + end + + # Outputs the formatted value with a prefix. + def to_s(io) + io << @prefix + io << ' ' + io << @value + end + end +end