style: format the whole tree with cargo fmt (stock defaults, #35)
One-time, mechanical reformat — no functional changes. The tree was not rustfmt-clean (~1800 hunks across ~100 files); this brings it to stock `cargo fmt` defaults so a `cargo fmt --check` CI gate can follow. Behaviour-preserving: 2509 pass / 0 fail / 1 ignored (unchanged baseline), clippy clean. A .git-blame-ignore-revs entry follows so `git blame` skips this commit.
This commit is contained in:
+139
-143
@@ -25,9 +25,9 @@
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
|
||||
use crate::dsl::parser::{parse_command_with_schema, parse_command_with_schema_in_mode};
|
||||
use crate::mode::Mode;
|
||||
use crate::dsl::walker;
|
||||
use crate::dsl::{ParseError, parse_command};
|
||||
use crate::mode::Mode;
|
||||
use crate::theme::Theme;
|
||||
|
||||
/// A run of text with its byte range in the source and the
|
||||
@@ -85,7 +85,16 @@ pub fn render_input_runs_in_mode(
|
||||
mode: Mode,
|
||||
) -> Vec<StyledRun> {
|
||||
// Identity feedback view — highlight/overlay the whole input.
|
||||
render_input_runs_feedback(input, cursor_byte, theme, cache, mode, input, cursor_byte, 0)
|
||||
render_input_runs_feedback(
|
||||
input,
|
||||
cursor_byte,
|
||||
theme,
|
||||
cache,
|
||||
mode,
|
||||
input,
|
||||
cursor_byte,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
/// [`render_input_runs_in_mode`] with a separate **feedback view** for
|
||||
@@ -121,12 +130,14 @@ pub fn render_input_runs_feedback(
|
||||
byte_range: (0, offset),
|
||||
style: ratatui::style::Style::default().fg(theme.fg),
|
||||
}];
|
||||
r.extend(lex_to_runs_in_mode(view, theme, mode).into_iter().map(|run| {
|
||||
StyledRun {
|
||||
byte_range: (run.byte_range.0 + offset, run.byte_range.1 + offset),
|
||||
..run
|
||||
}
|
||||
}));
|
||||
r.extend(
|
||||
lex_to_runs_in_mode(view, theme, mode)
|
||||
.into_iter()
|
||||
.map(|run| StyledRun {
|
||||
byte_range: (run.byte_range.0 + offset, run.byte_range.1 + offset),
|
||||
..run
|
||||
}),
|
||||
);
|
||||
r
|
||||
};
|
||||
if let InputState::DefiniteErrorAt(pos) =
|
||||
@@ -150,7 +161,11 @@ pub fn render_input_runs_feedback(
|
||||
walker::Severity::Error => theme.tok_error,
|
||||
walker::Severity::Warning => theme.warning,
|
||||
};
|
||||
overlay_span(&mut runs, (diag.span.0 + offset, diag.span.1 + offset), colour);
|
||||
overlay_span(
|
||||
&mut runs,
|
||||
(diag.span.0 + offset, diag.span.1 + offset),
|
||||
colour,
|
||||
);
|
||||
}
|
||||
inject_cursor(&mut runs, input, cursor_byte, theme);
|
||||
runs
|
||||
@@ -234,9 +249,7 @@ pub fn classify_input_with_schema_in_mode(
|
||||
))
|
||||
}
|
||||
|
||||
fn classify_parse_result(
|
||||
result: Result<crate::dsl::Command, ParseError>,
|
||||
) -> InputState {
|
||||
fn classify_parse_result(result: Result<crate::dsl::Command, ParseError>) -> InputState {
|
||||
match result {
|
||||
Ok(_) => InputState::Valid,
|
||||
Err(ParseError::Empty) => InputState::Empty,
|
||||
@@ -372,8 +385,7 @@ pub fn advanced_alternative_note(
|
||||
// carries a blocking ERROR diagnostic such as a value-count
|
||||
// mismatch. Incomplete input (still being typed) and empty input are
|
||||
// excluded so the pointer doesn't flicker mid-keystroke.
|
||||
let definite_dsl_error = match classify_input_with_schema_in_mode(input, cache, Mode::Simple)
|
||||
{
|
||||
let definite_dsl_error = match classify_input_with_schema_in_mode(input, cache, Mode::Simple) {
|
||||
InputState::DefiniteErrorAt(_) => true,
|
||||
InputState::Valid => {
|
||||
crate::dsl::walker::input_verdict_in_mode(input, Some(cache), Mode::Simple)
|
||||
@@ -386,8 +398,7 @@ pub fn advanced_alternative_note(
|
||||
}
|
||||
// The validity-verdict-driven gate (ADR-0033 Amendment 5): the
|
||||
// line must be fully valid (verdict `None`) in advanced mode.
|
||||
if crate::dsl::walker::input_verdict_in_mode(input, Some(cache), Mode::Advanced).is_some()
|
||||
{
|
||||
if crate::dsl::walker::input_verdict_in_mode(input, Some(cache), Mode::Advanced).is_some() {
|
||||
return None;
|
||||
}
|
||||
Some(crate::t!("advanced_mode.also_valid_sql"))
|
||||
@@ -714,8 +725,7 @@ fn ambient_hint_core_in_mode(
|
||||
// narrows column candidates to the active table and runs the
|
||||
// §10.6 look-ahead, so it is the authoritative "what can go
|
||||
// here" set.
|
||||
let completion =
|
||||
crate::completion::candidates_at_cursor_in_mode(input, cursor, cache, mode);
|
||||
let completion = crate::completion::candidates_at_cursor_in_mode(input, cursor, cache, mode);
|
||||
|
||||
// Schema-aware diagnostics (ADR-0027 §2). `input_diagnostics`
|
||||
// is non-empty only for a command that *structurally parses*
|
||||
@@ -834,7 +844,9 @@ fn ambient_hint_core_in_mode(
|
||||
// keyword set.
|
||||
return Some(AmbientHint::Prose(crate::friendly::translate(key, &[])));
|
||||
}
|
||||
Some(crate::dsl::grammar::HintMode::SuppressProse | crate::dsl::grammar::HintMode::Default)
|
||||
Some(
|
||||
crate::dsl::grammar::HintMode::SuppressProse | crate::dsl::grammar::HintMode::Default,
|
||||
)
|
||||
| None => {}
|
||||
}
|
||||
|
||||
@@ -855,7 +867,8 @@ fn ambient_hint_core_in_mode(
|
||||
// Invalid identifier: cursor sits in a known-set slot but
|
||||
// the typed prefix matches nothing in the schema. (Stage
|
||||
// 8e / the user's #5.)
|
||||
if let Some(inv) = crate::completion::invalid_ident_at_cursor_in_mode(input, cursor, cache, mode)
|
||||
if let Some(inv) =
|
||||
crate::completion::invalid_ident_at_cursor_in_mode(input, cursor, cache, mode)
|
||||
{
|
||||
let kind = match inv.source {
|
||||
crate::dsl::grammar::IdentSource::Tables => "table",
|
||||
@@ -1036,11 +1049,7 @@ pub fn lex_to_runs(input: &str, theme: &Theme) -> Vec<StyledRun> {
|
||||
/// with `Mode::Advanced` so SQL keywords past the entry word
|
||||
/// match and get highlighted (ADR-0030 §8).
|
||||
#[must_use]
|
||||
pub fn lex_to_runs_in_mode(
|
||||
input: &str,
|
||||
theme: &Theme,
|
||||
mode: Mode,
|
||||
) -> Vec<StyledRun> {
|
||||
pub fn lex_to_runs_in_mode(input: &str, theme: &Theme, mode: Mode) -> Vec<StyledRun> {
|
||||
base_runs(input, theme, mode)
|
||||
}
|
||||
|
||||
@@ -1076,12 +1085,7 @@ fn base_runs(input: &str, theme: &Theme, mode: Mode) -> Vec<StyledRun> {
|
||||
runs
|
||||
}
|
||||
|
||||
fn inject_cursor(
|
||||
runs: &mut Vec<StyledRun>,
|
||||
input: &str,
|
||||
cursor_byte: usize,
|
||||
theme: &Theme,
|
||||
) {
|
||||
fn inject_cursor(runs: &mut Vec<StyledRun>, input: &str, cursor_byte: usize, theme: &Theme) {
|
||||
let cursor_byte = cursor_byte.min(input.len());
|
||||
|
||||
// End-of-input cursor: append the empty-range sentinel.
|
||||
@@ -1164,9 +1168,10 @@ mod tests {
|
||||
let mut cache = SchemaCache::default();
|
||||
cache.tables.push("Customers".into());
|
||||
cache.columns.push("name".into());
|
||||
cache
|
||||
.table_columns
|
||||
.insert("Customers".into(), vec![TableColumn::new("name", Type::Text)]);
|
||||
cache.table_columns.insert(
|
||||
"Customers".into(),
|
||||
vec![TableColumn::new("name", Type::Text)],
|
||||
);
|
||||
let input = ": select name from Customers";
|
||||
let view = "select name from Customers";
|
||||
let offset = 2; // ": "
|
||||
@@ -1362,9 +1367,10 @@ mod tests {
|
||||
let mut cache = crate::completion::SchemaCache::default();
|
||||
cache.tables.push("users".to_string());
|
||||
cache.columns.push("email".to_string());
|
||||
cache
|
||||
.table_columns
|
||||
.insert("users".to_string(), vec![TableColumn::new("email", Type::Text)]);
|
||||
cache.table_columns.insert(
|
||||
"users".to_string(),
|
||||
vec![TableColumn::new("email", Type::Text)],
|
||||
);
|
||||
cache
|
||||
}
|
||||
|
||||
@@ -1392,7 +1398,10 @@ mod tests {
|
||||
}
|
||||
// Tab candidates remain available (completion is independent).
|
||||
let comp = crate::completion::candidates_at_cursor_in_mode(
|
||||
input, input.len(), &cache, Mode::Simple,
|
||||
input,
|
||||
input.len(),
|
||||
&cache,
|
||||
Mode::Simple,
|
||||
)
|
||||
.expect("completion remains available");
|
||||
let texts: Vec<&str> = comp.candidates.iter().map(|c| c.text.as_str()).collect();
|
||||
@@ -1424,7 +1433,10 @@ mod tests {
|
||||
&hint,
|
||||
Some(AmbientHint::Prose(p)) if p.contains("row count")
|
||||
);
|
||||
assert!(!is_count_prose, "count hint must not show for {input:?}; got {hint:?}");
|
||||
assert!(
|
||||
!is_count_prose,
|
||||
"count hint must not show for {input:?}; got {hint:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1502,14 +1514,12 @@ mod tests {
|
||||
use crate::dsl::types::Type;
|
||||
let mut cache = SchemaCache::default();
|
||||
cache.tables.push("Customers".to_string());
|
||||
let tc = vec![
|
||||
TableColumn {
|
||||
name: "Age".to_string(),
|
||||
user_type: Type::Int,
|
||||
not_null: false,
|
||||
has_default: false,
|
||||
},
|
||||
];
|
||||
let tc = vec![TableColumn {
|
||||
name: "Age".to_string(),
|
||||
user_type: Type::Int,
|
||||
not_null: false,
|
||||
has_default: false,
|
||||
}];
|
||||
for c in &tc {
|
||||
cache.columns.push(c.name.clone());
|
||||
}
|
||||
@@ -1551,9 +1561,7 @@ mod tests {
|
||||
p.contains("No such") && p.contains("Agx"),
|
||||
"a genuine column typo before FROM must warn at typing time; got: {p:?}",
|
||||
),
|
||||
other => panic!(
|
||||
"`select Agx` must surface a typing-time typo hint; got: {other:?}",
|
||||
),
|
||||
other => panic!("`select Agx` must surface a typing-time typo hint; got: {other:?}",),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1652,8 +1660,7 @@ mod tests {
|
||||
// ADR-0022 Amendment 1: advanced-mode ambient assistance
|
||||
// surfaces SQL completion candidates (here the FROM-slot
|
||||
// table) instead of the simple-mode "this is SQL" gate.
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let cache = schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let input = "select * from ";
|
||||
match ambient_hint_in_mode(
|
||||
input,
|
||||
@@ -1678,10 +1685,7 @@ mod tests {
|
||||
// `INSERT … (` column list. (The simple-mode DSL value-slot
|
||||
// prose is a separate surface; this pins the §8 advanced claim.)
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Name", Type::Text)]);
|
||||
|
||||
let set_slot = "update Customers set ";
|
||||
match ambient_hint_in_mode(set_slot, set_slot.len(), None, &cache, Mode::Advanced) {
|
||||
@@ -1706,16 +1710,10 @@ mod tests {
|
||||
fn simple_mode_ambient_does_not_surface_sql_candidates() {
|
||||
// The simple-mode entry point keeps gating SQL — advanced
|
||||
// assistance is opt-in via mode, never leaked into simple.
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let cache = schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let input = "select * from ";
|
||||
let hint = ambient_hint_in_mode(
|
||||
input,
|
||||
input.len(),
|
||||
None,
|
||||
&cache,
|
||||
crate::mode::Mode::Simple,
|
||||
);
|
||||
let hint =
|
||||
ambient_hint_in_mode(input, input.len(), None, &cache, crate::mode::Mode::Simple);
|
||||
let offers_table = matches!(
|
||||
&hint,
|
||||
Some(AmbientHint::Candidates { items, .. })
|
||||
@@ -1733,8 +1731,7 @@ mod tests {
|
||||
fn f1_mid_typed_table_prefix_shows_completion_not_error() {
|
||||
// "select * from c" — `c` prefix-matches `Customers`. The
|
||||
// hint must offer the completion, not "no such table c".
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let cache = schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
match ambient_hint_in_mode(
|
||||
"select * from c",
|
||||
"select * from c".len(),
|
||||
@@ -1753,8 +1750,7 @@ mod tests {
|
||||
#[test]
|
||||
fn f1_genuinely_unknown_table_still_shows_error() {
|
||||
// "zzz" matches no table prefix — the error must still show.
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let cache = schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
match ambient_hint_in_mode(
|
||||
"select * from zzz",
|
||||
"select * from zzz".len(),
|
||||
@@ -1773,8 +1769,7 @@ mod tests {
|
||||
fn f1_simple_mode_dsl_mid_typed_table_completes() {
|
||||
// The same shadowing affects DSL commands in simple mode:
|
||||
// "show data c" must offer Customers, not "no such table c".
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
let cache = schema_with_columns("Customers", &[("id", crate::dsl::types::Type::Int)]);
|
||||
match ambient_hint_in_mode(
|
||||
"show data c",
|
||||
"show data c".len(),
|
||||
@@ -1804,7 +1799,12 @@ mod tests {
|
||||
cache.columns.push("order_col".to_string());
|
||||
cache.table_columns.insert(
|
||||
"Orders".to_string(),
|
||||
vec![TableColumn { name: "order_col".to_string(), user_type: Type::Int, not_null: false, has_default: false }],
|
||||
vec![TableColumn {
|
||||
name: "order_col".to_string(),
|
||||
user_type: Type::Int,
|
||||
not_null: false,
|
||||
has_default: false,
|
||||
}],
|
||||
);
|
||||
|
||||
let comp = crate::completion::candidates_at_cursor_in_mode(
|
||||
@@ -1846,9 +1846,7 @@ mod tests {
|
||||
for c in &columns {
|
||||
cache.columns.push(c.name.clone());
|
||||
}
|
||||
cache
|
||||
.table_columns
|
||||
.insert(table.to_string(), columns);
|
||||
cache.table_columns.insert(table.to_string(), columns);
|
||||
cache
|
||||
}
|
||||
|
||||
@@ -1860,7 +1858,11 @@ mod tests {
|
||||
("Customers", &[("id", Type::Serial), ("name", Type::Text)]),
|
||||
(
|
||||
"Products",
|
||||
&[("id", Type::Serial), ("name", Type::Text), ("price", Type::Decimal)],
|
||||
&[
|
||||
("id", Type::Serial),
|
||||
("name", Type::Text),
|
||||
("price", Type::Decimal),
|
||||
],
|
||||
),
|
||||
(
|
||||
"OrderLines",
|
||||
@@ -1873,13 +1875,19 @@ mod tests {
|
||||
),
|
||||
(
|
||||
"Orders",
|
||||
&[("id", Type::Serial), ("customer_id", Type::Int), ("date", Type::Date)],
|
||||
&[
|
||||
("id", Type::Serial),
|
||||
("customer_id", Type::Int),
|
||||
("date", Type::Date),
|
||||
],
|
||||
),
|
||||
];
|
||||
for (t, cols) in tables {
|
||||
cache.tables.push((*t).to_string());
|
||||
let tc: Vec<TableColumn> =
|
||||
cols.iter().map(|(n, ty)| TableColumn::new(*n, *ty)).collect();
|
||||
let tc: Vec<TableColumn> = cols
|
||||
.iter()
|
||||
.map(|(n, ty)| TableColumn::new(*n, *ty))
|
||||
.collect();
|
||||
for c in &tc {
|
||||
cache.columns.push(c.name.clone());
|
||||
}
|
||||
@@ -1914,17 +1922,11 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_insert_first_value_shows_int_prose() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Name", Type::Text)]);
|
||||
let input = "insert into Customers values (";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
assert!(
|
||||
p.contains("integer"),
|
||||
"expected int-slot prose, got: {p:?}",
|
||||
);
|
||||
assert!(p.contains("integer"), "expected int-slot prose, got: {p:?}",);
|
||||
}
|
||||
other => panic!("expected Prose, got {other:?}"),
|
||||
}
|
||||
@@ -1942,7 +1944,11 @@ mod tests {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Serial), ("Name", Type::Text), ("Email", Type::Text)],
|
||||
&[
|
||||
("id", Type::Serial),
|
||||
("Name", Type::Text),
|
||||
("Email", Type::Text),
|
||||
],
|
||||
);
|
||||
let input = "insert into Customers values (1, 'Alice', 'a@b.c')";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
@@ -1966,10 +1972,7 @@ mod tests {
|
||||
// A valid simple-mode DSL command gets no advanced pointer —
|
||||
// it isn't an error, and there is nothing to switch modes for.
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Serial), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Serial), ("Name", Type::Text)]);
|
||||
let input = "insert into Customers values ('Alice')";
|
||||
if let Some(AmbientHint::Prose(p)) = ambient_hint(input, input.len(), None, &cache) {
|
||||
assert!(
|
||||
@@ -2010,10 +2013,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_insert_second_value_shows_text_prose() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Name", Type::Text)]);
|
||||
let input = "insert into Customers values (1, ";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
@@ -2029,10 +2029,8 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_update_set_shows_per_column_prose() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Birthday", Type::Date)],
|
||||
);
|
||||
let cache =
|
||||
schema_with_columns("Customers", &[("id", Type::Int), ("Birthday", Type::Date)]);
|
||||
let input = "update Customers set Birthday=";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
@@ -2057,9 +2055,7 @@ mod tests {
|
||||
// hasn't committed), the Optional propagates Incomplete
|
||||
// and the user sees no error overlay until they submit.
|
||||
assert_eq!(
|
||||
classify_input(
|
||||
"insert into Orders (id, CustId, Total) values (42, 89, 17.59"
|
||||
),
|
||||
classify_input("insert into Orders (id, CustId, Total) values (42, 89, 17.59"),
|
||||
InputState::IncompleteAtEof,
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -2071,18 +2067,12 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_insert_first_value_mentions_column_name() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Name", Type::Text)]);
|
||||
let input = "insert into Customers values (";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
assert!(p.contains("id"), "expected column name `id`, got {p:?}");
|
||||
assert!(
|
||||
p.contains("integer"),
|
||||
"expected int prose, got {p:?}",
|
||||
);
|
||||
assert!(p.contains("integer"), "expected int prose, got {p:?}",);
|
||||
}
|
||||
other => panic!("expected Prose, got {other:?}"),
|
||||
}
|
||||
@@ -2091,10 +2081,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_update_set_mentions_column_name() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Email", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Email", Type::Text)]);
|
||||
let input = "update Customers set Email=";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
@@ -2131,10 +2118,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ambient_hint_at_second_insert_value_mentions_second_column() {
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("id", Type::Int), ("Name", Type::Text)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("id", Type::Int), ("Name", Type::Text)]);
|
||||
let input = "insert into Customers values (1, ";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
@@ -2165,14 +2149,20 @@ mod tests {
|
||||
use crate::dsl::types::Type;
|
||||
let cases: &[(&[(&str, Type)], &str)] = &[
|
||||
// string first value (the report's case): first col text.
|
||||
(&[("Name", Type::Text), ("Age", Type::Int)],
|
||||
"insert into Customers values ('Oli'"),
|
||||
(
|
||||
&[("Name", Type::Text), ("Age", Type::Int)],
|
||||
"insert into Customers values ('Oli'",
|
||||
),
|
||||
// integer first value: first col int.
|
||||
(&[("Age", Type::Int), ("Name", Type::Text)],
|
||||
"insert into Customers values (42"),
|
||||
(
|
||||
&[("Age", Type::Int), ("Name", Type::Text)],
|
||||
"insert into Customers values (42",
|
||||
),
|
||||
// real first value: first col real.
|
||||
(&[("Score", Type::Real), ("Name", Type::Text)],
|
||||
"insert into Customers values (3.5"),
|
||||
(
|
||||
&[("Score", Type::Real), ("Name", Type::Text)],
|
||||
"insert into Customers values (3.5",
|
||||
),
|
||||
];
|
||||
for (cols, input) in cases {
|
||||
let cache = schema_with_columns("Customers", cols);
|
||||
@@ -2232,10 +2222,7 @@ mod tests {
|
||||
// is nothing left to fill. Guards against over-correcting the
|
||||
// fix into never suggesting the close paren.
|
||||
use crate::dsl::types::Type;
|
||||
let cache = schema_with_columns(
|
||||
"Customers",
|
||||
&[("Name", Type::Text), ("Age", Type::Int)],
|
||||
);
|
||||
let cache = schema_with_columns("Customers", &[("Name", Type::Text), ("Age", Type::Int)]);
|
||||
let input = "insert into Customers values ('Oli', 52";
|
||||
match ambient_hint(input, input.len(), None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
@@ -2384,10 +2371,7 @@ mod tests {
|
||||
match ambient_hint("show data Missing", 17, None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
assert!(p.contains("Missing"), "got {p:?}");
|
||||
assert!(
|
||||
p.to_lowercase().contains("no such table"),
|
||||
"got {p:?}",
|
||||
);
|
||||
assert!(p.to_lowercase().contains("no such table"), "got {p:?}",);
|
||||
}
|
||||
other => panic!("expected Prose, got {other:?}"),
|
||||
}
|
||||
@@ -2440,8 +2424,7 @@ mod tests {
|
||||
use crate::dsl::types::Type;
|
||||
// Two type-mismatch WARNINGs; the hint names the column
|
||||
// whose offending literal the cursor sits in.
|
||||
let cache =
|
||||
schema_with_columns("Events", &[("a", Type::Int), ("b", Type::Int)]);
|
||||
let cache = schema_with_columns("Events", &[("a", Type::Int), ("b", Type::Int)]);
|
||||
let input = "delete from Events where a = 'x' or b = 'y'";
|
||||
let on_x = input.find("'x'").expect("'x' literal") + 1;
|
||||
let on_y = input.find("'y'").expect("'y' literal") + 1;
|
||||
@@ -2460,8 +2443,16 @@ mod tests {
|
||||
inserted_range: (5, 5),
|
||||
original_text: String::new(),
|
||||
candidates: vec![
|
||||
Candidate { text: "data".to_string(), kind: CandidateKind::Keyword, mode: crate::completion::ModeClass::Both },
|
||||
Candidate { text: "table".to_string(), kind: CandidateKind::Keyword, mode: crate::completion::ModeClass::Both },
|
||||
Candidate {
|
||||
text: "data".to_string(),
|
||||
kind: CandidateKind::Keyword,
|
||||
mode: crate::completion::ModeClass::Both,
|
||||
},
|
||||
Candidate {
|
||||
text: "table".to_string(),
|
||||
kind: CandidateKind::Keyword,
|
||||
mode: crate::completion::ModeClass::Both,
|
||||
},
|
||||
],
|
||||
selection_idx: 1,
|
||||
};
|
||||
@@ -2494,8 +2485,16 @@ mod tests {
|
||||
// produce — proves the memo's list is being used,
|
||||
// not a recomputed one.
|
||||
candidates: vec![
|
||||
Candidate { text: "data".to_string(), kind: CandidateKind::Keyword, mode: crate::completion::ModeClass::Both },
|
||||
Candidate { text: "table".to_string(), kind: CandidateKind::Keyword, mode: crate::completion::ModeClass::Both },
|
||||
Candidate {
|
||||
text: "data".to_string(),
|
||||
kind: CandidateKind::Keyword,
|
||||
mode: crate::completion::ModeClass::Both,
|
||||
},
|
||||
Candidate {
|
||||
text: "table".to_string(),
|
||||
kind: CandidateKind::Keyword,
|
||||
mode: crate::completion::ModeClass::Both,
|
||||
},
|
||||
],
|
||||
selection_idx: 1,
|
||||
};
|
||||
@@ -2564,10 +2563,7 @@ mod tests {
|
||||
fn classify_trailing_whitespace_does_not_create_definite_error() {
|
||||
// Trailing whitespace alone shouldn't promote an
|
||||
// incomplete-at-EOF state into a definite error.
|
||||
assert_eq!(
|
||||
classify_input("create "),
|
||||
InputState::IncompleteAtEof,
|
||||
);
|
||||
assert_eq!(classify_input("create "), InputState::IncompleteAtEof,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user