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:
Michael Miller 2022-10-08 14:04:02 -06:00
parent 1998edbbb2
commit 4dfa5ccb6e
No known key found for this signature in database
GPG key ID: 32B47AE8F388A1FF
3 changed files with 15 additions and 18 deletions

View file

@ -26,6 +26,15 @@ module Spectator
super(_spectator_double_stubs + message_stubs)
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.
private def _spectator_stubbed_name : String
"#<LazyDouble #{@name || "Anonymous"}>"