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:
claude@clouddev1
2026-06-17 21:39:19 +00:00
parent e9606b5f6d
commit 41b7e9a049
102 changed files with 8017 additions and 4975 deletions
+210 -188
View File
@@ -509,7 +509,10 @@ pub enum LoadPickerSubMode {
/// Switched to via `b`. Same input/cursor surface as
/// `PathEntryModal`; kept inline so the picker can flip
/// back to List with `Esc`.
PathEntry { input: String, cursor: usize },
PathEntry {
input: String,
cursor: usize,
},
}
const PAGE_SCROLL_LINES: usize = 5;
@@ -697,9 +700,7 @@ impl App {
// `trimmed[1..].trim()`.
let leading_ws = self.input.len() - self.input.trim_start().len();
let mut offset = leading_ws + 1; // past the `:`
while offset < self.input.len()
&& self.input.as_bytes()[offset].is_ascii_whitespace()
{
while offset < self.input.len() && self.input.as_bytes()[offset].is_ascii_whitespace() {
offset += 1;
}
let view = &self.input[offset..];
@@ -727,8 +728,7 @@ impl App {
pub fn input_validity_verdict(&self) -> Option<crate::dsl::walker::Severity> {
let mode = match self.effective_mode() {
EffectiveMode::Simple => Mode::Simple,
EffectiveMode::AdvancedPersistent
| EffectiveMode::AdvancedOneShot => Mode::Advanced,
EffectiveMode::AdvancedPersistent | EffectiveMode::AdvancedOneShot => Mode::Advanced,
};
// Strip the `:` one-shot prefix so the walker verdicts the SQL
// itself, not the escape marker (which it can't parse).
@@ -1037,10 +1037,7 @@ impl App {
Vec::new()
}
AppEvent::ExportSucceeded { path } => {
self.note_system(crate::t!(
"project.export_ok",
path = path.display()
));
self.note_system(crate::t!("project.export_ok", path = path.display()));
Vec::new()
}
AppEvent::ExportFailed { error } => {
@@ -1056,11 +1053,7 @@ impl App {
// `[ok] replay — N command(s)` summary is payload-bearing
// (the count) and stays.
self.mark_oldest_pending_echo(EchoStatus::Ok);
self.note_system(crate::t!(
"replay.completed",
path = path,
count = count
));
self.note_system(crate::t!("replay.completed", path = path, count = count));
// ADR-0034: surface `[skip]` warnings for app-lifecycle
// commands whose omission can leave the replayed state
// incomplete (`import`, nested `replay`).
@@ -1084,11 +1077,7 @@ impl App {
// it, mirroring how the interactive `running: …`
// path renders source-line context above an error.
if line_number == 0 {
self.note_error(crate::t!(
"replay.failed_open",
path = path,
error = error
));
self.note_error(crate::t!("replay.failed_open", path = path, error = error));
} else {
self.note_error(crate::t!(
"replay.failed_at_line",
@@ -1097,10 +1086,7 @@ impl App {
error = error
));
if !command.is_empty() {
self.note_error(crate::t!(
"replay.command_echo",
command = command
));
self.note_error(crate::t!("replay.command_echo", command = command));
}
}
Vec::new()
@@ -1237,8 +1223,7 @@ impl App {
// stays F1-only.
let hint_key = key.code == KeyCode::F(1)
|| (self.demo_mode
&& (key.code, key.modifiers)
== (KeyCode::Char('g'), KeyModifiers::CONTROL));
&& (key.code, key.modifiers) == (KeyCode::Char('g'), KeyModifiers::CONTROL));
if hint_key {
if self.input.trim().is_empty() {
self.note_hint_for_recent_error();
@@ -1369,8 +1354,8 @@ impl App {
/// against crossterm 0.29). Only active in demo mode (the caller
/// gates on `self.demo_mode`).
fn handle_demo_caption_key(&mut self, key: KeyEvent) -> Option<Vec<Action>> {
let is_toggle = key.code == KeyCode::Char('5')
&& key.modifiers.contains(KeyModifiers::CONTROL);
let is_toggle =
key.code == KeyCode::Char('5') && key.modifiers.contains(KeyModifiers::CONTROL);
if self.demo_caption_capturing {
if is_toggle {
@@ -1379,8 +1364,7 @@ impl App {
self.demo_caption_capturing = false;
let text = std::mem::take(&mut self.demo_caption_buffer);
let trimmed = text.trim();
self.demo_caption =
(!trimmed.is_empty()).then(|| trimmed.to_string());
self.demo_caption = (!trimmed.is_empty()).then(|| trimmed.to_string());
} else {
match key.code {
// Plain characters accumulate invisibly; the prompt
@@ -1553,7 +1537,10 @@ impl App {
&self.schema_cache,
self.effective_mode().as_mode(),
)?;
comp.replaced_range = (comp.replaced_range.0 + offset, comp.replaced_range.1 + offset);
comp.replaced_range = (
comp.replaced_range.0 + offset,
comp.replaced_range.1 + offset,
);
Some(comp)
}
@@ -1581,8 +1568,7 @@ impl App {
idx: usize,
) -> crate::completion::LastCompletion {
let inserted = comp.candidates[idx].text.clone();
let original_text =
self.input[comp.replaced_range.0..comp.replaced_range.1].to_string();
let original_text = self.input[comp.replaced_range.0..comp.replaced_range.1].to_string();
self.input
.replace_range(comp.replaced_range.0..comp.replaced_range.1, &inserted);
let new_end = comp.replaced_range.0 + inserted.len();
@@ -1777,7 +1763,10 @@ impl App {
// teaching echo (ADR-0038) on an advanced effective mode.
let (submission_mode, effective_input) =
if self.mode == Mode::Simple && trimmed.starts_with(':') {
(EffectiveMode::AdvancedOneShot, trimmed[1..].trim().to_string())
(
EffectiveMode::AdvancedOneShot,
trimmed[1..].trim().to_string(),
)
} else if self.mode == Mode::Advanced {
(EffectiveMode::AdvancedPersistent, trimmed.to_string())
} else {
@@ -1845,11 +1834,7 @@ impl App {
/// simple and advanced modes; the parse-first refactor
/// (round-5) routes app commands here before the
/// mode-specific DSL/SQL paths.
fn dispatch_app_command(
&mut self,
cmd: crate::dsl::AppCommand,
source: &str,
) -> Vec<Action> {
fn dispatch_app_command(&mut self, cmd: crate::dsl::AppCommand, source: &str) -> Vec<Action> {
use crate::dsl::{AppCommand, MessagesValue, ModeValue};
debug!(command = ?cmd, "dispatch app command");
match cmd {
@@ -2009,11 +1994,8 @@ impl App {
// mode so the walker gates SQL-only forms — simple-mode
// `select` returns the "this is SQL" hint as a normal
// parse error and is rendered through the Err arm below.
match crate::dsl::parser::parse_command_with_schema_in_mode(
input,
&self.schema_cache,
mode,
) {
match crate::dsl::parser::parse_command_with_schema_in_mode(input, &self.schema_cache, mode)
{
Ok(Command::Replay { path }) => {
// `replay` is parsed as a DSL command for the
// sake of grammar uniformity, but its execution
@@ -2127,15 +2109,9 @@ impl App {
.get(..*position)
.map_or(*position, |s| s.chars().count());
let pad = prefix.chars().count() + chars_before;
self.note_error(crate::t!(
"parse.caret",
padding = " ".repeat(pad)
));
self.note_error(crate::t!("parse.caret", padding = " ".repeat(pad)));
}
self.note_error(crate::t!(
"parse.error",
detail = parse_error_message(&err)
));
self.note_error(crate::t!("parse.error", detail = parse_error_message(&err)));
// ADR-0033 Amendment 3: combine the DSL error with a
// pointer to advanced mode when the same line would
// run as SQL there. Only in simple mode (a one-shot
@@ -2228,7 +2204,11 @@ impl App {
| Command::AddRelationship { .. }
| Command::DropRelationship { .. }
) {
debug!(verb = command.verb(), width = self.last_output_width, "render: relationship diagrams (ADR-0044)");
debug!(
verb = command.verb(),
width = self.last_output_width,
"render: relationship diagrams (ADR-0044)"
);
for line in crate::output_render::render_structure_with_diagrams(
desc,
self.last_output_width,
@@ -2252,11 +2232,7 @@ impl App {
}
}
fn handle_dsl_explain_success(
&mut self,
command: &Command,
plan: &crate::db::QueryPlan,
) {
fn handle_dsl_explain_success(&mut self, command: &Command, plan: &crate::db::QueryPlan) {
self.note_ok_summary(command);
// ADR-0028 §3: the display SQL, then the plan tree.
// `render_explain_plan` returns ready-built `OutputLine`s
@@ -2350,11 +2326,7 @@ impl App {
}
}
fn handle_dsl_add_column_success(
&mut self,
command: &Command,
result: AddColumnResult,
) {
fn handle_dsl_add_column_success(&mut self, command: &Command, result: AddColumnResult) {
self.note_ok_summary(command);
// ADR-0018 §9 / ADR-0038 §6 category 3: emit auto-fill note(s)
// before the structure render so the pedagogical "the tool did
@@ -2369,19 +2341,12 @@ impl App {
self.current_table = Some(result.description);
}
fn handle_dsl_drop_column_success(
&mut self,
command: &Command,
result: DropColumnResult,
) {
fn handle_dsl_drop_column_success(&mut self, command: &Command, result: DropColumnResult) {
self.note_ok_summary(command);
// ADR-0025: when `--cascade` removed covering indexes,
// name each one so the learner sees the side effect.
for index in &result.dropped_indexes {
self.note_system(crate::t!(
"ok.index_dropped_with_column",
index = index,
));
self.note_system(crate::t!("ok.index_dropped_with_column", index = index,));
}
for line in crate::output_render::render_structure(&result.description) {
self.note_system(line);
@@ -2415,10 +2380,7 @@ impl App {
lossy = note.lossy
)
} else {
crate::t!(
"client_side.transformed",
count = note.transformed
)
crate::t!("client_side.transformed", count = note.transformed)
};
self.push_category_three_prose(line);
}
@@ -2583,9 +2545,7 @@ impl App {
(Operation::RenameTable, Some(table.as_str()), None)
}
},
C::SqlCreateTable { name, .. } => {
(Operation::CreateTable, Some(name.as_str()), None)
}
C::SqlCreateTable { name, .. } => (Operation::CreateTable, Some(name.as_str()), None),
C::DropTable { name } => (Operation::DropTable, Some(name.as_str()), None),
C::SqlDropTable { name, .. } => (Operation::DropTable, Some(name.as_str()), None),
C::AddColumn { table, column, .. } => (
@@ -2635,9 +2595,7 @@ impl App {
// SQL `CREATE [UNIQUE] INDEX` shares the add-index operation
// (it reuses `do_add_index`); route engine/validation errors
// through it with the parsed table.
C::SqlCreateIndex { table, .. } => {
(Operation::AddIndex, Some(table.as_str()), None)
}
C::SqlCreateIndex { table, .. } => (Operation::AddIndex, Some(table.as_str()), None),
C::AddConstraint { table, column, .. } => (
Operation::AddConstraint,
Some(table.as_str()),
@@ -2700,19 +2658,13 @@ impl App {
// `dispatch_input` routes them through
// `dispatch_app_command` before the DSL execution
// pipeline that this context builder feeds.
C::App(_) => unreachable!(
"App commands are dispatched before reaching dsl execution"
),
C::App(_) => unreachable!("App commands are dispatched before reaching dsl execution"),
};
TranslateContext {
operation: Some(operation),
table: facts
.table
.or_else(|| fallback_table.map(str::to_string)),
column: facts
.column
.or_else(|| fallback_column.map(str::to_string)),
table: facts.table.or_else(|| fallback_table.map(str::to_string)),
column: facts.column.or_else(|| fallback_column.map(str::to_string)),
child_table: facts.child_table,
parent_table: facts.parent_table,
parent_column: facts.parent_column,
@@ -2818,11 +2770,7 @@ impl App {
}
}
fn handle_path_entry_key(
&mut self,
key: KeyEvent,
mut state: PathEntryModal,
) -> Vec<Action> {
fn handle_path_entry_key(&mut self, key: KeyEvent, mut state: PathEntryModal) -> Vec<Action> {
match key.code {
KeyCode::Esc => {
self.modal = None;
@@ -2904,11 +2852,7 @@ impl App {
}
}
fn handle_load_picker_key(
&mut self,
key: KeyEvent,
mut state: LoadPickerModal,
) -> Vec<Action> {
fn handle_load_picker_key(&mut self, key: KeyEvent, mut state: LoadPickerModal) -> Vec<Action> {
match &mut state.sub_mode {
LoadPickerSubMode::List => match key.code {
KeyCode::Esc => {
@@ -3198,7 +3142,10 @@ impl App {
.map(|c| c.text.clone())
.collect::<Vec<_>>()
.join(", ");
self.push_category_three_prose(crate::t!("hint.ambient_expected", expected = names));
self.push_category_three_prose(crate::t!(
"hint.ambient_expected",
expected = names
));
}
None => self.note_getting_started(),
}
@@ -3413,10 +3360,7 @@ fn render_usage_block(input: &str, mode: Mode) -> String {
.into_iter()
.map(|w| format!("`{w}`"))
.collect();
crate::t!(
"parse.available_commands",
commands = names.join(", ")
)
crate::t!("parse.available_commands", commands = names.join(", "))
}
fn render_cascade_effect(effect: &CascadeEffect) -> String {
@@ -3424,9 +3368,7 @@ fn render_cascade_effect(effect: &CascadeEffect) -> String {
let action_key = match effect.action {
ReferentialAction::Cascade => "db.cascade.action_deleted",
ReferentialAction::SetNull => "db.cascade.action_set_null",
ReferentialAction::Restrict | ReferentialAction::NoAction => {
"db.cascade.action_blocked"
}
ReferentialAction::Restrict | ReferentialAction::NoAction => "db.cascade.action_blocked",
};
crate::t!(
"db.cascade.summary",
@@ -3464,7 +3406,10 @@ mod tests {
fn demo_badge_label_maps_the_invisible_keys() {
let none = KeyModifiers::NONE;
assert_eq!(demo_badge_label(&ke(KeyCode::Tab, none)), Some("[TAB]"));
assert_eq!(demo_badge_label(&ke(KeyCode::BackTab, KeyModifiers::SHIFT)), Some("[SHIFT-TAB]"));
assert_eq!(
demo_badge_label(&ke(KeyCode::BackTab, KeyModifiers::SHIFT)),
Some("[SHIFT-TAB]")
);
assert_eq!(demo_badge_label(&ke(KeyCode::Enter, none)), Some("[ENTER]"));
assert_eq!(demo_badge_label(&ke(KeyCode::Esc, none)), Some("[ESC]"));
assert_eq!(demo_badge_label(&ke(KeyCode::Up, none)), Some("[UP]"));
@@ -3474,8 +3419,14 @@ mod tests {
assert_eq!(demo_badge_label(&ke(KeyCode::Home, none)), Some("[HOME]"));
assert_eq!(demo_badge_label(&ke(KeyCode::End, none)), Some("[END]"));
assert_eq!(demo_badge_label(&ke(KeyCode::PageUp, none)), Some("[PGUP]"));
assert_eq!(demo_badge_label(&ke(KeyCode::PageDown, none)), Some("[PGDN]"));
assert_eq!(demo_badge_label(&ke(KeyCode::Backspace, none)), Some("[BKSP]"));
assert_eq!(
demo_badge_label(&ke(KeyCode::PageDown, none)),
Some("[PGDN]")
);
assert_eq!(
demo_badge_label(&ke(KeyCode::Backspace, none)),
Some("[BKSP]")
);
assert_eq!(demo_badge_label(&ke(KeyCode::Delete, none)), Some("[DEL]"));
assert_eq!(
demo_badge_label(&ke(KeyCode::Char('o'), KeyModifiers::CONTROL)),
@@ -3493,12 +3444,24 @@ mod tests {
#[test]
fn demo_badge_label_none_for_glyphs_and_excluded_chords() {
// Plain characters render their own glyph — no badge.
assert_eq!(demo_badge_label(&ke(KeyCode::Char('a'), KeyModifiers::NONE)), None);
assert_eq!(demo_badge_label(&ke(KeyCode::Char(' '), KeyModifiers::NONE)), None);
assert_eq!(
demo_badge_label(&ke(KeyCode::Char('a'), KeyModifiers::NONE)),
None
);
assert_eq!(
demo_badge_label(&ke(KeyCode::Char(' '), KeyModifiers::NONE)),
None
);
// Quit and the (Phase C) caption toggle are deliberately excluded.
assert_eq!(demo_badge_label(&ke(KeyCode::Char('c'), KeyModifiers::CONTROL)), None);
assert_eq!(
demo_badge_label(&ke(KeyCode::Char('c'), KeyModifiers::CONTROL)),
None
);
// Ctrl+] decodes to Char('5')+CONTROL — must not badge.
assert_eq!(demo_badge_label(&ke(KeyCode::Char('5'), KeyModifiers::CONTROL)), None);
assert_eq!(
demo_badge_label(&ke(KeyCode::Char('5'), KeyModifiers::CONTROL)),
None
);
}
#[test]
@@ -3606,7 +3569,10 @@ mod tests {
assert!(app.demo_caption_capturing, "still capturing");
assert_eq!(app.demo_caption_buffer, "note");
assert_eq!(app.input, "");
assert_eq!(app.demo_badge, None, "inert keys raise no badge while capturing");
assert_eq!(
app.demo_badge, None,
"inert keys raise no badge while capturing"
);
}
#[test]
@@ -4211,7 +4177,9 @@ mod tests {
type_str(&mut app, "copy sideways");
let actions = submit(&mut app);
assert!(
!actions.iter().any(|a| matches!(a, Action::CopyToClipboard(_))),
!actions
.iter()
.any(|a| matches!(a, Action::CopyToClipboard(_))),
"an unknown target does not copy",
);
let rendered = app
@@ -4399,7 +4367,10 @@ mod tests {
);
// … names the table's columns so the user can see what's needed …
assert!(
out.contains("Name") && out.contains("Age") && out.contains("id") && out.contains("SerNo"),
out.contains("Name")
&& out.contains("Age")
&& out.contains("id")
&& out.contains("SerNo"),
"missing the column-name list in: {out}",
);
// … and shows the column-list override targeting the non-auto columns.
@@ -4423,9 +4394,15 @@ mod tests {
let _ = submit(&mut app);
let out = error_lines(&app);
// The teaching line names the user-supplied columns …
assert!(out.contains("Name") && out.contains("Age"), "missing non-auto column names in: {out}");
assert!(
out.contains("Name") && out.contains("Age"),
"missing non-auto column names in: {out}"
);
// … the auto-generated columns …
assert!(out.contains("id") && out.contains("SerNo"), "missing auto column names in: {out}");
assert!(
out.contains("id") && out.contains("SerNo"),
"missing auto column names in: {out}"
);
// … signals the contract …
assert!(
out.contains("auto-generated"),
@@ -4520,10 +4497,7 @@ mod tests {
let mut app = App::new();
install_customers_schema_two_serials(&mut app);
app.mode = Mode::Advanced;
type_str(
&mut app,
"insert into Customers values (13, 'Oli', 42, 13)",
);
type_str(&mut app, "insert into Customers values (13, 'Oli', 42, 13)");
let actions = submit(&mut app);
assert!(
actions
@@ -4552,7 +4526,9 @@ mod tests {
type_str(&mut app, "insert into Customers values ('Oli', 52, 3)");
let actions = submit(&mut app);
assert!(
!actions.iter().any(|a| matches!(a, Action::ExecuteDsl { .. })),
!actions
.iter()
.any(|a| matches!(a, Action::ExecuteDsl { .. })),
"simple-mode Form B count mismatch must NOT dispatch; got: {actions:?}",
);
}
@@ -4565,7 +4541,9 @@ mod tests {
type_str(&mut app, "insert into Customers values ('Oli')");
let actions = submit(&mut app);
assert!(
!actions.iter().any(|a| matches!(a, Action::ExecuteDsl { .. })),
!actions
.iter()
.any(|a| matches!(a, Action::ExecuteDsl { .. })),
"simple-mode Form B under-supply must NOT dispatch; got: {actions:?}",
);
}
@@ -4580,7 +4558,9 @@ mod tests {
type_str(&mut app, "insert into Customers (Name, Age) values ('Oli')");
let actions = submit(&mut app);
assert!(
!actions.iter().any(|a| matches!(a, Action::ExecuteDsl { .. })),
!actions
.iter()
.any(|a| matches!(a, Action::ExecuteDsl { .. })),
"simple-mode Form A count mismatch must NOT dispatch; got: {actions:?}",
);
}
@@ -4616,9 +4596,7 @@ mod tests {
for c in &tc {
app.schema_cache.columns.push(c.name.clone());
}
app.schema_cache
.table_columns
.insert("T".to_string(), tc);
app.schema_cache.table_columns.insert("T".to_string(), tc);
type_str(&mut app, "insert into T values (1, 2), (3, 4)");
let actions = submit(&mut app);
assert!(
@@ -4649,11 +4627,11 @@ mod tests {
// advanced-mode hint at all, so we look for any line carrying
// the "mode advanced" actionable fragment that the pointer
// always emits.
let has_pointer = app
.output
.iter()
.any(|l| l.text.contains("mode advanced"));
assert!(!has_pointer, "unknown command must not point at advanced mode");
let has_pointer = app.output.iter().any(|l| l.text.contains("mode advanced"));
assert!(
!has_pointer,
"unknown command must not point at advanced mode"
);
}
#[test]
@@ -4702,7 +4680,11 @@ mod tests {
app.mode = mode;
type_str(&mut app, input);
match submit(&mut app).as_slice() {
[Action::ExecuteDsl { submission_mode, .. }] => *submission_mode,
[
Action::ExecuteDsl {
submission_mode, ..
},
] => *submission_mode,
other => panic!("expected one ExecuteDsl; got {other:?}"),
}
};
@@ -4733,7 +4715,9 @@ mod tests {
app.update(AppEvent::DslSucceeded {
command: cmd.clone(),
description: None,
echo: Some(vec!["CREATE TABLE Other (id serial PRIMARY KEY)".to_string()]),
echo: Some(vec![
"CREATE TABLE Other (id serial PRIMARY KEY)".to_string(),
]),
});
let texts: Vec<&str> = app.output.iter().map(|l| l.text.as_str()).collect();
// ADR-0040: no `[ok]` summary; with no preceding `running:` echo
@@ -4792,7 +4776,10 @@ mod tests {
.position(|t| t.contains("Executing SQL:"))
.expect("an echo line");
assert_eq!(echo_idx, 0, "teaching echo leads the output: {texts:?}");
assert!(texts[echo_idx].contains(expected), "echo carries the SQL: {texts:?}");
assert!(
texts[echo_idx].contains(expected),
"echo carries the SQL: {texts:?}"
);
// ADR-0038 §4 polish: every success arm now wires the echo as
// `OutputKind::TeachingEcho` so `ui::render_output_line` fires
// the dim-prefix + advanced-lex custom branch. Pinning this
@@ -4911,7 +4898,9 @@ mod tests {
description: sample_description("T"),
client_side: None,
},
echo: Some(vec!["ALTER TABLE T ALTER COLUMN c SET DATA TYPE text".to_string()]),
echo: Some(vec![
"ALTER TABLE T ALTER COLUMN c SET DATA TYPE text".to_string(),
]),
dont_convert_caveat: false,
});
assert_echo_beneath_ok(&app, "ALTER TABLE T ALTER COLUMN c SET DATA TYPE text");
@@ -5126,9 +5115,7 @@ mod tests {
dont_convert_caveat: false,
});
assert!(
!app.output
.iter()
.any(|l| l.text.contains("--dont-convert")),
!app.output.iter().any(|l| l.text.contains("--dont-convert")),
"no caveat in simple mode (no echo to refer to)",
);
}
@@ -5198,7 +5185,10 @@ mod tests {
);
// Pin the `Executing SQL:` prefix repeats once per statement
// (the plain-rendering shape until the styled-runs polish lands).
let exec_count = texts.iter().filter(|t| t.contains("Executing SQL:")).count();
let exec_count = texts
.iter()
.filter(|t| t.contains("Executing SQL:"))
.count();
assert_eq!(exec_count, 3, "one Executing SQL: per statement: {texts:?}");
}
@@ -5223,19 +5213,13 @@ mod tests {
// (could be the caret line, the parse-error detail
// line, or the usage line). Scan for the friendly
// "unknown mode" anchor phrase.
let anywhere = app
.output
.iter()
.any(|l| l.text.contains("unknown mode"));
let anywhere = app.output.iter().any(|l| l.text.contains("unknown mode"));
assert!(
anywhere,
"expected 'unknown mode' somewhere in output: {:?}",
app.output.iter().map(|l| &l.text).collect::<Vec<_>>(),
);
let any_error = app
.output
.iter()
.any(|l| l.kind == OutputKind::Error);
let any_error = app.output.iter().any(|l| l.kind == OutputKind::Error);
assert!(any_error, "expected at least one Error line");
}
@@ -5325,11 +5309,17 @@ mod tests {
app.schema_cache.tables = vec!["Orders".into(), "Customers".into()];
app.schema_cache.table_columns.insert(
"Orders".into(),
vec![TableColumn::new("id", Type::Serial), TableColumn::new("customer_id", Type::Int)],
vec![
TableColumn::new("id", Type::Serial),
TableColumn::new("customer_id", Type::Int),
],
);
app.schema_cache.table_columns.insert(
"Customers".into(),
vec![TableColumn::new("id", Type::Serial), TableColumn::new("name", Type::Text)],
vec![
TableColumn::new("id", Type::Serial),
TableColumn::new("name", Type::Text),
],
);
for t in app.schema_cache.tables.clone() {
for c in &app.schema_cache.table_columns[&t] {
@@ -5490,10 +5480,7 @@ mod tests {
detail: "SCAN Customers".to_string(),
}],
};
app.update(AppEvent::DslExplainSucceeded {
command: cmd,
plan,
});
app.update(AppEvent::DslExplainSucceeded { command: cmd, plan });
// ADR-0040: no `[ok] explain …` header — the (no-echo here)
// command's success shows via the marker; the plan output
// itself carries the content.
@@ -5549,7 +5536,11 @@ mod tests {
.iter()
.find(|l| l.kind == OutputKind::Echo)
.expect("dispatch pushed an echo");
assert_eq!(echo.status, Some(EchoStatus::Pending), "pending before result");
assert_eq!(
echo.status,
Some(EchoStatus::Pending),
"pending before result"
);
app.update(AppEvent::DslSucceeded {
command: Command::CreateTable {
name: "T".to_string(),
@@ -5639,8 +5630,14 @@ mod tests {
.collect::<Vec<_>>()
.join("\n");
assert!(text.contains("[ok] replay"), "summary present:\n{text}");
assert!(text.contains("import a.zip"), "import skip warning rendered:\n{text}");
assert!(text.contains("nested `replay x`"), "nested-replay skip warning rendered:\n{text}");
assert!(
text.contains("import a.zip"),
"import skip warning rendered:\n{text}"
);
assert!(
text.contains("nested `replay x`"),
"nested-replay skip warning rendered:\n{text}"
);
}
#[test]
@@ -5736,7 +5733,7 @@ mod tests {
#[test]
fn hint_command_parses_to_app_hint() {
use crate::dsl::{parse_command, AppCommand, Command};
use crate::dsl::{AppCommand, Command, parse_command};
assert!(matches!(
parse_command("hint"),
Ok(Command::App(AppCommand::Hint))
@@ -5747,7 +5744,7 @@ mod tests {
#[test]
fn version_command_parses_to_app_version() {
use crate::dsl::{parse_command, AppCommand, Command};
use crate::dsl::{AppCommand, Command, parse_command};
assert!(matches!(
parse_command("version"),
Ok(Command::App(AppCommand::Version))
@@ -5801,7 +5798,10 @@ mod tests {
let mut app = App::new();
type_str(&mut app, "show ");
app.update(key(KeyCode::Tab));
assert!(app.last_completion.is_some(), "precondition: Tab sets the memo");
assert!(
app.last_completion.is_some(),
"precondition: Tab sets the memo"
);
let input = app.input.clone();
f1(&mut app);
assert!(app.last_completion.is_some(), "F1 must not clear the memo");
@@ -5827,8 +5827,14 @@ mod tests {
let input = app.input.clone();
let before = app.output.len();
app.update(ctrl_g());
assert_eq!(app.input, input, "Ctrl-G must not change the buffer (no `g` typed)");
assert!(app.output.len() > before, "Ctrl-G must emit the same hint F1 does");
assert_eq!(
app.input, input,
"Ctrl-G must not change the buffer (no `g` typed)"
);
assert!(
app.output.len() > before,
"Ctrl-G must emit the same hint F1 does"
);
}
#[test]
@@ -5855,7 +5861,11 @@ mod tests {
let before = app.output.len();
app.update(ctrl_g());
assert_eq!(app.input, input, "Ctrl-G must not insert a `g`");
assert_eq!(app.output.len(), before, "Ctrl-G does nothing when demo mode is off");
assert_eq!(
app.output.len(),
before,
"Ctrl-G does nothing when demo mode is off"
);
}
#[test]
@@ -5949,7 +5959,10 @@ mod tests {
#[test]
fn f1_on_add_relationship_renders_the_relationship_block() {
let mut app = App::new();
type_str(&mut app, "add 1:n relationship from Customers.id to Orders.cust ");
type_str(
&mut app,
"add 1:n relationship from Customers.id to Orders.cust ",
);
f1(&mut app);
assert!(
output_contains(&app, "one parent, many children"),
@@ -6142,14 +6155,8 @@ mod tests {
let mut app = App::new();
let cmd = Command::Update {
table: "Customers".to_string(),
assignments: vec![(
"id".to_string(),
crate::dsl::Value::Number("7".to_string()),
)],
filter: crate::dsl::RowFilter::eq(
"name",
crate::dsl::Value::Text("Bob".to_string()),
),
assignments: vec![("id".to_string(), crate::dsl::Value::Number("7".to_string()))],
filter: crate::dsl::RowFilter::eq("name", crate::dsl::Value::Text("Bob".to_string())),
};
let err = crate::db::DbError::Sqlite {
message: "UNIQUE constraint failed: Customers.id".to_string(),
@@ -6709,7 +6716,10 @@ mod tests {
app.update(key(KeyCode::Backspace));
let actions = app.update(key(KeyCode::Enter));
assert_eq!(app.input, "select", "input untouched in navigation mode");
assert!(actions.is_empty(), "Enter does not submit in navigation mode");
assert!(
actions.is_empty(),
"Enter does not submit in navigation mode"
);
}
#[test]
@@ -6720,7 +6730,10 @@ mod tests {
app.update(key(KeyCode::Down));
app.update(key(KeyCode::Down));
assert_eq!(app.tables_scroll, 2);
assert_eq!(app.relationships_scroll, 0, "only the focused panel scrolls");
assert_eq!(
app.relationships_scroll, 0,
"only the focused panel scrolls"
);
app.update(key(KeyCode::Up));
assert_eq!(app.tables_scroll, 1);
// Up saturates at the top.
@@ -6998,7 +7011,8 @@ mod tests {
for round in 0..3 {
app.update(key(KeyCode::Up));
assert_eq!(
app.input, "insert into Thing values (1)",
app.input,
"insert into Thing values (1)",
"Up #{} should recall the newest entry",
round + 1,
);
@@ -7220,8 +7234,7 @@ mod tests {
has_default: false,
}],
);
app.input =
"select * from products where price like 5".to_string();
app.input = "select * from products where price like 5".to_string();
assert_eq!(
app.input_validity_verdict(),
Some(crate::dsl::walker::Severity::Warning),
@@ -7350,8 +7363,10 @@ mod tests {
"directly-deleted count surfaced: {texts:?}",
);
assert!(
texts.iter().any(|t| t.contains("2 row(s) deleted in `Orders`")
&& t.contains("relationship `places`")),
texts
.iter()
.any(|t| t.contains("2 row(s) deleted in `Orders`")
&& t.contains("relationship `places`")),
"per-relationship cascade summary surfaced: {texts:?}",
);
}
@@ -7386,11 +7401,15 @@ mod tests {
});
let texts: Vec<String> = app.output.iter().map(|l| l.text.clone()).collect();
assert!(
texts.iter().any(|t| t.contains("20 row(s) seeded into users")),
texts
.iter()
.any(|t| t.contains("20 row(s) seeded into users")),
"seeded-row count surfaced: {texts:?}",
);
assert!(
texts.iter().any(|t| t.contains("status") && t.contains("generic text")),
texts
.iter()
.any(|t| t.contains("status") && t.contains("generic text")),
"the advisory names the enum-ish column: {texts:?}",
);
}
@@ -7424,8 +7443,9 @@ mod tests {
});
let texts: Vec<String> = app.output.iter().map(|l| l.text.clone()).collect();
assert!(
texts.iter().any(|t| t.contains("4 row(s) seeded into J")
&& t.contains("of 10 requested")),
texts
.iter()
.any(|t| t.contains("4 row(s) seeded into J") && t.contains("of 10 requested")),
"the cap note surfaces requested vs produced: {texts:?}",
);
}
@@ -7464,7 +7484,9 @@ mod tests {
});
let texts: Vec<String> = app.output.iter().map(|l| l.text.clone()).collect();
assert!(
texts.iter().any(|t| t.contains("2 row(s) deleted in `Orders`")),
texts
.iter()
.any(|t| t.contains("2 row(s) deleted in `Orders`")),
"cascade summary still surfaces alongside RETURNING: {texts:?}",
);
assert!(