diff --git a/spec/ameba/rules/debugger_statement_spec.cr b/spec/ameba/rules/debugger_statement_spec.cr new file mode 100644 index 00000000..85e8b132 --- /dev/null +++ b/spec/ameba/rules/debugger_statement_spec.cr @@ -0,0 +1,44 @@ +require "../../spec_helper" + +module Ameba::Rules + subject = DebuggerStatement.new + + describe DebuggerStatement do + it "passes if there is no debugger statement" do + s = Source.new %( + "this is not a debugger statement" + s = "debugger" + + def debugger(program) + end + debugger "" + + class A + def debugger + end + end + A.new.debugger + ) + subject.catch(s).valid?.should be_true + end + + it "fails if there is a debugger statement" do + s = Source.new %( + a = 2 + debugger + a = a + 1 + ) + subject.catch(s).valid?.should be_false + end + + it "reports rule, pos and message" do + s = Source.new "debugger" + subject.catch(s).valid?.should be_false + + error = s.errors.first + error.rule.should_not be_nil + error.pos.should eq 1 + error.message.should eq "Possible forgotten debugger statement detected" + end + end +end diff --git a/src/ameba/rules/debugger_statement.cr b/src/ameba/rules/debugger_statement.cr new file mode 100644 index 00000000..9b594206 --- /dev/null +++ b/src/ameba/rules/debugger_statement.cr @@ -0,0 +1,20 @@ +module Ameba::Rules + # A rule that disallows calls to debugger. + # + # This is because we don't want debugger breakpoints accidentally being + # committed into our codebase. + struct DebuggerStatement < Rule + def test(source) + AST::CallVisitor.new self, source + end + + def test(source, node : Crystal::Call) + return unless node.name == "debugger" && + node.args.empty? && + node.obj.nil? + + source.error self, node.location.try &.line_number, + "Possible forgotten debugger statement detected" + end + end +end