Skip to content

Commit

Permalink
feat(rules): add no console log rule (#1189)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xIchigo authored Aug 31, 2023
1 parent 2b48782 commit b98b352
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
31 changes: 31 additions & 0 deletions docs/rules/no_console_log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# no_console_log

Disallows the use of `console.log`.

Oftentimes, developers accidentally commit `console.log` statements, left in
particularly after debugging. Moreover, using `console.log` in code may leak
sensitive information to the output or clutter the console with unnecessary
information. This rule helps maintain clean and secure code by disallowing the
use of `console.log`.

### Invalid

```typescript
console.log("Debug message");

if (debug) console.log("Debugging");

function log() {
console.log("Log");
}
```

### Valid

```typescript
console.error("Error message");

function log_error(message: string) {
console.warn(message);
}
```
1 change: 1 addition & 0 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub mod no_case_declarations;
pub mod no_class_assign;
pub mod no_compare_neg_zero;
pub mod no_cond_assign;
pub mod no_console_log;
pub mod no_const_assign;
pub mod no_constant_condition;
pub mod no_control_regex;
Expand Down
89 changes: 89 additions & 0 deletions src/rules/no_console_log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use super::{Context, LintRule};
use crate::handler::{Handler, Traverse};
use crate::Program;
use deno_ast::view::{CallExpr, Expr, MemberProp};
use deno_ast::SourceRanged;

#[derive(Debug)]
pub struct NoConsoleLog;

const MESSAGE: &str = "'console.log` calls are not allowed.";
const CODE: &str = "no-console";

impl LintRule for NoConsoleLog {
fn tags(&self) -> &'static [&'static str] {
&["recommended"]
}

fn code(&self) -> &'static str {
CODE
}

fn lint_program_with_ast_view(
&self,
context: &mut Context,
program: Program,
) {
NoConsoleLogHandler.traverse(program, context);
}

#[cfg(feature = "docs")]
fn docs(&self) -> &'static str {
include_str!("../../docs/rules/no_console_log.md")
}
}

struct NoConsoleLogHandler;

impl Handler for NoConsoleLogHandler {
fn call_expr(&mut self, call_expr: &CallExpr, ctx: &mut Context) {
if let deno_ast::view::Callee::Expr(Expr::Member(member_expr)) =
&call_expr.callee
{
if let Expr::Ident(obj_ident) = &member_expr.obj {
if obj_ident.sym().as_ref() == "console" {
if let MemberProp::Ident(prop_ident) = &member_expr.prop {
if prop_ident.sym().as_ref() == "log" {
ctx.add_diagnostic(call_expr.range(), CODE, MESSAGE);
}
}
}
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn no_console_log_valid() {
// Test cases where a console.log call is not present
assert_lint_ok!(
NoConsoleLog,
r#"let foo = 0; const bar = 1;"#,
r#"console.error('Error message');"#
);
}

#[test]
fn no_console_log_invalid() {
// Test cases where console.log is present
assert_lint_err!(
NoConsoleLog,
r#"console.log('Debug message');"#: [{
col: 0,
message: MESSAGE,
}],
r#"if (debug) { console.log('Debugging'); }"#: [{
col: 13,
message: MESSAGE,
}],
r#"function log() { console.log('Log'); }"#: [{
col: 17,
message: MESSAGE,
}]
);
}
}

0 comments on commit b98b352

Please sign in to comment.