deno_lint 0.2.10

lint for deno
Documentation
// Copyright 2020 the Deno authors. All rights reserved. MIT license.

#![deny(warnings)]

#[macro_use]
extern crate log;

#[cfg(test)]
#[macro_use]
mod test_util;

pub mod ast_parser;
mod control_flow;
pub mod diagnostic;
mod globals;
mod ignore_directives;
mod js_regex;
pub mod linter;
pub mod rules;
mod scopes;
pub mod swc_util;

#[cfg(test)]
mod lint_tests {
  use crate::diagnostic::LintDiagnostic;
  use crate::linter::*;
  use crate::rules::{get_recommended_rules, LintRule};
  use crate::test_util::assert_diagnostic;

  fn lint(
    source: &str,
    unknown_rules: bool,
    unused_dir: bool,
    rules: Vec<Box<dyn LintRule>>,
  ) -> Vec<LintDiagnostic> {
    let mut linter = LinterBuilder::default()
      .lint_unknown_rules(unknown_rules)
      .lint_unused_ignore_directives(unused_dir)
      .rules(rules)
      .build();

    let (_, diagnostics) = linter
      .lint("lint_test.ts".to_string(), source.to_string())
      .expect("Failed to lint");
    diagnostics
  }

  fn lint_recommended_rules(
    source: &str,
    unknown_rules: bool,
    unused_dir: bool,
  ) -> Vec<LintDiagnostic> {
    lint(source, unknown_rules, unused_dir, get_recommended_rules())
  }

  fn lint_specified_rule<T: LintRule + 'static>(
    source: &str,
    unknown_rules: bool,
    unused_dir: bool,
  ) -> Vec<LintDiagnostic> {
    lint(source, unknown_rules, unused_dir, vec![T::new()])
  }

  #[test]
  fn empty_file() {
    let diagnostics = lint_recommended_rules("", true, false);
    assert!(diagnostics.is_empty());
  }

  #[test]
  fn warn_unknown_rules() {
    let src = r#"
 // deno-lint-ignore some-rule
 function foo() {
   // deno-lint-ignore some-rule-2 some-rule-3
   let bar_foo = true
 }
      "#;
    let diagnostics = lint_recommended_rules(src, true, false);

    assert_diagnostic(&diagnostics[0], "ban-unknown-rule-code", 2, 1, src);
    assert_diagnostic(&diagnostics[1], "ban-unknown-rule-code", 4, 3, src);
  }

  #[test]
  fn ignore_unknown_rules() {
    let diagnostics = lint_recommended_rules(
      r#"
 // deno-lint-ignore some-rule
 function foo() {
   // pass
 }
      "#,
      false,
      false,
    );

    assert_eq!(diagnostics.len(), 0);
  }

  #[test]
  fn unknown_rules_always_know_available_rules() {
    use crate::rules::camelcase::Camelcase;
    let diagnostics = lint_specified_rule::<Camelcase>(
      r#"
// deno-lint-ignore no-explicit-any
const fooBar: any = 42;
      "#,
      true,
      false,
    );

    assert!(diagnostics.is_empty());
  }

  #[test]
  fn warn_unused_dir() {
    let src = r#"
 // deno-lint-ignore no-explicit-any
 function bar(p: boolean) {
   // deno-lint-ignore no-misused-new eqeqeq
   const foo = false
 }
      "#;
    let diagnostics = lint_recommended_rules(src, false, true);

    assert_eq!(diagnostics.len(), 2);
    assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 2, 1, src);
    assert_diagnostic(&diagnostics[1], "ban-unused-ignore", 4, 3, src);
  }

  #[test]
  fn ignore_unused_dir() {
    let diagnostics = lint_recommended_rules(
      r#"
 // deno-lint-ignore no-explicit-any
 function bar(p: boolean) {
   // pass
 }
      "#,
      false,
      false,
    );

    assert_eq!(diagnostics.len(), 0);
  }

  #[test]
  fn unused_dir_not_report_unexecuted_rule() {
    use crate::rules::camelcase::Camelcase;
    let diagnostics = lint_specified_rule::<Camelcase>(
      r#"
// deno-lint-ignore no-explicit-any
const fooBar = 42;
      "#,
      false,
      true,
    );

    assert!(diagnostics.is_empty());
  }

  #[test]
  fn file_directive_with_code() {
    let diagnostics = lint_recommended_rules(
      r#"
 // deno-lint-ignore-file no-explicit-any

 function bar(p: any) {
   // pass
 }
      "#,
      false,
      false,
    );

    assert_eq!(diagnostics.len(), 0);
  }

  #[test]
  fn file_directive_with_code_unused() {
    let src = r#"
 // deno-lint-ignore-file no-explicit-any no-empty

 function bar(p: any) {
   // pass
 }
      "#;
    let diagnostics = lint_recommended_rules(src, false, true);

    assert_eq!(diagnostics.len(), 1);
    assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 2, 1, src);
  }

  #[test]
  fn file_directive_with_code_higher_precedence() {
    let src = r#"
 // deno-lint-ignore-file no-explicit-any

 // deno-lint-ignore no-explicit-any
 function bar(p: any) {
   // pass
 }
      "#;
    let diagnostics = lint_recommended_rules(src, false, true);

    assert_eq!(diagnostics.len(), 1);
    assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 4, 1, src);
  }
}