From bd44b5562e0a6e1a359294fd4013f2d50af0f460 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Fri, 9 Dec 2022 02:16:16 -0700 Subject: [PATCH] Possible fix for GitLab issue 80 Remove `is_a?` check on line 425. Replace with alternate logic that achieves the same thing. The `{{type}}` in `is_a?` was causing a compiler bug. I'm unsure of the root cause, but this works around it. --- src/spectator/mocks/stubbable.cr | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/spectator/mocks/stubbable.cr b/src/spectator/mocks/stubbable.cr index 4b03117..22c2c7a 100644 --- a/src/spectator/mocks/stubbable.cr +++ b/src/spectator/mocks/stubbable.cr @@ -422,12 +422,15 @@ module Spectator # If successful, which it will be in most cases, return it. # The caller will receive a properly typed value without unions or other side-effects. %cast = %value.as?({{type}}) - if %cast.is_a?({{type}}) + + {% if fail_cast == :nil %} %cast - else - {% if fail_cast == :nil %} - nil - {% elsif fail_cast == :raise %} + {% elsif fail_cast == :raise %} + # Check if nil was returned by the stub and if its okay to return it. + if %value.nil? && {{type}}.nilable? + # Value was nil and nil is allowed to be returned. + %cast.as({{type}}) + elsif %cast.nil? # The stubbed value was something else entirely and cannot be cast to the return type. # There's something weird going on (compiler bug?) that sometimes causes this class lookup to fail. %type = begin @@ -436,10 +439,13 @@ module Spectator "" end raise TypeCastError.new("#{_spectator_stubbed_name} received message #{ {{call}} } and is attempting to return a `#{%type}`, but returned type must be `#{ {{type}} }`.") - {% else %} - {% raise "fail_cast must be :nil, :raise, or :no_return, but got: #{fail_cast}" %} - {% end %} - end + else + # Types match and value can be returned as cast type. + %cast + end + {% else %} + {% raise "fail_cast must be :nil, :raise, or :no_return, but got: #{fail_cast}" %} + {% end %} {% end %} end end