diff --git a/crates/squawk_ide/src/code_actions/quote_identifier.rs b/crates/squawk_ide/src/code_actions/quote_identifier.rs index 0eec210b..8d6c8827 100644 --- a/crates/squawk_ide/src/code_actions/quote_identifier.rs +++ b/crates/squawk_ide/src/code_actions/quote_identifier.rs @@ -1,6 +1,9 @@ use rowan::TextSize; use salsa::Database as Db; -use squawk_syntax::ast::{self, AstNode}; +use squawk_syntax::{ + ast::{self, AstNode}, + quote::normalize_identifier, +}; use crate::{db::File, offsets::token_from_offset}; @@ -29,7 +32,7 @@ pub(super) fn quote_identifier( return None; } - let quoted = format!(r#""{}""#, text.to_lowercase()); + let quoted = format!(r#""{}""#, normalize_identifier(&text)); actions.push(CodeAction { title: "Quote identifier".to_owned(), @@ -57,6 +60,14 @@ mod test { ); } + #[test] + fn quote_doesnt_show_up_for_already_quoted_ident() { + assert!(code_action_not_applicable( + quote_identifier, + r#"create table T("X"$0 int);"# + )); + } + #[test] fn quote_identifier_on_name() { assert_snapshot!(apply_code_action( diff --git a/crates/squawk_ide/src/code_actions/test_utils.rs b/crates/squawk_ide/src/code_actions/test_utils.rs index e9bf5386..0a9aa707 100644 --- a/crates/squawk_ide/src/code_actions/test_utils.rs +++ b/crates/squawk_ide/src/code_actions/test_utils.rs @@ -8,6 +8,7 @@ use crate::test_utils::Fixture; use super::{ActionKind, CodeAction}; +#[must_use] pub(super) fn apply_code_action( f: impl Fn(&dyn Db, File, &mut Vec, TextSize) -> Option<()>, sql: &str, @@ -108,6 +109,7 @@ fn code_action_not_applicable_( actions.is_empty() } +#[must_use] pub(super) fn code_action_not_applicable( f: impl Fn(&dyn Db, File, &mut Vec, TextSize) -> Option<()>, sql: &str, @@ -115,6 +117,7 @@ pub(super) fn code_action_not_applicable( code_action_not_applicable_(f, sql, false) } +#[must_use] pub(super) fn code_action_not_applicable_with_errors( f: impl Fn(&dyn Db, File, &mut Vec, TextSize) -> Option<()>, sql: &str, diff --git a/crates/squawk_ide/src/completion.rs b/crates/squawk_ide/src/completion.rs index f9942917..2fd031c6 100644 --- a/crates/squawk_ide/src/completion.rs +++ b/crates/squawk_ide/src/completion.rs @@ -941,6 +941,7 @@ mod tests { use tabled::builder::Builder; use tabled::settings::Style; + #[must_use] fn completions(sql: &str) -> String { let fixture = Fixture::new(sql); let offset = fixture.marker().offset(); diff --git a/crates/squawk_ide/src/document_symbols.rs b/crates/squawk_ide/src/document_symbols.rs index 06d31c84..3e4e4f65 100644 --- a/crates/squawk_ide/src/document_symbols.rs +++ b/crates/squawk_ide/src/document_symbols.rs @@ -877,6 +877,7 @@ mod tests { } } + #[must_use] fn symbols(sql: &str) -> String { let db = Database::default(); let file = File::new(&db, sql.to_string().into()); diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 78609e9b..27275aa2 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -294,6 +294,7 @@ mod tests { use insta::assert_debug_snapshot; use squawk_syntax::{SourceFile, ast::AstNode}; + #[must_use] fn expand(sql: &str) -> Vec { let fixture = Fixture::new(sql); let offset = fixture.marker().offset(); diff --git a/crates/squawk_ide/src/find_references.rs b/crates/squawk_ide/src/find_references.rs index 3c4fe307..906df3bf 100644 --- a/crates/squawk_ide/src/find_references.rs +++ b/crates/squawk_ide/src/find_references.rs @@ -47,6 +47,7 @@ mod test { use rowan::TextRange; use rustc_hash::FxHashMap; + #[must_use] #[track_caller] fn find_refs(sql: &str) -> String { let fixture = Fixture::new(sql); diff --git a/crates/squawk_ide/src/folding_ranges.rs b/crates/squawk_ide/src/folding_ranges.rs index f1c902e6..a015a5d0 100644 --- a/crates/squawk_ide/src/folding_ranges.rs +++ b/crates/squawk_ide/src/folding_ranges.rs @@ -235,6 +235,7 @@ mod tests { } } + #[must_use] fn check(sql: &str) -> String { let db = Database::default(); let file = File::new(&db, sql.to_string().into()); diff --git a/crates/squawk_ide/src/hover.rs b/crates/squawk_ide/src/hover.rs index 25501f43..04b07a52 100644 --- a/crates/squawk_ide/src/hover.rs +++ b/crates/squawk_ide/src/hover.rs @@ -1606,6 +1606,7 @@ mod test { use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; use insta::assert_snapshot; + #[must_use] #[track_caller] fn check_hover(sql: &str) -> String { check_hover_(sql).expect("should find hover information") @@ -1641,6 +1642,7 @@ mod test { None } + #[must_use] #[track_caller] fn check_hover_info(sql: &str) -> super::Hover { let db = Database::default(); diff --git a/crates/squawk_ide/src/infer.rs b/crates/squawk_ide/src/infer.rs index 61a2c5e4..4478a1aa 100644 --- a/crates/squawk_ide/src/infer.rs +++ b/crates/squawk_ide/src/infer.rs @@ -85,6 +85,7 @@ mod tests { use super::*; use insta::assert_snapshot; + #[must_use] fn infer(sql: &str) -> String { let parse = ast::SourceFile::parse(sql); for stmt in parse.tree().stmts() { diff --git a/crates/squawk_ide/src/inlay_hints.rs b/crates/squawk_ide/src/inlay_hints.rs index 90b4e98c..f7bfe96f 100644 --- a/crates/squawk_ide/src/inlay_hints.rs +++ b/crates/squawk_ide/src/inlay_hints.rs @@ -191,6 +191,7 @@ mod test { use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; use insta::assert_snapshot; + #[must_use] #[track_caller] fn check_inlay_hints(sql: &str) -> String { let db = Database::default(); diff --git a/crates/squawk_ide/src/semantic_tokens.rs b/crates/squawk_ide/src/semantic_tokens.rs index 600860bd..f38ef626 100644 --- a/crates/squawk_ide/src/semantic_tokens.rs +++ b/crates/squawk_ide/src/semantic_tokens.rs @@ -354,6 +354,7 @@ mod test { use insta::assert_snapshot; use std::fmt::Write; + #[must_use] fn semantic_tokens(sql: &str) -> String { let db = Database::default(); let file = File::new(&db, sql.to_string().into()); diff --git a/crates/squawk_linter/src/rules/adding_field_with_default.rs b/crates/squawk_linter/src/rules/adding_field_with_default.rs index 61404f05..0d112393 100644 --- a/crates/squawk_linter/src/rules/adding_field_with_default.rs +++ b/crates/squawk_linter/src/rules/adding_field_with_default.rs @@ -130,6 +130,7 @@ mod test { use crate::test_utils::{lint_errors, lint_ok}; use crate::{LinterSettings, Rule}; + #[must_use] fn lint_errors_with(sql: &str, settings: LinterSettings) -> String { crate::test_utils::lint_errors_with(sql, settings, Rule::AddingFieldWithDefault) } diff --git a/crates/squawk_linter/src/rules/ban_char_field.rs b/crates/squawk_linter/src/rules/ban_char_field.rs index d8435959..f36ef7e1 100644 --- a/crates/squawk_linter/src/rules/ban_char_field.rs +++ b/crates/squawk_linter/src/rules/ban_char_field.rs @@ -100,6 +100,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::BanCharField) } diff --git a/crates/squawk_linter/src/rules/ban_concurrent_index_creation_in_transaction.rs b/crates/squawk_linter/src/rules/ban_concurrent_index_creation_in_transaction.rs index 164e2bda..bd3ad2d6 100644 --- a/crates/squawk_linter/src/rules/ban_concurrent_index_creation_in_transaction.rs +++ b/crates/squawk_linter/src/rules/ban_concurrent_index_creation_in_transaction.rs @@ -55,6 +55,7 @@ mod test { ); } + #[must_use] fn lint_errors_with(sql: &str, settings: LinterSettings) -> String { crate::test_utils::lint_errors_with( sql, diff --git a/crates/squawk_linter/src/rules/constraint_missing_not_valid.rs b/crates/squawk_linter/src/rules/constraint_missing_not_valid.rs index b297d7e0..03c0f8ed 100644 --- a/crates/squawk_linter/src/rules/constraint_missing_not_valid.rs +++ b/crates/squawk_linter/src/rules/constraint_missing_not_valid.rs @@ -156,6 +156,7 @@ mod test { crate::test_utils::lint_ok_with(sql, settings, Rule::ConstraintMissingNotValid); } + #[must_use] fn lint_errors_with(sql: &str, settings: LinterSettings) -> String { crate::test_utils::lint_errors_with(sql, settings, Rule::ConstraintMissingNotValid) } diff --git a/crates/squawk_linter/src/rules/prefer_bigint_over_int.rs b/crates/squawk_linter/src/rules/prefer_bigint_over_int.rs index dc07c26c..253fedbe 100644 --- a/crates/squawk_linter/src/rules/prefer_bigint_over_int.rs +++ b/crates/squawk_linter/src/rules/prefer_bigint_over_int.rs @@ -1,6 +1,7 @@ use rustc_hash::FxHashSet; use squawk_syntax::ast::AstNode; +use squawk_syntax::quote::normalize_identifier; use squawk_syntax::{Parse, SourceFile, ast, identifier::Identifier}; use crate::{Edit, Fix, Linter, Rule, Violation}; @@ -24,7 +25,7 @@ fn int_types() -> &'static FxHashSet { } fn int_to_bigint_replacement(int_type: &str) -> &'static str { - match int_type.to_lowercase().as_str() { + match normalize_identifier(int_type).as_str() { "int" | "integer" => "bigint", "int4" => "int8", "serial" => "bigserial", @@ -76,6 +77,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::PreferBigintOverInt) } diff --git a/crates/squawk_linter/src/rules/prefer_bigint_over_smallint.rs b/crates/squawk_linter/src/rules/prefer_bigint_over_smallint.rs index 9791bf97..696cd633 100644 --- a/crates/squawk_linter/src/rules/prefer_bigint_over_smallint.rs +++ b/crates/squawk_linter/src/rules/prefer_bigint_over_smallint.rs @@ -1,6 +1,7 @@ use rustc_hash::FxHashSet; use squawk_syntax::ast::AstNode; +use squawk_syntax::quote::normalize_identifier; use squawk_syntax::{Parse, SourceFile, ast, identifier::Identifier}; use crate::{Edit, Fix, Linter, Rule, Violation}; @@ -23,7 +24,7 @@ fn small_int_types() -> &'static FxHashSet { } fn smallint_to_bigint(smallint_type: &str) -> &'static str { - match smallint_type.to_lowercase().as_str() { + match normalize_identifier(smallint_type).as_str() { "smallint" => "bigint", "int2" => "int8", "smallserial" => "bigserial", @@ -74,6 +75,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::PreferBigintOverSmallint) } diff --git a/crates/squawk_linter/src/rules/prefer_identity.rs b/crates/squawk_linter/src/rules/prefer_identity.rs index 78173485..1a2797bc 100644 --- a/crates/squawk_linter/src/rules/prefer_identity.rs +++ b/crates/squawk_linter/src/rules/prefer_identity.rs @@ -4,6 +4,7 @@ use squawk_syntax::{ Parse, SourceFile, ast::{self, AstNode}, identifier::Identifier, + quote::normalize_identifier, }; use crate::{Edit, Fix, Linter, Rule, Violation}; @@ -27,7 +28,7 @@ fn serial_types() -> &'static FxHashSet { } fn replace_serial(serial_type: &str) -> &'static str { - match serial_type.to_lowercase().as_str() { + match normalize_identifier(serial_type).as_str() { "serial" | "serial4" => "integer generated by default as identity", "serial2" | "smallserial" => "smallint generated by default as identity", "serial8" | "bigserial" => "bigint generated by default as identity", @@ -75,6 +76,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::PreferIdentity) } diff --git a/crates/squawk_linter/src/rules/prefer_repack.rs b/crates/squawk_linter/src/rules/prefer_repack.rs index d78b6e36..9e1989a9 100644 --- a/crates/squawk_linter/src/rules/prefer_repack.rs +++ b/crates/squawk_linter/src/rules/prefer_repack.rs @@ -196,6 +196,7 @@ mod test { lint_ok_with(sql, pg19(), Rule::PreferRepack); } + #[must_use] fn fix(sql: &str) -> String { fix_sql_with(sql, pg19(), Rule::PreferRepack) } diff --git a/crates/squawk_linter/src/rules/prefer_robust_stmts.rs b/crates/squawk_linter/src/rules/prefer_robust_stmts.rs index 745ece0b..bc30f8eb 100644 --- a/crates/squawk_linter/src/rules/prefer_robust_stmts.rs +++ b/crates/squawk_linter/src/rules/prefer_robust_stmts.rs @@ -226,10 +226,12 @@ mod test { use crate::{LinterSettings, Rule}; + #[must_use] fn fix(sql: &str) -> String { crate::test_utils::fix_sql(sql, Rule::PreferRobustStmts) } + #[must_use] fn lint_errors(sql: &str) -> String { crate::test_utils::lint_errors(sql, Rule::PreferRobustStmts) } diff --git a/crates/squawk_linter/src/rules/prefer_text_field.rs b/crates/squawk_linter/src/rules/prefer_text_field.rs index 6139fe18..95bcc88a 100644 --- a/crates/squawk_linter/src/rules/prefer_text_field.rs +++ b/crates/squawk_linter/src/rules/prefer_text_field.rs @@ -92,6 +92,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::PreferTextField) } diff --git a/crates/squawk_linter/src/rules/prefer_timestamptz.rs b/crates/squawk_linter/src/rules/prefer_timestamptz.rs index b974dbe4..8b7c03f8 100644 --- a/crates/squawk_linter/src/rules/prefer_timestamptz.rs +++ b/crates/squawk_linter/src/rules/prefer_timestamptz.rs @@ -89,6 +89,7 @@ mod test { use crate::Rule; use crate::test_utils::{fix_sql, lint_errors, lint_ok}; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::PreferTimestampTz) } diff --git a/crates/squawk_linter/src/rules/require_concurrent_index_creation.rs b/crates/squawk_linter/src/rules/require_concurrent_index_creation.rs index 8dffd8cd..4178f600 100644 --- a/crates/squawk_linter/src/rules/require_concurrent_index_creation.rs +++ b/crates/squawk_linter/src/rules/require_concurrent_index_creation.rs @@ -57,6 +57,7 @@ mod test { crate::test_utils::lint_ok_with(sql, settings, Rule::RequireConcurrentIndexCreation); } + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::RequireConcurrentIndexCreation) } diff --git a/crates/squawk_linter/src/rules/require_concurrent_index_deletion.rs b/crates/squawk_linter/src/rules/require_concurrent_index_deletion.rs index e48e65c8..caeb69f7 100644 --- a/crates/squawk_linter/src/rules/require_concurrent_index_deletion.rs +++ b/crates/squawk_linter/src/rules/require_concurrent_index_deletion.rs @@ -38,6 +38,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::RequireConcurrentIndexDeletion) } diff --git a/crates/squawk_linter/src/rules/require_concurrent_partition_detach.rs b/crates/squawk_linter/src/rules/require_concurrent_partition_detach.rs index 08fa3472..03f0962e 100644 --- a/crates/squawk_linter/src/rules/require_concurrent_partition_detach.rs +++ b/crates/squawk_linter/src/rules/require_concurrent_partition_detach.rs @@ -46,6 +46,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::RequireConcurrentPartitionDetach) } diff --git a/crates/squawk_linter/src/rules/require_concurrent_reindex.rs b/crates/squawk_linter/src/rules/require_concurrent_reindex.rs index cb35eafe..2aa73148 100644 --- a/crates/squawk_linter/src/rules/require_concurrent_reindex.rs +++ b/crates/squawk_linter/src/rules/require_concurrent_reindex.rs @@ -49,6 +49,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::RequireConcurrentReindex) } diff --git a/crates/squawk_linter/src/rules/require_timeout_settings.rs b/crates/squawk_linter/src/rules/require_timeout_settings.rs index 0ae122d4..af5c2949 100644 --- a/crates/squawk_linter/src/rules/require_timeout_settings.rs +++ b/crates/squawk_linter/src/rules/require_timeout_settings.rs @@ -113,6 +113,7 @@ mod test { test_utils::{fix_sql, lint_errors, lint_ok}, }; + #[must_use] fn fix(sql: &str) -> String { fix_sql(sql, Rule::RequireTimeoutSettings) } diff --git a/crates/squawk_linter/src/rules/snapshots/squawk_linter__rules__prefer_identity__test__ok_when_quoted.snap b/crates/squawk_linter/src/rules/snapshots/squawk_linter__rules__prefer_identity__test__ok_when_quoted.snap index a47e65d8..5ccc8598 100644 --- a/crates/squawk_linter/src/rules/snapshots/squawk_linter__rules__prefer_identity__test__ok_when_quoted.snap +++ b/crates/squawk_linter/src/rules/snapshots/squawk_linter__rules__prefer_identity__test__ok_when_quoted.snap @@ -20,5 +20,5 @@ warning[prefer-identity]: Serial types make schema, dependency, and permission m ├ help: Use an `IDENTITY` column instead. ╭╴ 6 - id "bigserial" -6 + id integer generated by default as identity +6 + id bigint generated by default as identity ╰╴ diff --git a/crates/squawk_linter/src/rules/transaction_nesting.rs b/crates/squawk_linter/src/rules/transaction_nesting.rs index 52240f04..a9b6f36c 100644 --- a/crates/squawk_linter/src/rules/transaction_nesting.rs +++ b/crates/squawk_linter/src/rules/transaction_nesting.rs @@ -60,6 +60,7 @@ mod test { use crate::test_utils::{lint_errors, lint_ok}; use crate::{LinterSettings, Rule}; + #[must_use] fn lint_errors_with(sql: &str, settings: LinterSettings) -> String { crate::test_utils::lint_errors_with(sql, settings, Rule::TransactionNesting) } diff --git a/crates/squawk_linter/src/test_utils.rs b/crates/squawk_linter/src/test_utils.rs index 4e520917..2d4d6165 100644 --- a/crates/squawk_linter/src/test_utils.rs +++ b/crates/squawk_linter/src/test_utils.rs @@ -54,6 +54,7 @@ pub(crate) fn lint_errors_with(sql: &str, settings: LinterSettings, rule: Rule) format_violations(sql, &errors) } +#[must_use] pub(crate) fn fix_sql_with(sql: &str, settings: LinterSettings, rule: Rule) -> String { let errors = lint_settings(sql, settings.clone(), rule); assert!(!errors.is_empty(), "Should start with linter errors"); @@ -91,6 +92,7 @@ pub(crate) fn fix_sql_with(sql: &str, settings: LinterSettings, rule: Rule) -> S result } +#[must_use] pub(crate) fn fix_sql(sql: &str, rule: Rule) -> String { fix_sql_with(sql, LinterSettings::default(), rule) } diff --git a/crates/squawk_parser/tests/tests.rs b/crates/squawk_parser/tests/tests.rs index d0ac60a8..0f62cb09 100644 --- a/crates/squawk_parser/tests/tests.rs +++ b/crates/squawk_parser/tests/tests.rs @@ -109,6 +109,7 @@ fn regression_suite(fixture: Fixture<&str>) { } } +#[must_use] fn parse_text(text: &str) -> (String, Option) { let lexed = LexedStr::new(text); let input = lexed.to_input(); diff --git a/crates/squawk_syntax/src/identifier.rs b/crates/squawk_syntax/src/identifier.rs index 0c3cd6fa..440d2c4b 100644 --- a/crates/squawk_syntax/src/identifier.rs +++ b/crates/squawk_syntax/src/identifier.rs @@ -1,3 +1,5 @@ +use crate::quote::normalize_identifier; + /// Postgres Identifiers are case insensitive unless they're quoted. /// /// This type handles the casing rules for us to make comparisions easier. @@ -8,11 +10,7 @@ impl Identifier { // TODO: we need to handle more advanced identifiers like: // U&"d!0061t!+000061" UESCAPE '!' pub fn new(s: &str) -> Self { - let normalized = if s.starts_with('"') && s.ends_with('"') { - s[1..s.len() - 1].to_string() - } else { - s.to_lowercase() - }; + let normalized = normalize_identifier(s); Identifier(normalized) } } diff --git a/crates/squawk_syntax/src/quote.rs b/crates/squawk_syntax/src/quote.rs index 0b2944ab..0d099e63 100644 --- a/crates/squawk_syntax/src/quote.rs +++ b/crates/squawk_syntax/src/quote.rs @@ -72,7 +72,7 @@ fn needs_quoting(text: &str) -> bool { pub fn is_reserved_word(text: &str) -> bool { RESERVED_KEYWORDS - .binary_search(&text.to_lowercase().as_str()) + .binary_search(&text.to_ascii_lowercase().as_str()) .is_ok() } diff --git a/crates/xtask/src/codegen.rs b/crates/xtask/src/codegen.rs index 6a3e3a97..6d043975 100644 --- a/crates/xtask/src/codegen.rs +++ b/crates/xtask/src/codegen.rs @@ -236,7 +236,7 @@ const PRELUDE: &str = "\ fn generate_reserved_keywords_array(reserved_keywords: &[String]) -> Result { let mut reserved_keywords = reserved_keywords .iter() - .map(|x| x.to_lowercase()) + .map(|x| x.to_ascii_lowercase()) .collect::>(); reserved_keywords.sort(); @@ -986,7 +986,10 @@ fn operator_match() -> String { } fn keywords_match(all_keywords: &[String]) -> String { - let mut keywords: Vec = all_keywords.iter().map(|k| k.to_lowercase()).collect(); + let mut keywords: Vec = all_keywords + .iter() + .map(|k| k.to_ascii_lowercase()) + .collect(); keywords.sort(); let keywords_joined = keywords.join("|"); format!("(?xi)\\b({keywords_joined})\\b") diff --git a/crates/xtask/src/new_rule.rs b/crates/xtask/src/new_rule.rs index b5b6f79d..d1f2ad96 100644 --- a/crates/xtask/src/new_rule.rs +++ b/crates/xtask/src/new_rule.rs @@ -21,12 +21,14 @@ pub(crate) fn {rule_name_snake}(ctx: &mut Linter, parse: &Parse) {{ match stmt {{ // TODO: update to the stmt you want to check ast::Stmt::CreateTable(create_table) => {{ - ctx.report(Violation::for_node( - Rule::{rule_name_pascal}, - "todo".to_string(), - create_table.syntax(), - "todo or none".to_string(), - )); + ctx.report( + Violation::for_node( + Rule::{rule_name_pascal}, + "todo".to_string(), + create_table.syntax(), + ) + .help("todo or none"), + ); todo!(); }} _ => (), @@ -36,21 +38,21 @@ pub(crate) fn {rule_name_snake}(ctx: &mut Linter, parse: &Parse) {{ #[cfg(test)] mod test {{ - use insta::assert_debug_snapshot; + use insta::assert_snapshot; - use crate::{{Linter, Rule}}; - use squawk_syntax::SourceFile; + use crate::{{ + Rule, + test_utils::{{lint_errors, lint_ok}}, + }}; #[test] fn err() {{ let sql = r#" -- TODO: err sql "#; - let file = SourceFile::parse(sql); - let mut linter = Linter::from([Rule::{rule_name_pascal}]); - let errors = linter.lint(file, sql); - assert_ne!(errors.len(), 0); - assert_debug_snapshot!(errors); + assert_snapshot!(lint_errors(sql, Rule::{rule_name_pascal}), @r" +TODO +"); }} #[test] @@ -58,10 +60,7 @@ mod test {{ let sql = r#" -- TODO: ok sql "#; - let file = SourceFile::parse(sql); - let mut linter = Linter::from([Rule::{rule_name_pascal}]); - let errors = linter.lint(file, sql); - assert_eq!(errors.len(), 0); + lint_ok(sql, Rule::{rule_name_pascal}); }} }} "### diff --git a/crates/xtask/src/sync_pg.rs b/crates/xtask/src/sync_pg.rs index 58b9d599..3657b2db 100644 --- a/crates/xtask/src/sync_pg.rs +++ b/crates/xtask/src/sync_pg.rs @@ -304,7 +304,7 @@ pub(crate) fn preprocess_sql(source: R, mut dest: W) -> Re } } - let line_lower = line.to_lowercase(); + let line_lower = line.to_ascii_lowercase(); if (line_lower.starts_with("copy ") || line_lower.starts_with("\\copy")) && (line_lower.contains("from stdin") || line_lower.contains("from stdout")) {