mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-10 04:14:16 +00:00
CI: one test binary per crate, nextest, line tables only (#1213)
* Build: line tables only for workspace crates, no debug info for dependencies * Tests: one integration-test binary per crate * xtask ci: nextest, doctests, test build without examples, one wasm check
This commit is contained in:
1 parent
0f4fffcf6c
commit
f001f37906
47 files changed
+105
-38
No files matched your search
@@ -136,7 +136,7 @@ Standard: craftrules `standards/never-crash.md`.
|
||||
|
||||
## 5. Quality gates (before every commit)
|
||||
|
||||
`cargo xtask ci` = fmt check, clippy `-D warnings`, tests, layering check, asset check, wasm
|
||||
`cargo xtask ci` = fmt check, clippy `-D warnings`, tests (nextest when installed) and doctests, layering check, asset check, wasm
|
||||
check. Commit after each landed arc with a task id in the message (`M1.2: smart guides`) and push
|
||||
to `main`.
|
||||
|
||||
|
||||
@@ -84,11 +84,16 @@ self_named_constructors = "allow"
|
||||
large_enum_variant = "allow"
|
||||
result_large_err = "allow"
|
||||
|
||||
# Line tables keep file and line in panics and backtraces; full debug info
|
||||
# for every test binary and dependency would multiply the target dir size.
|
||||
# The test profile inherits both settings.
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 2
|
||||
debug = false
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
debug = "line-tables-only"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,6 @@
|
||||
mod cli;
|
||||
mod convert;
|
||||
mod damaged;
|
||||
// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md).
|
||||
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
mod mcp_roots;
|
||||
@@ -1,6 +1,4 @@
|
||||
//! `deckcraft-cli mcp` with the automation root flags, run as the real binary.
|
||||
// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md).
|
||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
File renamed without changes.
@@ -0,0 +1,2 @@
|
||||
mod chart_native;
|
||||
mod show_clicks;
|
||||
File renamed without changes.
@@ -2,8 +2,6 @@
|
||||
//! protocol, files open and load only from inside the read root and are saved and exported only
|
||||
//! inside the write root. Paths that leave a root (`..`, another folder, a sibling with the same
|
||||
//! prefix, a link) are refused, and nothing is written outside.
|
||||
// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md).
|
||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md).
|
||||
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
mod automation_roots;
|
||||
File renamed without changes.
@@ -0,0 +1 @@
|
||||
mod decode;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,27 @@
|
||||
mod anchor;
|
||||
mod chart_embed;
|
||||
mod comments;
|
||||
mod corpus;
|
||||
mod corpus_charts;
|
||||
mod corpus_elements;
|
||||
mod corpus_kinds;
|
||||
mod corpus_media;
|
||||
mod corpus_style;
|
||||
mod corpus_themes;
|
||||
mod fills;
|
||||
mod kept_parts;
|
||||
mod locks;
|
||||
mod malformed;
|
||||
mod math_ns;
|
||||
mod notes;
|
||||
mod ole;
|
||||
mod ole_vml;
|
||||
mod placeholders;
|
||||
mod roundtrip;
|
||||
mod sample;
|
||||
mod smartart;
|
||||
mod sniff;
|
||||
mod table_styles;
|
||||
mod tags;
|
||||
mod transition_xml;
|
||||
mod trigger_steps;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,7 +16,7 @@ PowerPoint opens and saves; Viewer = opens only).
|
||||
|
||||
| Format | PowerPoint | DeckCraft read | DeckCraft write | Fidelity / notes | Tested by |
|
||||
|---|---|---|---|---|---|
|
||||
| `.pptx` presentation | Editor | yes | yes | Broad (see below); an owned corpus of decks we author round-trips tables, charts, animations, media, sections, masters and layouts, comments, links and actions, custom shows, rotated groups, inherited placeholders, text effects and body layout, theme effects, fills, bevels, connectors, 3-D models and animation bounce end. Not measured against PowerPoint renders or decks from outside this repo | `crates/pptx/tests/corpus.rs`, `corpus_kinds.rs`, `corpus_elements.rs`, `corpus_style.rs`, `corpus_themes.rs`, `corpus_charts.rs`, `corpus_media.rs`, `roundtrip.rs`, `sample.rs`, `malformed.rs`, `sniff.rs`; opened in PowerPoint by hand 2026-10-06 |
|
||||
| `.pptx` presentation | Editor | yes | yes | Broad (see below); an owned corpus of decks we author round-trips tables, charts, animations, media, sections, masters and layouts, comments, links and actions, custom shows, rotated groups, inherited placeholders, text effects and body layout, theme effects, fills, bevels, connectors, 3-D models and animation bounce end. Not measured against PowerPoint renders or decks from outside this repo | `crates/pptx/tests/it/corpus.rs`, `corpus_kinds.rs`, `corpus_elements.rs`, `corpus_style.rs`, `corpus_themes.rs`, `corpus_charts.rs`, `corpus_media.rs`, `roundtrip.rs`, `sample.rs`, `malformed.rs`, `sniff.rs`; opened in PowerPoint by hand 2026-10-06 |
|
||||
| `.potx` template | Editor | yes (as a presentation) | no: written with the `.pptx` content type | `file.saveTemplate` is Save As under another name | none |
|
||||
| `.ppsx` slide show | Editor | yes (as a presentation) | no: written as `.pptx` content | Handed over by the system (command line, file association) it starts the slide show, as in PowerPoint; File › Open opens it for editing. The macOS Finder event arrives with #432 | `crates/ui-egui/src/opening.rs` tests |
|
||||
| `.pptm` / `.potm` / `.ppsm` macro-enabled | Editor | no | no | Should open and keep `vbaProject.bin` without running it | none |
|
||||
@@ -77,7 +77,7 @@ the round trip even though DeckCraft doesn't model it.
|
||||
| Presentation, slide size, sections (p14), custom shows | yes | yes | |
|
||||
| Slide masters, layouts, placeholders and inheritance | yes | yes | |
|
||||
| Themes: colour, font (Latin/EA/CS), effect schemes, background styles | yes | yes | Unknown theme parts kept |
|
||||
| Notes slides and notes master | yes | yes | Header, footer, date and slide-number text on the notes master is kept. Edited in View ▸ Notes Master. Notes keep their run and paragraph formatting (bold, italic, underline, size, levels, indents, bullets), shown and kept when edited in the notes pane and Notes Page (`crates/pptx/tests/notes.rs`). PDF notes pages print them as plain text; levels and bullets inherited from a custom notes master aren't shown |
|
||||
| Notes slides and notes master | yes | yes | Header, footer, date and slide-number text on the notes master is kept. Edited in View ▸ Notes Master. Notes keep their run and paragraph formatting (bold, italic, underline, size, levels, indents, bullets), shown and kept when edited in the notes pane and Notes Page (`crates/pptx/tests/it/notes.rs`). PDF notes pages print them as plain text; levels and bullets inherited from a custom notes master aren't shown |
|
||||
| Handout master | yes | yes | Header, footer, date and slide-number text is kept. Edited in View ▸ Handout Master |
|
||||
| Shapes: preset geometry (~180 presets), custom geometry, groups, connectors | yes | yes | Presets re-derived in `crates/geom/src/preset.rs` (and `preset/extra.rs`). Outlines, dashes, arrowheads and ink inside a group, and text, keep their size in points whatever the group's child-coordinate scale (#233). |
|
||||
| Fills: solid, gradient, picture (stretch/tile/crop), pattern, group | yes | yes | |
|
||||
@@ -108,7 +108,7 @@ the round trip even though DeckCraft doesn't model it.
|
||||
### What would move the PPTX number
|
||||
|
||||
1. A larger owned corpus (corporate templates, SmartArt, chartex charts, EMF, embedded fonts,
|
||||
every transition and animation) in a corpus repo. `crates/pptx/tests/corpus.rs` and
|
||||
every transition and animation) in a corpus repo. `crates/pptx/tests/it/corpus.rs` and
|
||||
`corpus_kinds.rs` already check open → save → reopen (parts and text) for decks we author:
|
||||
tables, charts, animations, media, sections and masters/layouts among them. Still needed:
|
||||
render checks and a PowerPoint reference render for each (owner runs PowerPoint).
|
||||
|
||||
+2
-2
@@ -181,7 +181,7 @@ Detail in [file-format-parity.md](file-format-parity.md).
|
||||
`Series.secondary_axis`) and is not written back when the chart is rebuilt.
|
||||
An unchanged chart's embedded workbook now survives save (#335); editing the chart still
|
||||
drops it rather than writing a stale spreadsheet. The workbook and other retained chart parts
|
||||
also survive `.deckcraft` save/reopen (`crates/engine/tests/chart_native.rs`), with binary
|
||||
also survive `.deckcraft` save/reopen (`crates/engine/tests/it/chart_native.rs`), with binary
|
||||
payloads in bounded ZIP entries sharing the media load budget (`crates/format` tests).
|
||||
- **Impact:** most business decks have charts; editing their data is routine.
|
||||
- **Estimate:** 12–20 h. Data and elements are **beta blockers** (6–10 h).
|
||||
@@ -215,7 +215,7 @@ of the effect gallery. Detail in [animation-parity.md](animation-parity.md). 8
|
||||
shapes in two decks) does nothing; triggers that start on `onStopAudio` or `begin` conditions are
|
||||
not read as triggers; click boxes are the shape's bounding box (a hexagon's corners count) and do
|
||||
not follow a shape that a motion path has moved. Trigger sequences now keep their separate
|
||||
click steps on PPTX save, including paragraph builds (`crates/pptx/tests/trigger_steps.rs`).
|
||||
click steps on PPTX save, including paragraph builds (`crates/pptx/tests/it/trigger_steps.rs`).
|
||||
- **Impact:** games built around sound effects on buttons, audio-triggered effects or moving
|
||||
clickable shapes do not play as authored.
|
||||
- **Estimate:** 4–8 h.
|
||||
|
||||
@@ -54,7 +54,7 @@ Open P0 items: Contextual tabs (Shape Format, Picture Format, Table Design/Layou
|
||||
| Application shell | Multiple open presentations | P1 | P |
|
||||
| Application shell | Preferences (autosave, units, defaults) | P2 | P |
|
||||
| Files | New blank presentation | P0 | D |
|
||||
| Files | Native file format (open/save; chart package parts retained, `crates/engine/tests/chart_native.rs`) | P0 | D |
|
||||
| Files | Native file format (open/save; chart package parts retained, `crates/engine/tests/it/chart_native.rs`) | P0 | D |
|
||||
| Files | Open PowerPoint .pptx | P0 | D |
|
||||
| Files | Save as PowerPoint .pptx | P0 | D |
|
||||
| Files | Open/save .potx/.ppsx/.pptm variants (.potx/.ppsx open; saved with the .pptx content type; no .pptm) | P2 | P |
|
||||
@@ -206,7 +206,7 @@ Open P0 items: Contextual tabs (Shape Format, Picture Format, Table Design/Layou
|
||||
| Animations | Effect options, start (on click/with/after), duration, delay | P0 | D |
|
||||
| Animations | Animation pane (reorder, timing) | P0 | P |
|
||||
| Animations | By-paragraph text builds | P1 | D |
|
||||
| Animations | Triggers (separate click steps and paragraph builds round-trip; `crates/pptx/tests/trigger_steps.rs`) | P2 | D |
|
||||
| Animations | Triggers (separate click steps and paragraph builds round-trip; `crates/pptx/tests/it/trigger_steps.rs`) | P2 | D |
|
||||
| Animations | Animation Painter | P2 | D |
|
||||
| Animations | Preview in editor | P1 | D |
|
||||
| Slide show | Full-screen show from start / current | P0 | D |
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ points and lead the beta plan.
|
||||
|
||||
| Core workflow | Works end to end? | Evidence | Hours to full pass |
|
||||
|---|---|---|---|
|
||||
| Build a deck from scratch (theme, layouts, titles and bullets, shapes, pictures from file), save, close and reopen it | yes | Commands for all of it; `.deckcraft` and `.pptx` round-trip tests (`crates/pptx/tests/roundtrip.rs`, `crates/format`); AutoRecover. Close discards edits without asking (#60, PR #75); image *paste* fails on Windows/Linux (#53), though insert-from-file works | 1–3 |
|
||||
| Build a deck from scratch (theme, layouts, titles and bullets, shapes, pictures from file), save, close and reopen it | yes | Commands for all of it; `.deckcraft` and `.pptx` round-trip tests (`crates/pptx/tests/it/roundtrip.rs`, `crates/format`); AutoRecover. Close discards edits without asking (#60, PR #75); image *paste* fails on Windows/Linux (#53), though insert-from-file works | 1–3 |
|
||||
| Open a colleague's `.pptx`, edit it, save it back as `.pptx` that PowerPoint opens | partial (not blocking) | The reader is lenient and keeps unknown objects. Files open in PowerPoint without repair (checked 2026-10-06). But only generated decks have been tested; text inside EMF/WMF pictures is missing; comment threads, media options and rewind are lost (#70, #74, #77) | 31–55 |
|
||||
| Present: full-screen show with transitions, animations, media, presenter view with notes, next slide and timer | yes | 48/48 transitions, 64 effects, triggers, builds, media playback, presenter window, See All Slides and zoom. The presenter timer pauses and resets, and notes have a size control. A custom show plays only its slides. Typing a slide number during the show shows it, and Enter goes there. Presenter view isn't placed on the second display automatically (drag it there; #433) | 2–4 |
|
||||
| Add business content: tables, charts with their data, simple diagrams | partial (not blocking) | Tables with styles, merge/split, all D or P. Charts insert with the common types and edit data in the Chart Data dialog (P0 partial); SmartArt is basic (pre-drawn shapes) | 12–20 |
|
||||
@@ -26,7 +26,7 @@ points and lead the beta plan.
|
||||
|
||||
1. **Stop losing work and crashing:** land Close's save prompt (#60, PR #75), the Windows GPU
|
||||
startup crashes (#40, #59), image paste on Windows/Linux (#53). 6–12 h.
|
||||
2. **PPTX on real decks:** the owned corpus (`crates/pptx/tests/corpus*.rs`) round-trips decks we
|
||||
2. **PPTX on real decks:** the owned corpus (`crates/pptx/tests/it/corpus*.rs`) round-trips decks we
|
||||
author: tables, charts, animations, media, sections, masters and layouts, comments, links and
|
||||
actions, custom shows, rotated groups, inherited placeholders, text effects and body layout,
|
||||
theme effects, fills, bevels, connectors, 3-D models and animation bounce end, and keeps notes-
|
||||
|
||||
+51
-24
@@ -13,7 +13,7 @@ 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 <command>
|
||||
@@ -22,8 +22,10 @@ commands:
|
||||
assets check that every icon/image/font/asset is attributed in ATTRIBUTION.md
|
||||
pdf-deps verify pinned writer sources and the production feature boundary
|
||||
layers enforce the crate dependency layering (plan/architecture.md §3)
|
||||
wasm cargo check --target wasm32-unknown-unknown for the wasm-safe crates
|
||||
ci fmt --check, pdf-deps, clippy -D warnings, test, assets, layers, wasm (stops at first failure)
|
||||
wasm cargo check --target wasm32-unknown-unknown for the wasm-safe crates (one call)
|
||||
test workspace tests (cargo nextest when installed, else cargo test), then doctests
|
||||
ci fmt --check, pdf-deps, clippy -D warnings, test, doctest, assets, layers, wasm
|
||||
(stops at first failure)
|
||||
stats [--exact] count tests and lines per crate (--exact: ask the test harness via `-- --list`)
|
||||
bench [--save] [DECK...]
|
||||
time open, render, save and export of the sample (and DECKs) in release, and
|
||||
@@ -41,6 +43,7 @@ fn main() -> ExitCode {
|
||||
Some("layers") => cmd_layers(),
|
||||
Some("pdf-deps") => pdf_deps::run(&root()),
|
||||
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()),
|
||||
@@ -136,21 +139,51 @@ fn wasm_set() -> Result<Vec<String>, String> {
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// One `cargo check` for the whole set: each crate is checked once, and
|
||||
/// `--keep-going` still reports every failing crate. Features unify across the
|
||||
/// set, so each crate is checked with the union of the features the set enables.
|
||||
fn cmd_wasm() -> Result<(), String> {
|
||||
let set = wasm_set()?;
|
||||
let mut results = Vec::new();
|
||||
if set.is_empty() {
|
||||
return Err("no wasm-safe crates found in the workspace metadata".into());
|
||||
}
|
||||
let mut c = cargo();
|
||||
c.args(["check", "--target", "wasm32-unknown-unknown", "--keep-going"]);
|
||||
for pkg in &set {
|
||||
let mut c = cargo();
|
||||
c.args(["check", "--target", "wasm32-unknown-unknown", "-p", pkg]);
|
||||
let ok = run(c, &format!("cargo check --target wasm32-unknown-unknown -p {pkg}")).is_ok();
|
||||
results.push((pkg.clone(), ok));
|
||||
c.args(["-p", pkg]);
|
||||
}
|
||||
println!("\nwasm32-unknown-unknown check:");
|
||||
for (p, ok) in &results {
|
||||
println!(" {:<6} {p}", if *ok { "ok" } else { "FAIL" });
|
||||
}
|
||||
let failed = results.iter().filter(|r| !r.1).count();
|
||||
if failed == 0 { Ok(()) } else { Err(format!("{failed} crate(s) failed the wasm check")) }
|
||||
run(c, &format!("cargo check --target wasm32-unknown-unknown --keep-going -p {}", set.join(" -p ")))?;
|
||||
println!("\nwasm32-unknown-unknown check: ok ({} crates: {})", set.len(), set.join(", "));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test 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> {
|
||||
@@ -169,18 +202,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)),
|
||||
|
||||
Reference in new issue
Block a user