mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 13:09:16 +00:00
Tests: the one-paint style fuzz case applies the styles it loads
The fuzz case also loads its .ai library with graphicStyle.loadLibrary, applies every style to the rich document's objects and then applies a red 2 pt stroke style read before the fuzzed one, and checks that the stroke style reaches the objects whenever the fuzzed text is only paint operators.
This commit is contained in:
@@ -4218,9 +4218,11 @@ proptest! {
|
||||
}
|
||||
|
||||
/// Graphic style libraries whose styles are one paint (`/SimpleStyle`): any paint operators in
|
||||
/// any order, with any operands or none, `Xd` missing or repeated, and the paint left open.
|
||||
/// any order, with any operands or none, `Xd` missing or repeated, and the paint left open. The
|
||||
/// library is also loaded in the Graphic Style Libraries panel and its styles applied to artwork.
|
||||
#[test]
|
||||
fn ai_style_libraries_of_one_paint_styles_never_panic(
|
||||
// Each operator, and whether it is a paint operator rather than any text.
|
||||
ops in prop::collection::vec(prop_oneof![
|
||||
prop::sample::select(vec![
|
||||
"0 R", "0 O", "0 1 1 0 K", "1 0 0 0 k", "0 0 0 0 1 0 0 Xa", "0 0 0 0 1 0 0 XA", "0.5 G", "0 g", "K", "Xa",
|
||||
@@ -4228,20 +4230,43 @@ proptest! {
|
||||
"1 0 Xd", "0 1 Xd", "1 1 Xd", "0 0 Xd", "1 Xd", "Xd", "0 1 0 0 0 Xy", "1 0.5 1 1 0 Xy", "Xy",
|
||||
"0 Bb", "2 (Sky) 0 0 0 100 1 0 0 1 0 0 Bg", "0 BB", "(Dots) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p",
|
||||
"(Dots) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] P", "0 XR",
|
||||
]).prop_map(str::to_string),
|
||||
"[ -~]{0,12}",
|
||||
]).prop_map(|op| (op.to_string(), true)),
|
||||
"[ -~]{0,12}".prop_map(|text| (text, false)),
|
||||
], 0..12),
|
||||
closed in any::<bool>(),
|
||||
) {
|
||||
use vectorcraft_testkit::ai;
|
||||
let close = if closed { "/Paint ;\n/Def ;\n" } else { "" };
|
||||
// C, a red 2 pt stroke, comes first, so that it reads whatever A holds.
|
||||
let header = format!(
|
||||
"%AI9_BeginArtStyles\n/KnownStyle :\n(A) /Name ,\n/SimpleStyle :\n{}\n{close}/KnownStyle :\n(B) /Name ,\n/SimpleStyle :\n1 0 Xd\n/Paint ;\n/Def ;\n\
|
||||
%AI9_EndArtStyles\n%AI9_BeginArtStyleList\n(A)\n(B)\n%AI9_EndArtStyleList\n",
|
||||
ops.join("\n")
|
||||
"%AI9_BeginArtStyles\n/KnownStyle :\n(C) /Name ,\n/SimpleStyle :\n0 R\n0 1 1 0 K\n2 w\n1 0 Xd\n/Paint ;\n/Def ;\n\
|
||||
/KnownStyle :\n(A) /Name ,\n/SimpleStyle :\n{}\n{close}/KnownStyle :\n(B) /Name ,\n/SimpleStyle :\n1 0 Xd\n/Paint ;\n/Def ;\n\
|
||||
%AI9_EndArtStyles\n%AI9_BeginArtStyleList\n(A)\n(B)\n(C)\n%AI9_EndArtStyleList\n",
|
||||
ops.iter().map(|(op, _)| op.as_str()).collect::<Vec<_>>().join("\n")
|
||||
);
|
||||
let library = ai::editing_data(200.0, 100.0, &header);
|
||||
survive("one-paint style library", || Some(vectorcraft_eps::layered_ai(library.as_bytes(), Document::new(200.0, 100.0), vec![], false, false, 1.0).0))?;
|
||||
let file = ai::ai(library.as_bytes(), ai::page_pdf());
|
||||
// How many objects C's look reached, and what applying it answered.
|
||||
let (mut styled, mut applied) = (0, Value::Null);
|
||||
survive("one-paint styles applied", || {
|
||||
let mut s = rich_session();
|
||||
let p = json!({"dataBase64": vectorcraft_format::base64_encode(&file), "name": "fuzz.ai"});
|
||||
let library = no_panic(s.execute("graphicStyle.loadLibrary", &p)).ok()?["library"].clone();
|
||||
no_panic(s.execute("select.all", &json!({}))).ok()?;
|
||||
// Every style is added and the first one, A when it reads, applied; then C is applied.
|
||||
let _ = no_panic(s.execute("graphicStyle.addFromLibrary", &json!({"library": library, "apply": true})));
|
||||
applied = no_panic(s.execute("graphicStyle.addFromLibrary", &json!({"library": library, "names": ["C"], "apply": true}))).ok()?;
|
||||
let d = (*s.doc().ok()?.doc).clone();
|
||||
if let Some(look) = applied["applied"].as_str().and_then(|name| d.graphic_style(name)).map(|g| &g.appearance) {
|
||||
d.walk(|n| styled += usize::from(n.appearance == *look));
|
||||
}
|
||||
Some(d)
|
||||
})?;
|
||||
// Text that isn't a paint operator can leave a string or a comment open over the style list.
|
||||
if ops.iter().all(|(_, paint)| *paint) {
|
||||
prop_assert!(applied["applied"].is_string() && styled > 0, "the stroke style wasn't applied: {applied}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Objects on Path records of any shape: ids in any order, repeated or missing, any number of
|
||||
|
||||
Reference in New Issue
Block a user