From 6b130b6f5e4ee4689f4c04e0aa55e3062f5ff927 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Fri, 15 May 2026 20:08:41 -0400 Subject: [PATCH] ide: improve test runtime by skipping builtins most of the time --- .../squawk_ide/src/code_actions/test_utils.rs | 7 ++-- crates/squawk_ide/src/completion.rs | 7 ++-- crates/squawk_ide/src/db.rs | 38 +++++++++++++++++-- crates/squawk_ide/src/expand_selection.rs | 6 +-- crates/squawk_ide/src/find_references.rs | 13 ++++--- crates/squawk_ide/src/goto_definition.rs | 26 +++++++------ crates/squawk_ide/src/hover.rs | 33 ++++++++-------- crates/squawk_ide/src/test_utils.rs | 28 ++++++++------ 8 files changed, 102 insertions(+), 56 deletions(-) diff --git a/crates/squawk_ide/src/code_actions/test_utils.rs b/crates/squawk_ide/src/code_actions/test_utils.rs index 5007102d..1483e22d 100644 --- a/crates/squawk_ide/src/code_actions/test_utils.rs +++ b/crates/squawk_ide/src/code_actions/test_utils.rs @@ -36,10 +36,10 @@ fn apply_code_action_( }; let offset = fixture.marker().offset_before(); let db = fixture.db(); - let file = fixture.file(); + let file = offset.file_id; let mut actions = vec![]; - f(db, InFile::new(file, offset), &mut actions); + f(db, offset, &mut actions); assert!( !actions.is_empty(), @@ -110,10 +110,9 @@ fn code_action_not_applicable_( }; let offset = fixture.marker().offset_before(); let db = fixture.db(); - let file = fixture.file(); let mut actions = vec![]; - f(db, InFile::new(file, offset), &mut actions); + f(db, offset, &mut actions); actions.is_empty() } diff --git a/crates/squawk_ide/src/completion.rs b/crates/squawk_ide/src/completion.rs index 2ed08702..ca19ba98 100644 --- a/crates/squawk_ide/src/completion.rs +++ b/crates/squawk_ide/src/completion.rs @@ -939,7 +939,7 @@ pub struct CompletionItem { #[cfg(test)] mod tests { use super::completion; - use crate::file::InFile; + use crate::test_utils::Fixture; use insta::assert_snapshot; use tabled::builder::Builder; @@ -949,7 +949,7 @@ mod tests { fn completions(sql: &str) -> String { let fixture = Fixture::new_allow_errors(sql); let offset = fixture.marker().offset(); - let items = completion(fixture.db(), InFile::new(fixture.file(), offset)); + let items = completion(fixture.db(), offset); assert!( !items.is_empty(), "No completions found. If this was intended, use `completions_not_found` instead." @@ -960,7 +960,7 @@ mod tests { fn completions_not_found(sql: &str) { let fixture = Fixture::new_allow_errors(sql); let offset = fixture.marker().offset(); - let items = completion(fixture.db(), InFile::new(fixture.file(), offset)); + let items = completion(fixture.db(), offset); assert_eq!( items, vec![], @@ -1143,6 +1143,7 @@ select $0 from t; #[test] fn completion_after_select_create_table_inherits_builtin() { assert_snapshot!(completions(" +-- include-builtins create table t () inherits (information_schema.sql_features); select $0 from t; diff --git a/crates/squawk_ide/src/db.rs b/crates/squawk_ide/src/db.rs index 3ae21645..0b99aa2a 100644 --- a/crates/squawk_ide/src/db.rs +++ b/crates/squawk_ide/src/db.rs @@ -1,5 +1,7 @@ use ::line_index::LineIndex; use salsa::Database as Db; +#[cfg(test)] +use salsa::Setter; use salsa::Storage; use squawk_syntax::{Parse, SourceFile}; use std::sync::Arc; @@ -26,20 +28,50 @@ pub fn line_index(db: &dyn Db, file: File) -> LineIndex { #[inline] pub(crate) fn list_files(db: &dyn Db, file: File) -> impl Iterator { - [file, builtins_file(db)].into_iter() + [Some(file), include_builtins(db).then(|| builtins_file(db))] + .into_iter() + .flatten() } #[salsa::tracked] -pub fn bind(db: &dyn Db, file: File) -> Binder { +pub(crate) fn bind(db: &dyn Db, file: File) -> Binder { let result = parse(db, file); let source_file = result.tree(); binder::bind(&source_file) } +#[salsa::input(singleton)] +pub(crate) struct Config { + // currently only used for improve test runtime by skipping builtins + pub(crate) include_builtins: bool, +} + +#[salsa::tracked] +pub(crate) fn include_builtins(db: &dyn Db) -> bool { + Config::get(db).include_builtins(db) +} + #[salsa::db] -#[derive(Clone, Default)] +#[derive(Clone)] pub struct Database { storage: Storage, } +impl Default for Database { + fn default() -> Self { + let db = Self { + storage: Storage::default(), + }; + Config::new(&db, true); + db + } +} + +#[cfg(test)] +pub(crate) fn set_include_builtins(db: &mut dyn Db, include_builtins: bool) { + Config::get(db) + .set_include_builtins(db) + .to(include_builtins); +} + impl salsa::Database for Database {} diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 27e72ced..152c00e2 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -298,11 +298,11 @@ mod tests { fn expand(sql: &str) -> Vec { let fixture = Fixture::new(sql); let offset = fixture.marker().offset(); - let sql = fixture.file().content(fixture.db()).clone(); - let tree = crate::db::parse(fixture.db(), fixture.file()).tree(); + let sql = offset.file_id.content(fixture.db()).clone(); + let tree = crate::db::parse(fixture.db(), offset.file_id).tree(); let root = tree.syntax(); - let mut range = TextRange::empty(offset); + let mut range = TextRange::empty(offset.value); let mut results = vec![]; for _ in 0..20 { diff --git a/crates/squawk_ide/src/find_references.rs b/crates/squawk_ide/src/find_references.rs index 6774de1f..24dfa4c1 100644 --- a/crates/squawk_ide/src/find_references.rs +++ b/crates/squawk_ide/src/find_references.rs @@ -41,7 +41,7 @@ pub fn find_references(db: &dyn Db, position: InFile) -> Vec mod test { use crate::builtins::builtins_file; use crate::db::File; - use crate::file::InFile; + use crate::find_references::find_references; use crate::test_utils::Fixture; use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; @@ -57,9 +57,9 @@ mod test { let offset = marker.offset_before(); let query_span = marker.range(); let db = fixture.db(); - let current_file = fixture.file(); + let current_file = offset.file_id; - let references = find_references(db, InFile::new(current_file, offset)); + let references = find_references(db, offset); let mut file_paths = FxHashMap::default(); file_paths.insert(current_file, "current.sql"); @@ -380,17 +380,18 @@ drop table foo_bar; #[test] fn builtin_function_references() { assert_snapshot!(find_refs(" +-- include-builtins select now$0(); select now(); "), @" - ╭▸ current.sql:2:8 + ╭▸ current.sql:3:8 │ - 2 │ select now(); + 3 │ select now(); │ ┬─┬ │ │ │ │ │ 0. query │ 1. reference - 3 │ select now(); + 4 │ select now(); │ ─── 2. reference ╰╴ diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index aea4cfc6..736ab634 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -135,7 +135,7 @@ fn find_following_commit_or_rollback(db: &dyn Db, position: InFile) -> mod test { use crate::builtins::builtins_file; use crate::db::File; - use crate::file::InFile; + use crate::goto_definition::goto_definition; use crate::test_utils::Fixture; use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; @@ -158,9 +158,9 @@ mod test { let offset = marker.offset_before(); let source_span = marker.range(); let db = fixture.db(); - let current_file = fixture.file(); + let current_file = offset.file_id; - let results = goto_definition(db, InFile::new(current_file, offset)); + let results = goto_definition(db, offset); if results.is_empty() { return None; } @@ -866,11 +866,12 @@ alter policy p on t #[test] fn goto_builtin_now() { assert_snapshot!(goto(" +-- include-builtins select now$0(); "), @" - ╭▸ current.sql:2:10 + ╭▸ current.sql:3:10 │ - 2 │ select now(); + 3 │ select now(); │ ─ 1. source ╰╴ @@ -884,11 +885,12 @@ select now$0(); #[test] fn goto_current_timestamp() { assert_snapshot!(goto(" +-- include-builtins select current_timestamp$0; "), @" - ╭▸ current.sql:2:24 + ╭▸ current.sql:3:24 │ - 2 │ select current_timestamp; + 3 │ select current_timestamp; │ ─ 1. source ╰╴ @@ -1010,12 +1012,13 @@ select current_timestamp$0 from t; #[test] fn goto_current_timestamp_in_where() { assert_snapshot!(goto(" +-- include-builtins create table t(created_at timestamptz); select * from t where current_timestamp$0 > t.created_at; "), @" - ╭▸ current.sql:3:39 + ╭▸ current.sql:4:39 │ - 3 │ select * from t where current_timestamp > t.created_at; + 4 │ select * from t where current_timestamp > t.created_at; │ ─ 1. source ╰╴ @@ -2162,13 +2165,14 @@ inherits (foo.bar, bar$0, buzz); #[test] fn goto_create_table_inherits_builtin() { assert_snapshot!(goto(" +-- include-builtins create table t () inherits (information_schema.sql_features); select feature_name$0 from t; "), @" - ╭▸ current.sql:4:19 + ╭▸ current.sql:5:19 │ - 4 │ select feature_name from t; + 5 │ select feature_name from t; │ ─ 1. source ╰╴ diff --git a/crates/squawk_ide/src/hover.rs b/crates/squawk_ide/src/hover.rs index bc318783..a425fb1e 100644 --- a/crates/squawk_ide/src/hover.rs +++ b/crates/squawk_ide/src/hover.rs @@ -1638,7 +1638,7 @@ fn unqualified_star_in_arg_list_ptrs( #[cfg(test)] mod test { - use crate::file::InFile; + use crate::hover::hover; use crate::test_utils::Fixture; use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; @@ -1655,16 +1655,13 @@ mod test { let fixture = Fixture::new(sql); let marker = fixture.marker(); let offset = marker.offset_before(); - let hover_span = marker.range(); let db = fixture.db(); - let file = fixture.file(); - - if let Some(type_info) = hover(db, InFile::new(file, offset)) { + if let Some(type_info) = hover(db, offset) { let title = format!("hover: {}", type_info.snippet); let group = Level::INFO.primary_title(&title).element( - Snippet::source(file.content(db).as_ref()) + Snippet::source(offset.file_id.content(db).as_ref()) .fold(true) - .annotation(AnnotationKind::Context.span(hover_span).label("hover")), + .annotation(AnnotationKind::Context.span(marker.range()).label("hover")), ); let renderer = Renderer::plain().decor_style(DecorStyle::Unicode); return Some( @@ -1684,8 +1681,7 @@ mod test { let fixture = Fixture::new(sql); let offset = fixture.marker().offset_before(); - hover(fixture.db(), InFile::new(fixture.file(), offset)) - .expect("should find hover information") + hover(fixture.db(), offset).expect("should find hover information") } #[test] @@ -2571,11 +2567,12 @@ select add$0(1, 2); #[test] fn hover_on_builtin_function_call() { assert_snapshot!(check_hover(" +-- include-builtins select now$0(); -"), @r" +"), @" hover: function pg_catalog.now() returns timestamp with time zone ╭▸ - 2 │ select now(); + 3 │ select now(); ╰╴ ─ hover "); } @@ -3495,6 +3492,7 @@ select *$0 from t u(x, y); #[test] fn hover_on_cte_table_alias_with_partial_column_list_star_from_information_schema() { assert_snapshot!(check_hover(" +-- include-builtins with t as (select * from information_schema.sql_features) select *$0 from t u(x); "), @" @@ -3506,7 +3504,7 @@ select *$0 from t u(x); column u.is_verified_by character_data column u.comments character_data ╭▸ - 3 │ select * from t u(x); + 4 │ select * from t u(x); ╰╴ ─ hover "); } @@ -3514,6 +3512,7 @@ select *$0 from t u(x); #[test] fn hover_cte_builtin_information_schema() { assert_snapshot!(check_hover(" +-- include-builtins with t as (select * from information_schema.sql_features) select *$0 from t; "), @" @@ -3525,7 +3524,7 @@ select *$0 from t; column t.is_verified_by character_data column t.comments character_data ╭▸ - 3 │ select * from t; + 4 │ select * from t; ╰╴ ─ hover "); } @@ -3606,6 +3605,7 @@ select *$0 from (table t); #[test] fn hover_on_star_from_information_schema_table() { assert_snapshot!(check_hover(" +-- include-builtins select *$0 from information_schema.sql_features; "), @" hover: column information_schema.sql_features.feature_id character_data @@ -3616,7 +3616,7 @@ select *$0 from information_schema.sql_features; column information_schema.sql_features.is_verified_by character_data column information_schema.sql_features.comments character_data ╭▸ - 2 │ select * from information_schema.sql_features; + 3 │ select * from information_schema.sql_features; ╰╴ ─ hover "); } @@ -4891,6 +4891,7 @@ select *$0 from u; #[test] fn hover_create_table_inherits_builtin_star() { assert_snapshot!(check_hover_info(" +-- include-builtins create table t () inherits (information_schema.sql_features); select *$0 from t; @@ -4908,6 +4909,7 @@ select *$0 from t; #[test] fn hover_create_table_like_builtin_star() { assert_snapshot!(check_hover_info(" +-- include-builtins create table t (like information_schema.sql_features); select *$0 from t; ").snippet, @" @@ -4979,13 +4981,14 @@ select a$0 from u; #[test] fn hover_create_table_inherits_builtin_column() { assert_snapshot!(check_hover(" +-- include-builtins create table t () inherits (information_schema.sql_features); select feature_name$0 from t; "), @" hover: column information_schema.sql_features.feature_name information_schema.character_data ╭▸ - 4 │ select feature_name from t; + 5 │ select feature_name from t; ╰╴ ─ hover "); } diff --git a/crates/squawk_ide/src/test_utils.rs b/crates/squawk_ide/src/test_utils.rs index 47bb2040..3373f9e0 100644 --- a/crates/squawk_ide/src/test_utils.rs +++ b/crates/squawk_ide/src/test_utils.rs @@ -1,6 +1,7 @@ use std::ops::Range; -use crate::db::{Database, File}; +use crate::db::{Database, File, set_include_builtins}; +use crate::file::InFile; use rowan::TextSize; // TODO: we should probably use something else since `$0` is valid syntax, maybe `%0`? @@ -14,6 +15,7 @@ pub(crate) struct Fixture { } pub(crate) struct Marker { + file: File, offset: TextSize, offset_before: TextSize, range: Range, @@ -31,7 +33,10 @@ impl Fixture { pub(crate) fn new_allow_errors(sql: &str) -> Self { if let Some(pos) = sql.find(MARKER) { let sql = sql.replace(MARKER, ""); - let db = Database::default(); + let mut db = Database::default(); + if !sql.trim_start().starts_with("-- include-builtins") { + set_include_builtins(&mut db, false); + } let file = File::new(&db, sql.as_str().into()); return Self { marker_offset: TextSize::new(pos as u32), @@ -46,6 +51,7 @@ impl Fixture { pub(crate) fn marker(&self) -> Marker { let offset_before = self.offset_before_marker(); Marker { + file: self.file, offset: self.marker_offset, offset_before, range: self.char_span_at(offset_before), @@ -75,18 +81,15 @@ impl Fixture { pub(crate) fn db(&self) -> &Database { &self.db } - pub(crate) fn file(&self) -> File { - self.file - } } impl Marker { - pub(crate) fn offset(&self) -> TextSize { - self.offset + pub(crate) fn offset(&self) -> InFile { + InFile::new(self.file, self.offset) } - pub(crate) fn offset_before(&self) -> TextSize { - self.offset_before + pub(crate) fn offset_before(&self) -> InFile { + InFile::new(self.file, self.offset_before) } pub(crate) fn range(&self) -> Range { @@ -103,8 +106,11 @@ mod tests { let fixture = Fixture::new("select 🦀$0"); let marker = fixture.marker(); - assert_eq!(usize::from(marker.offset()), "select 🦀".len()); - assert_eq!(marker.offset_before(), ("select ".len() as u32).into()); + assert_eq!(usize::from(marker.offset().value), "select 🦀".len()); + assert_eq!( + marker.offset_before().value, + ("select ".len() as u32).into() + ); assert_eq!(marker.range(), "select ".len().."select 🦀".len()); } }