From 1bfae77c16ee1760aed725fefcba73ab2a100e2d Mon Sep 17 00:00:00 2001 From: David Mann Date: Thu, 22 Oct 2026 21:39:28 +0200 Subject: [PATCH] Integration: test stringID blend modes through .atn import (#8502) The PR's test only called blend_label/blend_ps. This adds one through the import entry point: a Set Lyr step with Md enm("BlnM","softLight") and a Make layer step with Usng Md "luminosity", written with atn::write and imported, must give layer.setProps blend "Soft Light" and layer.new.layer mode "Luminosity" with no unsupported steps. Without the PR's table rows the Set step is unsupported (and the Make falls back to Normal). Co-authored-by: justinjohn0306 <34035011+justinjohn0306@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 (1M context) --- crates/engine/src/atn_cmds/tests.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/engine/src/atn_cmds/tests.rs b/crates/engine/src/atn_cmds/tests.rs index 9954f85fee..a3ddcde026 100644 --- a/crates/engine/src/atn_cmds/tests.rs +++ b/crates/engine/src/atn_cmds/tests.rs @@ -30,6 +30,32 @@ fn blend_modes_accept_photoshop_string_ids_and_export_canonical_char_ids() { } } +/// #8454: a Set and a Make layer step whose blend mode is stored as a Photoshop stringID import +/// with that mode (a Set was unsupported, a Make silently fell back to Normal). +#[test] +fn layer_steps_with_string_id_blend_modes_import_with_their_mode() { + let set = desc("null").with("null", target_ref("Lyr ")).with("T ", D::Descriptor(desc("Lyr ").with("Md ", enm("BlnM", "softLight")))); + let make = desc("null").with("null", class_ref("Lyr ")).with("Usng", D::Descriptor(desc("Lyr ").with("Md ", enm("BlnM", "luminosity")))); + let file = AtnFile { + name: UnicodeString::new_nul("Blend"), + expanded: false, + actions: vec![AtnAction { + name: UnicodeString::new_nul("A"), + items: vec![item("setd", "Set", Some(set)), item("Mk ", "Make", Some(make))], + ..Default::default() + }], + warnings: vec![], + }; + let imp = import(&atn::write(&file).unwrap()).unwrap(); + assert!(imp.unsupported.is_empty(), "{:?}", imp.unsupported.iter().map(|u| &u.event).collect::>()); + let steps = &imp.actions[0].steps; + assert_eq!(steps.len(), 2); + assert_eq!(steps[0].0, "layer.setProps"); + assert_eq!(steps[0].1["blend"], json!("Soft Light")); + assert_eq!(steps[1].0, "layer.new.layer"); + assert_eq!(steps[1].1["mode"], json!("Luminosity")); +} + fn item(event: &str, label: &str, d: Option) -> AtnItem { let event = match event.as_bytes() { [a, b, c, dd] => AtnEvent::Code([*a, *b, *c, *dd]),