Merge master into release/0.10

This commit is contained in:
Michael Miller 2021-07-05 11:32:45 -06:00
parent 8d32984eba
commit 6a01ab3531
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD
8 changed files with 111 additions and 19 deletions

View file

@ -301,7 +301,8 @@ This has been changed so that it compiles and raises an error at runtime with a
First version ready for public use.
[Unreleased]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.38...release%2F0.10
[Unreleased]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.39...release%2F0.10
[0.9.39]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.38...v0.9.39
[0.9.38]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.37...v0.9.38
[0.9.37]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.36...v0.9.37
[0.9.36]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.35...v0.9.36

View file

@ -0,0 +1,19 @@
require "../spec_helper"
Spectator.describe "GitHub Issue #28" do
class Test
def foo
42
end
end
mock Test do
stub foo
end
it "matches method stubs with no_args" do
test = Test.new
expect(test).to receive(:foo).with(no_args).and_return(42)
test.foo
end
end

View file

@ -0,0 +1,20 @@
require "../spec_helper"
Spectator.describe "GitHub Issue #29" do
class SomeClass
def goodbye
exit 0
end
end
mock SomeClass do
stub exit(code)
end
describe SomeClass do
it "captures exit" do
expect(subject).to receive(:exit).with(0)
subject.goodbye
end
end
end

View file

@ -0,0 +1,9 @@
require "../spec_helper"
Spectator.describe "GitHub Issue #30" do
let(dbl) { double(:foo) }
it "supports block-less symbol doubles" do
expect(dbl).to_not be_nil
end
end

View file

@ -11,22 +11,26 @@ module Spectator::DSL
type_name = "Double#{safe_name}".id
%}
{% if block.is_a?(Nop) %}
create_double({{type_name}}, {{name}}, {{stubs.double_splat}})
{% else %}
{% if block %}
define_double({{type_name}}, {{name}}, {{stubs.double_splat}}) {{block}}
{% else %}
create_double({{type_name}}, {{name}}, {{stubs.double_splat}})
{% end %}
{% end %}
end
macro create_double(type_name, name, **stubs)
{% type_name.resolve? || raise("Could not find a double labeled #{name}") %}
{{type_name}}.new.tap do |%double|
{% for name, value in stubs %}
allow(%double).to receive({{name.id}}).and_return({{value}})
{% end %}
end
{% if type_name.resolve? %}
{{type_name}}.new.tap do |%double|
{% for name, value in stubs %}
allow(%double).to receive({{name.id}}).and_return({{value}})
{% end %}
end
{% elsif @def %}
anonymous_double({{name ? name.stringify : "Anonymous"}}, {{stubs.double_splat}})
{% else %}
{% raise "Block required for double definition" %}
{% end %}
end
macro define_double(type_name, name, **stubs, &block)
@ -156,10 +160,10 @@ module Spectator::DSL
macro receive(method_name, _source_file = __FILE__, _source_line = __LINE__, &block)
%location = ::Spectator::Location.new({{_source_file}}, {{_source_line}})
{% if block.is_a?(Nop) %}
::Spectator::Mocks::NilMethodStub.new({{method_name.id.symbolize}}, %location)
{% else %}
{% if block %}
::Spectator::Mocks::ProcMethodStub.create({{method_name.id.symbolize}}, %location) { {{block.body}} }
{% else %}
::Spectator::Mocks::NilMethodStub.new({{method_name.id.symbolize}}, %location)
{% end %}
end
@ -171,5 +175,9 @@ module Spectator::DSL
{% end %}
%stubs
end
def no_args
::Spectator::Mocks::NoArguments.new
end
end
end

View file

@ -0,0 +1,21 @@
require "./arguments"
module Spectator::Mocks
class NoArguments < Arguments
def args
Tuple.new
end
def opts
NamedTuple.new
end
def ===(other : Arguments) : Bool
other.args.empty? && other.opts.empty?
end
def ===(other) : Bool
false
end
end
end

View file

@ -54,11 +54,15 @@ module Spectator::Mocks
end
def expect(object, stub : MethodStub) : Nil
fetch_instance(object).expected.add(stub)
entry = fetch_instance(object)
entry.expected.add(stub)
entry.stubs.unshift(stub)
end
def expect(type : T.class, stub : MethodStub) : Nil forall T
fetch_type(type).expected.add(stub)
entry = fetch_type(type)
entry.expected.add(stub)
entry.stubs.unshift(stub)
end
private def fetch_instance(object)

View file

@ -59,8 +59,10 @@ module Spectator::Mocks
original = if (name == :new.id && receiver == "self.".id) ||
(t.superclass && t.superclass.has_method?(name) && !t.overrides?(t.superclass, name))
:super
else
elsif t.has_method?(name)
:previous_def
else
"::#{name}"
end.id
%}
@ -80,7 +82,11 @@ module Spectator::Mocks
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
%harness.mocks.record_call(self, %call)
if (%stub = %harness.mocks.find_stub(self, %call))
return %stub.call!(%args) { {{original}} }
if typeof({{original}}) == NoReturn
return %stub.call!(%args) { nil }
else
return %stub.call!(%args) { {{original}} }
end
end
{% if body && !body.is_a?(Nop) || return_type.is_a?(ArrayLiteral) %}
@ -99,7 +105,11 @@ module Spectator::Mocks
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
%harness.mocks.record_call(self, %call)
if (%stub = %harness.mocks.find_stub(self, %call))
return %stub.call!(%args) { {{original}} { |*%ya| yield *%ya } }
if typeof({{original}}) == NoReturn
return %stub.call!(%args) { nil }
else
return %stub.call!(%args) { {{original}} { |*%ya| yield *%ya } }
end
end
{% if body && !body.is_a?(Nop) || return_type.is_a?(ArrayLiteral) %}