module Ameba::Spec::ExpectIssue
Overview
Mixin for #expect_issue
and #expect_no_issues
This mixin makes it easier to specify strict issue expectations in a declarative and visual fashion. Just type out the code that should generate an issue, annotate code by writing '^'s underneath each character that should be highlighted, and follow the carets with a string (separated by a space) that is the message of the issue. You can include multiple issues in one code snippet.
Usage:
expect_issue subject, <<-CRYSTAL
a do
b
end.c
# ^^^ error: Avoid chaining a method call on a do...end block.
CRYSTAL
Equivalent assertion without #expect_issue
:
source = Source.new <<-CRYSTAL, "source.cr"
a do
b
end.c
CRYSTAL
subject.catch(source).should_not be_valid
source.issues.size.should be(1)
issue = source.issues.first
issue.location.to_s.should eq "source.cr:3:1"
issue.end_location.to_s.should eq "source.cr:3:5"
issue.message.should eq(
"Avoid chaining a method call on a do...end block."
)
Autocorrection can be tested using #expect_correction
after
#expect_issue
.
source = expect_issue subject, <<-CRYSTAL
x % 2 == 0
# ^^^^^^^^ error: Replace with `Int#even?`.
CRYSTAL
expect_correction source, <<-CRYSTAL
x.even?
CRYSTAL
If you do not want to specify an issue then use the
companion method #expect_no_issues
. This method is a much
simpler assertion since it just inspects the code and checks
that there were no issues. The #expect_issue
method has
to do more work by parsing out lines that contain carets.
If the code produces an issue that could not be auto-corrected, you can
use #expect_no_corrections
after #expect_issue
.
source = expect_issue subject, <<-CRYSTAL
a do
b
end.c
# ^^^ error: Avoid chaining a method call on a do...end block.
CRYSTAL
expect_no_corrections source
If your code has variables of different lengths, you can use %{foo}
,
^{foo}
, and _{foo}
to format your template; you can also abbreviate
issue messages with [...]
:
%w[raise fail].each do |keyword|
expect_issue subject, <<-CRYSTAL, keyword: keyword
%{keyword} Exception.new(msg)
# ^{keyword}^^^^^^^^^^^^^^^^^ error: Redundant `Exception.new` [...]
CRYSTAL
%w[has_one has_many].each do |type|
expect_issue subject, <<-CRYSTAL, type: type
class Book
%{type} :chapter, foreign_key: "book_id"
_{type} # ^^^^^^^^^^^^^^^^^^^^^^ error: Specifying the default [...]
end
CRYSTAL
end
If you need to specify an issue on a blank line, use the empty ^{}
marker:
expect_issue subject, <<-CRYSTAL
# ^{} error: Missing frozen string literal comment.
puts 1
CRYSTAL
Included Modules
Defined in:
ameba/spec/expect_issue.crInstance Method Summary
- #expect_correction(source, correction, *, file = __FILE__, line = __LINE__)
- #expect_issue(rules : Rule::Base | Enumerable(Rule::Base), annotated_code : String, path = "", *, file = __FILE__, line = __LINE__, **replacements)
- #expect_no_corrections(source, *, file = __FILE__, line = __LINE__)
- #expect_no_issues(rules : Rule::Base | Enumerable(Rule::Base), code : String, path = "", *, file = __FILE__, line = __LINE__)