mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Add as_null_object method
This commit is contained in:
parent
5d21e4bb71
commit
99aa8afdce
2 changed files with 156 additions and 4 deletions
143
spec/spectator/dsl/mocks/null_double_spec.cr
Normal file
143
spec/spectator/dsl/mocks/null_double_spec.cr
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
require "../../../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe "Null double DSL" do
|
||||||
|
private macro expect_null_double(double, actual)
|
||||||
|
%actual_box = Box.box({{actual}})
|
||||||
|
%double_box = Box.box({{double}})
|
||||||
|
expect(%actual_box).to eq(%double_box), {{actual.stringify}} + " is not " + {{double.stringify}}
|
||||||
|
end
|
||||||
|
|
||||||
|
context "specifying methods as keyword args" do
|
||||||
|
double(:test, foo: "foobar", bar: 42)
|
||||||
|
subject(dbl) { double(:test).as_null_object }
|
||||||
|
|
||||||
|
it "defines a double with methods" do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(dbl.foo).to eq("foobar")
|
||||||
|
expect(dbl.bar).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "compiles types without unions" do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(dbl.foo).to compile_as(String)
|
||||||
|
expect(dbl.bar).to compile_as(Int32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns self for unexpected messages" do
|
||||||
|
expect_null_double(dbl.baz, dbl)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "block with stubs" do
|
||||||
|
context "one method" do
|
||||||
|
double(:test2) do
|
||||||
|
stub def foo
|
||||||
|
"one method"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { double(:test2).as_null_object }
|
||||||
|
|
||||||
|
it "defines a double with methods" do
|
||||||
|
expect(dbl.foo).to eq("one method")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "compiles types without unions" do
|
||||||
|
expect(dbl.foo).to compile_as(String)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "two methods" do
|
||||||
|
double(:test3) do
|
||||||
|
stub def foo
|
||||||
|
"two methods"
|
||||||
|
end
|
||||||
|
|
||||||
|
stub def bar
|
||||||
|
42
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { double(:test3).as_null_object }
|
||||||
|
|
||||||
|
it "defines a double with methods" do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(dbl.foo).to eq("two methods")
|
||||||
|
expect(dbl.bar).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "compiles types without unions" do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(dbl.foo).to compile_as(String)
|
||||||
|
expect(dbl.bar).to compile_as(Int32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "empty block" do
|
||||||
|
double(:test4) do
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { double(:test4).as_null_object }
|
||||||
|
|
||||||
|
it "defines a double" do
|
||||||
|
expect(dbl).to be_a(Spectator::Double)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "stub-less method" do
|
||||||
|
double(:test5) do
|
||||||
|
def foo
|
||||||
|
"no stub"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { double(:test5).as_null_object }
|
||||||
|
|
||||||
|
it "defines a double with methods" do
|
||||||
|
expect(dbl.foo).to eq("no stub")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "mixing keyword arguments" do
|
||||||
|
double(:test6, foo: "kwargs", bar: 42) do
|
||||||
|
stub def foo
|
||||||
|
"block"
|
||||||
|
end
|
||||||
|
|
||||||
|
stub def baz
|
||||||
|
"block"
|
||||||
|
end
|
||||||
|
|
||||||
|
stub def baz(value)
|
||||||
|
"block2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { double(:test6).as_null_object }
|
||||||
|
|
||||||
|
it "overrides the keyword arguments with the block methods" do
|
||||||
|
expect(dbl.foo).to eq("block")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "falls back to the keyword argument value for mismatched arguments" do
|
||||||
|
expect(dbl.foo(42)).to eq("kwargs")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can call methods defined only by keyword arguments" do
|
||||||
|
expect(dbl.bar).to eq(42)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can call methods defined only by the block" do
|
||||||
|
expect(dbl.baz).to eq("block")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can call methods defined by the block with different signatures" do
|
||||||
|
expect(dbl.baz(42)).to eq("block2")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,14 +11,23 @@ module Spectator::DSL
|
||||||
private macro def_double(name, **value_methods, &block)
|
private macro def_double(name, **value_methods, &block)
|
||||||
{% # Construct a unique type name for the double by using the number of defined doubles.
|
{% # Construct a unique type name for the double by using the number of defined doubles.
|
||||||
index = ::Spectator::DSL::Mocks::DOUBLES.size
|
index = ::Spectator::DSL::Mocks::DOUBLES.size
|
||||||
double_type_name = "Double#{index}".id.symbolize
|
double_type_name = "Double#{index}".id
|
||||||
|
null_double_type_name = "NullDouble#{index}".id
|
||||||
|
|
||||||
# Store information about how the double is defined and its context.
|
# Store information about how the double is defined and its context.
|
||||||
# This is important for constructing an instance of the double later.
|
# This is important for constructing an instance of the double later.
|
||||||
::Spectator::DSL::Mocks::DOUBLES << {name.id.symbolize, @type.name(generic_args: false).symbolize, double_type_name} %}
|
::Spectator::DSL::Mocks::DOUBLES << {name.id.symbolize, @type.name(generic_args: false).symbolize, double_type_name.symbolize} %}
|
||||||
|
|
||||||
|
::Spectator::Double.define({{double_type_name}}, {{name}}, {{**value_methods}}) do
|
||||||
|
def as_null_object
|
||||||
|
{{null_double_type_name}}.new(@stubs)
|
||||||
|
end
|
||||||
|
|
||||||
|
{% if block %}{{block.body}}{% end %}
|
||||||
|
end
|
||||||
|
|
||||||
{% begin %}
|
{% begin %}
|
||||||
::Spectator::Double.define({{double_type_name}}, {{name}}, {{**value_methods}}){% if block %} do
|
::Spectator::NullDouble.define({{null_double_type_name}}, {{name}}, {{**value_methods}}){% if block %} do
|
||||||
{{block.body}}
|
{{block.body}}
|
||||||
end{% end %}
|
end{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
Loading…
Reference in a new issue