I have some checks in my projects that will throw compile time errors if you do not have a required method defined, or adding an annotation to an instance method vs class method.
Is there a way to test these compile time error get thrown as expected; similar to expect_raises
or the assert_error
method in the stdlib?
2 Likes
Similar, would be more interested in making sure the correct compile time error is thrown than just a true/false if it compiles or not tho.
Just to complete this topic. This is what i ended up doing:
def assert_error(path : String, message : String) : Nil
buffer = IO::Memory.new
result = Process.run("crystal", ["run", "--no-color", "--no-codegen", "spec/" + path], error: buffer)
result.success?.should be_false
buffer.to_s.should contain message
buffer.close
end
Where i created separate files for each assertion, like:
require "../../../routing_spec_helper"
class CompileController < Athena::Routing::Controller
@[Athena::Routing::Get(path: "int8/")]
def no_return_type
123
end
end
Athena::Routing.run
Then used it
describe "without a return type" do
it "should not compile" do
assert_error "routing/compiler/actions/no_return_type.cr", "Route action return type must be set for 'CompileController.no_return_type'"
end
end
EDIT: I created GitHub - athena-framework/spec: Common/helpful Spec compliant testing utilities that includes this among other additional testing utilities.
5 Likes
Update: Actually came up with a bit better way to handle it:
private def assert_error(message : String, code : String) : Nil
input = IO::Memory.new <<-CR
require "./spec_helper.cr"
#{code}
ATH.run
CR
buffer = IO::Memory.new
result = Process.run("crystal", ["run", "--no-color", "--no-codegen", "--stdin-filename", "#{__DIR__}/test.cr"], input: input.rewind, output: buffer, error: buffer)
fail buffer.to_s if result.success?
buffer.to_s.should contain message
buffer.close
end
This method allows passing the code as a string to the method as opposed to a file path. This ultimately is easier to maintain. Example use would be like:
it "action missing return type" do
assert_error "Route action return type must be set for 'CompileController#action'.", <<-CODE
class CompileController < Athena::Framework::Controller
@[ARTA::Get(path: "/")]
def action
123
end
end
CODE
end
2 Likes