From e14e86a5f398ee7a32d1e407950513f4ed89caa3 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Tue, 5 Feb 2019 19:37:25 -0700 Subject: [PATCH] Add `have_value` matcher --- src/spectator/dsl/matcher_dsl.cr | 17 +++++++++++++ src/spectator/matchers/have_value_matcher.cr | 25 ++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/spectator/matchers/have_value_matcher.cr diff --git a/src/spectator/dsl/matcher_dsl.cr b/src/spectator/dsl/matcher_dsl.cr index 854668a..999bcf4 100644 --- a/src/spectator/dsl/matcher_dsl.cr +++ b/src/spectator/dsl/matcher_dsl.cr @@ -412,6 +412,23 @@ module Spectator::DSL have_key({{expected}}) end + # Indicates that some set, such as a `Hash`, has a given value. + # The `has_value?` method is used for this check. + # + # Examples: + # ``` + # expect({foo: "bar"}).to have_value("bar") + # expect({"lucky" => 7}).to have_value(7) + # ``` + macro have_value(expected) + ::Spectator::Matchers::HaveValueMatcher.new({{expected.stringify}}, {{expected}}) + end + + # ditto + macro has_value(expected) + have_value({{expected}}) + end + # Indicates that some value should have a set of attributes matching some conditions. # A list of named arguments are expected. # The names correspond to the attributes in the instance to check. diff --git a/src/spectator/matchers/have_value_matcher.cr b/src/spectator/matchers/have_value_matcher.cr new file mode 100644 index 0000000..87848a6 --- /dev/null +++ b/src/spectator/matchers/have_value_matcher.cr @@ -0,0 +1,25 @@ +require "./value_matcher" + +module Spectator::Matchers + # Matcher that tests whether a `Hash` (or similar type) has a given value. + # The set is checked with the `has_value?` method. + struct HaveValueMatcher(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.has_value?(expected) + end + + # Describes the condition that satisfies the matcher. + # This is informational and displayed to the end-user. + def message(partial) + "Expected #{partial.label} to have value #{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 have value #{label}" + end + end +end