Add negation wrappers

Fixes the reported expected values when the expectation is negated.
This commit is contained in:
Michael Miller 2019-03-06 21:39:28 -07:00
parent a9d1f1aabc
commit ee7a91c3dd
24 changed files with 118 additions and 23 deletions

View file

@ -21,7 +21,13 @@ module Spectator::Expectations
# Information about the match.
# Returned value and type will something that has key-value pairs (like a `NamedTuple`).
def values
@match_data.values
@match_data.values.tap do |values|
if @negated
values.each_value do |value|
value.negate if value.responds_to?(:negate)
end
end
end
end
# Text that indicates the condition that must be met for the expectation to be satisifed.

View file

@ -0,0 +1,28 @@
module Spectator::Matchers
# Selects a value based on whether the value is negated.
# This is used when a matcher is negated.
private class AlternativeValue(T1, T2)
# Negatable value.
getter value
# Creates the wrapper.
def initialize(@value1 : T1, @value2 : T2)
@negated = false
end
# Negates (toggles) the value.
def negate
@negated = !@negated
end
# Produces a stringified value.
def to_s(io)
io << @negated ? @value1 : @value2
end
# Produces a stringified value with additional information.
def inspect(io)
(@negated ? @value1 : @value2).inspect(io)
end
end
end

View file

@ -49,7 +49,7 @@ module Spectator::Matchers
{% begin %}
{
{% for attribute in ExpectedType.keys %}
{{"expected " + attribute.stringify}}: @values.expected[{{attribute.symbolize}}],
{{"expected " + attribute.stringify}}: NegatableValue.new(@values.expected[{{attribute.symbolize}}]),
{{"actual " + attribute.stringify}}: @values.actual[{{attribute.symbolize}}],
{% end %}
}

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: @values.expected,
expected: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -28,7 +28,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
subset: @values.expected,
subset: NegatableValue.new(@values.expected),
superset: @values.actual,
}
end

View file

@ -27,7 +27,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: [] of Nil,
expected: NegatableValue.new([] of Nil),
actual: @actual,
}
end

View file

@ -39,7 +39,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: @values.expected,
expected: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: @values.expected,
expected: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: PrefixedValue.new(">=", @values.expected),
expected: NegatablePrefixedValue.new(">=", "<", @values.expected),
actual: PrefixedValue.new(actual_operator, @values.actual),
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: PrefixedValue.new(">", @values.expected),
expected: NegatablePrefixedValue.new(">", "<=", @values.expected),
actual: PrefixedValue.new(actual_operator, @values.actual),
}
end

View file

@ -27,7 +27,7 @@ module Spectator::Matchers
def values
actual = @values.actual
{
key: @values.expected,
key: NegatableValue.new(@values.expected),
actual: actual.responds_to?(:keys) ? actual.keys : actual,
}
end

View file

@ -51,7 +51,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
subset: @values.expected,
subset: NegatableValue.new(@values.expected),
superset: @values.actual,
}
end

View file

@ -27,7 +27,7 @@ module Spectator::Matchers
def values
actual = @values.actual
{
value: @values.expected,
value: NegatableValue.new(@values.expected),
actual: actual.responds_to?(:values) ? actual.values : actual,
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: PrefixedValue.new("Not", @values.expected),
expected: NegatablePrefixedValue.new("Not", "", @values.expected),
actual: @values.actual,
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: PrefixedValue.new("<=", @values.expected),
expected: NegatablePrefixedValue.new("<=", ">", @values.expected),
actual: PrefixedValue.new(actual_operator, @values.actual),
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: PrefixedValue.new("<", @values.expected),
expected: NegatablePrefixedValue.new("<", ">=", @values.expected),
actual: PrefixedValue.new(actual_operator, @values.actual),
}
end

View file

@ -0,0 +1,27 @@
module Spectator::Matchers
# Wraps a prefixed value that can be negated.
# This is used when a matcher is negated.
private class NegatablePrefixedValue(T)
# Creates the wrapper.
def initialize(@positive_prefix : String, @negative_prefix : String, @value : T)
@negated = false
end
# Negates (toggles) the value.
def negate
@negated = !@negated
end
# Produces a stringified value.
def to_s(io)
io << @negated ? @negative_prefix : @positive_prefix
io << @value
end
# Produces a stringified value with additional information.
def inspect(io)
io << @negated ? @negative_prefix : @positive_prefix
@value.inspect(io)
end
end
end

View file

@ -0,0 +1,32 @@
module Spectator::Matchers
# Wraps an expected value that can be negated.
# This is used when a matcher is negated.
private class NegatableValue(T)
# Negatable value.
getter value
# Creates the wrapper.
def initialize(@value : T)
@negated = false
end
# Negates (toggles) the value.
def negate
@negated = !@negated
end
# Produces a stringified value.
# The string will be prefixed with "Not" when negated.
def to_s(io)
io << "Not " if @negated
io << @value
end
# Produces a stringified value with additional information.
# The string will be prefixed with "Not" when negated.
def inspect(io)
io << "Not " if @negated
@value.inspect(io)
end
end
end

View file

@ -27,7 +27,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: nil,
expected: NegatableValue.new(nil),
actual: @actual,
}
end

View file

@ -67,8 +67,8 @@ module Spectator::Matchers
# Information about the match.
def values
{
lower: PrefixedValue.new(">=", range.begin),
upper: PrefixedValue.new(exclusive? ? "<" : "<=", range.end),
lower: NegatablePrefixedValue.new(">=", "<", range.begin),
upper: NegatablePrefixedValue.new(exclusive? ? "<" : "<=", exclusive? ? ">=" : ">", range.end),
actual: @values.actual,
}
end
@ -112,7 +112,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
set: @values.expected,
set: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -26,7 +26,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: @values.expected,
expected: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -39,7 +39,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: @values.expected,
expected: NegatableValue.new(@values.expected),
actual: @values.actual,
}
end

View file

@ -96,8 +96,10 @@ module Spectator::Matchers
# Information about the match.
def values
truthy = "Not false or nil"
falsey = "false or nil"
{
expected: @truthy ? "Not false or nil" : "false or nil",
expected: AlternativeValue.new(@truthy ? truthy : falsey, @truthy ? falsey : truthy),
actual: @actual,
truthy: !!@actual,
}

View file

@ -32,7 +32,7 @@ module Spectator::Matchers
# Information about the match.
def values
{
expected: ExpectedType,
expected: NegatableValue.new(ExpectedType),
actual: ActualType,
}
end