From 0744347065ab2cb059e7f1abd9e36ac193e9c336 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 5 Oct 2026 06:39:22 +0700 Subject: [PATCH] M14.4: tests main gained follow the no-panic lint rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the branch does for older tests: `panic!("…")` instead of `unreachable!()` in test code (clippy.toml only allows unwrap, expect and panic there), and the integration tests main added (CLI file I/O, render gradient text and stroke geometry, SVG export suites) opt out of the unwrap/expect/panic lints. No test logic changed. Co-Authored-By: Claude Opus 5.5 --- apps/vectorcraft-cli/tests/fileio.rs | 2 ++ crates/color/src/harmony.rs | 2 +- crates/color/src/lib.rs | 2 +- crates/doc/src/node.rs | 2 +- crates/doc/src/overprint.rs | 4 ++-- crates/effects/src/stroke/tests_arrows.rs | 2 +- crates/engine/src/tests_containers.rs | 2 +- crates/engine/src/tests_focal.rs | 2 +- crates/engine/src/tests_stylepanel.rs | 2 +- crates/engine/src/tests_swatches.rs | 2 +- crates/render/tests/gradient_text.rs | 2 ++ crates/render/tests/stroke_geometry.rs | 2 ++ crates/svg/tests/blend_export.rs | 2 ++ crates/svg/tests/container_export.rs | 2 ++ crates/svg/tests/dash_align.rs | 2 ++ crates/svg/tests/effects_export.rs | 2 ++ crates/svg/tests/focal.rs | 2 ++ crates/svg/tests/mask_options.rs | 2 ++ crates/svg/tests/stroke_export.rs | 2 ++ crates/svg/tests/text_stroke.rs | 2 ++ 20 files changed, 32 insertions(+), 10 deletions(-) diff --git a/apps/vectorcraft-cli/tests/fileio.rs b/apps/vectorcraft-cli/tests/fileio.rs index e95f36ab..f27feda3 100644 --- a/apps/vectorcraft-cli/tests/fileio.rs +++ b/apps/vectorcraft-cli/tests/fileio.rs @@ -1,4 +1,6 @@ //! The CLI opens every readable format (PDF, .ai, images) through the engine's `document.open`. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use std::process::Command; diff --git a/crates/color/src/harmony.rs b/crates/color/src/harmony.rs index a251bc79..8bdff710 100644 --- a/crates/color/src/harmony.rs +++ b/crates/color/src/harmony.rs @@ -386,7 +386,7 @@ mod tests { for h in Harmony::ALL { assert!(h.apply(base).iter().all(|c| matches!(c, Color::Cmyk { .. })), "{}", h.label()); } - let Color::Cmyk { c, m, y, .. } = Harmony::Complementary.apply(base)[1] else { unreachable!() }; + let Color::Cmyk { c, m, y, .. } = Harmony::Complementary.apply(base)[1] else { panic!("a CMYK complement") }; assert!(c > m && c > y, "the complement of red is a cyan: {c} {m} {y}"); let g = Guide::new(Color::gray(0.4), Harmony::Triad, &GuideOptions::default()); assert!(g.grid.iter().flatten().all(|c| matches!(c, Color::Gray { .. }))); diff --git a/crates/color/src/lib.rs b/crates/color/src/lib.rs index 4b2c6b7d..742dfb74 100644 --- a/crates/color/src/lib.rs +++ b/crates/color/src/lib.rs @@ -516,7 +516,7 @@ mod tests { *t = 0.5; true }); - let Paint::Gradient(g) = g else { unreachable!() }; + let Paint::Gradient(g) = g else { panic!("a gradient") }; assert!(g.gradient.stops.iter().all(|s| s.swatch.as_deref() == Some("Ink") && s.tint == 0.5)); } diff --git a/crates/doc/src/node.rs b/crates/doc/src/node.rs index 39162c46..f075ebcb 100644 --- a/crates/doc/src/node.rs +++ b/crates/doc/src/node.rs @@ -1132,7 +1132,7 @@ mod tests { let fresh = || Node::path(NodeId(2), shapes::rectangle(Rect::new(0.0, 0.0, 100.0, 50.0)), Appearance::basic(grad(), grad(), 2.0)); let geoms = |n: &Node| match (n.appearance.fill_paint(), n.appearance.stroke_paint()) { (Paint::Gradient(f), Paint::Gradient(s)) => (f.geom, s.geom), - _ => unreachable!(), + _ => panic!("gradient fill and stroke"), }; let mut n = fresh(); n.transform(Affine::translate((10.0, 5.0)) * Affine::scale(2.0), true); diff --git a/crates/doc/src/overprint.rs b/crates/doc/src/overprint.rs index 0fcf3b18..86b61921 100644 --- a/crates/doc/src/overprint.rs +++ b/crates/doc/src/overprint.rs @@ -163,10 +163,10 @@ mod tests { let style = CharStyle { fill: spot, stroke: k, stroke_width: 1.0, ..CharStyle::default() }; let mut t = Node::new(NodeId(2), NodeKind::Text(Box::new(TextObject::point(Point::ZERO, "Hi", style)))); OverprintBlack::default().apply(&mut t, &["Ink".to_string()]); - let NodeKind::Text(tx) = &t.kind else { unreachable!() }; + let NodeKind::Text(tx) = &t.kind else { panic!("type") }; assert!(!tx.runs[0].style.overprint_fill && tx.runs[0].style.overprint_stroke); OverprintBlack { spot: true, ..Default::default() }.apply(&mut t, &["Ink".to_string()]); - let NodeKind::Text(tx) = &t.kind else { unreachable!() }; + let NodeKind::Text(tx) = &t.kind else { panic!("type") }; assert!(tx.runs[0].style.overprint_fill); } diff --git a/crates/effects/src/stroke/tests_arrows.rs b/crates/effects/src/stroke/tests_arrows.rs index 14e2fa23..39d6d9d5 100644 --- a/crates/effects/src/stroke/tests_arrows.rs +++ b/crates/effects/src/stroke/tests_arrows.rs @@ -32,7 +32,7 @@ fn contours(bp: &BezPath) -> Vec> { c.pop(); } } - _ => unreachable!("flattened"), + _ => panic!("flattened"), }); out } diff --git a/crates/engine/src/tests_containers.rs b/crates/engine/src/tests_containers.rs index 8ad6f0a0..dc11f0c0 100644 --- a/crates/engine/src/tests_containers.rs +++ b/crates/engine/src/tests_containers.rs @@ -116,7 +116,7 @@ fn type_fills_go_above_or_below_the_characters() { // A new fill on type copies its characters' fill (it has none of its own). run(&mut s, "appearance.addFill", json!({})); let n = node(&s, t); - let NodeKind::Text(tx) = &n.kind else { unreachable!() }; + let NodeKind::Text(tx) = &n.kind else { panic!("type") }; assert_eq!(n.appearance.fill_paint(), tx.runs[0].style.fill); run(&mut s, "appearance.moveItem", json!({"from": "contents", "to": 1})); assert_eq!(node(&s, t).appearance.contents_at(), 1); diff --git a/crates/engine/src/tests_focal.rs b/crates/engine/src/tests_focal.rs index 63d7f52d..214fe774 100644 --- a/crates/engine/src/tests_focal.rs +++ b/crates/engine/src/tests_focal.rs @@ -76,7 +76,7 @@ fn the_focal_point_round_trips_through_params_and_the_native_format() { s.execute("paint.setGradientGeom", &json!({"focal": [170, 190], "aspect": 80})).unwrap(); let want = geom(&s, id); // Gradient params (what swatches and agents read) carry it, and give it back. - let Paint::Gradient(g) = s.doc().unwrap().doc.node(id).unwrap().appearance.fill_paint() else { unreachable!() }; + let Paint::Gradient(g) = s.doc().unwrap().doc.node(id).unwrap().appearance.fill_paint() else { panic!("a gradient fill") }; let params = vectorcraft_tools::params::gradient_params(&g); assert_eq!(params["focal"], json!([170.0, 190.0])); s.execute("paint.setFill", &json!({"gradient": {"kind": "linear"}})).unwrap(); diff --git a/crates/engine/src/tests_stylepanel.rs b/crates/engine/src/tests_stylepanel.rs index 7717f4f7..07ffb03f 100644 --- a/crates/engine/src/tests_stylepanel.rs +++ b/crates/engine/src/tests_stylepanel.rs @@ -109,7 +109,7 @@ fn override_character_color_clears_the_run_fill() { let text = |s: &mut Session, y: f64| id_of(&run(s, "text.create", json!({"x": 10, "y": y, "text": "Hi", "size": 40}))); let runs = |s: &Session, id: NodeId| match &s.doc().unwrap().doc.node(id).unwrap().kind { NodeKind::Text(t) => t.runs.iter().map(|r| (r.style.fill.clone(), r.style.stroke.clone())).collect::>(), - _ => unreachable!(), + _ => panic!("type"), }; // On by default: the characters' own colour gives way to the style's fill and stroke. assert_eq!(run(&mut s, "graphicStyle.setOptions", json!({}))["overrideCharColor"], true); diff --git a/crates/engine/src/tests_swatches.rs b/crates/engine/src/tests_swatches.rs index 271eaee0..5b886278 100644 --- a/crates/engine/src/tests_swatches.rs +++ b/crates/engine/src/tests_swatches.rs @@ -149,7 +149,7 @@ fn editing_a_global_swatch_recolours_linked_art_in_one_step() { assert_eq!(fill_of(&s, b), Paint::solid(Color::from_hex("#2a6fb0").unwrap()), "unlinked art keeps its colour"); let text_fill = |s: &Session| match &doc(s).node(t).unwrap().kind { vectorcraft_doc::NodeKind::Text(tx) => tx.runs[0].style.fill.clone(), - _ => unreachable!(), + _ => panic!("type"), }; assert_eq!(text_fill(&s), linked("#ff0000", "Brand"), "text runs follow the swatch"); assert_eq!(s.paint.stroke, linked("#ff0000", "Brand"), "so does the default stroke"); diff --git a/crates/render/tests/gradient_text.rs b/crates/render/tests/gradient_text.rs index 2857058c..6307a406 100644 --- a/crates/render/tests/gradient_text.rs +++ b/crates/render/tests/gradient_text.rs @@ -1,4 +1,6 @@ //! Gradients on type: a vector across the text, and run strokes fitted like object strokes. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use serde_json::json; use vectorcraft_color::Paint; diff --git a/crates/render/tests/stroke_geometry.rs b/crates/render/tests/stroke_geometry.rs index 4176ca5a..1dbb110c 100644 --- a/crates/render/tests/stroke_geometry.rs +++ b/crates/render/tests/stroke_geometry.rs @@ -1,5 +1,7 @@ //! Pixel tests for the shared stroke geometry (`vectorcraft_effects::stroke`) on the canvas: //! dotted lines (zero-length dashes) and arrowheads (hollow kinds, alignment, compositing). +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Color, Gradient, GradientKind, GradientPaint, GradientStop, Paint}; use vectorcraft_doc::{Appearance, AppearanceItem, ArrowAlign, Arrowhead, Dash, Document, LineCap, StrokeLayer}; diff --git a/crates/svg/tests/blend_export.rs b/crates/svg/tests/blend_export.rs index 503130c9..7cf88f62 100644 --- a/crates/svg/tests/blend_export.rs +++ b/crates/svg/tests/blend_export.rs @@ -1,5 +1,7 @@ //! Blend modes and opacity masks in SVG export look as on the canvas: every mode follows the //! reference formulas when resvg draws the file, and masks take luminance the canvas's way. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::blend::blend_rgb; use vectorcraft_color::{BlendMode, Color, Paint}; diff --git a/crates/svg/tests/container_export.rs b/crates/svg/tests/container_export.rs index 9f3afc74..12f0b44b 100644 --- a/crates/svg/tests/container_export.rs +++ b/crates/svg/tests/container_export.rs @@ -1,6 +1,8 @@ //! The appearance of groups and layers in SVG export: their own fills and strokes are baked into //! paths painting the members (below or above them as the contents slot says), their geometry //! effects into the members, and their raster effects filter the whole group. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use std::sync::Arc; diff --git a/crates/svg/tests/dash_align.rs b/crates/svg/tests/dash_align.rs index 2885d374..edb047b1 100644 --- a/crates/svg/tests/dash_align.rs +++ b/crates/svg/tests/dash_align.rs @@ -1,5 +1,7 @@ //! Dashes fitted to corners export as the canvas's filled outlines (a dash array can't fit them); //! exact dashes stay a `stroke-dasharray`. Checked by rendering the exported SVG with resvg. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Color, Paint}; use vectorcraft_doc::{Appearance, AppearanceItem, Dash, Document, Node, StrokeLayer}; diff --git a/crates/svg/tests/effects_export.rs b/crates/svg/tests/effects_export.rs index 911c2342..5e6f433e 100644 --- a/crates/svg/tests/effects_export.rs +++ b/crates/svg/tests/effects_export.rs @@ -1,5 +1,7 @@ //! Live effects in SVG export: a fill or stroke's own raster effects become filters on that item's //! element, and geometry effects on type are baked through its outlines. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use serde_json::json; use vectorcraft_color::{Color, Paint}; diff --git a/crates/svg/tests/focal.rs b/crates/svg/tests/focal.rs index 4d76faf4..e6191445 100644 --- a/crates/svg/tests/focal.rs +++ b/crates/svg/tests/focal.rs @@ -1,4 +1,6 @@ //! Radial gradients' focal points as `fx`/`fy`, out and back in. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Gradient, GradientGeom, GradientKind, GradientPaint, Paint}; use vectorcraft_doc::{Appearance, Document, Node}; diff --git a/crates/svg/tests/mask_options.rs b/crates/svg/tests/mask_options.rs index fd310d11..ab9a1518 100644 --- a/crates/svg/tests/mask_options.rs +++ b/crates/svg/tests/mask_options.rs @@ -1,6 +1,8 @@ //! Opacity-mask options survive SVG (M3.87): exported masks list the options that differ from the //! defaults in `data-vectorcraft-mask`, and import restores them and the original mask art (without //! the backdrop rectangle and inverting filter that draw the options in SVG). +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Color, Paint}; use vectorcraft_doc::{Appearance, Document, Node, OpacityMask}; diff --git a/crates/svg/tests/stroke_export.rs b/crates/svg/tests/stroke_export.rs index 47a5d592..4c861469 100644 --- a/crates/svg/tests/stroke_export.rs +++ b/crates/svg/tests/stroke_export.rs @@ -1,6 +1,8 @@ //! Strokes in SVG export look as on the canvas: arrowheads, width profiles, dots and brushes are //! written as the canvas's filled outlines or art, aligned strokes are clipped or masked, and open //! paths stroke centred. Checked by rendering the exported SVG with resvg. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Color, Paint}; use vectorcraft_doc::{Appearance, AppearanceItem, Arrowhead, Dash, Document, LineCap, LineJoin, Node, StrokeAlign, StrokeLayer, WidthProfile}; diff --git a/crates/svg/tests/text_stroke.rs b/crates/svg/tests/text_stroke.rs index 81293f8e..c1fe28f5 100644 --- a/crates/svg/tests/text_stroke.rs +++ b/crates/svg/tests/text_stroke.rs @@ -1,5 +1,7 @@ //! Strokes on type in SVG: character stroke options on live text (and back), runs that differ //! from the first, and the object's own strokes drawn over the glyph outlines. +// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness). +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use vectorcraft_color::{Color, Paint}; use vectorcraft_doc::{AppearanceItem, CharStyle, Dash, Document, LineCap, LineJoin, Node, NodeKind, StrokeLayer, TextObject, TextRun};