Update RegexMatcher to use MatchData

This commit is contained in:
Michael Miller 2019-03-06 13:10:16 -07:00
parent f29aba42d2
commit fbee1d9461
2 changed files with 151 additions and 97 deletions

View file

@ -1,108 +1,146 @@
require "../spec_helper" require "../spec_helper"
describe Spectator::Matchers::RegexMatcher do describe Spectator::Matchers::RegexMatcher do
describe "#match?" do describe "#match" do
it "compares using #=~" do it "compares using #=~" do
spy = SpySUT.new spy = SpySUT.new
partial = new_partial(spy) partial = new_partial(spy)
matcher = Spectator::Matchers::RegexMatcher.new(/foobar/) matcher = Spectator::Matchers::RegexMatcher.new(/foobar/)
matcher.match?(partial).should be_true matcher.match(partial)
spy.match_call_count.should be > 0 spy.match_call_count.should be > 0
end end
context "with a matching pattern" do context "returned MatchData" do
it "is true" do describe "#matched?" do
value = "foobar" context "with a matching pattern" do
pattern = /foo/ it "is true" do
partial = new_partial(value) value = "foobar"
matcher = Spectator::Matchers::RegexMatcher.new(pattern) pattern = /foo/
matcher.match?(partial).should be_true partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern)
match_data = matcher.match(partial)
match_data.matched?.should be_true
end
end
context "with a non-matching pattern" do
it "is false" do
value = "foo"
pattern = /bar/
partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern)
match_data = matcher.match(partial)
match_data.matched?.should be_false
end
end
end end
end
context "with a non-matching pattern" do describe "#values" do
it "is false" do context "expected" do
value = "foo" it "is the expected value" do
pattern = /bar/ value = "foo"
partial = new_partial(value) pattern = /bar/
matcher = Spectator::Matchers::RegexMatcher.new(pattern) partial = new_partial(value)
matcher.match?(partial).should be_false matcher = Spectator::Matchers::RegexMatcher.new(pattern)
match_data = matcher.match(partial)
match_data.values[:expected].should eq(pattern)
end
end
context "actual" do
it "is the actual value" do
value = "foo"
pattern = /bar/
partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern)
match_data = matcher.match(partial)
match_data.values[:actual].should eq(value)
end
end
end end
end
end
describe "#message" do describe "#message" do
it "mentions =~" do it "mentions =~" do
value = "foobar" value = "foobar"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.message(partial).should contain("=~") match_data = matcher.match(partial)
end match_data.message.should contain("=~")
end
it "contains the actual label" do it "contains the actual label" do
value = "foobar" value = "foobar"
label = "different" label = "different"
pattern = /foo/ pattern = /foo/
partial = new_partial(value, label) partial = new_partial(value, label)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.message(partial).should contain(label) match_data = matcher.match(partial)
end match_data.message.should contain(label)
end
it "contains the expected label" do it "contains the expected label" do
value = "foobar" value = "foobar"
label = "different" label = "different"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern, label) matcher = Spectator::Matchers::RegexMatcher.new(pattern, label)
matcher.message(partial).should contain(label) match_data = matcher.match(partial)
end match_data.message.should contain(label)
end
context "when expected label is omitted" do context "when expected label is omitted" do
it "contains stringified form of expected value" do it "contains stringified form of expected value" do
value = "foobar" value = "foobar"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.message(partial).should contain(pattern.to_s) match_data = matcher.match(partial)
match_data.message.should contain(pattern.to_s)
end
end
end end
end
end
describe "#negated_message" do describe "#negated_message" do
it "mentions =~" do it "mentions =~" do
value = "foobar" value = "foobar"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.negated_message(partial).should contain("=~") match_data = matcher.match(partial)
end match_data.negated_message.should contain("=~")
end
it "contains the actual label" do it "contains the actual label" do
value = "foobar" value = "foobar"
label = "different" label = "different"
pattern = /foo/ pattern = /foo/
partial = new_partial(value, label) partial = new_partial(value, label)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.negated_message(partial).should contain(label) match_data = matcher.match(partial)
end match_data.negated_message.should contain(label)
end
it "contains the expected label" do it "contains the expected label" do
value = "foobar" value = "foobar"
label = "different" label = "different"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern, label) matcher = Spectator::Matchers::RegexMatcher.new(pattern, label)
matcher.negated_message(partial).should contain(label) match_data = matcher.match(partial)
end match_data.negated_message.should contain(label)
end
context "when expected label is omitted" do context "when expected label is omitted" do
it "contains stringified form of expected value" do it "contains stringified form of expected value" do
value = "foobar" value = "foobar"
pattern = /foo/ pattern = /foo/
partial = new_partial(value) partial = new_partial(value)
matcher = Spectator::Matchers::RegexMatcher.new(pattern) matcher = Spectator::Matchers::RegexMatcher.new(pattern)
matcher.negated_message(partial).should contain(pattern.to_s) match_data = matcher.match(partial)
match_data.negated_message.should contain(pattern.to_s)
end
end
end end
end end
end end

View file

@ -5,27 +5,43 @@ module Spectator::Matchers
# The value is compared with the =~ operator. # The value is compared with the =~ operator.
struct RegexMatcher(ExpectedType) < ValueMatcher(ExpectedType) struct RegexMatcher(ExpectedType) < ValueMatcher(ExpectedType)
# Determines whether the matcher is satisfied with the value given to it. # Determines whether the matcher is satisfied with the value given to it.
# True is returned if the match was successful, false otherwise. private def match?(actual)
def match?(partial) !!(actual =~ expected)
!!(partial.actual =~ expected)
end end
# Determines whether the matcher is satisfied with the partial given to it. # Determines whether the matcher is satisfied with the partial given to it.
# `MatchData` is returned that contains information about the match. # `MatchData` is returned that contains information about the match.
def match(partial) : MatchData def match(partial)
raise NotImplementedError.new("#match") values = ExpectedActual.new(partial, self)
MatchData.new(match?(values.actual), values)
end end
# Describes the condition that satisfies the matcher. # Match data specific to this matcher.
# This is informational and displayed to the end-user. private struct MatchData(ExpectedType, ActualType) < MatchData
def message(partial) # Creates the match data.
"Expected #{partial.label} to match #{label} (using =~)" def initialize(matched, @values : ExpectedActual(ExpectedType, ActualType))
end super(matched)
end
# Describes the condition that won't satsify the matcher. # Information about the match.
# This is informational and displayed to the end-user. def values
def negated_message(partial) {
"Expected #{partial.label} to not match #{label} (using =~)" expected: @values.expected,
actual: @values.actual,
}
end
# Describes the condition that satisfies the matcher.
# This is informational and displayed to the end-user.
def message
"#{@values.actual_label} matches #{@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} does not match #{@values.expected_label} (using =~)"
end
end end
end end
end end