Update tests to use new Double usage

This commit is contained in:
Michael Miller 2022-03-12 13:54:40 -07:00
parent c8864b169e
commit 5b1a5cd49d
No known key found for this signature in database
GPG key ID: 32B47AE8F388A1FF

View file

@ -1,40 +1,49 @@
require "../../spec_helper" require "../../spec_helper"
Spectator.describe Spectator::Double do Spectator.describe Spectator::Double do
Spectator::Double.define(TestDouble, foo: 42, bar: "baz") Spectator::Double.define(EmptyDouble)
Spectator::Double.define(FooBarDouble, "dbl-name", foo: 42, bar: "baz")
subject(dbl) { TestDouble.new("dbl-name") } # The subject `dbl` must be carefully used in sub-contexts, otherwise it pollutes parent scopes.
# This changes the type of `dbl` to `Double`, which produces a union of methods and their return types.
context "plain double" do
subject(dbl) { FooBarDouble.new }
it "responds to defined messages" do it "responds to defined messages" do
aggregate_failures do aggregate_failures do
expect(dbl.foo).to eq(42) expect(dbl.foo).to eq(42)
expect(dbl.bar).to eq("baz") expect(dbl.bar).to eq("baz")
end
end end
end
it "fails on undefined messages" do it "fails on undefined messages" do
expect { dbl.baz }.to raise_error(Spectator::UnexpectedMessage, /baz/) expect { dbl.baz }.to raise_error(Spectator::UnexpectedMessage, /baz/)
end end
it "reports the name in errors" do it "reports the name in errors" do
expect { dbl.baz }.to raise_error(/dbl-name/) expect { dbl.baz }.to raise_error(/"dbl-name"/)
end end
it "reports arguments" do it "reports arguments" do
expect { dbl.baz(123, "qux", field: :value) }.to raise_error(Spectator::UnexpectedMessage, /\(123, "qux", field: :value\)/) expect { dbl.baz(123, "qux", field: :value) }.to raise_error(Spectator::UnexpectedMessage, /\(123, "qux", field: :value\)/)
end end
it "has a non-union return type" do it "has a non-union return type" do
aggregate_failures do aggregate_failures do
expect(dbl.foo).to compile_as(Int32) expect(dbl.foo).to compile_as(Int32)
expect(dbl.bar).to compile_as(String) expect(dbl.bar).to compile_as(String)
end
end
it "uses nil for undefined messages" do
expect { dbl.baz }.to compile_as(Nil)
end end
end end
context "without a double name" do context "without a double name" do
Spectator::Double.define(TestDouble, foo: 42) Spectator::Double.define(NamelessDouble, foo: 42)
subject(dbl) { TestDouble.new } subject(dbl) { NamelessDouble.new }
it "reports as anonymous" do it "reports as anonymous" do
expect { dbl.baz }.to raise_error(/anonymous/i) expect { dbl.baz }.to raise_error(/anonymous/i)
@ -43,29 +52,29 @@ Spectator.describe Spectator::Double do
context "with common object methods" do context "with common object methods" do
subject(dbl) do subject(dbl) do
Spectator::Double.new( EmptyDouble.new([
"!=": "!=", Spectator::ValueStub.new(:"!=", "!="),
"!~": "!~", Spectator::ValueStub.new(:"!~", "!~"),
"==": "==", Spectator::ValueStub.new(:"==", "=="),
"===": "===", Spectator::ValueStub.new(:"===", "==="),
"=~": "=~", Spectator::ValueStub.new(:"=~", "=~"),
"class": "class", Spectator::ValueStub.new(:class, "class"),
"dup": "dup", Spectator::ValueStub.new(:dup, "dup"),
"hash": "hash", Spectator::ValueStub.new(:hash, "hash"),
"in?": true, Spectator::ValueStub.new(:"in?", true),
"inspect": "inspect", Spectator::ValueStub.new(:inspect, "inspect"),
"itself": "itself", Spectator::ValueStub.new(:itself, "itself"),
"not_nil!": "not_nil!", Spectator::ValueStub.new(:"not_nil!", "not_nil!"),
"pretty_inspect": "pretty_inspect", Spectator::ValueStub.new(:pretty_inspect, "pretty_inspect"),
"tap": "tap", Spectator::ValueStub.new(:tap, "tap"),
"to_json": "to_json", Spectator::ValueStub.new(:to_json, "to_json"),
"to_pretty_json": "to_pretty_json", Spectator::ValueStub.new(:to_pretty_json, "to_pretty_json"),
"to_s": "to_s", Spectator::ValueStub.new(:to_s, "to_s"),
"to_yaml": "to_yaml", Spectator::ValueStub.new(:to_yaml, "to_yaml"),
"try": "try", Spectator::ValueStub.new(:try, "try"),
"object_id": 42_u64, Spectator::ValueStub.new(:object_id, 42_u64),
"same?": false, Spectator::ValueStub.new(:"same?", false),
) ] of Spectator::Stub)
end end
it "responds with defined messages" do it "responds with defined messages" do
@ -103,42 +112,42 @@ Spectator.describe Spectator::Double do
end end
context "without common object methods" do context "without common object methods" do
subject(dbl) { Spectator::Double.new } subject(dbl) { EmptyDouble.new }
it "raises with undefined messages" do it "raises with undefined messages" do
io = IO::Memory.new io = IO::Memory.new
pp = PrettyPrint.new(io) pp = PrettyPrint.new(io)
aggregate_failures do aggregate_failures do
expect { dbl.!=(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.!=(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.!~(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.!~(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.==(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.==(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.===(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.===(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.=~(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.=~(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.class }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.class }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.dup }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.dup }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.hash(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.hash(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.hash }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.hash }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.in?(42) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.in?(42) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.in?(1, 2, 3) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.in?(1, 2, 3) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.inspect }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.inspect }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.itself }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.itself }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.not_nil! }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.not_nil! }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.pretty_inspect }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.pretty_inspect }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.pretty_inspect(io) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.pretty_inspect(io) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.pretty_print(pp) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.pretty_print(pp) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.tap { nil } }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.tap { nil } }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_json }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_json }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_json(io) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_json(io) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_pretty_json }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_pretty_json }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_pretty_json(io) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_pretty_json(io) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_s }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_s }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_s(io) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_s(io) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_yaml }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_yaml }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.to_yaml(io) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.to_yaml(io) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.try { nil } }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.try { nil } }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.object_id }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.object_id }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.same?(dbl) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.same?(dbl) }.to raise_error(Spectator::UnexpectedMessage)
expect { dbl.same?(nil) }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.same?(nil) }.to raise_error(Spectator::UnexpectedMessage)
end end
end end
@ -149,35 +158,46 @@ Spectator.describe Spectator::Double do
context "with arguments constraints" do context "with arguments constraints" do
let(arguments) { Spectator::Arguments.capture(/foo/) } let(arguments) { Spectator::Arguments.capture(/foo/) }
let(stub) { Spectator::ValueStub.new(:foo, "bar", arguments).as(Spectator::Stub) }
subject(dbl) { Spectator::Double({foo: String}).new([stub]) }
it "returns the response when constraint satisfied" do context "without common object methods" do
expect(dbl.foo("foobar")).to eq("bar") Spectator::Double.define(TestDouble) do
end abstract_stub abstract def foo(value) : String
end
it "raises an error when constraint unsatisfied" do let(stub) { Spectator::ValueStub.new(:foo, "bar", arguments).as(Spectator::Stub) }
expect { dbl.foo("baz") }.to raise_error(Spectator::UnexpectedMessage) subject(dbl) { TestDouble.new([stub]) }
end
it "raises an error when argument count doesn't match" do it "returns the response when constraint satisfied" do
expect { dbl.foo }.to raise_error(Spectator::UnexpectedMessage) expect(dbl.foo("foobar")).to eq("bar")
end end
it "has a non-union return type" do it "raises an error when constraint unsatisfied" do
expect(dbl.foo("foobar")).to compile_as(String) expect { dbl.foo("baz") }.to raise_error(Spectator::UnexpectedMessage)
end
it "raises an error when argument count doesn't match" do
expect { dbl.foo }.to raise_error(Spectator::UnexpectedMessage)
end
it "has a non-union return type" do
expect(dbl.foo("foobar")).to compile_as(String)
end
end end
context "with common object methods" do context "with common object methods" do
Spectator::Double.define(TestDouble) do
stub abstract def same?(other : Reference) : Bool
end
let(stub) { Spectator::ValueStub.new(:"same?", true, arguments).as(Spectator::Stub) } let(stub) { Spectator::ValueStub.new(:"same?", true, arguments).as(Spectator::Stub) }
subject(dbl) { Spectator::Double({"same?": Bool}).new([stub]) } subject(dbl) { TestDouble.new([stub]) }
it "returns the response when constraint satisfied" do it "returns the response when constraint satisfied" do
expect(dbl.same?("foobar")).to eq(true) expect(dbl.same?("foobar")).to eq(true)
end end
it "raises an error when constraint unsatisfied" do it "raises an error when constraint unsatisfied" do
expect { dbl.same?("baz") }.to raise_error(Spectator::UnexpectedMessage, /mask/) expect { dbl.same?("baz") }.to raise_error(Spectator::UnexpectedMessage)
end end
it "raises an error when argument count doesn't match" do it "raises an error when argument count doesn't match" do