mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(linter): fix file name checking behavior of unicorn/filename-case (#6463)
- closes #6459 Currently, the `unicorn/filename-case` doesn't match the behavior of the original rule. There are several issues which this PR fixes: - The defaults cases were incorrect: only kebab case should be enabled by default, according to the original rule docs. - Setting a single case or multiple cases did not remove the default cases as it should. - Leading/trailing underscores were not ignored by default. - We did not provide a clear diagnostic message indicating which cases are allowed. - We did not try to parse out multiple file parts (separated by `.`). - TODO: We should also support multiple file part checking (which the original rule supports via a config option), for file names such as `someTest.fileName.js` I have also added many of the original test cases to ensure we are more closely compatible. This also improves the performance of just running the `unicorn/filename-case` alone by 4% (20ms total) on the `vscode` codebase: ``` Benchmark 1: ./oxlint-main -A all -W unicorn/filename-case --silent vscode Time (mean ± σ): 489.4 ms ± 24.0 ms [User: 2623.8 ms, System: 447.2 ms] Range (min … max): 474.7 ms … 622.9 ms 100 runs Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options. Benchmark 2: ./oxlint-new-filename-case -A all -W unicorn/filename-case --silent vscode Time (mean ± σ): 470.8 ms ± 22.9 ms [User: 2478.8 ms, System: 463.5 ms] Range (min … max): 455.6 ms … 599.3 ms 100 runs Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options. Summary ./oxlint-new-filename-case -A all -W unicorn/filename-case --silent vscode ran 1.04 ± 0.07 times faster than ./oxlint-main -A all -W unicorn/filename-case --silent vscode ``` Perplexingly, it seems like it might actually be even faster on the `vscode` repository, saving ~5% (70ms) with the default ruleset enabled as well. Maybe my laptop was just running a bit faster. ``` Benchmark 1: ./oxlint-main -W unicorn/filename-case --silent vscode Time (mean ± σ): 1.402 s ± 0.096 s [User: 8.863 s, System: 0.505 s] Range (min … max): 1.318 s … 1.920 s 100 runs Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options. Benchmark 2: ./oxlint-new-filename-case -W unicorn/filename-case --silent vscode Time (mean ± σ): 1.339 s ± 0.042 s [User: 8.582 s, System: 0.511 s] Range (min … max): 1.266 s … 1.506 s 100 runs Summary ./oxlint-new-filename-case -W unicorn/filename-case --silent vscode ran 1.05 ± 0.08 times faster than ./oxlint-main -W unicorn/filename-case --silent vscode ```
This commit is contained in:
parent
725f9f6eb0
commit
d6a0d2e164
2 changed files with 311 additions and 63 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use convert_case::{Case, Casing};
|
||||
use convert_case::{Boundary, Case, Converter};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::Span;
|
||||
|
|
@ -6,41 +6,81 @@ use serde_json::Value;
|
|||
|
||||
use crate::{context::LintContext, rule::Rule};
|
||||
|
||||
fn filename_case_diagnostic(span: Span, case_name: &str) -> OxcDiagnostic {
|
||||
OxcDiagnostic::warn(format!("Filename should not be in {case_name} case")).with_label(span)
|
||||
fn join_strings_disjunction(strings: &[String]) -> String {
|
||||
let mut list = String::new();
|
||||
for (i, s) in strings.iter().enumerate() {
|
||||
if i == 0 {
|
||||
list.push_str(s);
|
||||
} else if i == strings.len() - 1 {
|
||||
list.push_str(&format!(", or {s}"));
|
||||
} else {
|
||||
list.push_str(&format!(", {s}"));
|
||||
}
|
||||
}
|
||||
list
|
||||
}
|
||||
|
||||
fn filename_case_diagnostic(valid_cases: &[&str]) -> OxcDiagnostic {
|
||||
let case_names = valid_cases.iter().map(|s| format!("{s} case")).collect::<Vec<_>>();
|
||||
let message = format!("Filename should be in {}", join_strings_disjunction(&case_names));
|
||||
OxcDiagnostic::warn(message).with_label(Span::default())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::struct_field_names)]
|
||||
pub struct FilenameCase {
|
||||
/// Whether kebab case is allowed.
|
||||
kebab_case: bool,
|
||||
/// Whether camel case is allowed.
|
||||
camel_case: bool,
|
||||
/// Whether snake case is allowed.
|
||||
snake_case: bool,
|
||||
/// Whether pascal case is allowed.
|
||||
pascal_case: bool,
|
||||
underscore_case: bool,
|
||||
}
|
||||
|
||||
impl Default for FilenameCase {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kebab_case: false,
|
||||
camel_case: true,
|
||||
snake_case: false,
|
||||
pascal_case: true,
|
||||
underscore_case: false,
|
||||
}
|
||||
Self { kebab_case: true, camel_case: false, snake_case: false, pascal_case: false }
|
||||
}
|
||||
}
|
||||
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
///
|
||||
/// Enforce a case style for filenames.
|
||||
/// Enforces specific case styles for filenames. By default, kebab case is enforced.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
/// Inconsistent file naming conventions can make it harder to locate files or to create new ones.
|
||||
///
|
||||
/// ### Cases
|
||||
///
|
||||
/// Examples of **correct** filenames for each case:
|
||||
///
|
||||
/// #### `kebabCase`
|
||||
///
|
||||
/// - `some-file-name.js`
|
||||
/// - `some-file-name.test.js`
|
||||
/// - `some-file-name.test-utils.js`
|
||||
///
|
||||
/// #### `camelCase`
|
||||
///
|
||||
/// - `someFileName.js`
|
||||
/// - `someFileName.test.js`
|
||||
/// - `someFileName.testUtils.js`
|
||||
///
|
||||
/// #### `snakeCase`
|
||||
///
|
||||
/// - `some_file_name.js`
|
||||
/// - `some_file_name.test.js`
|
||||
/// - `some_file_name.test_utils.js`
|
||||
///
|
||||
/// #### `pascalCase`
|
||||
///
|
||||
/// - `SomeFileName.js`
|
||||
/// - `SomeFileName.Test.js`
|
||||
/// - `SomeFileName.TestUtils.js`
|
||||
FilenameCase,
|
||||
style
|
||||
);
|
||||
|
|
@ -51,37 +91,27 @@ impl Rule for FilenameCase {
|
|||
return Self::default();
|
||||
};
|
||||
|
||||
if let Some(Value::String(s)) = case_type.get("case") {
|
||||
return match s.as_str() {
|
||||
"kebabCase" => Self { kebab_case: true, ..Self::default() },
|
||||
"camelCase" => Self { camel_case: true, ..Self::default() },
|
||||
"snakeCase" => Self { snake_case: true, ..Self::default() },
|
||||
"pascalCase" => Self { pascal_case: true, ..Self::default() },
|
||||
"underscoreCase" => Self { underscore_case: true, ..Self::default() },
|
||||
_ => Self::default(),
|
||||
};
|
||||
}
|
||||
let off =
|
||||
Self { kebab_case: false, camel_case: false, snake_case: false, pascal_case: false };
|
||||
|
||||
if let Some(Value::String(s)) = case_type.get("case") {
|
||||
return match s.as_str() {
|
||||
"kebabCase" => Self { kebab_case: true, ..Self::default() },
|
||||
"camelCase" => Self { camel_case: true, ..Self::default() },
|
||||
"snakeCase" => Self { snake_case: true, ..Self::default() },
|
||||
"pascalCase" => Self { pascal_case: true, ..Self::default() },
|
||||
"underscoreCase" => Self { underscore_case: true, ..Self::default() },
|
||||
"kebabCase" => Self { kebab_case: true, ..off },
|
||||
"camelCase" => Self { camel_case: true, ..off },
|
||||
"snakeCase" => Self { snake_case: true, ..off },
|
||||
"pascalCase" => Self { pascal_case: true, ..off },
|
||||
_ => Self::default(),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(Value::Object(map)) = case_type.get("cases") {
|
||||
let mut filename_case = Self::default();
|
||||
let mut filename_case = off;
|
||||
for (key, value) in map {
|
||||
match (key.as_str(), value) {
|
||||
("kebabCase", Value::Bool(b)) => filename_case.kebab_case = *b,
|
||||
("camelCase", Value::Bool(b)) => filename_case.camel_case = *b,
|
||||
("snakeCase", Value::Bool(b)) => filename_case.snake_case = *b,
|
||||
("pascalCase", Value::Bool(b)) => filename_case.pascal_case = *b,
|
||||
("underscoreCase", Value::Bool(b)) => filename_case.underscore_case = *b,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -96,27 +126,29 @@ impl Rule for FilenameCase {
|
|||
return;
|
||||
};
|
||||
|
||||
let mut case_name = None;
|
||||
// get filename up to the first dot, or the whole filename if there is no dot
|
||||
let filename = filename.split('.').next().unwrap_or(filename);
|
||||
// ignore all leading and trailing underscores
|
||||
let filename = filename.trim_matches('_');
|
||||
|
||||
let cases = [
|
||||
(Case::Kebab, "kebab", self.kebab_case),
|
||||
(Case::Camel, "camel", self.camel_case),
|
||||
(Case::Snake, "snake", self.snake_case),
|
||||
(Case::Pascal, "pascal", self.pascal_case),
|
||||
(Case::Pascal, "underscore", self.underscore_case),
|
||||
(self.camel_case, Case::Camel, "camel"),
|
||||
(self.kebab_case, Case::Kebab, "kebab"),
|
||||
(self.snake_case, Case::Snake, "snake"),
|
||||
(self.pascal_case, Case::Pascal, "pascal"),
|
||||
];
|
||||
let mut enabled_cases = cases.iter().filter(|(enabled, _, _)| *enabled);
|
||||
|
||||
for (case, name, condition) in cases {
|
||||
if filename.to_case(case) == filename {
|
||||
if condition {
|
||||
return;
|
||||
}
|
||||
case_name.replace(name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(case_name) = case_name {
|
||||
ctx.diagnostic(filename_case_diagnostic(Span::default(), case_name));
|
||||
if !enabled_cases.any(|(_, case, _)| {
|
||||
let converter =
|
||||
Converter::new().remove_boundaries(&[Boundary::LowerDigit, Boundary::DigitLower]);
|
||||
converter.to_case(*case).convert(filename) == filename
|
||||
}) {
|
||||
let case_names = cases
|
||||
.iter()
|
||||
.filter_map(|(enabled, _, name)| if *enabled { Some(*name) } else { None })
|
||||
.collect::<Vec<_>>();
|
||||
ctx.diagnostic(filename_case_diagnostic(&case_names));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,18 +159,134 @@ fn test() {
|
|||
|
||||
use crate::tester::Tester;
|
||||
|
||||
fn test_case(
|
||||
path: &'static str,
|
||||
casing: &'static str,
|
||||
) -> (&'static str, Option<Value>, Option<Value>, Option<PathBuf>) {
|
||||
(
|
||||
"",
|
||||
if casing.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(serde_json::json!(
|
||||
[{ "case": casing }]
|
||||
))
|
||||
},
|
||||
None,
|
||||
Some(PathBuf::from(path)),
|
||||
)
|
||||
}
|
||||
|
||||
fn test_cases<const N: usize>(
|
||||
path: &'static str,
|
||||
casings: [&'static str; N],
|
||||
) -> (&'static str, Option<Value>, Option<Value>, Option<PathBuf>) {
|
||||
(
|
||||
"",
|
||||
if casings.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut map = serde_json::Map::new();
|
||||
// turn ["camelCase", "snakeCase"] into [{ "cases": { "camelCase": true, "snakeCase": true } }]
|
||||
for casing in casings {
|
||||
map.insert(casing.to_string(), Value::Bool(true));
|
||||
}
|
||||
Some(serde_json::json!([{ "cases": map }]))
|
||||
},
|
||||
None,
|
||||
Some(PathBuf::from(path)),
|
||||
)
|
||||
}
|
||||
|
||||
let pass = vec![
|
||||
// should pass - camel_case, pascal_case both allowed
|
||||
("", None, None, Some(PathBuf::from("foo/bar/baz/Que.tsx"))),
|
||||
// should pass - camel_case, pascal_case both allowed
|
||||
("", None, None, Some(PathBuf::from("foo/bar/baz/QueAbc.tsx"))),
|
||||
("", None, None, Some(PathBuf::from("ansiHTML.tsx"))),
|
||||
test_cases("src/foo/fooBar.js", ["camelCase"]),
|
||||
test_case("src/foo/bar.js", "camelCase"),
|
||||
test_case("src/foo/fooBar.js", "camelCase"),
|
||||
test_case("src/foo/bar.test.js", "camelCase"),
|
||||
test_case("src/foo/fooBar.test.js", "camelCase"),
|
||||
test_case("src/foo/fooBar.test-utils.js", "camelCase"),
|
||||
test_case("src/foo/fooBar.test_utils.js", "camelCase"),
|
||||
test_case("src/foo/.test_utils.js", "camelCase"),
|
||||
test_case("src/foo/foo.js", "snakeCase"),
|
||||
test_case("src/foo/foo_bar.js", "snakeCase"),
|
||||
test_case("src/foo/foo.test.js", "snakeCase"),
|
||||
test_case("src/foo/foo_bar.test.js", "snakeCase"),
|
||||
test_case("src/foo/foo_bar.test_utils.js", "snakeCase"),
|
||||
test_case("src/foo/foo_bar.test-utils.js", "snakeCase"),
|
||||
test_case("src/foo/.test-utils.js", "snakeCase"),
|
||||
test_case("src/foo/foo.js", "kebabCase"),
|
||||
test_case("src/foo/foo-bar.js", "kebabCase"),
|
||||
test_case("src/foo/foo.test.js", "kebabCase"),
|
||||
test_case("src/foo/foo-bar.test.js", "kebabCase"),
|
||||
test_case("src/foo/foo-bar.test-utils.js", "kebabCase"),
|
||||
test_case("src/foo/foo-bar.test_utils.js", "kebabCase"),
|
||||
test_case("src/foo/.test_utils.js", "kebabCase"),
|
||||
test_case("src/foo/Foo.js", "pascalCase"),
|
||||
test_case("src/foo/FooBar.js", "pascalCase"),
|
||||
test_case("src/foo/Foo.test.js", "pascalCase"),
|
||||
test_case("src/foo/FooBar.test.js", "pascalCase"),
|
||||
test_case("src/foo/FooBar.test-utils.js", "pascalCase"),
|
||||
test_case("src/foo/FooBar.test_utils.js", "pascalCase"),
|
||||
test_case("src/foo/.test_utils.js", "pascalCase"),
|
||||
test_case("spec/iss47Spec.js", "camelCase"),
|
||||
test_case("spec/iss47Spec100.js", "camelCase"),
|
||||
test_case("spec/i18n.js", "camelCase"),
|
||||
test_case("spec/iss47-spec.js", "kebabCase"),
|
||||
test_case("spec/iss-47-spec.js", "kebabCase"),
|
||||
test_case("spec/iss47-100spec.js", "kebabCase"),
|
||||
test_case("spec/i18n.js", "kebabCase"),
|
||||
test_case("spec/iss47_spec.js", "snakeCase"),
|
||||
test_case("spec/iss_47_spec.js", "snakeCase"),
|
||||
test_case("spec/iss47_100spec.js", "snakeCase"),
|
||||
test_case("spec/i18n.js", "snakeCase"),
|
||||
test_case("spec/Iss47Spec.js", "pascalCase"),
|
||||
test_case("spec/Iss47.100spec.js", "pascalCase"),
|
||||
test_case("spec/I18n.js", "pascalCase"),
|
||||
test_case("src/foo/_fooBar.js", "camelCase"),
|
||||
test_case("src/foo/___fooBar.js", "camelCase"),
|
||||
test_case("src/foo/_foo_bar.js", "snakeCase"),
|
||||
test_case("src/foo/___foo_bar.js", "snakeCase"),
|
||||
test_case("src/foo/_foo-bar.js", "kebabCase"),
|
||||
test_case("src/foo/___foo-bar.js", "kebabCase"),
|
||||
test_case("src/foo/_FooBar.js", "pascalCase"),
|
||||
test_case("src/foo/___FooBar.js", "pascalCase"),
|
||||
test_case("src/foo/$foo.js", "pascalCase"),
|
||||
test_cases("src/foo/foo-bar.js", []),
|
||||
test_cases("src/foo/fooBar.js", ["camelCase"]),
|
||||
test_cases("src/foo/FooBar.js", ["kebabCase", "pascalCase"]),
|
||||
test_cases("src/foo/___foo_bar.js", ["snakeCase", "pascalCase"]),
|
||||
];
|
||||
let fail = vec![
|
||||
// should pass - by default kebab_case is not allowed
|
||||
("import foo from 'bar'", None, None, Some(PathBuf::from("foo/bar/baz/aaa-bbb.tsx"))),
|
||||
// should pass - by default snake_case is not allowed
|
||||
("baz;", None, None, Some(PathBuf::from("foo/bar/baz/foo_bar.tsx"))),
|
||||
test_case("src/foo/foo_bar.js", ""),
|
||||
// todo: linter does not support uppercase JS files
|
||||
// test_case("src/foo/foo_bar.JS", "camelCase"),
|
||||
test_case("src/foo/foo_bar.test.js", "camelCase"),
|
||||
test_case("test/foo/foo_bar.test_utils.js", "camelCase"),
|
||||
test_case("test/foo/fooBar.js", "snakeCase"),
|
||||
test_case("test/foo/fooBar.test.js", "snakeCase"),
|
||||
test_case("test/foo/fooBar.testUtils.js", "snakeCase"),
|
||||
test_case("test/foo/fooBar.js", "kebabCase"),
|
||||
test_case("test/foo/fooBar.test.js", "kebabCase"),
|
||||
test_case("test/foo/fooBar.testUtils.js", "kebabCase"),
|
||||
test_case("test/foo/fooBar.js", "pascalCase"),
|
||||
test_case("test/foo/foo_bar.test.js", "pascalCase"),
|
||||
test_case("test/foo/foo-bar.test-utils.js", "pascalCase"),
|
||||
test_case("src/foo/_FOO-BAR.js", "camelCase"),
|
||||
test_case("src/foo/___FOO-BAR.js", "camelCase"),
|
||||
test_case("src/foo/_FOO-BAR.js", "snakeCase"),
|
||||
test_case("src/foo/___FOO-BAR.js", "snakeCase"),
|
||||
test_case("src/foo/_FOO-BAR.js", "kebabCase"),
|
||||
test_case("src/foo/___FOO-BAR.js", "kebabCase"),
|
||||
test_case("src/foo/_FOO-BAR.js", "pascalCase"),
|
||||
test_case("src/foo/___FOO-BAR.js", "pascalCase"),
|
||||
test_cases("src/foo/foo_bar.js", []),
|
||||
test_cases("src/foo/foo-bar.js", ["camelCase", "pascalCase"]),
|
||||
test_cases("src/foo/_foo_bar.js", ["camelCase", "pascalCase", "kebabCase"]),
|
||||
test_cases("src/foo/_FOO-BAR.js", ["snakeCase"]),
|
||||
test_case("src/foo/[foo_bar].js", ""),
|
||||
test_case("src/foo/$foo_bar.js", ""),
|
||||
test_case("src/foo/$fooBar.js", ""),
|
||||
test_cases("src/foo/{foo_bar}.js", ["camelCase", "pascalCase", "kebabCase"]),
|
||||
];
|
||||
|
||||
Tester::new(FilenameCase::NAME, pass, fail).test_and_snapshot();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,114 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
---
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should not be in kebab case
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
1 │ import foo from 'bar'
|
||||
· ▲
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should not be in snake case
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case, or pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case, kebab case, or pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in snake case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in kebab case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
╰────
|
||||
|
||||
⚠ eslint-plugin-unicorn(filename-case): Filename should be in camel case, kebab case, or pascal case
|
||||
╭─[filename_case.tsx:1:1]
|
||||
1 │ baz;
|
||||
· ▲
|
||||
╰────
|
||||
|
|
|
|||
Loading…
Reference in a new issue