Ensure that a TypeNode is resolved

When describing a constant, the `resolve?` method can return a
non-TypeNode, which is the constant's value.
The Crystal docs seem to indicate this should only return `TypeNode` or
`NilLiteral`.
But, I can see when this would be useful to resolve a constant in a
macro.
To work around this, `described_class` and `subject` should only be
defined when it resolves to a `TypeNode`.

Fixes arctic-fox/spectator#40
Fixes arctic-fox/spectator#41
This commit is contained in:
Michael Miller 2020-03-04 23:16:29 -07:00
parent d945a414f9
commit e126cb744b
1 changed files with 3 additions and 1 deletions

View File

@ -19,7 +19,9 @@ module Spectator
%source = ::Spectator::Source.new({{_source_file}}, {{_source_line}})
::Spectator::SpecBuilder.start_group({{description}}, %source)
{% if (what.is_a?(Path) || what.is_a?(Generic)) && (described_type = what.resolve?) %}
# Oddly, `#resolve?` can return a constant's value, which isn't a TypeNode.
# Ensure `described_class` and `subject` are only set for real types (is a `TypeNode`).
{% if (what.is_a?(Path) || what.is_a?(Generic)) && (described_type = what.resolve?).is_a?(TypeNode) %}
macro described_class
{{described_type.name}}
end