CI: one test binary per crate, nextest, line tables only (#2372)

* CI: dev builds keep line tables only

* CI: one integration-test binary per crate

* CI: xtask runs tests with nextest, doctests apart, --keep-going on clippy and wasm

cargo xtask test runs the workspace tests (--lib --bins --tests) with cargo-nextest when it is installed, else cargo test, then the doctests. cargo xtask ci uses the same two steps.

* CI: docs name cargo xtask test

* CI: agent guides name the moved fuzz test

* CI: tests added on main join their crate's test binary
This commit is contained in:
aiongg
2026-10-23 12:59:46 -04:00
committed by GitHub
parent bdf8b8cc75
commit a7608ada6d
128 changed files with 186 additions and 27 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ People trust GridCraft with their numbers; a crash loses their work. **This outr
- **Input-derived numbers are hostile** (files, formulas, commands, MCP/control params): `get()` instead of indexing, checked/saturating arithmetic, cap input-sized allocations (huge ranges, `REPT`, `SEQUENCE`, whole-column references).
- **Bound recursion** (formula nesting, dependency chains, names referring to names).
- **Last-resort guard:** `Session::execute` catches escaped panics and restores the workbook. It's a safety net, not a licence.
- **Prove it:** every crash fix lands with a regression test (`tests::every_command_survives_empty_params` fuzzes every command; `crates/engine/tests/command_sequence_fuzz.rs` fuzzes random command sequences against undo/redo, XLSX round-trip and full-recalc invariants; soak it with `GRIDCRAFT_FUZZ_SEEDS`/`GRIDCRAFT_FUZZ_STEPS`, replay with `GRIDCRAFT_FUZZ_SEED`).
- **Prove it:** every crash fix lands with a regression test (`tests::every_command_survives_empty_params` fuzzes every command; `crates/engine/tests/it/command_sequence_fuzz.rs` fuzzes random command sequences against undo/redo, XLSX round-trip and full-recalc invariants; soak it with `GRIDCRAFT_FUZZ_SEEDS`/`GRIDCRAFT_FUZZ_STEPS`, replay with `GRIDCRAFT_FUZZ_SEED`).
- Crates carry `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`.
## Non-negotiables
+1 -1
View File
@@ -26,7 +26,7 @@ People trust GridCraft with their numbers; a crash loses their work. **This outr
- **Input-derived numbers are hostile** (files, formulas, commands, MCP/control params): `get()` instead of indexing, checked/saturating arithmetic, cap input-sized allocations (huge ranges, `REPT`, `SEQUENCE`, whole-column references).
- **Bound recursion** (formula nesting, dependency chains, names referring to names).
- **Last-resort guard:** `Session::execute` catches escaped panics and restores the workbook. It's a safety net, not a licence.
- **Prove it:** every crash fix lands with a regression test (`tests::every_command_survives_empty_params` fuzzes every command; `crates/engine/tests/command_sequence_fuzz.rs` fuzzes random command sequences against undo/redo, XLSX round-trip and full-recalc invariants; soak it with `GRIDCRAFT_FUZZ_SEEDS`/`GRIDCRAFT_FUZZ_STEPS`, replay with `GRIDCRAFT_FUZZ_SEED`).
- **Prove it:** every crash fix lands with a regression test (`tests::every_command_survives_empty_params` fuzzes every command; `crates/engine/tests/it/command_sequence_fuzz.rs` fuzzes random command sequences against undo/redo, XLSX round-trip and full-recalc invariants; soak it with `GRIDCRAFT_FUZZ_SEEDS`/`GRIDCRAFT_FUZZ_STEPS`, replay with `GRIDCRAFT_FUZZ_SEED`).
- Crates carry `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`.
## Non-negotiables
+2
View File
@@ -68,9 +68,11 @@ type_complexity = "allow"
[profile.dev.package."*"]
opt-level = 2
debug = false
[profile.dev]
opt-level = 1
debug = "line-tables-only"
[profile.release]
opt-level = 3
@@ -1,5 +1,3 @@
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Output, Stdio};
+5
View File
@@ -0,0 +1,5 @@
//! The crate's integration tests, one module per file, built as one test binary.
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
mod cli;
mod text_to_columns_quotes;
@@ -23,7 +23,7 @@
//!
//! Knobs (environment variables):
//! - `GRIDCRAFT_FUZZ_SEEDS` (default 6) and `GRIDCRAFT_FUZZ_STEPS` (default 40): the budget. Soak with
//! `GRIDCRAFT_FUZZ_SEEDS=200 GRIDCRAFT_FUZZ_STEPS=200 cargo test --release -p gridcraft-engine --test command_sequence_fuzz`.
//! `GRIDCRAFT_FUZZ_SEEDS=200 GRIDCRAFT_FUZZ_STEPS=200 cargo test --release -p gridcraft-engine --test it command_sequence_fuzz::`.
//! - `GRIDCRAFT_FUZZ_SEED=17`: replay that one seed (the failure message prints the command line).
//! - `GRIDCRAFT_FUZZ_SHRINK=1`: on failure, shrink the sequence to a minimal list of commands that
//! still fails the same way, printed as `execute` calls ready for a regression test.
@@ -138,7 +138,7 @@ fn report(seed: u64, steps: usize, sample: &str, sequence: &[Step], f: &Failure)
None => format!("end-of-run checks after {} steps", sequence.len()),
};
let mut out = format!(
"command-sequence fuzz failure: seed {seed} (sample `{sample}`), {at}\n invariant [{}]: {}\n replay: GRIDCRAFT_FUZZ_SEED={seed} GRIDCRAFT_FUZZ_STEPS={steps} cargo test -p gridcraft-engine --test command_sequence_fuzz\n",
"command-sequence fuzz failure: seed {seed} (sample `{sample}`), {at}\n invariant [{}]: {}\n replay: GRIDCRAFT_FUZZ_SEED={seed} GRIDCRAFT_FUZZ_STEPS={steps} cargo test -p gridcraft-engine --test it command_sequence_fuzz::\n",
f.kind, f.what
);
let end = (f.step + 1).min(sequence.len());
+29
View File
@@ -0,0 +1,29 @@
//! The crate's integration tests, one module per file, built as one test binary.
mod autofit_filter_buttons;
mod cf_formula_validate;
mod chart_workbook_names;
mod command_sequence_fuzz;
mod cross_sheet_cut;
mod csv_export_budget;
mod custom_filter_blanks;
mod custom_view_freeze;
mod dynamicmetadata;
mod extreme_selection_moves;
mod format_as_table_restyle;
mod hidden_sheet_navigation;
mod ink_roundtrip;
mod line_count_overflow;
mod long_operator_chains;
mod offset_overflow;
mod percent_entry;
mod pivot_unknown_func;
mod pivotchart_link;
mod range_fill_formats;
mod row_autofit;
mod sheet_name_quoting;
mod sparse_clear_invalidation;
mod stored_list_shape;
mod table_resize_overlap;
mod table_total_row_last_row;
mod wrap_row_height;
+4
View File
@@ -0,0 +1,4 @@
//! The crate's integration tests, one module per file, built as one test binary.
mod printer_roundtrip;
mod spanish_input;
+91
View File
@@ -0,0 +1,91 @@
//! The crate's integration tests, one module per file, built as one test binary.
//!
//! `header_autofit_fonts.rs` and `keytips.rs` stay separate binaries: they set process-wide state
//! (the installed-font catalog, a registered test command) that would leak into these tests.
mod accounting_fill;
mod advanced_filter;
mod argument_names;
mod autosave_persist;
mod borders;
mod cell_editor_caret;
mod cell_pictures;
mod chart_resize;
mod clipboard;
mod comments_pane;
mod commit_after_pointing;
mod committed_text_fields;
mod context_menu_stays_open;
mod control_timeout;
mod dialog_button_row;
mod dialog_confirm;
mod dialog_focus;
mod dialog_move;
mod drag_cursor;
mod file_menu;
mod fill_handle_double_click;
mod fill_handle_right_drag;
mod fill_options_button;
mod filter_list_scroll;
mod filter_menu_enter;
mod find_dialog_focus;
mod floating_pictures;
mod font_size_box;
mod format_painter;
mod formula_locale;
mod formula_point_headers;
mod formula_popup;
mod freeze_handles;
mod header_autofit;
mod header_column_drag;
mod host_chrome;
mod hyperlink_ctrl_click;
mod in_cell_editor_size;
mod in_cell_editor_wrap;
mod insert_copied_cells;
mod interaction;
mod interface_scale;
mod keyboard_shortcuts;
mod keytips_generated;
mod menu_hover;
mod merged_cells;
mod more_colors;
mod native_print;
mod nowrap_line_breaks;
mod number_stored_as_text;
mod open_encrypted;
mod outline;
mod page_layout_view;
mod page_setup_margins;
mod paste_special_dialog;
mod pivot_pane;
mod popup_dismissal;
mod protect_password;
mod right_to_left;
mod scroll_position;
mod scrollbar_column_fill;
mod selection;
mod selection_fill;
mod selection_glide;
mod selection_scroll;
mod sheet_navigator;
mod sheet_tab_rename;
mod sheet_tabs;
mod show_objects;
mod shrink_to_fit;
mod sort_dialog_columns;
mod symbol_glyphs;
mod system_theme;
mod table_headings;
mod text_box_editing;
mod text_overflow_scroll;
mod touch_pan;
mod trace_navigation;
mod translated_form_fields;
mod ui_clock;
mod validation_alert;
mod validation_input_message;
mod wheel_zoom;
mod whole_line_shortcuts;
mod widgets;
mod zoom_dialog;

Some files were not shown because too many files have changed in this diff Show More