diff --git a/src/spectator/expectation.cr b/src/spectator/expectation.cr index 848630d..cfaa6ae 100644 --- a/src/spectator/expectation.cr +++ b/src/spectator/expectation.cr @@ -106,17 +106,6 @@ module Spectator report(match_data, message) end - def to(stub : Mocks::MethodStub) : Nil - Harness.current.mocks.expect(@expression.value, stub) - value = Value.new(stub.name, stub.to_s) - matcher = Matchers::ReceiveMatcher.new(value, stub.arguments?) - to_eventually(matcher) - end - - def to(stubs : Enumerable(Mocks::MethodStub)) : Nil - stubs.each { |stub| to(stub) } - end - # Asserts that some criteria defined by the matcher is not satisfied. # This is effectively the opposite of `#to`. # Allows a custom message to be used. @@ -131,24 +120,6 @@ module Spectator to_not(matcher, message) end - def to_not(stub : Mocks::MethodStub) : Nil - value = Value.new(stub.name, stub.to_s) - matcher = Matchers::ReceiveMatcher.new(value, stub.arguments?) - to_never(matcher) - end - - def not_to(stub : Mocks::MethodStub) : Nil - to_not(stub) - end - - def to_not(stubs : Enumerable(Mocks::MethodStub)) : Nil - stubs.each { |stub| to_not(stub) } - end - - def not_to(stubs : Enumerable(Mocks::MethodStub)) : Nil - to_not(stubs) - end - # Asserts that some criteria defined by the matcher is eventually satisfied. # The expectation is checked after the example finishes and all hooks have run. # Allows a custom message to be used. @@ -156,14 +127,6 @@ module Spectator Harness.current.defer { to(matcher, message) } end - def to_eventually(stub : Mocks::MethodStub) : Nil - to(stub) - end - - def to_eventually(stubs : Enumerable(Mocks::MethodStub)) : Nil - to(stub) - end - # Asserts that some criteria defined by the matcher is never satisfied. # The expectation is checked after the example finishes and all hooks have run. # Allows a custom message to be used. @@ -177,14 +140,6 @@ module Spectator to_never(matcher, message) end - def to_never(stub : Mocks::MethodStub) : Nil - to_not(stub) - end - - def to_never(stub : Enumerable(Mocks::MethodStub)) : Nil - to_not(stub) - end - # Reports an expectation to the current harness. private def report(match_data : Matchers::MatchData, message : String? | Proc(String) = nil) expectation = Expectation.new(match_data, @location, message) diff --git a/src/spectator/harness.cr b/src/spectator/harness.cr index 37c27f3..ec21d51 100644 --- a/src/spectator/harness.cr +++ b/src/spectator/harness.cr @@ -3,7 +3,6 @@ require "./example_failed" require "./example_pending" require "./expectation" require "./expectation_failed" -require "./mocks" require "./multiple_expectations_failed" require "./pass_result" require "./result" @@ -39,8 +38,6 @@ module Spectator # Retrieves the harness for the current running example. class_getter! current : self - getter mocks = Mocks::Registry.new - # Wraps an example with a harness and runs test code. # A block provided to this method is considered to be the test code. # The value of `.current` is set to the harness for the duration of the test. @@ -134,7 +131,6 @@ module Spectator elapsed = Time.measure do error = catch { yield } end - error = nil if error.is_a?(SystemExit) && mocks.exit_handled? {elapsed, error} end diff --git a/src/spectator/matchers/receive_matcher.cr b/src/spectator/matchers/receive_matcher.cr deleted file mode 100644 index 7f3d233..0000000 --- a/src/spectator/matchers/receive_matcher.cr +++ /dev/null @@ -1,126 +0,0 @@ -require "../mocks" -require "./standard_matcher" - -module Spectator::Matchers - struct ReceiveMatcher < StandardMatcher - alias Range = ::Range(Int32, Int32) | ::Range(Nil, Int32) | ::Range(Int32, Nil) - - def initialize(@expected : Expression(Symbol), @args : Mocks::Arguments? = nil, @range : Range? = nil) - end - - def description : String - range = @range - "received message #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}" - end - - def match?(actual : Expression(T)) : Bool forall T - calls = Harness.current.mocks.calls_for(actual.value, @expected.value) - calls.select! { |call| @args === call.args } if @args - if (range = @range) - range.includes?(calls.size) - else - !calls.empty? - end - end - - def failure_message(actual : Expression(T)) : String forall T - range = @range - "#{actual.label} did not receive #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args || "any arguments"}" - end - - def failure_message_when_negated(actual) : String - range = @range - "#{actual.label} received #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args || "any arguments"}" - end - - def values(actual : Expression(T)) forall T - calls = Harness.current.mocks.calls_for(actual.value, @expected.value) - calls.select! { |call| @args === call.args } if @args - range = @range - { - expected: "#{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}", - received: "#{calls.size} time(s)", - } - end - - def negated_values(actual : Expression(T)) forall T - calls = Harness.current.mocks.calls_for(actual.value, @expected.value) - calls.select! { |call| @args === call.args } if @args - range = @range - { - expected: "#{range ? "Not #{humanize_range(range)} time(s)" : "Never"} with #{@args || "any arguments"}", - received: "#{calls.size} time(s)", - } - end - - def with(*args, **opts) - args = Mocks::GenericArguments.new(args, opts) - ReceiveMatcher.new(@expected, args, @range) - end - - def once - ReceiveMatcher.new(@expected, @args, (1..1)) - end - - def twice - ReceiveMatcher.new(@expected, @args, (2..2)) - end - - def exactly(count) - Count.new(@expected, @args, (count..count)) - end - - def at_least(count) - Count.new(@expected, @args, (count..)) - end - - def at_most(count) - Count.new(@expected, @args, (..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 : Expression(Symbol), @args : Mocks::Arguments?, @range : Range) - end - - def times - ReceiveMatcher.new(@expected, @args, @range) - end - end - end -end diff --git a/src/spectator/matchers/receive_type_matcher.cr b/src/spectator/matchers/receive_type_matcher.cr deleted file mode 100644 index 362707d..0000000 --- a/src/spectator/matchers/receive_type_matcher.cr +++ /dev/null @@ -1,126 +0,0 @@ -require "../mocks" -require "./standard_matcher" - -module Spectator::Matchers - struct ReceiveTypeMatcher < StandardMatcher - alias Range = ::Range(Int32, Int32) | ::Range(Nil, Int32) | ::Range(Int32, Nil) - - def initialize(@expected : Expression(Symbol), @args : Mocks::Arguments? = nil, @range : Range? = nil) - end - - def description : String - range = @range - "received message #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}" - end - - def match?(actual : Expression(T)) : Bool forall T - calls = Harness.current.mocks.calls_for_type(actual.value, @expected.value) - calls.select! { |call| @args === call.args } if @args - if (range = @range) - range.includes?(calls.size) - else - !calls.empty? - end - end - - def failure_message(actual : Expression(T)) : String forall T - range = @range - "#{actual.label} did not receive #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args || "any arguments"}" - end - - def failure_message_when_negated(actual : Expression(T)) : String forall T - range = @range - "#{actual.label} received #{@expected.label} #{range ? "#{humanize_range(range)} time(s)" : "at least once"} with #{@args || "any arguments"}" - end - - def values(actual : Expression(T)) forall T - calls = Harness.current.mocks.calls_for_type(T, @expected.value) - calls.select! { |call| @args === call.args } if @args - range = @range - { - expected: "#{range ? "#{humanize_range(range)} time(s)" : "At least once"} with #{@args || "any arguments"}", - received: "#{calls.size} time(s)", - } - end - - def negated_values(actual : Expression(T)) forall T - calls = Harness.current.mocks.calls_for_type(T, @expected.value) - calls.select! { |call| @args === call.args } if @args - range = @range - { - expected: "#{range ? "Not #{humanize_range(range)} time(s)" : "Never"} with #{@args || "any arguments"}", - received: "#{calls.size} time(s)", - } - end - - def with(*args, **opts) - args = Mocks::GenericArguments.new(args, opts) - ReceiveTypeMatcher.new(@expected, args, @range) - end - - def once - ReceiveTypeMatcher.new(@expected, @args, (1..1)) - end - - def twice - ReceiveTypeMatcher.new(@expected, @args, (2..2)) - end - - def exactly(count) - Count.new(@expected, @args, (count..count)) - end - - def at_least(count) - Count.new(@expected, @args, (count..)) - end - - def at_most(count) - Count.new(@expected, @args, (..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 : Expression(Symbol), @args : Mocks::Arguments?, @range : Range) - end - - def times - ReceiveTypeMatcher.new(@expected, @args, @range) - end - end - end -end diff --git a/src/spectator/mocks.cr b/src/spectator/mocks.cr index b72ffea..f50bf9e 100644 --- a/src/spectator/mocks.cr +++ b/src/spectator/mocks.cr @@ -1,18 +1,7 @@ require "./mocks/*" -require "./system_exit" module Spectator # Functionality for mocking existing types. module Mocks end end - -# Add default stub to `exit` method. -# This captures *most* (technically not all) attempts to exit the process. -# This stub only takes effect in example code. -# It intercepts `exit` calls and raises `Spectator::SystemExit` to prevent killing the test. -# class ::Process -# include ::Spectator::Mocks::Stubs - -# stub self.exit(code) { raise ::Spectator::SystemExit.new } -# end diff --git a/src/spectator/system_exit.cr b/src/spectator/system_exit.cr deleted file mode 100644 index bdb0aea..0000000 --- a/src/spectator/system_exit.cr +++ /dev/null @@ -1,5 +0,0 @@ -module Spectator - # Exception raised when `exit` is called and intercepted from a stub. - class SystemExit < Exception - end -end