From 4c85ad7c753e66d76f5900dd3f151aa574e4304c Mon Sep 17 00:00:00 2001 From: Vitalii Elenhaupt Date: Thu, 25 Jan 2018 11:50:11 +0200 Subject: [PATCH] Syntax rule running priorities --- spec/ameba/base_spec.cr | 13 +++++++++++ spec/ameba/formatter/todo_formatter_spec.cr | 15 +++++++++++++ spec/ameba/rule/syntax_spec.cr | 2 -- spec/ameba/runner_spec.cr | 24 +++++++++++++++++++++ src/ameba/formatter/todo_formatter.cr | 1 + src/ameba/rule/base.cr | 5 +++-- src/ameba/rule/syntax.cr | 5 ----- src/ameba/runner.cr | 11 +++++++--- 8 files changed, 64 insertions(+), 12 deletions(-) diff --git a/spec/ameba/base_spec.cr b/spec/ameba/base_spec.cr index 4574cb46..2c3251e7 100644 --- a/spec/ameba/base_spec.cr +++ b/spec/ameba/base_spec.cr @@ -7,6 +7,19 @@ module Ameba::Rule end describe Base do + context ".rules" do + it "returns a list of all rules" do + rules = Rule.rules + rules.should_not be_nil + rules.should contain DummyRule + rules.should contain NoProperties + end + + it "should not include syntax rule" do + Rule.rules.should_not contain Rule::Syntax + end + end + context "properties" do subject = DummyRule.new diff --git a/spec/ameba/formatter/todo_formatter_spec.cr b/spec/ameba/formatter/todo_formatter_spec.cr index 7c7f8295..a022b8c4 100644 --- a/spec/ameba/formatter/todo_formatter_spec.cr +++ b/spec/ameba/formatter/todo_formatter_spec.cr @@ -50,6 +50,21 @@ module Ameba it "excludes source from this rule" do create_todo.should contain "Excluded:\n - source.cr" end + + context "when invalid syntax" do + it "does not exclude Syntax rule" do + file = IO::Memory.new + formatter = Formatter::TODOFormatter.new IO::Memory.new, file + + s = Source.new "def invalid_syntax" + s.error Rule::Syntax.new, s.location(1, 2), "message" + + formatter.finished [s] + content = file.to_s + + content.should_not contain "Syntax" + end + end end end end diff --git a/spec/ameba/rule/syntax_spec.cr b/spec/ameba/rule/syntax_spec.cr index f8eaf771..79b2d8a9 100644 --- a/spec/ameba/rule/syntax_spec.cr +++ b/spec/ameba/rule/syntax_spec.cr @@ -9,7 +9,6 @@ module Ameba::Rule def hello puts "totally valid" rescue e: Exception - # end ) subject.catch(s).should be_valid @@ -20,7 +19,6 @@ module Ameba::Rule def hello puts "invalid" rescue Exception => e - # end ) subject.catch(s).should_not be_valid diff --git a/spec/ameba/runner_spec.cr b/spec/ameba/runner_spec.cr index 0bacee76..c57d6afd 100644 --- a/spec/ameba/runner_spec.cr +++ b/spec/ameba/runner_spec.cr @@ -51,6 +51,30 @@ module Ameba Runner.new(rules, [source], formatter).run.success?.should be_true end + + context "invalid syntax" do + it "reports a syntax error" do + rules = [Rule::Syntax.new] of Rule::Base + source = Source.new "def bad_syntax" + + Runner.new(rules, [source], formatter).run + source.should_not be_valid + source.errors.first.rule.name.should eq "Syntax" + end + + it "does not run other rules" do + rules = [Rule::Syntax.new, Rule::ConstantNames.new] of Rule::Base + source = Source.new %q( + MyBadConstant = 1 + + when my_bad_syntax + ) + + Runner.new(rules, [source], formatter).run + source.should_not be_valid + source.errors.size.should eq 1 + end + end end describe "#success?" do diff --git a/src/ameba/formatter/todo_formatter.cr b/src/ameba/formatter/todo_formatter.cr index c12bca14..1843fd03 100644 --- a/src/ameba/formatter/todo_formatter.cr +++ b/src/ameba/formatter/todo_formatter.cr @@ -31,6 +31,7 @@ module Ameba::Formatter private def rule_errors_map(errors) Hash(Rule::Base, Array(Source::Error)).new.tap do |h| errors.each do |error| + next if error.rule.is_a? Rule::Syntax h[error.rule] ||= Array(Source::Error).new h[error.rule] << error end diff --git a/src/ameba/rule/base.cr b/src/ameba/rule/base.cr index 989b626c..c10c6a30 100644 --- a/src/ameba/rule/base.cr +++ b/src/ameba/rule/base.cr @@ -82,13 +82,14 @@ module Ameba::Rule end end - # Returns a list of all available rules. + # Returns a list of all available rules + # (except a `Rule::Syntax` which is a special rule). # # ``` # Ameba::Rule.rules # => [LineLength, ConstantNames, ....] # ``` # def self.rules - Base.subclasses + Base.subclasses.reject! &.== Rule::Syntax end end diff --git a/src/ameba/rule/syntax.cr b/src/ameba/rule/syntax.cr index 52feee5e..341a4b89 100644 --- a/src/ameba/rule/syntax.cr +++ b/src/ameba/rule/syntax.cr @@ -20,11 +20,6 @@ module Ameba::Rule # ``` # struct Syntax < Base - properties do - enabled = true - description = "Reports invalid Crystal syntax" - end - def test(source) source.ast rescue e : Crystal::SyntaxException diff --git a/src/ameba/runner.cr b/src/ameba/runner.cr index bd64dfbb..725878ac 100644 --- a/src/ameba/runner.cr +++ b/src/ameba/runner.cr @@ -20,6 +20,9 @@ module Ameba # A formatter to prepare report. @formatter : Formatter::BaseFormatter + # A syntax rule which always inspects a source first + @syntax_rule = Rule::Syntax.new + # Instantiates a runner using a `config`. # # ``` @@ -57,9 +60,11 @@ module Ameba @sources.each do |source| @formatter.source_started source - @rules.each do |rule| - next if rule.excluded?(source) - rule.test(source) + if @syntax_rule.catch(source).valid? + @rules.each do |rule| + next if rule.excluded?(source) + rule.test(source) + end end @formatter.source_finished source