M14.4: tests main gained follow the no-panic lint rules

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 <[email protected]>
This commit is contained in:
bflatasticandClaude Opus 5.5 committed 2026-10-05 06:40:34 +07:00
1 parent 8d0fae610d
commit 0744347065
20 files changed
+32 -10

No files matched your search

+2
View File
@@ -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;
+1 -1
View File
@@ -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 { .. })));
+1 -1
View File
@@ -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));
}
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -32,7 +32,7 @@ fn contours(bp: &BezPath) -> Vec<Vec<Point>> {
c.pop();
}
}
_ => unreachable!("flattened"),
_ => panic!("flattened"),
});
out
}
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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::<Vec<_>>(),
_ => 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);
+1 -1
View File
@@ -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");
+2
View File
@@ -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;
+2
View File
@@ -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};
+2
View File
@@ -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};
+2
View File
@@ -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;
+2
View File
@@ -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};
+2
View File
@@ -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};
+2
View File
@@ -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};
+2
View File
@@ -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};
+2
View File
@@ -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};
+2
View File
@@ -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};