From a7608ada6dc91f9caf53f9eb7c2cdb3231ab1e75 Mon Sep 17 00:00:00 2001 From: aiongg <67543387+aiongg@users.noreply.github.com> Date: Fri, 23 Oct 2026 12:59:46 -0400 Subject: [PATCH] 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 --- AGENTS.md | 2 +- CLAUDE.md | 2 +- Cargo.toml | 2 + apps/gridcraft-cli/tests/{ => it}/cli.rs | 2 - apps/gridcraft-cli/tests/it/main.rs | 5 + .../tests/{ => it}/text_to_columns_quotes.rs | 0 .../tests/{ => it}/autofit_filter_buttons.rs | 0 .../tests/{ => it}/cf_formula_validate.rs | 0 .../tests/{ => it}/chart_workbook_names.rs | 0 .../tests/{ => it}/command_sequence_fuzz.rs | 4 +- .../engine/tests/{ => it}/cross_sheet_cut.rs | 0 .../tests/{ => it}/csv_export_budget.rs | 0 .../tests/{ => it}/custom_filter_blanks.rs | 0 .../tests/{ => it}/custom_view_freeze.rs | 0 .../engine/tests/{ => it}/dynamicmetadata.rs | 0 .../tests/{ => it}/extreme_selection_moves.rs | 0 .../tests/{ => it}/format_as_table_restyle.rs | 0 .../tests/{ => it}/hidden_sheet_navigation.rs | 0 crates/engine/tests/{ => it}/ink_roundtrip.rs | 0 .../tests/{ => it}/line_count_overflow.rs | 0 .../long_operator_chains.rs} | 0 crates/engine/tests/it/main.rs | 29 ++++++ .../engine/tests/{ => it}/offset_overflow.rs | 0 crates/engine/tests/{ => it}/percent_entry.rs | 0 .../tests/{ => it}/pivot_unknown_func.rs | 0 .../engine/tests/{ => it}/pivotchart_link.rs | 0 .../tests/{ => it}/range_fill_formats.rs | 0 crates/engine/tests/{ => it}/row_autofit.rs | 0 .../tests/{ => it}/sheet_name_quoting.rs | 0 .../{ => it}/sparse_clear_invalidation.rs | 0 .../tests/{ => it}/stored_list_shape.rs | 0 .../tests/{ => it}/table_resize_overlap.rs | 0 .../{ => it}/table_total_row_last_row.rs | 0 .../engine/tests/{ => it}/wrap_row_height.rs | 0 crates/formula/tests/it/main.rs | 4 + .../tests/{ => it}/printer_roundtrip.rs | 0 .../formula/tests/{ => it}/spanish_input.rs | 0 .../ui-egui/tests/{ => it}/accounting_fill.rs | 0 .../ui-egui/tests/{ => it}/advanced_filter.rs | 0 .../ui-egui/tests/{ => it}/argument_names.rs | 0 .../tests/{ => it}/autosave_persist.rs | 0 crates/ui-egui/tests/{ => it}/borders.rs | 0 .../tests/{ => it}/cell_editor_caret.rs | 0 .../ui-egui/tests/{ => it}/cell_pictures.rs | 0 crates/ui-egui/tests/{ => it}/chart_resize.rs | 0 crates/ui-egui/tests/{ => it}/clipboard.rs | 0 .../ui-egui/tests/{ => it}/comments_pane.rs | 0 .../tests/{ => it}/commit_after_pointing.rs | 0 .../tests/{ => it}/committed_text_fields.rs | 0 .../tests/{ => it}/context_menu_stays_open.rs | 0 .../ui-egui/tests/{ => it}/control_timeout.rs | 0 .../tests/{ => it}/dialog_button_row.rs | 0 .../ui-egui/tests/{ => it}/dialog_confirm.rs | 0 crates/ui-egui/tests/{ => it}/dialog_focus.rs | 0 crates/ui-egui/tests/{ => it}/dialog_move.rs | 0 crates/ui-egui/tests/{ => it}/drag_cursor.rs | 0 crates/ui-egui/tests/{ => it}/file_menu.rs | 0 .../{ => it}/fill_handle_double_click.rs | 0 .../tests/{ => it}/fill_handle_right_drag.rs | 0 .../tests/{ => it}/fill_options_button.rs | 0 .../tests/{ => it}/filter_list_scroll.rs | 0 .../tests/{ => it}/filter_menu_enter.rs | 0 .../tests/{ => it}/find_dialog_focus.rs | 0 .../tests/{ => it}/floating_pictures.rs | 0 .../ui-egui/tests/{ => it}/font_size_box.rs | 0 .../ui-egui/tests/{ => it}/format_painter.rs | 0 .../ui-egui/tests/{ => it}/formula_locale.rs | 0 .../tests/{ => it}/formula_point_headers.rs | 0 .../ui-egui/tests/{ => it}/formula_popup.rs | 0 .../ui-egui/tests/{ => it}/freeze_handles.rs | 0 .../ui-egui/tests/{ => it}/header_autofit.rs | 0 .../tests/{ => it}/header_column_drag.rs | 0 crates/ui-egui/tests/{ => it}/host_chrome.rs | 0 .../tests/{ => it}/hyperlink_ctrl_click.rs | 0 .../tests/{ => it}/in_cell_editor_size.rs | 0 .../tests/{ => it}/in_cell_editor_wrap.rs | 0 .../tests/{ => it}/insert_copied_cells.rs | 0 crates/ui-egui/tests/{ => it}/interaction.rs | 0 .../ui-egui/tests/{ => it}/interface_scale.rs | 0 .../tests/{ => it}/keyboard_shortcuts.rs | 0 .../tests/{ => it}/keytips_generated.rs | 0 crates/ui-egui/tests/it/main.rs | 91 +++++++++++++++++++ crates/ui-egui/tests/{ => it}/menu_hover.rs | 0 crates/ui-egui/tests/{ => it}/merged_cells.rs | 0 crates/ui-egui/tests/{ => it}/more_colors.rs | 0 crates/ui-egui/tests/{ => it}/native_print.rs | 0 .../tests/{ => it}/nowrap_line_breaks.rs | 0 .../tests/{ => it}/number_stored_as_text.rs | 0 .../ui-egui/tests/{ => it}/open_encrypted.rs | 0 crates/ui-egui/tests/{ => it}/outline.rs | 0 .../tests/{ => it}/page_layout_view.rs | 0 .../tests/{ => it}/page_setup_margins.rs | 0 .../tests/{ => it}/paste_special_dialog.rs | 0 crates/ui-egui/tests/{ => it}/pivot_pane.rs | 0 .../ui-egui/tests/{ => it}/popup_dismissal.rs | 0 .../tests/{ => it}/protect_password.rs | 0 .../ui-egui/tests/{ => it}/right_to_left.rs | 0 .../ui-egui/tests/{ => it}/scroll_position.rs | 0 .../tests/{ => it}/scrollbar_column_fill.rs | 0 crates/ui-egui/tests/{ => it}/selection.rs | 0 .../ui-egui/tests/{ => it}/selection_fill.rs | 0 .../ui-egui/tests/{ => it}/selection_glide.rs | 0 .../tests/{ => it}/selection_scroll.rs | 0 .../ui-egui/tests/{ => it}/sheet_navigator.rs | 0 .../tests/{ => it}/sheet_tab_rename.rs | 0 crates/ui-egui/tests/{ => it}/sheet_tabs.rs | 0 crates/ui-egui/tests/{ => it}/show_objects.rs | 0 .../ui-egui/tests/{ => it}/shrink_to_fit.rs | 0 .../tests/{ => it}/sort_dialog_columns.rs | 0 .../ui-egui/tests/{ => it}/symbol_glyphs.rs | 0 crates/ui-egui/tests/{ => it}/system_theme.rs | 0 .../ui-egui/tests/{ => it}/table_headings.rs | 0 .../tests/{ => it}/text_box_editing.rs | 0 .../tests/{ => it}/text_overflow_scroll.rs | 0 crates/ui-egui/tests/{ => it}/touch_pan.rs | 0 .../tests/{ => it}/trace_navigation.rs | 0 .../tests/{ => it}/translated_form_fields.rs | 0 crates/ui-egui/tests/{ => it}/ui_clock.rs | 0 .../tests/{ => it}/validation_alert.rs | 0 .../{ => it}/validation_input_message.rs | 0 crates/ui-egui/tests/{ => it}/wheel_zoom.rs | 0 .../tests/{ => it}/whole_line_shortcuts.rs | 0 crates/ui-egui/tests/{ => it}/widgets.rs | 0 crates/ui-egui/tests/{ => it}/zoom_dialog.rs | 0 docs/roadmap.md | 6 +- docs/target-app-parity.md | 2 +- xtask/src/keytips.rs | 4 +- xtask/src/main.rs | 60 ++++++++---- 128 files changed, 186 insertions(+), 27 deletions(-) rename apps/gridcraft-cli/tests/{ => it}/cli.rs (99%) create mode 100644 apps/gridcraft-cli/tests/it/main.rs rename apps/gridcraft-cli/tests/{ => it}/text_to_columns_quotes.rs (100%) rename crates/engine/tests/{ => it}/autofit_filter_buttons.rs (100%) rename crates/engine/tests/{ => it}/cf_formula_validate.rs (100%) rename crates/engine/tests/{ => it}/chart_workbook_names.rs (100%) rename crates/engine/tests/{ => it}/command_sequence_fuzz.rs (99%) rename crates/engine/tests/{ => it}/cross_sheet_cut.rs (100%) rename crates/engine/tests/{ => it}/csv_export_budget.rs (100%) rename crates/engine/tests/{ => it}/custom_filter_blanks.rs (100%) rename crates/engine/tests/{ => it}/custom_view_freeze.rs (100%) rename crates/engine/tests/{ => it}/dynamicmetadata.rs (100%) rename crates/engine/tests/{ => it}/extreme_selection_moves.rs (100%) rename crates/engine/tests/{ => it}/format_as_table_restyle.rs (100%) rename crates/engine/tests/{ => it}/hidden_sheet_navigation.rs (100%) rename crates/engine/tests/{ => it}/ink_roundtrip.rs (100%) rename crates/engine/tests/{ => it}/line_count_overflow.rs (100%) rename crates/engine/tests/{long-operator-chains.rs => it/long_operator_chains.rs} (100%) create mode 100644 crates/engine/tests/it/main.rs rename crates/engine/tests/{ => it}/offset_overflow.rs (100%) rename crates/engine/tests/{ => it}/percent_entry.rs (100%) rename crates/engine/tests/{ => it}/pivot_unknown_func.rs (100%) rename crates/engine/tests/{ => it}/pivotchart_link.rs (100%) rename crates/engine/tests/{ => it}/range_fill_formats.rs (100%) rename crates/engine/tests/{ => it}/row_autofit.rs (100%) rename crates/engine/tests/{ => it}/sheet_name_quoting.rs (100%) rename crates/engine/tests/{ => it}/sparse_clear_invalidation.rs (100%) rename crates/engine/tests/{ => it}/stored_list_shape.rs (100%) rename crates/engine/tests/{ => it}/table_resize_overlap.rs (100%) rename crates/engine/tests/{ => it}/table_total_row_last_row.rs (100%) rename crates/engine/tests/{ => it}/wrap_row_height.rs (100%) create mode 100644 crates/formula/tests/it/main.rs rename crates/formula/tests/{ => it}/printer_roundtrip.rs (100%) rename crates/formula/tests/{ => it}/spanish_input.rs (100%) rename crates/ui-egui/tests/{ => it}/accounting_fill.rs (100%) rename crates/ui-egui/tests/{ => it}/advanced_filter.rs (100%) rename crates/ui-egui/tests/{ => it}/argument_names.rs (100%) rename crates/ui-egui/tests/{ => it}/autosave_persist.rs (100%) rename crates/ui-egui/tests/{ => it}/borders.rs (100%) rename crates/ui-egui/tests/{ => it}/cell_editor_caret.rs (100%) rename crates/ui-egui/tests/{ => it}/cell_pictures.rs (100%) rename crates/ui-egui/tests/{ => it}/chart_resize.rs (100%) rename crates/ui-egui/tests/{ => it}/clipboard.rs (100%) rename crates/ui-egui/tests/{ => it}/comments_pane.rs (100%) rename crates/ui-egui/tests/{ => it}/commit_after_pointing.rs (100%) rename crates/ui-egui/tests/{ => it}/committed_text_fields.rs (100%) rename crates/ui-egui/tests/{ => it}/context_menu_stays_open.rs (100%) rename crates/ui-egui/tests/{ => it}/control_timeout.rs (100%) rename crates/ui-egui/tests/{ => it}/dialog_button_row.rs (100%) rename crates/ui-egui/tests/{ => it}/dialog_confirm.rs (100%) rename crates/ui-egui/tests/{ => it}/dialog_focus.rs (100%) rename crates/ui-egui/tests/{ => it}/dialog_move.rs (100%) rename crates/ui-egui/tests/{ => it}/drag_cursor.rs (100%) rename crates/ui-egui/tests/{ => it}/file_menu.rs (100%) rename crates/ui-egui/tests/{ => it}/fill_handle_double_click.rs (100%) rename crates/ui-egui/tests/{ => it}/fill_handle_right_drag.rs (100%) rename crates/ui-egui/tests/{ => it}/fill_options_button.rs (100%) rename crates/ui-egui/tests/{ => it}/filter_list_scroll.rs (100%) rename crates/ui-egui/tests/{ => it}/filter_menu_enter.rs (100%) rename crates/ui-egui/tests/{ => it}/find_dialog_focus.rs (100%) rename crates/ui-egui/tests/{ => it}/floating_pictures.rs (100%) rename crates/ui-egui/tests/{ => it}/font_size_box.rs (100%) rename crates/ui-egui/tests/{ => it}/format_painter.rs (100%) rename crates/ui-egui/tests/{ => it}/formula_locale.rs (100%) rename crates/ui-egui/tests/{ => it}/formula_point_headers.rs (100%) rename crates/ui-egui/tests/{ => it}/formula_popup.rs (100%) rename crates/ui-egui/tests/{ => it}/freeze_handles.rs (100%) rename crates/ui-egui/tests/{ => it}/header_autofit.rs (100%) rename crates/ui-egui/tests/{ => it}/header_column_drag.rs (100%) rename crates/ui-egui/tests/{ => it}/host_chrome.rs (100%) rename crates/ui-egui/tests/{ => it}/hyperlink_ctrl_click.rs (100%) rename crates/ui-egui/tests/{ => it}/in_cell_editor_size.rs (100%) rename crates/ui-egui/tests/{ => it}/in_cell_editor_wrap.rs (100%) rename crates/ui-egui/tests/{ => it}/insert_copied_cells.rs (100%) rename crates/ui-egui/tests/{ => it}/interaction.rs (100%) rename crates/ui-egui/tests/{ => it}/interface_scale.rs (100%) rename crates/ui-egui/tests/{ => it}/keyboard_shortcuts.rs (100%) rename crates/ui-egui/tests/{ => it}/keytips_generated.rs (100%) create mode 100644 crates/ui-egui/tests/it/main.rs rename crates/ui-egui/tests/{ => it}/menu_hover.rs (100%) rename crates/ui-egui/tests/{ => it}/merged_cells.rs (100%) rename crates/ui-egui/tests/{ => it}/more_colors.rs (100%) rename crates/ui-egui/tests/{ => it}/native_print.rs (100%) rename crates/ui-egui/tests/{ => it}/nowrap_line_breaks.rs (100%) rename crates/ui-egui/tests/{ => it}/number_stored_as_text.rs (100%) rename crates/ui-egui/tests/{ => it}/open_encrypted.rs (100%) rename crates/ui-egui/tests/{ => it}/outline.rs (100%) rename crates/ui-egui/tests/{ => it}/page_layout_view.rs (100%) rename crates/ui-egui/tests/{ => it}/page_setup_margins.rs (100%) rename crates/ui-egui/tests/{ => it}/paste_special_dialog.rs (100%) rename crates/ui-egui/tests/{ => it}/pivot_pane.rs (100%) rename crates/ui-egui/tests/{ => it}/popup_dismissal.rs (100%) rename crates/ui-egui/tests/{ => it}/protect_password.rs (100%) rename crates/ui-egui/tests/{ => it}/right_to_left.rs (100%) rename crates/ui-egui/tests/{ => it}/scroll_position.rs (100%) rename crates/ui-egui/tests/{ => it}/scrollbar_column_fill.rs (100%) rename crates/ui-egui/tests/{ => it}/selection.rs (100%) rename crates/ui-egui/tests/{ => it}/selection_fill.rs (100%) rename crates/ui-egui/tests/{ => it}/selection_glide.rs (100%) rename crates/ui-egui/tests/{ => it}/selection_scroll.rs (100%) rename crates/ui-egui/tests/{ => it}/sheet_navigator.rs (100%) rename crates/ui-egui/tests/{ => it}/sheet_tab_rename.rs (100%) rename crates/ui-egui/tests/{ => it}/sheet_tabs.rs (100%) rename crates/ui-egui/tests/{ => it}/show_objects.rs (100%) rename crates/ui-egui/tests/{ => it}/shrink_to_fit.rs (100%) rename crates/ui-egui/tests/{ => it}/sort_dialog_columns.rs (100%) rename crates/ui-egui/tests/{ => it}/symbol_glyphs.rs (100%) rename crates/ui-egui/tests/{ => it}/system_theme.rs (100%) rename crates/ui-egui/tests/{ => it}/table_headings.rs (100%) rename crates/ui-egui/tests/{ => it}/text_box_editing.rs (100%) rename crates/ui-egui/tests/{ => it}/text_overflow_scroll.rs (100%) rename crates/ui-egui/tests/{ => it}/touch_pan.rs (100%) rename crates/ui-egui/tests/{ => it}/trace_navigation.rs (100%) rename crates/ui-egui/tests/{ => it}/translated_form_fields.rs (100%) rename crates/ui-egui/tests/{ => it}/ui_clock.rs (100%) rename crates/ui-egui/tests/{ => it}/validation_alert.rs (100%) rename crates/ui-egui/tests/{ => it}/validation_input_message.rs (100%) rename crates/ui-egui/tests/{ => it}/wheel_zoom.rs (100%) rename crates/ui-egui/tests/{ => it}/whole_line_shortcuts.rs (100%) rename crates/ui-egui/tests/{ => it}/widgets.rs (100%) rename crates/ui-egui/tests/{ => it}/zoom_dialog.rs (100%) diff --git a/AGENTS.md b/AGENTS.md index ab73047e..7fd1629c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index 280fe8bc..1d1a77d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/Cargo.toml b/Cargo.toml index 9994d44e..4d3fd4b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/apps/gridcraft-cli/tests/cli.rs b/apps/gridcraft-cli/tests/it/cli.rs similarity index 99% rename from apps/gridcraft-cli/tests/cli.rs rename to apps/gridcraft-cli/tests/it/cli.rs index 5295368e..dde018ca 100644 --- a/apps/gridcraft-cli/tests/cli.rs +++ b/apps/gridcraft-cli/tests/it/cli.rs @@ -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}; diff --git a/apps/gridcraft-cli/tests/it/main.rs b/apps/gridcraft-cli/tests/it/main.rs new file mode 100644 index 00000000..17f8db87 --- /dev/null +++ b/apps/gridcraft-cli/tests/it/main.rs @@ -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; diff --git a/apps/gridcraft-cli/tests/text_to_columns_quotes.rs b/apps/gridcraft-cli/tests/it/text_to_columns_quotes.rs similarity index 100% rename from apps/gridcraft-cli/tests/text_to_columns_quotes.rs rename to apps/gridcraft-cli/tests/it/text_to_columns_quotes.rs diff --git a/crates/engine/tests/autofit_filter_buttons.rs b/crates/engine/tests/it/autofit_filter_buttons.rs similarity index 100% rename from crates/engine/tests/autofit_filter_buttons.rs rename to crates/engine/tests/it/autofit_filter_buttons.rs diff --git a/crates/engine/tests/cf_formula_validate.rs b/crates/engine/tests/it/cf_formula_validate.rs similarity index 100% rename from crates/engine/tests/cf_formula_validate.rs rename to crates/engine/tests/it/cf_formula_validate.rs diff --git a/crates/engine/tests/chart_workbook_names.rs b/crates/engine/tests/it/chart_workbook_names.rs similarity index 100% rename from crates/engine/tests/chart_workbook_names.rs rename to crates/engine/tests/it/chart_workbook_names.rs diff --git a/crates/engine/tests/command_sequence_fuzz.rs b/crates/engine/tests/it/command_sequence_fuzz.rs similarity index 99% rename from crates/engine/tests/command_sequence_fuzz.rs rename to crates/engine/tests/it/command_sequence_fuzz.rs index f8cb603c..012757f6 100644 --- a/crates/engine/tests/command_sequence_fuzz.rs +++ b/crates/engine/tests/it/command_sequence_fuzz.rs @@ -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()); diff --git a/crates/engine/tests/cross_sheet_cut.rs b/crates/engine/tests/it/cross_sheet_cut.rs similarity index 100% rename from crates/engine/tests/cross_sheet_cut.rs rename to crates/engine/tests/it/cross_sheet_cut.rs diff --git a/crates/engine/tests/csv_export_budget.rs b/crates/engine/tests/it/csv_export_budget.rs similarity index 100% rename from crates/engine/tests/csv_export_budget.rs rename to crates/engine/tests/it/csv_export_budget.rs diff --git a/crates/engine/tests/custom_filter_blanks.rs b/crates/engine/tests/it/custom_filter_blanks.rs similarity index 100% rename from crates/engine/tests/custom_filter_blanks.rs rename to crates/engine/tests/it/custom_filter_blanks.rs diff --git a/crates/engine/tests/custom_view_freeze.rs b/crates/engine/tests/it/custom_view_freeze.rs similarity index 100% rename from crates/engine/tests/custom_view_freeze.rs rename to crates/engine/tests/it/custom_view_freeze.rs diff --git a/crates/engine/tests/dynamicmetadata.rs b/crates/engine/tests/it/dynamicmetadata.rs similarity index 100% rename from crates/engine/tests/dynamicmetadata.rs rename to crates/engine/tests/it/dynamicmetadata.rs diff --git a/crates/engine/tests/extreme_selection_moves.rs b/crates/engine/tests/it/extreme_selection_moves.rs similarity index 100% rename from crates/engine/tests/extreme_selection_moves.rs rename to crates/engine/tests/it/extreme_selection_moves.rs diff --git a/crates/engine/tests/format_as_table_restyle.rs b/crates/engine/tests/it/format_as_table_restyle.rs similarity index 100% rename from crates/engine/tests/format_as_table_restyle.rs rename to crates/engine/tests/it/format_as_table_restyle.rs diff --git a/crates/engine/tests/hidden_sheet_navigation.rs b/crates/engine/tests/it/hidden_sheet_navigation.rs similarity index 100% rename from crates/engine/tests/hidden_sheet_navigation.rs rename to crates/engine/tests/it/hidden_sheet_navigation.rs diff --git a/crates/engine/tests/ink_roundtrip.rs b/crates/engine/tests/it/ink_roundtrip.rs similarity index 100% rename from crates/engine/tests/ink_roundtrip.rs rename to crates/engine/tests/it/ink_roundtrip.rs diff --git a/crates/engine/tests/line_count_overflow.rs b/crates/engine/tests/it/line_count_overflow.rs similarity index 100% rename from crates/engine/tests/line_count_overflow.rs rename to crates/engine/tests/it/line_count_overflow.rs diff --git a/crates/engine/tests/long-operator-chains.rs b/crates/engine/tests/it/long_operator_chains.rs similarity index 100% rename from crates/engine/tests/long-operator-chains.rs rename to crates/engine/tests/it/long_operator_chains.rs diff --git a/crates/engine/tests/it/main.rs b/crates/engine/tests/it/main.rs new file mode 100644 index 00000000..385ec76c --- /dev/null +++ b/crates/engine/tests/it/main.rs @@ -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; diff --git a/crates/engine/tests/offset_overflow.rs b/crates/engine/tests/it/offset_overflow.rs similarity index 100% rename from crates/engine/tests/offset_overflow.rs rename to crates/engine/tests/it/offset_overflow.rs diff --git a/crates/engine/tests/percent_entry.rs b/crates/engine/tests/it/percent_entry.rs similarity index 100% rename from crates/engine/tests/percent_entry.rs rename to crates/engine/tests/it/percent_entry.rs diff --git a/crates/engine/tests/pivot_unknown_func.rs b/crates/engine/tests/it/pivot_unknown_func.rs similarity index 100% rename from crates/engine/tests/pivot_unknown_func.rs rename to crates/engine/tests/it/pivot_unknown_func.rs diff --git a/crates/engine/tests/pivotchart_link.rs b/crates/engine/tests/it/pivotchart_link.rs similarity index 100% rename from crates/engine/tests/pivotchart_link.rs rename to crates/engine/tests/it/pivotchart_link.rs diff --git a/crates/engine/tests/range_fill_formats.rs b/crates/engine/tests/it/range_fill_formats.rs similarity index 100% rename from crates/engine/tests/range_fill_formats.rs rename to crates/engine/tests/it/range_fill_formats.rs diff --git a/crates/engine/tests/row_autofit.rs b/crates/engine/tests/it/row_autofit.rs similarity index 100% rename from crates/engine/tests/row_autofit.rs rename to crates/engine/tests/it/row_autofit.rs diff --git a/crates/engine/tests/sheet_name_quoting.rs b/crates/engine/tests/it/sheet_name_quoting.rs similarity index 100% rename from crates/engine/tests/sheet_name_quoting.rs rename to crates/engine/tests/it/sheet_name_quoting.rs diff --git a/crates/engine/tests/sparse_clear_invalidation.rs b/crates/engine/tests/it/sparse_clear_invalidation.rs similarity index 100% rename from crates/engine/tests/sparse_clear_invalidation.rs rename to crates/engine/tests/it/sparse_clear_invalidation.rs diff --git a/crates/engine/tests/stored_list_shape.rs b/crates/engine/tests/it/stored_list_shape.rs similarity index 100% rename from crates/engine/tests/stored_list_shape.rs rename to crates/engine/tests/it/stored_list_shape.rs diff --git a/crates/engine/tests/table_resize_overlap.rs b/crates/engine/tests/it/table_resize_overlap.rs similarity index 100% rename from crates/engine/tests/table_resize_overlap.rs rename to crates/engine/tests/it/table_resize_overlap.rs diff --git a/crates/engine/tests/table_total_row_last_row.rs b/crates/engine/tests/it/table_total_row_last_row.rs similarity index 100% rename from crates/engine/tests/table_total_row_last_row.rs rename to crates/engine/tests/it/table_total_row_last_row.rs diff --git a/crates/engine/tests/wrap_row_height.rs b/crates/engine/tests/it/wrap_row_height.rs similarity index 100% rename from crates/engine/tests/wrap_row_height.rs rename to crates/engine/tests/it/wrap_row_height.rs diff --git a/crates/formula/tests/it/main.rs b/crates/formula/tests/it/main.rs new file mode 100644 index 00000000..01bff98c --- /dev/null +++ b/crates/formula/tests/it/main.rs @@ -0,0 +1,4 @@ +//! The crate's integration tests, one module per file, built as one test binary. + +mod printer_roundtrip; +mod spanish_input; diff --git a/crates/formula/tests/printer_roundtrip.rs b/crates/formula/tests/it/printer_roundtrip.rs similarity index 100% rename from crates/formula/tests/printer_roundtrip.rs rename to crates/formula/tests/it/printer_roundtrip.rs diff --git a/crates/formula/tests/spanish_input.rs b/crates/formula/tests/it/spanish_input.rs similarity index 100% rename from crates/formula/tests/spanish_input.rs rename to crates/formula/tests/it/spanish_input.rs diff --git a/crates/ui-egui/tests/accounting_fill.rs b/crates/ui-egui/tests/it/accounting_fill.rs similarity index 100% rename from crates/ui-egui/tests/accounting_fill.rs rename to crates/ui-egui/tests/it/accounting_fill.rs diff --git a/crates/ui-egui/tests/advanced_filter.rs b/crates/ui-egui/tests/it/advanced_filter.rs similarity index 100% rename from crates/ui-egui/tests/advanced_filter.rs rename to crates/ui-egui/tests/it/advanced_filter.rs diff --git a/crates/ui-egui/tests/argument_names.rs b/crates/ui-egui/tests/it/argument_names.rs similarity index 100% rename from crates/ui-egui/tests/argument_names.rs rename to crates/ui-egui/tests/it/argument_names.rs diff --git a/crates/ui-egui/tests/autosave_persist.rs b/crates/ui-egui/tests/it/autosave_persist.rs similarity index 100% rename from crates/ui-egui/tests/autosave_persist.rs rename to crates/ui-egui/tests/it/autosave_persist.rs diff --git a/crates/ui-egui/tests/borders.rs b/crates/ui-egui/tests/it/borders.rs similarity index 100% rename from crates/ui-egui/tests/borders.rs rename to crates/ui-egui/tests/it/borders.rs diff --git a/crates/ui-egui/tests/cell_editor_caret.rs b/crates/ui-egui/tests/it/cell_editor_caret.rs similarity index 100% rename from crates/ui-egui/tests/cell_editor_caret.rs rename to crates/ui-egui/tests/it/cell_editor_caret.rs diff --git a/crates/ui-egui/tests/cell_pictures.rs b/crates/ui-egui/tests/it/cell_pictures.rs similarity index 100% rename from crates/ui-egui/tests/cell_pictures.rs rename to crates/ui-egui/tests/it/cell_pictures.rs diff --git a/crates/ui-egui/tests/chart_resize.rs b/crates/ui-egui/tests/it/chart_resize.rs similarity index 100% rename from crates/ui-egui/tests/chart_resize.rs rename to crates/ui-egui/tests/it/chart_resize.rs diff --git a/crates/ui-egui/tests/clipboard.rs b/crates/ui-egui/tests/it/clipboard.rs similarity index 100% rename from crates/ui-egui/tests/clipboard.rs rename to crates/ui-egui/tests/it/clipboard.rs diff --git a/crates/ui-egui/tests/comments_pane.rs b/crates/ui-egui/tests/it/comments_pane.rs similarity index 100% rename from crates/ui-egui/tests/comments_pane.rs rename to crates/ui-egui/tests/it/comments_pane.rs diff --git a/crates/ui-egui/tests/commit_after_pointing.rs b/crates/ui-egui/tests/it/commit_after_pointing.rs similarity index 100% rename from crates/ui-egui/tests/commit_after_pointing.rs rename to crates/ui-egui/tests/it/commit_after_pointing.rs diff --git a/crates/ui-egui/tests/committed_text_fields.rs b/crates/ui-egui/tests/it/committed_text_fields.rs similarity index 100% rename from crates/ui-egui/tests/committed_text_fields.rs rename to crates/ui-egui/tests/it/committed_text_fields.rs diff --git a/crates/ui-egui/tests/context_menu_stays_open.rs b/crates/ui-egui/tests/it/context_menu_stays_open.rs similarity index 100% rename from crates/ui-egui/tests/context_menu_stays_open.rs rename to crates/ui-egui/tests/it/context_menu_stays_open.rs diff --git a/crates/ui-egui/tests/control_timeout.rs b/crates/ui-egui/tests/it/control_timeout.rs similarity index 100% rename from crates/ui-egui/tests/control_timeout.rs rename to crates/ui-egui/tests/it/control_timeout.rs diff --git a/crates/ui-egui/tests/dialog_button_row.rs b/crates/ui-egui/tests/it/dialog_button_row.rs similarity index 100% rename from crates/ui-egui/tests/dialog_button_row.rs rename to crates/ui-egui/tests/it/dialog_button_row.rs diff --git a/crates/ui-egui/tests/dialog_confirm.rs b/crates/ui-egui/tests/it/dialog_confirm.rs similarity index 100% rename from crates/ui-egui/tests/dialog_confirm.rs rename to crates/ui-egui/tests/it/dialog_confirm.rs diff --git a/crates/ui-egui/tests/dialog_focus.rs b/crates/ui-egui/tests/it/dialog_focus.rs similarity index 100% rename from crates/ui-egui/tests/dialog_focus.rs rename to crates/ui-egui/tests/it/dialog_focus.rs diff --git a/crates/ui-egui/tests/dialog_move.rs b/crates/ui-egui/tests/it/dialog_move.rs similarity index 100% rename from crates/ui-egui/tests/dialog_move.rs rename to crates/ui-egui/tests/it/dialog_move.rs diff --git a/crates/ui-egui/tests/drag_cursor.rs b/crates/ui-egui/tests/it/drag_cursor.rs similarity index 100% rename from crates/ui-egui/tests/drag_cursor.rs rename to crates/ui-egui/tests/it/drag_cursor.rs diff --git a/crates/ui-egui/tests/file_menu.rs b/crates/ui-egui/tests/it/file_menu.rs similarity index 100% rename from crates/ui-egui/tests/file_menu.rs rename to crates/ui-egui/tests/it/file_menu.rs diff --git a/crates/ui-egui/tests/fill_handle_double_click.rs b/crates/ui-egui/tests/it/fill_handle_double_click.rs similarity index 100% rename from crates/ui-egui/tests/fill_handle_double_click.rs rename to crates/ui-egui/tests/it/fill_handle_double_click.rs diff --git a/crates/ui-egui/tests/fill_handle_right_drag.rs b/crates/ui-egui/tests/it/fill_handle_right_drag.rs similarity index 100% rename from crates/ui-egui/tests/fill_handle_right_drag.rs rename to crates/ui-egui/tests/it/fill_handle_right_drag.rs diff --git a/crates/ui-egui/tests/fill_options_button.rs b/crates/ui-egui/tests/it/fill_options_button.rs similarity index 100% rename from crates/ui-egui/tests/fill_options_button.rs rename to crates/ui-egui/tests/it/fill_options_button.rs diff --git a/crates/ui-egui/tests/filter_list_scroll.rs b/crates/ui-egui/tests/it/filter_list_scroll.rs similarity index 100% rename from crates/ui-egui/tests/filter_list_scroll.rs rename to crates/ui-egui/tests/it/filter_list_scroll.rs diff --git a/crates/ui-egui/tests/filter_menu_enter.rs b/crates/ui-egui/tests/it/filter_menu_enter.rs similarity index 100% rename from crates/ui-egui/tests/filter_menu_enter.rs rename to crates/ui-egui/tests/it/filter_menu_enter.rs diff --git a/crates/ui-egui/tests/find_dialog_focus.rs b/crates/ui-egui/tests/it/find_dialog_focus.rs similarity index 100% rename from crates/ui-egui/tests/find_dialog_focus.rs rename to crates/ui-egui/tests/it/find_dialog_focus.rs diff --git a/crates/ui-egui/tests/floating_pictures.rs b/crates/ui-egui/tests/it/floating_pictures.rs similarity index 100% rename from crates/ui-egui/tests/floating_pictures.rs rename to crates/ui-egui/tests/it/floating_pictures.rs diff --git a/crates/ui-egui/tests/font_size_box.rs b/crates/ui-egui/tests/it/font_size_box.rs similarity index 100% rename from crates/ui-egui/tests/font_size_box.rs rename to crates/ui-egui/tests/it/font_size_box.rs diff --git a/crates/ui-egui/tests/format_painter.rs b/crates/ui-egui/tests/it/format_painter.rs similarity index 100% rename from crates/ui-egui/tests/format_painter.rs rename to crates/ui-egui/tests/it/format_painter.rs diff --git a/crates/ui-egui/tests/formula_locale.rs b/crates/ui-egui/tests/it/formula_locale.rs similarity index 100% rename from crates/ui-egui/tests/formula_locale.rs rename to crates/ui-egui/tests/it/formula_locale.rs diff --git a/crates/ui-egui/tests/formula_point_headers.rs b/crates/ui-egui/tests/it/formula_point_headers.rs similarity index 100% rename from crates/ui-egui/tests/formula_point_headers.rs rename to crates/ui-egui/tests/it/formula_point_headers.rs diff --git a/crates/ui-egui/tests/formula_popup.rs b/crates/ui-egui/tests/it/formula_popup.rs similarity index 100% rename from crates/ui-egui/tests/formula_popup.rs rename to crates/ui-egui/tests/it/formula_popup.rs diff --git a/crates/ui-egui/tests/freeze_handles.rs b/crates/ui-egui/tests/it/freeze_handles.rs similarity index 100% rename from crates/ui-egui/tests/freeze_handles.rs rename to crates/ui-egui/tests/it/freeze_handles.rs diff --git a/crates/ui-egui/tests/header_autofit.rs b/crates/ui-egui/tests/it/header_autofit.rs similarity index 100% rename from crates/ui-egui/tests/header_autofit.rs rename to crates/ui-egui/tests/it/header_autofit.rs diff --git a/crates/ui-egui/tests/header_column_drag.rs b/crates/ui-egui/tests/it/header_column_drag.rs similarity index 100% rename from crates/ui-egui/tests/header_column_drag.rs rename to crates/ui-egui/tests/it/header_column_drag.rs diff --git a/crates/ui-egui/tests/host_chrome.rs b/crates/ui-egui/tests/it/host_chrome.rs similarity index 100% rename from crates/ui-egui/tests/host_chrome.rs rename to crates/ui-egui/tests/it/host_chrome.rs diff --git a/crates/ui-egui/tests/hyperlink_ctrl_click.rs b/crates/ui-egui/tests/it/hyperlink_ctrl_click.rs similarity index 100% rename from crates/ui-egui/tests/hyperlink_ctrl_click.rs rename to crates/ui-egui/tests/it/hyperlink_ctrl_click.rs diff --git a/crates/ui-egui/tests/in_cell_editor_size.rs b/crates/ui-egui/tests/it/in_cell_editor_size.rs similarity index 100% rename from crates/ui-egui/tests/in_cell_editor_size.rs rename to crates/ui-egui/tests/it/in_cell_editor_size.rs diff --git a/crates/ui-egui/tests/in_cell_editor_wrap.rs b/crates/ui-egui/tests/it/in_cell_editor_wrap.rs similarity index 100% rename from crates/ui-egui/tests/in_cell_editor_wrap.rs rename to crates/ui-egui/tests/it/in_cell_editor_wrap.rs diff --git a/crates/ui-egui/tests/insert_copied_cells.rs b/crates/ui-egui/tests/it/insert_copied_cells.rs similarity index 100% rename from crates/ui-egui/tests/insert_copied_cells.rs rename to crates/ui-egui/tests/it/insert_copied_cells.rs diff --git a/crates/ui-egui/tests/interaction.rs b/crates/ui-egui/tests/it/interaction.rs similarity index 100% rename from crates/ui-egui/tests/interaction.rs rename to crates/ui-egui/tests/it/interaction.rs diff --git a/crates/ui-egui/tests/interface_scale.rs b/crates/ui-egui/tests/it/interface_scale.rs similarity index 100% rename from crates/ui-egui/tests/interface_scale.rs rename to crates/ui-egui/tests/it/interface_scale.rs diff --git a/crates/ui-egui/tests/keyboard_shortcuts.rs b/crates/ui-egui/tests/it/keyboard_shortcuts.rs similarity index 100% rename from crates/ui-egui/tests/keyboard_shortcuts.rs rename to crates/ui-egui/tests/it/keyboard_shortcuts.rs diff --git a/crates/ui-egui/tests/keytips_generated.rs b/crates/ui-egui/tests/it/keytips_generated.rs similarity index 100% rename from crates/ui-egui/tests/keytips_generated.rs rename to crates/ui-egui/tests/it/keytips_generated.rs diff --git a/crates/ui-egui/tests/it/main.rs b/crates/ui-egui/tests/it/main.rs new file mode 100644 index 00000000..b89253bb --- /dev/null +++ b/crates/ui-egui/tests/it/main.rs @@ -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; diff --git a/crates/ui-egui/tests/menu_hover.rs b/crates/ui-egui/tests/it/menu_hover.rs similarity index 100% rename from crates/ui-egui/tests/menu_hover.rs rename to crates/ui-egui/tests/it/menu_hover.rs diff --git a/crates/ui-egui/tests/merged_cells.rs b/crates/ui-egui/tests/it/merged_cells.rs similarity index 100% rename from crates/ui-egui/tests/merged_cells.rs rename to crates/ui-egui/tests/it/merged_cells.rs diff --git a/crates/ui-egui/tests/more_colors.rs b/crates/ui-egui/tests/it/more_colors.rs similarity index 100% rename from crates/ui-egui/tests/more_colors.rs rename to crates/ui-egui/tests/it/more_colors.rs diff --git a/crates/ui-egui/tests/native_print.rs b/crates/ui-egui/tests/it/native_print.rs similarity index 100% rename from crates/ui-egui/tests/native_print.rs rename to crates/ui-egui/tests/it/native_print.rs diff --git a/crates/ui-egui/tests/nowrap_line_breaks.rs b/crates/ui-egui/tests/it/nowrap_line_breaks.rs similarity index 100% rename from crates/ui-egui/tests/nowrap_line_breaks.rs rename to crates/ui-egui/tests/it/nowrap_line_breaks.rs diff --git a/crates/ui-egui/tests/number_stored_as_text.rs b/crates/ui-egui/tests/it/number_stored_as_text.rs similarity index 100% rename from crates/ui-egui/tests/number_stored_as_text.rs rename to crates/ui-egui/tests/it/number_stored_as_text.rs diff --git a/crates/ui-egui/tests/open_encrypted.rs b/crates/ui-egui/tests/it/open_encrypted.rs similarity index 100% rename from crates/ui-egui/tests/open_encrypted.rs rename to crates/ui-egui/tests/it/open_encrypted.rs diff --git a/crates/ui-egui/tests/outline.rs b/crates/ui-egui/tests/it/outline.rs similarity index 100% rename from crates/ui-egui/tests/outline.rs rename to crates/ui-egui/tests/it/outline.rs diff --git a/crates/ui-egui/tests/page_layout_view.rs b/crates/ui-egui/tests/it/page_layout_view.rs similarity index 100% rename from crates/ui-egui/tests/page_layout_view.rs rename to crates/ui-egui/tests/it/page_layout_view.rs diff --git a/crates/ui-egui/tests/page_setup_margins.rs b/crates/ui-egui/tests/it/page_setup_margins.rs similarity index 100% rename from crates/ui-egui/tests/page_setup_margins.rs rename to crates/ui-egui/tests/it/page_setup_margins.rs diff --git a/crates/ui-egui/tests/paste_special_dialog.rs b/crates/ui-egui/tests/it/paste_special_dialog.rs similarity index 100% rename from crates/ui-egui/tests/paste_special_dialog.rs rename to crates/ui-egui/tests/it/paste_special_dialog.rs diff --git a/crates/ui-egui/tests/pivot_pane.rs b/crates/ui-egui/tests/it/pivot_pane.rs similarity index 100% rename from crates/ui-egui/tests/pivot_pane.rs rename to crates/ui-egui/tests/it/pivot_pane.rs diff --git a/crates/ui-egui/tests/popup_dismissal.rs b/crates/ui-egui/tests/it/popup_dismissal.rs similarity index 100% rename from crates/ui-egui/tests/popup_dismissal.rs rename to crates/ui-egui/tests/it/popup_dismissal.rs diff --git a/crates/ui-egui/tests/protect_password.rs b/crates/ui-egui/tests/it/protect_password.rs similarity index 100% rename from crates/ui-egui/tests/protect_password.rs rename to crates/ui-egui/tests/it/protect_password.rs diff --git a/crates/ui-egui/tests/right_to_left.rs b/crates/ui-egui/tests/it/right_to_left.rs similarity index 100% rename from crates/ui-egui/tests/right_to_left.rs rename to crates/ui-egui/tests/it/right_to_left.rs diff --git a/crates/ui-egui/tests/scroll_position.rs b/crates/ui-egui/tests/it/scroll_position.rs similarity index 100% rename from crates/ui-egui/tests/scroll_position.rs rename to crates/ui-egui/tests/it/scroll_position.rs diff --git a/crates/ui-egui/tests/scrollbar_column_fill.rs b/crates/ui-egui/tests/it/scrollbar_column_fill.rs similarity index 100% rename from crates/ui-egui/tests/scrollbar_column_fill.rs rename to crates/ui-egui/tests/it/scrollbar_column_fill.rs diff --git a/crates/ui-egui/tests/selection.rs b/crates/ui-egui/tests/it/selection.rs similarity index 100% rename from crates/ui-egui/tests/selection.rs rename to crates/ui-egui/tests/it/selection.rs diff --git a/crates/ui-egui/tests/selection_fill.rs b/crates/ui-egui/tests/it/selection_fill.rs similarity index 100% rename from crates/ui-egui/tests/selection_fill.rs rename to crates/ui-egui/tests/it/selection_fill.rs diff --git a/crates/ui-egui/tests/selection_glide.rs b/crates/ui-egui/tests/it/selection_glide.rs similarity index 100% rename from crates/ui-egui/tests/selection_glide.rs rename to crates/ui-egui/tests/it/selection_glide.rs diff --git a/crates/ui-egui/tests/selection_scroll.rs b/crates/ui-egui/tests/it/selection_scroll.rs similarity index 100% rename from crates/ui-egui/tests/selection_scroll.rs rename to crates/ui-egui/tests/it/selection_scroll.rs diff --git a/crates/ui-egui/tests/sheet_navigator.rs b/crates/ui-egui/tests/it/sheet_navigator.rs similarity index 100% rename from crates/ui-egui/tests/sheet_navigator.rs rename to crates/ui-egui/tests/it/sheet_navigator.rs diff --git a/crates/ui-egui/tests/sheet_tab_rename.rs b/crates/ui-egui/tests/it/sheet_tab_rename.rs similarity index 100% rename from crates/ui-egui/tests/sheet_tab_rename.rs rename to crates/ui-egui/tests/it/sheet_tab_rename.rs diff --git a/crates/ui-egui/tests/sheet_tabs.rs b/crates/ui-egui/tests/it/sheet_tabs.rs similarity index 100% rename from crates/ui-egui/tests/sheet_tabs.rs rename to crates/ui-egui/tests/it/sheet_tabs.rs diff --git a/crates/ui-egui/tests/show_objects.rs b/crates/ui-egui/tests/it/show_objects.rs similarity index 100% rename from crates/ui-egui/tests/show_objects.rs rename to crates/ui-egui/tests/it/show_objects.rs diff --git a/crates/ui-egui/tests/shrink_to_fit.rs b/crates/ui-egui/tests/it/shrink_to_fit.rs similarity index 100% rename from crates/ui-egui/tests/shrink_to_fit.rs rename to crates/ui-egui/tests/it/shrink_to_fit.rs diff --git a/crates/ui-egui/tests/sort_dialog_columns.rs b/crates/ui-egui/tests/it/sort_dialog_columns.rs similarity index 100% rename from crates/ui-egui/tests/sort_dialog_columns.rs rename to crates/ui-egui/tests/it/sort_dialog_columns.rs diff --git a/crates/ui-egui/tests/symbol_glyphs.rs b/crates/ui-egui/tests/it/symbol_glyphs.rs similarity index 100% rename from crates/ui-egui/tests/symbol_glyphs.rs rename to crates/ui-egui/tests/it/symbol_glyphs.rs diff --git a/crates/ui-egui/tests/system_theme.rs b/crates/ui-egui/tests/it/system_theme.rs similarity index 100% rename from crates/ui-egui/tests/system_theme.rs rename to crates/ui-egui/tests/it/system_theme.rs diff --git a/crates/ui-egui/tests/table_headings.rs b/crates/ui-egui/tests/it/table_headings.rs similarity index 100% rename from crates/ui-egui/tests/table_headings.rs rename to crates/ui-egui/tests/it/table_headings.rs diff --git a/crates/ui-egui/tests/text_box_editing.rs b/crates/ui-egui/tests/it/text_box_editing.rs similarity index 100% rename from crates/ui-egui/tests/text_box_editing.rs rename to crates/ui-egui/tests/it/text_box_editing.rs diff --git a/crates/ui-egui/tests/text_overflow_scroll.rs b/crates/ui-egui/tests/it/text_overflow_scroll.rs similarity index 100% rename from crates/ui-egui/tests/text_overflow_scroll.rs rename to crates/ui-egui/tests/it/text_overflow_scroll.rs diff --git a/crates/ui-egui/tests/touch_pan.rs b/crates/ui-egui/tests/it/touch_pan.rs similarity index 100% rename from crates/ui-egui/tests/touch_pan.rs rename to crates/ui-egui/tests/it/touch_pan.rs diff --git a/crates/ui-egui/tests/trace_navigation.rs b/crates/ui-egui/tests/it/trace_navigation.rs similarity index 100% rename from crates/ui-egui/tests/trace_navigation.rs rename to crates/ui-egui/tests/it/trace_navigation.rs diff --git a/crates/ui-egui/tests/translated_form_fields.rs b/crates/ui-egui/tests/it/translated_form_fields.rs similarity index 100% rename from crates/ui-egui/tests/translated_form_fields.rs rename to crates/ui-egui/tests/it/translated_form_fields.rs diff --git a/crates/ui-egui/tests/ui_clock.rs b/crates/ui-egui/tests/it/ui_clock.rs similarity index 100% rename from crates/ui-egui/tests/ui_clock.rs rename to crates/ui-egui/tests/it/ui_clock.rs diff --git a/crates/ui-egui/tests/validation_alert.rs b/crates/ui-egui/tests/it/validation_alert.rs similarity index 100% rename from crates/ui-egui/tests/validation_alert.rs rename to crates/ui-egui/tests/it/validation_alert.rs diff --git a/crates/ui-egui/tests/validation_input_message.rs b/crates/ui-egui/tests/it/validation_input_message.rs similarity index 100% rename from crates/ui-egui/tests/validation_input_message.rs rename to crates/ui-egui/tests/it/validation_input_message.rs diff --git a/crates/ui-egui/tests/wheel_zoom.rs b/crates/ui-egui/tests/it/wheel_zoom.rs similarity index 100% rename from crates/ui-egui/tests/wheel_zoom.rs rename to crates/ui-egui/tests/it/wheel_zoom.rs diff --git a/crates/ui-egui/tests/whole_line_shortcuts.rs b/crates/ui-egui/tests/it/whole_line_shortcuts.rs similarity index 100% rename from crates/ui-egui/tests/whole_line_shortcuts.rs rename to crates/ui-egui/tests/it/whole_line_shortcuts.rs diff --git a/crates/ui-egui/tests/widgets.rs b/crates/ui-egui/tests/it/widgets.rs similarity index 100% rename from crates/ui-egui/tests/widgets.rs rename to crates/ui-egui/tests/it/widgets.rs diff --git a/crates/ui-egui/tests/zoom_dialog.rs b/crates/ui-egui/tests/it/zoom_dialog.rs similarity index 100% rename from crates/ui-egui/tests/zoom_dialog.rs rename to crates/ui-egui/tests/it/zoom_dialog.rs diff --git a/docs/roadmap.md b/docs/roadmap.md index 4894d77b..62e1735f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap detail -> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (PivotTable calculated fields) · **Target:** Microsoft Excel (Microsoft 365) +> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-23 · **Change:** minor (test command) · **Target:** Microsoft Excel (Microsoft 365) Forward-looking plan. The one-page summary is [`ROADMAP.md`](../ROADMAP.md); the ranked work list is [`gaps.md`](gaps.md); numbers and method are in @@ -100,7 +100,8 @@ to check our files, and Windows machines with the reported GPU drivers. - `cargo xtask parity` regenerates [`parity-checklist.md`](parity-checklist.md) (ribbon catalog vs registered commands); `cargo xtask ci` checks it is current. -- `cargo test --workspace`: engine, formula, function, XLSX and UI behaviour. +- `cargo xtask test`: engine, formula, function, XLSX and UI behaviour (cargo-nextest when + installed, else `cargo test`), then the doctests. - `cargo run --release -p gridcraft-ui-egui --example snapshot -- --sample sales out.png`: look at the UI offscreen. - Function coverage: the script method in [function-parity.md](function-parity.md). A @@ -112,6 +113,7 @@ to check our files, and Windows machines with the reported GPU drivers. | Date | Change | Summary | |---|---|---| +| 2026-10-23 | minor | Measuring: tests run through `cargo xtask test` | | 2026-10-11 | minor | PivotTable calculated fields landed | | 2026-10-10 | minor | Current focus and M15 updated for the 10-10 merges | | 2026-10-10 | minor | Added the alpha gate table (six core workflows; passes, stays alpha) | diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 08a9124b..99a1e071 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -341,7 +341,7 @@ The inventory carried over from the 2026-10-07 ROADMAP.md, updated for what land | 2026-10-12 | minor | Essentials AutoFit evidence: rows auto-fit oversized fonts on open and row formatting (#833) | | 2026-10-12 | minor | Sheet tabs: reveal the selected tab on navigation and resize while preserving manual scrolling (#681); no score change | | 2026-10-12 | minor | PivotTables: values on rows (Σ Values in Rows at any position, all three layouts; `pivot.moveField` and the field pane move it; `dataOnRows` round-trips) (no score change) | -| 2026-10-11 | minor | Stability: command-sequence fuzz harness (`crates/engine/tests/command_sequence_fuzz.rs`) checks random command sequences against undo/redo, XLSX round-trip, full-recalc and structure invariants; the sequence bugs it found are fixed (no score change) | +| 2026-10-11 | minor | Stability: command-sequence fuzz harness (`crates/engine/tests/it/command_sequence_fuzz.rs`) checks random command sequences against undo/redo, XLSX round-trip, full-recalc and structure invariants; the sequence bugs it found are fixed (no score change) | | 2026-10-11 | minor | Password-encrypted workbooks open (#11): Essentials file-opening work 24–36 h | | 2026-10-11 | minor | Worksheet functions 505 / 523 (96.6%; 496 working): ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD | | 2026-10-11 | minor | Worksheet functions 503 / 523 (96.2%; 494 working): PERCENTOF, EUROCONVERT | diff --git a/xtask/src/keytips.rs b/xtask/src/keytips.rs index 63b1554a..f6df981b 100644 --- a/xtask/src/keytips.rs +++ b/xtask/src/keytips.rs @@ -1,6 +1,6 @@ //! Regenerate the keytip sequence table and its per-sequence test suite from `keytips.json`. //! -//! `cargo xtask keytips` regenerate the table + `tests/keytips_generated.rs` +//! `cargo xtask keytips` regenerate the table + `tests/it/keytips_generated.rs` //! `cargo xtask keytips --check` fail if either generated file differs from the JSON source //! //! Requires the default `engine` feature: the generator probes the live command @@ -92,7 +92,7 @@ pub fn run(root: &Path, rest: &[&str]) -> Result<(), String> { { let json_path = root.join("crates/ui-egui/src/keytips/keytips.json"); let table_path = root.join("crates/ui-egui/src/keytips/keytip_table/generated.rs"); - let tests_path = root.join("crates/ui-egui/tests/keytips_generated.rs"); + let tests_path = root.join("crates/ui-egui/tests/it/keytips_generated.rs"); let source = fs::read_to_string(&json_path).map_err(|e| format!("read {}: {e}", json_path.display()))?; let (entries, probe) = parse_and_probe(&source)?; let generated = diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 14e9af32..0c9f5547 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -15,17 +15,19 @@ mod stats; mod version; use std::path::{Path, PathBuf}; -use std::process::{Command, ExitCode}; +use std::process::{Command, ExitCode, Stdio}; const USAGE: &str = "\ usage: cargo xtask commands: - ci fmt --check, clippy -D warnings, test, assets, layers, wasm, parity --check - (stops at the first failure; the parity check runs only if docs/parity-checklist.md exists) + ci fmt --check, clippy -D warnings, test, doctest, assets, layers, wasm, parity --check, + keytips --check (stops at the first failure; the parity check runs only if + docs/parity-checklist.md exists) + test workspace tests (cargo nextest when installed, else cargo test), then doctests assets check that every icon/image/font/sample file is attributed in ATTRIBUTION.md layers enforce the crate dependency layering (AGENTS.md \"Layering\") - wasm cargo check --target wasm32-unknown-unknown for the L0-L5 crates (+ gridcraft-web) + wasm cargo check --target wasm32-unknown-unknown for the L0-L5 crates (+ gridcraft-web), one call parity [--check] [--out PATH] write docs/parity-checklist.md from gridcraft_engine::catalog (implemented vs missing ids) keytips [--check] @@ -44,6 +46,7 @@ fn main() -> ExitCode { Some("assets") => assets::run(&root()), Some("layers") => cmd_layers(), Some("wasm") => cmd_wasm(), + Some("test") => cmd_test().and_then(|()| cmd_doctest()), Some("ci") => cmd_ci(), Some("stats") => stats::run(&root(), rest.contains(&"--exact")), Some("parity") => parity::run(&root(), &rest), @@ -139,17 +142,19 @@ fn wasm_set() -> Result, String> { .collect()) } +/// One `cargo check` for the whole set; `--keep-going` reports every failing crate, not just the +/// first. fn cmd_wasm() -> Result<(), String> { let set = wasm_set()?; if set.is_empty() { return Err("no wasm crates found in the workspace".into()); } let mut c = cargo(); - c.args(["check", "--target", "wasm32-unknown-unknown"]); + c.args(["check", "--target", "wasm32-unknown-unknown", "--keep-going"]); for p in &set { c.args(["-p", p]); } - let r = run(c, &format!("cargo check --target wasm32-unknown-unknown -p {}", set.join(" -p "))); + let r = run(c, &format!("cargo check --target wasm32-unknown-unknown --keep-going -p {}", set.join(" -p "))); println!("\nwasm32-unknown-unknown check ({}): {}", set.join(", "), if r.is_ok() { "ok" } else { "FAIL" }); if r.is_err() { println!("(if the target is missing: rustup target add wasm32-unknown-unknown)"); @@ -157,6 +162,35 @@ fn cmd_wasm() -> Result<(), String> { r } +/// Targets for the test build. Examples are left out so they aren't linked; clippy +/// `--all-targets` still compiles them. +const TEST_TARGETS: [&str; 4] = ["--workspace", "--lib", "--bins", "--tests"]; + +fn nextest_available() -> bool { + cargo().args(["nextest", "--version"]).stdout(Stdio::null()).stderr(Stdio::null()).status().is_ok_and(|s| s.success()) +} + +fn cmd_test() -> Result<(), String> { + let mut c = cargo(); + let tool = if nextest_available() { + c.args(["nextest", "run"]); + "nextest run" + } else { + eprintln!("note: cargo-nextest is not installed, running cargo test (cargo install cargo-nextest --locked)"); + c.arg("test"); + "test" + }; + c.args(TEST_TARGETS); + run(c, &format!("cargo {tool} {}", TEST_TARGETS.join(" "))) +} + +/// nextest does not run doctests. +fn cmd_doctest() -> Result<(), String> { + let mut c = cargo(); + c.args(["test", "--workspace", "--doc"]); + run(c, "cargo test --workspace --doc") +} + fn cmd_ci() -> Result<(), String> { type Step = (&'static str, Box Result<(), String>>); let steps: Vec = vec![ @@ -172,18 +206,12 @@ fn cmd_ci() -> Result<(), String> { "clippy", Box::new(|| { let mut c = cargo(); - c.args(["clippy", "--workspace", "--all-targets", "--", "-D", "warnings"]); - run(c, "cargo clippy --workspace --all-targets -- -D warnings") - }), - ), - ( - "test", - Box::new(|| { - let mut c = cargo(); - c.args(["test", "--workspace"]); - run(c, "cargo test --workspace") + c.args(["clippy", "--workspace", "--all-targets", "--keep-going", "--", "-D", "warnings"]); + run(c, "cargo clippy --workspace --all-targets --keep-going -- -D warnings") }), ), + ("test", Box::new(cmd_test)), + ("doctest", Box::new(cmd_doctest)), ("assets", Box::new(|| assets::run(&root()))), ("layers", Box::new(cmd_layers)), ("wasm", Box::new(cmd_wasm)),