diff --git a/spec/ameba/rule/layout/trailing_blank_lines_spec.cr b/spec/ameba/rule/layout/trailing_blank_lines_spec.cr index b1fb26df..4f42f9a6 100644 --- a/spec/ameba/rule/layout/trailing_blank_lines_spec.cr +++ b/spec/ameba/rule/layout/trailing_blank_lines_spec.cr @@ -4,35 +4,55 @@ module Ameba::Rule::Layout subject = TrailingBlankLines.new describe TrailingBlankLines do - it "passes if there is no blank lines at the end" do - source = Source.new "no-blankline" + it "passes if there is a blank line at the end of a source" do + source = Source.new "a = 1\n", normalize: false subject.catch(source).should be_valid end - it "fails if there is a blank line at the end of a source" do - source = Source.new "a = 1\n \n ", normalize: false - subject.catch(source).should_not be_valid - end - it "passes if source is empty" do source = Source.new "" subject.catch(source).should be_valid end - it "passes if last line is not blank" do - source = Source.new "\n\n\n puts 22", normalize: false - subject.catch(source).should be_valid + it "fails if there is no blank lines at the end" do + source = Source.new "no-blankline" + subject.catch(source).should_not be_valid end - it "reports rule, pos and message" do - source = Source.new "a = 1\n\n ", "source.cr", normalize: false + it "fails if there more then one blank line at the end of a source" do + source = Source.new "a = 1\n \n", normalize: false subject.catch(source).should_not be_valid + end - issue = source.issues.first - issue.rule.should_not be_nil - issue.location.to_s.should eq "source.cr:2:1" - issue.end_location.should be_nil - issue.message.should eq "Blank lines detected at the end of the file" + it "fails if last line is not blank" do + source = Source.new "\n\n\n puts 22", normalize: false + subject.catch(source).should_not be_valid + end + + context "when unnecessary blank line has been detected" do + it "reports rule, pos and message" do + source = Source.new "a = 1\n\n", "source.cr", normalize: false + subject.catch(source).should_not be_valid + + issue = source.issues.first + issue.rule.should_not be_nil + issue.location.to_s.should eq "source.cr:2:1" + issue.end_location.should be_nil + issue.message.should eq "Excessive trailing newline detected" + end + end + + context "when final line has been missed" do + it "reports rule, pos and message" do + source = Source.new "a = 1", "source.cr", normalize: false + subject.catch(source).should_not be_valid + + issue = source.issues.first + issue.rule.should_not be_nil + issue.location.to_s.should eq "source.cr:0:1" + issue.end_location.should be_nil + issue.message.should eq "Trailing newline missing" + end end end end diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 7e5bfef2..005b207e 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -20,9 +20,8 @@ module Ameba private def normalize_source(code, separator = "\n") lines = code.split(separator) - # remove unneeded first and last blank lines if any + # remove unneeded first blank lines if any lines.shift if lines[0].blank? && lines.size > 1 - lines.pop if lines[-1].blank? && lines.size > 1 # find the minimum indentation min_indent = lines.min_of do |line| diff --git a/src/ameba/rule/layout/trailing_blank_lines.cr b/src/ameba/rule/layout/trailing_blank_lines.cr index 208cf09e..24499e9c 100644 --- a/src/ameba/rule/layout/trailing_blank_lines.cr +++ b/src/ameba/rule/layout/trailing_blank_lines.cr @@ -13,11 +13,20 @@ module Ameba::Rule::Layout description "Disallows trailing blank lines" end - MSG = "Blank lines detected at the end of the file" + MSG = "Excessive trailing newline detected" + MSG_FINAL_NEWLINE = "Trailing newline missing" def test(source) - if source.lines.size > 1 && source.lines[-2, 2].join.strip.empty? - issue_for({source.lines.size - 1, 1}, MSG) + source_lines = source.lines + return if source_lines.empty? + + last_source_line = source_lines.last + source_lines_size = source_lines.size + return if source_lines_size == 1 && last_source_line.empty? + + last_line_not_empty = !last_source_line.empty? + if source_lines_size >= 1 && (source_lines.last(2).join.strip.empty? || last_line_not_empty) + issue_for({source_lines_size - 1, 1}, last_line_not_empty ? MSG_FINAL_NEWLINE : MSG) end end end