mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
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:
@@ -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).
|
- **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).
|
- **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.
|
- **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)]`.
|
- Crates carry `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`.
|
||||||
|
|
||||||
## Non-negotiables
|
## Non-negotiables
|
||||||
|
|||||||
@@ -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).
|
- **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).
|
- **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.
|
- **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)]`.
|
- Crates carry `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`.
|
||||||
|
|
||||||
## Non-negotiables
|
## Non-negotiables
|
||||||
|
|||||||
@@ -68,9 +68,11 @@ type_complexity = "allow"
|
|||||||
|
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
debug = false
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
debug = "line-tables-only"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Command, Output, Stdio};
|
use std::process::{Command, Output, Stdio};
|
||||||
@@ -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;
|
||||||
+2
-2
@@ -23,7 +23,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Knobs (environment variables):
|
//! Knobs (environment variables):
|
||||||
//! - `GRIDCRAFT_FUZZ_SEEDS` (default 6) and `GRIDCRAFT_FUZZ_STEPS` (default 40): the budget. Soak with
|
//! - `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_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
|
//! - `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.
|
//! 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()),
|
None => format!("end-of-run checks after {} steps", sequence.len()),
|
||||||
};
|
};
|
||||||
let mut out = format!(
|
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
|
f.kind, f.what
|
||||||
);
|
);
|
||||||
let end = (f.step + 1).min(sequence.len());
|
let end = (f.step + 1).min(sequence.len());
|
||||||
@@ -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;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
//! The crate's integration tests, one module per file, built as one test binary.
|
||||||
|
|
||||||
|
mod printer_roundtrip;
|
||||||
|
mod spanish_input;
|
||||||
@@ -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
Reference in New Issue
Block a user