mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Prevent defining stubs on undefined methods in LazyDouble
In Crystal 1.6, a segfault would occur in the spec spec/spectator/mocks/lazy_double_spec.cr:238 I suspect this is a Crystal bug of some kind, but can't reduce it. The methods produced by `method_missing` don't have a return type including Symbol. Symbol is excluded from the union of return types (Int32 | String | Nil). The program segfaults when calling a method on the actual value, which is a symbol. It ultimately crashes when producing a failure message, which indicates the value it tested doesn't equal the expected value (a symbol of the same value). Avoid this issue by preventing stubs on undefined/untyped methods.
This commit is contained in:
parent
1998edbbb2
commit
4dfa5ccb6e
3 changed files with 15 additions and 18 deletions
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Removed
|
||||||
|
- Removed support for stubbing undefined (untyped) methods in lazy doubles. Avoids possible segfault.
|
||||||
|
|
||||||
## [0.11.3] - 2022-09-03
|
## [0.11.3] - 2022-09-03
|
||||||
### Fixed
|
### Fixed
|
||||||
- Display error block (failure message and stack trace) when using `fail`. [#78](https://gitlab.com/arctic-fox/spectator/-/issues/78)
|
- Display error block (failure message and stack trace) when using `fail`. [#78](https://gitlab.com/arctic-fox/spectator/-/issues/78)
|
||||||
|
|
|
@ -235,16 +235,9 @@ Spectator.describe Spectator::LazyDouble do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with previously undefined methods" do
|
context "with previously undefined methods" do
|
||||||
it "can stub methods" do
|
it "raises an error" do
|
||||||
stub = Spectator::ValueStub.new(:baz, :xyz)
|
stub = Spectator::ValueStub.new(:baz, :xyz)
|
||||||
dbl._spectator_define_stub(stub)
|
expect { dbl._spectator_define_stub(stub) }.to raise_error(/stub/)
|
||||||
expect(dbl.baz).to eq(:xyz)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "uses a stub only if an argument constraint is met" do
|
|
||||||
stub = Spectator::ValueStub.new(:baz, :xyz, Spectator::Arguments.capture(:right))
|
|
||||||
dbl._spectator_define_stub(stub)
|
|
||||||
expect { dbl.baz }.to raise_error(Spectator::UnexpectedMessage, /baz/)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -258,15 +251,6 @@ Spectator.describe Spectator::LazyDouble do
|
||||||
it "removes previously defined stubs" do
|
it "removes previously defined stubs" do
|
||||||
expect { dbl._spectator_clear_stubs }.to change { dbl.foo }.from(5).to(42)
|
expect { dbl._spectator_clear_stubs }.to change { dbl.foo }.from(5).to(42)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises on methods without an implementation" do
|
|
||||||
stub = Spectator::ValueStub.new(:baz, :xyz)
|
|
||||||
dbl._spectator_define_stub(stub)
|
|
||||||
expect(dbl.baz).to eq(:xyz)
|
|
||||||
|
|
||||||
dbl._spectator_clear_stubs
|
|
||||||
expect { dbl.baz }.to raise_error(Spectator::UnexpectedMessage, /baz/)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#_spectator_calls" do
|
describe "#_spectator_calls" do
|
||||||
|
|
|
@ -26,6 +26,15 @@ module Spectator
|
||||||
super(_spectator_double_stubs + message_stubs)
|
super(_spectator_double_stubs + message_stubs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Defines a stub to change the behavior of a method in this double.
|
||||||
|
#
|
||||||
|
# NOTE: Defining a stub for a method not defined in the double's type raises an error.
|
||||||
|
protected def _spectator_define_stub(stub : Stub) : Nil
|
||||||
|
return super if Messages.types.has_key?(stub.method)
|
||||||
|
|
||||||
|
raise "Can't define stub #{stub} on lazy double because it wasn't initially defined."
|
||||||
|
end
|
||||||
|
|
||||||
# Returns the double's name formatted for user output.
|
# Returns the double's name formatted for user output.
|
||||||
private def _spectator_stubbed_name : String
|
private def _spectator_stubbed_name : String
|
||||||
"#<LazyDouble #{@name || "Anonymous"}>"
|
"#<LazyDouble #{@name || "Anonymous"}>"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue