mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge ReceiveArgumentsMatcher and ReceiveMatcher
Finally found the issue causing other matchers derived from StandardMatcher to be "leaked" doubles and mocks indirectly. The if-condition in ExpectationPartial#to and #to_not caused the matcher to be given the StandardMatcher type instead of a union type. This lead to really strange compilation errors and wasted a lot of hours.
This commit is contained in:
parent
f0bfd8b6d4
commit
d9d30c57d0
3 changed files with 15 additions and 125 deletions
|
@ -27,11 +27,7 @@ module Spectator::Expectations
|
||||||
def to(stub : Mocks::MethodStub) : Nil
|
def to(stub : Mocks::MethodStub) : Nil
|
||||||
Harness.current.mocks.expect(@actual.value, stub.name)
|
Harness.current.mocks.expect(@actual.value, stub.name)
|
||||||
value = TestValue.new(stub.name, stub.to_s)
|
value = TestValue.new(stub.name, stub.to_s)
|
||||||
matcher = if (arguments = stub.arguments?)
|
matcher = Matchers::ReceiveMatcher.new(value, stub.arguments?)
|
||||||
Matchers::ReceiveArgumentsMatcher.new(value, arguments)
|
|
||||||
else
|
|
||||||
Matchers::ReceiveMatcher.new(value)
|
|
||||||
end
|
|
||||||
to_eventually(matcher)
|
to_eventually(matcher)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,11 +40,7 @@ module Spectator::Expectations
|
||||||
|
|
||||||
def to_not(stub : Mocks::MethodStub) : Nil
|
def to_not(stub : Mocks::MethodStub) : Nil
|
||||||
value = TestValue.new(stub.name, stub.to_s)
|
value = TestValue.new(stub.name, stub.to_s)
|
||||||
matcher = if (arguments = stub.arguments?)
|
matcher = Matchers::ReceiveMatcher.new(value, stub.arguments?)
|
||||||
Matchers::ReceiveArgumentsMatcher.new(value, arguments)
|
|
||||||
else
|
|
||||||
Matchers::ReceiveMatcher.new(value)
|
|
||||||
end
|
|
||||||
to_never(matcher)
|
to_never(matcher)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
require "../mocks"
|
|
||||||
require "./standard_matcher"
|
|
||||||
|
|
||||||
module Spectator::Matchers
|
|
||||||
struct ReceiveArgumentsMatcher < StandardMatcher
|
|
||||||
alias Range = ::Range(Int32, Int32) | ::Range(Nil, Int32) | ::Range(Int32, Nil)
|
|
||||||
|
|
||||||
def initialize(@expected : TestExpression(Symbol), @args : Mocks::Arguments, @range : Range? = nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
def description : String
|
|
||||||
range = @range
|
|
||||||
"received message #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def match?(actual : TestExpression(T)) : Bool forall T
|
|
||||||
calls = Harness.current.mocks.calls_for(actual.value, @expected.value).select { |call| @args === call.args }
|
|
||||||
if (range = @range)
|
|
||||||
range.includes?(calls.size)
|
|
||||||
else
|
|
||||||
!calls.empty?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def failure_message(actual : TestExpression(T)) : String forall T
|
|
||||||
range = @range
|
|
||||||
"#{actual.label} did not receive #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def values(actual : TestExpression(T)) forall T
|
|
||||||
calls = Harness.current.mocks.calls_for(actual.value, @expected.value).select { |call| @args === call.args }
|
|
||||||
range = @range
|
|
||||||
{
|
|
||||||
expected: "#{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args}",
|
|
||||||
received: "#{calls.size} time(s)",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def once
|
|
||||||
ReceiveArgumentsMatcher.new(@expected, @args, (1..1))
|
|
||||||
end
|
|
||||||
|
|
||||||
def twice
|
|
||||||
ReceiveArgumentsMatcher.new(@expected, @args, (2..2))
|
|
||||||
end
|
|
||||||
|
|
||||||
def exactly(count)
|
|
||||||
Count.new(@expected, (count..count))
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_least(count)
|
|
||||||
Count.new(@expected, (count..))
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_most(count)
|
|
||||||
Count.new(@expected, (..count))
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_least_once
|
|
||||||
at_least(1).times
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_least_twice
|
|
||||||
at_least(2).times
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_most_once
|
|
||||||
at_most(1).times
|
|
||||||
end
|
|
||||||
|
|
||||||
def at_most_twice
|
|
||||||
at_most(2).times
|
|
||||||
end
|
|
||||||
|
|
||||||
def humanize_range(range : Range)
|
|
||||||
if (min = range.begin)
|
|
||||||
if (max = range.end)
|
|
||||||
if min == max
|
|
||||||
min
|
|
||||||
else
|
|
||||||
"#{min} to #{max}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
"At least #{min}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (max = range.end)
|
|
||||||
"At most #{max}"
|
|
||||||
else
|
|
||||||
raise "Unexpected endless range"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private struct Count
|
|
||||||
def initialize(@expected : TestExpression(Symbol), @args : Mocks::Arguments, @range : Range)
|
|
||||||
end
|
|
||||||
|
|
||||||
def times
|
|
||||||
ReceiveArgumentsMatcher.new(@expected, @args, @range)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +1,21 @@
|
||||||
require "../mocks/double"
|
require "../mocks"
|
||||||
require "./standard_matcher"
|
require "./standard_matcher"
|
||||||
|
|
||||||
module Spectator::Matchers
|
module Spectator::Matchers
|
||||||
struct ReceiveMatcher < StandardMatcher
|
struct ReceiveMatcher < StandardMatcher
|
||||||
alias Range = ::Range(Int32, Int32) | ::Range(Nil, Int32) | ::Range(Int32, Nil)
|
alias Range = ::Range(Int32, Int32) | ::Range(Nil, Int32) | ::Range(Int32, Nil)
|
||||||
|
|
||||||
def initialize(@expected : TestExpression(Symbol), @range : Range? = nil)
|
def initialize(@expected : TestExpression(Symbol), @args : Mocks::Arguments? = nil, @range : Range? = nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def description : String
|
def description : String
|
||||||
range = @range
|
range = @range
|
||||||
"received message #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with any arguments"
|
"received message #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def match?(actual : TestExpression(T)) : Bool forall T
|
def match?(actual : TestExpression(T)) : Bool forall T
|
||||||
calls = Harness.current.mocks.calls_for(actual.value, @expected.value)
|
calls = Harness.current.mocks.calls_for(actual.value, @expected.value)
|
||||||
|
calls.select! { |call| @args === call.args } if @args
|
||||||
if (range = @range)
|
if (range = @range)
|
||||||
range.includes?(calls.size)
|
range.includes?(calls.size)
|
||||||
else
|
else
|
||||||
|
@ -24,29 +25,30 @@ module Spectator::Matchers
|
||||||
|
|
||||||
def failure_message(actual : TestExpression(T)) : String forall T
|
def failure_message(actual : TestExpression(T)) : String forall T
|
||||||
range = @range
|
range = @range
|
||||||
"#{actual.label} did not receive #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"}"
|
"#{actual.label} did not receive #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args || "any arguments"}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def values(actual : TestExpression(T)) forall T
|
def values(actual : TestExpression(T)) forall T
|
||||||
calls = Harness.current.mocks.calls_for(actual.value, @expected.value)
|
calls = Harness.current.mocks.calls_for(actual.value, @expected.value)
|
||||||
|
calls.select! { |call| @args === call.args } if @args
|
||||||
range = @range
|
range = @range
|
||||||
{
|
{
|
||||||
expected: "#{range ? "#{humanize_range(range)} time(s)" : "At least once"} with any arguments",
|
expected: "#{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}",
|
||||||
received: "#{calls.size} time(s) with any arguments",
|
received: "#{calls.size} time(s)",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def with(*args, **opts)
|
def with(*args, **opts)
|
||||||
args = Mocks::GenericArguments.new(args, opts)
|
args = Mocks::GenericArguments.new(args, opts)
|
||||||
ReceiveArgumentsMatcher.new(@expected, args, @range)
|
ReceiveMatcher.new(@expected, args, @range)
|
||||||
end
|
end
|
||||||
|
|
||||||
def once
|
def once
|
||||||
ReceiveMatcher.new(@expected, (1..1))
|
ReceiveMatcher.new(@expected, @args, (1..1))
|
||||||
end
|
end
|
||||||
|
|
||||||
def twice
|
def twice
|
||||||
ReceiveMatcher.new(@expected, (2..2))
|
ReceiveMatcher.new(@expected, @args, (2..2))
|
||||||
end
|
end
|
||||||
|
|
||||||
def exactly(count)
|
def exactly(count)
|
||||||
|
@ -98,11 +100,11 @@ module Spectator::Matchers
|
||||||
end
|
end
|
||||||
|
|
||||||
private struct Count
|
private struct Count
|
||||||
def initialize(@expected : TestExpression(Symbol), @range : Range)
|
def initialize(@expected : TestExpression(Symbol), @args : Mocks::Arguments?, @range : Range)
|
||||||
end
|
end
|
||||||
|
|
||||||
def times
|
def times
|
||||||
ReceiveMatcher.new(@expected, @range)
|
ReceiveMatcher.new(@expected, @args, @range)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue