mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-01 05:47:31 -06:00
9863 lines
1.2 MiB
Plaintext
9863 lines
1.2 MiB
Plaintext
{
|
|
"integration_code_sha": "f5b3f1238bb414b43851ebe86f3a58ce83bb9b48",
|
|
"cases": [
|
|
{
|
|
"id": "PR-3455",
|
|
"pr": 3455,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked recording_and_appending_steps_can_be_undone_without_restarting_recording -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked definition_edits_undo_redo_without_touching_document_or_journal -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked enabled_step_edits_undo_and_invalidate_redo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked undo_pending_step_deletion_does_not_duplicate_recording -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked actions_shortcut_undo_and_redo_edit_script_without_undoing_pixels -- --nocapture"
|
|
],
|
|
"expected": "recording and appending steps can be undone without restarting recording; definition edits undo redo without touching document or journal; enabled step edits undo and invalidate redo; undo pending step deletion does not duplicate recording; actions shortcut undo and redo edit script without undoing pixels",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked recording_and_appending_steps_can_be_undone_without_restarting_recording -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked definition_edits_undo_redo_without_touching_document_or_journal -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked enabled_step_edits_undo_and_invalidate_redo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked undo_pending_step_deletion_does_not_duplicate_recording -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked actions_shortcut_undo_and_redo_edit_script_without_undoing_pixels -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "recording_and_appending_steps_can_be_undone_without_restarting_recording",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked recording_and_appending_steps_can_be_undone_without_restarting_recording -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n s.execute(\"actions.record\", json!({\"name\": \"A\"})).unwrap();\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"actions.stop\", json!({})).unwrap();\n s.execute(\"actions.record\", json!({\"action\": \"A\"})).unwrap();\n s.execute(\"select.all\", json!({})).unwrap();\n s.execute(\"actions.stop\", json!({})).unwrap();\n let doc = s.active().unwrap().doc.clone();\n assert_eq!(s.actions.list[0].steps.len(), 2);\n s.execute(\"actions.undo\", json!({})).unwrap();\n assert_eq!(s.actions.list[0].steps.len(), 1);",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.actions.list[0].steps.len(), 2);\n s.execute(\"actions.undo\", json!({})).unwrap();\n assert_eq!(s.actions.list[0].steps.len(), 1);\n assert!(s.actions.recording.is_none());\n s.execute(\"actions.redo\", json!({})).unwrap();\n assert_eq!(s.actions.list[0].steps.len(), 2);\n assert!(s.actions.recording.is_none());\n assert_eq!(s.active().unwrap().doc, doc);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d84fa7955d260505378a1a596ec80d602036319d/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "definition_edits_undo_redo_without_touching_document_or_journal",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked definition_edits_undo_redo_without_touching_document_or_journal -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n s.actions.list.push(Action {\n name: \"A\".into(),\n steps: vec![(\"layer.new.layer\".into(), json!({})), (\"select.all\".into(), json!({}))],\n disabled: Default::default(),\n });\n s.actions.list.push(Action { name: \"Caller\".into(), steps: vec![(\"actions.play\".into(), json!({\"action\": \"A\"}))], disabled: Default::default() });\n s.edit_prefs(|p| {\n p.shortcuts.insert(\"actions.play:A\".into(), \"F6\".into());\n });\n let before = s.actions.list.clone();",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.actions.list, before);\n assert_eq!(s.prefs().shortcuts.get(\"actions.play:A\").map(String::as_str), Some(\"F6\"));\n assert!(!s.prefs().shortcuts.contains_key(\"actions.play:B\"));\n for _ in 0..3 {\n s.execute(\"actions.redo\", json!({})).unwrap();\n }\n assert_eq!(s.actions.list, after);\n assert_eq!(s.active().unwrap().doc, doc);\n assert_eq!(s.journal, journal);\n s.execute(\"actions.undo\", json!({})).unwrap();\n s.execute(\"actions.delete\", json!({\"action\": \"Caller\"})).unwrap();\n assert!(!can_redo(&s));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d84fa7955d260505378a1a596ec80d602036319d/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "enabled_step_edits_undo_and_invalidate_redo",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked enabled_step_edits_undo_and_invalidate_redo -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.actions.list.push(Action::new(\"A\", vec![(\"select.all\".into(), json!({}))]));\n s.execute(\"actions.toggle\", json!({\"action\": \"A\", \"step\": 0})).unwrap();\n assert!(s.actions.list[0].disabled.contains(&0));\n s.execute(\"actions.undo\", json!({})).unwrap();\n assert!(s.actions.list[0].disabled.is_empty());\n s.execute(\"actions.redo\", json!({})).unwrap();\n assert!(s.actions.list[0].disabled.contains(&0));\n s.execute(\"actions.undo\", json!({})).unwrap();\n s.execute(\"actions.toggle\", json!({\"action\": \"A\"})).unwrap();\n assert!(!can_redo(&s));\n }",
|
|
"expected_assertions": [
|
|
" assert!(s.actions.list[0].disabled.contains(&0));\n s.execute(\"actions.undo\", json!({})).unwrap();\n assert!(s.actions.list[0].disabled.is_empty());\n s.execute(\"actions.redo\", json!({})).unwrap();\n assert!(s.actions.list[0].disabled.contains(&0));\n s.execute(\"actions.undo\", json!({})).unwrap();\n s.execute(\"actions.toggle\", json!({\"action\": \"A\"})).unwrap();\n assert!(!can_redo(&s));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d84fa7955d260505378a1a596ec80d602036319d/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "undo_pending_step_deletion_does_not_duplicate_recording",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked undo_pending_step_deletion_does_not_duplicate_recording -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n s.execute(\"actions.record\", json!({\"name\": \"A\"})).unwrap();\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"actions.delete\", json!({\"action\": \"A\", \"step\": 0})).unwrap();\n s.execute(\"actions.undo\", json!({})).unwrap();\n s.execute(\"actions.stop\", json!({})).unwrap();\n assert_eq!(s.actions.list[0].steps.len(), 1);\n assert_eq!(s.active().unwrap().doc.layers.len(), 2);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.actions.list[0].steps.len(), 1);\n assert_eq!(s.active().unwrap().doc.layers.len(), 2);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d84fa7955d260505378a1a596ec80d602036319d/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "actions_shortcut_undo_and_redo_edit_script_without_undoing_pixels",
|
|
"path": "crates/ui-egui/src/actions.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked actions_shortcut_undo_and_redo_edit_script_without_undoing_pixels -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n app.run(\"layer.new.layer\", json!({})).unwrap();\n app.session.actions.list.push(Action { name: \"A\".into(), steps: vec![(\"select.all\".into(), json!({}))], disabled: Default::default() });\n let doc = app.session.active().unwrap().doc.clone();\n let mut h = Harness::builder().with_size(vec2(320.0, 260.0)).build_ui_state(|ui, app| panel(app, ui), app);\n h.run_steps(3);\n h.get_by_label(\"A\").click();\n h.run_steps(3);\n assert!(h.state().ui.actions.focused);\n h.state_mut().run(\"actions.delete\", json!({\"action\": \"A\", \"step\": 0})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.actions.focused);\n h.state_mut().run(\"actions.delete\", json!({\"action\": \"A\", \"step\": 0})).unwrap();\n let ctx = egui::Context::default();\n crate::shortcut_dispatch::dispatch(h.state_mut(), &ctx, \"edit.undo\");\n assert_eq!(h.state().session.actions.list[0].steps.len(), 1);\n assert_eq!(h.state().session.active().unwrap().doc, doc);\n crate::shortcut_dispatch::dispatch(h.state_mut(), &ctx, \"edit.redo\");\n assert!(h.state().session.actions.list[0].steps.is_empty());\n h.state_mut().ui.actions.focused = false;\n crate::shortcut_dispatch::dispatch(h.state_mut(), &ctx, \"edit.undo\");\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 1);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d84fa7955d260505378a1a596ec80d602036319d/crates/ui-egui/src/actions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3748",
|
|
"pr": 3748,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked unknown_names_suggest_the_right_method_or_command -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked errors_are_tool_errors_not_crashes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked protocol_listing_method_points_at_command_list -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked near_misses_suggest_registered_ids -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked suggestions_are_capped_and_ordered -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked protocol_method_hints -- --nocapture",
|
|
"cargo test -p photocraft-text --locked tokenizer_and_distance -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked unknown_names_suggest_the_right_method_or_command -- --nocapture"
|
|
],
|
|
"expected": "unknown names suggest the right method or command; errors are tool errors not crashes; protocol listing method points at command list; near misses suggest registered ids; suggestions are capped and ordered; protocol method hints; tokenizer and distance; unknown names suggest the right method or command",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked unknown_names_suggest_the_right_method_or_command -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked errors_are_tool_errors_not_crashes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked protocol_listing_method_points_at_command_list -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked near_misses_suggest_registered_ids -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked suggestions_are_capped_and_ordered -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked protocol_method_hints -- --nocapture",
|
|
"cargo test -p photocraft-text --locked tokenizer_and_distance -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked unknown_names_suggest_the_right_method_or_command -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "unknown_names_suggest_the_right_method_or_command",
|
|
"path": "crates/automation/src/rpc.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked unknown_names_suggest_the_right_method_or_command -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = Headless::new();\n let err = |h: &mut Headless, m: &str, p: Value| h.handle(m, p).unwrap_err().to_string();\n let e = err(&mut h, \"engine.execute\", json!({\"command\": \"engine.commands\"}));\n assert!(e.contains(\"did you mean `command.list`\") && e.contains(\"protocol method\"), \"{e}\");\n let e = err(&mut h, \"engine.execute\", json!({\"command\": \"doc.inspect\"}));\n assert!(e.contains(\"`doc.inspect` is a protocol method\"), \"{e}\");\n let e = err(&mut h, \"engine.execute\", json!({\"command\": \"edit.undoo\"}));\n assert!(e.contains(\"did you mean `edit.undo`\"), \"{e}\");\n let e = err(&mut h, \"doc.inspct\", Value::Null);\n assert!(e.contains(\"did you mean `doc.inspect`\") && e.contains(\"(try `methods`)\"), \"{e}\");\n let e = err(&mut h, \"edit.undo\", Value::Null);\n assert!(e.contains(\"engine.execute {\\\"command\\\": \\\"edit.undo\\\"}\"), \"{e}\");",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(\"did you mean `command.list`\") && e.contains(\"protocol method\"), \"{e}\");\n let e = err(&mut h, \"engine.execute\", json!({\"command\": \"doc.inspect\"}));\n assert!(e.contains(\"`doc.inspect` is a protocol method\"), \"{e}\");\n let e = err(&mut h, \"engine.execute\", json!({\"command\": \"edit.undoo\"}));\n assert!(e.contains(\"did you mean `edit.undo`\"), \"{e}\");\n let e = err(&mut h, \"doc.inspct\", Value::Null);\n assert!(e.contains(\"did you mean `doc.inspect`\") && e.contains(\"(try `methods`)\"), \"{e}\");\n let e = err(&mut h, \"edit.undo\", Value::Null);\n assert!(e.contains(\"engine.execute {\\\"command\\\": \\\"edit.undo\\\"}\"), \"{e}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/automation/src/rpc.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "errors_are_tool_errors_not_crashes",
|
|
"path": "crates/automation/tests/mcp.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked errors_are_tool_errors_not_crashes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let client = connect(PhotocraftMcp::headless()).await;\n let r = call(&client, \"command_run\", json!({\"id\": \"no.such.command\"})).await;\n assert_eq!(r.is_error, Some(true));\n assert!(text(&r).contains(\"unknown command\"));\n // #3674: the error names the nearest registered id.\n let r = call(&client, \"command_run\", json!({\"id\": \"engine.commands\"})).await;\n assert_eq!(r.is_error, Some(true));\n assert!(text(&r).contains(\"did you mean `command.list`\"), \"{}\", text(&r));\n let r = call(&client, \"doc_inspect\", json!({\"index\": 0})).await;\n assert_eq!(r.is_error, Some(true));\n let r = call(&client, \"doc_open\", json!({\"path\": \"/definitely/missing.png\"})).await;\n assert_eq!(r.is_error, Some(true));",
|
|
"expected_assertions": [
|
|
" assert_eq!(r.is_error, Some(true));\n assert!(text(&r).contains(\"unknown command\"));\n // #3674: the error names the nearest registered id.\n let r = call(&client, \"command_run\", json!({\"id\": \"engine.commands\"})).await;\n assert_eq!(r.is_error, Some(true));\n assert!(text(&r).contains(\"did you mean `command.list`\"), \"{}\", text(&r));\n let r = call(&client, \"doc_inspect\", json!({\"index\": 0})).await;\n assert_eq!(r.is_error, Some(true));\n let r = call(&client, \"doc_open\", json!({\"path\": \"/definitely/missing.png\"})).await;\n assert_eq!(r.is_error, Some(true));\n let r = call(&client, \"ui_inspect\", json!({})).await;\n assert_eq!(r.is_error, Some(true));\n assert!(text(&r).contains(\"bridge\"));\n let r = call(&client, \"doc_export\", json!({})).await;\n assert_eq!(r.is_error, Some(true));\n // Server still alive.\n json_of(&call(&client, \"session_list\", json!({})).await);\n client.cancel().await.unwrap();"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/automation/tests/mcp.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "protocol_listing_method_points_at_command_list",
|
|
"path": "crates/engine/src/command_hints.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked protocol_listing_method_points_at_command_list -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert_eq!(unknown(\"engine.commands\"), \"unknown command `engine.commands`; did you mean `command.list`?\");\n let mut s = Session::new();\n let e = s.execute(\"engine.commands\", json!({})).unwrap_err().to_string();\n assert!(e.contains(\"did you mean `command.list`\"), \"{e}\");\n assert!(s.disabled_reason(\"engine.commands\").unwrap().contains(\"`command.list`\"));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(unknown(\"engine.commands\"), \"unknown command `engine.commands`; did you mean `command.list`?\");\n let mut s = Session::new();\n let e = s.execute(\"engine.commands\", json!({})).unwrap_err().to_string();\n assert!(e.contains(\"did you mean `command.list`\"), \"{e}\");\n assert!(s.disabled_reason(\"engine.commands\").unwrap().contains(\"`command.list`\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/engine/src/command_hints.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "near_misses_suggest_registered_ids",
|
|
"path": "crates/engine/src/command_hints.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked near_misses_suggest_registered_ids -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Typo, case, and the same verb in another namespace.\n assert!(unknown(\"edit.undoo\").contains(\"did you mean `edit.undo`\"), \"{}\", unknown(\"edit.undoo\"));\n assert!(unknown(\"Edit.Undo\").contains(\"did you mean `edit.undo`\"), \"{}\", unknown(\"Edit.Undo\"));\n let e = unknown(\"document.undo\");\n assert!(e.contains(\"did you mean `edit.undo`\"), \"{e}\");\n assert!(unknown(\"document.redo\").contains(\"did you mean `edit.redo`\"));\n // A namespace prefix, a truncated id, a shorter last segment.\n assert!(unknown(\"layer.new\").contains(\"`layer.new.layer`\"), \"{}\", unknown(\"layer.new\"));\n assert!(unknown(\"filter.blur.gaussian\").contains(\"did you mean `filter.blur.gaussianBlur`\"));\n assert!(unknown(\"image.size\").contains(\"did you mean `image.imageSize`\"), \"{}\", unknown(\"image.size\"));\n assert!(e.len() < 200, \"a few suggestions, not a listing: {e}\");\n // Nothing close: the plain error.",
|
|
"expected_assertions": [
|
|
" assert!(unknown(\"edit.undoo\").contains(\"did you mean `edit.undo`\"), \"{}\", unknown(\"edit.undoo\"));\n assert!(unknown(\"Edit.Undo\").contains(\"did you mean `edit.undo`\"), \"{}\", unknown(\"Edit.Undo\"));\n let e = unknown(\"document.undo\");\n assert!(e.contains(\"did you mean `edit.undo`\"), \"{e}\");\n assert!(unknown(\"document.redo\").contains(\"did you mean `edit.redo`\"));\n // A namespace prefix, a truncated id, a shorter last segment.\n assert!(unknown(\"layer.new\").contains(\"`layer.new.layer`\"), \"{}\", unknown(\"layer.new\"));\n assert!(unknown(\"filter.blur.gaussian\").contains(\"did you mean `filter.blur.gaussianBlur`\"));\n assert!(unknown(\"image.size\").contains(\"did you mean `image.imageSize`\"), \"{}\", unknown(\"image.size\"));\n assert!(e.len() < 200, \"a few suggestions, not a listing: {e}\");\n // Nothing close: the plain error.\n assert_eq!(unknown(\"zzzz.qqqq\"), \"unknown command `zzzz.qqqq`\");\n assert_eq!(unknown(\"\"), \"unknown command ``\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/engine/src/command_hints.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "suggestions_are_capped_and_ordered",
|
|
"path": "crates/engine/src/command_hints.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked suggestions_are_capped_and_ordered -- --nocapture",
|
|
"fixture_and_action_excerpt": " let c = [\"a.bc\", \"a.bd\", \"a.be\", \"a.bf\", \"x.y\"];\n assert_eq!(near_matches(\"a.bb\", c), [\"a.bc\", \"a.bd\", \"a.be\"]);\n assert_eq!(did_you_mean(&[]), \"\");\n assert_eq!(did_you_mean(&[\"a\"]), \"; did you mean `a`?\");\n assert_eq!(did_you_mean(&[\"a\", \"b\", \"c\"]), \"; did you mean `a`, `b` or `c`?\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(near_matches(\"a.bb\", c), [\"a.bc\", \"a.bd\", \"a.be\"]);\n assert_eq!(did_you_mean(&[]), \"\");\n assert_eq!(did_you_mean(&[\"a\"]), \"; did you mean `a`?\");\n assert_eq!(did_you_mean(&[\"a\", \"b\", \"c\"]), \"; did you mean `a`, `b` or `c`?\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/engine/src/command_hints.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "protocol_method_hints",
|
|
"path": "crates/engine/src/command_hints.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked protocol_method_hints -- --nocapture",
|
|
"fixture_and_action_excerpt": " let methods = [\"engine.execute\", \"doc.inspect\", \"doc.open\", \"methods\"];\n assert_eq!(unknown_method(\"doc.inspct\", &methods), \"unknown method `doc.inspct`; did you mean `doc.inspect`?\");\n assert!(unknown_method(\"edit.undo\", &methods).contains(\"engine.execute {\\\"command\\\": \\\"edit.undo\\\"}\"));\n assert_eq!(unknown_method(\"zzzz\", &methods), \"unknown method `zzzz`\");\n assert!(protocol_method_as_command(\"doc.inspect\").contains(\"`doc.inspect` is a protocol method\"));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(unknown_method(\"doc.inspct\", &methods), \"unknown method `doc.inspct`; did you mean `doc.inspect`?\");\n assert!(unknown_method(\"edit.undo\", &methods).contains(\"engine.execute {\\\"command\\\": \\\"edit.undo\\\"}\"));\n assert_eq!(unknown_method(\"zzzz\", &methods), \"unknown method `zzzz`\");\n assert!(protocol_method_as_command(\"doc.inspect\").contains(\"`doc.inspect` is a protocol method\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/engine/src/command_hints.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "tokenizer_and_distance",
|
|
"path": "crates/text/src/spell.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked tokenizer_and_distance -- --nocapture",
|
|
"fixture_and_action_excerpt": " let t = \"it's well-known 'quoted' caf\u00e9\";\n let w: Vec<&str> = words(t).into_iter().map(|(a, b)| &t[a..b]).collect();\n assert_eq!(w, vec![\"it's\", \"well\", \"known\", \"quoted\", \"caf\u00e9\"]);\n let c = |s: &str| s.chars().collect::<Vec<char>>();\n let mut r = Rows::default();\n assert_eq!(distance(&c(\"teh\"), &c(\"the\"), 2, &mut r), Some(1));\n assert_eq!(distance(&c(\"teh\"), &c(\"toe\"), 2, &mut r), Some(2));\n assert_eq!(distance(&c(\"teh\"), &c(\"banana\"), 2, &mut r), None);\n assert_eq!(edit_distance(\"edit.undoo\", \"edit.undo\", 2), Some(1));\n assert_eq!(edit_distance(\"teh\", \"banana\", 2), None);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(w, vec![\"it's\", \"well\", \"known\", \"quoted\", \"caf\u00e9\"]);\n let c = |s: &str| s.chars().collect::<Vec<char>>();\n let mut r = Rows::default();\n assert_eq!(distance(&c(\"teh\"), &c(\"the\"), 2, &mut r), Some(1));\n assert_eq!(distance(&c(\"teh\"), &c(\"toe\"), 2, &mut r), Some(2));\n assert_eq!(distance(&c(\"teh\"), &c(\"banana\"), 2, &mut r), None);\n assert_eq!(edit_distance(\"edit.undoo\", \"edit.undo\", 2), Some(1));\n assert_eq!(edit_distance(\"teh\", \"banana\", 2), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/text/src/spell.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "unknown_names_suggest_the_right_method_or_command",
|
|
"path": "crates/ui-egui/src/control.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked unknown_names_suggest_the_right_method_or_command -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let ctx = egui::Context::default();\n let mut error = |method: &str, params: Value| {\n let reply = call(&mut app, &ctx, method, params);\n assert_eq!(reply[\"ok\"], false, \"{reply}\");\n reply[\"error\"].as_str().unwrap_or_default().to_owned()\n };\n let e = error(\"engine.execute\", json!({\"command\": \"engine.commands\"}));\n assert!(e.contains(\"did you mean `command.list`\") && e.contains(\"protocol method\"), \"{e}\");\n let e = error(\"engine.execute\", json!({\"command\": \"ui.inspect\"}));\n assert!(e.contains(\"`ui.inspect` is a protocol method\"), \"{e}\");\n let e = error(\"engine.execute\", json!({\"command\": \"edit.undoo\"}));",
|
|
"expected_assertions": [
|
|
" assert_eq!(reply[\"ok\"], false, \"{reply}\");\n reply[\"error\"].as_str().unwrap_or_default().to_owned()\n };\n let e = error(\"engine.execute\", json!({\"command\": \"engine.commands\"}));\n assert!(e.contains(\"did you mean `command.list`\") && e.contains(\"protocol method\"), \"{e}\");\n let e = error(\"engine.execute\", json!({\"command\": \"ui.inspect\"}));\n assert!(e.contains(\"`ui.inspect` is a protocol method\"), \"{e}\");\n let e = error(\"engine.execute\", json!({\"command\": \"edit.undoo\"}));\n assert!(e.contains(\"did you mean `edit.undo`\"), \"{e}\");\n let e = error(\"ui.inspct\", json!({}));\n assert!(e.contains(\"did you mean `ui.inspect`\"), \"{e}\");\n let e = error(\"edit.undo\", json!({}));\n assert!(e.contains(\"engine.execute {\\\"command\\\": \\\"edit.undo\\\"}\"), \"{e}\");\n for m in METHODS {\n let (req, _rx) = ControlRequest::new(*m, json!({}));\n if let Outcome::Done(v) = handle(&mut app, &ctx, &req) {\n assert!(!v.to_string().contains(\"unknown method\"), \"{m} is listed but not served: {v}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c45d01eafe84e600bb28033a6853cc19c827b7bf/crates/ui-egui/src/control.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4993",
|
|
"pr": 4993,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked engine_execute_cannot_change_document_behind_adjustment_dialog -- --nocapture"
|
|
],
|
|
"expected": "engine execute cannot change document behind adjustment dialog",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked engine_execute_cannot_change_document_behind_adjustment_dialog -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "engine_execute_cannot_change_document_behind_adjustment_dialog",
|
|
"path": "crates/ui-egui/src/control.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked engine_execute_cannot_change_document_behind_adjustment_dialog -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let ctx = egui::Context::default();\n app.run(\"file.new\", json!({\"width\": 60, \"height\": 40, \"background\": \"#3366cc\"})).unwrap();\n let opened = call(&mut app, &ctx, \"ui.menu.invoke\", json!({\"id\": \"image.adjustments.hueSaturation\"}));\n assert_eq!(opened[\"ok\"], true, \"{opened}\");\n let dialog = opened[\"result\"][\"dialog\"].as_u64().unwrap();\n let revision = app.session.active().unwrap().revision;\n let fields = call(&mut app, &ctx, \"ui.inspect\", json!({}))[\"result\"][\"dialogs\"][0][\"fields\"].clone();\n\n for method in [\"engine.execute\", \"ui.menu.invoke\"] {\n let blocked = call(&mut app, &ctx, method, json!({\"command\": \"image.adjustments.invert\"}));\n assert_eq!(blocked[\"ok\"], false, \"{method}: {blocked}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(opened[\"ok\"], true, \"{opened}\");\n let dialog = opened[\"result\"][\"dialog\"].as_u64().unwrap();\n let revision = app.session.active().unwrap().revision;\n let fields = call(&mut app, &ctx, \"ui.inspect\", json!({}))[\"result\"][\"dialogs\"][0][\"fields\"].clone();\n assert_eq!(blocked[\"ok\"], false, \"{method}: {blocked}\");\n assert_eq!(app.session.active().unwrap().revision, revision, \"{method} changed the document\");\n let snapshot = call(&mut app, &ctx, \"ui.inspect\", json!({}));\n assert_eq!(snapshot[\"result\"][\"dialogs\"][0][\"id\"], dialog);\n assert_eq!(snapshot[\"result\"][\"dialogs\"][0][\"fields\"], fields);\n }\n\n assert_eq!(call(&mut app, &ctx, \"ui.dialog.cancel\", json!({\"dialog\": dialog}))[\"ok\"], true);\n assert_eq!(call(&mut app, &ctx, \"engine.execute\", json!({\"command\": \"image.adjustments.invert\"}))[\"ok\"], true);\n assert!(app.session.active().unwrap().revision > revision);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/81964dc5ef77a71a2ae2a938958cf3ed77d90719/crates/ui-egui/src/control.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5090",
|
|
"pr": 5090,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-web --locked generated_defaults_are_persisted_without_unsaved_user_work -- --nocapture",
|
|
"cargo test -p photocraft-web --locked denied_storage_marks_default_edits_unsaved_and_retry_saves_them -- --nocapture",
|
|
"cargo test -p photocraft-web --locked finishing_default_transaction_keeps_newer_action_edits_unsaved -- --nocapture",
|
|
"cargo test -p photocraft-web --locked failed_default_transaction_does_not_warn_until_a_user_edit -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked load_defaults_preserves_names_and_edits_and_is_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked defaults_seed_once_and_restore_only_when_requested -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked old_store_and_early_actions_win_over_defaults -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked unreadable_actions_are_not_seeded_or_overwritten -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked auto_defaults_play_on_pixels_and_undo_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked subject_default_samples_visible_layers_and_undo_restores_selection -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked actions_persist_with_the_preset_store -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_preserves_subject_and_undoes_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_preserves_selection_alpha_masks_and_other_layers -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked background_sampling_excludes_subject_colors_for_both_blur_paths -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_without_subject_or_when_cancelled_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_rejects_invalid_targets_params_and_effective_locks -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_24mp_timing -- --nocapture --ignored",
|
|
"cargo test -p photocraft-engine --locked group_with_sampled_8_and_16_bit_tips_round_trips -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked commands_persist_and_delete_removes_from_disk -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked default_actions_load_from_empty_panel_and_play -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked default_actions_flyout_preserves_custom_actions_and_reveals_restored_set -- --nocapture"
|
|
],
|
|
"expected": "generated defaults are persisted without unsaved user work; denied storage marks default edits unsaved and retry saves them; finishing default transaction keeps newer action edits unsaved; failed default transaction does not warn until a user edit; load defaults preserves names and edits and is idempotent; defaults seed once and restore only when requested; old store and early actions win over defaults; unreadable actions are not seeded or overwritten; auto defaults play on pixels and undo at every depth; subject default samples visible layers and undo restores selection; actions persist with the preset store; blur background preserves subject and undoes at every depth; blur background preserves selection alpha masks and other layers; background sampling excludes subject colors for both blur paths; blur background without subject or when cancelled changes nothing; blur background rejects invalid targets params and effective locks; blur background 24mp timing; group with sampled 8 and 16 bit tips round trips; commands persist and delete removes from disk; default actions load from empty panel and play; default actions flyout preserves custom actions and reveals restored set",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-web --locked generated_defaults_are_persisted_without_unsaved_user_work -- --nocapture",
|
|
"cargo test -p photocraft-web --locked denied_storage_marks_default_edits_unsaved_and_retry_saves_them -- --nocapture",
|
|
"cargo test -p photocraft-web --locked finishing_default_transaction_keeps_newer_action_edits_unsaved -- --nocapture",
|
|
"cargo test -p photocraft-web --locked failed_default_transaction_does_not_warn_until_a_user_edit -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked load_defaults_preserves_names_and_edits_and_is_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked defaults_seed_once_and_restore_only_when_requested -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked old_store_and_early_actions_win_over_defaults -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked unreadable_actions_are_not_seeded_or_overwritten -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked auto_defaults_play_on_pixels_and_undo_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked subject_default_samples_visible_layers_and_undo_restores_selection -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked actions_persist_with_the_preset_store -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_preserves_subject_and_undoes_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_preserves_selection_alpha_masks_and_other_layers -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked background_sampling_excludes_subject_colors_for_both_blur_paths -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_without_subject_or_when_cancelled_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_rejects_invalid_targets_params_and_effective_locks -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked blur_background_24mp_timing -- --nocapture --ignored",
|
|
"cargo test -p photocraft-engine --locked group_with_sampled_8_and_16_bit_tips_round_trips -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked commands_persist_and_delete_removes_from_disk -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked default_actions_load_from_empty_panel_and_play -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked default_actions_flyout_preserves_custom_actions_and_reveals_restored_set -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "generated_defaults_are_persisted_without_unsaved_user_work",
|
|
"path": "apps/photocraft-web/src/preset_bridge.rs",
|
|
"package": "photocraft-web",
|
|
"command": "cargo test -p photocraft-web --locked generated_defaults_are_persisted_without_unsaved_user_work -- --nocapture",
|
|
"fixture_and_action_excerpt": " let b = Bridge::default();\n let (s, warnings) = session(b.clone());\n assert!(warnings.is_empty());\n assert_eq!(s.actions.list.len(), 5);\n assert!(!b.unsaved());\n let batch = b.begin().unwrap();\n let actions: serde_json::Value = serde_json::from_slice(batch.get(ACTIONS_FILE).unwrap().as_deref().unwrap()).unwrap();\n assert_eq!(actions[\"defaults_version\"], 1);\n assert_eq!(actions[\"actions\"].as_array().unwrap().len(), 5);\n assert!(!b.unsaved(), \"generated defaults in flight can be recreated on reload\");\n let restored = Bridge::default();\n for (name, bytes) in &batch {",
|
|
"expected_assertions": [
|
|
" assert!(warnings.is_empty());\n assert_eq!(s.actions.list.len(), 5);\n assert!(!b.unsaved());\n let batch = b.begin().unwrap();\n let actions: serde_json::Value = serde_json::from_slice(batch.get(ACTIONS_FILE).unwrap().as_deref().unwrap()).unwrap();\n assert_eq!(actions[\"defaults_version\"], 1);\n assert_eq!(actions[\"actions\"].as_array().unwrap().len(), 5);\n assert!(!b.unsaved(), \"generated defaults in flight can be recreated on reload\");\n let restored = Bridge::default();\n for (name, bytes) in &batch {\n if let Some(bytes) = bytes {\n assert!(warnings.is_empty());\n assert_eq!(reloaded.actions.list, s.actions.list);\n assert!(restored.begin().is_none(), \"the persisted marker avoids reseeding on reload\");\n assert!(!b.unsaved());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/apps/photocraft-web/src/preset_bridge.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "denied_storage_marks_default_edits_unsaved_and_retry_saves_them",
|
|
"path": "apps/photocraft-web/src/preset_bridge.rs",
|
|
"package": "photocraft-web",
|
|
"command": "cargo test -p photocraft-web --locked denied_storage_marks_default_edits_unsaved_and_retry_saves_them -- --nocapture",
|
|
"fixture_and_action_excerpt": " for command in [\"actions.delete\", \"actions.rename\"] {\n let b = Bridge::default();\n b.unavailable(\"SecurityError\".into());\n let (mut s, _) = session(b.clone());\n assert!(!b.unsaved());\n s.execute(command, json!({\"action\": \"Auto Tone\", \"name\": \"My Tone\"})).unwrap();\n assert!(b.unsaved(), \"editing generated defaults is user work: {command}\");\n assert!(b.begin().is_none());\n assert!(b.error().unwrap().contains(\"SecurityError\"));\n b.retry();\n let batch = b.begin().unwrap();\n assert!(b.unsaved(), \"the edit remains unsaved while its transaction runs\");",
|
|
"expected_assertions": [
|
|
" assert!(!b.unsaved());\n s.execute(command, json!({\"action\": \"Auto Tone\", \"name\": \"My Tone\"})).unwrap();\n assert!(b.unsaved(), \"editing generated defaults is user work: {command}\");\n assert!(b.begin().is_none());\n assert!(b.error().unwrap().contains(\"SecurityError\"));\n b.retry();\n let batch = b.begin().unwrap();\n assert!(b.unsaved(), \"the edit remains unsaved while its transaction runs\");\n let restored = Bridge::default();\n for (name, bytes) in &batch {\n if let Some(bytes) = bytes {\n assert!(!b.unsaved());\n assert!(b.error().is_none());\n let (reloaded, warnings) = session(restored);\n assert!(warnings.is_empty());\n assert_eq!(reloaded.actions.list, s.actions.list);\n assert!(!reloaded.actions.list.iter().any(|a| a.name == \"Auto Tone\"));\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/apps/photocraft-web/src/preset_bridge.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "finishing_default_transaction_keeps_newer_action_edits_unsaved",
|
|
"path": "apps/photocraft-web/src/preset_bridge.rs",
|
|
"package": "photocraft-web",
|
|
"command": "cargo test -p photocraft-web --locked finishing_default_transaction_keeps_newer_action_edits_unsaved -- --nocapture",
|
|
"fixture_and_action_excerpt": " for result in [Ok(()), Err(\"QuotaExceededError\".into())] {\n let b = Bridge::default();\n let (mut s, _) = session(b.clone());\n let defaults = b.begin().unwrap();\n s.execute(\"actions.delete\", json!({\"action\": \"Auto Tone\"})).unwrap();\n b.finish(defaults, result);\n assert!(b.unsaved(), \"the bootstrap transaction cannot save a later edit\");\n b.retry();\n let edited = b.begin().unwrap();\n let actions: serde_json::Value = serde_json::from_slice(edited.get(ACTIONS_FILE).unwrap().as_deref().unwrap()).unwrap();\n assert!(!actions[\"actions\"].as_array().unwrap().iter().any(|a| a[\"name\"] == \"Auto Tone\"));\n b.finish(edited, Ok(()));",
|
|
"expected_assertions": [
|
|
" assert!(b.unsaved(), \"the bootstrap transaction cannot save a later edit\");\n b.retry();\n let edited = b.begin().unwrap();\n let actions: serde_json::Value = serde_json::from_slice(edited.get(ACTIONS_FILE).unwrap().as_deref().unwrap()).unwrap();\n assert!(!actions[\"actions\"].as_array().unwrap().iter().any(|a| a[\"name\"] == \"Auto Tone\"));\n b.finish(edited, Ok(()));\n assert!(!b.unsaved());\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/apps/photocraft-web/src/preset_bridge.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "failed_default_transaction_does_not_warn_until_a_user_edit",
|
|
"path": "apps/photocraft-web/src/preset_bridge.rs",
|
|
"package": "photocraft-web",
|
|
"command": "cargo test -p photocraft-web --locked failed_default_transaction_does_not_warn_until_a_user_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " let b = Bridge::default();\n let (mut s, _) = session(b.clone());\n b.finish(b.begin().unwrap(), Err(\"QuotaExceededError\".into()));\n assert!(!b.unsaved(), \"the defaults are still reproducible after a failed write\");\n assert!(b.begin().is_none());\n import(&mut s);\n assert!(b.unsaved());\n assert!(b.error().unwrap().contains(\"QuotaExceededError\"));\n let (reloaded, warnings) = session(b.clone());\n assert!(warnings.is_empty());\n assert_eq!(reloaded.tools.presets, s.tools.presets);\n assert!(b.unsaved(), \"reattaching must not hide already pending user edits\");",
|
|
"expected_assertions": [
|
|
" assert!(!b.unsaved(), \"the defaults are still reproducible after a failed write\");\n assert!(b.begin().is_none());\n import(&mut s);\n assert!(b.unsaved());\n assert!(b.error().unwrap().contains(\"QuotaExceededError\"));\n let (reloaded, warnings) = session(b.clone());\n assert!(warnings.is_empty());\n assert_eq!(reloaded.tools.presets, s.tools.presets);\n assert!(b.unsaved(), \"reattaching must not hide already pending user edits\");\n b.retry();\n b.finish(b.begin().unwrap(), Ok(()));\n assert!(!b.unsaved());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/apps/photocraft-web/src/preset_bridge.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "load_defaults_preserves_names_and_edits_and_is_idempotent",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked load_defaults_preserves_names_and_edits_and_is_idempotent -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n assert!(s.actions.list.is_empty(), \"headless sessions remain hermetic\");\n let custom = Action::new(\"Auto Tone\", vec![(\"image.flipCanvasHorizontal\".into(), json!({}))]);\n s.actions.list.push(custom.clone());\n let loaded = s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n assert_eq!(loaded[\"added\"], json!([\"Auto Contrast\", \"Auto Color\", \"Select Subject\", \"Blur Background\"]));\n assert_eq!(s.actions.list[0], custom);\n assert!(s.actions.list.iter().skip(1).all(|a| a.set.as_deref() == Some(SET)));\n let rev = s.actions.rev;\n assert_eq!(s.execute(\"actions.loadDefaults\", json!({})).unwrap()[\"added\"], json!([]));\n assert_eq!(s.actions.rev, rev, \"unchanged defaults do not cause a store write\");\n assert!(s.journal.is_empty());",
|
|
"expected_assertions": [
|
|
" assert!(s.actions.list.is_empty(), \"headless sessions remain hermetic\");\n let custom = Action::new(\"Auto Tone\", vec![(\"image.flipCanvasHorizontal\".into(), json!({}))]);\n s.actions.list.push(custom.clone());\n let loaded = s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n assert_eq!(loaded[\"added\"], json!([\"Auto Contrast\", \"Auto Color\", \"Select Subject\", \"Blur Background\"]));\n assert_eq!(s.actions.list[0], custom);\n assert!(s.actions.list.iter().skip(1).all(|a| a.set.as_deref() == Some(SET)));\n let rev = s.actions.rev;\n assert_eq!(s.execute(\"actions.loadDefaults\", json!({})).unwrap()[\"added\"], json!([]));\n assert_eq!(s.actions.rev, rev, \"unchanged defaults do not cause a store write\");\n assert!(s.journal.is_empty());\n assert!(s.active().is_none());\n\n for bad in [Value::Null, json!([]), json!(\"defaults\"), json!(true), json!(1)] {\n assert!(s.execute(\"actions.loadDefaults\", bad).is_err());\n }\n s.execute(\"actions.record\", json!({\"name\": \"Recording\"})).unwrap();\n assert!(!s.is_enabled(\"actions.loadDefaults\"));\n assert!(s.execute(\"actions.loadDefaults\", json!({})).is_err());\n s.execute(\"actions.stop\", json!({})).unwrap();\n s.actions.playing = 1;\n assert!(load(&mut s, &json!({})).is_err());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "defaults_seed_once_and_restore_only_when_requested",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked defaults_seed_once_and_restore_only_when_requested -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mem = MemBackend::default();\n let mut s = attached(&mem);\n assert_eq!(s.actions.list, defaults());\n assert_eq!(saved(&mem).defaults_version, VERSION);\n s.execute(\"actions.delete\", json!({\"action\": \"Auto Tone\"})).unwrap();\n s.execute(\"actions.rename\", json!({\"action\": \"Auto Color\", \"name\": \"My Color\"})).unwrap();\n let customized = s.actions.list.clone();\n let mut restarted = attached(&mem);\n assert_eq!(restarted.actions.list, customized, \"deleted and renamed defaults stay customized on restart\");\n assert_eq!(restarted.execute(\"actions.loadDefaults\", json!({})).unwrap()[\"added\"], json!([\"Auto Tone\", \"Auto Color\"]));\n assert_eq!(attached(&mem).actions.list, restarted.actions.list);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.actions.list, defaults());\n assert_eq!(saved(&mem).defaults_version, VERSION);\n s.execute(\"actions.delete\", json!({\"action\": \"Auto Tone\"})).unwrap();\n s.execute(\"actions.rename\", json!({\"action\": \"Auto Color\", \"name\": \"My Color\"})).unwrap();\n let customized = s.actions.list.clone();\n assert_eq!(restarted.actions.list, customized, \"deleted and renamed defaults stay customized on restart\");\n assert_eq!(restarted.execute(\"actions.loadDefaults\", json!({})).unwrap()[\"added\"], json!([\"Auto Tone\", \"Auto Color\"]));\n assert_eq!(attached(&mem).actions.list, restarted.actions.list);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "old_store_and_early_actions_win_over_defaults",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked old_store_and_early_actions_win_over_defaults -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mem = MemBackend::default();\n let custom = Action::new(\"Auto Tone\", vec![(\"select.all\".into(), json!({}))]);\n let disk = Action::new(\"My Workflow\", vec![]);\n // Old files have no defaults_version field.\n mem.write(ACTIONS_FILE, &serde_json::to_vec(&json!({\"version\": 1, \"actions\": [custom, disk]})).unwrap()).unwrap();\n let mut s = Session::new();\n let early = Action::new(\"Auto Color\", vec![(\"select.deselect\".into(), json!({}))]);\n s.actions.list.push(early.clone());\n s.attach_preset_store(open(Box::new(mem.clone())));\n assert_eq!(&s.actions.list[..3], &[early, custom, disk]);\n assert_eq!(\n s.actions.list.iter().map(|a| a.name.as_str()).collect::<Vec<_>>(),",
|
|
"expected_assertions": [
|
|
" assert_eq!(&s.actions.list[..3], &[early, custom, disk]);\n assert_eq!(\n s.actions.list.iter().map(|a| a.name.as_str()).collect::<Vec<_>>(),\n [\"Auto Color\", \"Auto Tone\", \"My Workflow\", \"Auto Contrast\", \"Select Subject\", \"Blur Background\"]\n );\n assert_eq!(saved(&mem).defaults_version, VERSION);\n assert_eq!(attached(&mem).actions.list, s.actions.list);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "unreadable_actions_are_not_seeded_or_overwritten",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked unreadable_actions_are_not_seeded_or_overwritten -- --nocapture",
|
|
"fixture_and_action_excerpt": " for bytes in [b\"{\".as_slice(), br#\"{\"version\":999,\"actions\":[]}\"#.as_slice()] {\n let mem = MemBackend::default();\n mem.write(ACTIONS_FILE, bytes).unwrap();\n let mut s = Session::new();\n assert!(!s.attach_preset_store(open(Box::new(mem.clone()))).is_empty());\n assert!(s.actions.list.is_empty());\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n assert_eq!(s.actions.list, defaults(), \"explicit recovery is available in memory\");\n assert_eq!(mem.read(ACTIONS_FILE, 1 << 20).unwrap(), bytes, \"the unreadable original remains recoverable\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(!s.attach_preset_store(open(Box::new(mem.clone()))).is_empty());\n assert!(s.actions.list.is_empty());\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n assert_eq!(s.actions.list, defaults(), \"explicit recovery is available in memory\");\n assert_eq!(mem.read(ACTIONS_FILE, 1 << 20).unwrap(), bytes, \"the unreadable original remains recoverable\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "auto_defaults_play_on_pixels_and_undo_at_every_depth",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked auto_defaults_play_on_pixels_and_undo_at_every_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut s = Session::new();\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n s.execute(\"file.new\", json!({\"width\": 64, \"height\": 64, \"depth\": depth})).unwrap();\n s.edit(\"ramp\", |doc, _| {\n let surf = doc.layers[0].surface_mut().unwrap();\n for x in 0..64 {\n let v = 0.3 + 0.4 * x as f32 / 63.0;\n surf.fill_rect(Rect::new(x, 0, x + 1, 64), &[v, v * 0.9, v * 0.8, 1.0]);\n }\n Ok(())\n })",
|
|
"expected_assertions": [
|
|
" assert_eq!(played[\"ran\"], 1, \"{name} at {depth}: {played}\");\n assert!(played.get(\"failed\").is_none());\n let (a, b) = (pixel(&s, 0), pixel(&s, 63));\n let (lo, hi) = if name == \"Auto Contrast\" { (a[2], b[0]) } else { (a[0], b[0]) };\n assert!(lo < 0.05 && hi > 0.95, \"{name} at {depth}: {a:?} {b:?}\");\n assert_eq!(s.active().unwrap().history.past_len(), history + 1);\n assert!(s.undo());\n assert_eq!((pixel(&s, 0), pixel(&s, 63)), before);\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "subject_default_samples_visible_layers_and_undo_restores_selection",
|
|
"path": "crates/engine/src/action_defaults.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked subject_default_samples_visible_layers_and_undo_restores_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut s = Session::new();\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n s.execute(\"file.new\", json!({\"width\": 200, \"height\": 160, \"depth\": depth})).unwrap();\n s.edit(\"disc\", |doc, _| {\n let surf = doc.layers[0].surface_mut().unwrap();\n surf.fill_rect(Rect::new(0, 0, 200, 160), &[0.25, 0.45, 0.7, 1.0]);\n for y in 0..160 {\n for x in 0..200 {\n if (x - 100) * (x - 100) + (y - 80) * (y - 80) <= 45 * 45 {\n surf.fill_rect(Rect::new(x, y, x + 1, y + 1), &[0.9, 0.3, 0.15, 1.0]);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(played[\"ran\"], 1, \"{depth}: {played}\");\n assert!(played.get(\"failed\").is_none());\n let coverage = |s: &Session, x, y| s.active().unwrap().doc.selection.as_ref().unwrap().sample_channel(x, y, 0);\n assert!(coverage(&s, 100, 80) > 0.9, \"the subject on the underlying layer is selected\");\n assert!(coverage(&s, 0, 0) < 0.1, \"replace mode removes the old background selection\");\n assert!(s.undo());\n assert!(coverage(&s, 0, 0) > 0.9);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/action_defaults.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "actions_persist_with_the_preset_store",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked actions_persist_with_the_preset_store -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = std::env::temp_dir().join(format!(\"pc-actions-{}-persist\", std::process::id()));\n let _ = std::fs::remove_dir_all(&dir);\n let mut s = Session::new();\n let warnings = s.attach_preset_store(crate::preset_store::open_dir(&dir));\n assert!(warnings.iter().all(|w| !w.contains(\"actions\")), \"{warnings:?}\");\n s.execute(\"file.new\", json!({\"width\": 4, \"height\": 4})).unwrap();\n s.execute(\"actions.record\", json!({\"name\": \"Kept\"})).unwrap();\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"actions.stop\", json!({})).unwrap();\n drop(s);\n\n let mut t = Session::new();",
|
|
"expected_assertions": [
|
|
" assert!(warnings.iter().all(|w| !w.contains(\"actions\")), \"{warnings:?}\");\n s.execute(\"file.new\", json!({\"width\": 4, \"height\": 4})).unwrap();\n s.execute(\"actions.record\", json!({\"name\": \"Kept\"})).unwrap();\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n assert_eq!(kept[\"steps\"], 1);\n assert_eq!(t.execute(\"actions.get\", json!({\"action\": \"Kept\"})).unwrap()[\"steps\"][0][0], \"layer.new.layer\");\n\n // An action created before the store finishes loading is kept, and a different one on\n // disk is merged in.\n assert!(names.contains(&\"Early\".into()) && names.contains(&\"Kept\".into()), \"{names:?}\");\n\n std::fs::write(dir.join(\"actions.json\"), b\"{\").unwrap();\n let mut bad = Session::new();\n assert!(warnings.iter().any(|w| w.contains(\"actions\")), \"{warnings:?}\");\n assert!(bad.actions.list.is_empty());\n let _ = std::fs::remove_dir_all(&dir);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blur_background_preserves_subject_and_undoes_at_every_depth",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_background_preserves_subject_and_undoes_at_every_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut s = disc(200, 160, depth);\n let layer = id(&s);\n let before = s.active().unwrap().doc.clone();\n let history = s.active().unwrap().history.past_len();\n assert!(s.is_enabled(CMD));\n // Exercise the shipping action, including its command params and single-step undo.\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n let result = s.execute(\"actions.play\", json!({\"action\": \"Blur Background\"})).unwrap();\n assert_eq!(result[\"ran\"], 1, \"{depth}: {result}\");\n assert!(result.get(\"failed\").is_none(), \"{depth}: {result}\");\n assert_eq!(s.active().unwrap().history.past_len(), history + 1);",
|
|
"expected_assertions": [
|
|
" assert!(s.is_enabled(CMD));\n // Exercise the shipping action, including its command params and single-step undo.\n s.execute(\"actions.loadDefaults\", json!({})).unwrap();\n let result = s.execute(\"actions.play\", json!({\"action\": \"Blur Background\"})).unwrap();\n assert_eq!(result[\"ran\"], 1, \"{depth}: {result}\");\n assert!(result.get(\"failed\").is_none(), \"{depth}: {result}\");\n assert_eq!(s.active().unwrap().history.past_len(), history + 1);\n let old = before.layer(layer).unwrap().surface().unwrap();\n let new = surface(&s, layer);\n assert_eq!(\n new.read_region(Rect::new(85, 65, 115, 95)),\n old.read_region(Rect::new(85, 65, 115, 95)),\n \"the subject interior remains sharp at {depth}\"\n assert!(background_energy(new) < background_energy(old) * 0.1, \"background noise is reduced at {depth}\");\n let after = s.active().unwrap().doc.clone();\n assert!(s.undo());\n assert_eq!(s.active().unwrap().doc, before);\n assert!(s.redo());\n assert_eq!(s.active().unwrap().doc, after);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blur_background_preserves_selection_alpha_masks_and_other_layers",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_background_preserves_selection_alpha_masks_and_other_layers -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = disc(200, 160, 16);\n let layer = id(&s);\n s.execute(\"layer.new.layer\", json!({\"name\": \"Unchanged overlay\"})).unwrap();\n s.edit(\"existing state\", |doc, _| {\n let layer = doc.layer_mut(layer).unwrap();\n let surf = layer.surface_mut().unwrap();\n for y in 0..160 {\n for x in 0..200 {\n let mut pixel = surf.pixel(x, y);\n *pixel.last_mut().unwrap() = if x < 50 { 0.5 } else { 1.0 };\n surf.write_pixel(x, y, &pixel);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(*s.active().unwrap().doc, expected, \"only target layer pixels may change\");\n let (old, new) = (before.layer(layer).unwrap().surface().unwrap(), surface(&s, layer));\n assert_ne!(new.read_region(Rect::new(10, 10, 40, 40)), old.read_region(Rect::new(10, 10, 40, 40)));\n assert_eq!(new.read_region(Rect::new(60, 0, 200, 160)), old.read_region(Rect::new(60, 0, 200, 160)), \"outside the user's selection\");\n assert_eq!(new.read_region(Rect::new(-8, -8, 0, 0)), old.read_region(Rect::new(-8, -8, 0, 0)));\n for y in 0..160 {\n for x in 0..200 {\n assert_eq!(new.sample_channel(x, y, 3), old.sample_channel(x, y, 3));\n }\n }\n assert_eq!(s.active().unwrap().channel_view.target, crate::channel_cmds::ChannelTarget::LayerMask);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "background_sampling_excludes_subject_colors_for_both_blur_paths",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked background_sampling_excludes_subject_colors_for_both_blur_paths -- --nocapture",
|
|
"fixture_and_action_excerpt": " let bounds = Rect::new(0, 0, 80, 60);\n let subject = Region { bbox: Rect::new(30, 10, 50, 50), mask: vec![255; 20 * 40] };\n use photocraft_color::ColorMode;\n for mode in [ColorMode::Rgb, ColorMode::Grayscale, ColorMode::Cmyk, ColorMode::Lab] {\n for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {\n let mut source = Surface::new(PixelFormat::new(mode, depth, true));\n let colors = mode.color_channels();\n let mut background = vec![0.2; colors];\n let mut foreground = vec![0.9; colors];\n if mode == ColorMode::Rgb {\n background = vec![0.0, 0.3, 0.85];\n foreground = vec![1.0, 0.0, 0.0];",
|
|
"expected_assertions": [
|
|
" assert_eq!(output.format(), source.format());\n let edge = output.pixel(29, 30);\n for (c, value) in edge.iter().take(colors).enumerate() {\n assert!(\n (value - source.sample_channel(29, 30, c)).abs() < 0.005,\n \"foreground leaked into {mode:?} channel {c}, {depth:?}, radius {radius}: {edge:?}\"\n );\n assert!(edge[0] < 1e-6, \"subject red leaked through at {depth:?}, radius {radius}: {edge:?}\");\n }\n assert_eq!(output.read_region(subject.bbox), source.read_region(subject.bbox));\n assert_eq!(edge[colors], source.sample_channel(29, 30, colors));\n }\n }\n }\n assert_eq!(output, tiny_alpha, \"no usable background contribution must not turn into black\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blur_background_without_subject_or_when_cancelled_changes_nothing",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_background_without_subject_or_when_cancelled_changes_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 32, \"height\": 32, \"background\": \"white\"})).unwrap();\n s.execute(\"select.rect\", json!({\"x\": 4, \"y\": 4, \"width\": 16, \"height\": 16})).unwrap();\n let before = s.active().unwrap().doc.clone();\n let steps = s.active().unwrap().history.past_len();\n assert!(s.execute(CMD, json!({})).is_err());\n assert!(Arc::ptr_eq(&before, &s.active().unwrap().doc));\n assert_eq!(steps, s.active().unwrap().history.past_len());\n\n let mut s = disc(200, 160, 8);\n let before = s.active().unwrap().doc.clone();\n let steps = s.active().unwrap().history.past_len();",
|
|
"expected_assertions": [
|
|
" assert!(s.execute(CMD, json!({})).is_err());\n assert!(Arc::ptr_eq(&before, &s.active().unwrap().doc));\n assert_eq!(steps, s.active().unwrap().history.past_len());\n\n let mut s = disc(200, 160, 8);\n let before = s.active().unwrap().doc.clone();\n assert!(matches!(s.execute(CMD, json!({})), Err(EngineError::Cancelled)));\n assert!(Arc::ptr_eq(&before, &s.active().unwrap().doc));\n assert_eq!(steps, s.active().unwrap().history.past_len());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blur_background_rejects_invalid_targets_params_and_effective_locks",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_background_rejects_invalid_targets_params_and_effective_locks -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut empty = Session::new();\n assert!(!empty.is_enabled(CMD));\n assert!(empty.execute(CMD, json!({})).is_err());\n let mut s = disc(200, 160, 8);\n let before = s.active().unwrap().doc.clone();\n for params in [\n Value::Null,\n json!([]),\n json!(false),\n json!({\"radius\": \"8\"}),\n json!({\"radius\": null}),\n json!({\"radius\": 0}),",
|
|
"expected_assertions": [
|
|
" assert!(!empty.is_enabled(CMD));\n assert!(empty.execute(CMD, json!({})).is_err());\n let mut s = disc(200, 160, 8);\n let before = s.active().unwrap().doc.clone();\n for params in [\n assert!(s.execute(CMD, params.clone()).is_err(), \"{params}\");\n assert!(Arc::ptr_eq(&before, &s.active().unwrap().doc));\n }\n s.execute(\"layer.setProps\", json!({\"locks\": {\"pixels\": true}})).unwrap();\n assert!(!s.is_enabled(CMD));\n assert!(s.execute(CMD, json!({})).is_err());\n s.execute(\"layer.setProps\", json!({\"locks\": {\"pixels\": false}})).unwrap();\n s.execute(\"layer.groupLayers\", json!({})).unwrap();\n // The group is not a raster target; a locked parent also protects the member's pixels.\n assert!(!s.is_enabled(CMD));\n assert!(s.execute(CMD, json!({})).is_err());\n let group = id(&s);\n s.execute(\"layer.setProps\", json!({\"locks\": {\"all\": true}})).unwrap();\n let child = s.active().unwrap().doc.layer(group).unwrap().children().unwrap().first().unwrap().id;\n assert!(s.execute(CMD, json!({\"layer\": child.0})).is_err());\n assert!(Arc::ptr_eq(&before, &s.active().unwrap().doc));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blur_background_24mp_timing",
|
|
"path": "crates/engine/src/background_blur_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_background_24mp_timing -- --nocapture --ignored",
|
|
"fixture_and_action_excerpt": " let mut s = disc(6000, 4000, 8);\n let started = std::time::Instant::now();\n let result = s.execute(CMD, json!({})).unwrap();\n println!(\"Blur Background 24 MP: {:?}; {result}\", started.elapsed());\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/background_blur_cmds.rs",
|
|
"ignored_requires_explicit_execution": true,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "group_with_sampled_8_and_16_bit_tips_round_trips",
|
|
"path": "crates/engine/src/preset_store/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked group_with_sampled_8_and_16_bit_tips_round_trips -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = TempDir::new(\"roundtrip\");\n let (mut s, w) = session(&dir);\n assert!(w.is_empty(), \"{w:?}\");\n assert_eq!(dir.files(), [ACTIONS_FILE], \"only starter actions are written when attaching an empty store\");\n let mut a = sampled(\"Eight\", \"Inks\", tip8(64, 48, 1));\n a.brush.dual_brush.tip = TipShape::Sampled(tip8(12, 12, 5));\n a.brush.texture.pattern = Pattern::Tile(tip16(32, 32, 7));\n let b = sampled(\"Sixteen\", \"Inks\", tip16(50, 70, 2));\n let mut c = sampled(\"Shared tip\", \"Other\", tip8(64, 48, 1));\n c.brush.size = 9.0;\n s.tools.presets.extend([a, b, c]);\n s.brush_presets_changed();",
|
|
"expected_assertions": [
|
|
" assert!(w.is_empty(), \"{w:?}\");\n assert_eq!(dir.files(), [ACTIONS_FILE], \"only starter actions are written when attaching an empty store\");\n let mut a = sampled(\"Eight\", \"Inks\", tip8(64, 48, 1));\n a.brush.dual_brush.tip = TipShape::Sampled(tip8(12, 12, 5));\n a.brush.texture.pattern = Pattern::Tile(tip16(32, 32, 7));\n assert_eq!(files.iter().filter(|f| f.ends_with(\".pcbrushes\")).count(), 2, \"{files:?}\");\n // Four distinct bitmaps (the 64\u00d748 tip is shared by two presets) plus the previews of the two\n // 16-bit ones: an 8-bit tip this small is its own preview.\n assert_eq!(files.iter().filter(|f| f.starts_with(\"tips/\")).count(), 6, \"{files:?}\");\n // The session keeps previews, not the bitmaps (#1843).\n assert!(user(&s).iter().all(|p| matches!(&p.brush.tip, TipShape::Stored(r) if !r.is_loaded())));\n assert!(files.contains(&INDEX_FILE.to_string()));\n\n let (t, w) = session(&dir);\n assert!(w.is_empty(), \"{w:?}\");\n assert_eq!(user(&t), user(&s));\n let order: Vec<String> = user(&t).into_iter().map(|p| p.name).collect();\n assert_eq!(order, [\"Eight\", \"Sixteen\", \"Shared tip\"]);\n // Nothing changed: reloading rewrote nothing.\n let before: Vec<_> = DirBackend::new(&dir.0).list().unwrap();\n let mut t = t;\n assert_eq!(DirBackend::new(&dir.0).list().unwrap(), before);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/preset_store/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "commands_persist_and_delete_removes_from_disk",
|
|
"path": "crates/engine/src/preset_store/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked commands_persist_and_delete_removes_from_disk -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = TempDir::new(\"commands\");\n let (mut s, _) = session(&dir);\n s.tools.brush.tip = TipShape::Sampled(tip16(20, 20, 4));\n s.execute(\"brush.presets.save\", json!({\"name\": \"Scribble\"})).unwrap();\n assert_eq!(dir.files().iter().filter(|f| f.starts_with(\"tips/\")).count(), 2, \"the tip and its preview\");\n // The tool's brush now is the saved preset's stored tip, still loaded.\n assert!(matches!(&s.tools.brush.tip, TipShape::Stored(r) if r.is_loaded()));\n let (t, _) = session(&dir);\n let p = photocraft_paint::presets::find(&t.tools.presets, \"Scribble\").expect(\"saved preset reloads\");\n assert_eq!(p.brush.tip, s.tools.brush.tip);\n\n // Rename through the Preset Manager, then delete.",
|
|
"expected_assertions": [
|
|
" assert_eq!(dir.files().iter().filter(|f| f.starts_with(\"tips/\")).count(), 2, \"the tip and its preview\");\n // The tool's brush now is the saved preset's stored tip, still loaded.\n assert!(matches!(&s.tools.brush.tip, TipShape::Stored(r) if r.is_loaded()));\n let (t, _) = session(&dir);\n let p = photocraft_paint::presets::find(&t.tools.presets, \"Scribble\").expect(\"saved preset reloads\");\n assert_eq!(p.brush.tip, s.tools.brush.tip);\n\n // Rename through the Preset Manager, then delete.\n s.execute(\"edit.presets.presetManager\", json!({\"action\": \"rename\", \"kind\": \"brushes\", \"name\": \"Scribble\", \"newName\": \"Doodle\"})).unwrap();\n assert!(photocraft_paint::presets::find(&t.tools.presets, \"Doodle\").is_some());\n assert!(photocraft_paint::presets::find(&t.tools.presets, \"Scribble\").is_none());\n s.execute(\"brush.presets.delete\", json!({\"name\": \"Doodle\"})).unwrap();\n assert_eq!(dir.files(), [ACTIONS_FILE, INDEX_FILE], \"the group file and its tip are gone\");\n let (t, _) = session(&dir);\n assert!(photocraft_paint::presets::find(&t.tools.presets, \"Doodle\").is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/engine/src/preset_store/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "default_actions_load_from_empty_panel_and_play",
|
|
"path": "crates/ui-egui/src/actions.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked default_actions_load_from_empty_panel_and_play -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let mut h = Harness::builder().with_size(vec2(360.0, 400.0)).build_ui_state(|ui, app| panel(app, ui), app);\n h.run_steps(3);\n h.get_by_label(\"Load Default Actions\").click();\n h.run_steps(3);\n assert!(h.query_by_label(\"PhotoCraft Essentials\").is_some());\n for name in [\"Auto Tone\", \"Auto Contrast\", \"Auto Color\", \"Select Subject\", \"Blur Background\"] {\n assert!(h.query_by_label(name).is_some(), \"missing preset {name}\");\n }\n assert_eq!(h.state().ui.actions.selected, Some(0));\n h.state_mut().run(\"file.new\", json!({\"width\": 16, \"height\": 16})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(\"PhotoCraft Essentials\").is_some());\n for name in [\"Auto Tone\", \"Auto Contrast\", \"Auto Color\", \"Select Subject\", \"Blur Background\"] {\n assert!(h.query_by_label(name).is_some(), \"missing preset {name}\");\n }\n assert_eq!(h.state().ui.actions.selected, Some(0));\n h.state_mut().run(\"file.new\", json!({\"width\": 16, \"height\": 16})).unwrap();\n h.run_steps(3);\n h.get_by_label(\"Play selection\").click();\n assert!(!h.state().ui.status_error, \"{}\", h.state().ui.status);\n assert!(h.state().session.journal.iter().any(|(id, _)| id == \"image.autoTone\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/ui-egui/src/actions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "default_actions_flyout_preserves_custom_actions_and_reveals_restored_set",
|
|
"path": "crates/ui-egui/src/actions.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked default_actions_flyout_preserves_custom_actions_and_reveals_restored_set -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let custom = Action::new(\"Auto Tone\", vec![(\"view.fitOnScreen\".into(), json!({}))]);\n app.session.actions.list.push(custom.clone());\n app.ui.actions.collapsed_sets.push(\"PhotoCraft Essentials\".into());\n let mut h = Harness::builder().with_size(vec2(360.0, 400.0)).build_ui_state(\n |ui, app| {\n ui.menu_button(\"Actions menu\", |ui| panel_menu(app, ui));\n panel(app, ui);\n },\n app,\n );",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.actions.list[0], custom);\n assert_eq!(h.state().session.actions.list.len(), 5);\n assert_eq!(h.state().ui.actions.selected, Some(1));\n assert!(h.state().ui.actions.collapsed_sets.is_empty());\n assert!(h.query_by_label(\"Select Subject\").is_some());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61d9e8cc1aed29ed6bea0d0fd2702fa87c4f0206/crates/ui-egui/src/actions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5176",
|
|
"pr": 5176,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Synthetic ATN mappings, smart-object Edit Contents action, temporary pattern stores and matting hard/soft edges",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked every_mapped_command_exports_and_imports_back -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked save_in_edit_contents_updates_the_smart_object -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterns_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked corrupt_pattern_files_are_skipped_and_kept -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked large_patterns_load_on_use -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked matting::tests -- --nocapture"
|
|
],
|
|
"expected": "Mappings round-trip parameters; Save in Edit Contents updates parent smart content. Pattern names/pixels and rename/delete survive restart; corrupt assets are warned about and preserved; large patterns load full pixels lazily. Hard edge \u00b1100% shifts one pixel, \u00b150% gives half coverage within 0.02; feather 4/+100% reaches four pixels.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Named CopyCat/AJ/Line and Color playback needs licensed fixture identities and required document/pattern setup; missing action sets leave that subcase BLOCKED. Mapping tests alone do not prove full set playback. Also run all new legacy/new-store migration, interruption, corruption, duplicate-ID and deletion-authority regressions.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked every_mapped_command_exports_and_imports_back -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked save_in_edit_contents_updates_the_smart_object -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterns_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked corrupt_pattern_files_are_skipped_and_kept -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked large_patterns_load_on_use -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked matting::tests -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-6492",
|
|
"pr": 6492,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Process-isolated occupied loopback listener and successful prebound control-server fixtures in apps/photocraft tests",
|
|
"action": [
|
|
"cargo test -p photocraft --locked an_occupied_control_port_exits_with_status_2 -- --nocapture",
|
|
"cargo test -p photocraft --locked a_prebound_listener_authenticates_and_dispatches_requests -- --nocapture"
|
|
],
|
|
"expected": "Occupied port exits with status 2 before window/GPU initialization; successful prebound control authenticates and dispatches requests. Preserve timing, cleanup and child-exit assertions.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Use only the test-owned listener and process.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft --locked an_occupied_control_port_exits_with_status_2 -- --nocapture",
|
|
"cargo test -p photocraft --locked a_prebound_listener_authenticates_and_dispatches_requests -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-7742",
|
|
"pr": 7742,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked a_fractional_setting_an_integer_field_cannot_hold_is_refused_not_rounded -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked whole_number_settings_for_integer_fields_still_round_trip -- --nocapture"
|
|
],
|
|
"expected": "a fractional setting an integer field cannot hold is refused not rounded; whole number settings for integer fields still round trip",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked a_fractional_setting_an_integer_field_cannot_hold_is_refused_not_rounded -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked whole_number_settings_for_integer_fields_still_round_trip -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "a_fractional_setting_an_integer_field_cannot_hold_is_refused_not_rounded",
|
|
"path": "crates/engine/src/atn_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked a_fractional_setting_an_integer_field_cannot_hold_is_refused_not_rounded -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (id, params) in [(\"filter.pixelate.crystallize\", json!({\"cellSize\": 5.4})), (\"filter.distort.ripple\", json!({\"amount\": 81.4, \"size\": \"small\"}))] {\n let mut s = Session::new();\n s.actions.list.push(Action::new(\"A\", vec![(id.into(), params)]));\n let e = s.execute(\"actions.save\", json!({\"action\": \"A\"})).unwrap_err().to_string();\n assert!(e.contains(id), \"{id}: {e}\");\n let r = s.execute(\"actions.save\", json!({\"action\": \"A\", \"skipUnsupported\": true})).unwrap();\n assert_eq!(r[\"skipped\"], json!([{\"action\": \"A\", \"step\": 0, \"id\": id}]), \"{id}\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(id), \"{id}: {e}\");\n let r = s.execute(\"actions.save\", json!({\"action\": \"A\", \"skipUnsupported\": true})).unwrap();\n assert_eq!(r[\"skipped\"], json!([{\"action\": \"A\", \"step\": 0, \"id\": id}]), \"{id}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ab844f9cbcd1f1839ed7f286776331cb72e399aa/crates/engine/src/atn_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "whole_number_settings_for_integer_fields_still_round_trip",
|
|
"path": "crates/engine/src/atn_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked whole_number_settings_for_integer_fields_still_round_trip -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (id, params) in [\n (\"filter.pixelate.crystallize\", json!({\"cellSize\": 5})),\n (\"filter.distort.ripple\", json!({\"amount\": 81, \"size\": \"small\"})),\n (\"edit.stroke\", json!({\"width\": 2, \"color\": \"#d03060\", \"location\": \"inside\"})),\n ] {\n let mut s = Session::new();\n s.actions.list.push(Action::new(\"A\", vec![(id.into(), params.clone())]));\n let r = s.execute(\"actions.save\", json!({\"action\": \"A\"})).unwrap();\n assert_eq!(r[\"skipped\"], json!([]), \"{id}\");\n let imported = import(&photocraft_paint::tile::b64_decode(r[\"data\"].as_str().unwrap()).unwrap()).unwrap();\n let (back_id, back) = &imported.actions[0].steps[0];\n assert_eq!(back_id, id);",
|
|
"expected_assertions": [
|
|
" assert_eq!(r[\"skipped\"], json!([]), \"{id}\");\n let imported = import(&photocraft_paint::tile::b64_decode(r[\"data\"].as_str().unwrap()).unwrap()).unwrap();\n let (back_id, back) = &imported.actions[0].steps[0];\n assert_eq!(back_id, id);\n for (key, want) in params.as_object().unwrap() {\n let got = back.get(key);\n match want.as_f64() {\n Some(n) => assert_eq!(got.and_then(Value::as_f64), Some(n), \"{id}: {key} is {got:?}\"),\n None => assert_eq!(got, Some(want), \"{id}: {key} is {got:?}\"),\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ab844f9cbcd1f1839ed7f286776331cb72e399aa/crates/engine/src/atn_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8905",
|
|
"pr": 8905,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-plugins --locked parallel_bands_fit_the_total_memory_budget -- --nocapture",
|
|
"cargo test -p photocraft-plugins --locked one_band_at_a_time_matches_parallel_bands -- --nocapture"
|
|
],
|
|
"expected": "parallel bands fit the total memory budget; one band at a time matches parallel bands",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-plugins --locked parallel_bands_fit_the_total_memory_budget -- --nocapture",
|
|
"cargo test -p photocraft-plugins --locked one_band_at_a_time_matches_parallel_bands -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "parallel_bands_fit_the_total_memory_budget",
|
|
"path": "crates/plugins/tests/abi.rs",
|
|
"package": "photocraft-plugins",
|
|
"command": "cargo test -p photocraft-plugins --locked parallel_bands_fit_the_total_memory_budget -- --nocapture",
|
|
"fixture_and_action_excerpt": " let d = Limits::default();\n assert_eq!(d.parallel_bands(16), 4);\n assert!(d.parallel_bands(64) * d.max_memory_bytes <= d.max_total_memory_bytes);\n assert_eq!(d.parallel_bands(2), 2, \"fewer workers than the budget allows\");\n let small = Limits { max_memory_bytes: 64 << 20, ..Limits::default() };\n assert_eq!(small.parallel_bands(16), 16, \"small instances keep every worker busy\");\n let tight = Limits { max_total_memory_bytes: 1 << 20, ..Limits::default() };\n assert_eq!(tight.parallel_bands(16), 1, \"at least one band runs\");\n assert_eq!(d.parallel_bands(0), 1);\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(d.parallel_bands(16), 4);\n assert!(d.parallel_bands(64) * d.max_memory_bytes <= d.max_total_memory_bytes);\n assert_eq!(d.parallel_bands(2), 2, \"fewer workers than the budget allows\");\n let small = Limits { max_memory_bytes: 64 << 20, ..Limits::default() };\n assert_eq!(small.parallel_bands(16), 16, \"small instances keep every worker busy\");\n let tight = Limits { max_total_memory_bytes: 1 << 20, ..Limits::default() };\n assert_eq!(tight.parallel_bands(16), 1, \"at least one band runs\");\n assert_eq!(d.parallel_bands(0), 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/0fdc6259193aab32b8feab7347ddc36196f40a19/crates/plugins/tests/abi.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "one_band_at_a_time_matches_parallel_bands",
|
|
"path": "crates/plugins/tests/abi.rs",
|
|
"package": "photocraft-plugins",
|
|
"command": "cargo test -p photocraft-plugins --locked one_band_at_a_time_matches_parallel_bands -- --nocapture",
|
|
"fixture_and_action_excerpt": " let pool = rayon::ThreadPoolBuilder::new().num_threads(8).build().unwrap();\n let s = surface(PixelFormat::RGBA8, 600, 300);\n let canvas = Rect::new(0, 0, 600, 300);\n let run = |limits: Limits| {\n let p = Plugin::load(INVERT, limits).unwrap();\n pool.install(|| p.apply(&s, canvas, None, &json!({}))).unwrap()\n };\n let parallel = run(Limits { band_bytes: 1, ..Limits::default() });\n let serial = run(Limits { band_bytes: 1, max_total_memory_bytes: 512 << 20, ..Limits::default() });\n assert_eq!(serial, parallel);\n assert_ne!(serial, s, \"the filter ran\");\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(serial, parallel);\n assert_ne!(serial, s, \"the filter ran\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/0fdc6259193aab32b8feab7347ddc36196f40a19/crates/plugins/tests/abi.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3874",
|
|
"pr": 3874,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked blend_if_alt_split_and_drag_behavior -- --nocapture"
|
|
],
|
|
"expected": "blend if alt split and drag behavior",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked blend_if_alt_split_and_drag_behavior -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "blend_if_alt_split_and_drag_behavior",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked blend_if_alt_split_and_drag_behavior -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Case 1: Alt-drag on unsplit black handle [0, 0, 255, 255] splits the right half\n let mut mode = BlendDrag::Pair { pair: 0, origin_v: 0 };\n let q = [0, 0, 255, 255];\n let q1 = step_blend_drag(&mut mode, &q, 45, true);\n assert_eq!(q1, [0, 45, 255, 255], \"Alt-drag right must split black triangle into [0, 45]\");\n\n // Case 2: Moving the split right half further to 70\n let q2 = step_blend_drag(&mut mode, &q1, 70, false);\n assert_eq!(q2, [0, 70, 255, 255]);\n\n // Case 3: Dragging the split half back to 0 merges the handle\n let q3 = step_blend_drag(&mut mode, &q2, 0, false);",
|
|
"expected_assertions": [
|
|
" assert_eq!(q1, [0, 45, 255, 255], \"Alt-drag right must split black triangle into [0, 45]\");\n\n // Case 2: Moving the split right half further to 70\n let q2 = step_blend_drag(&mut mode, &q1, 70, false);\n assert_eq!(q2, [0, 70, 255, 255]);\n\n // Case 3: Dragging the split half back to 0 merges the handle\n let q3 = step_blend_drag(&mut mode, &q2, 0, false);\n assert_eq!(q3, [0, 0, 255, 255], \"Dragging back to origin reunites the triangle\");\n\n // Case 4: Alt-drag on unsplit white handle [0, 0, 255, 255] splits the left half\n let mut mode_w = BlendDrag::Pair { pair: 2, origin_v: 255 };\n assert_eq!(qw1, [0, 0, 200, 255], \"Alt-drag left must split white triangle into [200, 255]\");\n\n // Case 5: Dragging without Alt moves both halves together\n let mut mode_solid = BlendDrag::Pair { pair: 0, origin_v: 0 };\n assert_eq!(qs1, [35, 35, 255, 255], \"Drag without Alt moves solid handle together\");\n\n // Case 6: Clamping prevents black handle from crossing white handle\n let q_close = [0, 100, 150, 255];\n assert_eq!(q_clamped, [0, 150, 150, 255], \"Black max cannot exceed white min\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/92488307722c3b840507827cac7ee9a88470fc8a/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3967",
|
|
"pr": 3967,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_moves_and_deletes_the_clicked_filter_with_one_undo_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked two_filter_row_context_offers_reorder_and_delete -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked existing_filter_move_delete_commands_preserve_source_and_undo_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_disables_edges_and_deletes_the_only_remaining_filter -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_row_menu_closes_on_edits_undo_redo_document_switch_and_same_id_reopen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked parameter_and_camera_raw_modals_close_the_row_menu_without_mutation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pending_document_job_closes_row_menu_and_refuses_new_choices -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked existing_eye_and_name_double_click_remain_distinct_from_secondary_actions -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked capture_native_popup_at_two_scales_and_in_french -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_reorder_keeps_the_selected_filter_identity -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_delete_before_selection_keeps_the_remaining_filter_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_delete_selected_filter_clears_its_row_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_refused_edit_preserves_filter_order_and_selection -- --nocapture"
|
|
],
|
|
"expected": "row menu moves and deletes the clicked filter with one undo step; two filter row context offers reorder and delete; existing filter move delete commands preserve source and undo at every depth; row menu disables edges and deletes the only remaining filter; stale row menu closes on edits undo redo document switch and same id reopen; parameter and camera raw modals close the row menu without mutation; pending document job closes row menu and refuses new choices; existing eye and name double click remain distinct from secondary actions; capture native popup at two scales and in french; row menu reorder keeps the selected filter identity; row menu delete before selection keeps the remaining filter selected; row menu delete selected filter clears its row selection; row menu refused edit preserves filter order and selection",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_moves_and_deletes_the_clicked_filter_with_one_undo_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked two_filter_row_context_offers_reorder_and_delete -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked existing_filter_move_delete_commands_preserve_source_and_undo_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_disables_edges_and_deletes_the_only_remaining_filter -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_row_menu_closes_on_edits_undo_redo_document_switch_and_same_id_reopen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked parameter_and_camera_raw_modals_close_the_row_menu_without_mutation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pending_document_job_closes_row_menu_and_refuses_new_choices -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked existing_eye_and_name_double_click_remain_distinct_from_secondary_actions -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked capture_native_popup_at_two_scales_and_in_french -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_reorder_keeps_the_selected_filter_identity -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_delete_before_selection_keeps_the_remaining_filter_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_delete_selected_filter_clears_its_row_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked row_menu_refused_edit_preserves_filter_order_and_selection -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "row_menu_moves_and_deletes_the_clicked_filter_with_one_undo_step",
|
|
"path": "crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_moves_and_deletes_the_clicked_filter_with_one_undo_step -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for depth in [8, 16, 32] {\n for ppp in [1.0, 2.0] {\n let (mut h, layer) = harness_at(depth, ppp);\n let before = filters(h.state(), layer);\n let before_pixels = pixels(h.state(), layer);\n let source = photocraft_engine::smart_cmds::contents_of(&h.state().session.active().unwrap().doc, layer).unwrap();\n let st = h.state().session.active().unwrap();\n let active = st.active_layer;\n let selected = st.selected_layers.clone();\n let history = st.history.past_len();\n let other = st.doc.layer(active.unwrap()).unwrap().clone();",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(\"Move Up\").is_some(), \"actual filter row has Move Up\");\n h.get_by_label(\"Move Up\").click();\n h.run_steps(4);\n assert_eq!(filters(h.state(), layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\", \"filter.other.offset\"]);\n assert!(text_position(&h, \"Offset\").y < text_position(&h, \"Gaussian Blur\").y);\n assert_ne!(pixels(h.state(), layer), before_pixels);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 1);\n assert_eq!(h.state().session.active().unwrap().active_layer, active);\n assert_eq!(h.state().session.active().unwrap().selected_layers, selected);\n assert_eq!(photocraft_engine::smart_cmds::contents_of(&h.state().session.active().unwrap().doc, layer).unwrap(), source);\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n h.run_steps(3);\n assert_eq!(serde_json::to_value(filters(h.state(), layer)).unwrap(), serde_json::to_value(&before).unwrap());\n assert_eq!(pixels(h.state(), layer), before_pixels);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n h.run_steps(3);\n let offset = text_position(&h, \"Offset\");\n assert_eq!(serde_json::to_value(filters(h.state(), layer)).unwrap(), serde_json::to_value(&before).unwrap());\n assert_eq!(pixels(h.state(), layer), before_pixels);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 2);\n let offset = text_position(&h, \"Offset\");\n click(&mut h, offset, PointerButton::Secondary);\n h.get_by_label(\"Delete Smart Filter\").click();\n assert_eq!(filters(h.state(), layer).len(), 1);\n assert_eq!(filters(h.state(), layer)[0].command, \"filter.blur.gaussianBlur\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 3);\n assert_eq!(h.state().session.active().unwrap().active_layer, active);\n assert_eq!(h.state().session.active().unwrap().selected_layers, selected);\n assert_eq!(photocraft_engine::smart_cmds::contents_of(&h.state().session.active().unwrap().doc, layer).unwrap(), source);\n let unchanged = h.state().session.active().unwrap().doc.layer(other.id).unwrap();\n assert_eq!(unchanged, &other);\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(pixels(h.state(), layer), before_pixels);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(filters(h.state(), layer).len(), 1);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "two_filter_row_context_offers_reorder_and_delete",
|
|
"path": "crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked two_filter_row_context_offers_reorder_and_delete -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n let (mut h, layer) = harness();\n let top = text_position(&h, \"Gaussian Blur\");\n let bottom = text_position(&h, \"Offset\");\n assert!(top.y < bottom.y, \"index1 is visually above index0\");\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n click(&mut h, bottom, PointerButton::Secondary);\n assert!(std::sync::Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n let missing = [\"Move Up\", \"Move Down\", \"Delete Smart Filter\"].into_iter().filter(|label| h.query_by_label(label).is_none()).collect::<Vec<_>>();\n assert!(missing.is_empty(), \"filter row lacks context choices {missing:?}; stack has {} filters\", smart(h.state(), layer).smart_filters.len());",
|
|
"expected_assertions": [
|
|
" assert!(top.y < bottom.y, \"index1 is visually above index0\");\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n click(&mut h, bottom, PointerButton::Secondary);\n assert!(std::sync::Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n let missing = [\"Move Up\", \"Move Down\", \"Delete Smart Filter\"].into_iter().filter(|label| h.query_by_label(label).is_none()).collect::<Vec<_>>();\n assert!(missing.is_empty(), \"filter row lacks context choices {missing:?}; stack has {} filters\", smart(h.state(), layer).smart_filters.len());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "existing_filter_move_delete_commands_preserve_source_and_undo_at_every_depth",
|
|
"path": "crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked existing_filter_move_delete_commands_preserve_source_and_undo_at_every_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let (mut app, layer) = app(depth);\n let original = filters(&app, layer);\n let original_pixels = pixels(&app, layer);\n let source = photocraft_engine::smart_cmds::contents_of(&app.session.active().unwrap().doc, layer).unwrap();\n let active = app.session.active().unwrap().active_layer;\n let history = app.session.active().unwrap().history.past_len();\n app.run(\"layer.smartFilter.move\", json!({\"layer\": layer.0, \"index\": 0, \"to\": 1})).unwrap();\n assert_eq!(filters(&app, layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\", \"filter.other.offset\"]);\n assert_ne!(pixels(&app, layer), original_pixels, \"noncommuting operations really rerender\");\n assert_eq!(app.session.active().unwrap().history.past_len(), history + 1);\n assert_eq!(app.session.active().unwrap().active_layer, active);",
|
|
"expected_assertions": [
|
|
" assert_eq!(filters(&app, layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\", \"filter.other.offset\"]);\n assert_ne!(pixels(&app, layer), original_pixels, \"noncommuting operations really rerender\");\n assert_eq!(app.session.active().unwrap().history.past_len(), history + 1);\n assert_eq!(app.session.active().unwrap().active_layer, active);\n assert_eq!(photocraft_engine::smart_cmds::contents_of(&app.session.active().unwrap().doc, layer).unwrap(), source);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(serde_json::to_value(filters(&app, layer)).unwrap(), serde_json::to_value(&original).unwrap());\n assert_eq!(pixels(&app, layer), original_pixels);\n app.run(\"edit.redo\", json!({})).unwrap();\n let reordered_pixels = pixels(&app, layer);\n app.run(\"layer.smartFilter.delete\", json!({\"layer\": layer.0, \"index\": 1})).unwrap();\n assert_eq!(filters(&app, layer).len(), 1);\n assert_eq!(filters(&app, layer)[0].command, \"filter.blur.gaussianBlur\");\n assert_eq!(app.session.active().unwrap().history.past_len(), history + 2);\n assert_eq!(app.session.active().unwrap().active_layer, active);\n assert_eq!(photocraft_engine::smart_cmds::contents_of(&app.session.active().unwrap().doc, layer).unwrap(), source);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(pixels(&app, layer), reordered_pixels);\n app.run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(filters(&app, layer).len(), 1);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/context_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "row_menu_disables_edges_and_deletes_the_only_remaining_filter",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_disables_edges_and_deletes_the_only_remaining_filter -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for ppp in [1.0, 2.0] {\n let (mut h, layer) = harness_at(8, ppp);\n let top = text_position(&h, \"Gaussian Blur\");\n click(&mut h, top, PointerButton::Secondary);\n assert!(h.get_by_label(\"Move Up\").accesskit_node().is_disabled());\n assert!(!h.get_by_label(\"Move Down\").accesskit_node().is_disabled());\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(\"Move Up\").click();\n h.run_steps(3);\n assert!(Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));",
|
|
"expected_assertions": [
|
|
" assert!(h.get_by_label(\"Move Up\").accesskit_node().is_disabled());\n assert!(!h.get_by_label(\"Move Down\").accesskit_node().is_disabled());\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(\"Move Up\").click();\n assert!(Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n egui::Popup::close_all(&h.ctx);\n h.state_mut().run(\"layer.smartFilter.delete\", json!({\"layer\":layer.0,\"index\":0})).unwrap();\n h.run_steps(3);\n assert!(h.get_by_label(\"Move Up\").accesskit_node().is_disabled());\n assert!(h.get_by_label(\"Move Down\").accesskit_node().is_disabled());\n assert!(!h.get_by_label(\"Delete Smart Filter\").accesskit_node().is_disabled());\n h.get_by_label(\"Delete Smart Filter\").click();\n h.run_steps(4);\n assert!(filters(h.state(), layer).is_empty());\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 2);\n assert!(!egui::Popup::is_any_open(&h.ctx));\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(filters(h.state(), layer).len(), 1);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert!(filters(h.state(), layer).is_empty());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stale_row_menu_closes_on_edits_undo_redo_document_switch_and_same_id_reopen",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked stale_row_menu_closes_on_edits_undo_redo_document_switch_and_same_id_reopen -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for change in [\"move\", \"delete\", \"undo\", \"redo\", \"switch\", \"reopen\", \"close\"] {\n let (mut h, layer) = harness();\n let offset = text_position(&h, \"Offset\");\n click(&mut h, offset, PointerButton::Secondary);\n assert!(h.query_by_label(\"Delete Smart Filter\").is_some());\n match change {\n \"move\" => {\n h.state_mut().run(\"layer.smartFilter.move\", json!({\"layer\":layer.0,\"index\":0,\"to\":1})).unwrap();\n }\n \"delete\" => {\n h.state_mut().run(\"layer.smartFilter.delete\", json!({\"layer\":layer.0,\"index\":0})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(\"Delete Smart Filter\").is_some());\n match change {\n \"move\" => {\n h.state_mut().run(\"layer.smartFilter.move\", json!({\"layer\":layer.0,\"index\":0,\"to\":1})).unwrap();\n assert_eq!(session.documents()[index].doc.id, old.doc.id);\n session.active_mut().unwrap().revision = old.revision;\n assert!(!Arc::ptr_eq(&session.active().unwrap().doc, &old.doc));\n }\n \"close\" => {\n let session = &mut h.state_mut().session;\n assert!(h.query_by_label(\"Delete Smart Filter\").is_none(), \"{change} closes stale choices\");\n assert!(!egui::Popup::is_any_open(&h.ctx), \"{change} closes popup memory too\");\n if let Some((doc, revision, history)) = before {\n let st = h.state().session.active().unwrap();\n assert!(Arc::ptr_eq(&doc, &st.doc), \"{change} adds no accidental edit\");\n assert_eq!((st.revision, st.history.past_len()), (revision, history));\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "parameter_and_camera_raw_modals_close_the_row_menu_without_mutation",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked parameter_and_camera_raw_modals_close_the_row_menu_without_mutation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for raw in [false, true] {\n let (mut h, layer) = harness();\n let offset = text_position(&h, \"Offset\");\n click(&mut h, offset, PointerButton::Secondary);\n let ctx = h.ctx.clone();\n if raw {\n crate::camera_raw_ui::open(h.state_mut(), &ctx).unwrap();\n } else {\n let sm = smart(h.state(), layer).clone();\n open_editor(h.state_mut(), &ctx, layer.0, &sm, 0);\n assert!(h.state().ui.dialogs.last().unwrap().fields.contains_key(\"__smartFilter\"));",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.dialogs.last().unwrap().fields.contains_key(\"__smartFilter\"));\n }\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n assert!(h.query_by_label(\"Delete Smart Filter\").is_none());\n assert!(!egui::Popup::is_any_open(&h.ctx));\n assert!(Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pending_document_job_closes_row_menu_and_refuses_new_choices",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pending_document_job_closes_row_menu_and_refuses_new_choices -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n let (mut h, _layer) = harness();\n let offset = text_position(&h, \"Offset\");\n click(&mut h, offset, PointerButton::Secondary);\n let before = h.state().session.active().unwrap().doc.clone();\n let started = h\n .state_mut()\n .session\n .start_job(\n \"test.wait\",\n json!({}),\n \"Waiting filter\",",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(\"Delete Smart Filter\").is_none());\n assert!(!egui::Popup::is_any_open(&h.ctx));\n click(&mut h, offset, PointerButton::Secondary);\n assert!(h.query_by_label(\"Delete Smart Filter\").is_none());\n assert!(Arc::ptr_eq(&before, &h.state().session.active().unwrap().doc));\n h.state_mut().session.cancel_job(id);\n h.state_mut().session.join_cancelled_jobs();\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "existing_eye_and_name_double_click_remain_distinct_from_secondary_actions",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked existing_eye_and_name_double_click_remain_distinct_from_secondary_actions -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for ppp in [1.0, 2.0] {\n let (mut h, layer) = harness_at(8, ppp);\n let offset = text_position(&h, \"Offset\");\n let layer_row = crate::layer_row_ui::recorded(&h.ctx).into_iter().find(|r| r.layer == layer.0).unwrap().row;\n let eye = pos2(layer_row.left() + 15.0, offset.y);\n let history = h.state().session.active().unwrap().history.past_len();\n click(&mut h, eye, PointerButton::Primary);\n assert!(!filters(h.state(), layer)[0].visible);\n assert!(h.query_by_label(\"Delete Smart Filter\").is_none());\n assert!(h.state().ui.dialogs.is_empty());\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(!filters(h.state(), layer)[0].visible);\n assert!(h.query_by_label(\"Delete Smart Filter\").is_none());\n assert!(h.state().ui.dialogs.is_empty());\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n h.run_steps(40);\n click(&mut h, offset, PointerButton::Primary);\n assert_eq!(dialog.fields[\"__command\"], json!(\"filter.other.offset\"));\n assert_eq!(dialog.fields[\"__smartFilter\"], json!({\"layer\":layer.0,\"index\":0}));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "capture_native_popup_at_two_scales_and_in_french",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked capture_native_popup_at_two_scales_and_in_french -- --nocapture --ignored",
|
|
"fixture_and_action_excerpt": " let out = std::env::var(\"PHOTOCRAFT_SMART_FILTER_CAPTURE_DIR\").expect(\"capture destination\");\n for (language, ppp) in [(\"en\", 1.0), (\"fr\", 2.0)] {\n let (mut app, layer) = app(8);\n app.run(\"prefs.set\", json!({\"path\":\"interface.language\",\"value\":language})).unwrap();\n let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1440.0, 900.0)).with_pixels_per_point(ppp).with_max_steps(64).wgpu().build_eframe(\n move |cc| {\n PhotocraftApp::setup_context(&cc.egui_ctx, Default::default());\n app\n },\n );\n let ctx = h.ctx.clone();\n let (req, _) = crate::control::ControlRequest::new(\"ui.set\", json!({\"zoom\":12.0,\"dock\":{\"collapsed\":[\"color\",\"properties\",\"history\",\"navigator\"]}}));",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(label).is_some(), \"localized popup item {label}\");\n }\n h.run_steps(12);\n let file = std::path::Path::new(&out).join(format!(\"smart-filter-menu-{language}-{}x.png\", ppp as u32));"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": true,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "row_menu_reorder_keeps_the_selected_filter_identity",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_reorder_keeps_the_selected_filter_identity -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for ppp in [1.0, 2.0] {\n for (target, choice) in [(\"Offset\", \"Move Up\"), (\"Gaussian Blur\", \"Move Down\")] {\n let (mut h, layer) = harness_at(8, ppp);\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Primary);\n assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::False));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, target);\n click(&mut h, at, PointerButton::Secondary);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::False));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, target);\n assert_eq!(filters(h.state(), layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\", \"filter.other.offset\"]);\n assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True), \"{target}/{choice} keeps Offset selected\");\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::False));\n let st = h.state().session.active().unwrap();\n assert_eq!((st.active_layer, &st.selected_layers, st.history.past_len()), (active, &selected, history + 1));\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "row_menu_delete_before_selection_keeps_the_remaining_filter_selected",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_delete_before_selection_keeps_the_remaining_filter_selected -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for ppp in [1.0, 2.0] {\n let (mut h, layer) = harness_at(8, ppp);\n let at = text_position(&h, \"Gaussian Blur\");\n click(&mut h, at, PointerButton::Primary);\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Secondary);\n h.get_by_label(\"Delete Smart Filter\").click();\n h.run_steps(4);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, \"Offset\");\n assert_eq!(filters(h.state(), layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\"]);\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let st = h.state().session.active().unwrap();\n assert_eq!((st.active_layer, &st.selected_layers, st.history.past_len()), (active, &selected, history + 1));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "row_menu_delete_selected_filter_clears_its_row_selection",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_delete_selected_filter_clears_its_row_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n for ppp in [1.0, 2.0] {\n let (mut h, layer) = harness_at(8, ppp);\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Primary);\n assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Secondary);\n h.get_by_label(\"Delete Smart Filter\").click();\n h.run_steps(4);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n let at = text_position(&h, \"Offset\");\n assert_eq!(filters(h.state(), layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.blur.gaussianBlur\"]);\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::False));\n let doc = h.state().session.active().unwrap().doc.id;\n assert!(h.ctx.data(|d| d.get_temp::<FilterDrag>(selected_key(doc))).is_none());\n let st = h.state().session.active().unwrap();\n assert_eq!((st.active_layer, &st.selected_layers, st.history.past_len()), (active, &selected, history + 1));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "row_menu_refused_edit_preserves_filter_order_and_selection",
|
|
"path": "crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked row_menu_refused_edit_preserves_filter_order_and_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " let _language = crate::i18n::language_scope(crate::i18n::Lang::EN);\n let (mut h, layer) = harness();\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Primary);\n assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let before = h.state().session.active().unwrap().doc.clone();\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n h.state_mut().session.authorize =\n Some(|command, _| if command == \"layer.smartFilter.move\" { Err(photocraft_engine::EngineError::Other(\"refused menu edit\".into())) } else { Ok(()) });\n let at = text_position(&h, \"Offset\");\n click(&mut h, at, PointerButton::Secondary);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n let before = h.state().session.active().unwrap().doc.clone();\n let st = h.state().session.active().unwrap();\n let (active, selected, history) = (st.active_layer, st.selected_layers.clone(), st.history.past_len());\n assert!(Arc::ptr_eq(&before, &st.doc));\n assert_eq!((st.active_layer, &st.selected_layers, st.history.past_len()), (active, &selected, history));\n assert_eq!(filters(h.state(), layer).iter().map(|f| f.command.as_str()).collect::<Vec<_>>(), [\"filter.other.offset\", \"filter.blur.gaussianBlur\"]);\n assert_eq!(h.get_by_label(\"Offset\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::True));\n assert_eq!(h.get_by_label(\"Gaussian Blur\").accesskit_node().toggled(), Some(egui::accesskit::Toggled::False));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3a77519ce2cef0fb60cebd4ea796d599f68868cb/crates/ui-egui/src/smart_ui/menu_guard_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4023",
|
|
"pr": 4023,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Select Spanish UI, synthetic document, and menus/dialogs for video footage, Blur Gallery, Pixelate and Sharpen. Record Spanish language selection and screenshots.",
|
|
"action": "Check Interpret Footage = Interpretar material de v\u00eddeo; Replace Footage = Reemplazar material de v\u00eddeo; Tilt-Shift = Desenfoque de inclinaci\u00f3n y desplazamiento; Mezzotint = Grabado a media tinta; Smart Sharpen = Enfoque inteligente. Check their ellipsis variants in menus. Exercise a Count label with value 3 and confirm Recuento: 3, with no literal {n}.",
|
|
"expected": "Specified Spanish strings match the final catalog, ellipses remain where defined, and values replace placeholders without English fallback or raw {n}/{file} tokens.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-4305",
|
|
"pr": 4305,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked low_and_high_composite_back_to_the_source_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked high_must_be_on_linear_light -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked builds_a_named_group_above_the_source_and_targets_high -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked low_is_the_gaussian_blur_of_the_source_at_the_radius -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked one_undo_removes_everything_and_redo_brings_it_back -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked works_on_the_background -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked needs_a_pixel_layer_with_pixels -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked refuses_a_channel_or_mask_target -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked refuses_cmyk_and_lab -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked a_layer_of_transparent_tiles_is_refused_when_run -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_params_are_rejected_without_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked frequency_separation_sits_in_filter_other_after_color_to_alpha -- --nocapture"
|
|
],
|
|
"expected": "low and high composite back to the source at every depth; high must be on linear light; builds a named group above the source and targets high; low is the gaussian blur of the source at the radius; one undo removes everything and redo brings it back; works on the background; needs a pixel layer with pixels; refuses a channel or mask target; refuses cmyk and lab; a layer of transparent tiles is refused when run; bad params are rejected without changes; frequency separation sits in filter other after color to alpha",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked low_and_high_composite_back_to_the_source_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked high_must_be_on_linear_light -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked builds_a_named_group_above_the_source_and_targets_high -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked low_is_the_gaussian_blur_of_the_source_at_the_radius -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked one_undo_removes_everything_and_redo_brings_it_back -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked works_on_the_background -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked needs_a_pixel_layer_with_pixels -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked refuses_a_channel_or_mask_target -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked refuses_cmyk_and_lab -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked a_layer_of_transparent_tiles_is_refused_when_run -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_params_are_rejected_without_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked frequency_separation_sits_in_filter_other_after_color_to_alpha -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "low_and_high_composite_back_to_the_source_at_every_depth",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked low_and_high_composite_back_to_the_source_at_every_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (depth, mode, tol) in [(8, \"rgb\", 1.0 / 255.0), (16, \"rgb\", 1.0 / 65535.0), (32, \"rgb\", 1e-5), (8, \"gray\", 1.0 / 255.0), (32, \"gray\", 1e-5)] {\n let tol = tol + 1e-6;\n let mut s = session(depth, mode);\n let source = active(&s);\n let before = composite(doc(&s));\n s.execute(ID, json!({\"radius\": 3})).unwrap_or_else(|e| panic!(\"{depth} {mode}: {e}\"));\n let d = doc(&s);\n let (_, [low, high]) = group_of(d, source);\n // The group alone rebuilds the source: hide the source so it can't show through.\n let rebuilt = composite(&without(d, source));\n let err = max_diff(&before, &rebuilt);\n assert!(err <= tol, \"{depth} {mode}: Low + High is off by {err} (tolerance {tol})\");",
|
|
"expected_assertions": [
|
|
" assert!(err <= tol, \"{depth} {mode}: Low + High is off by {err} (tolerance {tol})\");\n assert!(max_diff(&composite(d), &rebuilt) <= 1e-6, \"{depth} {mode}: the group covers the source\");\n // Low alone is visibly smoother than the source; High carries what it lost.\n let low_only = composite(&without(&without(d, source), high));\n assert!(max_diff(&before, &low_only) > 0.1, \"{depth} {mode}: Low is blurred\");\n let h = d.layer(high).unwrap().surface().unwrap();\n assert!((0..W).any(|x| (h.rgba(x, 5)[0] - 0.5).abs() > 0.05), \"{depth} {mode}: High holds the detail\");\n assert_ne!(pixels(d, low), pixels(d, source), \"{depth} {mode}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "high_must_be_on_linear_light",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked high_must_be_on_linear_light -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(16, \"rgb\");\n let source = active(&s);\n let before = composite(doc(&s));\n s.execute(ID, json!({})).unwrap();\n let (_, [_, high]) = group_of(doc(&s), source);\n let mut d = doc(&s).clone();\n d.layer_mut(high).unwrap().blend = BlendMode::Normal;\n assert!(max_diff(&before, &composite(&d)) > 0.1);\n }",
|
|
"expected_assertions": [
|
|
" assert!(max_diff(&before, &composite(&d)) > 0.1);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "builds_a_named_group_above_the_source_and_targets_high",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked builds_a_named_group_above_the_source_and_targets_high -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8, \"rgb\");\n let source = active(&s);\n let source_px = pixels(doc(&s), source);\n let r = s.execute(ID, json!({})).unwrap();\n let d = doc(&s);\n let (group, [low, high]) = group_of(d, source);\n let g = d.layer(group).unwrap();\n assert_eq!(g.name, \"Frequency Separation\");\n assert_eq!(g.blend, BlendMode::PassThrough);\n let (l, h) = (d.layer(low).unwrap(), d.layer(high).unwrap());\n assert_eq!((l.name.as_str(), l.blend), (\"Low Frequency\", BlendMode::Normal));\n assert_eq!((h.name.as_str(), h.blend), (\"High Frequency\", BlendMode::LinearLight));",
|
|
"expected_assertions": [
|
|
" assert_eq!(g.name, \"Frequency Separation\");\n assert_eq!(g.blend, BlendMode::PassThrough);\n let (l, h) = (d.layer(low).unwrap(), d.layer(high).unwrap());\n assert_eq!((l.name.as_str(), l.blend), (\"Low Frequency\", BlendMode::Normal));\n assert_eq!((h.name.as_str(), h.blend), (\"High Frequency\", BlendMode::LinearLight));\n assert!(matches!(l.content, LayerContent::Raster(_)) && matches!(h.content, LayerContent::Raster(_)));\n assert!(l.visible && h.visible && g.visible);\n // High draws where the source does, not grey over the transparent rest of its tiles.\n let bounds = |id: LayerId| d.layer(id).unwrap().surface().unwrap().content_bounds();\n assert_eq!(bounds(source), Rect::new(0, 0, W, H));\n assert_eq!(bounds(high), bounds(source));\n // The source is left exactly as it was, visible, below the group.\n let src = d.layer(source).unwrap();\n assert_eq!((src.name.as_str(), src.visible), (\"Skin\", true));\n assert_eq!(pixels(d, source), source_px);\n assert_eq!(active(&s), high, \"retouching starts on the High layer\");\n assert_eq!(r, json!({\"group\": group.0, \"low\": low.0, \"high\": high.0, \"radius\": 4.0}));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "low_is_the_gaussian_blur_of_the_source_at_the_radius",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked low_is_the_gaussian_blur_of_the_source_at_the_radius -- --nocapture",
|
|
"fixture_and_action_excerpt": " for radius in [2.0, 6.5] {\n let mut s = session(16, \"rgb\");\n let source = active(&s);\n s.execute(ID, json!({\"radius\": radius})).unwrap();\n let (_, [low, _]) = group_of(doc(&s), source);\n let mut t = session(16, \"rgb\");\n t.execute(\"filter.blur.gaussianBlur\", json!({\"radius\": radius})).unwrap();\n assert_eq!(pixels(doc(&s), low), pixels(doc(&t), active(&t)), \"radius {radius}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(pixels(doc(&s), low), pixels(doc(&t), active(&t)), \"radius {radius}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "one_undo_removes_everything_and_redo_brings_it_back",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked one_undo_removes_everything_and_redo_brings_it_back -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8, \"rgb\");\n let source = active(&s);\n let before = doc(&s).clone();\n let steps = s.active().unwrap().history.past_len();\n s.execute(ID, json!({})).unwrap();\n assert_eq!(s.active().unwrap().history.past_len(), steps + 1);\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Frequency Separation\"));\n let after = doc(&s).clone();\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(*doc(&s), before);\n assert_eq!(active(&s), source);\n s.execute(\"edit.redo\", json!({})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.active().unwrap().history.past_len(), steps + 1);\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Frequency Separation\"));\n let after = doc(&s).clone();\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(*doc(&s), before);\n assert_eq!(active(&s), source);\n s.execute(\"edit.redo\", json!({})).unwrap();\n assert_eq!(*doc(&s), after);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "works_on_the_background",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked works_on_the_background -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": W, \"height\": H})).unwrap();\n paint(&mut s);\n let source = active(&s);\n assert!(doc(&s).is_background(source));\n let before = composite(doc(&s));\n s.execute(ID, json!({\"radius\": 2})).unwrap();\n let d = doc(&s);\n assert!(d.is_background(source));\n let (_, [low, high]) = group_of(d, source);\n for id in [low, high] {\n assert_eq!(d.layer(id).unwrap().locks, Default::default());",
|
|
"expected_assertions": [
|
|
" assert!(doc(&s).is_background(source));\n let before = composite(doc(&s));\n s.execute(ID, json!({\"radius\": 2})).unwrap();\n let d = doc(&s);\n assert!(d.is_background(source));\n let (_, [low, high]) = group_of(d, source);\n for id in [low, high] {\n assert_eq!(d.layer(id).unwrap().locks, Default::default());\n }\n assert!(max_diff(&before, &composite(d)) <= 1.0 / 255.0 + 1e-6);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "needs_a_pixel_layer_with_pixels",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked needs_a_pixel_layer_with_pixels -- --nocapture",
|
|
"fixture_and_action_excerpt": " refused(&mut Session::new(), \"no document\");\n\n let mut s = session(8, \"rgb\");\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n refused(&mut s, \"an empty layer\");\n let e = s.execute(ID, json!({})).unwrap_err().to_string();\n assert!(e.contains(\"no pixels\"), \"{e}\");\n\n let mut s = session(8, \"rgb\");\n s.execute(\"type.create\", json!({\"x\": 4, \"y\": 20, \"text\": \"Hi\", \"size\": 12})).unwrap();\n refused(&mut s, \"a type layer\");\n let e = s.execute(ID, json!({})).unwrap_err().to_string();",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(\"no pixels\"), \"{e}\");\n\n let mut s = session(8, \"rgb\");\n s.execute(\"type.create\", json!({\"x\": 4, \"y\": 20, \"text\": \"Hi\", \"size\": 12})).unwrap();\n assert!(e.contains(\"pixel layer\"), \"{e}\");\n\n let mut s = session(8, \"rgb\");\n s.execute(\"layer.newAdjustmentLayer.invert\", json!({})).unwrap();"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "refuses_a_channel_or_mask_target",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked refuses_a_channel_or_mask_target -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8, \"rgb\");\n s.execute(\"select.all\", json!({})).unwrap();\n s.execute(\"select.saveSelection\", json!({})).unwrap();\n s.execute(\"select.deselect\", json!({})).unwrap();\n s.execute(\"channel.target\", json!({\"channel\": \"Alpha 1\"})).unwrap();\n assert!(crate::channel_cmds::edits_channel(&s));\n refused(&mut s, \"an alpha channel\");\n\n let mut s = session(8, \"rgb\");\n s.execute(\"layer.layerMask.revealAll\", json!({})).unwrap();\n s.execute(\"channel.target\", json!({\"channel\": \"mask\"})).unwrap();\n assert_eq!(s.active().unwrap().channel_view.target, crate::channel_cmds::ChannelTarget::LayerMask);",
|
|
"expected_assertions": [
|
|
" assert!(crate::channel_cmds::edits_channel(&s));\n refused(&mut s, \"an alpha channel\");\n\n let mut s = session(8, \"rgb\");\n assert_eq!(s.active().unwrap().channel_view.target, crate::channel_cmds::ChannelTarget::LayerMask);\n refused(&mut s, \"a targeted layer mask\");\n // The same layer, its pixels targeted again: allowed (the refusal was the target's).\n s.execute(\"channel.target\", json!({\"channel\": \"composite\"})).unwrap();\n assert!(s.is_enabled(ID));\n s.execute(ID, json!({})).unwrap();\n\n // Showing the mask (\u2325-click its thumbnail) targets it too.\n assert!(s.is_enabled(ID));\n s.execute(\"view.layerMask\", json!({\"mode\": \"gray\"})).unwrap();\n refused(&mut s, \"a mask shown in mask view\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "refuses_cmyk_and_lab",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked refuses_cmyk_and_lab -- --nocapture",
|
|
"fixture_and_action_excerpt": " for mode in [\"cmyk\", \"lab\"] {\n let mut s = session(8, mode);\n refused(&mut s, mode);\n let e = s.execute(ID, json!({})).unwrap_err().to_string();\n assert!(e.contains(\"RGB or Grayscale\"), \"{mode}: {e}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(\"RGB or Grayscale\"), \"{mode}: {e}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_layer_of_transparent_tiles_is_refused_when_run",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked a_layer_of_transparent_tiles_is_refused_when_run -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8, \"rgb\");\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.edit(\"clear\", |doc, active| {\n let surf = doc.layer_mut(active.unwrap()).unwrap().surface_mut().unwrap();\n surf.write_region(Rect::new(0, 0, 8, 8), &vec![0.0; 8 * 8 * surf.channels()]);\n Ok(())\n })\n .unwrap();\n assert!(s.is_enabled(ID));\n let before = doc(&s).clone();\n let e = s.execute(ID, json!({})).unwrap_err().to_string();\n assert!(e.contains(\"no pixels\"), \"{e}\");",
|
|
"expected_assertions": [
|
|
" assert!(s.is_enabled(ID));\n let before = doc(&s).clone();\n let e = s.execute(ID, json!({})).unwrap_err().to_string();\n assert!(e.contains(\"no pixels\"), \"{e}\");\n assert_eq!(*doc(&s), before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "bad_params_are_rejected_without_changes",
|
|
"path": "crates/engine/src/frequency_separation_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked bad_params_are_rejected_without_changes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8, \"rgb\");\n let before = doc(&s).clone();\n for p in [\n json!(7),\n json!(\"4\"),\n json!({\"radius\": 0}),\n json!({\"radius\": 0.05}),\n json!({\"radius\": -3}),\n json!({\"radius\": 1000.5}),\n json!({\"radius\": 1e308}),\n json!({\"radius\": \"4\"}),\n json!({\"radius\": null}),",
|
|
"expected_assertions": [
|
|
" assert!(matches!(s.execute(ID, p.clone()), Err(EngineError::BadParams { .. })), \"{p}\");\n }\n assert_eq!(*doc(&s), before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/engine/src/frequency_separation_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "frequency_separation_sits_in_filter_other_after_color_to_alpha",
|
|
"path": "crates/ui-egui/src/menus.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked frequency_separation_sits_in_filter_other_after_color_to_alpha -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 32, \"height\": 32})).unwrap();\n let items = menu_items(&app);\n let at = |id: &str| items.iter().position(|i| i.id == id).unwrap_or_else(|| panic!(\"{id} missing\"));\n let (c2a, fs) = (at(\"filter.other.colorToAlpha\"), at(\"layer.frequencySeparation\"));\n assert_eq!(fs, c2a + 1);\n assert_eq!(items[fs].path, items[at(\"filter.other.highPass\")].path);\n assert_eq!(items[fs].label, \"Frequency Separation\u2026\");\n assert!(items[fs].enabled, \"the Background is a pixel layer with pixels\");\n assert!(crate::filter_dialog::has_dialog(\"layer.frequencySeparation\"));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(fs, c2a + 1);\n assert_eq!(items[fs].path, items[at(\"filter.other.highPass\")].path);\n assert_eq!(items[fs].label, \"Frequency Separation\u2026\");\n assert!(items[fs].enabled, \"the Background is a pixel layer with pixels\");\n assert!(crate::filter_dialog::has_dialog(\"layer.frequencySeparation\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b74873991dbb2e9803d228a969291f09c6f1032/crates/ui-egui/src/menus.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4711",
|
|
"pr": 4711,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked dissolve_adjustment_is_a_per_pixel_choice -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_fill_is_a_per_pixel_choice -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked color_overlay_keeps_dissolve_coverage -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked dissolve_adjustments_and_effects_match_cpu_in_offset_regions -- --nocapture"
|
|
],
|
|
"expected": "clipped dissolve is binary and preserves the base shape; clipped dissolve matches whole render at offset regions and depths; dissolve adjustment is a per pixel choice; clipped dissolve fill is a per pixel choice; color overlay keeps dissolve coverage; groups masks and clipping; dissolve adjustments and effects match cpu in offset regions",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked dissolve_adjustment_is_a_per_pixel_choice -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_fill_is_a_per_pixel_choice -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked color_overlay_keeps_dissolve_coverage -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked dissolve_adjustments_and_effects_match_cpu_in_offset_regions -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "clipped_dissolve_is_binary_and_preserves_the_base_shape",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut d = doc_white(40, 12);\n d.layers.push(solid_layer(\"base\", Rect::new(0, 0, 20, 12), [0.0, 0.0, 1.0, 1.0]));\n let mut clip = solid_layer(\"clip\", d.bounds(), [1.0, 0.0, 0.0, 1.0]);\n clip.clipped = true;\n clip.blend = BlendMode::Dissolve;\n clip.opacity = 0.6;\n clip.fill_opacity = 0.5;\n d.layers.push(clip);\n let mut red = 0;\n let mut blue = 0;\n for y in 0..12 {\n for x in 0..20 {",
|
|
"expected_assertions": [
|
|
" assert!(close4(p, [0.0, 0.0, 1.0, 1.0]), \"Dissolve must not interpolate: {p:?} at ({x},{y})\");\n blue += 1;\n }\n }\n assert!(close4(px(&d, 30, y), [1.0; 4]), \"outside the base the clip is invisible\");\n }\n assert!(red > 0 && blue > 0, \"Dissolve must expose both source and base: {red}/{blue}\");\n assert!((red as f32 / (red + blue) as f32 - 0.3).abs() < 0.1, \"coverage should follow 60% opacity \u00d7 50% fill: {red}/{blue}\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "clipped_dissolve_matches_whole_render_at_offset_regions_and_depths",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"fixture_and_action_excerpt": " for fmt in [PixelFormat::RGBA8, PixelFormat::RGBA16, PixelFormat::RGBA32F] {\n let mut d = Document::new(\"coverage\", Size::new(32, 18), ColorMode::Rgb, fmt.sample);\n let bounds = Rect::new(-3, -2, 32, 18);\n let mut base = Layer::raster(\"base\", fmt);\n base.surface_mut().unwrap().fill_rect(bounds, &[0.0, 0.0, 1.0, 0.5]);\n d.layers.push(base);\n let mut clip = Layer::raster(\"clip\", fmt);\n clip.surface_mut().unwrap().fill_rect(bounds, &[1.0, 0.0, 0.0, 0.75]);\n clip.clipped = true;\n clip.blend = BlendMode::Dissolve;\n clip.opacity = 0.6;\n clip.fill_opacity = 0.5;",
|
|
"expected_assertions": [
|
|
" assert!(close4(part.get(x, y), whole.get(x, y)), \"{fmt:?}: region mismatch at ({x},{y})\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dissolve_adjustment_is_a_per_pixel_choice",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked dissolve_adjustment_is_a_per_pixel_choice -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut d = doc_white(16, 16);\n let mut inv = Layer::new(\"inv\", LayerContent::Adjustment(Adjustment::Invert));\n inv.blend = photocraft_color::BlendMode::Dissolve;\n inv.opacity = 0.5;\n d.layers.push(inv);\n let b = flatten(&d);\n let (black, white, other) = b.px.iter().fold((0, 0, 0), |(k, w, o), p| {\n if close4(*p, [0.0, 0.0, 0.0, 1.0]) {\n (k + 1, w, o)\n } else if close4(*p, [1.0, 1.0, 1.0, 1.0]) {\n (k, w + 1, o)\n } else {",
|
|
"expected_assertions": [
|
|
" assert_eq!(other, 0, \"a partial mix would be gray\");\n assert!(black > 40 && white > 40, \"black {black} white {white}\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "clipped_dissolve_fill_is_a_per_pixel_choice",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked clipped_dissolve_fill_is_a_per_pixel_choice -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut d = doc_white(16, 16);\n let mut l = solid_layer(\"k\", Rect::new(0, 0, 16, 16), [0.0, 0.0, 0.0, 1.0]);\n l.clipped = true;\n l.blend = photocraft_color::BlendMode::Dissolve;\n l.opacity = 0.5;\n d.layers.push(l);\n let b = flatten(&d);\n assert!(b.px.iter().all(|p| close4(*p, [0.0, 0.0, 0.0, 1.0]) || close4(*p, [1.0; 4])));\n}",
|
|
"expected_assertions": [
|
|
" assert!(b.px.iter().all(|p| close4(*p, [0.0, 0.0, 0.0, 1.0]) || close4(*p, [1.0; 4])));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "color_overlay_keeps_dissolve_coverage",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked color_overlay_keeps_dissolve_coverage -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::effects::{Effect, FxCommon};\n let mut d = doc_white(16, 16);\n let mut l = Layer::new(\"ink\", LayerContent::Fill(Fill::Solid(photocraft_color::Color::BLACK)));\n l.effects.items.push(Effect::ColorOverlay { common: FxCommon::new(photocraft_color::BlendMode::Normal, 1.0), color: photocraft_color::Color::BLACK });\n l.blend = photocraft_color::BlendMode::Dissolve;\n l.opacity = 0.5;\n d.layers.push(l);\n let b = flatten(&d);\n assert!(b.px.iter().all(|p| close4(*p, [0.0, 0.0, 0.0, 1.0]) || close4(*p, [1.0; 4])));\n}",
|
|
"expected_assertions": [
|
|
" assert!(b.px.iter().all(|p| close4(*p, [0.0, 0.0, 0.0, 1.0]) || close4(*p, [1.0; 4])));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "groups_masks_and_clipping",
|
|
"path": "crates/gpu/tests/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"fixture_and_action_excerpt": " let Some(mut g) = gpu() else { return };\n let child = |seed, mode| {\n let mut l = noise_layer(\"c\", PixelFormat::RGBA8, Rect::new(5, 5, 50, 40), seed, 0.0);\n l.blend = mode;\n l\n };\n for isolated in [false, true] {\n let mut d = base_doc(56, 44);\n let mut grp = Layer::group(\"g\", vec![child(11, BlendMode::Normal), child(12, BlendMode::Screen), child(13, BlendMode::Multiply)]);\n if isolated {\n grp.blend = BlendMode::Overlay;\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/gpu/tests/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dissolve_adjustments_and_effects_match_cpu_in_offset_regions",
|
|
"path": "crates/gpu/tests/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked dissolve_adjustments_and_effects_match_cpu_in_offset_regions -- --nocapture",
|
|
"fixture_and_action_excerpt": " let Some(mut g) = gpu() else { return };\n for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {\n for effects in [false, true] {\n let mut d = Document::new(\"Dissolve\", Size::new(300, 280), ColorMode::Rgb, depth);\n d.layers.push(noise_layer(\"base\", d.pixel_format(), Rect::new(0, 0, 300, 280), 19, 0.4));\n let mut layer = if effects {\n let mut l = noise_layer(\"effect\", d.pixel_format(), Rect::new(-8, 13, 290, 270), 27, 0.6);\n l.effects.items = vec![Effect::ColorOverlay { common: FxCommon::new(BlendMode::Normal, 0.7), color: Color::rgb(0.2, 0.8, 0.4) }];\n l\n } else {\n Layer::new(\"adjustment\", LayerContent::Adjustment(Adjustment::Invert))\n };",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/db546ff4822a011a7915b66af3834f94c05767db/crates/gpu/tests/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4992",
|
|
"pr": 4992,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_rotate_event_reaches_canvas_when_trackpad_rotation_is_enabled -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_pinch_resets_legacy_gesture_continuation -- --nocapture"
|
|
],
|
|
"expected": "clipped dissolve is binary and preserves the base shape; clipped dissolve matches whole render at offset regions and depths; groups masks and clipping; native rotate event reaches canvas when trackpad rotation is enabled; native pinch resets legacy gesture continuation",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_rotate_event_reaches_canvas_when_trackpad_rotation_is_enabled -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_pinch_resets_legacy_gesture_continuation -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "clipped_dissolve_is_binary_and_preserves_the_base_shape",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked clipped_dissolve_is_binary_and_preserves_the_base_shape -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut d = doc_white(40, 12);\n d.layers.push(solid_layer(\"base\", Rect::new(0, 0, 20, 12), [0.0, 0.0, 1.0, 1.0]));\n let mut clip = solid_layer(\"clip\", d.bounds(), [1.0, 0.0, 0.0, 1.0]);\n clip.clipped = true;\n clip.blend = BlendMode::Dissolve;\n clip.opacity = 0.6;\n clip.fill_opacity = 0.5;\n d.layers.push(clip);\n let mut red = 0;\n let mut blue = 0;\n for y in 0..12 {\n for x in 0..20 {",
|
|
"expected_assertions": [
|
|
" assert!(close4(p, [0.0, 0.0, 1.0, 1.0]), \"Dissolve must not interpolate: {p:?} at ({x},{y})\");\n blue += 1;\n }\n }\n assert!(close4(px(&d, 30, y), [1.0; 4]), \"outside the base the clip is invisible\");\n }\n assert!(red > 0 && blue > 0, \"Dissolve must expose both source and base: {red}/{blue}\");\n assert!((red as f32 / (red + blue) as f32 - 0.3).abs() < 0.1, \"coverage should follow 60% opacity \u00d7 50% fill: {red}/{blue}\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/194a8976cd6c14441222b287b9b4f4841a0eb2f9/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "clipped_dissolve_matches_whole_render_at_offset_regions_and_depths",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked clipped_dissolve_matches_whole_render_at_offset_regions_and_depths -- --nocapture",
|
|
"fixture_and_action_excerpt": " for fmt in [PixelFormat::RGBA8, PixelFormat::RGBA16, PixelFormat::RGBA32F] {\n let mut d = Document::new(\"coverage\", Size::new(32, 18), ColorMode::Rgb, fmt.sample);\n let bounds = Rect::new(-3, -2, 32, 18);\n let mut base = Layer::raster(\"base\", fmt);\n base.surface_mut().unwrap().fill_rect(bounds, &[0.0, 0.0, 1.0, 0.5]);\n d.layers.push(base);\n let mut clip = Layer::raster(\"clip\", fmt);\n clip.surface_mut().unwrap().fill_rect(bounds, &[1.0, 0.0, 0.0, 0.75]);\n clip.clipped = true;\n clip.blend = BlendMode::Dissolve;\n clip.opacity = 0.6;\n clip.fill_opacity = 0.5;",
|
|
"expected_assertions": [
|
|
" assert!(close4(part.get(x, y), whole.get(x, y)), \"{fmt:?}: region mismatch at ({x},{y})\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/194a8976cd6c14441222b287b9b4f4841a0eb2f9/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "groups_masks_and_clipping",
|
|
"path": "crates/gpu/tests/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked groups_masks_and_clipping -- --nocapture",
|
|
"fixture_and_action_excerpt": " let Some(mut g) = gpu() else { return };\n let child = |seed, mode| {\n let mut l = noise_layer(\"c\", PixelFormat::RGBA8, Rect::new(5, 5, 50, 40), seed, 0.0);\n l.blend = mode;\n l\n };\n for isolated in [false, true] {\n let mut d = base_doc(56, 44);\n let mut grp = Layer::group(\"g\", vec![child(11, BlendMode::Normal), child(12, BlendMode::Screen), child(13, BlendMode::Multiply)]);\n if isolated {\n grp.blend = BlendMode::Overlay;\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/194a8976cd6c14441222b287b9b4f4841a0eb2f9/crates/gpu/tests/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "native_rotate_event_reaches_canvas_when_trackpad_rotation_is_enabled",
|
|
"path": "crates/ui-egui/src/rotate_view.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked native_rotate_event_reaches_canvas_when_trackpad_rotation_is_enabled -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let mut enabled = None;\n let mut disabled = None;\n let raw = egui::RawInput { events: vec![Event::Rotate(std::f32::consts::FRAC_PI_6)], ..Default::default() };\n let mut output = ctx.run_ui(raw, |ui| {\n enabled = trackpad_delta(ui.ctx(), true);\n disabled = trackpad_delta(ui.ctx(), false);\n });\n output.textures_delta.clear();\n\n assert!(enabled.is_some_and(|degrees| (degrees - 30.0).abs() < 1e-3), \"{enabled:?}\");\n assert_eq!(disabled, None);",
|
|
"expected_assertions": [
|
|
" assert!(enabled.is_some_and(|degrees| (degrees - 30.0).abs() < 1e-3), \"{enabled:?}\");\n assert_eq!(disabled, None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/194a8976cd6c14441222b287b9b4f4841a0eb2f9/crates/ui-egui/src/rotate_view.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "native_pinch_resets_legacy_gesture_continuation",
|
|
"path": "crates/ui-egui/src/wheel_nav.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked native_pinch_resets_legacy_gesture_continuation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = Context::default();\n let mut legacy = RawInput { time: Some(1.0), events: vec![wheel(Vec2::new(0.0, 0.25), CTRL)], ..Default::default() };\n fold_legacy_pinch(&ctx, &mut legacy);\n assert!(matches!(legacy.events[0], Event::Zoom(_)));\n\n // Native magnification takes over before the synthetic gesture times out.\n let mut native = RawInput { time: Some(1.1), events: vec![Event::Zoom(1.1), wheel(Vec2::new(0.0, 0.25), CTRL)], ..Default::default() };\n fold_legacy_pinch(&ctx, &mut native);\n assert!(matches!(native.events[0], Event::Zoom(f) if (f - 1.1).abs() < 1e-5));\n assert!(matches!(native.events[1], Event::MouseWheel { .. }));\n\n // A notched mouse scroll must no longer inherit the previous pinch.",
|
|
"expected_assertions": [
|
|
" assert!(matches!(legacy.events[0], Event::Zoom(_)));\n\n // Native magnification takes over before the synthetic gesture times out.\n let mut native = RawInput { time: Some(1.1), events: vec![Event::Zoom(1.1), wheel(Vec2::new(0.0, 0.25), CTRL)], ..Default::default() };\n assert!(matches!(native.events[0], Event::Zoom(f) if (f - 1.1).abs() < 1e-5));\n assert!(matches!(native.events[1], Event::MouseWheel { .. }));\n\n // A notched mouse scroll must no longer inherit the previous pinch.\n let mut notch = RawInput { time: Some(1.12), events: vec![wheel(Vec2::new(0.0, 1.0), CTRL)], ..Default::default() };\n assert!(matches!(notch.events[0], Event::MouseWheel { .. }));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/194a8976cd6c14441222b287b9b4f4841a0eb2f9/crates/ui-egui/src/wheel_nav.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-7153",
|
|
"pr": 7153,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Synthetic smart object with Liquify and Gaussian Blur filters; record original parameters, pixels and history",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked smart_filter_edit_after_the_stack_changed_updates_nothing -- --nocapture"
|
|
],
|
|
"expected": "Double-click opens existing Liquify in its workspace with stored settings; commit updates intended filter rather than appending; Undo/Redo restores it; Cancel preserves parameters/pixels/history. Reordered stale stack refuses without history and says Reopen its dialog.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Automated stale-stack guard and native happy path/Cancel/undo are separate required subcases. Use supported controls for stale-target reproduction.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked smart_filter_edit_after_the_stack_changed_updates_nothing -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-7903",
|
|
"pr": 7903,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked rough_pastels_and_angled_strokes_respond_to_every_slider -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_makes_flat_shapes_with_clean_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_keeps_the_tone_of_surviving_islands_at_low_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_stack_around_a_cutout_is_tile_independent -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked douglas_peucker_keeps_only_points_off_the_line -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked lines_cross_where_they_should -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked rounding_off_keeps_an_open_chains_ends -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_keeps_its_four_corners_and_straight_sides -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_rounded_corner_is_squared_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_open_chain_ends_where_it_started_at_any_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked curves_pass_through_their_vertices -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked fitting_keeps_small_islands_and_their_winding -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked bounds_cover_every_point -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_edge_between_two_regions_is_one_chain_between_junctions -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_island_is_one_closed_chain -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_anti_aliased_edge_is_placed_inside_its_pixel -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_covers_its_area_exactly -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked shapes_cover_every_pixel_once_with_no_seams -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked edge_fidelity_changes_the_outlines -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked empty_images_stop_before_the_transpose_and_row_passes -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked filling_does_not_depend_on_the_tiling -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked noise_merges_into_neighbours_and_noise_apart_colours_are_one -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked components_are_four_connected_and_numbered_in_raster_order -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked small_regions_merge_into_the_neighbour_they_share_most_border_with -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked slivers_merge_though_they_are_large -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked paper_is_stretched_towards_black_and_white_and_keeps_its_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked local_colour_drifts_within_a_shape_but_never_crosses_a_cut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture"
|
|
],
|
|
"expected": "rough pastels and angled strokes respond to every slider; cutout makes flat shapes with clean edges; cutout keeps the tone of surviving islands at low fidelity; a stack around a cutout is tile independent; oklab round trips and marks the gamut; out of gamut colours lose strength not hue; smoothing flattens noise and keeps edges; the palette finds the pictures own colours; a tone of two different hues splits in two; an empty image still has a palette; douglas peucker keeps only points off the line; lines cross where they should; rounding off keeps an open chains ends; a square keeps its four corners and straight sides; a rounded corner is squared back; an open chain ends where it started at any fidelity; curves pass through their vertices; fitting keeps small islands and their winding; bounds cover every point; the edge between two regions is one chain between junctions; an island is one closed chain; an anti aliased edge is placed inside its pixel; a square covers its area exactly; shapes cover every pixel once with no seams; edge fidelity changes the outlines; empty images stop before the transpose and row passes; filling does not depend on the tiling; noise merges into neighbours and noise apart colours are one; components are four connected and numbered in raster order; small regions merge into the neighbour they share most border with; slivers merge though they are large; paper is stretched towards black and white and keeps its hue; local colour drifts within a shape but never crosses a cut; transposing twice gives the image back; find returns the root and shortens the path",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked rough_pastels_and_angled_strokes_respond_to_every_slider -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_makes_flat_shapes_with_clean_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_keeps_the_tone_of_surviving_islands_at_low_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_stack_around_a_cutout_is_tile_independent -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked douglas_peucker_keeps_only_points_off_the_line -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked lines_cross_where_they_should -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked rounding_off_keeps_an_open_chains_ends -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_keeps_its_four_corners_and_straight_sides -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_rounded_corner_is_squared_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_open_chain_ends_where_it_started_at_any_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked curves_pass_through_their_vertices -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked fitting_keeps_small_islands_and_their_winding -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked bounds_cover_every_point -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_edge_between_two_regions_is_one_chain_between_junctions -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_island_is_one_closed_chain -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_anti_aliased_edge_is_placed_inside_its_pixel -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_covers_its_area_exactly -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked shapes_cover_every_pixel_once_with_no_seams -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked edge_fidelity_changes_the_outlines -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked empty_images_stop_before_the_transpose_and_row_passes -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked filling_does_not_depend_on_the_tiling -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked noise_merges_into_neighbours_and_noise_apart_colours_are_one -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked components_are_four_connected_and_numbered_in_raster_order -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked small_regions_merge_into_the_neighbour_they_share_most_border_with -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked slivers_merge_though_they_are_large -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked paper_is_stretched_towards_black_and_white_and_keeps_its_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked local_colour_drifts_within_a_shape_but_never_crosses_a_cut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "rough_pastels_and_angled_strokes_respond_to_every_slider",
|
|
"path": "crates/algo/src/artistic_fx.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked rough_pastels_and_angled_strokes_respond_to_every_slider -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #879: these smeared or drowned the image in texture, and some sliders did nothing.\n use crate::GalleryFilter as G;\n let b = Rect::new(0, 0, 56, 40);\n let s = pattern(SampleType::F32);\n let run = |e: &GalleryEffect, tile: i32| {\n let fp = FilterParams::FilterGallery { effects: vec![e.clone()] };\n apply_tiled(&s, &fp, b, b, None, tile, Some(b)).read_region(b)\n };\n for f in [G::RoughPastels, G::AngledStrokes, G::Cutout] {\n let base = run(&GalleryEffect::new(f), 256);\n for prm in f.params() {\n let crate::GalleryParamKind::Range { min, max, .. } = prm.kind else { continue };",
|
|
"expected_assertions": [
|
|
" assert_ne!(a, base, \"{} {} = {v} changed nothing\", f.key(), prm.key);\n let t = run(&e, 16);\n let worst = a.iter().zip(&t).map(|(x, y)| (x - y).abs()).fold(0.0, f32::max);\n assert!(worst < 1e-3, \"{} {} = {v} differs across tilings by {worst}\", f.key(), prm.key);\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/artistic_fx.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cutout_makes_flat_shapes_with_clean_edges",
|
|
"path": "crates/algo/src/artistic_fx.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked cutout_makes_flat_shapes_with_clean_edges -- --nocapture",
|
|
"fixture_and_action_excerpt": " // It used to posterize every pixel after a blur: noise survived as speckle, edges were\n // ragged and smooth gradients banded instead of becoming flat paper.\n let noisy: Vec<Vec<f32>> = (0..32).map(|y| (0..64).map(|x| if x < 32 { 0.2 } else { 0.8 } + (hash01(x, y, 0, 7) - 0.5) * 0.16).collect()).collect();\n let out = cutout_on(&noisy, &[]);\n for (x0, x1) in [(2, 28), (36, 62)] {\n let vals: Vec<f32> = (2..30).flat_map(|y| out[y][x0..x1].to_vec()).collect();\n let spread = vals.iter().fold(f32::MIN, |a, &v| a.max(v)) - vals.iter().fold(f32::MAX, |a, &v| a.min(v));\n assert!(spread < 1e-4, \"a noisy area should be one flat tone, spread {spread}\");\n }\n // The cut is an anti-aliased pixel or two, not a blur.\n for y in 0..32 {\n let (lo, hi) = (out[y][16], out[y][48]);",
|
|
"expected_assertions": [
|
|
" assert!(spread < 1e-4, \"a noisy area should be one flat tone, spread {spread}\");\n }\n // The cut is an anti-aliased pixel or two, not a blur.\n for y in 0..32 {\n assert!(soft <= 2, \"row {y}: {soft} edge pixels\");\n }\n // A ramp becomes `numberOfLevels` flat steps (the palette is the image's own colours, so\n // one may go to the wide flat margins and merge as noise).\n assert!(tones.len() <= levels as usize && tones.len() + 1 >= levels as usize, \"levels {levels}: tones {tones:?}\");\n assert!(tones.windows(2).all(|t| t[0] < t[1]), \"levels {levels}: tones {tones:?}\");\n }\n // Edge Simplicity drops specks.\n let speck: Vec<Vec<f32>> = (0..32).map(|y| (0..32).map(|x| if (15..18).contains(&x) && (15..18).contains(&y) { 0.9 } else { 0.2 }).collect()).collect();\n assert!(detailed[16][16] - detailed[2][2] > 0.5, \"the speck should survive at simplicity 0\");\n assert!((simple[16][16] - simple[2][2]).abs() < 1e-4, \"the speck should go at simplicity 10\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/artistic_fx.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cutout_keeps_the_tone_of_surviving_islands_at_low_fidelity",
|
|
"path": "crates/algo/src/artistic_fx.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked cutout_keeps_the_tone_of_surviving_islands_at_low_fidelity -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (size, simplicity) in [(2, 0.0), (3, 2.0), (4, 0.0), (4, 2.0), (6, 2.0)] {\n let rows: Vec<Vec<f32>> =\n (0..32).map(|y| (0..32).map(|x| if (12..12 + size).contains(&x) && (12..12 + size).contains(&y) { 0.9 } else { 0.2 }).collect()).collect();\n let reference = cutout_on(&rows, &[(\"edgeSimplicity\", simplicity), (\"edgeFidelity\", 2.0)]);\n let centre = 12 + size / 2;\n for fidelity in [1.0, 1.5, 2.0] {\n let out = cutout_on(&rows, &[(\"edgeSimplicity\", simplicity), (\"edgeFidelity\", fidelity)]);\n assert!(\n size == 2 || (out[centre][centre] - reference[centre][centre]).abs() < 0.02,\n \"{size}x{size}, simplicity {simplicity}, fidelity {fidelity}: {} vs {}\",\n out[centre][centre],\n reference[centre][centre]",
|
|
"expected_assertions": [
|
|
" assert!(\n size == 2 || (out[centre][centre] - reference[centre][centre]).abs() < 0.02,\n \"{size}x{size}, simplicity {simplicity}, fidelity {fidelity}: {} vs {}\",\n out[centre][centre],\n assert!(out[centre][centre] - out[2][2] > 0.5, \"the island keeps its contrast\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/artistic_fx.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_stack_around_a_cutout_is_tile_independent",
|
|
"path": "crates/algo/src/artistic_fx.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_stack_around_a_cutout_is_tile_independent -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Effects before a Cutout are traced with it over the whole image; effects after it run\n // per tile on the filled-in shapes.\n use crate::GalleryFilter as G;\n let b = Rect::new(0, 0, 56, 40);\n let s = pattern(SampleType::F32);\n let fp =\n FilterParams::FilterGallery { effects: vec![GalleryEffect::new(G::Spatter), GalleryEffect::new(G::Cutout), GalleryEffect::new(G::GlowingEdges)] };\n let a = apply_tiled(&s, &fp, b, b, None, 256, Some(b)).read_region(b);\n let t = apply_tiled(&s, &fp, b, b, None, 16, Some(b)).read_region(b);\n let worst = a.iter().zip(&t).map(|(x, y)| (x - y).abs()).fold(0.0, f32::max);\n assert!(worst < 1e-3, \"differs across tilings by {worst}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(worst < 1e-3, \"differs across tilings by {worst}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/artistic_fx.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "oklab_round_trips_and_marks_the_gamut",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"fixture_and_action_excerpt": " let white = oklab([1.0, 1.0, 1.0]);\n assert!((white[0] - 1.0).abs() < 1e-3 && white[1].abs() < 1e-3 && white[2].abs() < 1e-3, \"{white:?}\");\n assert!(oklab([0.0, 0.0, 0.0])[0].abs() < 1e-6);\n for p in [[0.2, 0.5, 0.9], [0.95, 0.1, 0.3], [0.5, 0.5, 0.5], [0.0, 1.0, 0.0]] {\n let back = srgb(oklab(p)).unwrap_or([-1.0; 3]);\n assert!(dist2(back, p) < 1e-6, \"{p:?} came back as {back:?}\");\n }\n // Very light and very colourful: no sRGB colour is that.\n assert_eq!(srgb([0.95, 0.3, 0.0]), None);\n }",
|
|
"expected_assertions": [
|
|
" assert!((white[0] - 1.0).abs() < 1e-3 && white[1].abs() < 1e-3 && white[2].abs() < 1e-3, \"{white:?}\");\n assert!(oklab([0.0, 0.0, 0.0])[0].abs() < 1e-6);\n for p in [[0.2, 0.5, 0.9], [0.95, 0.1, 0.3], [0.5, 0.5, 0.5], [0.0, 1.0, 0.0]] {\n let back = srgb(oklab(p)).unwrap_or([-1.0; 3]);\n assert!(dist2(back, p) < 1e-6, \"{p:?} came back as {back:?}\");\n }\n // Very light and very colourful: no sRGB colour is that.\n assert_eq!(srgb([0.95, 0.3, 0.0]), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "out_of_gamut_colours_lose_strength_not_hue",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (l, a, b) = (0.95, 0.3, 0.1);\n let c = in_gamut(l, a, b);\n let lab = oklab(c);\n assert!((lab[0] - l).abs() < 0.01, \"lightness kept: {lab:?}\");\n let chroma = (lab[1] * lab[1] + lab[2] * lab[2]).sqrt();\n assert!(chroma > 0.01 && chroma < (a * a + b * b).sqrt(), \"weaker but still coloured: {chroma}\");\n assert!((lab[2] / lab[1] - b / a).abs() < 0.05, \"same hue: {lab:?}\");\n // In gamut it is just the conversion.\n assert_eq!(in_gamut(0.6, 0.02, -0.03), srgb([0.6, 0.02, -0.03]).unwrap_or_default());\n }",
|
|
"expected_assertions": [
|
|
" assert!((lab[0] - l).abs() < 0.01, \"lightness kept: {lab:?}\");\n let chroma = (lab[1] * lab[1] + lab[2] * lab[2]).sqrt();\n assert!(chroma > 0.01 && chroma < (a * a + b * b).sqrt(), \"weaker but still coloured: {chroma}\");\n assert!((lab[2] / lab[1] - b / a).abs() < 0.05, \"same hue: {lab:?}\");\n // In gamut it is just the conversion.\n assert_eq!(in_gamut(0.6, 0.02, -0.03), srgb([0.6, 0.02, -0.03]).unwrap_or_default());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "smoothing_flattens_noise_and_keeps_edges",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (40usize, 20usize);\n let lab = noisy(w, h, 0.02, |x| if x < 20 { [0.3, 0.0, 0.0] } else { [0.8, 0.0, 0.0] });\n let out = smooth(lab.clone(), w, h, 2);\n let spread = |v: &[Px], xs: std::ops::Range<usize>| {\n let l: Vec<f32> = (0..h).flat_map(|y| xs.clone().map(move |x| y * w + x)).map(|i| v[i][0]).collect();\n let mean = l.iter().sum::<f32>() / l.len() as f32;\n (l.iter().map(|v| (v - mean).powi(2)).sum::<f32>() / l.len() as f32).sqrt()\n };\n assert!(spread(&out, 2..16) < spread(&lab, 2..16) / 2.0, \"noise kept: {} vs {}\", spread(&out, 2..16), spread(&lab, 2..16));\n // The step stays a step: the pixels either side of it keep most of their difference.\n let step = (0..h).map(|y| out[y * w + 20][0] - out[y * w + 19][0]).sum::<f32>() / h as f32;\n assert!(step > 0.4, \"edge blurred to {step}\");",
|
|
"expected_assertions": [
|
|
" assert!(spread(&out, 2..16) < spread(&lab, 2..16) / 2.0, \"noise kept: {} vs {}\", spread(&out, 2..16), spread(&lab, 2..16));\n // The step stays a step: the pixels either side of it keep most of their difference.\n let step = (0..h).map(|y| out[y * w + 20][0] - out[y * w + 19][0]).sum::<f32>() / h as f32;\n assert!(step > 0.4, \"edge blurred to {step}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_palette_finds_the_pictures_own_colours",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (60usize, 20usize);\n let (dark, light) = ([0.25, 0.02, -0.03], [0.75, -0.04, 0.05]);\n let lab = noisy(w, h, 0.01, |x| if x < 30 { dark } else { light });\n // Asked for up to six, it gives two: colours only noise apart are one.\n let p = palette(&lab, 6);\n assert_eq!(p.len(), 2, \"{p:?}\");\n for c in [dark, light] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.02), \"{c:?} not in {p:?}\");\n }\n assert_eq!(nearest(&p, dark), nearest(&p, [0.27, 0.0, -0.02]));\n assert_ne!(nearest(&p, dark), nearest(&p, light));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(p.len(), 2, \"{p:?}\");\n for c in [dark, light] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.02), \"{c:?} not in {p:?}\");\n }\n assert_eq!(nearest(&p, dark), nearest(&p, [0.27, 0.0, -0.02]));\n assert_ne!(nearest(&p, dark), nearest(&p, light));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_tone_of_two_different_hues_splits_in_two",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A dark tone and a light one, the light one half blue and half pink: two levels give\n // three colours, or the blue and pink areas would be one shape of their grey average.\n let (w, h) = (60usize, 20usize);\n let (dark, blue, pink) = ([0.2, 0.0, 0.0], [0.7, -0.03, -0.1], [0.7, 0.12, 0.0]);\n let lab = noisy(w, h, 0.005, |x| {\n if x < 30 {\n dark\n } else if x < 45 {\n blue\n } else {\n pink\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(p.len(), 3, \"{p:?}\");\n for c in [dark, blue, pink] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.03), \"{c:?} not in {p:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_empty_image_still_has_a_palette",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert_eq!(palette(&[], 4).len(), 1);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(palette(&[], 4).len(), 1);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "douglas_peucker_keeps_only_points_off_the_line",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked douglas_peucker_keeps_only_points_off_the_line -- --nocapture",
|
|
"fixture_and_action_excerpt": " // An L, slightly ragged: only its corner is further from the end-to-end line than the\n // tolerance, and the two arms are straight within it.\n let wobble = |i: usize| 0.05 * (i % 2) as f32;\n let p: Vec<Pt> = (0..9).map(|i| if i <= 4 { [i as f32, wobble(i)] } else { [4.0 + wobble(i), (i - 4) as f32] }).collect();\n let mut marks = vec![false; p.len()];\n simplify(&p, 0, 8, 0.5, &mut marks);\n assert_eq!(marks.iter().filter(|m| **m).count(), 1, \"{marks:?}\");\n assert!(marks[4]);\n let mut marks = vec![false; p.len()];\n simplify(&p, 0, 8, 3.0, &mut marks);\n assert!(marks.iter().all(|m| !m), \"under the tolerance nothing is kept\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(marks.iter().filter(|m| **m).count(), 1, \"{marks:?}\");\n assert!(marks[4]);\n let mut marks = vec![false; p.len()];\n simplify(&p, 0, 8, 3.0, &mut marks);\n assert!(marks.iter().all(|m| !m), \"under the tolerance nothing is kept\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "lines_cross_where_they_should",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked lines_cross_where_they_should -- --nocapture",
|
|
"fixture_and_action_excerpt": " let q = intersect([0.0, 0.0], [1.0, 1.0], [0.0, 2.0], [1.0, 1.0]);\n assert!(q.is_some_and(|q| close(q, [1.0, 1.0])), \"{q:?}\");\n assert_eq!(intersect([0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [2.0, 1.0]), None);\n }",
|
|
"expected_assertions": [
|
|
" assert!(q.is_some_and(|q| close(q, [1.0, 1.0])), \"{q:?}\");\n assert_eq!(intersect([0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [2.0, 1.0]), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "rounding_off_keeps_an_open_chains_ends",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked rounding_off_keeps_an_open_chains_ends -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p: Vec<Pt> = (0..12).map(|i| [i as f32, if i % 2 == 0 { 0.0 } else { 1.0 }]).collect();\n let r = round_off(&p, false, 3);\n assert_eq!((r[0], r[11]), (p[0], p[11]));\n assert!(r[5][1] > 0.2 && r[5][1] < 0.8, \"the zigzag is averaged out: {:?}\", r[5]);\n assert_eq!(round_off(&p, false, 0), p);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!((r[0], r[11]), (p[0], p[11]));\n assert!(r[5][1] > 0.2 && r[5][1] < 0.8, \"the zigzag is averaged out: {:?}\", r[5]);\n assert_eq!(round_off(&p, false, 0), p);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_square_keeps_its_four_corners_and_straight_sides",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_square_keeps_its_four_corners_and_straight_sides -- --nocapture",
|
|
"fixture_and_action_excerpt": " let out = fit(&square(), true, &settings(2.0));\n for c in [[2.0, 2.0], [12.0, 2.0], [12.0, 12.0], [2.0, 12.0]] {\n assert!(out.iter().any(|p| close(*p, c)), \"corner {c:?} lost: {out:?}\");\n }\n let on_side = |p: &Pt| [p[0] - 2.0, p[0] - 12.0, p[1] - 2.0, p[1] - 12.0].iter().any(|d| d.abs() < 1e-3);\n assert!(out.iter().all(on_side), \"{out:?}\");\n assert!(out.len() < 10, \"the sides are simplified to their ends: {out:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(out.iter().any(|p| close(*p, c)), \"corner {c:?} lost: {out:?}\");\n }\n let on_side = |p: &Pt| [p[0] - 2.0, p[0] - 12.0, p[1] - 2.0, p[1] - 12.0].iter().any(|d| d.abs() < 1e-3);\n assert!(out.iter().all(on_side), \"{out:?}\");\n assert!(out.len() < 10, \"the sides are simplified to their ends: {out:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_rounded_corner_is_squared_back",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_rounded_corner_is_squared_back -- --nocapture",
|
|
"fixture_and_action_excerpt": " // The pixels cut the corner at (12, 2): the outline goes (11, 2), (12, 3) instead.\n let mut p = square();\n p[10] = [11.5, 2.5];\n let out = fit(&p, true, &settings(2.0));\n assert!(out.iter().any(|q| close(*q, [12.0, 2.0])), \"{out:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(out.iter().any(|q| close(*q, [12.0, 2.0])), \"{out:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_open_chain_ends_where_it_started_at_any_fidelity",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_open_chain_ends_where_it_started_at_any_fidelity -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p: Vec<Pt> = (0..30).map(|i| [i as f32, (i as f32 / 5.0).sin() * 4.0 + 0.3 * (i % 3) as f32]).collect();\n for f in [1.0, 2.0, 3.0] {\n let out = fit(&p, false, &settings(f));\n assert_eq!((out.first(), out.last()), (p.first(), p.last()), \"fidelity {f}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.first(), out.last()), (p.first(), p.last()), \"fidelity {f}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "curves_pass_through_their_vertices",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked curves_pass_through_their_vertices -- --nocapture",
|
|
"fixture_and_action_excerpt": " let v = [[0.0, 0.0], [4.0, 3.0], [8.0, 0.0], [12.0, 4.0]];\n let out = curves(&v, &[false; 4], false);\n for p in v {\n assert!(out.iter().any(|q| close(*q, p)), \"{p:?} missed: {out:?}\");\n }\n assert!(out.len() > 8, \"flattened into steps: {}\", out.len());\n // Between two corners a segment is straight.\n assert_eq!(curves(&v, &[true; 4], false), v.to_vec());\n }",
|
|
"expected_assertions": [
|
|
" assert!(out.iter().any(|q| close(*q, p)), \"{p:?} missed: {out:?}\");\n }\n assert!(out.len() > 8, \"flattened into steps: {}\", out.len());\n // Between two corners a segment is straight.\n assert_eq!(curves(&v, &[true; 4], false), v.to_vec());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "fitting_keeps_small_islands_and_their_winding",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked fitting_keeps_small_islands_and_their_winding -- --nocapture",
|
|
"fixture_and_action_excerpt": " use super::super::edges::follow_edges;\n let (w, h) = (32, 32);\n for size in [2, 3, 4, 6] {\n let reg: Vec<u32> = (0..w * h).map(|i| u32::from((12..12 + size).contains(&(i % w)) && (12..12 + size).contains(&(i / w)))).collect();\n let colours = [[0.2; 3], [0.9; 3]];\n let c: Vec<_> = reg.iter().map(|&r| colours[r as usize]).collect();\n let (chains, _) = follow_edges(®, &colours, &c, w, h);\n let (pts, closed) = chains.iter().find(|(_, closed)| *closed).unwrap();\n assert!(*closed);\n let area = |p: &[Pt]| p.iter().zip(p.iter().cycle().skip(1)).map(|(a, b)| a[0] as f64 * b[1] as f64 - b[0] as f64 * a[1] as f64).sum::<f64>() / 2.0;\n let original = area(pts);\n for simplicity in [0.0, 2.0] {",
|
|
"expected_assertions": [
|
|
" assert!(*closed);\n let area = |p: &[Pt]| p.iter().zip(p.iter().cycle().skip(1)).map(|(a, b)| a[0] as f64 * b[1] as f64 - b[0] as f64 * a[1] as f64).sum::<f64>() / 2.0;\n let original = area(pts);\n for simplicity in [0.0, 2.0] {\n assert!(\n fitted * original > 0.0 && fitted.abs() >= original.abs() * 0.5,\n \"{size}x{size}, simplicity {simplicity}, fidelity {fidelity}: {original} -> {fitted}\"\n );\n assert_eq!(out.first(), out.last(), \"fallbacks must close the loop for the fill\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "bounds_cover_every_point",
|
|
"path": "crates/algo/src/cutout/curves.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked bounds_cover_every_point -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert_eq!(bounds(&[[1.0, 5.0], [-2.0, 3.0], [4.0, 4.0]]), [-2.0, 3.0, 4.0, 5.0]);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(bounds(&[[1.0, 5.0], [-2.0, 3.0], [4.0, 4.0]]), [-2.0, 3.0, 4.0, 5.0]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/curves.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_edge_between_two_regions_is_one_chain_between_junctions",
|
|
"path": "crates/algo/src/cutout/edges.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked the_edge_between_two_regions_is_one_chain_between_junctions -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (reg, colours, w, h) = regions(&[\"000111\", \"000111\", \"000111\", \"000111\"]);\n let c: Vec<Px> = reg.iter().map(|&r| colours[r as usize]).collect();\n let (chains, sides) = follow_edges(®, &colours, &c, w, h);\n let inner = between(&chains, &sides, 0, 1);\n assert_eq!(inner.len(), 1, \"{chains:?}\");\n let (pts, closed) = &inner[0];\n assert!(!closed);\n // From junction to junction (where it meets the canvas edge), one point per crack.\n let ends = [pts[0], pts[pts.len() - 1]];\n assert!(ends.contains(&[3.0, 0.0]) && ends.contains(&[3.0, 4.0]), \"{pts:?}\");\n assert_eq!(pts.len(), 2 + 4);\n assert!(pts.iter().all(|p| p[0] == 3.0), \"flat colours: the edge is on the crack: {pts:?}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(inner.len(), 1, \"{chains:?}\");\n let (pts, closed) = &inner[0];\n assert!(!closed);\n // From junction to junction (where it meets the canvas edge), one point per crack.\n let ends = [pts[0], pts[pts.len() - 1]];\n assert!(ends.contains(&[3.0, 0.0]) && ends.contains(&[3.0, 4.0]), \"{pts:?}\");\n assert_eq!(pts.len(), 2 + 4);\n assert!(pts.iter().all(|p| p[0] == 3.0), \"flat colours: the edge is on the crack: {pts:?}\");\n // Every crack between two regions, the canvas edge included, is in exactly one chain.\n let cracks: usize = chains.iter().map(|(p, closed)| p.len() - if *closed { 0 } else { 2 }).sum();\n assert_eq!(cracks, 4 + 2 * (w + h));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/edges.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_island_is_one_closed_chain",
|
|
"path": "crates/algo/src/cutout/edges.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_island_is_one_closed_chain -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (reg, colours, w, h) = regions(&[\"00000\", \"01100\", \"01100\", \"00000\"]);\n let c: Vec<Px> = reg.iter().map(|&r| colours[r as usize]).collect();\n let (chains, sides) = follow_edges(®, &colours, &c, w, h);\n let island = between(&chains, &sides, 0, 1);\n assert_eq!(island.len(), 1);\n assert!(island[0].1, \"closed\");\n assert_eq!(island[0].0.len(), 8, \"one point per crack around the 2x2 island\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(island.len(), 1);\n assert!(island[0].1, \"closed\");\n assert_eq!(island[0].0.len(), 8, \"one point per crack around the 2x2 island\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/edges.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_anti_aliased_edge_is_placed_inside_its_pixel",
|
|
"path": "crates/algo/src/cutout/edges.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_anti_aliased_edge_is_placed_inside_its_pixel -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Region 0 is black and region 1 white; the last column of region 0 is half white, so\n // the edge runs down the middle of that column.\n let (reg, _, w, h) = regions(&[\"000111\", \"000111\", \"000111\"]);\n let colours = vec![[0.0; 3], [1.0; 3]];\n let c: Vec<Px> = reg.iter().enumerate().map(|(i, &r)| if i % w == 2 { [0.5; 3] } else { colours[r as usize] }).collect();\n let (chains, sides) = follow_edges(®, &colours, &c, w, h);\n let inner = between(&chains, &sides, 0, 1);\n let pts = &inner[0].0;\n assert!(pts[1..pts.len() - 1].iter().all(|p| (p[0] - 2.5).abs() < 1e-5), \"{pts:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(pts[1..pts.len() - 1].iter().all(|p| (p[0] - 2.5).abs() < 1e-5), \"{pts:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/edges.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_square_covers_its_area_exactly",
|
|
"path": "crates/algo/src/cutout/fill.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_square_covers_its_area_exactly -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut acc = vec![0.0f32; 12 * 10];\n let sq = [[2.25, 2.5], [7.75, 2.5], [7.75, 6.5], [2.25, 6.5], [2.25, 2.5]];\n for s in sq.windows(2) {\n line_clipped(&mut acc, 12, 10, s[0], s[1]);\n }\n let mut total = 0.0;\n for y in 0..10 {\n let mut sum = 0.0;\n for x in 0..10 {\n sum += acc[y * 12 + x];\n total += sum.abs().min(1.0);\n }",
|
|
"expected_assertions": [
|
|
" assert!((total - 5.5 * 4.0).abs() < 1e-4, \"{total}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/fill.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shapes_cover_every_pixel_once_with_no_seams",
|
|
"path": "crates/algo/src/cutout/mod.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked shapes_cover_every_pixel_once_with_no_seams -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Blobs of four colours touching each other and the canvas edge, with T-junctions,\n // saddles and holes.\n let (w, h) = (48usize, 36usize);\n let pal = [[0.1, 0.1, 0.1], [0.9, 0.2, 0.2], [0.2, 0.7, 0.3], [0.95, 0.95, 0.9]];\n let c: Vec<Px> = (0..w * h)\n .map(|i| {\n let (x, y) = ((i % w) as f32, (i / w) as f32);\n let k = ((x / 7.0).sin() + (y / 5.0).cos() + (x * y / 90.0).sin()).abs() * 1.6;\n pal[(k as usize).min(3)]\n })\n .collect();\n let r = Rect::new(0, 0, w as i32, h as i32);",
|
|
"expected_assertions": [
|
|
" assert!(t.regions.len() > 4);\n let cov = coverage(&t, r);\n let worst = cov.iter().map(|v| (v - 1.0).abs()).fold(0.0, f32::max);\n assert!(worst < 1e-3, \"coverage off by {worst}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/mod.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "edge_fidelity_changes_the_outlines",
|
|
"path": "crates/algo/src/cutout/mod.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked edge_fidelity_changes_the_outlines -- --nocapture",
|
|
"fixture_and_action_excerpt": " // It used to set only which bends count as corners: on smooth shapes 0.5% of pixels\n // changed from fidelity 1 to 2 and 2.8% from 2 to 3 (now about 9% and 5%).\n // Large smooth shapes, as in a photo: few corners, long curved outlines.\n let (w, h) = (160usize, 120usize);\n let pal = [[0.1, 0.1, 0.1], [0.9, 0.3, 0.2], [0.3, 0.6, 0.9]];\n let c: Vec<Px> = (0..w * h)\n .map(|i| {\n let (x, y) = ((i % w) as f32, (i / w) as f32);\n let k = ((x / 17.0).sin() * 1.3 + (y / 13.0).cos() + (x * y / 900.0).sin()).abs();\n pal[(k as usize).min(2)]\n })\n .collect();",
|
|
"expected_assertions": [
|
|
" assert!(changed(&loose, &normal) > 0.04, \"fidelity 1 vs 2: {}\", changed(&loose, &normal));\n assert!(changed(&normal, &tight) > 0.04, \"fidelity 2 vs 3: {}\", changed(&normal, &tight));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/mod.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "empty_images_stop_before_the_transpose_and_row_passes",
|
|
"path": "crates/algo/src/cutout/mod.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked empty_images_stop_before_the_transpose_and_row_passes -- --nocapture",
|
|
"fixture_and_action_excerpt": " for r in [Rect::new(0, 0, 0, 4), Rect::new(0, 0, 4, 0), Rect::new(0, 0, 0, 0)] {\n let t = trace(&[], r, &settings(4, 2.0, 1.0));\n assert!(t.regions.is_empty());\n assert!(t.chains.is_empty());\n assert!(t.field.is_empty());\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(t.regions.is_empty());\n assert!(t.chains.is_empty());\n assert!(t.field.is_empty());\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/mod.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "filling_does_not_depend_on_the_tiling",
|
|
"path": "crates/algo/src/cutout/mod.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked filling_does_not_depend_on_the_tiling -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (40usize, 30usize);\n let c: Vec<Px> = (0..w * h).map(|i| if ((i % w) / 6 + (i / w) / 5) % 3 == 0 { [0.8, 0.3, 0.1] } else { [0.1, 0.3, 0.7] }).collect();\n let r = Rect::new(10, 20, 10 + w as i32, 20 + h as i32);\n let t = trace(&c, r, &settings(3, 1.0, 2.0));\n let whole = t.render(r);\n for tile in [Rect::new(10, 20, 23, 31), Rect::new(23, 31, 50, 50), Rect::new(37, 20, 50, 33)] {\n let part = t.render(tile);\n for y in tile.y0..tile.y1 {\n for x in tile.x0..tile.x1 {\n let a = whole[((y - r.y0) as usize) * w + (x - r.x0) as usize];\n let b = part[((y - tile.y0) as usize) * tile.width() as usize + (x - tile.x0) as usize];\n assert!(dist2(a, b) < 1e-8, \"({x}, {y}): {a:?} vs {b:?}\");",
|
|
"expected_assertions": [
|
|
" assert!(dist2(a, b) < 1e-8, \"({x}, {y}): {a:?} vs {b:?}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/mod.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "noise_merges_into_neighbours_and_noise_apart_colours_are_one",
|
|
"path": "crates/algo/src/cutout/mod.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked noise_merges_into_neighbours_and_noise_apart_colours_are_one -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (32usize, 32usize);\n let c: Vec<Px> = (0..w * h)\n .map(|i| {\n let v = 0.3 + crate::photo_util::hash01((i % w) as i64, (i / w) as i64, 5) * 0.06;\n if (11..14).contains(&(i % w)) && (11..14).contains(&(i / w)) { [0.9, 0.9, 0.9] } else { [v, v, v] }\n })\n .collect();\n let r = Rect::new(0, 0, w as i32, h as i32);\n assert_eq!(trace(&c, r, &settings(6, 0.0, 2.0)).regions.len(), 2, \"the speck stays at simplicity 0\");\n assert_eq!(trace(&c, r, &settings(6, 10.0, 2.0)).regions.len(), 1, \"the speck merges at simplicity 10\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(trace(&c, r, &settings(6, 0.0, 2.0)).regions.len(), 2, \"the speck stays at simplicity 0\");\n assert_eq!(trace(&c, r, &settings(6, 10.0, 2.0)).regions.len(), 1, \"the speck merges at simplicity 10\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/mod.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "components_are_four_connected_and_numbered_in_raster_order",
|
|
"path": "crates/algo/src/cutout/regions.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked components_are_four_connected_and_numbered_in_raster_order -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (l, w, h) = labels(&[\"aab\", \"abb\", \"bba\"]);\n let (comp, n) = components(&l, w, h);\n // The top-left `a`s, the `b`s (one area), then the lone `a` (touching the first only\n // diagonally), in the order their first pixels come.\n assert_eq!(n, 3);\n assert_eq!(comp, vec![0, 0, 1, 0, 1, 1, 1, 1, 2]);\n // A U shape: both arms are found as separate runs first and joined further down.\n let (l, w, h) = labels(&[\"a.a\", \"a.a\", \"aaa\"]);\n let (comp, n) = components(&l, w, h);\n assert_eq!(n, 2);\n assert_eq!(comp[0], comp[2]);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(n, 3);\n assert_eq!(comp, vec![0, 0, 1, 0, 1, 1, 1, 1, 2]);\n // A U shape: both arms are found as separate runs first and joined further down.\n let (l, w, h) = labels(&[\"a.a\", \"a.a\", \"aaa\"]);\n let (comp, n) = components(&l, w, h);\n assert_eq!(n, 2);\n assert_eq!(comp[0], comp[2]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/regions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "small_regions_merge_into_the_neighbour_they_share_most_border_with",
|
|
"path": "crates/algo/src/cutout/regions.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked small_regions_merge_into_the_neighbour_they_share_most_border_with -- --nocapture",
|
|
"fixture_and_action_excerpt": " let rows = [\"aaaaaaaa\", \"aaaaaaaa\", \"aacaaaaa\", \"aaccbbbb\", \"aaaabbbb\", \"aaaabbbb\", \"aaaabbbb\"];\n // At Edge Simplicity 0 every region is kept.\n assert_eq!(merged(&rows, 0.0).1.len(), 3);\n // At 1 (regions under four pixels merge) the three `c`s go into the `a`s, which they share seven\n // cracks with (one with the `b`s).\n let (reg, colours) = merged(&rows, 1.0);\n assert_eq!(colours.len(), 2);\n assert_eq!(reg[2 * 8 + 2], reg[0]);\n assert_ne!(reg[3 * 8 + 4], reg[0]);\n // A region's colour is the mean of its pixels: 37 `a`s (0.0) and 3 `c`s (0.5).\n let a = colours[reg[0] as usize][0];\n assert!((a - 1.5 / 40.0).abs() < 1e-6, \"{a}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(merged(&rows, 0.0).1.len(), 3);\n // At 1 (regions under four pixels merge) the three `c`s go into the `a`s, which they share seven\n // cracks with (one with the `b`s).\n let (reg, colours) = merged(&rows, 1.0);\n assert_eq!(colours.len(), 2);\n assert_eq!(reg[2 * 8 + 2], reg[0]);\n assert_ne!(reg[3 * 8 + 4], reg[0]);\n // A region's colour is the mean of its pixels: 37 `a`s (0.0) and 3 `c`s (0.5).\n let a = colours[reg[0] as usize][0];\n assert!((a - 1.5 / 40.0).abs() < 1e-6, \"{a}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/regions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "slivers_merge_though_they_are_large",
|
|
"path": "crates/algo/src/cutout/regions.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked slivers_merge_though_they_are_large -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A line one pixel wide between two areas: the blend along an edge, not a shape.\n let rows: Vec<String> = (0..40).map(|_| format!(\"{}c{}\", \"a\".repeat(10), \"b\".repeat(9))).collect();\n let rows: Vec<&str> = rows.iter().map(String::as_str).collect();\n assert_eq!(merged(&rows, 0.0).1.len(), 3, \"kept at Edge Simplicity 0\");\n let (_, colours) = merged(&rows, 4.0);\n assert_eq!(colours.len(), 2, \"40 pixels is over the 25 that merge at 4, but it is a sliver\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(merged(&rows, 0.0).1.len(), 3, \"kept at Edge Simplicity 0\");\n let (_, colours) = merged(&rows, 4.0);\n assert_eq!(colours.len(), 2, \"40 pixels is over the 25 that merge at 4, but it is a sliver\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/regions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "paper_is_stretched_towards_black_and_white_and_keeps_its_hue",
|
|
"path": "crates/algo/src/cutout/regions.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked paper_is_stretched_towards_black_and_white_and_keeps_its_hue -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Three regions: a dark and a light grey, and a mid-tone orange.\n let lab = [[0.35, 0.0, 0.0], [0.65, 0.0, 0.0], [0.5, 0.06, 0.05]];\n let reg: Vec<u32> = (0..300).map(|i| (i / 100) as u32).collect();\n let px: Vec<Px> = reg.iter().map(|&r| lab[r as usize]).collect();\n let paper: Vec<Px> = paper_colours(®, 3, &px).into_iter().map(oklab).collect();\n assert!(paper[0][0] < 0.25 && paper[1][0] > 0.75, \"{paper:?}\");\n assert!((paper[2][0] - 0.5).abs() < 0.05, \"a middle tone stays in the middle: {paper:?}\");\n assert!((paper[2][2] / paper[2][1] - 0.05 / 0.06).abs() < 0.05, \"hue kept: {paper:?}\");\n assert!(paper[0][1].abs() < 1e-3 && paper[0][2].abs() < 1e-3, \"grey stays grey: {paper:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(paper[0][0] < 0.25 && paper[1][0] > 0.75, \"{paper:?}\");\n assert!((paper[2][0] - 0.5).abs() < 0.05, \"a middle tone stays in the middle: {paper:?}\");\n assert!((paper[2][2] / paper[2][1] - 0.05 / 0.06).abs() < 0.05, \"hue kept: {paper:?}\");\n assert!(paper[0][1].abs() < 1e-3 && paper[0][2].abs() < 1e-3, \"grey stays grey: {paper:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/regions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "local_colour_drifts_within_a_shape_but_never_crosses_a_cut",
|
|
"path": "crates/algo/src/cutout/regions.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked local_colour_drifts_within_a_shape_but_never_crosses_a_cut -- --nocapture",
|
|
"fixture_and_action_excerpt": " // One light region, pink on the left and cream on the right, next to a blue one.\n let (w, h) = (30usize, 4usize);\n let reg: Vec<u32> = (0..w * h).map(|i| u32::from(i % w >= 20)).collect();\n let lab: Vec<Px> = (0..w * h)\n .map(|i| match i % w {\n 0..10 => [0.8, 0.08, 0.02],\n 10..20 => [0.8, 0.01, 0.04],\n _ => [0.4, -0.02, -0.12],\n })\n .collect();\n let paper = [srgb([0.8, 0.04, 0.03]).unwrap_or_default(), srgb([0.4, -0.02, -0.12]).unwrap_or_default()];\n let out: Vec<Px> = local_paper(®, &paper, &lab, w, h, 3.0).into_iter().map(oklab).collect();",
|
|
"expected_assertions": [
|
|
" assert!(left[1] > right[1] + 0.03, \"the pink side is pinker: {left:?} vs {right:?}\");\n assert!((left[0] - right[0]).abs() < 0.01, \"one lightness across the shape: {left:?} vs {right:?}\");\n assert!(edge[2] > 0.0, \"no blue from the next shape at the cut: {edge:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/regions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "transposing_twice_gives_the_image_back",
|
|
"path": "crates/algo/src/cutout/util.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (5usize, 3usize);\n let c: Vec<Px> = (0..w * h).map(|i| [i as f32, 0.0, 0.0]).collect();\n let t = transpose(&c, w, h);\n assert_eq!(t[1], c[w], \"the second value of the first column is the first of the second row\");\n assert_eq!(transpose(&t, h, w), c);\n let ids: Vec<u32> = (0..(w * h) as u32).collect();\n assert_eq!(transpose_u32(&ids, w, h), t.iter().map(|p| p[0] as u32).collect::<Vec<_>>());\n assert_eq!(transpose_u32(&transpose_u32(&ids, w, h), h, w), ids);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(t[1], c[w], \"the second value of the first column is the first of the second row\");\n assert_eq!(transpose(&t, h, w), c);\n let ids: Vec<u32> = (0..(w * h) as u32).collect();\n assert_eq!(transpose_u32(&ids, w, h), t.iter().map(|p| p[0] as u32).collect::<Vec<_>>());\n assert_eq!(transpose_u32(&transpose_u32(&ids, w, h), h, w), ids);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/util.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "find_returns_the_root_and_shortens_the_path",
|
|
"path": "crates/algo/src/cutout/util.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " // 4 -> 3 -> 2 -> 1 -> 0.\n let mut parent = vec![0, 0, 1, 2, 3];\n assert_eq!(find(&mut parent, 4), 0);\n assert_eq!(find(&mut parent, 0), 0);\n assert!(parent[4] < 3, \"the path was halved: {parent:?}\");\n assert!(parent.iter().all(|&p| p <= 2));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(find(&mut parent, 4), 0);\n assert_eq!(find(&mut parent, 0), 0);\n assert!(parent[4] < 3, \"the path was halved: {parent:?}\");\n assert!(parent.iter().all(|&p| p <= 2));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5c30699087b02edcaa23397a0f7076bf503be048/crates/algo/src/cutout/util.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8039",
|
|
"pr": 8039,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked softer_outer_glow_keeps_a_fading_tail_past_its_size -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked softer_outer_glow_margin_includes_its_tail_support -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked softer_outer_glow_program_keeps_the_tent_and_adds_a_distance_tail -- --nocapture"
|
|
],
|
|
"expected": "softer outer glow keeps a fading tail past its size; softer outer glow margin includes its tail support; softer outer glow program keeps the tent and adds a distance tail",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked softer_outer_glow_keeps_a_fading_tail_past_its_size -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked softer_outer_glow_margin_includes_its_tail_support -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked softer_outer_glow_program_keeps_the_tent_and_adds_a_distance_tail -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "softer_outer_glow_keeps_a_fading_tail_past_its_size",
|
|
"path": "crates/compose/src/effects.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked softer_outer_glow_keeps_a_fading_tail_past_its_size -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut shape = Map::new(220, 220, 0.0);\n for y in 0..shape.h {\n for x in 20..100 {\n shape.v[y * shape.w + x] = 1.0;\n }\n }\n let glow = Glow {\n common: photocraft_doc::FxCommon::new(BlendMode::Screen, 1.0),\n paint: FxPaint::Color(photocraft_color::Color::WHITE),\n technique: GlowTechnique::Softer,\n spread: 0.0,\n size: 60.0,",
|
|
"expected_assertions": [
|
|
" assert!(at(50) > 0.024, \"the softer shoulder should stay visible: {}\", at(50));\n assert!(at(60) > 1.0 / 255.0, \"the glow must retain a visible tail at its Size: {}\", at(60));\n assert!(at(62) > 0.5 / 255.0, \"the glow must extend beyond its Size: {}\", at(62));\n assert!(at(66) < 1e-6, \"the added tail should fade to zero: {}\", at(66));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5579cf5439856fed93f41a669a3fc9b56d5813cf/crates/compose/src/effects.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "softer_outer_glow_margin_includes_its_tail_support",
|
|
"path": "crates/compose/src/effects.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked softer_outer_glow_margin_includes_its_tail_support -- --nocapture",
|
|
"fixture_and_action_excerpt": " let glow = Glow {\n common: photocraft_doc::FxCommon::new(BlendMode::Screen, 1.0),\n paint: FxPaint::Color(photocraft_color::Color::WHITE),\n technique: GlowTechnique::Softer,\n spread: 0.0,\n size: 60.0,\n contour: Contour::Linear,\n anti_alias: false,\n range: 0.5,\n jitter: 0.0,\n noise: 0.0,\n source: GlowSource::Edge,",
|
|
"expected_assertions": [
|
|
" assert_eq!(margin(&layer), 68);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5579cf5439856fed93f41a669a3fc9b56d5813cf/crates/compose/src/effects.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "softer_outer_glow_program_keeps_the_tent_and_adds_a_distance_tail",
|
|
"path": "crates/gpu/src/fx.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked softer_outer_glow_program_keeps_the_tent_and_adds_a_distance_tail -- --nocapture",
|
|
"fixture_and_action_excerpt": " let effect = Effect::OuterGlow(photocraft_doc::Glow {\n common: FxCommon::new(BlendMode::Screen, 1.0),\n paint: photocraft_doc::FxPaint::Color(photocraft_color::Color::WHITE),\n technique: GlowTechnique::Softer,\n spread: 0.0,\n size: 60.0,\n contour: Contour::Linear,\n anti_alias: false,\n range: 0.5,\n jitter: 0.0,\n noise: 0.0,\n source: GlowSource::Edge,",
|
|
"expected_assertions": [
|
|
" assert_eq!(blur.len(), 2);\n for stage in blur {\n assert_eq!(stage.radius, kernel.0);\n assert_eq!(stage.lut.as_deref().unwrap(), kernel.1.as_slice());\n }\n let tail = p.stages.iter().find(|s| s.kernel == Kernel::MGlow).unwrap();\n assert_eq!(tail.a, Some(In::Field(FieldKind::Outside)));\n assert_eq!(tail.p0, [54.0, 6.0, 0.0025, 1.0]);\n assert!(p.stages.iter().any(|s| s.kernel == Kernel::MFinish && s.p0[0] == 2.0));\n assert!(p.fields.contains(&(FieldKind::Outside, reach_for(66.0))));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5579cf5439856fed93f41a669a3fc9b56d5813cf/crates/gpu/src/fx.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8191",
|
|
"pr": 8191,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture"
|
|
],
|
|
"expected": "oklab round trips and marks the gamut; out of gamut colours lose strength not hue; smoothing flattens noise and keeps edges; the palette finds the pictures own colours; a tone of two different hues splits in two; an empty image still has a palette; transposing twice gives the image back; find returns the root and shortens the path",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "oklab_round_trips_and_marks_the_gamut",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked oklab_round_trips_and_marks_the_gamut -- --nocapture",
|
|
"fixture_and_action_excerpt": " let white = oklab([1.0, 1.0, 1.0]);\n assert!((white[0] - 1.0).abs() < 1e-3 && white[1].abs() < 1e-3 && white[2].abs() < 1e-3, \"{white:?}\");\n assert!(oklab([0.0, 0.0, 0.0])[0].abs() < 1e-6);\n for p in [[0.2, 0.5, 0.9], [0.95, 0.1, 0.3], [0.5, 0.5, 0.5], [0.0, 1.0, 0.0]] {\n let back = srgb(oklab(p)).unwrap_or([-1.0; 3]);\n assert!(dist2(back, p) < 1e-6, \"{p:?} came back as {back:?}\");\n }\n // Very light and very colourful: no sRGB colour is that.\n assert_eq!(srgb([0.95, 0.3, 0.0]), None);\n }",
|
|
"expected_assertions": [
|
|
" assert!((white[0] - 1.0).abs() < 1e-3 && white[1].abs() < 1e-3 && white[2].abs() < 1e-3, \"{white:?}\");\n assert!(oklab([0.0, 0.0, 0.0])[0].abs() < 1e-6);\n for p in [[0.2, 0.5, 0.9], [0.95, 0.1, 0.3], [0.5, 0.5, 0.5], [0.0, 1.0, 0.0]] {\n let back = srgb(oklab(p)).unwrap_or([-1.0; 3]);\n assert!(dist2(back, p) < 1e-6, \"{p:?} came back as {back:?}\");\n }\n // Very light and very colourful: no sRGB colour is that.\n assert_eq!(srgb([0.95, 0.3, 0.0]), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "out_of_gamut_colours_lose_strength_not_hue",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked out_of_gamut_colours_lose_strength_not_hue -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (l, a, b) = (0.95, 0.3, 0.1);\n let c = in_gamut(l, a, b);\n let lab = oklab(c);\n assert!((lab[0] - l).abs() < 0.01, \"lightness kept: {lab:?}\");\n let chroma = (lab[1] * lab[1] + lab[2] * lab[2]).sqrt();\n assert!(chroma > 0.01 && chroma < (a * a + b * b).sqrt(), \"weaker but still coloured: {chroma}\");\n assert!((lab[2] / lab[1] - b / a).abs() < 0.05, \"same hue: {lab:?}\");\n // In gamut it is just the conversion.\n assert_eq!(in_gamut(0.6, 0.02, -0.03), srgb([0.6, 0.02, -0.03]).unwrap_or_default());\n }",
|
|
"expected_assertions": [
|
|
" assert!((lab[0] - l).abs() < 0.01, \"lightness kept: {lab:?}\");\n let chroma = (lab[1] * lab[1] + lab[2] * lab[2]).sqrt();\n assert!(chroma > 0.01 && chroma < (a * a + b * b).sqrt(), \"weaker but still coloured: {chroma}\");\n assert!((lab[2] / lab[1] - b / a).abs() < 0.05, \"same hue: {lab:?}\");\n // In gamut it is just the conversion.\n assert_eq!(in_gamut(0.6, 0.02, -0.03), srgb([0.6, 0.02, -0.03]).unwrap_or_default());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "smoothing_flattens_noise_and_keeps_edges",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked smoothing_flattens_noise_and_keeps_edges -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (40usize, 20usize);\n let lab = noisy(w, h, 0.02, |x| if x < 20 { [0.3, 0.0, 0.0] } else { [0.8, 0.0, 0.0] });\n let out = smooth(lab.clone(), w, h, 2);\n let spread = |v: &[Px], xs: std::ops::Range<usize>| {\n let l: Vec<f32> = (0..h).flat_map(|y| xs.clone().map(move |x| y * w + x)).map(|i| v[i][0]).collect();\n let mean = l.iter().sum::<f32>() / l.len() as f32;\n (l.iter().map(|v| (v - mean).powi(2)).sum::<f32>() / l.len() as f32).sqrt()\n };\n assert!(spread(&out, 2..16) < spread(&lab, 2..16) / 2.0, \"noise kept: {} vs {}\", spread(&out, 2..16), spread(&lab, 2..16));\n // The step stays a step: the pixels either side of it keep most of their difference.\n let step = (0..h).map(|y| out[y * w + 20][0] - out[y * w + 19][0]).sum::<f32>() / h as f32;\n assert!(step > 0.4, \"edge blurred to {step}\");",
|
|
"expected_assertions": [
|
|
" assert!(spread(&out, 2..16) < spread(&lab, 2..16) / 2.0, \"noise kept: {} vs {}\", spread(&out, 2..16), spread(&lab, 2..16));\n // The step stays a step: the pixels either side of it keep most of their difference.\n let step = (0..h).map(|y| out[y * w + 20][0] - out[y * w + 19][0]).sum::<f32>() / h as f32;\n assert!(step > 0.4, \"edge blurred to {step}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_palette_finds_the_pictures_own_colours",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked the_palette_finds_the_pictures_own_colours -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (60usize, 20usize);\n let (dark, light) = ([0.25, 0.02, -0.03], [0.75, -0.04, 0.05]);\n let lab = noisy(w, h, 0.01, |x| if x < 30 { dark } else { light });\n // Asked for up to six, it gives two: colours only noise apart are one.\n let p = palette(&lab, 6);\n assert_eq!(p.len(), 2, \"{p:?}\");\n for c in [dark, light] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.02), \"{c:?} not in {p:?}\");\n }\n assert_eq!(nearest(&p, dark), nearest(&p, [0.27, 0.0, -0.02]));\n assert_ne!(nearest(&p, dark), nearest(&p, light));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(p.len(), 2, \"{p:?}\");\n for c in [dark, light] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.02), \"{c:?} not in {p:?}\");\n }\n assert_eq!(nearest(&p, dark), nearest(&p, [0.27, 0.0, -0.02]));\n assert_ne!(nearest(&p, dark), nearest(&p, light));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_tone_of_two_different_hues_splits_in_two",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked a_tone_of_two_different_hues_splits_in_two -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A dark tone and a light one, the light one half blue and half pink: two levels give\n // three colours, or the blue and pink areas would be one shape of their grey average.\n let (w, h) = (60usize, 20usize);\n let (dark, blue, pink) = ([0.2, 0.0, 0.0], [0.7, -0.03, -0.1], [0.7, 0.12, 0.0]);\n let lab = noisy(w, h, 0.005, |x| {\n if x < 30 {\n dark\n } else if x < 45 {\n blue\n } else {\n pink\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(p.len(), 3, \"{p:?}\");\n for c in [dark, blue, pink] {\n assert!(p.iter().any(|q| dist2(*q, c).sqrt() < 0.03), \"{c:?} not in {p:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_empty_image_still_has_a_palette",
|
|
"path": "crates/algo/src/cutout/colour.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_empty_image_still_has_a_palette -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert_eq!(palette(&[], 4).len(), 1);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(palette(&[], 4).len(), 1);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/colour.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "transposing_twice_gives_the_image_back",
|
|
"path": "crates/algo/src/cutout/util.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked transposing_twice_gives_the_image_back -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (5usize, 3usize);\n let c: Vec<Px> = (0..w * h).map(|i| [i as f32, 0.0, 0.0]).collect();\n let t = transpose(&c, w, h);\n assert_eq!(t[1], c[w], \"the second value of the first column is the first of the second row\");\n assert_eq!(transpose(&t, h, w), c);\n let ids: Vec<u32> = (0..(w * h) as u32).collect();\n assert_eq!(transpose_u32(&ids, w, h), t.iter().map(|p| p[0] as u32).collect::<Vec<_>>());\n assert_eq!(transpose_u32(&transpose_u32(&ids, w, h), h, w), ids);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(t[1], c[w], \"the second value of the first column is the first of the second row\");\n assert_eq!(transpose(&t, h, w), c);\n let ids: Vec<u32> = (0..(w * h) as u32).collect();\n assert_eq!(transpose_u32(&ids, w, h), t.iter().map(|p| p[0] as u32).collect::<Vec<_>>());\n assert_eq!(transpose_u32(&transpose_u32(&ids, w, h), h, w), ids);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/util.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "find_returns_the_root_and_shortens_the_path",
|
|
"path": "crates/algo/src/cutout/util.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked find_returns_the_root_and_shortens_the_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " // 4 -> 3 -> 2 -> 1 -> 0.\n let mut parent = vec![0, 0, 1, 2, 3];\n assert_eq!(find(&mut parent, 4), 0);\n assert_eq!(find(&mut parent, 0), 0);\n assert!(parent[4] < 3, \"the path was halved: {parent:?}\");\n assert!(parent.iter().all(|&p| p <= 2));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(find(&mut parent, 4), 0);\n assert_eq!(find(&mut parent, 0), 0);\n assert!(parent[4] < 3, \"the path was halved: {parent:?}\");\n assert!(parent.iter().all(|&p| p <= 2));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/91e4cec43525ca739c05cff614701fbd3576e389/crates/algo/src/cutout/util.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8192",
|
|
"pr": 8192,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Synthetic label maps in cutout/regions.rs",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked components_are_four_connected_and_numbered_in_raster_order -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked small_regions_merge_into_the_neighbour_they_share_most_border_with -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked slivers_merge_though_they_are_large -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked local_colour_drifts_within_a_shape_but_never_crosses_a_cut -- --nocapture"
|
|
],
|
|
"expected": "Four-connected components have deterministic raster numbering; small regions choose the shared-border neighbour; narrow slivers merge despite area; colour variation never crosses a cut.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "The earlier Oklab test is supporting coverage, not the regions-stage oracle.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked components_are_four_connected_and_numbered_in_raster_order -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked small_regions_merge_into_the_neighbour_they_share_most_border_with -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked slivers_merge_though_they_are_large -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked local_colour_drifts_within_a_shape_but_never_crosses_a_cut -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-8193",
|
|
"pr": 8193,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Two-region boundaries, islands, antialiased edges, squares and open chains in cutout/edges.rs and curves.rs",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked the_edge_between_two_regions_is_one_chain_between_junctions -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_island_is_one_closed_chain -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_anti_aliased_edge_is_placed_inside_its_pixel -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_keeps_its_four_corners_and_straight_sides -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_open_chain_ends_where_it_started_at_any_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked fitting_keeps_small_islands_and_their_winding -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_makes_flat_shapes_with_clean_edges -- --nocapture"
|
|
],
|
|
"expected": "Shared boundaries are single chains; islands close; subpixel edge placement, square corners, open endpoints and winding survive fitting. Complete Cutout yields the asserted clean flat shapes.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Run after the complete #8191 \u2192 #8192 \u2192 #8193 \u2192 #7903 chain.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked the_edge_between_two_regions_is_one_chain_between_junctions -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_island_is_one_closed_chain -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_anti_aliased_edge_is_placed_inside_its_pixel -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked a_square_keeps_its_four_corners_and_straight_sides -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_open_chain_ends_where_it_started_at_any_fidelity -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked fitting_keeps_small_islands_and_their_winding -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked cutout_makes_flat_shapes_with_clean_edges -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-8903",
|
|
"pr": 8903,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked minified_pattern_is_filtered_not_aliased -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked pattern_fill_layers -- --nocapture"
|
|
],
|
|
"expected": "minified pattern is filtered not aliased; pattern fill layers",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked minified_pattern_is_filtered_not_aliased -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked pattern_fill_layers -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "minified_pattern_is_filtered_not_aliased",
|
|
"path": "crates/compose/src/pattern.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked minified_pattern_is_filtered_not_aliased -- --nocapture",
|
|
"fixture_and_action_excerpt": " // 1-px dark / light stripes (mean 0.5), shown at 25 %: every pixel covers 4 tile pixels.\n // The 0.125 px phase puts each pixel centre on a light tile pixel's centre, so a single\n // bilinear tap would return pure white.\n let mut s = Surface::new(PixelFormat::RGBA8);\n s.fill_rect(Rect::new(0, 0, 8, 8), &[1.0, 1.0, 1.0, 1.0]);\n for x in (0..8).step_by(2) {\n s.fill_rect(Rect::new(x, 0, x + 1, 8), &[0.0, 0.0, 0.0, 1.0]);\n }\n let t = Tile::new(&Pattern::new(\"stripes\", s, 8, 8)).unwrap();\n let place = Placement::new(Rect::EMPTY, false, (0.125, 0.0), 0.25, 0.0);\n let (u, _) = place.map(0.5, 0.5);\n assert_eq!(t.sample(u, 0.5)[0], 1.0, \"the single tap lands on a light stripe\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(t.sample(u, 0.5)[0], 1.0, \"the single tap lands on a light stripe\");\n for p in render(&t, &place, Rect::new(0, 0, 8, 1)) {\n assert!((p[0] - 0.5).abs() < 0.05, \"{p:?}\");\n }\n // 100 % stays exact.\n let one = Placement::new(Rect::EMPTY, false, (0.0, 0.0), 1.0, 0.0);\n assert_eq!((row[0][0], row[1][0]), (0.0, 1.0));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d387f52f1f2f5681b2c7d1c517aa5b5992c7bc88/crates/compose/src/pattern.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pattern_fill_layers",
|
|
"path": "crates/gpu/tests/it/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked pattern_fill_layers -- --nocapture",
|
|
"fixture_and_action_excerpt": " let Some(mut g) = gpu() else { return };\n let pat = checker_pattern();\n for (link, scale, angle, masked) in [(true, 1.0, 0.0, false), (false, 0.7, 25.0, true), (true, 1.6, -40.0, false), (true, 0.3, 10.0, false)] {\n let mut d = base_doc(70, 50);\n d.patterns.push(pat.clone());\n let fill = Fill::Pattern { name: pat.name.clone(), id: pat.id.clone(), scale, angle, link, phase: (3.0, -2.0) };\n let mut l = Layer::new(\"pat\", LayerContent::Fill(fill));\n l.opacity = 0.85;\n l.blend = BlendMode::Overlay;\n if masked {\n l.mask = Some(mask(Rect::new(5, 5, 60, 45), 61, 0.0));\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d387f52f1f2f5681b2c7d1c517aa5b5992c7bc88/crates/gpu/tests/it/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9472",
|
|
"pr": 9472,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked displace_psd_filter_with_only_a_map_path_renders_after_replace_contents -- --nocapture",
|
|
"cargo test -p photocraft-io --locked a_map_named_only_by_its_path_imports_as_map_path -- --nocapture"
|
|
],
|
|
"expected": "displace psd filter with only a map path renders after replace contents; a map named only by its path imports as map path",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked displace_psd_filter_with_only_a_map_path_renders_after_replace_contents -- --nocapture",
|
|
"cargo test -p photocraft-io --locked a_map_named_only_by_its_path_imports_as_map_path -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "displace_psd_filter_with_only_a_map_path_renders_after_replace_contents",
|
|
"path": "crates/engine/tests/it/smart_psd.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked displace_psd_filter_with_only_a_map_path_renders_after_replace_contents -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_psd::descriptor::{Descriptor, Id, UnicodeString, Value};\n let dir = std::env::temp_dir().join(format!(\"pcraft-9162-{}\", std::process::id()));\n std::fs::create_dir_all(&dir).unwrap();\n let png = |name: &str, size: (u32, u32), c: [f32; 4]| {\n let d = Document::with_background(\n \"m\",\n photocraft_geom::Size::new(size.0, size.1),\n photocraft_color::ColorMode::Rgb,\n photocraft_color::SampleType::U8,\n photocraft_color::Color::rgba(c[0], c[1], c[2], c[3]),\n );\n let path = dir.join(name);",
|
|
"expected_assertions": [
|
|
" assert_eq!(out[\"warnings\"], json!([]), \"depth {depth}\");\n let cache = smart(&s2.active().unwrap().doc).1.cache.unwrap();\n // 10 % of 128 px at full map contrast: the design (x 8..80) moves 12.8 px left.\n let alpha = |x: i32| cache.pixel(x, 30)[3];\n assert!(alpha(2) > 0.99 && alpha(75) < 0.01, \"depth {depth}: {} {}\", alpha(2), alpha(75));\n }\n std::fs::remove_dir_all(&dir).ok();\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4bab657cd4fb4a91ced44d3721e63a002ca5068c/crates/engine/tests/it/smart_psd.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_map_named_only_by_its_path_imports_as_map_path",
|
|
"path": "crates/io/src/displace_map.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked a_map_named_only_by_its_path_imports_as_map_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let with_file = |file: Value| {\n let mut i = item(Vec::new());\n let mut f = get_desc(&i, \"Fltr\").unwrap().clone();\n f.items.retain(|(k, _)| !k.is(MAP_KEY));\n set(&mut f, \"DspF\", file);\n set(&mut i, \"Fltr\", Value::Descriptor(f));\n i\n };\n let src = with_file(pth(\"C:\\\\maps\\\\repro-map.psd\"));\n let f = filter_from_item(&src);\n assert_eq!(f.command, COMMAND);\n assert_eq!(f.params[\"mapPath\"], json!(\"C:\\\\maps\\\\repro-map.psd\"));",
|
|
"expected_assertions": [
|
|
" assert_eq!(f.command, COMMAND);\n assert_eq!(f.params[\"mapPath\"], json!(\"C:\\\\maps\\\\repro-map.psd\"));\n assert!(embedded_map(&f.params).is_none());\n assert_eq!(item_for_filter(&f).unwrap(), src, \"written back as it was\");\n let mut moved = f.clone();\n moved.params[\"mapPath\"] = json!(\"/elsewhere/map.png\");\n assert!(item_for_filter(&moved).is_err(), \"another map path has no place in the template\");\n let mut no_path = f.clone();\n no_path.params.as_object_mut().unwrap().remove(\"mapPath\");\n assert!(item_for_filter(&no_path).is_err(), \"a path-only template needs its mapPath, or the PSD names a map the render never read\");\n // A record whose size field disagrees with its units, or without the final NUL.\n let mut wrong_size = pth(\"map.psd\");\n if let Value::Path(b) = &mut wrong_size {\n assert_eq!(filter_from_item(&src).command, UNSUPPORTED_FILTER);\n }\n // A damaged embedded map is never replaced by a readable path.\n let mut damaged = item(vec![0; 4]);\n assert_eq!(filter_from_item(&damaged).command, UNSUPPORTED_FILTER);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4bab657cd4fb4a91ced44d3721e63a002ca5068c/crates/io/src/displace_map.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9509",
|
|
"pr": 9509,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked full_coverage_adjustment_keeps_its_result_over_huge_hdr_values -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked reused_render_matches_previous_allocating_stack -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked mixing_through_a_selection_matches_sampling_it_per_pixel -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked full_coverage_keeps_the_edit_over_huge_hdr_values -- --nocapture"
|
|
],
|
|
"expected": "full coverage adjustment keeps its result over huge hdr values; reused render matches previous allocating stack; mixing through a selection matches sampling it per pixel; full coverage keeps the edit over huge hdr values",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked full_coverage_adjustment_keeps_its_result_over_huge_hdr_values -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked reused_render_matches_previous_allocating_stack -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked mixing_through_a_selection_matches_sampling_it_per_pixel -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked full_coverage_keeps_the_edit_over_huge_hdr_values -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "full_coverage_adjustment_keeps_its_result_over_huge_hdr_values",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked full_coverage_adjustment_keeps_its_result_over_huge_hdr_values -- --nocapture",
|
|
"fixture_and_action_excerpt": " for v in [1.0e6_f32, 1.0e8, -1.0e6] {\n let mut d = Document::new(\"hdr\", Size::new(2, 2), ColorMode::Rgb, SampleType::F32);\n let mut base = Layer::raster(\"b\", PixelFormat::RGBA32F);\n base.surface_mut().unwrap().fill_rect(Rect::new(0, 0, 2, 2), &[v, v, v, 1.0]);\n let look = Adjustment::ColorLookup { name: \"half\".into(), lut: Some(std::sync::Arc::new(vec![0.5; 24])), size: 2, tetrahedral: false, dither: false };\n d.layers = vec![base, Layer::new(\"look\", LayerContent::Adjustment(look))];\n let got = px(&d, 0, 0);\n for c in &got[..3] {\n assert!((c - 0.5).abs() < 1e-6, \"{v}: {got:?}\");\n }\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!((c - 0.5).abs() < 1e-6, \"{v}: {got:?}\");\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d78d7493d3f0b6e760c88de969ac810e9bc5d910/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reused_render_matches_previous_allocating_stack",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked reused_render_matches_previous_allocating_stack -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {\n let mut doc = Document::new(\"equivalence\", Size::new(513, 7), ColorMode::Rgb, depth);\n let rect = doc.bounds();\n for (name, color) in [(\"bottom\", [0.2, 0.4, 0.8, 1.0]), (\"top\", [1.5, -0.25, 0.6, 0.5])] {\n let mut layer = Layer::raster(name, doc.pixel_format());\n layer.surface_mut().unwrap().fill_rect(rect, &color);\n doc.layers.push(layer);\n }\n let mut levels = Adjustment::identity_levels();\n if let Adjustment::Levels { master, .. } = &mut levels {\n master.gamma = 1.4;\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d78d7493d3f0b6e760c88de969ac810e9bc5d910/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "mixing_through_a_selection_matches_sampling_it_per_pixel",
|
|
"path": "crates/engine/src/pixels_tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked mixing_through_a_selection_matches_sampling_it_per_pixel -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A rectangle across tile edges (negative x included), a selection with fractional\n // coverage, untouched tiles (default coverage) and a 16-bit as well as an 8-bit layer.\n let r = Rect::new(-300, 200, 330, 290);\n let gray32 = PixelFormat { mode: ColorMode::Grayscale, sample: SampleType::F32, alpha: false };\n for sel_fmt in [PixelFormat::GRAY8, PixelFormat::GRAYA8, gray32] {\n let mut sel = Surface::new(sel_fmt);\n sel.fill_rect(Rect::new(-260, 210, 40, 280), &vec![0.6; sel_fmt.channels()]);\n for x in 0..120 {\n sel.write_pixel(x * 2, 230 + x % 40, &vec![x as f32 / 119.0; sel_fmt.channels()]);\n }\n for fmt in [PixelFormat::RGBA8, PixelFormat::RGBA16] {\n let n = (r.width() * r.height()) as usize;",
|
|
"expected_assertions": [
|
|
" assert_eq!(mix_through_selection(&fmt, r, &orig, &edited, Some(&sel)), expected, \"{sel_fmt:?} over {fmt:?}\");\n }\n }\n // Without a selection the edit is taken whole; an empty rectangle mixes nothing.\n assert_eq!(mix_through_selection(&fmt, Rect::new(0, 0, 1, 1), &[[0.0; 4]], &px, None), enc[..m].to_vec());\n assert!(mix_through_selection(&fmt, Rect::EMPTY, &[], &[], None).is_empty());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d78d7493d3f0b6e760c88de969ac810e9bc5d910/crates/engine/src/pixels_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "full_coverage_keeps_the_edit_over_huge_hdr_values",
|
|
"path": "crates/engine/src/pixels_tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked full_coverage_keeps_the_edit_over_huge_hdr_values -- --nocapture",
|
|
"fixture_and_action_excerpt": " let fmt = PixelFormat::RGBA32F;\n for (o, a) in [(1.0e8_f32, 0.5_f32), (1.0e6, 0.1), (-1.0e6, 0.9)] {\n let out = mix_through_selection(&fmt, Rect::new(0, 0, 1, 1), &[[o, o, o, 1.0]], &[[a, a, a, 1.0]], None);\n assert_eq!(out[..3], [a, a, a], \"{a} over {o}\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(out[..3], [a, a, a], \"{a} over {o}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d78d7493d3f0b6e760c88de969ac810e9bc5d910/crates/engine/src/pixels_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9512",
|
|
"pr": 9512,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked adjustment_fill_changes_the_special_blend_modes -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked special_eight_fill_on_adjustment_layers_matches_cpu -- --nocapture"
|
|
],
|
|
"expected": "adjustment fill changes the special blend modes; special eight fill on adjustment layers matches cpu",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked adjustment_fill_changes_the_special_blend_modes -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked special_eight_fill_on_adjustment_layers_matches_cpu -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "adjustment_fill_changes_the_special_blend_modes",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked adjustment_fill_changes_the_special_blend_modes -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (mode, want) in [(BlendMode::ColorDodge, [80, 160, 240]), (BlendMode::LinearBurn, [13, 77, 141])] {\n let mut d = Document::with_background(\"fill\", Size::new(1, 1), ColorMode::Rgb, SampleType::U8, Color::WHITE);\n let mut base = Layer::raster(\"b\", PixelFormat::RGBA8);\n base.surface_mut().unwrap().fill_rect(Rect::new(0, 0, 1, 1), &[64.0 / 255.0, 128.0 / 255.0, 192.0 / 255.0, 1.0]);\n let look = Adjustment::ColorLookup { name: \"half\".into(), lut: Some(std::sync::Arc::new(vec![0.5; 24])), size: 2, tetrahedral: false, dither: false };\n let mut adj = Layer::new(\"look\", LayerContent::Adjustment(look));\n adj.blend = mode;\n adj.fill_opacity = 0.4;\n d.layers.push(base);\n d.layers.push(adj);\n let got = px(&d, 0, 0);\n let got: Vec<i32> = got[..3].iter().map(|v| (v * 255.0).round() as i32).collect();",
|
|
"expected_assertions": [
|
|
" assert!(got.iter().zip(want).all(|(g, w)| (g - w).abs() <= 1), \"{mode:?}: {got:?} vs Photoshop {want:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/6c55561128caf5ac917eb3d174e8e7bb4bd48e23/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "special_eight_fill_on_adjustment_layers_matches_cpu",
|
|
"path": "crates/gpu/tests/it/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked special_eight_fill_on_adjustment_layers_matches_cpu -- --nocapture",
|
|
"fixture_and_action_excerpt": " let Some(mut g) = gpu() else { return };\n let special = [\n BlendMode::ColorBurn,\n BlendMode::LinearBurn,\n BlendMode::ColorDodge,\n BlendMode::LinearDodge,\n BlendMode::VividLight,\n BlendMode::LinearLight,\n BlendMode::HardMix,\n BlendMode::Difference,\n ];\n for mode in special {",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/6c55561128caf5ac917eb3d174e8e7bb4bd48e23/crates/gpu/tests/it/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9584",
|
|
"pr": 9584,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked blend_if_16_bit_cutoffs_follow_photoshops_steps -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked blend_if_gray_follows_photoshops_weights_and_rounding -- --nocapture"
|
|
],
|
|
"expected": "blend if 16 bit cutoffs follow photoshops steps; blend if gray follows photoshops weights and rounding",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked blend_if_16_bit_cutoffs_follow_photoshops_steps -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked blend_if_gray_follows_photoshops_weights_and_rounding -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "blend_if_16_bit_cutoffs_follow_photoshops_steps",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked blend_if_16_bit_cutoffs_follow_photoshops_steps -- --nocapture",
|
|
"fixture_and_action_excerpt": " let shown = |v16: u16, black: u8, white: u8| {\n let v = f32::from(v16) / 65535.0;\n let mut d = Document::new(\"t\", Size::new(1, 1), ColorMode::Rgb, SampleType::U16);\n let layer16 = |name: &str, c: [f32; 4]| {\n let mut l = Layer::raster(name, PixelFormat::RGBA16);\n l.surface_mut().unwrap().fill_rect(Rect::new(0, 0, 1, 1), &c);\n l\n };\n d.layers.push(layer16(\"under\", [v, v, v, 1.0]));\n let mut l = layer16(\"top\", [1.0, 1.0, 1.0, 1.0]);\n l.blend_if.set(3, [FULL, range([black, black], [white, white])]);\n d.layers.push(l);",
|
|
"expected_assertions": [
|
|
" assert!(shown(at(step), c, 255), \"black {c}: step {step} shows\");\n assert!(!shown(at(step - 1), c, 255), \"black {c}: step {} hides\", step - 1);\n assert!(shown(at(step), 0, c), \"white {c}: step {step} shows\");\n assert!(!shown(at(step + 1), 0, c), \"white {c}: step {} hides\", step + 1);\n }\n assert!(shown(32895, 128, 255) && !shown(32894, 128, 255), \"the reporter's RGB16 boundary\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/fc0f7b1132f799b5bba7be642c9047499d95a887/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blend_if_gray_follows_photoshops_weights_and_rounding",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked blend_if_gray_follows_photoshops_weights_and_rounding -- --nocapture",
|
|
"fixture_and_action_excerpt": " let shown = |rgb: [u8; 3], black: u8, white: u8| {\n let mut d = Document::new(\"t\", Size::new(1, 1), ColorMode::Rgb, SampleType::U8);\n let c = rgb.map(|v| f32::from(v) / 255.0);\n d.layers.push(solid_layer(\"under\", Rect::new(0, 0, 1, 1), [c[0], c[1], c[2], 1.0]));\n let mut l = solid_layer(\"top\", Rect::new(0, 0, 1, 1), [1.0, 1.0, 1.0, 1.0]);\n l.blend_if.set(0, [FULL, range([black, black], [white, white])]);\n d.layers.push(l);\n px(&d, 0, 0)[0] > 0.999 && px(&d, 0, 0)[2] > 0.999\n };\n // (colour hidden by a black point at `cut`, the next colour shown), single channels.\n for (cut, below, at) in [\n (20, [65, 0, 0], [66, 0, 0]),",
|
|
"expected_assertions": [
|
|
" assert!(!shown(below, cut, 255), \"{below:?} hidden by black {cut}\");\n assert!(shown(at, cut, 255), \"{at:?} shown by black {cut}\");\n }\n // The reporter's mixed colours, and the white point's half-down rounding.\n assert!(shown([123, 126, 151], 128, 255), \"127.85 is 128\");\n assert!(shown([120, 129, 149], 0, 128), \"128.5 is 128\");\n assert!(!shown([121, 129, 149], 0, 128), \"128.8 is 129\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/fc0f7b1132f799b5bba7be642c9047499d95a887/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9589",
|
|
"pr": 9589,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked adjustment_blend_if_judges_the_result_before_opacity -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked blend_if -- --nocapture"
|
|
],
|
|
"expected": "adjustment blend if judges the result before opacity; blend if",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked adjustment_blend_if_judges_the_result_before_opacity -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked blend_if -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "adjustment_blend_if_judges_the_result_before_opacity",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked adjustment_blend_if_judges_the_result_before_opacity -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (black, white, want) in [(150u8, 255u8, [115, 128, 140]), (0, 150, [64, 128, 192])] {\n let mut d = Document::with_background(\"bi\", Size::new(1, 1), ColorMode::Rgb, SampleType::U8, Color::WHITE);\n d.layers.push(solid_layer(\"base\", Rect::new(0, 0, 1, 1), [64.0 / 255.0, 128.0 / 255.0, 192.0 / 255.0, 1.0]));\n let mut inv = Layer::new(\"invert\", LayerContent::Adjustment(Adjustment::Invert));\n inv.opacity = 0.4;\n inv.blend_if.set(1, [range([black, black], [white, white]), FULL]);\n d.layers.push(inv);\n let got: Vec<i32> = px(&d, 0, 0)[..3].iter().map(|v| (v * 255.0).round() as i32).collect();\n assert!(got.iter().zip(want).all(|(g, w)| (g - w).abs() <= 1), \"black {black} white {white}: {got:?} vs Photoshop {want:?}\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(got.iter().zip(want).all(|(g, w)| (g - w).abs() <= 1), \"black {black} white {white}: {got:?} vs Photoshop {want:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da157945077190e550b53a5e14b0536f62761292/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blend_if",
|
|
"path": "crates/gpu/tests/it/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked blend_if -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::BlendRange;\n let Some(mut g) = gpu() else { return };\n let r = |b0: u8, b1: u8, w0: u8, w1: u8| BlendRange { black: [b0, b1], white: [w0, w1] };\n // (name, entry, [this layer, underlying], has a hard point)\n let cases: [(&str, usize, [BlendRange; 2], bool); 7] = [\n (\"gray this hard\", 0, [r(90, 90, 255, 255), BlendRange::FULL], true),\n (\"gray under split\", 0, [BlendRange::FULL, r(30, 140, 150, 230)], false),\n (\"red both\", 1, [r(0, 60, 200, 200), r(20, 20, 180, 250)], true),\n (\"red both split\", 1, [r(0, 60, 190, 230), r(10, 50, 180, 250)], false),\n (\"green white split\", 2, [r(0, 0, 100, 220), BlendRange::FULL], false),\n (\"blue under hard\", 3, [BlendRange::FULL, r(128, 128, 255, 255)], true),\n (\"everything hidden\", 0, [r(255, 255, 0, 0), BlendRange::FULL], true),",
|
|
"expected_assertions": [
|
|
" assert!(hits.prefix_hits > 0, \"{depth:?} {name}: the edit above reuses the lower stack\");\n\n // Masked, with channel restrictions.\n let mut m = l.clone();"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da157945077190e550b53a5e14b0536f62761292/crates/gpu/tests/it/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9595",
|
|
"pr": 9595,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked pass_through_group_with_blend_if_is_isolated -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked pass_through_group_with_blend_if_is_isolated -- --nocapture"
|
|
],
|
|
"expected": "pass through group with blend if is isolated; pass through group with blend if is isolated",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked pass_through_group_with_blend_if_is_isolated -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked pass_through_group_with_blend_if_is_isolated -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "pass_through_group_with_blend_if_is_isolated",
|
|
"path": "crates/compose/src/tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked pass_through_group_with_blend_if_is_isolated -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (gated, want) in [(true, [64, 128, 192]), (false, [191, 127, 63])] {\n let mut d = Document::with_background(\"pt\", Size::new(1, 1), ColorMode::Rgb, SampleType::U8, Color::WHITE);\n d.layers.push(solid_layer(\"base\", Rect::new(0, 0, 1, 1), [64.0 / 255.0, 128.0 / 255.0, 192.0 / 255.0, 1.0]));\n let mut g = Layer::group(\"group\", vec![Layer::new(\"invert\", LayerContent::Adjustment(Adjustment::Invert))]);\n g.blend = BlendMode::PassThrough;\n if gated {\n g.blend_if.set(1, [FULL, range([0, 0], [110, 110])]);\n }\n d.layers.push(g);\n let got: Vec<i32> = px(&d, 0, 0)[..3].iter().map(|v| (v * 255.0).round() as i32).collect();\n assert!(got.iter().zip(want).all(|(g, w)| (g - w).abs() <= 1), \"Blend If {gated}: {got:?} vs Photoshop {want:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(got.iter().zip(want).all(|(g, w)| (g - w).abs() <= 1), \"Blend If {gated}: {got:?} vs Photoshop {want:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/75fa71a4f55a098061b12d91508b514565ab8dcf/crates/compose/src/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pass_through_group_with_blend_if_is_isolated",
|
|
"path": "crates/gpu/tests/it/parity.rs",
|
|
"package": "photocraft-gpu",
|
|
"command": "cargo test -p photocraft-gpu --locked pass_through_group_with_blend_if_is_isolated -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::BlendRange;\n let Some(mut g) = gpu() else { return };\n for gated in [true, false] {\n let mut d = base_doc(64, 48);\n d.layers[0] = noise_layer(\"bg\", PixelFormat::RGBA8, Rect::from_xywh(0, 0, 64, 48), 5, 1.0);\n let mut grp = Layer::group(\"group\", vec![Layer::new(\"inv\", LayerContent::Adjustment(Adjustment::Invert))]);\n grp.blend = BlendMode::PassThrough;\n if gated {\n grp.blend_if.set(1, [BlendRange::FULL, BlendRange { black: [0, 0], white: [110, 110] }]);\n }\n d.layers.push(grp);\n check(&mut g, &d, &format!(\"pass-through group, Blend If {gated}\"));",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/75fa71a4f55a098061b12d91508b514565ab8dcf/crates/gpu/tests/it/parity.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9651",
|
|
"pr": 9651,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked matches_scalar_sharpen_bit_for_bit_across_layouts_edges_and_hdr -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked empty_channel_layout_remains_empty -- --nocapture"
|
|
],
|
|
"expected": "matches scalar sharpen bit for bit across layouts edges and hdr; empty channel layout remains empty",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked matches_scalar_sharpen_bit_for_bit_across_layouts_edges_and_hdr -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked empty_channel_layout_remains_empty -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "matches_scalar_sharpen_bit_for_bit_across_layouts_edges_and_hdr",
|
|
"path": "crates/algo/tests/it/retouch_sharpen_exact.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked matches_scalar_sharpen_bit_for_bit_across_layouts_edges_and_hdr -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (w, h) in [(1, 1), (3, 7), (37, 29)] {\n for ch in 1..=5 {\n for alpha in std::iter::once(None).chain((0..ch).map(Some)) {\n let data: Vec<f32> = (0..w * h * ch)\n .map(|i| if Some(i % ch) == alpha { [0.0, 1e-8, 0.25, 0.75, 1.0][(i / ch) % 5] } else { ((i * 73 + 19) % 113) as f32 / 17.0 - 2.0 })\n .collect();\n for win in [(0, 0, w, h), (w / 2, h / 2, w, h), (0, 0, 1, 1), (0, 0, 0, h)] {\n for amount in [0.0, 0.5, 1.0, 2.5] {\n for protect_detail in [false, true] {\n let expected = scalar_local_sharpen(&data, w, h, ch, alpha, win, amount, protect_detail);\n let actual = local_sharpen(&data, w, h, ch, alpha, win, amount, protect_detail);\n assert_eq!(actual.len(), expected.len());",
|
|
"expected_assertions": [
|
|
" assert_eq!(actual.len(), expected.len());\n for (i, (a, b)) in actual.iter().zip(&expected).enumerate() {\n assert_eq!(\n a.to_bits(),\n b.to_bits(),\n \"{w}x{h} ch={ch} alpha={alpha:?} win={win:?} amount={amount} protect={protect_detail} sample={i}\""
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/67666bdf72a58066df868868cef82e5b9cc838de/crates/algo/tests/it/retouch_sharpen_exact.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "empty_channel_layout_remains_empty",
|
|
"path": "crates/algo/tests/it/retouch_sharpen_exact.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked empty_channel_layout_remains_empty -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert!(local_sharpen(&[], 5, 5, 0, None, (0, 0, 5, 5), 1.0, true).is_empty());\n}",
|
|
"expected_assertions": [
|
|
" assert!(local_sharpen(&[], 5, 5, 0, None, (0, 0, 5, 5), 1.0, true).is_empty());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/67666bdf72a58066df868868cef82e5b9cc838de/crates/algo/tests/it/retouch_sharpen_exact.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9703",
|
|
"pr": 9703,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked a_new_adjustment_or_fill_layer_shows_its_settings_until_the_mask_thumbnail_is_clicked -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked adjustment_names_target_contents_instead_of_masks -- --nocapture"
|
|
],
|
|
"expected": "a new adjustment or fill layer shows its settings until the mask thumbnail is clicked; adjustment names target contents instead of masks",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked a_new_adjustment_or_fill_layer_shows_its_settings_until_the_mask_thumbnail_is_clicked -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked adjustment_names_target_contents_instead_of_masks -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "a_new_adjustment_or_fill_layer_shows_its_settings_until_the_mask_thumbnail_is_clicked",
|
|
"path": "crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_new_adjustment_or_fill_layer_shows_its_settings_until_the_mask_thumbnail_is_clicked -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (command, settings) in [(\"layer.newAdjustmentLayer.curves\", Some(\"Reset to defaults\")), (\"layer.newFillLayer.solidColor\", None)] {\n let mut s = photocraft_engine::Session::new();\n s.execute(\"file.new\", json!({\"width\": 200, \"height\": 100})).unwrap();\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n let mut h = harness(s, 0, 1.0, 290.0);\n let ctx = h.ctx.clone();\n let (req, _rx) = crate::control::ControlRequest::new(\"ui.set\", json!({\"dock\": {\"collapsed\": [\"color\", \"history\", \"navigator\"]}}));\n crate::control::handle(h.state_mut(), &ctx, &req);\n h.state_mut().run(command, json!({})).unwrap();\n h.run_steps(6);\n let id = h.state().session.active().unwrap().active_layer.unwrap().0;\n assert!(h.state().ui.mask_target, \"{command}: the new mask is targeted\");",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.mask_target, \"{command}: the new mask is targeted\");\n assert_eq!(crate::canvas::paint_target(h.state()), json!(\"mask\"), \"{command}: painting edits the mask\");\n assert!(h.query_all_by_label(\"Density\").next().is_none(), \"{command}: Properties shows the layer, not its mask\");\n if let Some(label) = settings {\n assert!(h.query_all_by_label(label).next().is_some(), \"{command}: its settings show\");\n }\n // Clicking the row (not a thumbnail) keeps the settings.\n let row = h.get_by_label(&layer(&h, id).name).rect().center();\n assert_eq!(h.state().ui.mask_target, command.starts_with(\"layer.newFillLayer.\"));\n assert!(!h.state().ui.vector_mask_target);\n assert!(h.query_all_by_label(\"Density\").next().is_none(), \"{command}: a row click keeps the settings\");\n // The mask thumbnail switches Properties to the mask.\n let r = mask_rect(&h, id, MaskKind::Pixel);\n click_with(&mut h, r.center(), Modifiers::NONE);\n assert!(h.state().ui.mask_target);\n assert!(h.query_all_by_label(\"Density\").next().is_some(), \"{command}: the mask thumbnail shows the mask controls\");\n if let Some(label) = settings {\n assert!(h.query_all_by_label(label).next().is_none());\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3605d30c38294c4d970e52f4a02f44f97e8bc1a9/crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "adjustment_names_target_contents_instead_of_masks",
|
|
"path": "crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked adjustment_names_target_contents_instead_of_masks -- --nocapture",
|
|
"fixture_and_action_excerpt": " for command in [\"layer.newAdjustmentLayer.hueSaturation\", \"layer.newAdjustmentLayer.curves\"] {\n for ppp in [1.0, 2.0] {\n let (mut s, _, other) = session();\n s.execute(command, json!({})).unwrap();\n let id = s.active().unwrap().active_layer.unwrap().0;\n let path = json!({\"subpaths\": [{\"knots\": [[20, 10], [120, 10], [120, 90], [20, 90]]}]});\n s.execute(\"layer.vectorMask.add\", json!({\"layer\": id, \"path\": path})).unwrap();\n let mut h = harness(s, 0, ppp, 360.0);\n for kind in [MaskKind::Pixel, MaskKind::Vector] {\n let at = mask_rect(&h, id, kind).center();\n click_with(&mut h, at, Modifiers::NONE);\n assert_eq!(h.state().ui.mask_target, kind == MaskKind::Pixel);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.mask_target, kind == MaskKind::Pixel);\n assert_eq!(h.state().ui.vector_mask_target, kind == MaskKind::Vector);\n let name = crate::layer_row_ui::recorded(&h.ctx).into_iter().find(|r| r.layer == id).unwrap().name.unwrap().center();\n click_with(&mut h, name, Modifiers::NONE);\n assert!(!h.state().ui.mask_target && !h.state().ui.vector_mask_target, \"{command} @{ppp}x after {kind:?}\");\n let thumb = crate::layer_row_ui::recorded(&h.ctx).into_iter().find(|r| r.layer == id).unwrap().thumbnail.unwrap();\n assert!(near(super::brackets(&h.ctx).unwrap(), thumb.expand(3.0)), \"the content thumbnail is selected\");\n assert_eq!(h.state().session.active().unwrap().active_layer.unwrap().0, id);\n }\n let name = crate::layer_row_ui::recorded(&h.ctx).into_iter().find(|r| r.layer == other).unwrap().name.unwrap().center();\n click_with(&mut h, name, Modifiers::NONE);\n assert_eq!(h.state().session.active().unwrap().active_layer.unwrap().0, id);\n assert!(!h.state().ui.mask_target && !h.state().ui.vector_mask_target, \"{command} @{ppp}x from another layer\");\n assert_eq!(crate::canvas::paint_target(h.state()), json!(\"mask\"));\n let content = layer(&h, id).content;\n h.state_mut().run(\"edit.fill\", json!({\"contents\": \"black\"})).unwrap();\n assert_eq!(layer(&h, id).content, content, \"filling must preserve the adjustment or fill content\");\n assert_eq!(layer(&h, id).mask.unwrap().surface.sample_channel(50, 50, 0), 0.0, \"Fill edits the mask\");\n assert!(!h.state().ui.mask_target && !h.state().ui.vector_mask_target, \"painting leaves the content thumbnail selected\");\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/3605d30c38294c4d970e52f4a02f44f97e8bc1a9/crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-1991",
|
|
"pr": 1991,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked automation_rejects_ambient_path_commands_and_preferences -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked json_actions_round_trip_preserves_metadata -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked reimport_after_changing_button_color_keeps_names_unique -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked parents_before_children_are_retargeted_and_reimport_is_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked invalid_json_params_and_nested_indices_fail_atomically -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked long_unicode_collision_names_remain_portable_and_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked loading_json_actions_uses_engine_import_and_selects_the_new_action -- --nocapture"
|
|
],
|
|
"expected": "automation rejects ambient path commands and preferences; json actions round trip preserves metadata; reimport after changing button color keeps names unique; parents before children are retargeted and reimport is idempotent; invalid json params and nested indices fail atomically; long unicode collision names remain portable and idempotent; loading json actions uses engine import and selects the new action",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked automation_rejects_ambient_path_commands_and_preferences -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked json_actions_round_trip_preserves_metadata -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked reimport_after_changing_button_color_keeps_names_unique -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked parents_before_children_are_retargeted_and_reimport_is_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked invalid_json_params_and_nested_indices_fail_atomically -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked long_unicode_collision_names_remain_portable_and_idempotent -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked loading_json_actions_uses_engine_import_and_selects_the_new_action -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "automation_rejects_ambient_path_commands_and_preferences",
|
|
"path": "crates/automation/src/workspace.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked automation_rejects_ambient_path_commands_and_preferences -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (id, params) in [\n (\"brush.presets.importAbr\", serde_json::json!({\"path\": \"/outside/set.abr\"})),\n (\"brush.presets.importImage\", serde_json::json!({\"path\": \"/outside/tip.png\"})),\n (\"gradient.presets.importGrd\", serde_json::json!({\"path\": \"/outside/set.grd\"})),\n (\"plugin.install\", serde_json::json!({\"path\": \"/outside/plugin.wasm\"})),\n (\"plugin.reload\", serde_json::json!({\"path\": \"/outside/plugins\"})),\n (\"plugin.reload\", serde_json::json!({})),\n (\"plugin.install\", serde_json::json!({\"path\": \" \"})),\n (\"swatches.import\", serde_json::json!({\"path\": \"/outside/set.aco\"})),\n (\"swatches.export\", serde_json::json!({\"path\": \"/outside/set.ase\"})),\n (\"actions.load\", serde_json::json!({\"path\": \"/outside/set.atn\"})),\n (\"actions.save\", serde_json::json!({\"path\": \"/outside/set.atn\"})),",
|
|
"expected_assertions": [
|
|
" assert!(authorize_engine_command(id, ¶ms).is_err(), \"{id}: {params}\");\n }\n for (id, params) in [\n (\"brush.presets.importAbr\", serde_json::json!({\"data\": \"QUJD\"})),\n assert!(authorize_engine_command(id, ¶ms).is_ok(), \"{id}: {params}\");\n }\n for path in [\n \"\",\n assert!(authorize_engine_command(\"prefs.set\", &serde_json::json!({\"path\": path, \"value\": {}})).is_err(), \"{path}\");\n }\n assert!(\n authorize_engine_command(\"prefs.set\", &serde_json::json!({\"values\": {\"interface.language\": \"fr\", \"historyLog.filePath\": \"/outside/log\"}})).is_err()\n );\n assert!(authorize_engine_command(\"prefs.set\", &serde_json::json!({\"path\": \"interface.language\", \"value\": \"fr\"})).is_ok());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/automation/src/workspace.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "json_actions_round_trip_preserves_metadata",
|
|
"path": "crates/engine/src/actions_cmds/json_file.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked json_actions_round_trip_preserves_metadata -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n let mut action = Action::new(\"Draw\", vec![(\"layer.new.layer\".into(), json!({}))]);\n action.disabled.insert(0);\n action.dialogs.insert(0);\n action.set = Some(\"Painting\".into());\n s.actions.list.push(action.clone());\n let exported = s.execute(\"actions.export\", json!({})).unwrap();\n s.actions.list.clear();\n let result = s.execute(\"actions.import\", json!({\"data\": exported[\"data\"]})).unwrap();\n assert_eq!(result[\"imported\"], 1);\n assert_eq!(s.actions.list, [action]);\n let rev = s.actions.rev;",
|
|
"expected_assertions": [
|
|
" assert_eq!(result[\"imported\"], 1);\n assert_eq!(s.actions.list, [action]);\n let rev = s.actions.rev;\n assert_eq!(s.execute(\"actions.import\", json!({\"data\": exported[\"data\"]})).unwrap()[\"imported\"], 0);\n assert_eq!(s.actions.rev, rev);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/engine/src/actions_cmds/json_file.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reimport_after_changing_button_color_keeps_names_unique",
|
|
"path": "crates/engine/src/actions_cmds/json_file.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked reimport_after_changing_button_color_keeps_names_unique -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.actions.list.push(Action::new(\"Draw\", vec![]));\n let data = s.execute(\"actions.export\", json!({})).unwrap()[\"data\"].clone();\n s.execute(\"actions.setColor\", json!({\"action\": \"Draw\", \"color\": \"red\"})).unwrap();\n let params = json!({\"data\": data});\n assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 1);\n assert_eq!(s.actions.list[0].name, \"Draw\");\n assert_eq!(s.actions.list[0].color, \"red\");\n assert_eq!(s.actions.list[1].name, \"Draw (Imported 2)\");\n assert!(s.actions.list[1].color.is_empty());\n let before = s.actions.clone();\n assert_eq!(s.execute(\"actions.import\", params).unwrap()[\"imported\"], 0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 1);\n assert_eq!(s.actions.list[0].name, \"Draw\");\n assert_eq!(s.actions.list[0].color, \"red\");\n assert_eq!(s.actions.list[1].name, \"Draw (Imported 2)\");\n assert!(s.actions.list[1].color.is_empty());\n let before = s.actions.clone();\n assert_eq!(s.execute(\"actions.import\", params).unwrap()[\"imported\"], 0);\n assert_eq!(s.actions, before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/engine/src/actions_cmds/json_file.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "parents_before_children_are_retargeted_and_reimport_is_idempotent",
|
|
"path": "crates/engine/src/actions_cmds/json_file.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked parents_before_children_are_retargeted_and_reimport_is_idempotent -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.actions.list.push(Action::new(\"Child\", vec![]));\n let file = ActionsFile {\n version: 1,\n actions: vec![\n Action::new(\"Parent\", vec![(\"actions.play\".into(), json!({\"action\": 1}))]),\n Action::new(\"Child\", vec![(\"layer.new.layer\".into(), json!({}))]),\n Action::new(\"Named\", vec![(\"actions.play\".into(), json!({\"action\": \"Child\"}))]),\n ],\n };\n let params = json!({\"data\": serde_json::to_string(&file).unwrap()});\n assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 3);",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 3);\n assert_eq!(s.actions.list[1].steps[0].1[\"action\"], \"Child (Imported 2)\");\n assert_eq!(s.actions.list[2].name, \"Child (Imported 2)\");\n assert_eq!(s.actions.list[3].steps[0].1[\"action\"], \"Child (Imported 2)\");\n let before = s.actions.clone();\n assert_eq!(s.execute(\"actions.import\", params).unwrap()[\"imported\"], 0);\n assert_eq!(s.actions, before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/engine/src/actions_cmds/json_file.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "invalid_json_params_and_nested_indices_fail_atomically",
|
|
"path": "crates/engine/src/actions_cmds/json_file.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked invalid_json_params_and_nested_indices_fail_atomically -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.actions.list.push(Action::new(\"Keep\", vec![]));\n let before = s.actions.clone();\n for p in [Value::Null, json!([]), json!({\"data\": true}), json!({\"data\": \"invalid\"}), json!({\"data\": \"{\\\"version\\\":2,\\\"actions\\\":[]}\"})] {\n assert!(s.execute(\"actions.import\", p).is_err());\n assert_eq!(s.actions, before);\n }\n for target in [json!(-1), json!(0.5), json!(1), Value::Null] {\n let file = ActionsFile { version: 1, actions: vec![Action::new(\"A\", vec![(\"actions.play\".into(), json!({\"action\": target}))])] };\n assert!(s.execute(\"actions.import\", json!({\"data\": serde_json::to_string(&file).unwrap()})).is_err());\n assert_eq!(s.actions, before);\n }",
|
|
"expected_assertions": [
|
|
" assert!(s.execute(\"actions.import\", p).is_err());\n assert_eq!(s.actions, before);\n }\n for target in [json!(-1), json!(0.5), json!(1), Value::Null] {\n let file = ActionsFile { version: 1, actions: vec![Action::new(\"A\", vec![(\"actions.play\".into(), json!({\"action\": target}))])] };\n assert!(s.execute(\"actions.import\", json!({\"data\": serde_json::to_string(&file).unwrap()})).is_err());\n assert_eq!(s.actions, before);\n }\n assert!(s.execute(\"actions.export\", json!({\"path\": 1})).is_err());\n s.actions.recording = Some((0, 0));\n assert!(s.execute(\"actions.import\", json!({\"data\": \"{}\"})).is_err());\n assert!(s.execute(\"actions.export\", json!({})).is_err());\n assert_eq!(s.actions.list, before.list);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/engine/src/actions_cmds/json_file.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "long_unicode_collision_names_remain_portable_and_idempotent",
|
|
"path": "crates/engine/src/actions_cmds/json_file.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked long_unicode_collision_names_remain_portable_and_idempotent -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n let name = \"\u754c\".repeat(85);\n s.actions.list.push(Action::new(&name, vec![]));\n let file = ActionsFile { version: 1, actions: vec![Action::new(&name, vec![(\"select.all\".into(), json!({}))])] };\n let params = json!({\"data\": serde_json::to_string(&file).unwrap()});\n assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 1);\n assert!(s.actions.list[1].name.len() <= MAX_NAME_BYTES);\n assert_eq!(s.execute(\"actions.import\", params).unwrap()[\"imported\"], 0);\n assert!(s.execute(\"actions.export\", json!({})).is_ok());\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.execute(\"actions.import\", params.clone()).unwrap()[\"imported\"], 1);\n assert!(s.actions.list[1].name.len() <= MAX_NAME_BYTES);\n assert_eq!(s.execute(\"actions.import\", params).unwrap()[\"imported\"], 0);\n assert!(s.execute(\"actions.export\", json!({})).is_ok());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/engine/src/actions_cmds/json_file.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "loading_json_actions_uses_engine_import_and_selects_the_new_action",
|
|
"path": "crates/ui-egui/src/actions.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked loading_json_actions_uses_engine_import_and_selects_the_new_action -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let action = Action::new(\"Portable\", vec![(\"select.all\".into(), json!({}))]);\n let file = actions_cmds::ActionsFile { version: 1, actions: vec![action.clone()] };\n let bytes = serde_json::to_vec(&file).unwrap();\n assert_eq!(load_bytes(&mut app, \"Actions.JSON\", &bytes).unwrap()[\"imported\"], 1);\n assert_eq!(app.session.actions.list, [action]);\n assert_eq!(app.ui.actions.selected, Some(0));\n assert_eq!(app.ui.actions.selected_step, None);\n assert!(app.ui.actions.expanded[0]);\n assert!(!app.ui.status_error);\n let before = app.session.actions.clone();\n assert_eq!(load_bytes(&mut app, \"Actions.json\", &bytes).unwrap()[\"imported\"], 0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(load_bytes(&mut app, \"Actions.JSON\", &bytes).unwrap()[\"imported\"], 1);\n assert_eq!(app.session.actions.list, [action]);\n assert_eq!(app.ui.actions.selected, Some(0));\n assert_eq!(app.ui.actions.selected_step, None);\n assert!(app.ui.actions.expanded[0]);\n assert!(!app.ui.status_error);\n let before = app.session.actions.clone();\n assert_eq!(load_bytes(&mut app, \"Actions.json\", &bytes).unwrap()[\"imported\"], 0);\n assert_eq!(app.session.actions, before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/202266b90613280e16ae285b53dd4e10d5f0c7ac/crates/ui-egui/src/actions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3142",
|
|
"pr": 3142,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-raw --locked measured_image_areas_crop_the_borders_without_touching_the_rest -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked encrypted_applied_white_balance_and_black_reach_the_developer -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked plain_levels_win_and_invalid_encrypted_levels_are_ignored -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked hostile_private_metadata_is_bounded_and_optional -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked measured_keystream_recurrence_and_unencrypted_tail -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked decode_matches_the_measured_oracles -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked developing_produces_the_crop_in_16bit_rgb -- --nocapture"
|
|
],
|
|
"expected": "measured image areas crop the borders without touching the rest; encrypted applied white balance and black reach the developer; plain levels win and invalid encrypted levels are ignored; hostile private metadata is bounded and optional; measured keystream recurrence and unencrypted tail; decode matches the measured oracles; developing produces the crop in 16bit rgb",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-raw --locked measured_image_areas_crop_the_borders_without_touching_the_rest -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked encrypted_applied_white_balance_and_black_reach_the_developer -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked plain_levels_win_and_invalid_encrypted_levels_are_ignored -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked hostile_private_metadata_is_bounded_and_optional -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked measured_keystream_recurrence_and_unencrypted_tail -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked decode_matches_the_measured_oracles -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked developing_produces_the_crop_in_16bit_rgb -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "measured_image_areas_crop_the_borders_without_touching_the_rest",
|
|
"path": "crates/raw/src/cameras.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked measured_image_areas_crop_the_borders_without_touching_the_rest -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = nef(\"NIKON D800E\", 7424, 4924);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(8, 6, 7360, 4912));\n // Only the image area is measured: levels, colour and tone stay untouched.\n assert!(s.color.calibrations.is_empty() && s.tone_curve.is_empty());\n assert_eq!(s.white, [16383.0; 3]);\n\n let mut s = sensor(\"SONY\", \"ILCE-7\", 6048, 4024);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(12, 12, 6000, 4000));\n\n let mut s = sensor(\"SONY\", \"ILCE-6000\", 6048, 4024);",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.crop, Rect::new(8, 6, 7360, 4912));\n // Only the image area is measured: levels, colour and tone stay untouched.\n assert!(s.color.calibrations.is_empty() && s.tone_curve.is_empty());\n assert_eq!(s.white, [16383.0; 3]);\n\n let mut s = sensor(\"SONY\", \"ILCE-7\", 6048, 4024);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(12, 12, 6000, 4000));\n\n let mut s = sensor(\"SONY\", \"ILCE-6000\", 6048, 4024);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(12, 12, 6000, 4000));\n assert!(s.color.calibrations.is_empty() && s.tone_curve.is_empty());\n // A file's explicit crop wins, including a different in-camera aspect ratio.\n s.crop = Rect::new(12, 324, 6000, 3376);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(12, 324, 6000, 3376));\n\n let mut s = sensor(\"SONY\", \"ILCE-6000\", 3024, 2012);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(0, 0, 3024, 2012));\n\n // Another size or model of the same maker is left alone.\n let mut s = nef(\"NIKON D800E\", 2496, 1646);\n assert_eq!(s.crop, Rect::new(0, 0, 2496, 1646));\n let mut s = nef(\"NIKON D800\", 7424, 4924);\n apply(&mut s);\n assert_eq!(s.crop, Rect::new(0, 0, 7424, 4924));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/src/cameras.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "encrypted_applied_white_balance_and_black_reach_the_developer",
|
|
"path": "crates/raw/src/sony_metadata.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked encrypted_applied_white_balance_and_black_reach_the_developer -- --nocapture",
|
|
"fixture_and_action_excerpt": " for be in [false, true] {\n let bytes = fixture(be, false, [512, 513, 514, 515], [3072, 1024, 1024, 2048]);\n let s = decode(&bytes, &Limits::default()).unwrap();\n assert_eq!(s.format, RawFormat::Arw);\n assert_eq!(s.camera_wb, Some([3.0, 1.0, 2.0]));\n assert_eq!(s.black.values, vec![512.0, 513.0, 514.0, 515.0]);\n let dev = develop_sensor(&s, &DevelopOptions::default()).unwrap();\n assert_eq!(dev.info.wb_multipliers, [3.0, 1.0, 2.0]);\n assert!(!dev.warnings.iter().any(|w| w.contains(\"grey world\") || w.contains(\"assumed 0\")));\n let explicit = develop_sensor(&s, &DevelopOptions { white_balance: WhiteBalance::Multipliers([3.0, 1.0, 2.0]), ..Default::default() }).unwrap();\n assert_eq!(dev.rgb, explicit.rgb);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.format, RawFormat::Arw);\n assert_eq!(s.camera_wb, Some([3.0, 1.0, 2.0]));\n assert_eq!(s.black.values, vec![512.0, 513.0, 514.0, 515.0]);\n let dev = develop_sensor(&s, &DevelopOptions::default()).unwrap();\n assert_eq!(dev.info.wb_multipliers, [3.0, 1.0, 2.0]);\n assert!(!dev.warnings.iter().any(|w| w.contains(\"grey world\") || w.contains(\"assumed 0\")));\n let explicit = develop_sensor(&s, &DevelopOptions { white_balance: WhiteBalance::Multipliers([3.0, 1.0, 2.0]), ..Default::default() }).unwrap();\n assert_eq!(dev.rgb, explicit.rgb);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/src/sony_metadata.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "plain_levels_win_and_invalid_encrypted_levels_are_ignored",
|
|
"path": "crates/raw/src/sony_metadata.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked plain_levels_win_and_invalid_encrypted_levels_are_ignored -- --nocapture",
|
|
"fixture_and_action_excerpt": " let s = decode(&fixture(false, true, [800; 4], [3072, 1024, 1024, 2048]), &Limits::default()).unwrap();\n assert_eq!(s.camera_wb, Some([2.0, 1.0, 1.5]));\n assert_eq!(s.black.values, vec![600.0; 4]);\n let mut broken_plain = fixture(false, true, [800; 4], [3072, 1024, 1024, 2048]);\n let t = Tiff::new(&broken_plain).unwrap();\n let raw = t.all_ifds().into_iter().find(|i| i.has(0x7313)).unwrap();\n let at = raw.get(0x7313).unwrap().at;\n broken_plain[at..at + 8].fill(0);\n let s = decode(&broken_plain, &Limits::default()).unwrap();\n assert_eq!(s.camera_wb, Some([3.0, 1.0, 2.0]));\n assert_eq!(s.black.values, vec![600.0; 4]);\n for wb in [[0, 0, 0, 0], [65535, 1024, 1024, 2048], [30000, 1024, 1024, 2048], [3072, 0, 0, 2048]] {",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.camera_wb, Some([2.0, 1.0, 1.5]));\n assert_eq!(s.black.values, vec![600.0; 4]);\n let mut broken_plain = fixture(false, true, [800; 4], [3072, 1024, 1024, 2048]);\n let t = Tiff::new(&broken_plain).unwrap();\n let raw = t.all_ifds().into_iter().find(|i| i.has(0x7313)).unwrap();\n assert_eq!(s.camera_wb, Some([3.0, 1.0, 2.0]));\n assert_eq!(s.black.values, vec![600.0; 4]);\n for wb in [[0, 0, 0, 0], [65535, 1024, 1024, 2048], [30000, 1024, 1024, 2048], [3072, 0, 0, 2048]] {\n let s = decode(&fixture(false, false, [65535; 4], wb), &Limits::default()).unwrap();\n assert_eq!(s.camera_wb, None);\n assert_eq!(s.black.values, vec![0.0]);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/src/sony_metadata.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "hostile_private_metadata_is_bounded_and_optional",
|
|
"path": "crates/raw/src/sony_metadata.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked hostile_private_metadata_is_bounded_and_optional -- --nocapture",
|
|
"fixture_and_action_excerpt": " let bytes = fixture(false, false, [512; 4], [3072, 1024, 1024, 2048]);\n for n in 0..bytes.len() {\n if let Some(t) = Tiff::new(&bytes[..n]) {\n let _ = read(&t, &Limits::default());\n }\n }\n let t = Tiff::new(&bytes).unwrap();\n assert!(read(&t, &Limits { max_alloc: 2000, ..Default::default() }).is_none());\n let root = t.ifd_at(t.first_ifd, 0).unwrap();\n let private = t.ifd_at(t.u32_at(root.get(PRIVATE_DATA).unwrap().at).unwrap() as usize, 0).unwrap();\n for (at, value) in [(private.get(KEY).unwrap().at, 0), (private.get(LENGTH).unwrap().at, u32::MAX), (private.get(OFFSET).unwrap().at, u32::MAX)] {\n let mut corrupt = bytes.clone();",
|
|
"expected_assertions": [
|
|
" assert!(read(&t, &Limits { max_alloc: 2000, ..Default::default() }).is_none());\n let root = t.ifd_at(t.first_ifd, 0).unwrap();\n let private = t.ifd_at(t.u32_at(root.get(PRIVATE_DATA).unwrap().at).unwrap() as usize, 0).unwrap();\n for (at, value) in [(private.get(KEY).unwrap().at, 0), (private.get(LENGTH).unwrap().at, u32::MAX), (private.get(OFFSET).unwrap().at, u32::MAX)] {\n assert!(read(&Tiff::new(&corrupt).unwrap(), &Limits::default()).is_none());\n let s = decode(&corrupt, &Limits::default()).unwrap();\n assert_eq!(s.camera_wb, None);\n }\n let start = t.tag_uint(&private, OFFSET).unwrap() as usize;\n let len = t.tag_uint(&private, LENGTH).unwrap() as usize;\n assert!(read(&Tiff::new(&corrupt).unwrap(), &Limits::default()).unwrap().wb.is_none());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/src/sony_metadata.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "measured_keystream_recurrence_and_unencrypted_tail",
|
|
"path": "crates/raw/src/sony_metadata.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked measured_keystream_recurrence_and_unencrypted_tail -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut zero = vec![0; 14239 * 4 + 2];\n decipher(&mut zero);\n assert_eq!(&zero[..4], &[0x54, 0xc2, 0xc4, 0xd6]);\n // Words recovered independently from all three oracle dumps, including ring wrap\n // and the final complete word of a real metadata block.\n assert_eq!(&zero[127 * 4..128 * 4], &[0x86, 0xbe, 0x2e, 0x12]);\n assert_eq!(&zero[255 * 4..256 * 4], &[0xc9, 0x1a, 0x54, 0xc4]);\n assert_eq!(&zero[14238 * 4..14239 * 4], &[0xb9, 0xd3, 0x6e, 0xab]);\n assert_eq!(&zero[14239 * 4..], &[0, 0]);\n decipher(&mut zero);\n assert!(zero.iter().all(|&b| b == 0));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(&zero[..4], &[0x54, 0xc2, 0xc4, 0xd6]);\n // Words recovered independently from all three oracle dumps, including ring wrap\n // and the final complete word of a real metadata block.\n assert_eq!(&zero[127 * 4..128 * 4], &[0x86, 0xbe, 0x2e, 0x12]);\n assert_eq!(&zero[255 * 4..256 * 4], &[0xc9, 0x1a, 0x54, 0xc4]);\n assert_eq!(&zero[14238 * 4..14239 * 4], &[0xb9, 0xd3, 0x6e, 0xab]);\n assert_eq!(&zero[14239 * 4..], &[0, 0]);\n decipher(&mut zero);\n assert!(zero.iter().all(|&b| b == 0));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/src/sony_metadata.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "decode_matches_the_measured_oracles",
|
|
"path": "crates/raw/tests/raw_corpus.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked decode_matches_the_measured_oracles -- --nocapture",
|
|
"fixture_and_action_excerpt": " for w in WANTS {\n let bytes = std::fs::read(pixls(w.file)).unwrap_or_else(|e| panic!(\"{}: {e}\", w.file));\n let s = photocraft_raw::decode(&bytes, &Limits::default()).unwrap_or_else(|e| panic!(\"{}: {e}\", w.file));\n assert_eq!(s.format, w.format, \"{}\", w.file);\n assert_eq!(s.make.as_deref(), Some(w.make), \"{}\", w.file);\n assert_eq!(s.model.as_deref(), Some(w.model), \"{}\", w.file);\n assert_eq!((s.width, s.height), w.size, \"{}\", w.file);\n let cfa = s.cfa.as_ref().unwrap_or_else(|| panic!(\"{}: no CFA\", w.file));\n assert_eq!(cfa.colors, w.cfa, \"{}\", w.file);\n assert_eq!(s.black.values, w.black, \"{}\", w.file);\n if w.file == \"DSC00009.ARW\" {\n assert_eq!(s.camera_wb, Some([2056.0 / 1024.0, 1.0, 1908.0 / 1024.0]));",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.format, w.format, \"{}\", w.file);\n assert_eq!(s.make.as_deref(), Some(w.make), \"{}\", w.file);\n assert_eq!(s.model.as_deref(), Some(w.model), \"{}\", w.file);\n assert_eq!((s.width, s.height), w.size, \"{}\", w.file);\n let cfa = s.cfa.as_ref().unwrap_or_else(|| panic!(\"{}: no CFA\", w.file));\n assert_eq!(cfa.colors, w.cfa, \"{}\", w.file);\n assert_eq!(s.black.values, w.black, \"{}\", w.file);\n if w.file == \"DSC00009.ARW\" {\n assert_eq!(s.camera_wb, Some([2056.0 / 1024.0, 1.0, 1908.0 / 1024.0]));\n }\n for ch in 0..3 {\n assert!((s.white[ch] - w.white[ch]).abs() < 0.5, \"{} white[{ch}] = {}\", w.file, s.white[ch]);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/tests/raw_corpus.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "developing_produces_the_crop_in_16bit_rgb",
|
|
"path": "crates/raw/tests/raw_corpus.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked developing_produces_the_crop_in_16bit_rgb -- --nocapture",
|
|
"fixture_and_action_excerpt": " for w in WANTS {\n let bytes = std::fs::read(pixls(w.file)).unwrap_or_else(|e| panic!(\"{}: {e}\", w.file));\n let s = photocraft_raw::decode(&bytes, &Limits::default()).unwrap_or_else(|e| panic!(\"{}: {e}\", w.file));\n let d = photocraft_raw::develop_sensor(&s, &photocraft_raw::DevelopOptions::default()).unwrap_or_else(|e| panic!(\"{}: {e}\", w.file));\n assert_eq!((d.width as usize, d.height as usize), (s.crop.width, s.crop.height), \"{}\", w.file);\n assert_eq!(d.rgb.len(), d.width as usize * d.height as usize * 3, \"{}\", w.file);\n // A real exposure covers a sane share of the range and never leaves it.\n let (mut lo, mut hi) = (u16::MAX, 0u16);\n for v in &d.rgb {\n lo = (*v).min(lo);\n hi = (*v).max(hi);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!((d.width as usize, d.height as usize), (s.crop.width, s.crop.height), \"{}\", w.file);\n assert_eq!(d.rgb.len(), d.width as usize * d.height as usize * 3, \"{}\", w.file);\n // A real exposure covers a sane share of the range and never leaves it.\n let (mut lo, mut hi) = (u16::MAX, 0u16);\n for v in &d.rgb {\n assert!(lo < black_cap, \"{}: developed blacks at {lo}\", w.file);\n assert!(hi > u16::MAX / 4, \"{}: developed highlights at {hi}\", w.file);\n // Deterministic: a second develop of the same sensor gives the same pixels.\n let d2 = photocraft_raw::develop_sensor(&s, &photocraft_raw::DevelopOptions::default()).unwrap();\n assert_eq!(d.rgb, d2.rgb, \"{}\", w.file);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2ed234e654e574109ffcdb9756f8e8d1b8a00b2/crates/raw/tests/raw_corpus.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3387",
|
|
"pr": 3387,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Native 7\u00d75 Gray/GrayA/RGB/RGBA U8/U16 fixtures plus 2/513/8193-pixel-wide alpha samples in codecs/tests/jxl_export.rs",
|
|
"action": [
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_decodes_losslessly_with_independent_decoder -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_preserves_sixteen_bit_alpha_across_dimension_header_sizes -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_encoding_is_deterministic_and_converts_float_to_integer -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_is_export_only_and_detects_both_signatures -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_rejects_one_pixel_images_without_panicking -- --nocapture"
|
|
],
|
|
"expected": "Independent jxl_oxide decoding equals original integer samples exactly, including alpha and GrayA widening. Dimensions/channels and deterministic output are correct; capabilities remain export-only; 1\u00d71 refuses without panic.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "These native independent-decoder checks cannot be established by wasm or malformed-header rejection alone.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_decodes_losslessly_with_independent_decoder -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_preserves_sixteen_bit_alpha_across_dimension_header_sizes -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_encoding_is_deterministic_and_converts_float_to_integer -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_is_export_only_and_detects_both_signatures -- --nocapture",
|
|
"cargo test -p photocraft-codecs --locked jpeg_xl_rejects_one_pixel_images_without_panicking -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-3464",
|
|
"pr": 3464,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked appended_work_and_saved_components_preserve_existing_geometry_and_undo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked appending_valid_components_cannot_exceed_total_path_budget -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked invalid_path_coordinates_leave_work_and_saved_paths_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked large_straight_work_and_saved_paths_append_and_undo_without_shape_coordinate_limits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shape_layer_paths_are_edited_and_a_direct_selection_is_cleared -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_tools_edit_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_with_freeform_and_curvature_edits_the_selected_saved_path_after_modifier_release -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_cannot_edit_an_existing_path_when_the_freeform_trace_failed_to_finish -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_an_anchor_moves_it_in_one_undoable_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrow_keys_nudge_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_saved_and_work_paths_win_overlapping_shape_hits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_cannot_apply_to_another_document_or_a_reopened_identity -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked external_revision_cancels_preview_and_preserves_the_new_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_path_and_tool_changes_cancel_the_owned_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closing_a_document_and_changing_marquee_target_discard_old_events -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked serialized_anchor_selection_has_no_runtime_ownership_and_is_not_restored -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_drag_after_failed_pen_commit_preserves_draft_and_existing_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked switching_between_selection_and_convert_tools_cancels_an_in_flight_drag -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_convert_point_tool_edits_selected_saved_paths_without_changing_the_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked changing_the_channel_vector_mask_target_cancels_an_owned_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked esc_ends_a_pen_path_and_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_shows_the_close_path_pointer_over_the_first_anchor -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked real_freeform_freehand_and_alt_straight_segments_append_to_the_owned_saved_path_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked real_freeform_stale_target_source_revision_and_document_cancel_without_finishing_elsewhere -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked another_freeform_trace_cannot_replace_a_failed_owned_draft_or_retry_it_automatically -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_alt_release_in_the_next_press_keeps_the_failed_fit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked clicking_the_vector_mask_targets_it_for_the_path_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_enter_while_drawing_finishes_the_path_and_loads_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_and_path_selection_releases_cannot_edit_a_different_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_release_cancels_after_revision_or_target_change -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_valid_release_is_one_undoable_path_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked frame_cancellation_consumes_old_events_after_switching_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_work_and_saved_paths_append_pen_and_curvature_components_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked deselected_work_path_is_replaced_without_touching_saved_paths -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked captured_path_and_shape_mode_do_not_follow_later_ui_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked captured_pen_paint_preserves_float_colour_and_alpha_after_toolbar_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_drafts_are_cancelled_before_tool_switch_or_pointer_input -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked sync_views_and_input_apis_discard_unowned_or_closed_document_drafts -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked same_named_saved_paths_do_not_share_selection_or_drafts_across_tabs -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reopened_same_id_and_revision_do_not_reuse_the_saved_path_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ordinary_path_edits_undo_and_redo_preserve_the_explicit_saved_path_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_pen_and_curvature_commits_keep_the_exact_draft_and_do_not_retry_each_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ordinary_tool_switch_commits_the_owned_draft_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_saved_paths_move_and_free_transform_without_changing_work_or_shape -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked explicit_work_path_precedes_vector_mask_and_deselection_restores_mask_fallback -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_keeps_its_captured_vector_mask_when_another_path_is_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_finish_uses_its_captured_saved_path_and_rejects_foreign_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked saved_path_drag_visual_fixture -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked enter_selects_a_stroke_style_and_escape_closes_its_popups_without_committing_pen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked transparent_and_absent_paints_remain_distinct_and_open_pen_keeps_foreground -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked all_shape_tools_and_open_pen_use_the_complete_stroke_defaults -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_straight_segments_keep_the_captured_saved_path_and_reject_a_foreign_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_freeform_straight_segment_commit_keeps_its_owned_fitted_draft -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked show_target_path_and_extras_hide_the_path_outlines -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_last_anchor_hit_tolerance_tracks_zoom_and_draft_round_trips -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_keep_large_straight_coordinates_and_shape_limits_stay_put -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_reject_coordinates_that_overflow_the_ui_or_segment_arithmetic -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_bound_total_knots_subpaths_and_combined_tessellation -- --nocapture"
|
|
],
|
|
"expected": "appended work and saved components preserve existing geometry and undo; appending valid components cannot exceed total path budget; invalid path coordinates leave work and saved paths unchanged; large straight work and saved paths append and undo without shape coordinate limits; shape layer paths are edited and a direct selection is cleared; add and delete anchor tools edit the selected saved path; command with freeform and curvature edits the selected saved path after modifier release; command cannot edit an existing path when the freeform trace failed to finish; dragging an anchor moves it in one undoable step; arrow keys nudge the selected saved path; selected saved and work paths win overlapping shape hits; direct selection cannot apply to another document or a reopened identity; external revision cancels preview and preserves the new path; layer path and tool changes cancel the owned edit; closing a document and changing marquee target discard old events; serialized anchor selection has no runtime ownership and is not restored; command drag after failed pen commit preserves draft and existing work path; switching between selection and convert tools cancels an in flight drag; the convert point tool edits selected saved paths without changing the work path; changing the channel vector mask target cancels an owned edit; esc ends a pen path and keeps it; pen shows the close path pointer over the first anchor; real freeform freehand and alt straight segments append to the owned saved path once; real freeform stale target source revision and document cancel without finishing elsewhere; another freeform trace cannot replace a failed owned draft or retry it automatically; freeform alt release in the next press keeps the failed fit; clicking the vector mask targets it for the path tools; cmd enter while drawing finishes the path and loads it; freeform and path selection releases cannot edit a different document; freeform release cancels after revision or target change; freeform valid release is one undoable path edit; frame cancellation consumes old events after switching tools; selected work and saved paths append pen and curvature components once; deselected work path is replaced without touching saved paths; captured path and shape mode do not follow later ui selection; captured pen paint preserves float colour and alpha after toolbar changes; stale drafts are cancelled before tool switch or pointer input; sync views and input apis discard unowned or closed document drafts; same named saved paths do not share selection or drafts across tabs; reopened same id and revision do not reuse the saved path selection; ordinary path edits undo and redo preserve the explicit saved path selection; failed pen and curvature commits keep the exact draft and do not retry each frame; ordinary tool switch commits the owned draft once; selected saved paths move and free transform without changing work or shape; explicit work path precedes vector mask and deselection restores mask fallback; pen keeps its captured vector mask when another path is selected; freeform finish uses its captured saved path and rejects foreign documents; saved path drag visual fixture; enter selects a stroke style and escape closes its popups without committing pen; transparent and absent paints remain distinct and open pen keeps foreground; all shape tools and open pen use the complete stroke defaults; freeform straight segments keep the captured saved path and reject a foreign document; failed freeform straight segment commit keeps its owned fitted draft; show target path and extras hide the path outlines; pen last anchor hit tolerance tracks zoom and draft round trips; general paths keep large straight coordinates and shape limits stay put; general paths reject coordinates that overflow the ui or segment arithmetic; general paths bound total knots subpaths and combined tessellation",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked appended_work_and_saved_components_preserve_existing_geometry_and_undo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked appending_valid_components_cannot_exceed_total_path_budget -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked invalid_path_coordinates_leave_work_and_saved_paths_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked large_straight_work_and_saved_paths_append_and_undo_without_shape_coordinate_limits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shape_layer_paths_are_edited_and_a_direct_selection_is_cleared -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_tools_edit_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_with_freeform_and_curvature_edits_the_selected_saved_path_after_modifier_release -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_cannot_edit_an_existing_path_when_the_freeform_trace_failed_to_finish -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_an_anchor_moves_it_in_one_undoable_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrow_keys_nudge_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_saved_and_work_paths_win_overlapping_shape_hits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_cannot_apply_to_another_document_or_a_reopened_identity -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked external_revision_cancels_preview_and_preserves_the_new_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_path_and_tool_changes_cancel_the_owned_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closing_a_document_and_changing_marquee_target_discard_old_events -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked serialized_anchor_selection_has_no_runtime_ownership_and_is_not_restored -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked command_drag_after_failed_pen_commit_preserves_draft_and_existing_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked switching_between_selection_and_convert_tools_cancels_an_in_flight_drag -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_convert_point_tool_edits_selected_saved_paths_without_changing_the_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked changing_the_channel_vector_mask_target_cancels_an_owned_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked esc_ends_a_pen_path_and_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_shows_the_close_path_pointer_over_the_first_anchor -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked real_freeform_freehand_and_alt_straight_segments_append_to_the_owned_saved_path_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked real_freeform_stale_target_source_revision_and_document_cancel_without_finishing_elsewhere -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked another_freeform_trace_cannot_replace_a_failed_owned_draft_or_retry_it_automatically -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_alt_release_in_the_next_press_keeps_the_failed_fit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked clicking_the_vector_mask_targets_it_for_the_path_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_enter_while_drawing_finishes_the_path_and_loads_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_and_path_selection_releases_cannot_edit_a_different_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_release_cancels_after_revision_or_target_change -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_valid_release_is_one_undoable_path_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked frame_cancellation_consumes_old_events_after_switching_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_work_and_saved_paths_append_pen_and_curvature_components_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked deselected_work_path_is_replaced_without_touching_saved_paths -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked captured_path_and_shape_mode_do_not_follow_later_ui_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked captured_pen_paint_preserves_float_colour_and_alpha_after_toolbar_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_drafts_are_cancelled_before_tool_switch_or_pointer_input -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked sync_views_and_input_apis_discard_unowned_or_closed_document_drafts -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked same_named_saved_paths_do_not_share_selection_or_drafts_across_tabs -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reopened_same_id_and_revision_do_not_reuse_the_saved_path_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ordinary_path_edits_undo_and_redo_preserve_the_explicit_saved_path_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_pen_and_curvature_commits_keep_the_exact_draft_and_do_not_retry_each_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ordinary_tool_switch_commits_the_owned_draft_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_saved_paths_move_and_free_transform_without_changing_work_or_shape -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked explicit_work_path_precedes_vector_mask_and_deselection_restores_mask_fallback -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_keeps_its_captured_vector_mask_when_another_path_is_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_finish_uses_its_captured_saved_path_and_rejects_foreign_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked saved_path_drag_visual_fixture -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked enter_selects_a_stroke_style_and_escape_closes_its_popups_without_committing_pen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked transparent_and_absent_paints_remain_distinct_and_open_pen_keeps_foreground -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked all_shape_tools_and_open_pen_use_the_complete_stroke_defaults -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_straight_segments_keep_the_captured_saved_path_and_reject_a_foreign_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_freeform_straight_segment_commit_keeps_its_owned_fitted_draft -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked show_target_path_and_extras_hide_the_path_outlines -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pen_last_anchor_hit_tolerance_tracks_zoom_and_draft_round_trips -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_keep_large_straight_coordinates_and_shape_limits_stay_put -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_reject_coordinates_that_overflow_the_ui_or_segment_arithmetic -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked general_paths_bound_total_knots_subpaths_and_combined_tessellation -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "appended_work_and_saved_components_preserve_existing_geometry_and_undo",
|
|
"path": "crates/engine/tests/pen_path_append.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked appended_work_and_saved_components_preserve_existing_geometry_and_undo -- --nocapture",
|
|
"fixture_and_action_excerpt": " for name in [\"work\", \"Saved drawing\"] {\n let mut session = session();\n let first = json!({\"subpaths\": [{\"closed\": false, \"knots\": [[20, 20], [80, 20]]}]});\n let second = json!({\"subpaths\": [{\"closed\": false, \"knots\": [[30, 60], [90, 60]]}]});\n session.execute(\"path.set\", json!({\"name\": name, \"path\": first})).unwrap();\n let before = session.execute(\"path.info\", json!({\"name\": name})).unwrap();\n session.execute(\"path.set\", json!({\"name\": name, \"path\": second, \"op\": \"combine\"})).unwrap();\n let after = session.execute(\"path.info\", json!({\"name\": name})).unwrap();\n assert_eq!(after[\"path\"][\"subpaths\"].as_array().unwrap().len(), 2);\n assert_eq!(after[\"path\"][\"subpaths\"][0], before[\"path\"][\"subpaths\"][0]);\n session.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(session.execute(\"path.info\", json!({\"name\": name})).unwrap(), before);",
|
|
"expected_assertions": [
|
|
" assert_eq!(after[\"path\"][\"subpaths\"].as_array().unwrap().len(), 2);\n assert_eq!(after[\"path\"][\"subpaths\"][0], before[\"path\"][\"subpaths\"][0]);\n session.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(session.execute(\"path.info\", json!({\"name\": name})).unwrap(), before);\n session.execute(\"edit.redo\", json!({})).unwrap();\n assert_eq!(session.execute(\"path.info\", json!({\"name\": name})).unwrap(), after);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/engine/tests/pen_path_append.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "appending_valid_components_cannot_exceed_total_path_budget",
|
|
"path": "crates/engine/tests/pen_path_append.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked appending_valid_components_cannot_exceed_total_path_budget -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut session = session();\n let subpath = json!({\"closed\": false, \"knots\": []});\n session.execute(\"path.set\", json!({\"path\": {\"subpaths\": vec![subpath.clone(); 2_049]}})).unwrap();\n let before = session.active().unwrap().doc.work_path.clone();\n let history = session.active().unwrap().history.entries().len();\n let error = session.execute(\"path.set\", json!({\"path\": {\"subpaths\": vec![subpath; 2_048]}, \"op\": \"combine\"})).unwrap_err();\n assert!(error.to_string().contains(\"4096\"));\n assert_eq!(session.active().unwrap().doc.work_path, before);\n assert_eq!(session.active().unwrap().history.entries().len(), history);\n}",
|
|
"expected_assertions": [
|
|
" assert!(error.to_string().contains(\"4096\"));\n assert_eq!(session.active().unwrap().doc.work_path, before);\n assert_eq!(session.active().unwrap().history.entries().len(), history);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/engine/tests/pen_path_append.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "invalid_path_coordinates_leave_work_and_saved_paths_unchanged",
|
|
"path": "crates/engine/tests/pen_path_append.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked invalid_path_coordinates_leave_work_and_saved_paths_unchanged -- --nocapture",
|
|
"fixture_and_action_excerpt": " for name in [\"work\", \"Saved drawing\"] {\n let mut session = session();\n session.execute(\"path.set\", json!({\"name\": name, \"path\": {\"subpaths\": [{\"knots\": [[10, 10], [20, 20]]}]}})).unwrap();\n let before = session.execute(\"path.info\", json!({\"name\": name})).unwrap();\n let history = session.active().unwrap().history.entries().len();\n assert!(\n session.execute(\"path.set\", json!({\"name\": name, \"op\": \"combine\", \"path\": {\"subpaths\": [{\"knots\": [[-1.0e308, 10], [1.0e308, 20]]}]}})).is_err()\n );\n assert_eq!(session.execute(\"path.info\", json!({\"name\": name})).unwrap(), before);\n assert_eq!(session.active().unwrap().history.entries().len(), history);\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(\n session.execute(\"path.set\", json!({\"name\": name, \"op\": \"combine\", \"path\": {\"subpaths\": [{\"knots\": [[-1.0e308, 10], [1.0e308, 20]]}]}})).is_err()\n );\n assert_eq!(session.execute(\"path.info\", json!({\"name\": name})).unwrap(), before);\n assert_eq!(session.active().unwrap().history.entries().len(), history);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/engine/tests/pen_path_append.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "large_straight_work_and_saved_paths_append_and_undo_without_shape_coordinate_limits",
|
|
"path": "crates/engine/tests/pen_path_append.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked large_straight_work_and_saved_paths_append_and_undo_without_shape_coordinate_limits -- --nocapture",
|
|
"fixture_and_action_excerpt": " for name in [\"work\", \"Saved drawing\"] {\n let mut session = session();\n let large = json!({\"subpaths\": [{\"closed\": true, \"knots\": [[0.0, 0.0], [3.0e9, 0.0], [3.0e9, 1.0e9]]}]});\n let before = session.active().unwrap().doc.clone();\n let history = session.active().unwrap().history.entries().len();\n session.execute(\"path.set\", json!({\"name\":name,\"path\":large})).unwrap();\n let first = session.execute(\"path.info\", json!({\"name\":name})).unwrap();\n assert_eq!(first[\"path\"][\"subpaths\"][0][\"knots\"][1][\"anchor\"], json!([3.0e9, 0.0]));\n assert_eq!(session.active().unwrap().history.entries().len(), history + 1);\n session.execute(\"path.set\", json!({\"name\":name,\"op\":\"combine\",\"path\":{\"subpaths\":[{\"knots\":[[10,20],[80,20]]}]}})).unwrap();\n let appended = session.execute(\"path.info\", json!({\"name\":name})).unwrap();\n assert_eq!(appended[\"path\"][\"subpaths\"].as_array().unwrap().len(), 2);",
|
|
"expected_assertions": [
|
|
" assert_eq!(first[\"path\"][\"subpaths\"][0][\"knots\"][1][\"anchor\"], json!([3.0e9, 0.0]));\n assert_eq!(session.active().unwrap().history.entries().len(), history + 1);\n session.execute(\"path.set\", json!({\"name\":name,\"op\":\"combine\",\"path\":{\"subpaths\":[{\"knots\":[[10,20],[80,20]]}]}})).unwrap();\n let appended = session.execute(\"path.info\", json!({\"name\":name})).unwrap();\n assert_eq!(appended[\"path\"][\"subpaths\"].as_array().unwrap().len(), 2);\n assert_eq!(appended[\"path\"][\"subpaths\"][0], first[\"path\"][\"subpaths\"][0]);\n session.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(session.execute(\"path.info\", json!({\"name\":name})).unwrap(), first);\n session.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(session.active().unwrap().doc.work_path, before.work_path);\n assert_eq!(session.active().unwrap().doc.paths, before.paths);\n session.execute(\"edit.redo\", json!({})).unwrap();\n assert_eq!(session.execute(\"path.info\", json!({\"name\":name})).unwrap(), first);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/engine/tests/pen_path_append.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shape_layer_paths_are_edited_and_a_direct_selection_is_cleared",
|
|
"path": "crates/ui-egui/src/anchor_tools_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shape_layer_paths_are_edited_and_a_direct_selection_is_cleared -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n let id = app.run(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [20, 20, 60, 60], \"fill\": \"#3070c0\"})).unwrap()[\"layer\"].as_u64().unwrap();\n click(&mut app, [80.0, 80.0], Modifiers::NONE);\n assert_eq!((app.ui.direct_selection.target.clone(), app.ui.direct_selection.anchors.clone()), (Some(PathRef::Layer(id)), vec![[0, 2]]));\n app.ui.tool = Tool::AddAnchorPoint;\n click(&mut app, [50.0, 20.0], Modifiers::NONE);\n let info = app.run(\"shape.info\", json!({\"layer\": id})).unwrap();\n assert_eq!(info[\"path\"][\"subpaths\"][0][\"knots\"].as_array().unwrap().len(), 5);\n assert!(app.ui.direct_selection.anchors.is_empty(), \"the selection no longer points at a shifted anchor\");\n app.ui.tool = Tool::DeleteAnchorPoint;\n click(&mut app, [20.0, 80.0], Modifiers::NONE);\n let info = app.run(\"shape.info\", json!({\"layer\": id})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!((app.ui.direct_selection.target.clone(), app.ui.direct_selection.anchors.clone()), (Some(PathRef::Layer(id)), vec![[0, 2]]));\n app.ui.tool = Tool::AddAnchorPoint;\n click(&mut app, [50.0, 20.0], Modifiers::NONE);\n let info = app.run(\"shape.info\", json!({\"layer\": id})).unwrap();\n assert_eq!(info[\"path\"][\"subpaths\"][0][\"knots\"].as_array().unwrap().len(), 5);\n assert!(app.ui.direct_selection.anchors.is_empty(), \"the selection no longer points at a shifted anchor\");\n app.ui.tool = Tool::DeleteAnchorPoint;\n click(&mut app, [20.0, 80.0], Modifiers::NONE);\n let info = app.run(\"shape.info\", json!({\"layer\": id})).unwrap();\n assert_eq!(info[\"path\"][\"subpaths\"][0][\"knots\"].as_array().unwrap().len(), 4);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/anchor_tools_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "add_and_delete_anchor_tools_edit_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/anchor_tools_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_tools_edit_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::AddAnchorPoint);\n with_path(&mut app);\n let before_work = work(&app);\n let path = photocraft_engine::vector_cmds::path_json(&before_work);\n app.run(\"path.set\", json!({\"name\":\"Saved\", \"path\":path})).unwrap();\n app.ui.selected_path = Some(\"Saved\".into());\n let n = steps(&app);\n click(&mut app, [80.0, 120.0], Modifiers::NONE);\n let saved = || app.session.active().unwrap().doc.paths.iter().find(|path| path.name == \"Saved\").unwrap().path.clone();\n let added = saved();\n assert_eq!(added.subpaths[0].knots.len(), 5);\n assert_eq!(work(&app), before_work);",
|
|
"expected_assertions": [
|
|
" assert_eq!(added.subpaths[0].knots.len(), 5);\n assert_eq!(work(&app), before_work);\n assert_eq!(steps(&app), n + 1);\n app.ui.tool = Tool::DeleteAnchorPoint;\n let anchor = added.subpaths[0].knots[3].anchor;\n click(&mut app, [anchor.x, anchor.y], Modifiers::NONE);\n assert_eq!(deleted.subpaths[0].knots.len(), 4);\n assert_eq!(work(&app), before_work);\n assert_eq!(steps(&app), n + 2);\n assert!(app.session.undo());\n assert_eq!(app.session.active().unwrap().doc.paths.iter().find(|path| path.name == \"Saved\").unwrap().path, added);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/anchor_tools_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "command_with_freeform_and_curvature_edits_the_selected_saved_path_after_modifier_release",
|
|
"path": "crates/ui-egui/src/direct_select.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked command_with_freeform_and_curvature_edits_the_selected_saved_path_after_modifier_release -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::FreeformPen, Tool::CurvaturePen] {\n let mut app = app(tool);\n let original = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n let command = Modifiers { command: true, ctrl: true, ..Default::default() };\n assert!(pointer(&mut app, ToolEvent::Down { x: 20.0, y: 20.0, pressure: 1.0 }, command));\n assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved drawing\".into())));\n assert!(captured_drag(&app));\n assert!(pointer(&mut app, ToolEvent::Move { x: 30.0, y: 40.0, pressure: 1.0 }, Modifiers::NONE));\n assert!(pointer(&mut app, ToolEvent::Up { x: 30.0, y: 40.0 }, Modifiers::NONE));\n let st = app.session.active().unwrap();\n assert_eq!(st.doc.work_path, original.work_path);",
|
|
"expected_assertions": [
|
|
" assert!(pointer(&mut app, ToolEvent::Down { x: 20.0, y: 20.0, pressure: 1.0 }, command));\n assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved drawing\".into())));\n assert!(captured_drag(&app));\n assert!(pointer(&mut app, ToolEvent::Move { x: 30.0, y: 40.0, pressure: 1.0 }, Modifiers::NONE));\n assert!(pointer(&mut app, ToolEvent::Up { x: 30.0, y: 40.0 }, Modifiers::NONE));\n let st = app.session.active().unwrap();\n assert_eq!(st.doc.work_path, original.work_path);\n assert_eq!(st.doc.paths[0].path.subpaths[0].knots[0].anchor, Point::new(30.0, 40.0));\n assert_eq!(st.history.past_len(), n + 1);\n assert!(app.ui.direct_selection.owner.as_ref().unwrap().valid(&app));\n assert!(!captured_drag(&app));\n assert!(app.session.undo());\n assert_eq!(app.session.active().unwrap().doc.paths, original.paths);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "command_cannot_edit_an_existing_path_when_the_freeform_trace_failed_to_finish",
|
|
"path": "crates/ui-egui/src/direct_select.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked command_cannot_edit_an_existing_path_when_the_freeform_trace_failed_to_finish -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::FreeformPen);\n let original = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n for [x, y] in [[40.0, 60.0], [1e40, 60.0], [140.0, 80.0]] {\n assert!(crate::lasso_ui::pointer(&mut app, ToolEvent::Down { x, y, pressure: 1.0 }, Modifiers::ALT));\n assert!(crate::lasso_ui::pointer(&mut app, ToolEvent::Up { x, y }, Modifiers::ALT));\n }\n let command = Modifiers { command: true, ctrl: true, ..Default::default() };\n assert!(pointer(&mut app, ToolEvent::Down { x: 20.0, y: 20.0, pressure: 1.0 }, command));\n let pen = app.ui.pen.as_ref().expect(\"failed Freeform commit must preserve its fitted draft\");\n assert!(pen.commit_failed && pen.owner.is_some());\n assert!(app.ui.direct_selection.drag.is_none());",
|
|
"expected_assertions": [
|
|
" assert!(crate::lasso_ui::pointer(&mut app, ToolEvent::Down { x, y, pressure: 1.0 }, Modifiers::ALT));\n assert!(crate::lasso_ui::pointer(&mut app, ToolEvent::Up { x, y }, Modifiers::ALT));\n }\n let command = Modifiers { command: true, ctrl: true, ..Default::default() };\n assert!(pointer(&mut app, ToolEvent::Down { x: 20.0, y: 20.0, pressure: 1.0 }, command));\n let pen = app.ui.pen.as_ref().expect(\"failed Freeform commit must preserve its fitted draft\");\n assert!(pen.commit_failed && pen.owner.is_some());\n assert!(app.ui.direct_selection.drag.is_none());\n assert!(app.ui.direct_selection.cancelled_drag);\n assert!(pointer(&mut app, ToolEvent::Up { x: 30.0, y: 40.0 }, command));\n assert!(app.ui.direct_selection.drag.is_none());\n assert_eq!(app.session.active().unwrap().doc.paths, original.paths);\n assert_eq!(app.session.active().unwrap().doc.work_path, original.work_path);\n assert_eq!(app.session.active().unwrap().history.past_len(), n);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dragging_an_anchor_moves_it_in_one_undoable_step",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_an_anchor_moves_it_in_one_undoable_step -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_path(&mut app);\n let (before, n) = (work(&app), steps(&app));\n drag(&mut app, [40.5, 120.5], [50.5, 130.5], Modifiers::NONE);\n assert_eq!(anchor(&app, 3), Point::new(50.0, 130.0));\n assert_eq!(anchor(&app, 0), Point::new(40.0, 40.0), \"only the dragged anchor moved\");\n assert_eq!(steps(&app), n + 1, \"one history step for the whole drag\");\n assert_eq!((app.ui.direct_selection.target.clone(), app.ui.direct_selection.anchors.clone()), (Some(PathRef::Work), vec![[0, 3]]));\n assert!(app.session.undo());\n assert_eq!(work(&app), before);\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(anchor(&app, 3), Point::new(50.0, 130.0));\n assert_eq!(anchor(&app, 0), Point::new(40.0, 40.0), \"only the dragged anchor moved\");\n assert_eq!(steps(&app), n + 1, \"one history step for the whole drag\");\n assert_eq!((app.ui.direct_selection.target.clone(), app.ui.direct_selection.anchors.clone()), (Some(PathRef::Work), vec![[0, 3]]));\n assert!(app.session.undo());\n assert_eq!(work(&app), before);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "arrow_keys_nudge_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked arrow_keys_nudge_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_path(&mut app);\n save_path(&mut app);\n app.ui.selected_path = Some(\"Saved\".into());\n click(&mut app, [40.0, 120.0], Modifiers::NONE);\n assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved\".into())));\n let (work_before, n) = (work(&app), steps(&app));\n assert!(press(&mut app, egui::Key::ArrowRight, Modifiers::NONE));\n assert!(press(&mut app, egui::Key::ArrowRight, Modifiers::NONE));\n assert_eq!(saved(&app).subpaths[0].knots[3].anchor, Point::new(42.0, 120.0));\n assert_eq!(work(&app), work_before);\n assert_eq!(steps(&app), n + 2);",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved\".into())));\n let (work_before, n) = (work(&app), steps(&app));\n assert!(press(&mut app, egui::Key::ArrowRight, Modifiers::NONE));\n assert!(press(&mut app, egui::Key::ArrowRight, Modifiers::NONE));\n assert_eq!(saved(&app).subpaths[0].knots[3].anchor, Point::new(42.0, 120.0));\n assert_eq!(work(&app), work_before);\n assert_eq!(steps(&app), n + 2);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "selected_saved_and_work_paths_win_overlapping_shape_hits",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked selected_saved_and_work_paths_win_overlapping_shape_hits -- --nocapture",
|
|
"fixture_and_action_excerpt": " for name in [\"Saved\", \"work\"] {\n let mut app = app(Tool::DirectSelection);\n let id = app.run(\"shape.create\", json!({\"kind\":\"rect\", \"rect\":[40,40,80,80]})).unwrap()[\"layer\"].as_u64().unwrap();\n with_path(&mut app);\n save_path(&mut app);\n app.ui.selected_path = Some(name.into());\n let (before_work, before_saved, n) = (work(&app), saved(&app), steps(&app));\n let before_shape = app.run(\"shape.info\", json!({\"layer\":id})).unwrap()[\"path\"].clone();\n drag(&mut app, [40.0, 120.0], [55.0, 130.0], Modifiers::NONE);\n let (actual, unchanged, target) =\n if name == \"Saved\" { (saved(&app), work(&app), PathRef::Saved(\"Saved\".into())) } else { (work(&app), saved(&app), PathRef::Work) };\n assert_eq!(actual.subpaths[0].knots[3].anchor, Point::new(55.0, 130.0));",
|
|
"expected_assertions": [
|
|
" assert_eq!(actual.subpaths[0].knots[3].anchor, Point::new(55.0, 130.0));\n assert_eq!(unchanged, if name == \"Saved\" { before_work.clone() } else { before_saved.clone() });\n assert_eq!(app.ui.direct_selection.target.as_ref(), Some(&target));\n assert_eq!(steps(&app), n + 1);\n assert_eq!(app.run(\"shape.info\", json!({\"layer\":id})).unwrap()[\"path\"], before_shape);\n assert!(app.session.undo());\n assert_eq!(work(&app), before_work);\n assert_eq!(saved(&app), before_saved);\n app.sync_views();\n assert!(app.ui.direct_selection.anchors.is_empty(), \"undo invalidates runtime anchor ownership\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "direct_selection_cannot_apply_to_another_document_or_a_reopened_identity",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked direct_selection_cannot_apply_to_another_document_or_a_reopened_identity -- --nocapture",
|
|
"fixture_and_action_excerpt": " for reopen in [false, true] {\n let mut app = app(Tool::Pen);\n with_path(&mut app);\n let source = app.session.active().unwrap().doc.clone();\n let revision = app.session.active().unwrap().revision;\n start_command_drag(&mut app);\n if reopen {\n app.session.close(0).unwrap();\n }\n app.session.add_document((*source).clone(), None);\n app.session.active_mut().unwrap().revision = revision;\n let (before, n) = (work(&app), steps(&app));",
|
|
"expected_assertions": [
|
|
" assert_ne!(source.id, app.session.active().unwrap().doc.id);\n } else {\n assert_eq!(source.id, app.session.active().unwrap().doc.id, \"a reopened document may preserve its ID\");\n }\n // The frame hook may cancel before the old pointer event arrives.\n app.sync_views();\n assert_eq!(work(&app), before);\n assert_eq!(steps(&app), n);\n assert!(app.ui.pen.is_none(), \"an old release must not start a new Pen draft\");\n if !reopen {\n assert_eq!(app.session.documents()[0].doc.work_path.as_ref(), source.work_path.as_ref());\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "external_revision_cancels_preview_and_preserves_the_new_path",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked external_revision_cancels_preview_and_preserves_the_new_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n with_path(&mut app);\n start_command_drag(&mut app);\n assert!(super::pointer(&mut app, ToolEvent::Move { x: 50.0, y: 130.0, pressure: 1.0 }, Modifiers::COMMAND));\n app.session.execute(\"path.moveAnchors\", json!({\"name\":\"work\", \"anchors\":[[0,0]], \"move\":[-5,7]})).unwrap();\n let (before, n) = (work(&app), steps(&app));\n consume_stale_drag(&mut app);\n assert_eq!(work(&app), before);\n assert_eq!(steps(&app), n);\n assert!(app.ui.pen.is_none());\n}",
|
|
"expected_assertions": [
|
|
" assert!(super::pointer(&mut app, ToolEvent::Move { x: 50.0, y: 130.0, pressure: 1.0 }, Modifiers::COMMAND));\n app.session.execute(\"path.moveAnchors\", json!({\"name\":\"work\", \"anchors\":[[0,0]], \"move\":[-5,7]})).unwrap();\n let (before, n) = (work(&app), steps(&app));\n consume_stale_drag(&mut app);\n assert_eq!(work(&app), before);\n assert_eq!(steps(&app), n);\n assert!(app.ui.pen.is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_path_and_tool_changes_cancel_the_owned_edit",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_path_and_tool_changes_cancel_the_owned_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " for change in [\"layer\", \"path\", \"vectorMask\", \"tool\"] {\n let mut app = app(Tool::Pen);\n with_path(&mut app);\n save_path(&mut app);\n let first = app.session.active().unwrap().active_layer.unwrap();\n app.run(\"layer.new.layer\", json!({})).unwrap();\n let second = app.session.active().unwrap().active_layer.unwrap();\n app.run(\"layer.select\", json!({\"layer\":first.0})).unwrap();\n start_command_drag(&mut app);\n match change {\n \"layer\" => {\n app.session.execute(\"layer.select\", json!({\"layer\":second.0})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(work(&app), before_work, \"{change}\");\n assert_eq!(saved(&app), before_saved, \"{change}\");\n assert_eq!(steps(&app), n, \"{change}\");\n assert!(app.ui.pen.is_none());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closing_a_document_and_changing_marquee_target_discard_old_events",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked closing_a_document_and_changing_marquee_target_discard_old_events -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n with_path(&mut app);\n start_command_drag(&mut app);\n let closed = app.session.close(0).unwrap();\n app.sync_views();\n consume_stale_drag(&mut app);\n assert_eq!(closed.doc.work_path.as_ref().unwrap().subpaths[0].knots[3].anchor, Point::new(40.0, 120.0));\n\n app.session.add_document((*closed.doc).clone(), None);\n app.sync_views();\n save_path(&mut app);\n app.ui.tool = Tool::DirectSelection;",
|
|
"expected_assertions": [
|
|
" assert_eq!(closed.doc.work_path.as_ref().unwrap().subpaths[0].knots[3].anchor, Point::new(40.0, 120.0));\n\n app.session.add_document((*closed.doc).clone(), None);\n app.sync_views();\n assert!(super::pointer(&mut app, ToolEvent::Down { x: 30.0, y: 110.0, pressure: 1.0 }, Modifiers::NONE));\n assert!(matches!(app.ui.direct_selection.drag, Some(Drag::Marquee { .. })));\n app.ui.selected_path = Some(\"Saved\".into());\n let n = steps(&app);\n consume_stale_drag(&mut app);\n assert_eq!(steps(&app), n);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "serialized_anchor_selection_has_no_runtime_ownership_and_is_not_restored",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked serialized_anchor_selection_has_no_runtime_ownership_and_is_not_restored -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_path(&mut app);\n click(&mut app, [40.0, 120.0], Modifiers::NONE);\n let serialized = serde_json::to_value(&app.ui.direct_selection).unwrap();\n assert!(serialized.get(\"owner\").is_none());\n assert!(serialized.get(\"drag\").is_none());\n assert!(serialized.get(\"cancelled_drag\").is_none());\n app.ui.direct_selection = serde_json::from_value(serialized).unwrap();\n assert!(app.ui.direct_selection.owner.is_none());\n super::cancel_stale(&mut app);\n assert!(app.ui.direct_selection.anchors.is_empty());\n assert!(app.ui.direct_selection.target.is_none());",
|
|
"expected_assertions": [
|
|
" assert!(serialized.get(\"owner\").is_none());\n assert!(serialized.get(\"drag\").is_none());\n assert!(serialized.get(\"cancelled_drag\").is_none());\n app.ui.direct_selection = serde_json::from_value(serialized).unwrap();\n assert!(app.ui.direct_selection.owner.is_none());\n super::cancel_stale(&mut app);\n assert!(app.ui.direct_selection.anchors.is_empty());\n assert!(app.ui.direct_selection.target.is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "command_drag_after_failed_pen_commit_preserves_draft_and_existing_work_path",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked command_drag_after_failed_pen_commit_preserves_draft_and_existing_work_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n with_path(&mut app);\n app.ui.extras.snap = false;\n for [x, y] in [[1e40, 0.0], [40.0, 120.0]] {\n tool_event(&mut app, ToolEvent::Down { x, y, pressure: 1.0 }, Modifiers::NONE);\n tool_event(&mut app, ToolEvent::Up { x, y }, Modifiers::NONE);\n }\n let before_draft = app.ui.pen.as_ref().unwrap().knots.clone();\n let (before_work, n, revision) = (work(&app), steps(&app), app.session.active().unwrap().revision);\n // \u2318 off the draft ends it (a press on it would edit it in place, #4022); here that fails.\n tool_event(&mut app, ToolEvent::Down { x: 40.0, y: 40.0, pressure: 1.0 }, Modifiers::COMMAND);\n assert!(app.ui.pen.as_ref().unwrap().commit_failed);",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.pen.as_ref().unwrap().commit_failed);\n assert!(app.ui.direct_selection.drag.is_none(), \"the press must not go on to edit the old work path\");\n assert!(app.ui.direct_selection.cancelled_drag);\n tool_event(&mut app, ToolEvent::Move { x: 60.0, y: 140.0, pressure: 1.0 }, Modifiers::COMMAND);\n tool_event(&mut app, ToolEvent::Up { x: 60.0, y: 140.0 }, Modifiers::COMMAND);\n assert_eq!(app.ui.pen.as_ref().unwrap().knots, before_draft);\n assert_eq!(work(&app), before_work);\n assert_eq!(steps(&app), n);\n assert_eq!(app.session.active().unwrap().revision, revision);\n assert!(app.ui.status_error);\n assert!(!app.ui.direct_selection.cancelled_drag);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "switching_between_selection_and_convert_tools_cancels_an_in_flight_drag",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked switching_between_selection_and_convert_tools_cancels_an_in_flight_drag -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (from, to) in [(Tool::DirectSelection, Tool::ConvertPoint), (Tool::ConvertPoint, Tool::DirectSelection)] {\n let mut app = app(from);\n with_path(&mut app);\n let (before, n) = (work(&app), steps(&app));\n tool_event(&mut app, ToolEvent::Down { x: 40.0, y: 120.0, pressure: 1.0 }, Modifiers::NONE);\n assert!(app.ui.direct_selection.drag.is_some());\n app.ui.tool = to;\n app.sync_views();\n consume_stale_drag(&mut app);\n assert_eq!((work(&app), steps(&app)), (before, n));\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.direct_selection.drag.is_some());\n app.ui.tool = to;\n app.sync_views();\n consume_stale_drag(&mut app);\n assert_eq!((work(&app), steps(&app)), (before, n));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_convert_point_tool_edits_selected_saved_paths_without_changing_the_work_path",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_convert_point_tool_edits_selected_saved_paths_without_changing_the_work_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::ConvertPoint);\n with_path(&mut app);\n save_path(&mut app);\n app.ui.selected_path = Some(\"Saved\".into());\n let (before_work, before_saved, n) = (work(&app), saved(&app), steps(&app));\n click(&mut app, [120.0, 40.0], Modifiers::NONE);\n assert_eq!(saved(&app).subpaths[0].knots[1], photocraft_doc::Knot::corner(120.0, 40.0));\n assert_eq!(work(&app), before_work);\n assert_eq!(steps(&app), n + 1);\n assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved\".into())));\n assert!(app.session.undo());\n assert_eq!(saved(&app), before_saved);",
|
|
"expected_assertions": [
|
|
" assert_eq!(saved(&app).subpaths[0].knots[1], photocraft_doc::Knot::corner(120.0, 40.0));\n assert_eq!(work(&app), before_work);\n assert_eq!(steps(&app), n + 1);\n assert_eq!(app.ui.direct_selection.target, Some(PathRef::Saved(\"Saved\".into())));\n assert!(app.session.undo());\n assert_eq!(saved(&app), before_saved);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "changing_the_channel_vector_mask_target_cancels_an_owned_edit",
|
|
"path": "crates/ui-egui/src/direct_select_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked changing_the_channel_vector_mask_target_cancels_an_owned_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_path(&mut app);\n tool_event(&mut app, ToolEvent::Down { x: 40.0, y: 120.0, pressure: 1.0 }, Modifiers::NONE);\n assert!(app.ui.direct_selection.drag.is_some());\n let (before, n) = (work(&app), steps(&app));\n app.session.active_mut().unwrap().channel_view.target = photocraft_engine::channel_cmds::ChannelTarget::VectorMask;\n assert!(!app.ui.vector_mask_target, \"the channel target can change before the UI syncs its mask flag\");\n consume_stale_drag(&mut app);\n assert_eq!((work(&app), steps(&app)), (before, n));\n}",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.direct_selection.drag.is_some());\n let (before, n) = (work(&app), steps(&app));\n app.session.active_mut().unwrap().channel_view.target = photocraft_engine::channel_cmds::ChannelTarget::VectorMask;\n assert!(!app.ui.vector_mask_target, \"the channel target can change before the UI syncs its mask flag\");\n consume_stale_drag(&mut app);\n assert_eq!((work(&app), steps(&app)), (before, n));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/direct_select_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "esc_ends_a_pen_path_and_keeps_it",
|
|
"path": "crates/ui-egui/src/input_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked esc_ends_a_pen_path_and_keeps_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().ui.tool = crate::state::Tool::Pen;\n let owner = crate::vector_ui::capture_pen_owner(h.state());\n h.state_mut().ui.pen =\n Some(crate::vector_ui::PenPath { knots: vec![[[50.0, 50.0]; 3], [[150.0, 50.0]; 3], [[150.0, 120.0]; 3]], owner, ..Default::default() });\n h.key_press(Key::Escape);\n h.run_steps(2);\n assert!(h.state().ui.pen.is_none(), \"the Pen leaves drawing state\");\n let doc = &h.state().session.active().unwrap().doc;\n let path = doc.work_path.as_ref().expect(\"the path is kept as the work path\");\n assert_eq!(path.subpaths.len(), 1);\n assert!(!path.subpaths[0].closed, \"left open\");",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.pen.is_none(), \"the Pen leaves drawing state\");\n let doc = &h.state().session.active().unwrap().doc;\n let path = doc.work_path.as_ref().expect(\"the path is kept as the work path\");\n assert_eq!(path.subpaths.len(), 1);\n assert!(!path.subpaths[0].closed, \"left open\");\n assert_eq!(path.subpaths[0].knots.len(), 3);\n assert_eq!(h.state().ui.selected_path.as_deref(), Some(\"work\"));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/input_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pen_shows_the_close_path_pointer_over_the_first_anchor",
|
|
"path": "crates/ui-egui/src/input_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pen_shows_the_close_path_pointer_over_the_first_anchor -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().ui.tool = crate::state::Tool::Pen;\n let owner = crate::vector_ui::capture_pen_owner(h.state());\n h.state_mut().ui.pen = Some(crate::vector_ui::PenPath { knots: vec![[[50.0, 50.0]; 3], [[150.0, 50.0]; 3]], owner, ..Default::default() });\n let screen = |h: &Harness<'static, PhotocraftApp>, x: f32, y: f32| {\n let v = &h.state().ui.views[0];\n let c = h.state().last_canvas_rect.center();\n pos2(c.x + (x - v.center[0]) * v.zoom, c.y + (y - v.center[1]) * v.zoom)\n };\n let pointer = |h: &mut Harness<'static, PhotocraftApp>, x: f32, y: f32| {\n let p = screen(h, x, y);\n h.hover_at(p);",
|
|
"expected_assertions": [
|
|
" assert_eq!(close.0, egui::CursorIcon::Crosshair, \"the fallback under the bitmap\");\n assert!(close.1.is_some(), \"a bitmap\");\n let elsewhere = pointer(&mut h, 200.0, 200.0);\n assert_ne!(elsewhere.1, close.1, \"empty canvas: the plain Pen pointer\");\n assert_ne!(pointer(&mut h, 150.0, 50.0).1, close.1, \"the last anchor doesn't close\");\n assert_eq!(pointer(&mut h, 50.0, 50.0), close, \"back on the first anchor\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/input_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "real_freeform_freehand_and_alt_straight_segments_append_to_the_owned_saved_path_once",
|
|
"path": "crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked real_freeform_freehand_and_alt_straight_segments_append_to_the_owned_saved_path_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = freeform_harness();\n let original = h.state().session.active().unwrap().doc.clone();\n let n = h.state().session.active().unwrap().history.past_len();\n freeform_run_and_straight_click(&mut h);\n h.event(Event::ModifiersChanged(Modifiers::NONE));\n h.run_steps(3);\n let app = h.state();\n assert!(!active(app) && app.ui.pen.is_none());\n let st = app.session.active().unwrap();\n assert_eq!(st.doc.work_path, original.work_path);\n let path = &st.doc.paths[0].path;\n assert_eq!(path.subpaths.len(), 2);",
|
|
"expected_assertions": [
|
|
" assert!(!active(app) && app.ui.pen.is_none());\n let st = app.session.active().unwrap();\n assert_eq!(st.doc.work_path, original.work_path);\n let path = &st.doc.paths[0].path;\n assert_eq!(path.subpaths.len(), 2);\n assert_eq!(path.subpaths[0], original.paths[0].path.subpaths[0]);\n let knots = &path.subpaths[1].knots;\n assert_eq!(knots.last().unwrap().anchor, photocraft_geom::Point::new(180.0, 100.0));\n assert_eq!(knots.last().unwrap().in_ctrl, knots.last().unwrap().anchor);\n assert_eq!(knots[knots.len() - 2].out_ctrl, knots[knots.len() - 2].anchor);\n assert_eq!(st.history.past_len(), n + 1);\n assert!(h.state_mut().session.undo());\n assert_eq!(h.state().session.active().unwrap().doc.paths, original.paths);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "real_freeform_stale_target_source_revision_and_document_cancel_without_finishing_elsewhere",
|
|
"path": "crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked real_freeform_stale_target_source_revision_and_document_cancel_without_finishing_elsewhere -- --nocapture",
|
|
"fixture_and_action_excerpt": " for change in [\"target\", \"source\", \"revision\", \"document\"] {\n let mut h = freeform_harness();\n freeform_run_and_straight_click(&mut h);\n let app = h.state_mut();\n match change {\n \"target\" => app.ui.selected_path = Some(\"work\".into()),\n \"source\" => {\n let st = app.session.active_mut().unwrap();\n st.doc = std::sync::Arc::new((*st.doc).clone());\n }\n \"revision\" => app.session.active_mut().unwrap().revision += 1,\n \"document\" => {",
|
|
"expected_assertions": [
|
|
" assert!(!active(app) && app.ui.pen.is_none(), \"{change}: no stale trace remains\");\n assert!(std::sync::Arc::ptr_eq(&source, &app.session.active().unwrap().doc), \"{change}: late input changed document pixels or paths\");\n assert_eq!(app.session.active().unwrap().history.past_len(), n, \"{change}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "another_freeform_trace_cannot_replace_a_failed_owned_draft_or_retry_it_automatically",
|
|
"path": "crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked another_freeform_trace_cannot_replace_a_failed_owned_draft_or_retry_it_automatically -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool = Tool::FreeformPen;\n app.ui.extras.snap = false;\n for [x, y] in [[40.0, 60.0], [1e40, 60.0], [140.0, 80.0]] {\n event(&mut app, \"down\", x, y, Modifiers::ALT);\n event(&mut app, \"up\", x, y, Modifiers::ALT);\n }\n modifiers(&mut app, Modifiers::NONE);\n let failed = app.ui.pen.clone().expect(\"invalid fitted trace must remain available\");\n assert!(failed.commit_failed && failed.owner.is_some());\n assert!(!active(&app));\n let source = app.session.active().unwrap().doc.clone();",
|
|
"expected_assertions": [
|
|
" assert!(failed.commit_failed && failed.owner.is_some());\n assert!(!active(&app));\n let source = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n let journal = app.session.journal.len();\n assert!(!active(&app), \"pending fitted draft owns the next drawing attempt\");\n }\n modifiers(&mut app, Modifiers::NONE);\n assert_eq!(app.ui.pen.as_ref(), Some(&failed));\n assert!(std::sync::Arc::ptr_eq(&source, &app.session.active().unwrap().doc));\n assert_eq!(app.session.active().unwrap().history.past_len(), n);\n assert_eq!(app.session.journal.len(), journal, \"drawing must not retry the failed engine command\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_alt_release_in_the_next_press_keeps_the_failed_fit",
|
|
"path": "crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_alt_release_in_the_next_press_keeps_the_failed_fit -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool = Tool::FreeformPen;\n for [x, y] in [[40.0, 60.0], [1e40, 60.0], [140.0, 80.0]] {\n event(&mut app, \"down\", x, y, Modifiers::ALT);\n event(&mut app, \"up\", x, y, Modifiers::ALT);\n }\n assert!(active(&app));\n let source = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n // No separate modifier-change event: this press both releases Alt and tries a new trace.\n event(&mut app, \"down\", 200.0, 100.0, Modifiers::NONE);\n let failed = app.ui.pen.clone().expect(\"failed fit must survive the press that finished it\");",
|
|
"expected_assertions": [
|
|
" assert!(active(&app));\n let source = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n // No separate modifier-change event: this press both releases Alt and tries a new trace.\n assert!(failed.commit_failed && failed.owner.is_some());\n assert!(!active(&app));\n let journal = app.session.journal.len();\n event(&mut app, \"move\", 240.0, 120.0, Modifiers::NONE);\n event(&mut app, \"up\", 240.0, 120.0, Modifiers::NONE);\n assert_eq!(app.ui.pen.as_ref(), Some(&failed));\n assert_eq!(app.session.journal.len(), journal);\n assert!(std::sync::Arc::ptr_eq(&source, &app.session.active().unwrap().doc));\n assert_eq!(app.session.active().unwrap().history.past_len(), n);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/lasso_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "clicking_the_vector_mask_targets_it_for_the_path_tools",
|
|
"path": "crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked clicking_the_vector_mask_targets_it_for_the_path_tools -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (s, masked, _) = session();\n let mut h = harness(s, 0, 1.0, 290.0);\n let r = mask_rect(&h, masked, MaskKind::Vector);\n click_with(&mut h, r.center(), Modifiers::NONE);\n assert!(h.state().ui.vector_mask_target && !h.state().ui.mask_target);\n assert_eq!(h.state().ui.selected_path.as_deref(), Some(\"layer\"), \"the Paths panel selects its path\");\n assert!(near(super::brackets(&h.ctx).unwrap(), r.expand(3.0)), \"brackets on the vector mask\");\n assert_eq!(crate::canvas::paint_target(h.state()), json!(\"pixels\"));\n // Path Selection moves the vector mask.\n crate::vector_ui::path_selection_finish(h.state_mut(), [30.0, 30.0], [35.0, 32.0]);\n let k = layer(&h, masked).vector_mask.unwrap().path.subpaths[0].knots[0].anchor;\n assert_eq!((k.x, k.y), (25.0, 12.0));",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.vector_mask_target && !h.state().ui.mask_target);\n assert_eq!(h.state().ui.selected_path.as_deref(), Some(\"layer\"), \"the Paths panel selects its path\");\n assert!(near(super::brackets(&h.ctx).unwrap(), r.expand(3.0)), \"brackets on the vector mask\");\n assert_eq!(crate::canvas::paint_target(h.state()), json!(\"pixels\"));\n // Path Selection moves the vector mask.\n crate::vector_ui::path_selection_finish(h.state_mut(), [30.0, 30.0], [35.0, 32.0]);\n let k = layer(&h, masked).vector_mask.unwrap().path.subpaths[0].knots[0].anchor;\n assert_eq!((k.x, k.y), (25.0, 12.0));\n // The Pen adds a subpath to it.\n let owner = crate::vector_ui::capture_pen_owner(h.state());\n h.state_mut().ui.pen =\n assert_eq!(layer(&h, masked).vector_mask.unwrap().path.subpaths.len(), 2);\n assert!(h.state().session.active().unwrap().doc.work_path.is_none(), \"not a work path\");\n h.run_steps(2);\n // The pixel mask and the layer thumbnail take the brackets back.\n let m = mask_rect(&h, masked, MaskKind::Pixel);\n assert!(h.state().ui.mask_target && !h.state().ui.vector_mask_target);\n assert!(near(super::brackets(&h.ctx).unwrap(), m.expand(3.0)));\n click_with(&mut h, r.center(), Modifiers::NONE);\n let p = layer_thumb_center(&h, masked);\n click_with(&mut h, p, Modifiers::NONE);\n assert!(!h.state().ui.mask_target && !h.state().ui.vector_mask_target);\n // Deleting the vector mask drops the target.\n click_with(&mut h, r.center(), Modifiers::NONE);\n assert!(h.state().ui.vector_mask_target);\n h.state_mut().run(\"layer.vectorMask.delete\", json!({\"layer\": masked})).unwrap();\n h.run_steps(2);\n assert!(!h.state().ui.vector_mask_target);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/mask_thumbs_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cmd_enter_while_drawing_finishes_the_path_and_loads_it",
|
|
"path": "crates/ui-egui/src/path_selection_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked cmd_enter_while_drawing_finishes_the_path_and_loads_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().ui.tool = Tool::Pen;\n let p = |x: f64, y: f64| [[x, y], [x, y], [x, y]];\n let owner = crate::vector_ui::capture_pen_owner(h.state());\n h.state_mut().ui.pen = Some(PenPath { knots: vec![p(20.0, 20.0), p(120.0, 20.0), p(120.0, 80.0)], owner, ..Default::default() });\n h.run_steps(2);\n press(&mut h, Key::Enter, command());\n let app = h.state();\n assert!(app.ui.pen.is_none(), \"the pen path was finished\");\n assert!(app.session.active().unwrap().doc.work_path.is_some(), \"into the work path\");\n assert!(app.session.active().unwrap().doc.selection.is_some(), \"and loaded as a selection: {}\", app.ui.status);\n // Plain \u21a9 still only finishes a path.",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.pen.is_none(), \"the pen path was finished\");\n assert!(app.session.active().unwrap().doc.work_path.is_some(), \"into the work path\");\n assert!(app.session.active().unwrap().doc.selection.is_some(), \"and loaded as a selection: {}\", app.ui.status);\n // Plain \u21a9 still only finishes a path.\n let mut h = harness();\n h.state_mut().ui.tool = Tool::Pen;\n assert!(h.state().session.active().unwrap().doc.work_path.is_some());\n assert!(h.state().session.active().unwrap().doc.selection.is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/path_selection_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_and_path_selection_releases_cannot_edit_a_different_document",
|
|
"path": "crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_and_path_selection_releases_cannot_edit_a_different_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::FreeformPen, Tool::PathSelection] {\n let mut app = app(tool);\n app.run(\"path.set\", json!({\"path\": {\"subpaths\": [{\"knots\": [[20, 20], [50, 35], [90, 80]]}]}})).unwrap();\n let original = app.session.active().unwrap().doc.work_path.clone();\n down(&mut app);\n app.session.execute(\"file.new\", json!({\"width\": 200, \"height\": 200})).unwrap();\n app.sync_views();\n let revision = app.session.active().unwrap().revision;\n tool_event(&mut app, ToolEvent::Up { x: 100.0, y: 100.0 }, Modifiers::NONE);\n assert!(app.drag.is_none());\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n assert_eq!(app.session.active().unwrap().revision, revision);",
|
|
"expected_assertions": [
|
|
" assert!(app.drag.is_none());\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n assert_eq!(app.session.active().unwrap().revision, revision);\n assert_eq!(app.session.documents()[0].doc.work_path, original);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_release_cancels_after_revision_or_target_change",
|
|
"path": "crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_release_cancels_after_revision_or_target_change -- --nocapture",
|
|
"fixture_and_action_excerpt": " for change in [\"revision\", \"selected\", \"mode\"] {\n let mut app = app(Tool::FreeformPen);\n down(&mut app);\n match change {\n \"revision\" => {\n app.run(\"path.set\", json!({\"path\": {\"subpaths\": [{\"knots\": [[10, 10], [15, 15]]}]}})).unwrap();\n }\n \"selected\" => app.ui.selected_path = Some(\"Another path\".into()),\n _ => app.ui.tool_options.vector_mode = \"shape\".into(),\n }\n let before = app.session.active().unwrap().doc.clone();\n let revision = app.session.active().unwrap().revision;",
|
|
"expected_assertions": [
|
|
" assert!(app.drag.is_none());\n assert_eq!(app.session.active().unwrap().doc.work_path, before.work_path);\n assert_eq!(app.session.active().unwrap().doc.layers, before.layers);\n assert_eq!(app.session.active().unwrap().revision, revision);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_valid_release_is_one_undoable_path_edit",
|
|
"path": "crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_valid_release_is_one_undoable_path_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::FreeformPen);\n let history = app.session.active().unwrap().history.entries().len();\n down(&mut app);\n tool_event(&mut app, ToolEvent::Up { x: 100.0, y: 100.0 }, Modifiers::NONE);\n assert!(app.session.active().unwrap().doc.work_path.is_some());\n assert_eq!(app.session.active().unwrap().history.entries().len(), history + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n app.run(\"edit.redo\", json!({})).unwrap();\n assert!(app.session.active().unwrap().doc.work_path.is_some());\n}",
|
|
"expected_assertions": [
|
|
" assert!(app.session.active().unwrap().doc.work_path.is_some());\n assert_eq!(app.session.active().unwrap().history.entries().len(), history + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n app.run(\"edit.redo\", json!({})).unwrap();\n assert!(app.session.active().unwrap().doc.work_path.is_some());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "frame_cancellation_consumes_old_events_after_switching_tools",
|
|
"path": "crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked frame_cancellation_consumes_old_events_after_switching_tools -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::FreeformPen);\n down(&mut app);\n app.ui.tool = Tool::PolygonLasso;\n app.ui.polygon = vec![[10.0, 10.0], [20.0, 20.0]];\n let polygon = app.ui.polygon.clone();\n app.sync_views();\n assert!(app.drag.is_none());\n let modifiers = Modifiers { alt: true, ..Modifiers::NONE };\n tool_event(&mut app, ToolEvent::Move { x: 100.0, y: 100.0, pressure: 1.0 }, modifiers);\n tool_event(&mut app, ToolEvent::Up { x: 100.0, y: 100.0 }, modifiers);\n assert_eq!(app.ui.polygon, polygon, \"old pointer events must not become a Polygonal Lasso gesture\");\n assert!(!app.cancelled_vector_drag);",
|
|
"expected_assertions": [
|
|
" assert!(app.drag.is_none());\n let modifiers = Modifiers { alt: true, ..Modifiers::NONE };\n tool_event(&mut app, ToolEvent::Move { x: 100.0, y: 100.0, pressure: 1.0 }, modifiers);\n tool_event(&mut app, ToolEvent::Up { x: 100.0, y: 100.0 }, modifiers);\n assert_eq!(app.ui.polygon, polygon, \"old pointer events must not become a Polygonal Lasso gesture\");\n assert!(!app.cancelled_vector_drag);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_gesture_owner_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "selected_work_and_saved_paths_append_pen_and_curvature_components_once",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked selected_work_and_saved_paths_append_pen_and_curvature_components_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::Pen, Tool::CurvaturePen] {\n for name in [\"work\", \"Saved drawing\"] {\n let mut app = app(tool);\n seed(&mut app, \"work\", 20.0);\n seed(&mut app, \"Saved drawing\", 40.0);\n app.ui.selected_path = Some(name.into());\n let (original, other) = (path(&app, name), path(&app, if name == \"work\" { \"Saved drawing\" } else { \"work\" }));\n let n = steps(&app);\n draft(&mut app);\n assert_eq!(steps(&app), n, \"placing anchors is not a history step\");\n vector_ui::pen_commit(&mut app, false);\n let after = path(&app, name);",
|
|
"expected_assertions": [
|
|
" assert_eq!(steps(&app), n, \"placing anchors is not a history step\");\n vector_ui::pen_commit(&mut app, false);\n let after = path(&app, name);\n assert_eq!(after.subpaths.len(), 2, \"{tool:?}: {name}\");\n assert_eq!(after.subpaths[0], original.subpaths[0]);\n let anchors: Vec<_> = after.subpaths[1].knots.iter().map(|k| [k.anchor.x, k.anchor.y]).collect();\n assert_eq!(anchors, [[30.0, 60.0], [130.0, 60.0]]);\n assert_eq!(path(&app, if name == \"work\" { \"Saved drawing\" } else { \"work\" }), other);\n assert_eq!(app.ui.selected_path.as_deref(), Some(name));\n assert_eq!(steps(&app), n + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, name), original);\n app.run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(path(&app, name), after);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "deselected_work_path_is_replaced_without_touching_saved_paths",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked deselected_work_path_is_replaced_without_touching_saved_paths -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n seed(&mut app, \"work\", 20.0);\n seed(&mut app, \"Saved drawing\", 40.0);\n app.ui.selected_path = None;\n let (before, saved, n) = (path(&app, \"work\"), path(&app, \"Saved drawing\"), steps(&app));\n draft(&mut app);\n vector_ui::pen_commit(&mut app, false);\n let after = path(&app, \"work\");\n assert_eq!(after.subpaths.len(), 1);\n assert_eq!(after.subpaths[0].knots[0].anchor.y, 60.0);\n assert_eq!(path(&app, \"Saved drawing\"), saved);\n assert_eq!(steps(&app), n + 1);",
|
|
"expected_assertions": [
|
|
" assert_eq!(after.subpaths.len(), 1);\n assert_eq!(after.subpaths[0].knots[0].anchor.y, 60.0);\n assert_eq!(path(&app, \"Saved drawing\"), saved);\n assert_eq!(steps(&app), n + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, \"work\"), before);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "captured_path_and_shape_mode_do_not_follow_later_ui_selection",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked captured_path_and_shape_mode_do_not_follow_later_ui_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " for shape in [false, true] {\n let mut app = app(Tool::Pen);\n seed(&mut app, \"work\", 20.0);\n seed(&mut app, \"Saved drawing\", 40.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n app.ui.tool_options.vector_mode = if shape { \"shape\" } else { \"path\" }.into();\n let (work, saved, n) = (path(&app, \"work\"), path(&app, \"Saved drawing\"), steps(&app));\n click(&mut app, 30.0, 60.0);\n app.ui.selected_path = Some(\"work\".into());\n app.ui.tool_options.vector_mode = if shape { \"path\" } else { \"shape\" }.into();\n app.ui.vector_mask_target = true;\n click(&mut app, 130.0, 60.0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(path(&app, \"work\"), work);\n if shape {\n let st = app.session.active().unwrap();\n assert!(matches!(st.doc.layer(st.active_layer.unwrap()).unwrap().content, LayerContent::Shape(_)));\n assert_eq!(path(&app, \"Saved drawing\"), saved);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"layer\"));\n } else {\n assert_eq!(path(&app, \"Saved drawing\").subpaths.len(), 2);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n }\n assert_eq!(steps(&app), n + 1);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "captured_pen_paint_preserves_float_colour_and_alpha_after_toolbar_changes",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked captured_pen_paint_preserves_float_colour_and_alpha_after_toolbar_changes -- --nocapture",
|
|
"fixture_and_action_excerpt": " for closed in [false, true] {\n let mut app = app(Tool::Pen);\n app.ui.tool_options.vector_mode = \"shape\".into();\n app.ui.tool_options.shape_fill = true;\n app.ui.tool_options.stroke_width = 3.0;\n let foreground = [0.12345, 0.34567, 0.56789, 0.375];\n let background = [0.76543, 0.54321, 0.32109, 0.625];\n app.session.tools.foreground = foreground;\n app.session.tools.background = background;\n click(&mut app, 30.0, 60.0);\n app.session.tools.foreground = [1.0; 4];\n app.session.tools.background = [0.0; 4];",
|
|
"expected_assertions": [
|
|
" assert_eq!(shape.fill, closed.then(|| paint(foreground)));\n assert_eq!(shape.stroke.as_ref().unwrap().paint, paint(if closed { background } else { foreground }));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stale_drafts_are_cancelled_before_tool_switch_or_pointer_input",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked stale_drafts_are_cancelled_before_tool_switch_or_pointer_input -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::Pen, Tool::CurvaturePen] {\n for change in [\"document\", \"revision\", \"reopen\"] {\n let mut app = app(tool);\n seed(&mut app, \"Saved drawing\", 20.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n draft(&mut app);\n let source = app.session.active().unwrap().doc.clone();\n let revision = app.session.active().unwrap().revision;\n match change {\n \"document\" => {\n app.session.execute(\"file.new\", json!({\"width\": 200, \"height\": 200})).unwrap();\n app.session.execute(\"path.set\", json!({\"name\":\"Saved drawing\", \"path\": {\"subpaths\": [{\"knots\": [[50, 50], [80, 80]]}]}})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.pen.is_none(), \"{tool:?}: {change}\");\n vector_ui::pen_move(&mut app, 160.0, 80.0);\n vector_ui::curvature_move(&mut app, 160.0, 80.0);\n vector_ui::pen_up(&mut app);\n assert!(std::sync::Arc::ptr_eq(&app.session.active().unwrap().doc, ¤t));\n assert_eq!(steps(&app), n);\n assert_eq!(source.paths[0].path.subpaths.len(), 1);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "sync_views_and_input_apis_discard_unowned_or_closed_document_drafts",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked sync_views_and_input_apis_discard_unowned_or_closed_document_drafts -- --nocapture",
|
|
"fixture_and_action_excerpt": " for entry in [\"sync\", \"move\", \"up\", \"commit\", \"undo\", \"toggle\", \"down\"] {\n let mut app = app(Tool::CurvaturePen);\n draft(&mut app);\n app.session.close(0).unwrap();\n match entry {\n \"sync\" => app.sync_views(),\n \"move\" => vector_ui::curvature_move(&mut app, 160.0, 80.0),\n \"up\" => vector_ui::curvature_up(&mut app),\n \"commit\" => vector_ui::pen_commit(&mut app, false),\n \"undo\" => {\n assert!(vector_ui::pen_undo_last_point(&mut app));\n }",
|
|
"expected_assertions": [
|
|
" assert!(vector_ui::pen_undo_last_point(&mut app));\n }\n \"toggle\" => vector_ui::curvature_toggle(&mut app, 30.0, 60.0),\n \"down\" => vector_ui::curvature_down(&mut app, 160.0, 80.0),\n assert!(app.ui.pen.is_none(), \"{entry}\");\n }\n let mut app = app(Tool::Pen);\n draft(&mut app);\n assert!(app.ui.pen.is_none());\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n assert_eq!(steps(&app), n);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "same_named_saved_paths_do_not_share_selection_or_drafts_across_tabs",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked same_named_saved_paths_do_not_share_selection_or_drafts_across_tabs -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n seed(&mut app, \"Saved drawing\", 20.0);\n let first = path(&app, \"Saved drawing\");\n app.run(\"file.new\", json!({\"width\":200,\"height\":200})).unwrap();\n seed(&mut app, \"Saved drawing\", 90.0);\n let second = path(&app, \"Saved drawing\");\n assert!(app.session.set_active(0));\n app.sync_views();\n app.ui.selected_path = Some(\"Saved drawing\".into());\n draft(&mut app);\n assert!(app.session.set_active(1));\n app.sync_views();",
|
|
"expected_assertions": [
|
|
" assert!(app.session.set_active(0));\n app.sync_views();\n app.ui.selected_path = Some(\"Saved drawing\".into());\n draft(&mut app);\n assert!(app.session.set_active(1));\n app.sync_views();\n assert!(app.ui.selected_path.is_none());\n assert!(app.ui.pen.is_none());\n let n = steps(&app);\n vector_ui::pen_commit(&mut app, false);\n assert_eq!(path(&app, \"Saved drawing\"), second);\n assert_eq!(steps(&app), n);\n // A fresh drawing without explicitly selecting B's saved path creates a work path.\n draft(&mut app);\n vector_ui::pen_commit(&mut app, false);\n assert_eq!(path(&app, \"Saved drawing\"), second);\n assert_eq!(path(&app, \"work\").subpaths[0].knots[0].anchor.y, 60.0);\n assert!(app.session.set_active(0));\n app.sync_views();\n assert!(app.ui.selected_path.is_none());\n assert_eq!(path(&app, \"Saved drawing\"), first);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reopened_same_id_and_revision_do_not_reuse_the_saved_path_selection",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked reopened_same_id_and_revision_do_not_reuse_the_saved_path_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n seed(&mut app, \"Saved drawing\", 20.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n let original = path(&app, \"Saved drawing\");\n draft(&mut app);\n let closed = app.session.close(0).unwrap();\n // Recovery can preserve both the document ID and revision before another frame is drawn.\n app.session.add_document((*closed.doc).clone(), None);\n app.session.active_mut().unwrap().revision = closed.revision;\n assert_eq!(app.session.active().unwrap().doc.id, closed.doc.id);\n app.sync_views();\n assert!(app.ui.selected_path.is_none());",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.session.active().unwrap().doc.id, closed.doc.id);\n app.sync_views();\n assert!(app.ui.selected_path.is_none());\n assert!(app.ui.pen.is_none());\n draft(&mut app);\n vector_ui::pen_commit(&mut app, false);\n assert_eq!(path(&app, \"Saved drawing\"), original);\n assert_eq!(path(&app, \"work\").subpaths[0].knots[0].anchor.y, 60.0);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "ordinary_path_edits_undo_and_redo_preserve_the_explicit_saved_path_selection",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked ordinary_path_edits_undo_and_redo_preserve_the_explicit_saved_path_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n seed(&mut app, \"Saved drawing\", 20.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n let original = path(&app, \"Saved drawing\");\n let revision = app.session.active().unwrap().revision;\n seed(&mut app, \"Saved drawing\", 90.0);\n assert!(app.session.active().unwrap().revision > revision);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n let changed = path(&app, \"Saved drawing\");\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, \"Saved drawing\"), original);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));",
|
|
"expected_assertions": [
|
|
" assert!(app.session.active().unwrap().revision > revision);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n let changed = path(&app, \"Saved drawing\");\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, \"Saved drawing\"), original);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n app.run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(path(&app, \"Saved drawing\"), changed);\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n app.sync_views();\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"Saved drawing\"));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "failed_pen_and_curvature_commits_keep_the_exact_draft_and_do_not_retry_each_frame",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked failed_pen_and_curvature_commits_keep_the_exact_draft_and_do_not_retry_each_frame -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::Pen, Tool::CurvaturePen] {\n let mut app = app(tool);\n click(&mut app, 30.0, 60.0);\n click(&mut app, 1e40, 60.0);\n let (before, original, n) = (app.session.active().unwrap().doc.clone(), app.ui.pen.clone().unwrap(), steps(&app));\n vector_ui::pen_commit(&mut app, false);\n let failed = app.ui.pen.as_ref().expect(\"invalid geometry leaves an editable draft\");\n assert_eq!(failed.knots, original.knots);\n assert_eq!(failed.unlinked, original.unlinked);\n assert_eq!(failed.owner, original.owner);\n assert!(failed.commit_failed && app.ui.status_error);\n assert!(std::sync::Arc::ptr_eq(&before, &app.session.active().unwrap().doc));",
|
|
"expected_assertions": [
|
|
" assert_eq!(failed.knots, original.knots);\n assert_eq!(failed.unlinked, original.unlinked);\n assert_eq!(failed.owner, original.owner);\n assert!(failed.commit_failed && app.ui.status_error);\n assert!(std::sync::Arc::ptr_eq(&before, &app.session.active().unwrap().doc));\n assert_eq!(steps(&app), n);\n app.ui.tool = Tool::Brush;\n let journal = app.session.journal.len();\n vector_ui::finish_pen_if_left(&mut app);\n assert_eq!(app.session.journal.len(), journal, \"tool switch must not continually retry a failing commit\");\n assert!(vector_ui::path_to_selection(&mut app, Value::Null).is_err(), \"a failed draft cannot select an unrelated path\");\n app.ui.pen.as_mut().unwrap().knots[1] = [[130.0, 60.0]; 3];\n vector_ui::pen_commit(&mut app, false);\n assert!(app.ui.pen.is_none());\n assert_eq!(path(&app, \"work\").subpaths[0].knots[1].anchor.x, 130.0);\n assert_eq!(steps(&app), n + 1);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "ordinary_tool_switch_commits_the_owned_draft_once",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked ordinary_tool_switch_commits_the_owned_draft_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::Pen, Tool::CurvaturePen] {\n let mut app = app(tool);\n draft(&mut app);\n let n = steps(&app);\n app.ui.tool = Tool::Brush;\n vector_ui::finish_pen_if_left(&mut app);\n vector_ui::finish_pen_if_left(&mut app);\n assert_eq!(path(&app, \"work\").subpaths[0].knots.len(), 2);\n assert_eq!(steps(&app), n + 1);\n assert!(app.ui.pen.is_none());\n }\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(path(&app, \"work\").subpaths[0].knots.len(), 2);\n assert_eq!(steps(&app), n + 1);\n assert!(app.ui.pen.is_none());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "selected_saved_paths_move_and_free_transform_without_changing_work_or_shape",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked selected_saved_paths_move_and_free_transform_without_changing_work_or_shape -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::PathSelection, Tool::DirectSelection] {\n let mut app = app(tool);\n app.run(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [110, 110, 50, 40]})).unwrap();\n let shape = app.run(\"shape.info\", json!({})).unwrap();\n seed(&mut app, \"work\", 20.0);\n seed(&mut app, \"Saved drawing\", 40.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n let (original, work, n) = (path(&app, \"Saved drawing\"), path(&app, \"work\"), steps(&app));\n let (params, selected) = vector_ui::free_transform_path(&app).unwrap();\n assert_eq!(params, json!({\"name\":\"Saved drawing\"}));\n assert_eq!(selected, original);\n vector_ui::path_selection_finish(&mut app, [0.0, 0.0], [10.4, -4.6]);",
|
|
"expected_assertions": [
|
|
" assert_eq!(params, json!({\"name\":\"Saved drawing\"}));\n assert_eq!(selected, original);\n vector_ui::path_selection_finish(&mut app, [0.0, 0.0], [10.4, -4.6]);\n let moved = path(&app, \"Saved drawing\");\n for (a, b) in original.subpaths[0].knots.iter().zip(&moved.subpaths[0].knots) {\n assert_eq!(b.anchor.x, a.anchor.x + 10.0);\n assert_eq!(b.anchor.y, a.anchor.y - 5.0);\n assert_eq!(b.in_ctrl.x, a.in_ctrl.x + 10.0);\n assert_eq!(b.out_ctrl.y, a.out_ctrl.y - 5.0);\n }\n assert_eq!(path(&app, \"work\"), work);\n assert_eq!(app.run(\"shape.info\", json!({})).unwrap(), shape);\n assert_eq!(steps(&app), n + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, \"Saved drawing\"), original);\n let mut params = params;\n params[\"matrix\"] = json!([1, 0, 0, 1, 7, 9]);\n app.run(\"path.transform\", params).unwrap();\n assert_eq!(path(&app, \"Saved drawing\").subpaths[0].knots[0].anchor.x, 17.0);\n assert_eq!(path(&app, \"work\"), work);\n assert_eq!(app.run(\"shape.info\", json!({})).unwrap(), shape);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(path(&app, \"Saved drawing\"), original);\n app.ui.selected_path = None;\n assert_eq!(vector_ui::free_transform_path(&app).unwrap().0[\"name\"], \"layer\", \"deselection restores the shape fallback\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "explicit_work_path_precedes_vector_mask_and_deselection_restores_mask_fallback",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked explicit_work_path_precedes_vector_mask_and_deselection_restores_mask_fallback -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::PathSelection);\n seed(&mut app, \"work\", 20.0);\n let layer = app.session.active().unwrap().active_layer.unwrap();\n app.run(\"layer.vectorMask.add\", json!({\"layer\":layer.0,\"path\":{\"subpaths\":[{\"knots\":[[30,40],[80,40]]}]}})).unwrap();\n app.ui.vector_mask_target = true;\n app.ui.selected_path = Some(\"work\".into());\n assert_eq!(vector_ui::free_transform_path(&app).unwrap().0, json!({\"name\":\"work\"}));\n app.ui.selected_path = None;\n assert_eq!(vector_ui::free_transform_path(&app).unwrap().0, json!({\"name\":\"layer\",\"layer\":layer.0}));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(vector_ui::free_transform_path(&app).unwrap().0, json!({\"name\":\"work\"}));\n app.ui.selected_path = None;\n assert_eq!(vector_ui::free_transform_path(&app).unwrap().0, json!({\"name\":\"layer\",\"layer\":layer.0}));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pen_keeps_its_captured_vector_mask_when_another_path_is_selected",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pen_keeps_its_captured_vector_mask_when_another_path_is_selected -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n seed(&mut app, \"Saved drawing\", 20.0);\n let layer = app.session.active().unwrap().active_layer.unwrap();\n app.run(\"layer.vectorMask.add\", json!({\"layer\":layer.0,\"path\":{\"subpaths\":[{\"knots\":[[30,40],[80,40]]}]}})).unwrap();\n app.ui.selected_path = None;\n app.ui.vector_mask_target = true;\n let (saved, original, n) = (path(&app, \"Saved drawing\"), app.session.active().unwrap().doc.layer(layer).unwrap().vector_mask.clone().unwrap(), steps(&app));\n click(&mut app, 30.0, 60.0);\n app.ui.vector_mask_target = false;\n app.ui.selected_path = Some(\"Saved drawing\".into());\n click(&mut app, 130.0, 60.0);\n vector_ui::pen_commit(&mut app, false);",
|
|
"expected_assertions": [
|
|
" assert_eq!(mask.path.subpaths.len(), 2);\n assert_eq!(mask.path.subpaths[0], original.path.subpaths[0]);\n assert_eq!(mask.path.subpaths[1].knots[0].anchor.y, 60.0);\n assert_eq!(path(&app, \"Saved drawing\"), saved);\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n assert_eq!(steps(&app), n + 1);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(app.session.active().unwrap().doc.layer(layer).unwrap().vector_mask.as_ref(), Some(&original));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_finish_uses_its_captured_saved_path_and_rejects_foreign_documents",
|
|
"path": "crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_finish_uses_its_captured_saved_path_and_rejects_foreign_documents -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::FreeformPen);\n seed(&mut app, \"work\", 20.0);\n seed(&mut app, \"Saved drawing\", 40.0);\n app.ui.selected_path = Some(\"Saved drawing\".into());\n let owner = vector_ui::capture_pen_owner(&app).unwrap();\n let points = [[30.0, 60.0, 1.0], [80.0, 60.0, 1.0], [130.0, 60.0, 1.0]];\n let (original, work, n) = (path(&app, \"Saved drawing\"), path(&app, \"work\"), steps(&app));\n app.ui.selected_path = Some(\"work\".into());\n app.ui.tool_options.vector_mode = \"shape\".into();\n vector_ui::freeform_finish_owned(&mut app, &points, &[], owner);\n assert_eq!(path(&app, \"Saved drawing\").subpaths.len(), 2);\n assert_eq!(path(&app, \"Saved drawing\").subpaths[0], original.subpaths[0]);",
|
|
"expected_assertions": [
|
|
" assert_eq!(path(&app, \"Saved drawing\").subpaths.len(), 2);\n assert_eq!(path(&app, \"Saved drawing\").subpaths[0], original.subpaths[0]);\n assert_eq!(path(&app, \"work\"), work);\n assert_eq!(steps(&app), n + 1);\n app.ui.tool_options.vector_mode = \"path\".into();\n let owner = vector_ui::capture_pen_owner(&app).unwrap();\n app.session.execute(\"file.new\", json!({\"width\":200,\"height\":200})).unwrap();\n assert!(std::sync::Arc::ptr_eq(&source, &app.session.active().unwrap().doc));\n assert_eq!(steps(&app), n);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_ownership_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "saved_path_drag_visual_fixture",
|
|
"path": "crates/ui-egui/src/pen_path_visual_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked saved_path_drag_visual_fixture -- --nocapture --ignored",
|
|
"fixture_and_action_excerpt": " let baseline = std::env::var(\"PHOTOCRAFT_PEN_VISUAL_BASELINE\").is_ok_and(|v| v == \"1\");\n let output = std::env::var_os(\"PHOTOCRAFT_PEN_VISUAL_DIR\").map(std::path::PathBuf::from).unwrap_or_else(|| \"log/pen-path-visual\".into());\n std::fs::create_dir_all(&output).expect(\"create synthetic screenshot directory\");\n let mut h = egui_kittest::Harness::builder().with_size(vec2(1280.0, 800.0)).with_max_steps(64).wgpu().build_eframe(|cc| {\n PhotocraftApp::setup_context(&cc.egui_ctx, Default::default());\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.edit_prefs(|p| p.interface.language = \"en\".into());\n if let Some(rs) = cc.wgpu_render_state.as_ref() {\n app.set_wgpu(rs.clone());\n }\n app.run(\"file.new\", json!({\"name\": \"Saved path targeting\", \"width\": 400, \"height\": 260, \"background\": \"white\"})).unwrap();\n app.run(\"path.set\", json!({\"name\": \"work\", \"path\": {\"subpaths\": [{\"closed\": true, \"knots\": [[40, 80], [140, 80], [90, 180]]}]}})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.selected_path.as_deref(), Some(\"Saved drawing\"), \"the Paths panel row selects the saved path\");\n let (work, saved) = (path(h.state(), \"work\"), path(h.state(), \"Saved drawing\"));\n let history = h.state().session.active().unwrap().history.past_len();\n let mode = if baseline { \"baseline\" } else { \"fixed\" };\n assert!(xf.rect.contains(start) && xf.rect.contains(end));\n h.event(Event::PointerMoved(start));\n h.event(button(start, true));\n h.step();\n assert!(h.state().drag.is_some(), \"native movement past the drag threshold starts a path gesture\");\n h.event(button(end, false));\n h.step();\n h.run_steps(12);\n assert!(h.state().drag.is_none());\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 1, \"one native drag is one Undo step\");\n if baseline {\n assert_eq!(path(h.state(), \"Saved drawing\"), saved, \"baseline incorrectly leaves the selected saved path untouched\");\n assert_eq!(path(h.state(), \"work\"), translated(work, 25.0, -20.0), \"baseline incorrectly moves the Work Path\");\n } else {\n assert_eq!(path(h.state(), \"work\"), work, \"editing a saved path preserves the Work Path\");\n assert_eq!(path(h.state(), \"Saved drawing\"), translated(saved, 25.0, -20.0), \"the selected saved path and its curve handles move together\");\n }\n let after = output.join(format!(\"{mode}-after.png\"));\n h.render().expect(\"render completed drag\").save(&after).expect(\"save completed drag\");"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/pen_path_visual_tests.rs",
|
|
"ignored_requires_explicit_execution": true,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "enter_selects_a_stroke_style_and_escape_closes_its_popups_without_committing_pen",
|
|
"path": "crates/ui-egui/src/shape_stroke_ui/shortcut_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked enter_selects_a_stroke_style_and_escape_closes_its_popups_without_committing_pen -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::Pen);\n let owner = crate::vector_ui::capture_pen_owner(&app);\n app.ui.pen = Some(crate::vector_ui::PenPath { knots: vec![[[12.0, 12.0]; 3], [[60.0, 40.0]; 3]], owner, ..Default::default() });\n let pen = app.ui.pen.clone();\n let original = app.session.active().unwrap().doc.clone();\n let history = app.session.active().unwrap().history.past_len();\n let mut h = harness(app, false);\n open(&mut h);\n h.get_by_role_and_label(egui::accesskit::Role::RadioButton, \"Dotted\").focus();\n h.run_steps(2);\n h.key_press(Key::Enter);\n h.run_steps(3);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.tool_options.shape_stroke.dashes, [0.0, 2.0]);\n assert_eq!(h.state().ui.pen, pen, \"Enter belongs to the focused style target\");\n h.get_by_role_and_label(egui::accesskit::Role::ComboBox, \"Caps\").click();\n h.run_steps(3);\n assert!(egui::Popup::is_any_open(&h.ctx));\n h.key_press(Key::Escape);\n h.run_steps(3);\n assert!(!egui::Popup::is_any_open(&h.ctx));\n assert!(h.state().ui.stroke_editor.is_some());\n assert_eq!(h.state().ui.pen, pen);\n h.key_press(Key::Escape);\n h.run_steps(3);\n assert!(h.state().ui.stroke_editor.is_none());\n assert_eq!(h.state().ui.pen, pen, \"dismissing Stroke Options leaves the Pen gesture intact\");\n assert_eq!(h.state().session.active().unwrap().doc, original);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/shape_stroke_ui/shortcut_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "transparent_and_absent_paints_remain_distinct_and_open_pen_keeps_foreground",
|
|
"path": "crates/ui-egui/src/vector_paint_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked transparent_and_absent_paints_remain_distinct_and_open_pen_keeps_foreground -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(\"rgb\", 32);\n let transparent = [0.124578, 0.564321, 0.765432, 0.0];\n set_tool_paint(&mut app, false, PaintChange::Color(transparent)).unwrap();\n set_tool_paint(&mut app, true, PaintChange::Color(transparent)).unwrap();\n let preview = shape_preview(&app, Tool::Rectangle, [20.0, 20.0], [80.0, 70.0], Modifiers::NONE).unwrap();\n assert_eq!(preview.fill, Some(solid_paint(transparent)));\n assert_eq!(preview.stroke.as_ref().unwrap().paint, solid_paint(transparent));\n finish_shape(&mut app, Tool::Rectangle, [20.0, 20.0], [80.0, 70.0], Modifiers::NONE);\n assert_eq!(shape(&app).fill, preview.fill);\n assert_eq!(shape(&app).stroke, preview.stroke);\n assert_eq!(shape(&app).cache.as_ref().unwrap().pixel(40, 40), vec![0.0; 4]);\n set_tool_paint(&mut app, false, PaintChange::None).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(preview.fill, Some(solid_paint(transparent)));\n assert_eq!(preview.stroke.as_ref().unwrap().paint, solid_paint(transparent));\n finish_shape(&mut app, Tool::Rectangle, [20.0, 20.0], [80.0, 70.0], Modifiers::NONE);\n assert_eq!(shape(&app).fill, preview.fill);\n assert_eq!(shape(&app).stroke, preview.stroke);\n assert_eq!(shape(&app).cache.as_ref().unwrap().pixel(40, 40), vec![0.0; 4]);\n set_tool_paint(&mut app, false, PaintChange::None).unwrap();\n set_tool_paint(&mut app, true, PaintChange::None).unwrap();\n finish_shape(&mut app, Tool::Triangle, [20.0, 20.0], [80.0, 70.0], Modifiers::NONE);\n assert!(shape(&app).fill.is_none() && shape(&app).stroke.is_none());\n let foreground = [0.836521, 0.125468, 0.745632, 0.438271];\n app.run(\"tools.setColors\", json!({\"foreground\": foreground, \"background\": [0.0, 1.0, 0.0, 1.0]})).unwrap();\n app.ui.tool_options.vector_mode = \"shape\".into();\n assert!(shape(&app).fill.is_none());\n assert!(!shape(&app).path.subpaths[0].closed);\n assert_eq!(shape(&app).stroke.as_ref().unwrap().paint, solid_paint(foreground));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_paint_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "all_shape_tools_and_open_pen_use_the_complete_stroke_defaults",
|
|
"path": "crates/ui-egui/src/vector_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked all_shape_tools_and_open_pen_use_the_complete_stroke_defaults -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::Rectangle, Tool::EllipseShape, Tool::Triangle, Tool::Polygon, Tool::Line, Tool::CustomShape] {\n let mut a = app();\n a.ui.tool_options.stroke_width = 5.0;\n a.ui.tool_options.shape_stroke = crate::shape_stroke_ui::StrokeOptions {\n cap: photocraft_doc::LineCap::Square,\n join: photocraft_doc::LineJoin::Bevel,\n dashes: vec![4.0, 2.0, 1.0, 3.0],\n dash_offset: -0.5,\n opacity: 0.4,\n ..Default::default()\n };\n let history = a.session.active().unwrap().history.past_len();",
|
|
"expected_assertions": [
|
|
" assert_eq!(info[\"stroke\"][\"dashes\"], json!([4.0, 2.0, 1.0, 3.0]));\n assert_eq!(info[\"stroke\"][\"cap\"], \"square\");\n assert_eq!(info[\"stroke\"][\"width\"], 5.0);\n assert_eq!(a.session.active().unwrap().history.past_len(), history + 1);\n a.run(\"edit.undo\", json!({})).unwrap();\n a.run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(a.run(\"shape.info\", json!({})).unwrap(), info);\n a.ui.tool_options.vector_mode = \"shape\".into();\n a.ui.pen = Some(PenPath { knots: vec![[[30.0, 40.0]; 3], [[80.0, 40.0]; 3]], owner: capture_pen_owner(&a), ..Default::default() });\n pen_commit(&mut a, false);\n assert_eq!(open[\"stroke\"][\"dashes\"], info[\"stroke\"][\"dashes\"]);\n assert_eq!(open[\"path\"][\"subpaths\"][0][\"closed\"], false);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_straight_segments_keep_the_captured_saved_path_and_reject_a_foreign_document",
|
|
"path": "crates/ui-egui/src/vector_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_straight_segments_keep_the_captured_saved_path_and_reject_a_foreign_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool = Tool::FreeformPen;\n let seed = json!({\"subpaths\":[{\"knots\":[[20,20],[120,20]]}]});\n for name in [\"work\", \"Saved drawing\"] {\n app.run(\"path.set\", json!({\"name\": name, \"path\": seed})).unwrap();\n }\n app.ui.selected_path = Some(\"Saved drawing\".into());\n let owner = capture_pen_owner(&app).unwrap();\n let original = app.session.active().unwrap().doc.clone();\n let n = app.session.active().unwrap().history.past_len();\n let points = [[20.0, 60.0, 1.0], [60.0, 60.0, 1.0], [100.0, 80.0, 1.0], [140.0, 80.0, 1.0]];\n app.ui.selected_path = Some(\"work\".into());",
|
|
"expected_assertions": [
|
|
" assert_eq!(st.doc.work_path, original.work_path);\n let saved = &st.doc.paths.iter().find(|p| p.name == \"Saved drawing\").unwrap().path;\n assert_eq!(saved.subpaths[0], original.paths[0].path.subpaths[0]);\n assert_eq!(saved.subpaths.len(), 2);\n let knots = &saved.subpaths[1].knots;\n assert_eq!(knots.len(), 4);\n for (a, b) in [(0, 1), (2, 3)] {\n assert_eq!(knots[a].out_ctrl, knots[a].anchor, \"straight segment starts at its anchor\");\n assert_eq!(knots[b].in_ctrl, knots[b].anchor, \"straight segment ends at its anchor\");\n }\n assert_eq!(st.history.past_len(), n + 1);\n assert!(app.ui.pen.is_none());\n app.ui.tool_options.vector_mode = \"path\".into();\n let owner = capture_pen_owner(&app).unwrap();\n app.run(\"file.new\", json!({\"width\": 200, \"height\": 200})).unwrap();\n assert!(Arc::ptr_eq(&source, &app.session.active().unwrap().doc));\n assert_eq!(app.session.active().unwrap().history.past_len(), n);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "failed_freeform_straight_segment_commit_keeps_its_owned_fitted_draft",
|
|
"path": "crates/ui-egui/src/vector_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked failed_freeform_straight_segment_commit_keeps_its_owned_fitted_draft -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool = Tool::FreeformPen;\n let owner = capture_pen_owner(&app).unwrap();\n let (source, n) = (app.session.active().unwrap().doc.clone(), app.session.active().unwrap().history.past_len());\n let points = [[20.0, 60.0, 1.0], [1e40, 60.0, 1.0], [140.0, 80.0, 1.0]];\n freeform_finish_owned(&mut app, &points, &[1, 2], owner.clone());\n let pen = app.ui.pen.as_ref().expect(\"invalid fitted geometry must remain available after its failed commit\");\n assert!(pen.commit_failed);\n assert_eq!(pen.owner.as_ref(), Some(&owner));\n assert!(owner.valid(&app));\n assert_eq!(pen.knots.len(), 3);\n assert_eq!(pen.knots[1], [[1e40, 60.0]; 3]);",
|
|
"expected_assertions": [
|
|
" assert!(pen.commit_failed);\n assert_eq!(pen.owner.as_ref(), Some(&owner));\n assert!(owner.valid(&app));\n assert_eq!(pen.knots.len(), 3);\n assert_eq!(pen.knots[1], [[1e40, 60.0]; 3]);\n assert!(Arc::ptr_eq(&source, &app.session.active().unwrap().doc));\n assert_eq!(app.session.active().unwrap().history.past_len(), n);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "show_target_path_and_extras_hide_the_path_outlines",
|
|
"path": "crates/ui-egui/src/vector_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked show_target_path_and_extras_hide_the_path_outlines -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #1119: View \u203a Show \u203a Target Path only flipped its checkmark; the canvas kept drawing the\n // work path and the active shape's path.\n let ctx = egui::Context::default();\n let mut app = app();\n let path = json!({\"subpaths\": [{\"closed\": true, \"knots\": [\n {\"anchor\": [10, 10], \"in\": [10, 10], \"out\": [10, 10]},\n {\"anchor\": [80, 10], \"in\": [80, 10], \"out\": [80, 10]},\n {\"anchor\": [80, 80], \"in\": [80, 80], \"out\": [80, 80]}\n ]}]});\n app.run(\"path.set\", json!({\"path\": path})).unwrap();\n assert!(app.session.active().unwrap().doc.work_path.is_some());\n finish_shape(&mut app, Tool::Rectangle, [100.0, 100.0], [160.0, 150.0], egui::Modifiers::NONE);",
|
|
"expected_assertions": [
|
|
" assert!(app.session.active().unwrap().doc.work_path.is_some());\n finish_shape(&mut app, Tool::Rectangle, [100.0, 100.0], [160.0, 150.0], egui::Modifiers::NONE);\n let toggle = |app: &mut PhotocraftApp, id: &str| crate::menus::invoke(app, &ctx, id, Value::Null).unwrap();\n for tool in [Tool::Pen, Tool::PathSelection, Tool::DirectSelection, Tool::Rectangle] {\n assert!(app.ui.view.show.target_path && app.ui.view.extras);\n assert!(overlay_shapes(&app, &ctx) > 0, \"{tool:?}: the paths are drawn by default\");\n toggle(&mut app, \"view.show.targetPath\");\n assert!(!app.ui.view.show.target_path);\n assert_eq!(overlay_shapes(&app, &ctx), 0, \"{tool:?}: Target Path off\");\n toggle(&mut app, \"view.show.targetPath\");\n toggle(&mut app, \"view.extras\");\n assert!(!app.ui.view.extras);\n assert_eq!(overlay_shapes(&app, &ctx), 0, \"{tool:?}: Extras off\");\n toggle(&mut app, \"view.extras\");\n assert!(overlay_shapes(&app, &ctx) > 0, \"{tool:?}: shown again\");\n }\n // The Pen's path in progress is a gesture, not the target path: it stays visible.\n app.ui.tool = Tool::Pen;\n assert!(overlay_shapes(&app, &ctx) > 0, \"the pen path in progress is still drawn\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pen_last_anchor_hit_tolerance_tracks_zoom_and_draft_round_trips",
|
|
"path": "crates/ui-egui/src/vector_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pen_last_anchor_hit_tolerance_tracks_zoom_and_draft_round_trips -- --nocapture",
|
|
"fixture_and_action_excerpt": " for zoom in [0.25, 1.0, 4.0] {\n let mut app = app();\n app.ui.views[0].zoom = zoom;\n pen_down(&mut app, 20.0, 20.0);\n pen_up(&mut app);\n pen_down(&mut app, 100.0, 100.0);\n pen_move(&mut app, 110.0, 120.0);\n pen_up(&mut app);\n let incoming = app.ui.pen.as_ref().unwrap().knots[1][1];\n pen_down(&mut app, 100.0 + 5.0 / f64::from(zoom), 100.0);\n pen_up(&mut app);\n let pen = app.ui.pen.as_ref().unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(pen.knots.len(), 2);\n assert_eq!(pen.knots[1][1], incoming);\n assert_eq!(pen.knots[1][2], pen.knots[1][0]);\n let saved = serde_json::to_value(pen).unwrap();\n let restored: PenPath = serde_json::from_value(saved).unwrap();\n // The runtime owner isn't saved: a restored draft belongs to no document.\n assert_eq!(restored, PenPath { owner: None, ..pen.clone() });\n assert_eq!(pen_to_json(&restored, false)[\"subpaths\"][0][\"knots\"][1][\"smooth\"], false);\n pen_down(&mut app, 100.0 + 7.0 / f64::from(zoom), 100.0);\n assert_eq!(app.ui.pen.as_ref().unwrap().knots.len(), 3);\n }\n let legacy: PenPath = serde_json::from_value(json!({\"knots\": [[[10, 10], [10, 10], [10, 10]]]})).unwrap();\n assert!(legacy.unlinked.is_empty());\n assert!(!legacy.dragging && !legacy.adjusting_last);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/ui-egui/src/vector_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "general_paths_keep_large_straight_coordinates_and_shape_limits_stay_put",
|
|
"path": "crates/vector/src/flatten.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked general_paths_keep_large_straight_coordinates_and_shape_limits_stay_put -- --nocapture",
|
|
"fixture_and_action_excerpt": " let at_shape_limit = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (1_000_000.0, 0.0)])], ..Default::default() };\n assert!(validate_shape(&at_shape_limit, None).is_ok());\n let outside_shape = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (1_000_001.0, 0.0)])], ..Default::default() };\n assert_eq!(validate_shape(&outside_shape, None), Err(\"shape coordinates must be finite and within \u00b11000000 px\"));\n assert!(validate_path(&outside_shape).is_ok());\n for extent in [3.0e9, f64::from(f32::MAX)] {\n let path = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (extent, 0.0), (extent, extent)])], ..Default::default() };\n assert!(validate_path(&path).is_ok());\n let line = flatten_subpath(&path.subpaths[0], crate::DEFAULT_TOLERANCE);\n assert_eq!(line.pts, [(0.0, 0.0), (extent, 0.0), (extent, extent)]);\n assert!(line.pts.iter().all(|(x, y)| (*x as f32).is_finite() && (*y as f32).is_finite()));\n assert!(validate_shape(&path, None).is_err());",
|
|
"expected_assertions": [
|
|
" assert!(validate_shape(&at_shape_limit, None).is_ok());\n let outside_shape = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (1_000_001.0, 0.0)])], ..Default::default() };\n assert_eq!(validate_shape(&outside_shape, None), Err(\"shape coordinates must be finite and within \u00b11000000 px\"));\n assert!(validate_path(&outside_shape).is_ok());\n for extent in [3.0e9, f64::from(f32::MAX)] {\n let path = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (extent, 0.0), (extent, extent)])], ..Default::default() };\n assert!(validate_path(&path).is_ok());\n let line = flatten_subpath(&path.subpaths[0], crate::DEFAULT_TOLERANCE);\n assert_eq!(line.pts, [(0.0, 0.0), (extent, 0.0), (extent, extent)]);\n assert!(line.pts.iter().all(|(x, y)| (*x as f32).is_finite() && (*y as f32).is_finite()));\n assert!(validate_shape(&path, None).is_err());\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/vector/src/flatten.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "general_paths_reject_coordinates_that_overflow_the_ui_or_segment_arithmetic",
|
|
"path": "crates/vector/src/flatten.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked general_paths_reject_coordinates_that_overflow_the_ui_or_segment_arithmetic -- --nocapture",
|
|
"fixture_and_action_excerpt": " for extent in [f64::from(f32::MAX) * 2.0, 1.0e308, f64::INFINITY, f64::NAN] {\n let path = Path { subpaths: vec![Subpath::polygon(&[(-extent, 0.0), (extent, 0.0)])], ..Default::default() };\n assert_eq!(validate_path(&path), Err(\"path coordinates must be finite and representable as f32\"));\n }\n // The shared arithmetic guard also rejects overflow independently of coordinate policy.\n let overflowing_difference = Path { subpaths: vec![Subpath::polygon(&[(-1.0e308, 0.0), (1.0e308, 0.0)])], ..Default::default() };\n assert_eq!(validate_workload(&overflowing_difference, None, f64::MAX, \"coordinates\"), Err(\"path geometry arithmetic must be finite\"));\n let overflowing_length = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (f64::MAX, f64::MAX)])], ..Default::default() };\n assert_eq!(validate_workload(&overflowing_length, None, f64::MAX, \"coordinates\"), Err(\"path geometry arithmetic must be finite\"));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(validate_path(&path), Err(\"path coordinates must be finite and representable as f32\"));\n }\n // The shared arithmetic guard also rejects overflow independently of coordinate policy.\n let overflowing_difference = Path { subpaths: vec![Subpath::polygon(&[(-1.0e308, 0.0), (1.0e308, 0.0)])], ..Default::default() };\n assert_eq!(validate_workload(&overflowing_difference, None, f64::MAX, \"coordinates\"), Err(\"path geometry arithmetic must be finite\"));\n let overflowing_length = Path { subpaths: vec![Subpath::polygon(&[(0.0, 0.0), (f64::MAX, f64::MAX)])], ..Default::default() };\n assert_eq!(validate_workload(&overflowing_length, None, f64::MAX, \"coordinates\"), Err(\"path geometry arithmetic must be finite\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/vector/src/flatten.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "general_paths_bound_total_knots_subpaths_and_combined_tessellation",
|
|
"path": "crates/vector/src/flatten.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked general_paths_bound_total_knots_subpaths_and_combined_tessellation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let line = Subpath::polygon(&[(0.0, 0.0)]);\n let mut paths = Path { subpaths: vec![line.clone(); 4096], ..Default::default() };\n assert!(validate_path(&paths).is_ok());\n paths.subpaths.push(line);\n assert_eq!(validate_path(&paths), Err(\"path exceeds 4096 knots/subpaths\"));\n let knots = Path { subpaths: vec![Subpath::polygon(&vec![(0.0, 0.0); 4097])], ..Default::default() };\n assert_eq!(validate_path(&knots), Err(\"path exceeds 4096 knots/subpaths\"));\n\n let curve = shapes::ellipse(0.0, 0.0, 1000.0, 1000.0).subpaths.remove(0);\n let points = 1 + curve.segments().iter().map(|s| if is_line(s) { 1 } else { pieces(s, crate::DEFAULT_TOLERANCE) }).sum::<usize>();\n let half = 100_000 / points / 2 + 1;\n let mut combined = Path { subpaths: vec![curve.clone(); half], ..Default::default() };",
|
|
"expected_assertions": [
|
|
" assert!(validate_path(&paths).is_ok());\n paths.subpaths.push(line);\n assert_eq!(validate_path(&paths), Err(\"path exceeds 4096 knots/subpaths\"));\n let knots = Path { subpaths: vec![Subpath::polygon(&vec![(0.0, 0.0); 4097])], ..Default::default() };\n assert_eq!(validate_path(&knots), Err(\"path exceeds 4096 knots/subpaths\"));\n\n let curve = shapes::ellipse(0.0, 0.0, 1000.0, 1000.0).subpaths.remove(0);\n let points = 1 + curve.segments().iter().map(|s| if is_line(s) { 1 } else { pieces(s, crate::DEFAULT_TOLERANCE) }).sum::<usize>();\n assert!(validate_path(&combined).is_ok());\n assert!(validate_shape(&combined, None).is_ok());\n combined.subpaths.extend(vec![curve; half]);\n assert!(combined.subpaths.len() < 4096 && combined.subpaths.iter().map(|s| s.knots.len()).sum::<usize>() < 4096);\n assert_eq!(validate_path(&combined), Err(\"path tessellation exceeds 100000 points\"));\n assert_eq!(validate_shape(&combined, None), Err(\"path tessellation exceeds 100000 points\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1eecd00b2dff4ae4c642269cec211cd06ce1c3aa/crates/vector/src/flatten.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3519",
|
|
"pr": 3519,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked layers_to_files_can_trim_transparent_margins_without_changing_the_document -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked streamed_layer_export_respects_trim -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked trimming_an_empty_layer_keeps_a_valid_nonzero_canvas -- --nocapture"
|
|
],
|
|
"expected": "layers to files can trim transparent margins without changing the document; streamed layer export respects trim; trimming an empty layer keeps a valid nonzero canvas",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked layers_to_files_can_trim_transparent_margins_without_changing_the_document -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked streamed_layer_export_respects_trim -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked trimming_an_empty_layer_keeps_a_valid_nonzero_canvas -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "layers_to_files_can_trim_transparent_margins_without_changing_the_document",
|
|
"path": "crates/engine/src/file_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked layers_to_files_can_trim_transparent_margins_without_changing_the_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = tmp(\"layers-trim\");\n for depth in [8, 16, 32] {\n let mut s = session(12, 11, depth);\n s.execute(\"layer.new.layer\", json!({\"name\": \"Ink\"})).unwrap();\n s.execute(\"select.rect\", json!({\"x\": 3, \"y\": 2, \"width\": 4, \"height\": 5})).unwrap();\n s.execute(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n s.execute(\"select.deselect\", json!({})).unwrap();\n\n let before = doc(&s).clone();\n let regular = s.execute(\"file.export.layersToFiles\", json!({\"dir\": dir, \"prefix\": format!(\"full-{depth}\"), \"format\": \"png\"})).unwrap();\n let full = std::fs::read(regular[\"files\"][0].as_str().unwrap()).unwrap();\n let full = photocraft_io::import(\"full.png\", &full).unwrap().document;",
|
|
"expected_assertions": [
|
|
" assert_eq!((full.size.width, full.size.height), (12, 11), \"default is unchanged\");\n\n let trimmed = s.execute(\"file.export.layersToFiles\", json!({\"dir\": dir, \"prefix\": format!(\"trim-{depth}\"), \"format\": \"png\", \"trim\": true})).unwrap();\n let image = std::fs::read(trimmed[\"files\"][0].as_str().unwrap()).unwrap();\n assert_eq!((cropped.size.width, cropped.size.height), (4, 5), \"depth {depth}\");\n let px = photocraft_compose::render(&cropped, Rect::new(0, 0, 1, 1)).px[0];\n assert!(px[0] > 0.95 && px[1] < 0.05 && px[2] < 0.05, \"depth {depth}: {px:?}\");\n assert_eq!(*doc(&s), before, \"export must not crop the original document\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/807de6c043a512cb947d86b944c758b3db1277c7/crates/engine/src/file_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "streamed_layer_export_respects_trim",
|
|
"path": "crates/engine/src/file_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked streamed_layer_export_respects_trim -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(12, 11, 8);\n s.execute(\"layer.new.layer\", json!({\"name\": \"Ink\"})).unwrap();\n s.execute(\"select.rect\", json!({\"x\": 3, \"y\": 2, \"width\": 4, \"height\": 5})).unwrap();\n s.execute(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n s.execute(\"select.deselect\", json!({})).unwrap();\n let mut encoded = Vec::new();\n let names = super::export_layers_with(&s, &json!({\"trim\": true, \"format\": \"png\"}), |name, bytes| {\n encoded.push((name.to_string(), bytes.to_vec()));\n Ok(())\n })\n .unwrap();\n assert_eq!(names.len(), encoded.len());",
|
|
"expected_assertions": [
|
|
" assert_eq!(names.len(), encoded.len());\n let cropped = photocraft_io::import(&encoded[0].0, &encoded[0].1).unwrap().document;\n assert_eq!((cropped.size.width, cropped.size.height), (4, 5));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/807de6c043a512cb947d86b944c758b3db1277c7/crates/engine/src/file_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "trimming_an_empty_layer_keeps_a_valid_nonzero_canvas",
|
|
"path": "crates/engine/src/file_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked trimming_an_empty_layer_keeps_a_valid_nonzero_canvas -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = tmp(\"layers-trim-empty\");\n let mut s = session(6, 7, 8);\n s.execute(\"layer.new.layer\", json!({\"name\": \"Empty\"})).unwrap();\n let result = s.execute(\"file.export.layersToFiles\", json!({\"dir\": dir, \"format\": \"png\", \"trim\": true})).unwrap();\n let bytes = std::fs::read(result[\"files\"][0].as_str().unwrap()).unwrap();\n let back = photocraft_io::import(\"empty.png\", &bytes).unwrap().document;\n assert_eq!((back.size.width, back.size.height), (6, 7));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!((back.size.width, back.size.height), (6, 7));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/807de6c043a512cb947d86b944c758b3db1277c7/crates/engine/src/file_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5870",
|
|
"pr": 5870,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_across_the_whole_tree -- --nocapture",
|
|
"cargo test -p photocraft-format --locked duplicate_extreme_layer_ids_are_not_silently_remapped -- --nocapture",
|
|
"cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_before_fetching_payloads -- --nocapture",
|
|
"cargo test -p photocraft-format --locked unique_nested_layer_ids_preserve_comp_targets_in_both_load_modes -- --nocapture",
|
|
"cargo test -p photocraft-format --locked layer_identity_validation_keeps_smart_document_and_contents_scopes_independent -- --nocapture",
|
|
"cargo test -p photocraft-format --locked an_empty_layer_tree_loads_in_both_modes -- --nocapture"
|
|
],
|
|
"expected": "duplicate layer ids are rejected across the whole tree; duplicate extreme layer ids are not silently remapped; duplicate layer ids are rejected before fetching payloads; unique nested layer ids preserve comp targets in both load modes; layer identity validation keeps smart document and contents scopes independent; an empty layer tree loads in both modes",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_across_the_whole_tree -- --nocapture",
|
|
"cargo test -p photocraft-format --locked duplicate_extreme_layer_ids_are_not_silently_remapped -- --nocapture",
|
|
"cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_before_fetching_payloads -- --nocapture",
|
|
"cargo test -p photocraft-format --locked unique_nested_layer_ids_preserve_comp_targets_in_both_load_modes -- --nocapture",
|
|
"cargo test -p photocraft-format --locked layer_identity_validation_keeps_smart_document_and_contents_scopes_independent -- --nocapture",
|
|
"cargo test -p photocraft-format --locked an_empty_layer_tree_loads_in_both_modes -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "duplicate_layer_ids_are_rejected_across_the_whole_tree",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_across_the_whole_tree -- --nocapture",
|
|
"fixture_and_action_excerpt": " let doc = sample();\n let bytes = save_to_bytes(&doc, &SaveOptions::default()).unwrap();\n // Top-level siblings, ancestor/descendant, nested siblings, and unrelated groups must all\n // share one identity namespace. Reidentifying cannot recover an ambiguous comp target.\n for (source, target) in [\n (\"/document/layers/1/id\", \"/document/layers/2/id\"),\n (\"/document/layers/1/id\", \"/document/layers/1/content/children/1/content/children/0/id\"),\n (\"/document/layers/1/content/children/0/id\", \"/document/layers/1/content/children/1/id\"),\n (\"/document/layers/1/content/children/0/id\", \"/document/layers/2/content/children/0/id\"),\n (\"/document/layers/0/id\", \"/document/layers/1/content/children/1/content/children/0/id\"),\n ] {\n let mut duplicate = 0;",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "duplicate_extreme_layer_ids_are_not_silently_remapped",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked duplicate_extreme_layer_ids_are_not_silently_remapped -- --nocapture",
|
|
"fixture_and_action_excerpt": " let bytes = save_to_bytes(&sample(), &SaveOptions::default()).unwrap();\n let damaged = rewrite_manifest(&bytes, |m| {\n m[\"document\"][\"layers\"][0][\"id\"] = u64::MAX.into();\n m[\"document\"][\"layers\"][2][\"id\"] = u64::MAX.into();\n });\n for preserve_ids in [true, false] {\n let error = load_from_bytes_with(&damaged, &LoadOptions { preserve_ids, ..Default::default() }).unwrap_err();\n assert_duplicate(error, u64::MAX);\n }\n}",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "duplicate_layer_ids_are_rejected_before_fetching_payloads",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked duplicate_layer_ids_are_rejected_before_fetching_payloads -- --nocapture",
|
|
"fixture_and_action_excerpt": " struct ManifestOnly {\n json: Vec<u8>,\n payload_reads: Cell<usize>,\n }\n impl ByteSource for ManifestOnly {\n fn get(&self, path: &str, _max: usize) -> photocraft_format::Result<Vec<u8>> {\n if path == \"manifest.json\" {\n return Ok(self.json.clone());\n }\n self.payload_reads.set(self.payload_reads.get() + 1);\n Err(FormatError::Corrupt(\"payload fetched before validating layer ids\".into()))\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(src.payload_reads.get(), 0);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "unique_nested_layer_ids_preserve_comp_targets_in_both_load_modes",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked unique_nested_layer_ids_preserve_comp_targets_in_both_load_modes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let doc = sample();\n let bytes = save_to_bytes(&doc, &SaveOptions::default()).unwrap();\n let original_ids: HashSet<_> = doc.walk().into_iter().map(|(_, _, l)| l.id).collect();\n for preserve_ids in [true, false] {\n let loaded = load_from_bytes_with(&bytes, &LoadOptions { preserve_ids, ..Default::default() }).unwrap();\n let walk = loaded.walk();\n let ids: HashSet<_> = walk.iter().map(|(_, _, l)| l.id).collect();\n assert_eq!(ids.len(), walk.len());\n for ((_, _, layer), state) in walk.iter().zip(&loaded.layer_comps[0].states) {\n assert_eq!(state.layer, layer.id);\n assert_eq!(loaded.layer(state.layer), Some(*layer));\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(ids.len(), walk.len());\n for ((_, _, layer), state) in walk.iter().zip(&loaded.layer_comps[0].states) {\n assert_eq!(state.layer, layer.id);\n assert_eq!(loaded.layer(state.layer), Some(*layer));\n }\n if preserve_ids {\n assert_eq!(loaded, doc);\n } else {\n assert!(ids.is_disjoint(&original_ids));\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_identity_validation_keeps_smart_document_and_contents_scopes_independent",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked layer_identity_validation_keeps_smart_document_and_contents_scopes_independent -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut doc = sample();\n let mut inner = Document::new(\"inside\", doc.size, doc.mode, doc.depth);\n inner.layers.push(doc.layers[0].clone());\n let bytes = Arc::new(save_to_bytes(&inner, &SaveOptions::default()).unwrap());\n let mut smart = SmartObject::new(SmartSource::Embedded { file_name: \"inside.pcraft\".into(), bytes: bytes.clone() }, Affine::IDENTITY, None);\n // These typed identities may have the same number without identifying the same thing.\n smart.contents_id = SmartContentsId(doc.layers[0].id.0);\n doc.id = DocId(doc.layers[0].id.0);\n let first = Layer::new(\"instance\", LayerContent::Smart(smart));\n let second = first.duplicate();\n doc.layers.extend([first, second]);\n let outer = save_to_bytes(&doc, &SaveOptions::default()).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(instances.len(), 2);\n assert_eq!(instances[0].contents_id, instances[1].contents_id);\n for instance in instances {\n let SmartSource::Embedded { bytes: stored, .. } = &instance.source else { panic!(\"embedded source expected\") };\n assert_eq!(stored, &bytes);\n let restored = load_from_bytes_with(stored, &opts).unwrap();\n assert_eq!(restored.layers.len(), 1);\n if preserve_ids {\n assert_eq!(restored, inner);\n assert_eq!(restored.layers[0].id, loaded.layers[0].id);\n }\n }\n if preserve_ids {\n assert_eq!(loaded, doc);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_empty_layer_tree_loads_in_both_modes",
|
|
"path": "crates/format/tests/layer_identities.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked an_empty_layer_tree_loads_in_both_modes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let doc = Document::new(\"empty\", Size::new(1, 1), ColorMode::Rgb, SampleType::U8);\n let bytes = save_to_bytes(&doc, &SaveOptions::default()).unwrap();\n for preserve_ids in [true, false] {\n let loaded = load_from_bytes_with(&bytes, &LoadOptions { preserve_ids, ..Default::default() }).unwrap();\n assert!(loaded.layers.is_empty());\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(loaded.layers.is_empty());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f9de0a6abc78aa405b1ef46f5da6cba424106204/crates/format/tests/layer_identities.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6383",
|
|
"pr": 6383,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Portable/executable artifact and symbols ZIP from the SAME immutable final-SHA build run, per claimed architecture",
|
|
"action": [
|
|
"Manual artifact/identity inspection described below"
|
|
],
|
|
"expected": "ZIP has photocraft.pdb, photocraft_cli.pdb and symbols.txt. Each PDB GUID/age matches its same-run executable; debugger/profiler resolves a PhotoCraft function. Portable/MSI launches without optional symbols.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Inspect PE CodeView/PDB identity, record run/job/artifact IDs and hashes. Same SHA rebuilt is not the same PDB identity. Source lines are not required because release omits line tables. Missing packaging artifacts/identity evidence is BLOCKED; do not publish a release just for fixtures.",
|
|
"tested_sha": "",
|
|
"test_commands": []
|
|
},
|
|
{
|
|
"id": "PR-8892",
|
|
"pr": 8892,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Studio Dark and Studio Light, UI scale 100% and 200%, 1280x800 then 900x600 logical-point window; synthetic document with at least two selected layers, Move tool, overflowing document/panel tabs, and Save for Web. Record physical pixel dimensions and pixels-per-point.",
|
|
"action": "Inspect Move alignment controls and Align and distribute ellipsis. Force tab overflow and open its chevron menu. Open Save for Web, record dialog width, enter an invalid Matte value such as not-a-colour, and record width/error placement; correct the value.",
|
|
"expected": "After the combined #8892/#9004 ports, Move icons and ellipsis use 20-point artwork in 28-point hit targets (40/56 physical pixels at 2x). Tab overflow uses a 16-point chevrons-right icon in its 18-point slot (32/36 pixels at 2x), with reachable menu items. Controls remain legible/unclipped. Invalid Matte displays its error without expanding Save for Web width; correction clears it.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-8897",
|
|
"pr": 8897,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Unix test-owned FIFO linked by synthetic 8\u00d76 document; bounded-reader synthetic fixtures",
|
|
"action": [
|
|
"cargo test -p photocraft-io --locked a_linked_fifo_is_not_read -- --nocapture",
|
|
"cargo test -p photocraft-format --locked reads_stop_at_the_total_limit -- --nocapture",
|
|
"cargo test -p photocraft-format --locked an_exact_hint_is_not_over_allocated -- --nocapture"
|
|
],
|
|
"expected": "FIFO export completes within 30 seconds without a writer, exports cached pixels and warns of fallback/not-regular-file. Exact-limit read succeeds, over-limit/never-ending reads fail FileTooLarge; size hints do not overallocate.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Use only owned temporary FIFO, never a real device. Non-Unix exclusion is BLOCKED for FIFO qualification, not PASSED.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-io --locked a_linked_fifo_is_not_read -- --nocapture",
|
|
"cargo test -p photocraft-format --locked reads_stop_at_the_total_limit -- --nocapture",
|
|
"cargo test -p photocraft-format --locked an_exact_hint_is_not_over_allocated -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-8986",
|
|
"pr": 8986,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_drags_an_anchor_of_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_marquee_selects_and_arrow_params_name_the_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_saved_path_is_only_edited_while_the_paths_panel_selects_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_selected_saved_path_comes_before_the_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_selection_moves_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked free_transform_path_names_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_point_edit_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_saved_path_read_from_a_psd_is_editable -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrows_leave_a_saved_path_the_paths_panel_no_longer_selects -- --nocapture"
|
|
],
|
|
"expected": "direct selection drags an anchor of the selected saved path; direct selection marquee selects and arrow params name the saved path; the saved path is only edited while the paths panel selects it; the selected saved path comes before the work path; path selection moves the selected saved path; free transform path names the selected saved path; add and delete anchor point edit the selected saved path; a saved path read from a psd is editable; arrows leave a saved path the paths panel no longer selects",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_drags_an_anchor_of_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked direct_selection_marquee_selects_and_arrow_params_name_the_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_saved_path_is_only_edited_while_the_paths_panel_selects_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_selected_saved_path_comes_before_the_work_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_selection_moves_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked free_transform_path_names_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_point_edit_the_selected_saved_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_saved_path_read_from_a_psd_is_editable -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrows_leave_a_saved_path_the_paths_panel_no_longer_selects -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "direct_selection_drags_an_anchor_of_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked direct_selection_drags_an_anchor_of_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_saved_path(&mut app);\n let (before, n) = (saved(&app), steps(&app));\n drag(&mut app, [120.5, 120.5], [130.5, 135.5], Modifiers::NONE);\n let after = saved(&app);\n assert_eq!(after.subpaths[0].knots[2].anchor, Point::new(130.0, 135.0), \"the dragged anchor moved\");\n assert_eq!(after.subpaths[0].knots[0].anchor, Point::new(40.0, 40.0), \"the others stay\");\n assert_eq!(steps(&app), n + 1, \"one history step\");\n assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 2]]));\n assert!(app.session.active().unwrap().doc.work_path.is_none(), \"no work path was made\");\n assert!(app.session.undo());\n assert_eq!(saved(&app), before);",
|
|
"expected_assertions": [
|
|
" assert_eq!(after.subpaths[0].knots[2].anchor, Point::new(130.0, 135.0), \"the dragged anchor moved\");\n assert_eq!(after.subpaths[0].knots[0].anchor, Point::new(40.0, 40.0), \"the others stay\");\n assert_eq!(steps(&app), n + 1, \"one history step\");\n assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 2]]));\n assert!(app.session.active().unwrap().doc.work_path.is_none(), \"no work path was made\");\n assert!(app.session.undo());\n assert_eq!(saved(&app), before);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "direct_selection_marquee_selects_and_arrow_params_name_the_saved_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked direct_selection_marquee_selects_and_arrow_params_name_the_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_saved_path(&mut app);\n drag(&mut app, [30.0, 30.0], [50.0, 50.0], Modifiers::NONE);\n assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 0]]));\n assert_eq!(PathRef::Saved(0).params(&app), json!({\"name\": NAME}));\n // A path that is gone gets no name, which the engine refuses instead of editing another one.\n assert_eq!(PathRef::Saved(7).params(&app), json!({\"name\": \"\"}));\n assert!(app.run(\"path.moveAnchors\", json!({\"name\": \"\", \"anchors\": [[0, 0]], \"move\": [1, 1]})).is_err());\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 0]]));\n assert_eq!(PathRef::Saved(0).params(&app), json!({\"name\": NAME}));\n // A path that is gone gets no name, which the engine refuses instead of editing another one.\n assert_eq!(PathRef::Saved(7).params(&app), json!({\"name\": \"\"}));\n assert!(app.run(\"path.moveAnchors\", json!({\"name\": \"\", \"anchors\": [[0, 0]], \"move\": [1, 1]})).is_err());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_saved_path_is_only_edited_while_the_paths_panel_selects_it",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_saved_path_is_only_edited_while_the_paths_panel_selects_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_saved_path(&mut app);\n app.ui.selected_path = None;\n let before = saved(&app);\n drag(&mut app, [120.5, 120.5], [130.5, 135.5], Modifiers::NONE);\n assert_eq!(saved(&app), before, \"an unselected saved path is not the target path\");\n assert!(!crate::direct_select::active_paths(&app).iter().any(|(r, _)| matches!(r, PathRef::Saved(_))));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(saved(&app), before, \"an unselected saved path is not the target path\");\n assert!(!crate::direct_select::active_paths(&app).iter().any(|(r, _)| matches!(r, PathRef::Saved(_))));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_selected_saved_path_comes_before_the_work_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_selected_saved_path_comes_before_the_work_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_saved_path(&mut app);\n // A work path on top of the same square: the saved path the panel selects wins.\n app.run(\"path.set\", json!({\"name\": \"work\", \"path\": square(40.0, 40.0, 80.0)})).unwrap();\n let work = app.session.active().unwrap().doc.work_path.clone().unwrap();\n let refs: Vec<PathRef> = crate::direct_select::active_paths(&app).into_iter().map(|(r, _)| r).collect();\n assert_eq!(refs, vec![PathRef::Saved(0), PathRef::Work]);\n drag(&mut app, [40.5, 40.5], [20.5, 30.5], Modifiers::NONE);\n assert_eq!(saved(&app).subpaths[0].knots[0].anchor, Point::new(20.0, 30.0));\n assert_eq!(app.session.active().unwrap().doc.work_path.clone().unwrap(), work, \"the work path is untouched\");\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(refs, vec![PathRef::Saved(0), PathRef::Work]);\n drag(&mut app, [40.5, 40.5], [20.5, 30.5], Modifiers::NONE);\n assert_eq!(saved(&app).subpaths[0].knots[0].anchor, Point::new(20.0, 30.0));\n assert_eq!(app.session.active().unwrap().doc.work_path.clone().unwrap(), work, \"the work path is untouched\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "path_selection_moves_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked path_selection_moves_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::PathSelection);\n with_saved_path(&mut app);\n let n = steps(&app);\n drag(&mut app, [80.0, 40.0], [90.0, 55.0], Modifiers::NONE);\n assert_eq!(\n anchors(&saved(&app)),\n vec![Point::new(50.0, 55.0), Point::new(130.0, 55.0), Point::new(130.0, 135.0), Point::new(50.0, 135.0)],\n \"the whole path moved by (10, 15)\"\n );\n assert_eq!(steps(&app), n + 1);\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(\n anchors(&saved(&app)),\n vec![Point::new(50.0, 55.0), Point::new(130.0, 55.0), Point::new(130.0, 135.0), Point::new(50.0, 135.0)],\n \"the whole path moved by (10, 15)\"\n assert_eq!(steps(&app), n + 1);\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "free_transform_path_names_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked free_transform_path_names_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::PathSelection);\n with_saved_path(&mut app);\n let (params, path) = crate::vector_ui::free_transform_path(&app).expect(\"the saved path is transformable\");\n assert_eq!(params, json!({\"name\": NAME}));\n assert_eq!(path, saved(&app));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(params, json!({\"name\": NAME}));\n assert_eq!(path, saved(&app));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "add_and_delete_anchor_point_edit_the_selected_saved_path",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked add_and_delete_anchor_point_edit_the_selected_saved_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::AddAnchorPoint);\n with_saved_path(&mut app);\n tool_event(&mut app, ToolEvent::Down { x: 80.0, y: 40.0, pressure: 1.0 }, Modifiers::NONE);\n tool_event(&mut app, ToolEvent::Up { x: 80.0, y: 40.0 }, Modifiers::NONE);\n assert_eq!(anchors(&saved(&app)).len(), 5, \"an anchor was added on the top segment\");\n app.ui.tool = Tool::DeleteAnchorPoint;\n tool_event(&mut app, ToolEvent::Down { x: 120.0, y: 120.0, pressure: 1.0 }, Modifiers::NONE);\n tool_event(&mut app, ToolEvent::Up { x: 120.0, y: 120.0 }, Modifiers::NONE);\n assert!(!anchors(&saved(&app)).contains(&Point::new(120.0, 120.0)), \"the corner anchor was deleted\");\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(anchors(&saved(&app)).len(), 5, \"an anchor was added on the top segment\");\n app.ui.tool = Tool::DeleteAnchorPoint;\n tool_event(&mut app, ToolEvent::Down { x: 120.0, y: 120.0, pressure: 1.0 }, Modifiers::NONE);\n tool_event(&mut app, ToolEvent::Up { x: 120.0, y: 120.0 }, Modifiers::NONE);\n assert!(!anchors(&saved(&app)).contains(&Point::new(120.0, 120.0)), \"the corner anchor was deleted\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_saved_path_read_from_a_psd_is_editable",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_saved_path_read_from_a_psd_is_editable -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut src = app(Tool::DirectSelection);\n with_saved_path(&mut src);\n let doc = src.session.active().unwrap().doc.clone();\n let bytes = photocraft_io::export(&doc, \"psd\", &Default::default()).unwrap().bytes;\n let mut app = app(Tool::DirectSelection);\n photocraft_engine::file_cmds::open_bytes_as(&mut app.session, \"paths.psd\", &bytes, None, None).unwrap();\n app.sync_views();\n assert!(app.session.active().unwrap().doc.paths.iter().any(|p| p.name == NAME), \"the PSD keeps its saved path\");\n app.ui.selected_path = Some(NAME.into());\n let n = steps(&app);\n drag(&mut app, [120.5, 120.5], [130.5, 135.5], Modifiers::NONE);\n // PSD stores path points as 8.24 fixed-point fractions of the canvas: compare loosely.",
|
|
"expected_assertions": [
|
|
" assert!(app.session.active().unwrap().doc.paths.iter().any(|p| p.name == NAME), \"the PSD keeps its saved path\");\n app.ui.selected_path = Some(NAME.into());\n let n = steps(&app);\n drag(&mut app, [120.5, 120.5], [130.5, 135.5], Modifiers::NONE);\n assert!((a.x - 130.0).abs() < 1e-3 && (a.y - 135.0).abs() < 1e-3, \"the anchor moved to (130, 135): {a:?}\");\n assert_eq!(steps(&app), n + 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "arrows_leave_a_saved_path_the_paths_panel_no_longer_selects",
|
|
"path": "crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked arrows_leave_a_saved_path_the_paths_panel_no_longer_selects -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(Tool::DirectSelection);\n with_saved_path(&mut app);\n app.run(\"path.set\", json!({\"name\": \"Path 2\", \"path\": square(10.0, 10.0, 20.0)})).unwrap();\n drag(&mut app, [30.0, 30.0], [50.0, 50.0], Modifiers::NONE);\n assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 0]]));\n // One \u2192 press through the canvas arrow keys, as egui delivers it.\n let arrow = |app: &mut PhotocraftApp| {\n let ctx = egui::Context::default();\n ctx.input_mut(|i| {\n i.events.push(egui::Event::Key { key: egui::Key::ArrowRight, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE })\n });\n crate::direct_select::arrow_keys(app, &ctx)",
|
|
"expected_assertions": [
|
|
" assert_eq!((app.ui.direct_selection.target, app.ui.direct_selection.anchors.clone()), (Some(PathRef::Saved(0)), vec![[0, 0]]));\n // One \u2192 press through the canvas arrow keys, as egui delivers it.\n let arrow = |app: &mut PhotocraftApp| {\n let ctx = egui::Context::default();\n assert!(arrow(&mut app), \"the selected path's anchor is nudged\");\n assert_eq!(saved(&app).subpaths[0].knots[0].anchor, Point::new(41.0, 40.0));\n app.ui.selected_path = Some(\"Path 2\".into());\n let (one, two) = (saved(&app), app.session.active().unwrap().doc.paths[1].path.clone());\n assert!(!arrow(&mut app), \"no key is used for a path that is not the target\");\n assert_eq!(saved(&app), one, \"Path 1 stays\");\n assert_eq!(app.session.active().unwrap().doc.paths[1].path, two, \"Path 2 stays\");\n assert_eq!(app.ui.direct_selection.target, None, \"the stale anchor selection is dropped\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/390dfbbcb026b33d46c52c62360b65deca00f258/crates/ui-egui/src/saved_path_edit_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9339",
|
|
"pr": 9339,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked ico_export_is_available_and_rejects_oversize_output -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked nearest_neighbor_doubles_each_pixel_into_an_exact_block -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked resample_choices_are_checked -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_height_when_rounded_width_is_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_proxy_limits_both_dimensions_before_rounding -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_as_downscales_stroke_only_shapes_and_preview -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_and_flattens -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_when_only_the_height_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layered_preview_runs_outside_the_ui_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked exact_pixels_lock_aspect_and_leave_the_source -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_srgb_export_tags_without_rewriting_pixels -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_srgb_export_24mp_keeps_pixel_tiles -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_jpeg_export_embeds_the_requested_srgb_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_cache_tracks_working_profiles_but_prefers_embedded_profiles -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_workers_keep_the_captured_source_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked replay_converts_untagged_pixels_from_the_original_working_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked profile_and_metadata_follow_the_existing_exporter -- --nocapture"
|
|
],
|
|
"expected": "ico export is available and rejects oversize output; nearest neighbor doubles each pixel into an exact block; resample choices are checked; export document scales height when rounded width is unchanged; export document proxy limits both dimensions before rounding; the estimate is the exported files size; export as downscales stroke only shapes and preview; export document scales and flattens; export document scales when only the height changes; layered preview runs outside the ui frame; exact pixels lock aspect and leave the source; untagged srgb export tags without rewriting pixels; untagged srgb export 24mp keeps pixel tiles; untagged jpeg export embeds the requested srgb profile; preview cache tracks working profiles but prefers embedded profiles; preview workers keep the captured source profile; replay converts untagged pixels from the original working profile; profile and metadata follow the existing exporter",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked ico_export_is_available_and_rejects_oversize_output -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked nearest_neighbor_doubles_each_pixel_into_an_exact_block -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked resample_choices_are_checked -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_height_when_rounded_width_is_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_proxy_limits_both_dimensions_before_rounding -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_as_downscales_stroke_only_shapes_and_preview -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_and_flattens -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked export_document_scales_when_only_the_height_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layered_preview_runs_outside_the_ui_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked exact_pixels_lock_aspect_and_leave_the_source -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_srgb_export_tags_without_rewriting_pixels -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_srgb_export_24mp_keeps_pixel_tiles -- --nocapture --ignored",
|
|
"cargo test -p photocraft-ui-egui --locked untagged_jpeg_export_embeds_the_requested_srgb_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_cache_tracks_working_profiles_but_prefers_embedded_profiles -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_workers_keep_the_captured_source_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked replay_converts_untagged_pixels_from_the_original_working_profile -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked profile_and_metadata_follow_the_existing_exporter -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "ico_export_is_available_and_rejects_oversize_output",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked ico_export_is_available_and_rejects_oversize_output -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 300, \"height\": 200})).unwrap();\n let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"ico\"));\n f.insert(\"scale\".into(), json!(100));\n assert!(FORMATS.iter().any(|(ext, _)| *ext == \"ico\"));\n assert!(default_export_document(&app.session.active().unwrap().doc, &f, None).err().is_some_and(|e| e.contains(\"256\")));\n f.insert(\"scale\".into(), json!(50));\n let resized = default_export_document(&app.session.active().unwrap().doc, &f, None).unwrap();\n assert_eq!((resized.size.width, resized.size.height), (150, 100));\n }",
|
|
"expected_assertions": [
|
|
" assert!(FORMATS.iter().any(|(ext, _)| *ext == \"ico\"));\n assert!(default_export_document(&app.session.active().unwrap().doc, &f, None).err().is_some_and(|e| e.contains(\"256\")));\n f.insert(\"scale\".into(), json!(50));\n let resized = default_export_document(&app.session.active().unwrap().doc, &f, None).unwrap();\n assert_eq!((resized.size.width, resized.size.height), (150, 100));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "nearest_neighbor_doubles_each_pixel_into_an_exact_block",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked nearest_neighbor_doubles_each_pixel_into_an_exact_block -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::SampleType;\n for depth in [SampleType::U8, SampleType::U16] {\n let doc = checker_doc(depth);\n let before = doc.clone();\n let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"png\"));\n f.insert(\"scale\".into(), json!(200));\n f.insert(\"resample\".into(), json!(\"nearest\"));\n let out = default_export_document(&doc, &f, None).unwrap();\n assert_eq!((out.size.width, out.size.height), (10, 6));\n assert_eq!(out.depth, depth);\n let surf = out.layers[0].surface().unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), (10, 6));\n assert_eq!(out.depth, depth);\n let surf = out.layers[0].surface().unwrap();\n for y in 0..6 {\n for x in 0..10 {\n assert_eq!(surf.rgba(x, y), checker(x / 2, y / 2), \"{depth:?} pixel {x},{y}\");\n }\n }\n assert_eq!(doc, before, \"{depth:?}: export leaves the source document unchanged\");\n\n // The preview proxy keeps Nearest Neighbor's hard edges too.\n let proxy = default_export_document(&doc, &f, Some(512)).unwrap();\n assert_eq!(proxy.layers[0].surface().unwrap().rgba(1, 1), checker(0, 0), \"{depth:?}: preview proxy is nearest as well\");\n assert_eq!(preview_filter(&f), egui::TextureOptions::NEAREST);\n\n f.insert(\"resample\".into(), json!(DEFAULT_RESAMPLE));\n let smooth = default_export_document(&doc, &f, None).unwrap();\n assert!(blended, \"{depth:?}: Bicubic Automatic blends neighbouring squares\");\n assert_eq!(preview_filter(&f), egui::TextureOptions::LINEAR);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "resample_choices_are_checked",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked resample_choices_are_checked -- --nocapture",
|
|
"fixture_and_action_excerpt": " let doc = checker_doc(photocraft_doc::SampleType::U8);\n let mut f = Map::new();\n f.insert(\"scale\".into(), json!(300));\n for (method, _) in RESAMPLE {\n f.insert(\"resample\".into(), json!(method));\n let out = default_export_document(&doc, &f, None).unwrap();\n assert_eq!((out.size.width, out.size.height), (15, 9), \"{method}\");\n }\n for bad in [json!(\"lanczos\"), json!(\"NEAREST\"), json!(\"\"), json!(1), json!({\"m\": \"nearest\"})] {\n f.insert(\"resample\".into(), bad.clone());\n let err = default_export_document(&doc, &f, None).unwrap_err();\n assert!(err.contains(\"resample must be\"), \"{bad}: {err}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), (15, 9), \"{method}\");\n }\n for bad in [json!(\"lanczos\"), json!(\"NEAREST\"), json!(\"\"), json!(1), json!({\"m\": \"nearest\"})] {\n f.insert(\"resample\".into(), bad.clone());\n assert!(err.contains(\"resample must be\"), \"{bad}: {err}\");\n assert!(default_export_document(&doc, &f, Some(512)).is_err(), \"{bad}: the preview reports it too\");\n }\n f.remove(\"resample\");\n assert_eq!(resample_method(&f, None).unwrap(), \"bicubicAutomatic\");\n assert_eq!(resample_method(&f, Some(512)).unwrap(), \"bilinear\", \"the preview stays on the fast path\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "export_document_scales_height_when_rounded_width_is_unchanged",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked export_document_scales_height_when_rounded_width_is_unchanged -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::{Color, ColorMode, SampleType, Size};\n\n for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {\n for (width, height, scale, expected) in [\n (1, 100, 50, (1, 50)),\n (1, 200, 50, (1, 100)),\n (10, 100, 99, (10, 99)),\n (10, 100, 101, (10, 101)),\n (400, 300, 50, (200, 150)),\n (400, 300, 100, (400, 300)),\n ] {\n let doc = Document::with_background(\"x\", Size::new(width, height), ColorMode::Rgb, depth, Color::WHITE);",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), expected, \"{width} \u00d7 {height} at {scale}%, {depth:?}\");\n assert_eq!(out.depth, depth, \"export preserves the document's depth\");\n assert_eq!(doc, before, \"export leaves the source document unchanged\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "export_document_proxy_limits_both_dimensions_before_rounding",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked export_document_proxy_limits_both_dimensions_before_rounding -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::{Color, ColorMode, SampleType, Size};\n\n for (width, height, scale, max_side, expected) in\n [(1, 1000, 100, 360, (1, 360)), (1, 1000, 50, 360, (1, 360)), (1, 1000, 25, 360, (1, 250)), (13, 20, 50, 8, (5, 8)), (20, 13, 50, 8, (8, 5))]\n {\n let doc = Document::with_background(\"x\", Size::new(width, height), ColorMode::Rgb, SampleType::U8, Color::WHITE);\n let before = doc.clone();\n let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"png\"));\n f.insert(\"scale\".into(), json!(scale));\n let out = default_export_document(&doc, &f, Some(max_side)).unwrap();\n assert_eq!((out.size.width, out.size.height), expected, \"{width} \u00d7 {height} at {scale}%, proxy limit {max_side}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), expected, \"{width} \u00d7 {height} at {scale}%, proxy limit {max_side}\");\n assert!(out.size.width.max(out.size.height) <= max_side, \"proxy respects its longest-side limit\");\n assert_eq!(doc, before, \"preview leaves the source document unchanged\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_estimate_is_the_exported_files_size",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut doc = Document::with_background(\n \"x\",\n photocraft_doc::Size::new(900, 300),\n photocraft_doc::ColorMode::Rgb,\n photocraft_doc::SampleType::U8,\n photocraft_doc::Color::WHITE,\n );\n let id = doc.layers[0].id;\n let surf = doc.layer_mut(id).unwrap().surface_mut().unwrap();\n let mut seed = 12345u32;\n for y in (0..300).step_by(2) {\n for x in (0..900).step_by(2) {",
|
|
"expected_assertions": [
|
|
" assert!((old as f64 / actual as f64 - 1.0).abs() > 0.1, \"the proxy estimate was off: {old} vs {actual}\");\n\n let ctx = egui::Context::default();\n let key = egui::Id::new(\"exact-estimate-test\");\n assert!(std::time::Instant::now() < deadline, \"the exact estimate did not arrive\");\n std::thread::sleep(std::time::Duration::from_millis(10));\n };\n assert_eq!(size, Some(actual));\n // Over the limit there is no exact size; the proxy estimate stays.\n let huge = Map::from_iter([\n (\"format\".into(), json!(\"jpg\")),\n assert_eq!(default_exact_estimate(&doc, &huge), None);\n // In scale mode the size comes from the scale, as the export's does, not from stale pixels.\n let big = Arc::new(Document::with_background(\n \"big\",\n assert_eq!(default_exact_estimate(&big, &stale), None, \"10000 \u00d7 10000 at 1000 %, over the limit\");\n let small = Map::from_iter([\n (\"format\".into(), json!(\"png\")),\n (\"sizing\".into(), json!(\"scale\")),\n assert_eq!(default_exact_estimate(&big, &small), Some(at_10), \"100 \u00d7 100 at 10 %, within it\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "export_as_downscales_stroke_only_shapes_and_preview",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked export_as_downscales_stroke_only_shapes_and_preview -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut session = photocraft_engine::Session::new();\n session.execute(\"file.new\", json!({\"width\": 1024, \"height\": 1024, \"depth\": depth, \"background\": \"transparent\"})).unwrap();\n let id = session.execute(\"shape.create\", json!({\"rect\": [256, 256, 512, 512], \"fill\": null, \"stroke\": {\"width\": 32}})).unwrap()[\"layer\"]\n .as_u64()\n .unwrap();\n let doc = session.active().unwrap().doc.clone();\n let fields = Map::from_iter([(\"format\".into(), json!(\"png\")), (\"scale\".into(), json!(25))]);\n for limit in [None, Some(128)] {\n let out = default_export_document(&doc, &fields, limit).unwrap();\n let side = if limit.is_some() { 128 } else { 256 };\n assert_eq!((out.size.width, out.size.height), (side, side));",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), (side, side));\n let shape = out.layer(photocraft_doc::LayerId(id)).unwrap();\n let photocraft_doc::LayerContent::Shape(shape) = &shape.content else {\n panic!(\"shape lost\");\n assert_eq!(shape.stroke.as_ref().unwrap().width, side as f32 / 32.0);\n let pixels = photocraft_compose::flatten(&out);\n let row = (side / 2 * side) as usize;\n assert!(pixels.px[row + (side / 4) as usize][3] > 0.99);\n assert!(pixels.px[row + (side / 4 - side / 32) as usize][3] < 0.01);\n assert!(pixels.px[row + (side / 2) as usize][3] < 0.01);\n }\n assert_eq!(session.active().unwrap().doc, doc, \"export leaves the source unchanged\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "export_document_scales_and_flattens",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked export_document_scales_and_flattens -- --nocapture",
|
|
"fixture_and_action_excerpt": " let doc = Document::with_background(\n \"x\",\n photocraft_doc::Size::new(200, 100),\n photocraft_doc::ColorMode::Rgb,\n photocraft_doc::SampleType::U8,\n photocraft_doc::Color::WHITE,\n );\n let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"jpg\"));\n f.insert(\"scale\".into(), json!(50));\n let out = default_export_document(&doc, &f, None).unwrap();\n assert_eq!((out.size.width, out.size.height), (100, 50));",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), (100, 50));\n assert_eq!(out.layers.len(), 1);\n let proxy = default_export_document(&doc, &f, Some(40)).unwrap();\n assert_eq!(proxy.size.width, 40);\n assert_eq!(settings(&f).jpeg_quality, Some(85));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "export_document_scales_when_only_the_height_changes",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked export_document_scales_when_only_the_height_changes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"png\"));\n f.insert(\"scale\".into(), json!(50));\n for (src_h, want_h) in [(100u32, 50u32), (200, 100)] {\n let doc = Document::with_background(\n \"x\",\n photocraft_doc::Size::new(1, src_h),\n photocraft_doc::ColorMode::Rgb,\n photocraft_doc::SampleType::U8,\n photocraft_doc::Color::WHITE,\n );\n let out = default_export_document(&doc, &f, None).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!((out.size.width, out.size.height), (1, want_h), \"1 \u00d7 {src_h} at 50%\");\n // The preview proxy takes the same path.\n let proxy = default_export_document(&doc, &f, Some(40)).unwrap();\n assert_eq!((proxy.size.width, proxy.size.height), (1, 40), \"proxy of 1 \u00d7 {src_h}\");\n }\n // The label and the export agree, and neither side drops below 1 px.\n assert_eq!(scaled_size(1.0, 100.0, 0.5), (1.0, 50.0));\n assert_eq!(scaled_size(10.0, 300.0, 0.01), (1.0, 3.0));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layered_preview_runs_outside_the_ui_frame",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layered_preview_runs_outside_the_ui_frame -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 32, \"height\": 16})).unwrap();\n for _ in 0..33 {\n app.run(\"layer.new.layer\", json!({})).unwrap();\n }\n let doc = app.session.active().unwrap().doc.clone();\n assert!(background_preview_needed(&doc));\n let fields = Map::from_iter([(\"format\".into(), json!(\"png\")), (\"scale\".into(), json!(100))]);\n let ctx = egui::Context::default();\n let key = egui::Id::new(\"layered-preview-test\");\n let mut result = None;\n let mut output = ctx.run_ui(Default::default(), |ctx| {",
|
|
"expected_assertions": [
|
|
" assert!(background_preview_needed(&doc));\n let fields = Map::from_iter([(\"format\".into(), json!(\"png\")), (\"scale\".into(), json!(100))]);\n let ctx = egui::Context::default();\n let key = egui::Id::new(\"layered-preview-test\");\n assert!(result.is_none(), \"the first UI frame must only start the worker\");\n\n let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);\n loop {\n assert_eq!((preview.width, preview.height), (32, 16));\n assert_eq!(preview.rgba.len(), 32 * 16 * 4);\n assert!(preview.estimate.is_some_and(|bytes| bytes > 0));\n break;\n }\n assert!(std::time::Instant::now() < deadline, \"background preview did not complete\");\n std::thread::sleep(std::time::Duration::from_millis(10));\n }\n assert_eq!(estimate_native(&doc, &proxy, &tiff_fields), Some(scaled_estimate(actual_bytes, &doc, &proxy, &tiff_fields)));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "exact_pixels_lock_aspect_and_leave_the_source",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked exact_pixels_lock_aspect_and_leave_the_source -- --nocapture",
|
|
"fixture_and_action_excerpt": " let linked = resize_from_scale(400.0, 200.0, 50.0).unwrap();\n assert_eq!((linked.width, linked.height, linked.scale), (200.0, 100.0, 50.0));\n let from_width = resize_from_side(400.0, 200.0, 100.0, 200.0, true, true).unwrap();\n assert_eq!((from_width.width, from_width.height), (100.0, 50.0));\n let from_height = resize_from_side(400.0, 200.0, 100.0, 40.0, true, false).unwrap();\n assert_eq!((from_height.width, from_height.height), (80.0, 40.0));\n let free = resize_from_side(400.0, 200.0, 100.0, 80.0, false, true).unwrap();\n assert_eq!((free.width, free.height), (100.0, 80.0));\n assert!(resize_from_scale(400.0, 200.0, 0.0).is_err());\n assert!(resize_from_side(400.0, 200.0, 0.0, 10.0, false, true).is_err());\n assert!(resize_from_side(10.0, 10.0, 400_000.0, 10.0, false, true).is_err());\n",
|
|
"expected_assertions": [
|
|
" assert_eq!((linked.width, linked.height, linked.scale), (200.0, 100.0, 50.0));\n let from_width = resize_from_side(400.0, 200.0, 100.0, 200.0, true, true).unwrap();\n assert_eq!((from_width.width, from_width.height), (100.0, 50.0));\n let from_height = resize_from_side(400.0, 200.0, 100.0, 40.0, true, false).unwrap();\n assert_eq!((from_height.width, from_height.height), (80.0, 40.0));\n let free = resize_from_side(400.0, 200.0, 100.0, 80.0, false, true).unwrap();\n assert_eq!((free.width, free.height), (100.0, 80.0));\n assert!(resize_from_scale(400.0, 200.0, 0.0).is_err());\n assert!(resize_from_side(400.0, 200.0, 0.0, 10.0, false, true).is_err());\n assert!(resize_from_side(10.0, 10.0, 400_000.0, 10.0, false, true).is_err());\n\n let doc = Document::with_background(\n \"x\",\n assert_eq!((out.size.width, out.size.height), (120, 40), \"explicit pixels win over the percent scale\");\n let proxy = default_export_document(&doc, &f, Some(20)).unwrap();\n assert_eq!((proxy.size.width, proxy.size.height), (20, 7));\n assert_eq!(doc, before, \"export leaves the source document unchanged\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "untagged_srgb_export_tags_without_rewriting_pixels",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked untagged_srgb_export_tags_without_rewriting_pixels -- --nocapture",
|
|
"fixture_and_action_excerpt": " check_profile_only_export(8, 8);\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "untagged_srgb_export_24mp_keeps_pixel_tiles",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked untagged_srgb_export_24mp_keeps_pixel_tiles -- --nocapture --ignored",
|
|
"fixture_and_action_excerpt": " let elapsed = check_profile_only_export(6000, 4000);\n println!(\"24 MP sRGB profile preparation (optimized test build): {elapsed:?}; all pixel tiles shared\");\n }",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": true,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "untagged_jpeg_export_embeds_the_requested_srgb_profile",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked untagged_jpeg_export_embeds_the_requested_srgb_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::{Color, ColorMode, SampleType, Size};\n for (mode, depth) in [\n (ColorMode::Rgb, SampleType::U8),\n (ColorMode::Rgb, SampleType::U16),\n (ColorMode::Rgb, SampleType::F32),\n (ColorMode::Grayscale, SampleType::U8),\n (ColorMode::Cmyk, SampleType::U8),\n ] {\n let doc = Document::with_background(\"untagged\", Size::new(8, 8), mode, depth, Color::WHITE);\n assert!(doc.icc_profile.is_none());\n let before = doc.clone();\n let mut fields =",
|
|
"expected_assertions": [
|
|
" assert!(doc.icc_profile.is_none());\n let before = doc.clone();\n let mut fields =\n json!({\"format\": \"jpg\", \"profile\": \"srgb\", \"embedProfile\": true, \"metadata\": \"none\", \"width\": 8, \"height\": 8}).as_object().unwrap().clone();\n assert!(profile.same_colors(photocraft_cms::Builtin::Srgb.profile()), \"{depth:?}\");\n fields.insert(\"embedProfile\".into(), json!(false));\n let bytes = photocraft_io::export(&converted, \"out.jpg\", &settings(&fields).io_options()).unwrap().bytes;\n assert!(photocraft_io::import(\"out.jpg\", &bytes).unwrap().document.icc_profile.is_none(), \"embedding remains optional\");\n fields.insert(\"profile\".into(), json!(\"document\"));\n fields.insert(\"embedProfile\".into(), json!(true));\n let unchanged = default_export_document(&doc, &fields, None).unwrap();\n assert!(unchanged.icc_profile.is_none(), \"Document Profile preserves an untagged source\");\n assert_eq!(doc, before, \"export must not tag or convert the source document\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preview_cache_tracks_working_profiles_but_prefers_embedded_profiles",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preview_cache_tracks_working_profiles_but_prefers_embedded_profiles -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_cms::Builtin;\n use photocraft_doc::{Color, SampleType, Size};\n for embedded in [false, true] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.execute(\"edit.colorSettings\", json!({\"workingRgb\": \"display-p3\", \"policyRgb\": \"off\"})).unwrap();\n let mut doc = Document::with_background(\"colour\", Size::new(8, 8), ColorMode::Rgb, SampleType::U8, Color::rgba(0.35, 0.65, 0.45, 1.0));\n if embedded {\n doc.icc_profile = Some(Builtin::DisplayP3.profile().to_bytes());\n }\n app.session.open_document(doc, None);\n let id = open(&mut app).unwrap();\n let mut fields = app.ui.dialog_mut(id).unwrap().fields.clone();",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.session.active().unwrap().revision, revision);\n let after = draw(&mut app, &mut fields);\n assert_eq!(settings_of(&fields), settings);\n assert_eq!(before.signature != after.signature, !embedded);\n assert_eq!(before.texture.unwrap().id() != after.texture.unwrap().id(), !embedded);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preview_workers_keep_the_captured_source_profile",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preview_workers_keep_the_captured_source_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.execute(\"edit.colorSettings\", json!({\"workingRgb\": \"display-p3\", \"policyRgb\": \"off\"})).unwrap();\n let doc = Document::with_background(\n \"colour\",\n photocraft_doc::Size::new(8, 8),\n ColorMode::Rgb,\n photocraft_doc::SampleType::U8,\n photocraft_doc::Color::rgba(0.35, 0.65, 0.45, 1.0),\n );\n app.session.open_document(doc, None);\n let doc = app.session.active().unwrap().doc.clone();\n let profile = effective_source_profile(&app, &doc);",
|
|
"expected_assertions": [
|
|
" assert!(std::time::Instant::now() < deadline, \"profile-aware preview workers must finish\");\n std::thread::sleep(std::time::Duration::from_millis(10));\n }\n assert_eq!(preview.unwrap().unwrap().rgba, expected.rgba);\n assert_eq!(size.unwrap(), Some(expected_size));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "replay_converts_untagged_pixels_from_the_original_working_profile",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked replay_converts_untagged_pixels_from_the_original_working_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_cms::{Builtin, Intent};\n use photocraft_doc::{Color, ColorMode, SampleType, Size};\n for working in [Builtin::DisplayP3, Builtin::AdobeRgbCompat] {\n for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.execute(\"edit.colorSettings\", json!({\"workingRgb\": working.id(), \"policyRgb\": \"off\"})).unwrap();\n let doc = Document::with_background(\"untagged\", Size::new(8, 8), ColorMode::Rgb, depth, Color::rgba(0.35, 0.65, 0.45, 1.0));\n app.session.open_document(doc, None);\n let source = app.session.active().unwrap().doc.clone();\n assert!(source.icc_profile.is_none());\n let mut expected = (*source).clone();\n expected.icc_profile = Some(working.profile().to_bytes());",
|
|
"expected_assertions": [
|
|
" assert!(source.icc_profile.is_none());\n let mut expected = (*source).clone();\n expected.icc_profile = Some(working.profile().to_bytes());\n photocraft_engine::color_cmds::convert_document(&mut expected, Builtin::Srgb.profile(), Intent::Perceptual, true).unwrap();\n assert_ne!(original_pixel, expected_pixel, \"the control must require a pixel conversion\");\n let captured = Arc::new(std::sync::Mutex::new(None));\n let output = captured.clone();\n app.services.export = Some(Box::new(move |doc, _, _| {\n assert_eq!(actual.layers[0].surface().unwrap().pixel(0, 0), expected_pixel, \"{working:?} {depth:?}\");\n let profile = photocraft_cms::Profile::parse(actual.icc_profile.as_deref().unwrap()).unwrap();\n assert!(profile.same_bytes(Builtin::Srgb.profile()));\n assert_eq!(app.session.active().unwrap().doc, source);\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "profile_and_metadata_follow_the_existing_exporter",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked profile_and_metadata_follow_the_existing_exporter -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_cms::Builtin;\n\n let mut f = Map::new();\n f.insert(\"format\".into(), json!(\"jpg\"));\n assert!(settings(&f).embed_metadata, \"a missing metadata choice keeps EXIF and resolution\");\n assert!(settings(&f).embed_icc);\n f.insert(\"metadata\".into(), json!(\"none\"));\n f.insert(\"embedProfile\".into(), json!(false));\n let none = settings(&f);\n assert!(!none.xmp_all && !none.embed_metadata && !none.embed_icc);\n f.insert(\"metadata\".into(), json!(\"exif\"));\n let exif = settings(&f);",
|
|
"expected_assertions": [
|
|
" assert!(settings(&f).embed_metadata, \"a missing metadata choice keeps EXIF and resolution\");\n assert!(settings(&f).embed_icc);\n f.insert(\"metadata\".into(), json!(\"none\"));\n f.insert(\"embedProfile\".into(), json!(false));\n let none = settings(&f);\n assert!(!none.xmp_all && !none.embed_metadata && !none.embed_icc);\n f.insert(\"metadata\".into(), json!(\"exif\"));\n let exif = settings(&f);\n assert!(!exif.xmp_all && exif.embed_metadata);\n f.insert(\"metadata\".into(), json!(\"all\"));\n f.insert(\"embedProfile\".into(), json!(true));\n let all = settings(&f);\n assert!(all.xmp_all && all.embed_metadata && all.embed_icc);\n\n let mut doc = Document::with_background(\n \"x\",\n assert!(parsed.same_colors(Builtin::Srgb.profile()), \"Convert to sRGB replaces the document profile\");\n let stripped = photocraft_io::export(&converted, \"out.jpg\", &settings(&f).io_options()).unwrap().bytes;\n assert!(!stripped.windows(b\"ICC_PROFILE\".len()).any(|w| w == b\"ICC_PROFILE\"));\n assert!(!stripped.windows(b\"secret\".len()).any(|w| w == b\"secret\"));\n f.insert(\"metadata\".into(), json!(\"all\"));\n f.insert(\"embedProfile\".into(), json!(true));\n let kept = photocraft_io::export(&converted, \"out.jpg\", &settings(&f).io_options()).unwrap().bytes;\n assert!(kept.windows(b\"ICC_PROFILE\".len()).any(|w| w == b\"ICC_PROFILE\"));\n assert!(kept.windows(b\"secret\".len()).any(|w| w == b\"secret\"));\n assert_eq!(doc, before);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/393645ab91460af2e37cc3ba8f6921e7551f676e/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9342",
|
|
"pr": 9342,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked doc_save_rejects_a_bad_quality_instead_of_ignoring_or_clamping_it -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked exif_srgb_jpeg_round_trip -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked embed_color_profile_tags_an_untagged_document_srgb -- --nocapture",
|
|
"cargo test -p photocraft-io --locked untagged_documents_embed_the_profile_they_are_assumed_to_be_in -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture"
|
|
],
|
|
"expected": "doc save rejects a bad quality instead of ignoring or clamping it; exif srgb jpeg round trip; embed color profile tags an untagged document srgb; untagged documents embed the profile they are assumed to be in; the estimate is the exported files size",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked doc_save_rejects_a_bad_quality_instead_of_ignoring_or_clamping_it -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked exif_srgb_jpeg_round_trip -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked embed_color_profile_tags_an_untagged_document_srgb -- --nocapture",
|
|
"cargo test -p photocraft-io --locked untagged_documents_embed_the_profile_they_are_assumed_to_be_in -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "doc_save_rejects_a_bad_quality_instead_of_ignoring_or_clamping_it",
|
|
"path": "crates/automation/src/rpc.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked doc_save_rejects_a_bad_quality_instead_of_ignoring_or_clamping_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = std::env::temp_dir().join(format!(\"pc-rpc-save-quality-{}\", std::process::id()));\n std::fs::create_dir_all(&dir).unwrap();\n let path = dir.join(\"x.webp\");\n let mut h = Headless::trusted_local();\n h.handle(\"doc.new\", json!({\"width\": 16, \"height\": 16})).unwrap();\n for q in [json!(85.0), json!(\"85\"), json!(0), json!(500), json!(-5), json!(true)] {\n let err = h.handle(\"doc.save\", json!({\"path\": path.to_string_lossy(), \"quality\": q})).unwrap_err().to_string();\n assert!(err.contains(\"quality\"), \"{q}: {err}\");\n assert!(!path.exists(), \"{q} wrote a file\");\n }\n h.handle(\"doc.save\", json!({\"path\": path.to_string_lossy(), \"quality\": 85})).unwrap();\n let bytes = std::fs::read(&path).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(err.contains(\"quality\"), \"{q}: {err}\");\n assert!(!path.exists(), \"{q} wrote a file\");\n }\n h.handle(\"doc.save\", json!({\"path\": path.to_string_lossy(), \"quality\": 85})).unwrap();\n let bytes = std::fs::read(&path).unwrap();\n assert!(bytes.windows(4).any(|c| c == b\"VP8 \") && !bytes.windows(4).any(|c| c == b\"VP8L\"), \"a WebP saved with a quality is lossy\");\n std::fs::remove_dir_all(dir).unwrap();\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c46a74621d36adae9707ab8f3eb39cf6b4c302b9/crates/automation/src/rpc.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "exif_srgb_jpeg_round_trip",
|
|
"path": "crates/engine/src/color_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked exif_srgb_jpeg_round_trip -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"edit.colorSettings\", json!({\"workingRgb\": \"display-p3\"})).unwrap();\n // Embed Color Profile off: an untagged document is otherwise tagged sRGB on export (#9325).\n let mut opts = photocraft_io::ExportOptions::default();\n opts.encode.embed_icc = false;\n let r = photocraft_io::export(&untagged_camera_file(Some(1)), \"x.jpg\", &opts).unwrap();\n let back = photocraft_io::import(\"x.jpg\", &r.bytes).unwrap().document;\n assert!(back.icc_profile.is_none(), \"no ICC profile in the file\");\n let (_, r) = s.open_document(back, None);\n assert_eq!((r[\"action\"].as_str(), r[\"exif\"].as_bool()), (Some(\"kept\"), Some(true)));\n assert!(desc(&s.active().unwrap().doc).unwrap().starts_with(\"sRGB\"));\n }",
|
|
"expected_assertions": [
|
|
" assert!(back.icc_profile.is_none(), \"no ICC profile in the file\");\n let (_, r) = s.open_document(back, None);\n assert_eq!((r[\"action\"].as_str(), r[\"exif\"].as_bool()), (Some(\"kept\"), Some(true)));\n assert!(desc(&s.active().unwrap().doc).unwrap().starts_with(\"sRGB\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c46a74621d36adae9707ab8f3eb39cf6b4c302b9/crates/engine/src/color_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "embed_color_profile_tags_an_untagged_document_srgb",
|
|
"path": "crates/engine/src/web_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked embed_color_profile_tags_an_untagged_document_srgb -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session(8);\n assert!(s.active().unwrap().doc.icc_profile.is_none(), \"a new document is untagged\");\n let dir = tmp(\"assumed-icc\");\n let profile = |path: &str| decode(path).icc.map(|b| photocraft_cms::Profile::parse(&b).unwrap().description);\n for (format, ext) in [(\"jpeg\", \"jpg\"), (\"png24\", \"png\")] {\n let on = format!(\"{dir}/on.{ext}\");\n s.execute(\"file.export.saveForWebLegacy\", json!({\"format\": format, \"embedIcc\": true, \"path\": on})).unwrap();\n assert_eq!(profile(&on).as_deref(), Some(photocraft_cms::Builtin::Srgb.description()), \"{format}\");\n let off = format!(\"{dir}/off.{ext}\");\n s.execute(\"file.export.saveForWebLegacy\", json!({\"format\": format, \"embedIcc\": false, \"path\": off})).unwrap();\n assert_eq!(profile(&off), None, \"{format}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(s.active().unwrap().doc.icc_profile.is_none(), \"a new document is untagged\");\n let dir = tmp(\"assumed-icc\");\n let profile = |path: &str| decode(path).icc.map(|b| photocraft_cms::Profile::parse(&b).unwrap().description);\n for (format, ext) in [(\"jpeg\", \"jpg\"), (\"png24\", \"png\")] {\n assert_eq!(profile(&on).as_deref(), Some(photocraft_cms::Builtin::Srgb.description()), \"{format}\");\n let off = format!(\"{dir}/off.{ext}\");\n s.execute(\"file.export.saveForWebLegacy\", json!({\"format\": format, \"embedIcc\": false, \"path\": off})).unwrap();\n assert_eq!(profile(&off), None, \"{format}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c46a74621d36adae9707ab8f3eb39cf6b4c302b9/crates/engine/src/web_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "untagged_documents_embed_the_profile_they_are_assumed_to_be_in",
|
|
"path": "crates/io/src/flat.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked untagged_documents_embed_the_profile_they_are_assumed_to_be_in -- --nocapture",
|
|
"fixture_and_action_excerpt": " let opts = ExportOptions::default();\n assert!(opts.encode.embed_icc);\n for ext in [\"jpg\", \"png\", \"tif\", \"webp\"] {\n let r = crate::export(&doc(ColorMode::Rgb), ext, &opts).unwrap();\n assert_eq!(embedded(&r).as_deref(), Some(Builtin::Srgb.description()), \"{ext}\");\n }\n // #9342 review: an untagged gray document shows through the default working gray (Dot\n // Gain 20 %-compatible), so that is the profile its samples are tagged with, not sGray\n // (which would show them darker than the canvas).\n let r = crate::export(&doc(ColorMode::Grayscale), \"png\", &opts).unwrap();\n assert_eq!(embedded(&r).as_deref(), Some(Builtin::DotGain20Compat.description()));\n // Embed Color Profile off: still none.",
|
|
"expected_assertions": [
|
|
" assert!(opts.encode.embed_icc);\n for ext in [\"jpg\", \"png\", \"tif\", \"webp\"] {\n let r = crate::export(&doc(ColorMode::Rgb), ext, &opts).unwrap();\n assert_eq!(embedded(&r).as_deref(), Some(Builtin::Srgb.description()), \"{ext}\");\n }\n // #9342 review: an untagged gray document shows through the default working gray (Dot\n // Gain 20 %-compatible), so that is the profile its samples are tagged with, not sGray\n assert_eq!(embedded(&r).as_deref(), Some(Builtin::DotGain20Compat.description()));\n // Embed Color Profile off: still none.\n let mut off = ExportOptions::default();\n off.encode.embed_icc = false;\n assert_eq!(embedded(&crate::export(&doc(ColorMode::Rgb), \"jpg\", &off).unwrap()), None);\n // A format without profiles gets no warning about one.\n let r = crate::export(&doc(ColorMode::Rgb), \"bmp\", &opts).unwrap();\n assert!(!r.warnings.iter().any(|w| w.contains(\"profile\")), \"{:?}\", r.warnings);\n // A tagged document keeps its own profile.\n let mut p3 = doc(ColorMode::Rgb);\n p3.icc_profile = Some(Arc::new(Builtin::DisplayP3.profile().to_bytes().to_vec()));\n assert_eq!(embedded(&crate::export(&p3, \"jpg\", &opts).unwrap()).as_deref(), Some(Builtin::DisplayP3.description()));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c46a74621d36adae9707ab8f3eb39cf6b4c302b9/crates/io/src/flat.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_estimate_is_the_exported_files_size",
|
|
"path": "crates/ui-egui/src/export_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_estimate_is_the_exported_files_size -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut doc = Document::with_background(\n \"x\",\n photocraft_doc::Size::new(900, 300),\n photocraft_doc::ColorMode::Rgb,\n photocraft_doc::SampleType::U8,\n photocraft_doc::Color::WHITE,\n );\n let id = doc.layers[0].id;\n let surf = doc.layer_mut(id).unwrap().surface_mut().unwrap();\n let mut seed = 12345u32;\n for y in (0..300).step_by(2) {\n for x in (0..900).step_by(2) {",
|
|
"expected_assertions": [
|
|
" assert!((old as f64 / actual as f64 - 1.0).abs() > 0.1, \"the proxy estimate was off: {old} vs {actual}\");\n\n let ctx = egui::Context::default();\n let key = egui::Id::new(\"exact-estimate-test\");\n assert!(std::time::Instant::now() < deadline, \"the exact estimate did not arrive\");\n std::thread::sleep(std::time::Duration::from_millis(10));\n };\n assert_eq!(size, Some(actual));\n // Over the limit there is no exact size; the proxy estimate stays.\n let huge = Map::from_iter([\n (\"format\".into(), json!(\"jpg\")),\n assert_eq!(exact_estimate(&doc, &huge), None);\n // In scale mode the size comes from the scale, as the export's does, not from stale pixels.\n let big = Arc::new(Document::with_background(\n \"big\",\n assert_eq!(exact_estimate(&big, &stale), None, \"10000 \u00d7 10000 at 1000 %, over the limit\");\n let small = Map::from_iter([\n (\"format\".into(), json!(\"png\")),\n (\"sizing\".into(), json!(\"scale\")),\n assert_eq!(exact_estimate(&big, &small), Some(at_10), \"100 \u00d7 100 at 10 %, within it\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/c46a74621d36adae9707ab8f3eb39cf6b4c302b9/crates/ui-egui/src/export_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9401",
|
|
"pr": 9401,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked write_keeps_the_replaced_files_creation_time -- --nocapture",
|
|
"cargo test -p photocraft-format --locked keeps_the_original_creation_time -- --nocapture",
|
|
"cargo test -p photocraft-format --locked keeps_the_creation_time_under_a_deny_write_acl -- --nocapture"
|
|
],
|
|
"expected": "write keeps the replaced files creation time; keeps the original creation time; keeps the creation time under a deny write acl",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked write_keeps_the_replaced_files_creation_time -- --nocapture",
|
|
"cargo test -p photocraft-format --locked keeps_the_original_creation_time -- --nocapture",
|
|
"cargo test -p photocraft-format --locked keeps_the_creation_time_under_a_deny_write_acl -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "write_keeps_the_replaced_files_creation_time",
|
|
"path": "crates/automation/src/workspace.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked write_keeps_the_replaced_files_creation_time -- --nocapture",
|
|
"fixture_and_action_excerpt": " use std::os::macos::fs::FileTimesExt;\n let (inside, _, workspace) = roots(\"created\");\n let path = inside.join(\"doc.psd\");\n workspace.write(\"doc.psd\", b\"original\").unwrap();\n let born = std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1_600_000_000);\n std::fs::OpenOptions::new().write(true).open(&path).unwrap().set_times(std::fs::FileTimes::new().set_created(born)).unwrap();\n workspace.write(\"doc.psd\", b\"replacement\").unwrap();\n assert_eq!(std::fs::read(&path).unwrap(), b\"replacement\");\n assert_eq!(std::fs::metadata(&path).unwrap().created().unwrap(), born, \"the creation time survives the automation write\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(std::fs::read(&path).unwrap(), b\"replacement\");\n assert_eq!(std::fs::metadata(&path).unwrap().created().unwrap(), born, \"the creation time survives the automation write\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f241bba1adfb9c7ec5dd5ed9d86f95b63c7bc2c3/crates/automation/src/workspace.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "keeps_the_original_creation_time",
|
|
"path": "crates/format/src/atomic/tests.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked keeps_the_original_creation_time -- --nocapture",
|
|
"fixture_and_action_excerpt": " use std::os::macos::fs::FileTimesExt;\n let d = TempDir::new(\"created\");\n let p = d.0.join(\"doc.psd\");\n std::fs::write(&p, ORIGINAL).unwrap();\n // A creation time well in the past, so a reset to \"now\" can't pass for it.\n let born = std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1_600_000_000);\n std::fs::OpenOptions::new().write(true).open(&p).unwrap().set_times(std::fs::FileTimes::new().set_created(born)).unwrap();\n assert_eq!(std::fs::metadata(&p).unwrap().created().unwrap(), born);\n atomic_write(&p, b\"new\").unwrap();\n assert_eq!(std::fs::read(&p).unwrap(), b\"new\");\n assert_eq!(std::fs::metadata(&p).unwrap().created().unwrap(), born, \"the creation time survives the save\");\n assert_no_temp(&d.0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(std::fs::metadata(&p).unwrap().created().unwrap(), born);\n atomic_write(&p, b\"new\").unwrap();\n assert_eq!(std::fs::read(&p).unwrap(), b\"new\");\n assert_eq!(std::fs::metadata(&p).unwrap().created().unwrap(), born, \"the creation time survives the save\");\n assert_no_temp(&d.0);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f241bba1adfb9c7ec5dd5ed9d86f95b63c7bc2c3/crates/format/src/atomic/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "keeps_the_creation_time_under_a_deny_write_acl",
|
|
"path": "crates/format/src/atomic/tests.rs",
|
|
"package": "photocraft-format",
|
|
"command": "cargo test -p photocraft-format --locked keeps_the_creation_time_under_a_deny_write_acl -- --nocapture",
|
|
"fixture_and_action_excerpt": " use std::os::macos::fs::FileTimesExt;\n let d = TempDir::new(\"created-acl\");\n let p = d.0.join(\"doc.psd\");\n std::fs::write(&p, ORIGINAL).unwrap();\n let born = std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1_600_000_000);\n std::fs::OpenOptions::new().write(true).open(&p).unwrap().set_times(std::fs::FileTimes::new().set_created(born)).unwrap();\n let Ok(user) = std::env::var(\"USER\") else { return };\n let deny = exacl::AclEntry::deny_user(&user, exacl::Perm::WRITE, None);\n if exacl::setfacl(&[&p], &[deny], None).is_err() {\n return; // a file system without ACLs: nothing to assert\n }\n atomic_write(&p, b\"new\").unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(std::fs::read(&p).unwrap(), b\"new\");\n assert_eq!(std::fs::metadata(&p).unwrap().created().unwrap(), born, \"the creation time survives a deny-write ACL\");\n let _ = exacl::setfacl(&[&p], &[], None);\n assert_no_temp(&d.0);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f241bba1adfb9c7ec5dd5ed9d86f95b63c7bc2c3/crates/format/src/atomic/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9416",
|
|
"pr": 9416,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Synthetic repeated tags and fixed-record stream in affinity/src/tests.rs; licensed curve document with known topology/reference",
|
|
"action": [
|
|
"cargo test -p photocraft-affinity --locked lookup_keeps_first_match_for_every_object_size -- --nocapture",
|
|
"cargo test -p photocraft-affinity --locked a_fixed_size_array_is_one_buffer_and_one_value_per_record -- --nocapture"
|
|
],
|
|
"expected": "Tag lookup preserves first occurrence for sizes 0\u201359 and positional-tag exclusion; five 18-byte records occupy one buffer and report five elements. Full curve import preserves finite control points, nodes and topology.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Also run full affinity suite and applicable pinned corpus tests. Record curve fixture hash and compare imported geometry/appearance; if no end-to-end contiguous-curve fixture exists, mark that subcase BLOCKED. Storage tests alone do not establish render fidelity.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-affinity --locked lookup_keeps_first_match_for_every_object_size -- --nocapture",
|
|
"cargo test -p photocraft-affinity --locked a_fixed_size_array_is_one_buffer_and_one_value_per_record -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-9590",
|
|
"pr": 9590,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-io --locked psd_contours_keep_at_most_16_points_and_their_peaks -- --nocapture",
|
|
"cargo test -p photocraft-io --locked a_point_on_a_tiny_straight_span_is_not_a_bend -- --nocapture"
|
|
],
|
|
"expected": "psd contours keep at most 16 points and their peaks; a point on a tiny straight span is not a bend",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-io --locked psd_contours_keep_at_most_16_points_and_their_peaks -- --nocapture",
|
|
"cargo test -p photocraft-io --locked a_point_on_a_tiny_straight_span_is_not_a_bend -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "psd_contours_keep_at_most_16_points_and_their_peaks",
|
|
"path": "crates/io/src/effects_map.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked psd_contours_keep_at_most_16_points_and_their_peaks -- --nocapture",
|
|
"fixture_and_action_excerpt": " let points: Vec<CurvePoint> = (0..29)\n .map(|i| {\n let x = i as f32 / 28.0;\n // Rings at x = 0.25 and 0.75, small wiggles between.\n let y = (1.0 - ((x - 0.25).abs() * 8.0)).max(0.0).max(1.0 - (x - 0.75).abs() * 8.0) + if i % 2 == 0 { 0.0 } else { 0.01 };\n CurvePoint { input: x, output: y.clamp(0.0, 1.0) }\n })\n .collect();\n let c = Contour::Custom { name: \"Two rings\".into(), points: points.clone(), corners: vec![false; 29] };\n let out = crv(&contour_value(&c));\n assert_eq!(out.len(), 16);\n assert_eq!(out.first().copied(), Some((0.0, f64::from(points[0].output) * 255.0)));",
|
|
"expected_assertions": [
|
|
" assert_eq!(out.len(), 16);\n assert_eq!(out.first().copied(), Some((0.0, f64::from(points[0].output) * 255.0)));\n assert_eq!(out.last().map(|p| p.0), Some(255.0));\n let peak = |x: f32| out.iter().any(|p| ((p.0 / 255.0) as f32 - x).abs() < 0.03 && p.1 > 240.0);\n assert!(peak(0.25) && peak(0.75), \"both rings kept: {out:?}\");\n assert!(out.windows(2).all(|w| w[0].0 < w[1].0), \"in order: {out:?}\");\n\n let short = Contour::Custom { name: \"Short\".into(), points: points[..16].to_vec(), corners: vec![false; 16] };\n assert_eq!(crv(&contour_value(&short)).len(), 16);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9744ed44dc782613b19a97b8c159a091f73e669/crates/io/src/effects_map.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_point_on_a_tiny_straight_span_is_not_a_bend",
|
|
"path": "crates/io/src/effects_map.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked a_point_on_a_tiny_straight_span_is_not_a_bend -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = |input: f32, output: f32| CurvePoint { input, output };\n // Three distinct inputs a few ulps apart near 0.5, on a straight rise from 0 to 1.\n let (a, b) = (0.5_f32, f32::from_bits(0.5_f32.to_bits() + 2));\n let mid = f32::from_bits(0.5_f32.to_bits() + 1);\n let mut points = vec![p(0.0, 0.0), p(0.2, 0.0)];\n points.extend([p(a, 0.0), p(mid, 0.5), p(b, 1.0)]);\n // Fourteen gentle bends after it, each one a real (if small) peak.\n points.extend((0..14).map(|k| p(0.55 + k as f32 * 0.03, if k % 2 == 0 { 1.0 } else { 0.9 })));\n points.push(p(1.0, 1.0));\n let kept = psd_contour_points(&points);\n assert_eq!(kept.len(), 16);\n assert!(!kept.contains(&3), \"the point on the tiny straight span was kept over a real bend: {kept:?}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(kept.len(), 16);\n assert!(!kept.contains(&3), \"the point on the tiny straight span was kept over a real bend: {kept:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9744ed44dc782613b19a97b8c159a091f73e669/crates/io/src/effects_map.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4763",
|
|
"pr": 4763,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Windows portable build, synthetic grid in Liquify, Warp tool, brush diameter 40 px, density 50%, preview zoom 100%; repeat at 200%. Record document/history and brush settings before the gesture.",
|
|
"action": "Hold Alt and right-drag without Shift, or Ctrl+Alt and primary-drag. Move 25 screen points right: at 100% zoom diameter becomes 90 px, at 200% zoom 65 px. From density 50%, move 100 screen points down: density becomes 100% at either zoom; 100 points up becomes 0%. Release, then Cancel Liquify. Alt+primary alone remains the opposite-tool gesture; Shift+Alt+right is not brush resize.",
|
|
"expected": "HUD and circle remain anchored at press origin, show diameter/density, and follow the shared zoom-corrected resize formula. Resizing starts on the press and creates no paint stroke/history; releasing ends resize. Cancel restores original document and history.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-4985",
|
|
"pr": 4985,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_selects_journals_and_clear_erases -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mode_picker_outside_dismissal_does_not_paint_or_erase -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mode_control_can_pick_a_row_with_ui_click -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_cancels_and_other_gestures_keep_their_routes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked escape_dismissal_consumes_a_held_secondary_release -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_released_before_the_right_button_still_opens_the_mode_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_brush_does_not_open_presets_or_paint -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked brush_mode_control_routes_modifiers_and_reports_choices_without_history -- --nocapture"
|
|
],
|
|
"expected": "shift right mode picker selects journals and clear erases; mode picker outside dismissal does not paint or erase; mode control can pick a row with ui click; shift right mode picker cancels and other gestures keep their routes; escape dismissal consumes a held secondary release; shift released before the right button still opens the mode picker; shift right brush does not open presets or paint; brush mode control routes modifiers and reports choices without history",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_selects_journals_and_clear_erases -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mode_picker_outside_dismissal_does_not_paint_or_erase -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mode_control_can_pick_a_row_with_ui_click -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_cancels_and_other_gestures_keep_their_routes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked escape_dismissal_consumes_a_held_secondary_release -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_released_before_the_right_button_still_opens_the_mode_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_right_brush_does_not_open_presets_or_paint -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked brush_mode_control_routes_modifiers_and_reports_choices_without_history -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "shift_right_mode_picker_selects_journals_and_clear_erases",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_selects_journals_and_clear_erases -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n let mut h = harness(Some(\"erase\"));\n let history = h.state().session.active().unwrap().history.past_len();\n let journal = h.state().session.journal.len();\n mode_right_click(&mut h, Modifiers::SHIFT);\n assert!(h.state().ui.brush_mode_menu.is_some());\n assert!(h.state().ui.brush_picker.is_none() && h.state().drag.is_none());\n assert_eq!(h.state().session.journal.len(), journal);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n h.get_by_label(\"Multiply\").click();\n h.run_steps(2);\n assert!(h.state().ui.brush_mode_menu.is_none());",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_mode_menu.is_some());\n assert!(h.state().ui.brush_picker.is_none() && h.state().drag.is_none());\n assert_eq!(h.state().session.journal.len(), journal);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n h.get_by_label(\"Multiply\").click();\n h.run_steps(2);\n assert!(h.state().ui.brush_mode_menu.is_none());\n assert_eq!(h.state().session.tools.brush.mode, photocraft_doc::BlendMode::Multiply);\n assert_eq!(h.state().session.journal.last().unwrap(), &(\"tools.setBrush\".into(), json!({\"brush\": {\"mode\": \"Multiply\"}})));\n let (a, b) = drag(&mut h, PointerButton::Primary);\n let mid = a + (b - a) * 0.5;\n assert!(alpha_at(&h, mid) > 0.9);\n mode_right_click(&mut h, Modifiers::SHIFT);\n h.get_by_label(\"Clear\").click();\n h.run_steps(2);\n assert!(h.state().ui.tool_options.brush_clear);\n assert_eq!(h.state().session.tools.brush.mode, photocraft_doc::BlendMode::Multiply, \"Clear keeps the underlying mode, as the options bar does\");\n drag(&mut h, PointerButton::Primary);\n assert_eq!(alpha_at(&h, mid), 0.0);\n assert!(strokes(&h).last().unwrap()[\"erase\"].as_bool().unwrap());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "mode_picker_outside_dismissal_does_not_paint_or_erase",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked mode_picker_outside_dismissal_does_not_paint_or_erase -- --nocapture",
|
|
"fixture_and_action_excerpt": " for button in [PointerButton::Primary, PointerButton::Secondary] {\n let mut h = harness(Some(\"erase\"));\n drag(&mut h, PointerButton::Primary);\n let journal = h.state().session.journal.len();\n let history = h.state().session.active().unwrap().history.past_len();\n mode_right_click(&mut h, Modifiers::SHIFT);\n // A full outside drag must only dismiss, including its release click.\n drag(&mut h, button);\n assert!(h.state().ui.brush_mode_menu.is_none());\n assert_eq!(h.state().session.journal.len(), journal, \"dismissal must not paint/erase with {button:?}\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n }",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_mode_menu.is_none());\n assert_eq!(h.state().session.journal.len(), journal, \"dismissal must not paint/erase with {button:?}\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "mode_control_can_pick_a_row_with_ui_click",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked mode_control_can_pick_a_row_with_ui_click -- --nocapture",
|
|
"fixture_and_action_excerpt": " use crate::control::{ControlRequest, Outcome, handle};\n use egui_kittest::kittest::Queryable;\n let mut h = harness(Some(\"erase\"));\n let ctx = h.ctx.clone();\n let before = h.state().session.journal.len();\n let (req, _) = ControlRequest::new(\n \"ui.pointer\",\n json!({\"button\": \"right\", \"shift\": true,\n \"events\": [{\"kind\": \"down\", \"x\": 200, \"y\": 150}, {\"kind\": \"up\", \"x\": 200, \"y\": 150}]}),\n );\n assert!(matches!(handle(h.state_mut(), &ctx, &req), Outcome::Done(_)));\n h.run_steps(2);",
|
|
"expected_assertions": [
|
|
" assert!(matches!(handle(h.state_mut(), &ctx, &req), Outcome::Done(_)));\n h.run_steps(2);\n assert!(h.state().ui.brush_mode_menu.is_some());\n assert_eq!(h.state().session.journal.len(), before);\n let at = h.get_by_label(\"Darken\").rect().center();\n let (req, _) = ControlRequest::new(\"ui.click\", json!({\"x\": at.x, \"y\": at.y}));\n assert!(matches!(handle(h.state_mut(), &ctx, &req), Outcome::AfterInput));\n // The app injects these queued control events into its next frame's input.\n let events = std::mem::take(&mut h.state_mut().synthetic);\n for event in events {\n assert!(h.state().ui.brush_mode_menu.is_none());\n assert_eq!(h.state().session.tools.brush.mode, photocraft_doc::BlendMode::Darken);\n assert_eq!(h.state().session.journal.last().unwrap(), &(\"tools.setBrush\".into(), json!({\"brush\": {\"mode\": \"Darken\"}})));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shift_right_mode_picker_cancels_and_other_gestures_keep_their_routes",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_right_mode_picker_cancels_and_other_gestures_keep_their_routes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness(None);\n let journal = h.state().session.journal.len();\n mode_right_click(&mut h, Modifiers::SHIFT);\n h.key_press(egui::Key::Escape);\n h.run_steps(2);\n assert!(h.state().ui.brush_mode_menu.is_none());\n mode_right_click(&mut h, Modifiers::SHIFT);\n let outside = h.state().last_canvas_rect.min + vec2(2.0, 2.0);\n h.event(egui::Event::PointerMoved(outside));\n press(&mut h, outside, PointerButton::Secondary, true);\n press(&mut h, outside, PointerButton::Secondary, false);\n assert!(h.state().ui.brush_mode_menu.is_none());",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_mode_menu.is_none());\n mode_right_click(&mut h, Modifiers::SHIFT);\n let outside = h.state().last_canvas_rect.min + vec2(2.0, 2.0);\n h.event(egui::Event::PointerMoved(outside));\n assert!(h.state().ui.brush_mode_menu.is_none());\n mode_right_click(&mut h, Modifiers::SHIFT);\n h.state_mut().ui.tool = Tool::Pencil;\n h.run_steps(2);\n assert!(h.state().ui.brush_mode_menu.is_none());\n mode_right_click(&mut h, Modifiers::SHIFT);\n assert!(h.state().ui.brush_mode_menu.is_none() && h.state().ui.brush_picker.is_some());\n h.state_mut().ui.brush_picker = None;\n h.state_mut().ui.tool = Tool::Brush;\n mode_right_click(&mut h, Modifiers::NONE);\n assert!(h.state().ui.brush_picker.is_some() && h.state().ui.brush_mode_menu.is_none());\n assert_eq!(h.state().session.journal.len(), journal, \"opening/cancelling never changes brush or pixels\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "escape_dismissal_consumes_a_held_secondary_release",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked escape_dismissal_consumes_a_held_secondary_release -- --nocapture",
|
|
"fixture_and_action_excerpt": " for release_shift in [false, true] {\n let mut h = harness(Some(\"erase\"));\n let journal = h.state().session.journal.len();\n let history = h.state().session.active().unwrap().history.past_len();\n let p = h.state().last_canvas_rect.center();\n h.event(egui::Event::ModifiersChanged(Modifiers::SHIFT));\n h.event(egui::Event::PointerMoved(p));\n h.event(egui::Event::PointerButton { pos: p, button: PointerButton::Secondary, pressed: true, modifiers: Modifiers::SHIFT });\n h.run_steps(1);\n // A quick second press can arrive in the frame that opens the menu for the first\n // click's release, leaving the secondary button held while the picker is visible.\n h.event(egui::Event::PointerButton { pos: p, button: PointerButton::Secondary, pressed: false, modifiers: Modifiers::SHIFT });",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_mode_menu.is_some());\n assert!(h.ctx.input(|i| i.pointer.secondary_down()));\n h.key_press(egui::Key::Escape);\n h.run_steps(1);\n assert!(h.state().ui.brush_mode_menu.is_none());\n let mods = if release_shift { Modifiers::NONE } else { Modifiers::SHIFT };\n h.event(egui::Event::ModifiersChanged(mods));\n h.run_steps(1);\n assert!(h.state().ui.brush_mode_menu.is_none(), \"Escape must consume the pending release\");\n assert!(h.state().ui.brush_picker.is_none() && h.state().drag.is_none() && !h.state().secondary_erase);\n assert_eq!(h.state().session.journal.len(), journal);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n mode_right_click(&mut h, Modifiers::SHIFT);\n assert!(h.state().ui.brush_mode_menu.is_some(), \"the next gesture must still work\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shift_released_before_the_right_button_still_opens_the_mode_picker",
|
|
"path": "crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_released_before_the_right_button_still_opens_the_mode_picker -- --nocapture",
|
|
"fixture_and_action_excerpt": " // egui reports `secondary_clicked` on release. With Erase on, a click that lost Shift a\n // frame early must open the menu, not erase a dab.\n let mut h = harness(Some(\"erase\"));\n let history = h.state().session.active().unwrap().history.past_len();\n let journal = h.state().session.journal.len();\n let p = h.state().last_canvas_rect.center();\n h.event(egui::Event::ModifiersChanged(Modifiers::SHIFT));\n h.event(egui::Event::PointerMoved(p));\n h.run_steps(1);\n h.event(egui::Event::PointerButton { pos: p, button: PointerButton::Secondary, pressed: true, modifiers: Modifiers::SHIFT });\n h.run_steps(1);\n // Shift goes up in a frame of its own while the right button is still down.",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_mode_menu.is_some(), \"the press decided the gesture\");\n assert!(h.state().drag.is_none() && !h.state().secondary_erase);\n assert_eq!(h.state().session.journal.len(), journal, \"no erase dab\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/canvas/paint_mouse/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shift_right_brush_does_not_open_presets_or_paint",
|
|
"path": "crates/ui-egui/src/control/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_right_brush_does_not_open_presets_or_paint -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 64, \"height\": 64})).unwrap();\n app.ui.tool = crate::state::Tool::Brush;\n let ctx = egui::Context::default();\n let before = app.session.journal.len();\n call(\n &mut app,\n &ctx,\n \"ui.pointer\",\n json!({\"button\": \"right\", \"shift\": true,\n \"events\": [{\"kind\": \"down\", \"x\": 20, \"y\": 20}, {\"kind\": \"up\", \"x\": 20, \"y\": 20}]}),\n );",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.brush_picker.is_none(), \"Shift+right opens Mode, not Brush Presets\");\n assert!(app.drag.is_none());\n assert_eq!(app.session.journal.len(), before, \"opening a menu does not paint or journal\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/control/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "brush_mode_control_routes_modifiers_and_reports_choices_without_history",
|
|
"path": "crates/ui-egui/src/control/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked brush_mode_control_routes_modifiers_and_reports_choices_without_history -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n for (tool, modifiers, expected) in [\n (\"brush\", json!({\"shift\": true}), \"mode\"),\n (\"brush\", json!({}), \"erase\"),\n (\"brush\", json!({\"shift\": true, \"alt\": true}), \"resize\"),\n (\"brush\", json!({\"shift\": true, \"ctrl\": true}), if cfg!(target_os = \"macos\") { \"erase\" } else { \"layer\" }),\n (\"brush\", json!({\"shift\": true, \"command\": true}), \"layer\"),\n (\"pencil\", json!({\"shift\": true}), \"preset\"),\n ] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 64, \"height\": 64, \"background\": \"white\"})).unwrap();\n app.run(\"prefs.set\", json!({\"path\": \"tools.rightClickWithPaintingTools\", \"value\": \"erase\"})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.brush_mode_menu.is_some(), expected == \"mode\", \"{tool}: {modifiers}\");\n match expected {\n \"mode\" => {\n assert!(app.drag.is_none() && !app.secondary_erase);\n assert_eq!(app.session.active().unwrap().history.past_len(), history);\n let inspect = inspect(&app, &ctx);\n assert_eq!(inspect[\"brushModeMenu\"][\"choices\"], json!(crate::brush_mode_menu::choices().iter().map(|(_, label)| *label).collect::<Vec<_>>()));\n let journal = app.session.journal.len();\n call(\n &mut app,\n assert!(app.ui.brush_mode_menu.is_none() && app.drag.is_none());\n assert_eq!(app.session.journal.len(), journal, \"control dismissal cannot paint\");\n }\n \"preset\" => assert!(app.ui.brush_picker.is_some()),\n \"layer\" => assert!(app.ui.layer_menu.is_some()),\n \"resize\" => assert!(app.brush_resize.is_some()),\n \"erase\" => assert!(app.drag.as_ref().is_some_and(|d| d.erase)),\n _ => panic!(\"unknown fixture route: {expected}\"),\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1dc98f80f60e993f3edf20af815391b6a7e7add7/crates/ui-egui/src/control/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5082",
|
|
"pr": 5082,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Red/green canvas with blue foreground from alt_click_tests.rs; engine 80\u00d740 transparent canvas with blue stroke and red foreground",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked alt_click_with_the_mixer_brush_loads_the_reservoir_not_the_foreground -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked mixer_load_fills_the_reservoir_from_the_canvas_and_keeps_the_foreground -- --nocapture"
|
|
],
|
|
"expected": "Alt-click loads Current Brush Load/reservoir, preserving foreground and document revision and painting nothing. Dry stroke uses sampled blue until foreground changes; green foreground then paints green. Transparent sampling loads nothing; invalid coordinates preserve all state.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Historical PR title is stale: this case follows reviewed reservoir behavior, not foreground replacement. Repeat Alt/Option-click natively as a separate NOT RUN subcase.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked alt_click_with_the_mixer_brush_loads_the_reservoir_not_the_foreground -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked mixer_load_fills_the_reservoir_from_the_canvas_and_keeps_the_foreground -- --nocapture"
|
|
],
|
|
"title": "Mixer Brush Alt-click loads reservoir while preserving foreground",
|
|
"historical_pr_title": "fix(mixer-brush): Alt-click samples the foreground colour like the Brush (#4873)"
|
|
},
|
|
{
|
|
"id": "PR-5165",
|
|
"pr": 5165,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked selecting_a_controls_section_keeps_its_enabled_flag_and_brush_history -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked controls_section_checkbox_toggles_without_selecting_its_settings -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked f5_edits_the_default_brush_with_every_section -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked section_boxes_show_a_pressed_state -- --nocapture"
|
|
],
|
|
"expected": "selecting a controls section keeps its enabled flag and brush history; controls section checkbox toggles without selecting its settings; f5 edits the default brush with every section; section boxes show a pressed state",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked selecting_a_controls_section_keeps_its_enabled_flag_and_brush_history -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked controls_section_checkbox_toggles_without_selecting_its_settings -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked f5_edits_the_default_brush_with_every_section -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked section_boxes_show_a_pressed_state -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "selecting_a_controls_section_keeps_its_enabled_flag_and_brush_history",
|
|
"path": "crates/ui-egui/src/brush_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked selecting_a_controls_section_keeps_its_enabled_flag_and_brush_history -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n for (section, name) in [(1, \"Shape Dynamics\"), (2, \"Scattering\"), (3, \"Texture\")] {\n let mut h = harness(0, 0);\n let before = h.state().session.tools.brush.clone();\n let journal = h.state().session.journal.len();\n\n h.get_by_label(name).click();\n h.run_steps(3);\n\n assert_eq!(h.state().ui.brush_section, section, \"{name} settings are visible\");\n assert_eq!(h.state().session.tools.brush, before, \"{name} remains disabled\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.brush_section, section, \"{name} settings are visible\");\n assert_eq!(h.state().session.tools.brush, before, \"{name} remains disabled\");\n assert_eq!(h.state().session.journal.len(), journal, \"selecting {name} is not a brush edit\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/27bc6e4b37b701480efa69559ab13eafc52bd94c/crates/ui-egui/src/brush_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "controls_section_checkbox_toggles_without_selecting_its_settings",
|
|
"path": "crates/ui-egui/src/brush_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked controls_section_checkbox_toggles_without_selecting_its_settings -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n let mut h = harness(0, 0);\n let row = h.get_by_label(\"Scattering\").rect();\n let checkbox = egui::pos2(row.left() + 12.0, row.center().y);\n let journal = h.state().session.journal.len();\n\n for enabled in [true, false] {\n h.hover_at(checkbox);\n h.run_steps(1);\n h.drag_at(checkbox);\n h.run_steps(1);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.tools.brush.scattering.enabled, enabled);\n assert_eq!(h.state().ui.brush_section, 0, \"the checkbox does not select Scattering\");\n assert_eq!(last_journal(h.state()).unwrap().1[\"brush\"], json!({\"scattering\": {\"enabled\": enabled}}));\n }\n assert_eq!(h.state().session.journal.len(), journal + 2);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/27bc6e4b37b701480efa69559ab13eafc52bd94c/crates/ui-egui/src/brush_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "f5_edits_the_default_brush_with_every_section",
|
|
"path": "crates/ui-egui/src/brush_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked f5_edits_the_default_brush_with_every_section -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n let mut h = app_harness();\n assert!(!h.state().ui.panels.brush_settings);\n let fresh = h.state().session.tools.brush.clone();\n assert!(!fresh.shape_dynamics.enabled && !fresh.transfer.enabled, \"the default round brush has no dynamics yet\");\n h.key_press(egui::Key::F5);\n h.run_steps(3);\n assert!(h.state().ui.panels.brush_settings && h.state().ui.brush_tab == 0, \"F5 shows Brush Settings\");\n // Every section is there for the built-in round brush, not only for sampled or imported ones.\n for (name, _) in SECTIONS {\n assert!(h.query_all_by_label(name).next().is_some(), \"{name} listed\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(!h.state().ui.panels.brush_settings);\n let fresh = h.state().session.tools.brush.clone();\n assert!(!fresh.shape_dynamics.enabled && !fresh.transfer.enabled, \"the default round brush has no dynamics yet\");\n h.key_press(egui::Key::F5);\n h.run_steps(3);\n assert!(h.state().ui.panels.brush_settings && h.state().ui.brush_tab == 0, \"F5 shows Brush Settings\");\n // Every section is there for the built-in round brush, not only for sampled or imported ones.\n for (name, _) in SECTIONS {\n assert!(h.query_all_by_label(name).next().is_some(), \"{name} listed\");\n }\n // Clicking a section's name shows its settings without changing its enable flag.\n let n = h.state().session.journal.len();\n assert_eq!(h.state().ui.brush_section, 1);\n assert_eq!(h.state().session.tools.brush.shape_dynamics.enabled, shape_enabled);\n assert_eq!(h.state().session.journal.len(), n);\n // A section's box toggles it without showing it.\n h.get_by_label(\"Enable Transfer\").click();\n h.run_steps(3);\n assert!(h.state().session.tools.brush.transfer.enabled);\n assert_eq!(h.state().ui.brush_section, 1);\n assert_eq!(h.state().session.journal.len(), n + 1);\n // The rest of the brush is untouched.\n let b = &h.state().session.tools.brush;\n assert_eq!((b.size, b.hardness, &b.tip), (fresh.size, fresh.hardness, &fresh.tip));\n // F5 again hides the panel.\n h.key_press(egui::Key::F5);\n h.run_steps(2);\n assert!(!h.state().ui.panels.brush_settings);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/27bc6e4b37b701480efa69559ab13eafc52bd94c/crates/ui-egui/src/brush_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "section_boxes_show_a_pressed_state",
|
|
"path": "crates/ui-egui/src/brush_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked section_boxes_show_a_pressed_state -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n let mut h = app_harness();\n h.key_press(egui::Key::F5);\n h.run_steps(3);\n let t = Tokens::get(&h.ctx);\n let boxr = h.get_by_label(\"Enable Shape Dynamics\").rect();\n let row = h.get_by_label(\"Shape Dynamics\").rect();\n assert!(!h.state().session.tools.brush.shape_dynamics.enabled);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(false, false, &t)));\n // Selecting the controls row leaves its checkbox untouched, including while held.\n let at = egui::pos2(row.center().x, row.center().y);\n h.drag_at(at);",
|
|
"expected_assertions": [
|
|
" assert!(!h.state().session.tools.brush.shape_dynamics.enabled);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(false, false, &t)));\n // Selecting the controls row leaves its checkbox untouched, including while held.\n let at = egui::pos2(row.center().x, row.center().y);\n h.drag_at(at);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(false, false, &t)), \"row press leaves checkbox untouched\");\n h.drop_at(at);\n h.run_steps(3);\n assert!(!h.state().session.tools.brush.shape_dynamics.enabled);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(false, false, &t)));\n // The checkbox itself still shows its pressed state and toggles the section.\n h.drag_at(boxr.center());\n h.run_steps(2);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(false, true, &t)), \"pressed, unchecked\");\n h.drop_at(boxr.center());\n h.run_steps(3);\n assert!(h.state().session.tools.brush.shape_dynamics.enabled);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(true, false, &t)));\n // Held on the checked box itself: less opaque, then the release turns it off.\n h.drag_at(boxr.center());\n h.run_steps(2);\n assert_eq!(box_fill(&h, boxr), Some(widgets::check_box_fill(true, true, &t)), \"pressed, checked\");\n h.drop_at(boxr.center());\n h.run_steps(3);\n assert!(!h.state().session.tools.brush.shape_dynamics.enabled);\n // A checkbox-only row (no settings of its own) is one checkbox across the row: a press\n // anywhere on it presses its box, and the release toggles it.\n let wet = h.get_by_label(\"Wet Edges\").rect();\n assert_eq!(box_fill(&h, wet_box), Some(widgets::check_box_fill(was, true, &t)), \"pressed checkbox-only row\");\n h.drop_at(wet.center());\n h.run_steps(3);\n assert_ne!(h.state().session.tools.brush.wet_edges, was);\n // The four looks are distinct.\n let looks = [(false, false), (false, true), (true, false), (true, true)].map(|(on, pressed)| widgets::check_box_fill(on, pressed, &t));\n for (i, a) in looks.iter().enumerate() {\n assert!(looks.iter().skip(i + 1).all(|b| b != a), \"{looks:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/27bc6e4b37b701480efa69559ab13eafc52bd94c/crates/ui-egui/src/brush_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5453",
|
|
"pr": 5453,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Synthetic distinct paints and imported/clipboard patterns in shape_paint_fidelity.rs, shape_patterns.rs and shape_pattern_clipboard.rs across their depth/model matrix",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked exact_paints_roundtrip_through_create_edit_and_undo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked solid_alpha_and_library_patterns_render_and_embed_in_the_same_history_step -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterned_shapes_embed_render_and_undo_in_one_command_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterned_fill_and_stroke_clipboards_keep_cow_tiles_after_source_closes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked unresolved_and_conflicting_pattern_clipboards_fail_atomically -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked pattern_shape_fill_and_stroke_render_at_every_depth_and_model -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked patterned_shape_fill_and_stroke_clip_and_effects_match_cpu -- --nocapture"
|
|
],
|
|
"expected": "Distinct solid/gradient/pattern fill and stroke survive create/edit/undo. Pattern embedding shares the history transaction; copied paints retain pixels after source closes; unresolved/conflicting clipboard patterns refuse atomically. GPU matches CPU at the existing tolerance.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Verified adapter required for GPU comparison; cache-budget checks are additional reliability coverage, not a replacement.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked exact_paints_roundtrip_through_create_edit_and_undo -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked solid_alpha_and_library_patterns_render_and_embed_in_the_same_history_step -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterned_shapes_embed_render_and_undo_in_one_command_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked patterned_fill_and_stroke_clipboards_keep_cow_tiles_after_source_closes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked unresolved_and_conflicting_pattern_clipboards_fail_atomically -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked pattern_shape_fill_and_stroke_render_at_every_depth_and_model -- --nocapture",
|
|
"cargo test -p photocraft-gpu --locked patterned_shape_fill_and_stroke_clip_and_effects_match_cpu -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-5939",
|
|
"pr": 5939,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked blur_scales_with_brush_size_and_diffuses_pixels_visibly -- --nocapture"
|
|
],
|
|
"expected": "blur scales with brush size and diffuses pixels visibly",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked blur_scales_with_brush_size_and_diffuses_pixels_visibly -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "blur_scales_with_brush_size_and_diffuses_pixels_visibly",
|
|
"path": "crates/engine/src/retouch_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked blur_scales_with_brush_size_and_diffuses_pixels_visibly -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8u64, 16] {\n let run = |size: u32| {\n let mut s = session(120, 40, depth, \"rgb\");\n paint_layer(&mut s, |x, _| if x < 60 { [0.0, 0.0, 0.0, 1.0] } else { [1.0, 1.0, 1.0, 1.0] });\n s.execute(\"paint.blur\", json!({\"points\": [[60, 20]], \"size\": size, \"hardness\": 100, \"strength\": 100})).unwrap();\n (0..120).map(|x| rgba(&s, x, 20)[0]).collect::<Vec<_>>()\n };\n let p20 = run(20);\n let p60 = run(60);\n // Size 20 (sigma = 3.0, radius 10, footprint [50, 70]) leaves x=45 and x=75 untouched.\n assert_eq!(p20[45], 0.0, \"size 20 footprint does not reach x=45\");\n assert_eq!(p20[75], 1.0, \"size 20 footprint does not reach x=75\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(p20[45], 0.0, \"size 20 footprint does not reach x=45\");\n assert_eq!(p20[75], 1.0, \"size 20 footprint does not reach x=75\");\n // Size 60 (sigma = 9.0, radius 30, footprint [30, 90]) diffuses light and dark across a wider band.\n assert!(p60[45] > 0.0, \"size 60 diffuses light past x=45: {}\", p60[45]);\n assert!(p60[75] < 1.0, \"size 60 diffuses dark past x=75: {}\", p60[75]);\n // Near the step edge (x=55), size 60 diffuses more than size 20 due to larger sigma.\n assert!(p60[55] > p20[55], \"larger sigma diffuses deeper near edge: p60={} p20={}\", p60[55], p20[55]);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/7348e060b4be7204fb69b59079c3b9d808e9aad3/crates/engine/src/retouch_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6139",
|
|
"pr": 6139,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked a_refresh_outside_command_execution_surfaces_the_denial_instead_of_rendering_unfiltered -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked behind_brush_and_pencil_preserve_foreground_and_round_trip_history -- --nocapture",
|
|
"cargo test -p photocraft-paint --locked behind_preserves_native_channels_and_respects_alpha_selection_and_locks -- --nocapture",
|
|
"cargo test -p photocraft-paint --locked live_union_of_passes_matches_merging_the_finished_passes_after_every_chunk -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked german_color_picker_fits_its_actions_and_translates_the_title -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked file_info_multiline_fields_keep_enter_and_cancel_discards_edits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked file_info_keeps_multiline_metadata_on_confirm_and_reopen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mask_sampling_sets_gray_swatches_without_changing_pixel_sampling -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked move_alt_copy_cursor_follows_the_latched_duplication_drag -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked assignable_pick_layer_shortcut_follows_transformed_canvas_without_editing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_wheel_over_the_brush_mode_dropdown_steps_the_painting_mode -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked space_repositions_a_pen_anchor_and_keeps_its_handles -- --nocapture"
|
|
],
|
|
"expected": "a refresh outside command execution surfaces the denial instead of rendering unfiltered; behind brush and pencil preserve foreground and round trip history; behind preserves native channels and respects alpha selection and locks; live union of passes matches merging the finished passes after every chunk; german color picker fits its actions and translates the title; file info multiline fields keep enter and cancel discards edits; file info keeps multiline metadata on confirm and reopen; mask sampling sets gray swatches without changing pixel sampling; move alt copy cursor follows the latched duplication drag; assignable pick layer shortcut follows transformed canvas without editing; the wheel over the brush mode dropdown steps the painting mode; space repositions a pen anchor and keeps its handles",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked a_refresh_outside_command_execution_surfaces_the_denial_instead_of_rendering_unfiltered -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked behind_brush_and_pencil_preserve_foreground_and_round_trip_history -- --nocapture",
|
|
"cargo test -p photocraft-paint --locked behind_preserves_native_channels_and_respects_alpha_selection_and_locks -- --nocapture",
|
|
"cargo test -p photocraft-paint --locked live_union_of_passes_matches_merging_the_finished_passes_after_every_chunk -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked german_color_picker_fits_its_actions_and_translates_the_title -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked file_info_multiline_fields_keep_enter_and_cancel_discards_edits -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked file_info_keeps_multiline_metadata_on_confirm_and_reopen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked mask_sampling_sets_gray_swatches_without_changing_pixel_sampling -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked move_alt_copy_cursor_follows_the_latched_duplication_drag -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked assignable_pick_layer_shortcut_follows_transformed_canvas_without_editing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_wheel_over_the_brush_mode_dropdown_steps_the_painting_mode -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked space_repositions_a_pen_anchor_and_keeps_its_handles -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "a_refresh_outside_command_execution_surfaces_the_denial_instead_of_rendering_unfiltered",
|
|
"path": "crates/automation/tests/smart_filter_authorization.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked a_refresh_outside_command_execution_surfaces_the_denial_instead_of_rendering_unfiltered -- --nocapture",
|
|
"fixture_and_action_excerpt": " // link-watch and transform paths re-render through Session::edit, not Session::execute or\n // jobs::run; the gate must reach them and the denial must not silently pass pixels through\n // into the process-wide stack cache.\n for lookup in [false, true] {\n let f = Fixture::new();\n let (doc, layer) = f.saved_filter(lookup);\n let mut h = f.headless();\n h.open(Path::new(\"stored.pcraft\")).unwrap();\n let before = h.session.active().unwrap().doc.clone();\n // Session::edit is the outside-execute mutation path (an edit closure the UI or a\n // linked-file change runs); the stored filter must be denied there too.\n assert_denied(h.session.edit(\"Re-render\", |d, _| match smart_cmds::refresh(d, layer) {",
|
|
"expected_assertions": [
|
|
" assert!(Arc::ptr_eq(&before, &h.session.active().unwrap().doc));\n // A trusted session (no gate) still renders the same document.\n let mut trusted = Session::new();\n trusted.add_document(doc, None);\n assert!(smart_cmds::refresh(&mut d, layer).is_ok());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/automation/tests/smart_filter_authorization.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "behind_brush_and_pencil_preserve_foreground_and_round_trip_history",
|
|
"path": "crates/engine/src/brush_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked behind_brush_and_pencil_preserve_foreground_and_round_trip_history -- --nocapture",
|
|
"fixture_and_action_excerpt": " for cmd in [\"paint.stroke\", \"paint.pencil\"] {\n let mut s = session(40, 20);\n s.execute(cmd, json!({\"points\": [[10, 10]], \"size\": 6, \"color\": \"#ff0000\", \"hardness\": 1.0})).unwrap();\n let before = surface(&s);\n s.execute(cmd, json!({\"points\": [[2, 10], [38, 10]], \"size\": 6, \"color\": \"#0000ff\", \"mode\": \"behind\", \"hardness\": 1.0})).unwrap();\n assert_eq!(rgba(&s, 10, 10), [1.0, 0.0, 0.0, 1.0], \"{cmd}: existing opaque paint\");\n assert_eq!(rgba(&s, 25, 10), [0.0, 0.0, 1.0, 1.0], \"{cmd}: transparent pixels\");\n let painted = surface(&s);\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert!(same_pixels(&surface(&s), &before, Rect::new(0, 0, 40, 20)));\n s.execute(\"edit.redo\", json!({})).unwrap();\n assert!(same_pixels(&surface(&s), &painted, Rect::new(0, 0, 40, 20)));",
|
|
"expected_assertions": [
|
|
" assert_eq!(rgba(&s, 10, 10), [1.0, 0.0, 0.0, 1.0], \"{cmd}: existing opaque paint\");\n assert_eq!(rgba(&s, 25, 10), [0.0, 0.0, 1.0, 1.0], \"{cmd}: transparent pixels\");\n let painted = surface(&s);\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert!(same_pixels(&surface(&s), &before, Rect::new(0, 0, 40, 20)));\n s.execute(\"edit.redo\", json!({})).unwrap();\n assert!(same_pixels(&surface(&s), &painted, Rect::new(0, 0, 40, 20)));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/engine/src/brush_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "behind_preserves_native_channels_and_respects_alpha_selection_and_locks",
|
|
"path": "crates/paint/src/brush_tests.rs",
|
|
"package": "photocraft-paint",
|
|
"command": "cargo test -p photocraft-paint --locked behind_preserves_native_channels_and_respects_alpha_selection_and_locks -- --nocapture",
|
|
"fixture_and_action_excerpt": " for mode in [ColorMode::Rgb, ColorMode::Grayscale, ColorMode::Cmyk, ColorMode::Lab] {\n for sample in [SampleType::U8, SampleType::U16, SampleType::F32] {\n let fmt = PixelFormat::new(mode, sample, true);\n let b = BrushSettings { size: 12.0, behind: true, opacity: 0.5, color: [0.1, 0.3, 0.8, 1.0], ..brush() };\n let mut s = Surface::new(fmt);\n let native = photocraft_raster::from_rgba(&fmt, [0.8, 0.2, 0.1, 0.5]);\n s.fill_rect(Rect::new(0, 0, 12, 12), &native);\n let before = s.pixel(6, 6);\n let mut selection = Surface::new(PixelFormat::new(ColorMode::Grayscale, SampleType::F32, false));\n selection.fill_rect(Rect::new(0, 0, 8, 12), &[0.5]);\n render_stroke(&mut s, &b, &[StrokePoint::new(6.0, 6.0, 1.0)], Some(&selection), false, 1.0);\n let source = photocraft_raster::from_rgba(&fmt, b.color);",
|
|
"expected_assertions": [
|
|
" assert!((got[a] - alpha).abs() < 0.005, \"{fmt:?}: {got:?}\");\n for c in 0..a {\n let expected = (before[c] * before[a] + source[c] * under) / alpha;\n assert!((got[c] - expected).abs() < 0.005, \"{fmt:?} channel {c}: {got:?}, expected {expected}\");\n }\n assert_eq!(s.pixel(9, 6), before, \"outside selection\");\n let locked = s.clone();\n render_stroke(&mut s, &b, &[StrokePoint::new(6.0, 6.0, 1.0)], None, true, 1.0);\n assert_eq!(s.read_region(Rect::new(0, 0, 12, 12)), locked.read_region(Rect::new(0, 0, 12, 12)), \"locked transparency\");\n s.fill_rect(Rect::new(0, 0, 12, 12), &photocraft_raster::from_rgba(&fmt, [0.8, 0.2, 0.1, 1.0]));\n let opaque = s.pixel(6, 6);\n render_stroke(&mut s, &b, &[StrokePoint::new(6.0, 6.0, 1.0)], None, false, 1.0);\n assert_eq!(s.pixel(6, 6), opaque, \"opaque pixels\");\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/paint/src/brush_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "live_union_of_passes_matches_merging_the_finished_passes_after_every_chunk",
|
|
"path": "crates/paint/src/brush_tests.rs",
|
|
"package": "photocraft-paint",
|
|
"command": "cargo test -p photocraft-paint --locked live_union_of_passes_matches_merging_the_finished_passes_after_every_chunk -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Symmetric painting previews the stroke and its mirrors with `composite_union_live`, which\n // redraws only changed tiles; after every chunk the target must be exactly what finishing\n // every pass and merging them with `composite_union_many` gives (the commit takes these pixels).\n let base = BrushSettings { size: 14.0, hardness: 0.6, opacity: 0.6, ..brush() };\n let mut brushes = vec![base.clone()];\n brushes.push(BrushSettings { smoothing: Smoothing { amount: 0.7, ..Default::default() }, ..base.clone() });\n let mut b = base.clone();\n b.dual_brush.enabled = true;\n b.dual_brush.size = 6.0;\n b.dual_brush.scatter = 1.5;\n brushes.push(b);\n let mut b = base.clone();",
|
|
"expected_assertions": [
|
|
" assert!(\n target.read_region(area) == expected.read_region(area),\n \"{sample:?}, brush {bi}, four {four}, selection {}, points ..{end}\",\n selection.is_some()\n assert_eq!(live.bounds(), finished.iter().fold(Rect::EMPTY, |r, f| r.union(&f.bounds())));\n at = end;\n chunk = chunk % 3 + 1;\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/paint/src/brush_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "german_color_picker_fits_its_actions_and_translates_the_title",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked german_color_picker_fits_its_actions_and_translates_the_title -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let lang = crate::i18n::Lang::from_pref(\"de\");\n let text = |key| crate::i18n::with_language(lang, || crate::i18n::t(key).to_owned());\n let app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let mut h =\n Harness::builder().with_size(egui::vec2(760.0, 480.0)).build_ui_state(move |ui, app| crate::i18n::with_language(lang, || show(app, ui.ctx())), app);\n PhotocraftApp::setup_context(&h.ctx, Default::default());\n crate::color_picker_ui::open(h.state_mut(), \"foreground\");\n h.run_steps(4);\n let title = h.get_by_label(\"Farbw\u00e4hler (Vordergrundfarbe)\").rect();\n let swatch = h.get_by_label(&text(\"Click to restore the current colour\")).rect();\n let frame = rects(&h.ctx)[0];",
|
|
"expected_assertions": [
|
|
" assert!(r.left() > swatch.right(), \"{label} must stay beside the swatches: {r:?}, {swatch:?}\");\n assert!((r.right() - title.right()).abs() < 1.0, \"{label} aligns with the title edge\");\n }\n assert!(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(760.0, 480.0)).contains_rect(frame), \"{frame:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "file_info_multiline_fields_keep_enter_and_cancel_discards_edits",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked file_info_multiline_fields_keep_enter_and_cancel_discards_edits -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n crate::i18n::with_language(crate::i18n::Lang::EN, || {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 64, \"height\": 64})).unwrap();\n let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(900.0, 700.0)).build_ui_state(|ui, app| show(app, ui.ctx()), app);\n PhotocraftApp::setup_context(&h.ctx, crate::theme::ThemeKind::ALL[0]);\n let ctx = h.ctx.clone();\n crate::menus::invoke(h.state_mut(), &ctx, \"file.fileInfo\", json!({})).unwrap();\n h.run_steps(4);\n let labels = [\"Document Title\", \"Author\", \"Author title\", \"Description\", \"Keywords\", \"Copyright status\", \"Copyright Notice\", \"Copyright Info URL\"];\n for pair in labels.windows(2) {",
|
|
"expected_assertions": [
|
|
" assert!(h.get_by_label(pair[0]).rect().center().y < h.get_by_label(pair[1]).rect().center().y, \"field order: {pair:?}\");\n }\n for (label, key) in [(\"Description\", \"description\"), (\"Keywords\", \"keywords\"), (\"Copyright Notice\", \"copyright\")] {\n h.get_by_label(label).click();\n assert_eq!(dialog.fields[key], \"First\\nSecond\", \"{label}\");\n }\n h.get_by_label(\"Cancel\").click();\n h.run_steps(2);\n assert!(h.state().ui.dialogs.is_empty());\n assert_eq!(h.state_mut().run(\"file.fileInfo\", json!({})).unwrap()[\"description\"], \"\");\n });\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "file_info_keeps_multiline_metadata_on_confirm_and_reopen",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked file_info_keeps_multiline_metadata_on_confirm_and_reopen -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 64, \"height\": 64})).unwrap();\n let ctx = egui::Context::default();\n let id = crate::menus::invoke(&mut app, &ctx, \"file.fileInfo\", json!({})).unwrap()[\"dialog\"].as_u64().unwrap();\n for key in [\"description\", \"copyright\"] {\n app.ui.dialog_mut(id).unwrap().fields.insert(key.into(), json!(\"First line\\nSecond line\"));\n }\n confirm(&mut app, id).unwrap();\n let id = crate::menus::invoke(&mut app, &ctx, \"file.fileInfo\", json!({})).unwrap()[\"dialog\"].as_u64().unwrap();\n for key in [\"description\", \"copyright\"] {\n assert_eq!(app.ui.dialog_mut(id).unwrap().fields[key], \"First line\\nSecond line\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.dialog_mut(id).unwrap().fields[key], \"First line\\nSecond line\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "mask_sampling_sets_gray_swatches_without_changing_pixel_sampling",
|
|
"path": "crates/ui-egui/src/eyedropper_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked mask_sampling_sets_gray_swatches_without_changing_pixel_sampling -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 20, \"height\": 20, \"depth\": depth, \"background\": \"transparent\"})).unwrap();\n app.session\n .edit(\"red\", |doc, _| {\n let surface = doc.layers[0].surface_mut().unwrap();\n surface.fill_rect(photocraft_geom::Rect::new(0, 0, 20, 20), &photocraft_raster::from_rgba(&surface.format(), [1.0, 0.0, 0.0, 1.0]));\n doc.layers[0].mask = Some(photocraft_doc::LayerMask::reveal_all());\n Ok(())\n })\n .unwrap();\n app.ui.tool = Tool::Eyedropper;",
|
|
"expected_assertions": [
|
|
" assert_eq!(fg(&app), [gray, gray, gray, 1.0], \"depth {depth}\");\n click(&mut app, 5.0, 5.0, egui::Modifiers::ALT);\n assert_eq!(app.session.tools.background, [gray, gray, gray, 1.0]);\n app.ui.mask_target = false;\n click(&mut app, 5.0, 5.0, egui::Modifiers::NONE);\n assert_eq!(fg(&app), [1.0, 0.0, 0.0, 1.0]);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/eyedropper_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "move_alt_copy_cursor_follows_the_latched_duplication_drag",
|
|
"path": "crates/ui-egui/src/input_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked move_alt_copy_cursor_follows_the_latched_duplication_drag -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().run(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [150, 100, 100, 100], \"fill\": \"#ff0000\"})).unwrap();\n h.state_mut().ui.tool = crate::state::Tool::Move;\n h.state_mut().ui.tool_options.move_show_transform = false;\n let before = h.state().session.active().unwrap().doc.layers.len();\n let p = h.state().last_canvas_rect.center();\n h.hover_at(p);\n h.run_steps(2);\n assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Default);\n h.event(egui::Event::ModifiersChanged(Modifiers::ALT));\n h.run_steps(2);\n assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Copy);",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Default);\n h.event(egui::Event::ModifiersChanged(Modifiers::ALT));\n h.run_steps(2);\n assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Copy);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), before, \"hovering never duplicates\");\n h.event(egui::Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed: true, modifiers: Modifiers::ALT });\n h.run_steps(1);\n let end = p + vec2(25.0, 15.0);\n assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Copy, \"releasing Alt does not undo an active copy\");\n h.event(egui::Event::PointerButton { pos: end, button: egui::PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });\n h.run_steps(2);\n assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Default);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), before + 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/input_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "assignable_pick_layer_shortcut_follows_transformed_canvas_without_editing",
|
|
"path": "crates/ui-egui/src/input_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked assignable_pick_layer_shortcut_follows_transformed_canvas_without_editing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let base = h.state().session.active().unwrap().active_layer.unwrap();\n h.state_mut().run(\"layer.new.layer\", json!({\"name\": \"Paint\"})).unwrap();\n let paint = h.state().session.active().unwrap().active_layer.unwrap();\n h.state_mut().run(\"select.rect\", json!({\"x\": 100, \"y\": 100, \"width\": 40, \"height\": 40})).unwrap();\n h.state_mut().run(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n h.state_mut().run(\"select.deselect\", json!({})).unwrap();\n h.state_mut().run(\"layer.new.layer\", json!({\"name\": \"Empty\"})).unwrap();\n h.state_mut().run(\"prefs.set\", json!({\"path\": \"shortcuts.layer.selectUnderCursor\", \"value\": \"Cmd+Alt+K\"})).unwrap();\n h.state_mut().ui.tool = crate::state::Tool::Brush;\n for (zoom, rotation, flip) in [(1.0, 0.0, false), (2.0, 37.0, true), (0.5, -90.0, false)] {\n h.state_mut().ui.views[0].zoom = zoom;",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.active().unwrap().active_layer, Some(expected));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history, \"picking never adds a document edit\");\n assert!(!h.state().session.journal.iter().any(|(id, _)| id == \"paint.stroke\"));\n }\n }\n h.state_mut().run(\"layer.setProps\", json!({\"layer\": paint.0, \"visible\": false})).unwrap();\n assert_eq!(h.state().session.active().unwrap().active_layer, Some(base));\n // Outside the document and modal dialogs preserve the current selection.\n h.state_mut().run(\"layer.select\", json!({\"layer\": paint.0})).unwrap();\n h.hover_at(pos2(0.0, 0.0));\n assert_eq!(h.state().session.active().unwrap().active_layer, Some(paint));\n open_dialog(&mut h);\n h.hover_at(p);\n h.key_press_modifiers(Modifiers::COMMAND | Modifiers::ALT, Key::K);\n assert_eq!(h.state().session.active().unwrap().active_layer, Some(paint));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/input_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_wheel_over_the_brush_mode_dropdown_steps_the_painting_mode",
|
|
"path": "crates/ui-egui/src/options_bar_mode_wheel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_wheel_over_the_brush_mode_dropdown_steps_the_painting_mode -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness(Tool::Brush);\n let at = mode_dropdown(&h).center();\n assert_eq!(brush_mode(&h), BlendMode::Normal);\n wheel(&mut h, at, -1.0);\n assert_eq!(brush_mode(&h), BlendMode::Dissolve);\n wheel(&mut h, at, -1.0);\n assert!(h.state().session.tools.brush.behind, \"Behind follows Dissolve\");\n wheel(&mut h, at, -1.0);\n assert!(h.state().ui.tool_options.brush_clear, \"Clear follows Behind\");\n assert!(!h.state().session.tools.brush.behind);\n wheel(&mut h, at, -1.0);\n assert!(!h.state().ui.tool_options.brush_clear);",
|
|
"expected_assertions": [
|
|
" assert_eq!(brush_mode(&h), BlendMode::Normal);\n wheel(&mut h, at, -1.0);\n assert_eq!(brush_mode(&h), BlendMode::Dissolve);\n wheel(&mut h, at, -1.0);\n assert!(h.state().session.tools.brush.behind, \"Behind follows Dissolve\");\n wheel(&mut h, at, -1.0);\n assert!(h.state().ui.tool_options.brush_clear, \"Clear follows Behind\");\n assert!(!h.state().session.tools.brush.behind);\n wheel(&mut h, at, -1.0);\n assert!(!h.state().ui.tool_options.brush_clear);\n assert_eq!(brush_mode(&h), BlendMode::Darken);\n wheel(&mut h, at, 4.0);\n assert_eq!(brush_mode(&h), BlendMode::Normal, \"up steps back and stops at the first mode\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/options_bar_mode_wheel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "space_repositions_a_pen_anchor_and_keeps_its_handles",
|
|
"path": "crates/ui-egui/src/pen_draw_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked space_repositions_a_pen_anchor_and_keeps_its_handles -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().ui.extras.snap = false;\n click(&mut h, [20.0, 20.0]);\n let center = h.state().ui.views[0].center;\n let p = screen(&h, [80.0, 50.0]);\n h.event(egui::Event::PointerMoved(p));\n button(&mut h, p, true, Modifiers::NONE);\n move_to(&mut h, [80.0, 50.0], [100.0, 60.0]);\n h.event(egui::Event::Key { key: Key::Space, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });\n h.run_steps(1);\n move_to(&mut h, [100.0, 60.0], [120.0, 90.0]);\n let k = h.state().ui.pen.as_ref().unwrap().knots[1];",
|
|
"expected_assertions": [
|
|
" assert!(near(k[0], [100.0, 80.0]) && near(k[1], [80.0, 70.0]) && near(k[2], [120.0, 90.0]), \"anchor and handles moved together: {k:?}\");\n assert_eq!(h.state().ui.views[0].center, center, \"the canvas never pans\");\n h.event(egui::Event::Key { key: Key::Space, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::NONE });\n h.run_steps(1);\n move_to(&mut h, [120.0, 90.0], [130.0, 80.0]);\n assert!(near(k[0], [100.0, 80.0]) && near(k[1], [70.0, 80.0]) && near(k[2], [130.0, 80.0]), \"releasing Space resumes handle shaping: {k:?}\");\n h.key_press(Key::Enter);\n h.run_steps(2);\n assert!(h.state().session.active().unwrap().doc.work_path.is_some());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e2347f8ead85d929193044f139788b850e31c06f/crates/ui-egui/src/pen_draw_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-7848",
|
|
"pr": 7848,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked pressure_shape_and_smoothing_match_replay -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked native_modes_selection_and_lock_match_replay -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked changed_document_refuses_live_pixels -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked smudge_pickup_matches_full_neighborhood_when_pressure_expands -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked pressure_sized_live_dabs_commit_only_the_requested_mask_or_channel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pressure_sized_smudge_release_matches_replay_and_undo_redo -- --nocapture"
|
|
],
|
|
"expected": "pressure shape and smoothing match replay; native modes selection and lock match replay; changed document refuses live pixels; smudge pickup matches full neighborhood when pressure expands; pressure sized live dabs commit only the requested mask or channel; pressure sized smudge release matches replay and undo redo",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked pressure_shape_and_smoothing_match_replay -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked native_modes_selection_and_lock_match_replay -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked changed_document_refuses_live_pixels -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked smudge_pickup_matches_full_neighborhood_when_pressure_expands -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked pressure_sized_live_dabs_commit_only_the_requested_mask_or_channel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pressure_sized_smudge_release_matches_replay_and_undo_redo -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "pressure_shape_and_smoothing_match_replay",
|
|
"path": "crates/engine/tests/live_dab_matches_replay.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked pressure_shape_and_smoothing_match_replay -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut failures = Vec::new();\n for cmd in [\"paint.smudge\", \"paint.blur\", \"paint.sharpen\", \"paint.dodge\", \"paint.burn\", \"paint.sponge\"] {\n for case in [\"pressure\", \"locked\", \"ellipse\", \"smoothing\", \"scattering\"] {\n for depth in [8, 16, 32] {\n let mut s = setup(depth, \"rgb\");\n match case {\n \"locked\" => {\n s.edit(\"lock alpha\", |doc, active| {\n doc.layer_mut(active.unwrap()).unwrap().locks.transparency = true;\n Ok(())\n })\n .unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(result[\"fromLive\"], true);\n let got = pixels(&s);\n let count = got.iter().zip(&want).filter(|(a, b)| a != b).count();\n let max = got.iter().zip(&want).map(|(a, b)| (a - b).abs()).fold(0.0f32, f32::max);\n assert!(failures.is_empty(), \"{}\", failures.join(\"\\n\"));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/engine/tests/live_dab_matches_replay.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "native_modes_selection_and_lock_match_replay",
|
|
"path": "crates/engine/tests/live_dab_matches_replay.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked native_modes_selection_and_lock_match_replay -- --nocapture",
|
|
"fixture_and_action_excerpt": " for mode in [\"rgb\", \"gray\", \"cmyk\", \"lab\"] {\n for depth in [8, 16, 32] {\n let mut s = setup(depth, mode);\n s.edit(\"lock alpha\", |doc, active| {\n doc.layer_mut(active.unwrap()).unwrap().locks.transparency = true;\n Ok(())\n })\n .unwrap();\n s.execute(\"select.rect\", json!({\"x\":30,\"y\":20,\"width\":110,\"height\":60})).unwrap();\n let points = [[-10.0, 30.0], [80.0, 50.0], [160.0, 80.0], [60.0, 60.0]];\n for cmd in [\"paint.blur\", \"paint.sharpen\", \"paint.dodge\", \"paint.burn\", \"paint.sponge\", \"paint.smudge\"] {\n let params = json!({\"points\":points,\"size\":30,\"hardness\":40,\"strength\":70,\"opacity\":37});",
|
|
"expected_assertions": [
|
|
" assert_eq!(result[\"fromLive\"], true);\n assert_eq!(result[\"damage\"], expected_damage);\n assert_eq!(pixels(&s), want, \"{mode} {depth} {cmd}\");\n s.execute(\"edit.undo\", json!({})).unwrap();\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/engine/tests/live_dab_matches_replay.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "changed_document_refuses_live_pixels",
|
|
"path": "crates/engine/tests/live_dab_matches_replay.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked changed_document_refuses_live_pixels -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = setup(8, \"rgb\");\n let p = json!({\"points\":[[40,40],[80,60]],\"size\":30});\n let live = LiveDab::begin(&s, \"paint.blur\", &p).unwrap();\n s.execute(\"paint.stroke\", json!({\"points\":[[40,40],[80,60]],\"color\":\"#ffffff\",\"size\":20})).unwrap();\n let mut replay = Session::new();\n replay.add_document((*s.active().unwrap().doc).clone(), None);\n replay.tools.brush = s.tools.brush.clone();\n s.offer_live_dab(live).unwrap();\n assert!(s.execute(\"paint.blur\", p.clone()).unwrap().get(\"fromLive\").is_none());\n replay.execute(\"paint.blur\", p).unwrap();\n assert_eq!(pixels(&s), pixels(&replay));\n}",
|
|
"expected_assertions": [
|
|
" assert!(s.execute(\"paint.blur\", p.clone()).unwrap().get(\"fromLive\").is_none());\n replay.execute(\"paint.blur\", p).unwrap();\n assert_eq!(pixels(&s), pixels(&replay));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/engine/tests/live_dab_matches_replay.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "smudge_pickup_matches_full_neighborhood_when_pressure_expands",
|
|
"path": "crates/engine/tests/live_dab_matches_replay.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked smudge_pickup_matches_full_neighborhood_when_pressure_expands -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_paint::{\n Stroke,\n retouch::{Smudge, apply_dab_stroke},\n };\n\n let points = [[40.0, 40.0, 0.1], [65.0, 50.0, 0.4], [100.0, 60.0, 1.0], [140.0, 70.0, 0.7], [60.0, 40.0, 0.2]];\n for depth in [8, 16, 32] {\n let mut s = setup(depth, \"rgb\");\n let params = json!({\"points\":points,\"size\":40,\"hardness\":70,\"strength\":80,\"opacity\":55,\"spacing\":25});\n let (mut expected, lock) = {\n let st = s.active().unwrap();\n let id = st.active_layer.unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(pixels(&s) == want, \"command must read the whole pickup square at depth {depth}\");\n s.execute(\"edit.undo\", json!({})).unwrap();\n let live = LiveDab::begin(&s, \"paint.smudge\", ¶ms).unwrap();\n s.offer_live_dab(live).unwrap();\n assert_eq!(s.execute(\"paint.smudge\", params).unwrap()[\"fromLive\"], true);\n assert!(pixels(&s) == want, \"a single batch uses the same pickup square at depth {depth}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/engine/tests/live_dab_matches_replay.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pressure_sized_live_dabs_commit_only_the_requested_mask_or_channel",
|
|
"path": "crates/engine/tests/live_dab_matches_replay.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked pressure_sized_live_dabs_commit_only_the_requested_mask_or_channel -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_raster::Surface;\n\n let fill = |surface: &mut Surface| {\n let values: Vec<f32> = (0..120).flat_map(|y| (0..200).map(move |x| ((x * 7 + y * 3) % 31) as f32 / 31.0)).collect();\n surface.write_region(photocraft_geom::Rect::new(0, 0, 200, 120), &values);\n };\n for depth in [8, 16, 32] {\n let mut s = setup(depth, \"rgb\");\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"layer.layerMask.revealAll\", json!({})).unwrap();\n s.execute(\"channel.new\", json!({\"fill\":\"white\"})).unwrap();\n s.execute(\"select.editInQuickMaskMode\", json!({\"on\":true})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(s.execute(cmd, params).unwrap()[\"fromLive\"], true);\n assert_eq!(s.active().unwrap().doc, want, \"depth={depth} {cmd} target={target}\");\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert_eq!(s.active().unwrap().doc, before);\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/engine/tests/live_dab_matches_replay.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pressure_sized_smudge_release_matches_replay_and_undo_redo",
|
|
"path": "crates/ui-egui/src/stroke_timing_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pressure_sized_smudge_release_matches_replay_and_undo_redo -- --nocapture",
|
|
"fixture_and_action_excerpt": " use crate::stylus::PenSample;\n\n let setup = |run: &mut dyn FnMut(&str, Value)| {\n run(\"tools.setBrush\", json!({\"brush\": {\"size\":40,\"hardness\":0.7,\"pressureSize\":true,\"smoothing\":{\"amount\":0.4}}}));\n run(\"paint.stroke\", json!({\"points\":[[10,20],[190,80]],\"size\":30,\"color\":\"#2060c0\"}));\n };\n let mut h = harness();\n h.state_mut().ui.tool = Tool::Smudge;\n h.run_steps(1);\n setup(&mut |id, p| {\n h.state_mut().run(id, p).unwrap();\n });",
|
|
"expected_assertions": [
|
|
" assert!(h.state().live_stroke.is_some());\n button(&mut h, 60.0, 40.0, false);\n h.run_steps(2);\n assert!(h.state().retouch_from_live, \"release must actually reuse the live pixels\");\n let (_, params) = h.state().session.journal.iter().rev().find(|(id, _)| id == \"paint.smudge\").cloned().unwrap();\n let points = params[\"points\"].as_array().unwrap();\n assert!(points.iter().any(|p| p[2].as_f64().unwrap() < 0.2));\n assert!(points.iter().any(|p| p[2].as_f64().unwrap() > 0.9));\n\n let mut fresh = photocraft_engine::Session::new();\n fresh.execute(\"file.new\", json!({\"width\":200,\"height\":100,\"background\":\"white\"})).unwrap();\n assert_eq!(h.state().session.tools.brush, fresh.tools.brush, \"replay uses the Smudge tool's actual brush\");\n assert!(\n photocraft_compose::render(&before, before.bounds()).px == photocraft_compose::render(&fresh.active().unwrap().doc, before.bounds()).px,\n \"the replay fixture starts with identical pixels\"\n );\n assert!(fresh.execute(\"paint.smudge\", params).unwrap().get(\"fromLive\").is_none());\n let committed = h.state().session.active().unwrap().doc.clone();\n let expected = photocraft_compose::render(&fresh.active().unwrap().doc, committed.bounds());\n assert!(photocraft_compose::render(&committed, committed.bounds()).px == expected.px, \"live commit and replay must paint identical pixels\");\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(h.state().session.active().unwrap().doc, before);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(h.state().session.active().unwrap().doc, committed);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/389a1d5bd67072d5581c27989080222a7065b585/crates/ui-egui/src/stroke_timing_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9623",
|
|
"pr": 9623,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-paint --locked pencil_1px_freehand_line_never_breaks_where_it_turns -- --nocapture"
|
|
],
|
|
"expected": "pencil 1px freehand line never breaks where it turns",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-paint --locked pencil_1px_freehand_line_never_breaks_where_it_turns -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "pencil_1px_freehand_line_never_breaks_where_it_turns",
|
|
"path": "crates/paint/src/brush_tests.rs",
|
|
"package": "photocraft-paint",
|
|
"command": "cargo test -p photocraft-paint --locked pencil_1px_freehand_line_never_breaks_where_it_turns -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #8040: each segment of a freehand stroke samples its own line, so where the stroke turned\n // the last pixel of one segment and the first of the next could sit two pixels apart.\n let b = BrushSettings { aliased: true, hardness: 1.0, size: 1.0, ..brush() };\n let mut seed = 0x2545_f491_4f6c_dd1du64;\n let mut rnd = || {\n seed ^= seed << 13;\n seed ^= seed >> 7;\n seed ^= seed << 17;\n (seed >> 11) as f64 / (1u64 << 53) as f64\n };\n for _ in 0..300 {\n let mut pts = vec![StrokePoint::new(20.0 + rnd() * 8.0, 20.0 + rnd() * 8.0, 1.0)];",
|
|
"expected_assertions": [
|
|
" assert_eq!(reached.len(), painted.len(), \"the line breaks along {path:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/652075f4da7fe905ad651eebc3a6c276fe1d7a5d/crates/paint/src/brush_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3554",
|
|
"pr": 3554,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Run the checked-in AppRun CLI test; it builds stand-in binaries under a path with spaces.",
|
|
"action": "bash packaging/linux/apprun-cli-test.sh",
|
|
"expected": "Argument boundaries, MCP stdio round trip, exit status 37 and unchanged GUI entry behavior all pass the script assertions.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-4742",
|
|
"pr": 4742,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Frozen-SHA macOS bundle containing executable Contents/MacOS/photocraft-cli; synthetic droplet and image paths with spaces",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked droplets_are_written_and_run -- --nocapture"
|
|
],
|
|
"expected": "Explicit PHOTOCRAFT_CLI wins, then supported /Applications and ~/Applications bundles, then PATH. Arguments remain separate; the intended action runs without standalone CLI installation; ordinary signature verification succeeds.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Use an authorized test installation; do not replace user's app. Installed-bundle resolution is BLOCKED if required bundle is absent. Finder dropping onto a plain shell shim is not promised; app wrapper is separate.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked droplets_are_written_and_run -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-7743",
|
|
"pr": 7743,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Obtain an existing portable Windows ZIP built from the frozen integration; record its artifact identity.",
|
|
"action": "List root archive entries and extract into a new empty directory; launch the app from the extracted root.",
|
|
"expected": "Application files are directly at ZIP root without a redundant wrapping folder; extracted layout launches correctly.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-8985",
|
|
"pr": 8985,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked field_marker_stays_inside_the_field -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked color_field_cursor_stays_inside_the_field -- --nocapture"
|
|
],
|
|
"expected": "field marker stays inside the field; color field cursor stays inside the field",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked field_marker_stays_inside_the_field -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked color_field_cursor_stays_inside_the_field -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "field_marker_stays_inside_the_field",
|
|
"path": "crates/ui-egui/src/color_picker_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked field_marker_stays_inside_the_field -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Black in the default \"h\" mode: the marker is at the bottom-left corner.\n let h = picker(\"#000000\");\n let mut field = None;\n let mut circles = Vec::new();\n for clipped in &h.output().shapes {\n match &clipped.shape {\n egui::Shape::Mesh(m) if m.vertices.len() == 33 * 33 => {\n // The component slider is a 33 x 33 mesh too, drawn after the field.\n field.get_or_insert(m.calc_bounds());\n }\n egui::Shape::Circle(c) => circles.push((c.center, c.radius, clipped.clip_rect)),\n _ => {}",
|
|
"expected_assertions": [
|
|
" assert!(!circles.is_empty(), \"the marker is drawn\");\n for (center, radius, clip) in circles {\n let visible = Rect::from_center_size(center, vec2(2.0 * radius, 2.0 * radius)).intersect(clip);\n assert!(field.contains_rect(visible), \"marker {visible:?} leaves the field {field:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8e695caf885b529f01f482b3f0c90cdb34df1915/crates/ui-egui/src/color_picker_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "color_field_cursor_stays_inside_the_field",
|
|
"path": "crates/ui-egui/src/panels.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked color_field_cursor_stays_inside_the_field -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n // Black is s = 0, v = 0: the bottom-left corner.\n app.session.tools.foreground = [0.0, 0.0, 0.0, 1.0];\n let h = field_harness(app);\n let mut field = None;\n let mut circles = Vec::new();\n for clipped in &h.output().shapes {\n match &clipped.shape {\n // The saturation/brightness field is the 17 x 17 mesh; the hue strip is a 25 x 25 grid.\n egui::Shape::Mesh(m) if m.vertices.len() == 17 * 17 => field = Some(m.calc_bounds()),\n egui::Shape::Circle(c) => circles.push((c.center, c.radius, clipped.clip_rect)),\n _ => {}",
|
|
"expected_assertions": [
|
|
" assert!(rings.iter().any(|(_, radius, _)| *radius == 5.0), \"inner ring sits at the field's bottom-left corner\");\n assert!(rings.iter().any(|(_, radius, _)| *radius == 6.5), \"outer ring sits at the field's bottom-left corner\");\n for (center, radius, clip) in rings {\n let visible = egui::Rect::from_center_size(center, vec2(2.0 * radius, 2.0 * radius)).intersect(clip);\n assert!(field.contains_rect(visible), \"cursor ring {visible:?} leaves the field {field:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8e695caf885b529f01f482b3f0c90cdb34df1915/crates/ui-egui/src/panels.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9019",
|
|
"pr": 9019,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p xtask --locked unknown_bench_is_rejected_before_updating_the_baseline -- --nocapture"
|
|
],
|
|
"expected": "unknown bench is rejected before updating the baseline",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p xtask --locked unknown_bench_is_rejected_before_updating_the_baseline -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "unknown_bench_is_rejected_before_updating_the_baseline",
|
|
"path": "xtask/src/perf.rs",
|
|
"package": "xtask",
|
|
"command": "cargo test -p xtask --locked unknown_bench_is_rejected_before_updating_the_baseline -- --nocapture",
|
|
"fixture_and_action_excerpt": " let root = std::env::temp_dir().join(format!(\"photocraft-perf-unknown-bench-{}\", std::process::id()));\n std::fs::create_dir(&root).unwrap();\n std::fs::create_dir(root.join(\"perf\")).unwrap();\n std::fs::write(root.join(BUDGETS), \"[[bench]]\\nname = \\\"known\\\"\\npackage = \\\"unused\\\"\\nrequires = \\\"missing.rs\\\"\\n\").unwrap();\n let baseline = \"{\\\"schema\\\":1,\\\"sentinel\\\":true}\";\n std::fs::write(root.join(BASELINE), baseline).unwrap();\n let results = [\n run(&root, &[\"--bench\", \"unknown\", \"--reuse\", \"--update-baseline\"]),\n run(&root, &[\"--bench\", \"known\", \"--bench\", \"unknown\", \"--quick\", \"--reuse\", \"--update-baseline\"]),\n ];\n let after = std::fs::read_to_string(root.join(BASELINE)).unwrap();\n std::fs::remove_dir_all(root).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(result, Err(format!(\"perf: unknown bench `unknown` (see {BUDGETS})\")));\n }\n assert_eq!(after, baseline, \"an unknown bench must not update the baseline\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/364c4be1c19728aefa601ee924bc7a0cd6a09789/xtask/src/perf.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9110",
|
|
"pr": 9110,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Windows Intel host with functioning DX12; record OS, GPU and driver; frozen integration build",
|
|
"action": [
|
|
"cargo test -p photocraft-gpu --locked injected_fault_skips_the_gpu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layout_document_composites_on_the_gpu_like_the_cpu -- --nocapture"
|
|
],
|
|
"expected": "Every process honors WGPU_BACKEND=dx12. Example completes real composition; fault test renders before injecting loss and returns expected lost-device error; layout test executes CPU/GPU assertions.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Run cargo run --release -p photocraft-gpu --locked --example bench_stack_reuse -- --quick with WGPU_BACKEND=dx12. Record adapter/vendor/device/backend/driver and proof each comparison executed. Silent early returns are BLOCKED. Do not load the known-crashing Intel Vulkan backend.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-gpu --locked injected_fault_skips_the_gpu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layout_document_composites_on_the_gpu_like_the_cpu -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-9436",
|
|
"pr": 9436,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "startup_report.rs terminal/automation/display combinations and synthetic renderer/error/log text",
|
|
"action": [
|
|
"cargo test -p photocraft --locked a_desktop_launch_asks_the_user_and_a_script_does_not -- --nocapture",
|
|
"cargo test -p photocraft --locked the_text_names_the_error_renderer_version_and_log -- --nocapture",
|
|
"cargo test -p photocraft --locked a_fallback_that_was_not_the_preference_is_explained -- --nocapture",
|
|
"cargo test -p photocraft --locked path_names_the_attached_log_file -- --nocapture"
|
|
],
|
|
"expected": "Desktop launch with display and without terminal/control asks via dialog; terminal/headless/automation do not hang. Text contains error, attempted renderer, version, actual log path and applicable fallback reason; no invented log path.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Native dialog subcase uses only an existing safe failure reproduction in temporary settings. If unavailable, mark BLOCKED; never force a GPU driver crash.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft --locked a_desktop_launch_asks_the_user_and_a_script_does_not -- --nocapture",
|
|
"cargo test -p photocraft --locked the_text_names_the_error_renderer_version_and_log -- --nocapture",
|
|
"cargo test -p photocraft --locked a_fallback_that_was_not_the_preference_is_explained -- --nocapture",
|
|
"cargo test -p photocraft --locked path_names_the_attached_log_file -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-2300",
|
|
"pr": 2300,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_continues_with_button_up_and_keeps_vertices_fixed -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_places_the_next_vertex_in_the_panned_view_and_commits_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_keeps_pixel_aspect_and_shift_constrained_segments -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_pauses_for_dialogs_and_temporary_navigation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_never_moves_an_inactive_pane_or_survives_a_document_or_tool_switch -- --nocapture"
|
|
],
|
|
"expected": "polygon edge scroll continues with button up and keeps vertices fixed; polygon edge scroll places the next vertex in the panned view and commits once; polygon edge scroll keeps pixel aspect and shift constrained segments; polygon edge scroll pauses for dialogs and temporary navigation; polygon edge scroll never moves an inactive pane or survives a document or tool switch",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_continues_with_button_up_and_keeps_vertices_fixed -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_places_the_next_vertex_in_the_panned_view_and_commits_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_keeps_pixel_aspect_and_shift_constrained_segments -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_pauses_for_dialogs_and_temporary_navigation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_never_moves_an_inactive_pane_or_survives_a_document_or_tool_switch -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "polygon_edge_scroll_continues_with_button_up_and_keeps_vertices_fixed",
|
|
"path": "crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_continues_with_button_up_and_keeps_vertices_fixed -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (dx, dy, flip, rotation) in [\n (-1.0, 0.0, false, 0.0),\n (1.0, 0.0, false, 0.0),\n (0.0, -1.0, false, 0.0),\n (0.0, 1.0, false, 0.0),\n (-1.0, -1.0, false, 0.0),\n (1.0, -1.0, false, 0.0),\n (-1.0, 1.0, false, 0.0),\n (1.0, 1.0, false, 0.0),\n (1.0, 0.0, true, 0.0),\n (1.0, 0.0, false, 90.0),\n ] {",
|
|
"expected_assertions": [
|
|
" assert!(movement.dot(direction) > 0.1, \"edge ({dx},{dy}), flip={flip}, rotation={rotation}: {movement:?}\");\n assert!((movement.x * direction.y - movement.y * direction.x).abs() < 0.001, \"scroll follows the displayed axes\");\n assert!((next[0] - first[0]).hypot(next[1] - first[1]) > 0.1, \"stationary pointer keeps scrolling\");\n assert_eq!(h.state().ui.polygon, points, \"view motion never adds or moves vertices\");\n assert_eq!(steps(&h), before);\n assert!(selection(&h).is_none());\n assert!(!h.ctx.input(|i| i.pointer.any_down()));\n assert!(h.output().viewport_output[&egui::ViewportId::ROOT].repaint_delay.is_zero());\n h.event(egui::Event::PointerMoved(xf.rect.center()));\n h.run_steps(1);\n let stopped = h.state().ui.views[0].center;\n assert_eq!(h.state().ui.views[0].center, stopped, \"returning to the interior stops scrolling\");\n }\n\n let mut h = zoomed_polygon();\n assert!((center[0] - (400.0 - xf.rect.width() / (2.0 * xf.zoom))).abs() < 0.001, \"Overscroll off stops at the image's right edge\");\n h.run_steps(10);\n assert_eq!(h.state().ui.views[0].center, center, \"a long edge hold stays clamped\");\n assert_eq!(h.state().ui.polygon, points);\n assert_eq!(steps(&h), before);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ebf3777aec961d1815aa141d9987eaa645c2273f/crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "polygon_edge_scroll_places_the_next_vertex_in_the_panned_view_and_commits_once",
|
|
"path": "crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_places_the_next_vertex_in_the_panned_view_and_commits_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = zoomed_polygon();\n let before = steps(&h);\n let original = ViewXform::active(h.state()).unwrap();\n h.event(egui::Event::PointerMoved(original.rect.right_center() - vec2(4.0, 0.0)));\n h.run_steps(10);\n let panned = ViewXform::active(h.state()).unwrap();\n assert!(panned.center[0] > original.center[0], \"the zoomed image pans toward the right edge\");\n let at = panned.rect.center() + vec2(60.0, 0.0);\n let expected = panned.to_doc(at);\n h.event(egui::Event::PointerMoved(at));\n h.run_steps(20);\n button(&mut h, at, true, Modifiers::NONE);",
|
|
"expected_assertions": [
|
|
" assert!(panned.center[0] > original.center[0], \"the zoomed image pans toward the right edge\");\n let at = panned.rect.center() + vec2(60.0, 0.0);\n let expected = panned.to_doc(at);\n h.event(egui::Event::PointerMoved(at));\n assert_eq!(h.state().ui.polygon[1], expected, \"the next click uses the updated view transform\");\n h.run_steps(30);\n click(&mut h, expected[0] as f32, 190.0, Modifiers::NONE);\n h.key_press(egui::Key::Enter);\n assert!(h.state().ui.polygon.is_empty());\n assert!(selection(&h).is_some_and(|r| near(r, 170, 130, expected[0].ceil() as i32, 190)), \"{:?}\", selection(&h));\n assert_eq!(steps(&h), before + 1);\n h.event(egui::Event::PointerMoved(original.rect.right_center()));\n h.run_steps(4);\n assert_eq!(h.state().ui.views[0].center, panned.center, \"a finished polygon never scrolls\");\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert!(selection(&h).is_none(), \"one undo removes the completed selection\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ebf3777aec961d1815aa141d9987eaa645c2273f/crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "polygon_edge_scroll_keeps_pixel_aspect_and_shift_constrained_segments",
|
|
"path": "crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_keeps_pixel_aspect_and_shift_constrained_segments -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (flip, rotation) in [(false, 0.0), (true, 0.0), (false, 45.0), (true, 90.0)] {\n let mut h = zoomed_polygon();\n h.state_mut().ui.view.pixel_aspect = \"custom:2:Wide\".into();\n h.state_mut().ui.view.flip_horizontal = flip;\n h.state_mut().ui.views[0].rotation = rotation;\n h.run_steps(2);\n let original = ViewXform::active(h.state()).unwrap();\n let points = h.state().ui.polygon.clone();\n h.event(egui::Event::PointerMoved(original.rect.right_center() + vec2(4.0, 0.0)));\n h.run_steps(5);\n let panned = ViewXform::active(h.state()).unwrap();\n let movement = original.map_vec(vec2(panned.center[0] - original.center[0], panned.center[1] - original.center[1]));",
|
|
"expected_assertions": [
|
|
" assert!(movement.x > 1.0 && movement.y.abs() < 0.001, \"wide pixels, flip={flip}, rotation={rotation}: {movement:?}\");\n assert_eq!(h.state().ui.polygon, points, \"scrolling keeps existing document-space vertices\");\n\n let at = panned.rect.center() + vec2(60.0, 30.0);\n let expected = crate::canvas::constrained_polygon_point(points[0], panned.to_doc(at));\n assert_eq!(h.state().ui.polygon.len(), 2);\n assert_eq!(h.state().ui.polygon[1], expected, \"Shift still snaps in document space after panning\");\n assert_eq!(h.state().ui.polygon_mode, \"replace\", \"Shift after the first vertex does not change selection intent\");\n }\n\n let mut h = zoomed_polygon();\n assert!((center[0] - rightmost).abs() < 0.001, \"Overscroll off clamps using the displayed pixel aspect\");\n h.run_steps(10);\n assert_eq!(h.state().ui.views[0].center, center);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ebf3777aec961d1815aa141d9987eaa645c2273f/crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "polygon_edge_scroll_pauses_for_dialogs_and_temporary_navigation",
|
|
"path": "crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_pauses_for_dialogs_and_temporary_navigation -- --nocapture",
|
|
"fixture_and_action_excerpt": " for pause in [\"dialog\", \"space\", \"middle\"] {\n let mut h = zoomed_polygon();\n let rect = ViewXform::active(h.state()).unwrap().rect;\n let edge = rect.right_center() + vec2(4.0, 0.0);\n h.event(egui::Event::PointerMoved(edge));\n h.run_steps(1);\n match pause {\n \"dialog\" => {\n h.state_mut().ui.open_dialog(crate::state::DialogKind::Error, json!({\"message\":\"Pause\"}).as_object().unwrap().clone());\n }\n \"space\" => h.event(egui::Event::Key { key: egui::Key::Space, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE }),\n _ => h.event(egui::Event::PointerButton { pos: edge, button: PointerButton::Middle, pressed: true, modifiers: Modifiers::NONE }),",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.views[0].center, center, \"paused for {pause}\");\n assert_eq!(h.state().ui.polygon, points, \"{pause} retains the unfinished selection\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ebf3777aec961d1815aa141d9987eaa645c2273f/crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "polygon_edge_scroll_never_moves_an_inactive_pane_or_survives_a_document_or_tool_switch",
|
|
"path": "crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked polygon_edge_scroll_never_moves_an_inactive_pane_or_survives_a_document_or_tool_switch -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = zoomed_polygon();\n // Creating a document now cancels the old polygon immediately. Start a fresh one after\n // returning, so the inactive-pane and Enter checks exercise an outline that can commit.\n h.state_mut().run(\"file.new\", json!({\"width\":400,\"height\":300})).unwrap();\n h.state_mut().session.set_active(0);\n h.run_steps(2);\n for (x, y) in [(170.0, 130.0), (200.0, 130.0), (200.0, 170.0)] {\n click(&mut h, x, y, Modifiers::NONE);\n h.run_steps(30);\n }\n assert_eq!(h.state().ui.polygon.len(), 3);\n h.state_mut().ui.views[1].zoom = 4.0;",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.polygon.len(), 3);\n h.state_mut().ui.views[1].zoom = 4.0;\n h.state_mut().ui.views[1].center = [200.0, 150.0];\n h.state_mut().ui.views[1].fit_pending = false;\n assert_eq!(h.state().ui.views.iter().map(|v| v.center).collect::<Vec<_>>(), centers, \"hovering the other pane never pans either view\");\n assert_eq!(h.state().ui.polygon.len(), 3, \"the active polygon is still unfinished\");\n h.state_mut().session.set_active(1);\n h.key_press(egui::Key::Enter);\n h.run_steps(2);\n assert!(h.state().ui.polygon.is_empty(), \"the old document's unfinished polygon is discarded before Enter\");\n assert!(selection(&h).is_none());\n\n let mut h = zoomed_polygon();\n h.state_mut().ui.tool = Tool::Brush;\n assert!(h.state().ui.polygon.is_empty(), \"changing tools drops the polygon\");\n h.state_mut().ui.tool = Tool::PolygonLasso;\n click(&mut h, 170.0, 130.0, Modifiers::NONE);\n h.key_press(egui::Key::Escape);\n assert!(h.state().ui.polygon.is_empty());\n assert_eq!(h.state().ui.views[0].center, center, \"Escape stops edge scrolling\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ebf3777aec961d1815aa141d9987eaa645c2273f/crates/ui-egui/src/polygon_lasso_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5010",
|
|
"pr": 5010,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_is_laid_out_like_photoshops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_ok_cancel_and_enter -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_bin_deletes_the_selected_effect -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked every_effect_row_shows_a_checkbox -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked move_instance_reorders_within_its_kind -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked fx_menu_adds_or_shows_an_effect -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pending_style_is_the_dialogs_and_leaves_the_document_alone -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked body_keeps_invalid_params_and_renders_without_panicking -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked blending_page_renders_for_every_mode_and_odd_fields -- --nocapture"
|
|
],
|
|
"expected": "dragging the title bar moves the dialog; layer style keeps one size on every page; layer style fits a short screen; layer style is laid out like photoshops; layer style ok cancel and enter; layer style bin deletes the selected effect; every effect row shows a checkbox; move instance reorders within its kind; fx menu adds or shows an effect; pending style is the dialogs and leaves the document alone; body keeps invalid params and renders without panicking; blending page renders for every mode and odd fields",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_is_laid_out_like_photoshops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_ok_cancel_and_enter -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_bin_deletes_the_selected_effect -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked every_effect_row_shows_a_checkbox -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked move_instance_reorders_within_its_kind -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked fx_menu_adds_or_shows_an_effect -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pending_style_is_the_dialogs_and_leaves_the_document_alone -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked body_keeps_invalid_params_and_renders_without_panicking -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked blending_page_renders_for_every_mode_and_odd_fields -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "dragging_the_title_bar_moves_the_dialog",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n\n let app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let mut harness = Harness::builder().with_size(egui::vec2(1400.0, 1100.0)).build_ui_state(|ui, app| show(app, ui.ctx()), app);\n PhotocraftApp::setup_context(&harness.ctx, crate::theme::ThemeKind::ALL[0]);\n harness.state_mut().ui.open_dialog(DialogKind::LayerStyle, serde_json::Map::new());\n harness.run_steps(3);\n let before = harness.get_by_label(\"Layer Style\").rect();\n\n // Grab the title text itself: it must move the dialog, not select the text.\n let from = before.center();\n harness.hover_at(from);",
|
|
"expected_assertions": [
|
|
" assert!((moved - egui::vec2(-120.0, 80.0)).length() < 1.0, \"dialog moved by {moved:?}\");\n assert_eq!(harness.state().ui.dialogs.len(), 1, \"dragging must not close the dialog\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_keeps_one_size_on_every_page",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = layer_style_on_bevel(egui::vec2(1400.0, 900.0));\n let size = frame(&h).size();\n let dialog = h.state().ui.dialogs[0].id;\n for page in [\"blendingOptions\", \"styles\"] {\n h.state_mut().ui.dialog_mut(dialog).expect(\"still open\").fields.insert(\"selected\".into(), json!(page));\n h.run_steps(3);\n assert_eq!(frame(&h).size(), size, \"{page}\");\n }\n let grip = egui::Id::new((\"dialog\", dialog)).with(\"resize\").with(\"__resize_corner\");\n assert!(h.ctx.read_response(grip).is_none(), \"no resize grip\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(frame(&h).size(), size, \"{page}\");\n }\n let grip = egui::Id::new((\"dialog\", dialog)).with(\"resize\").with(\"__resize_corner\");\n assert!(h.ctx.read_response(grip).is_none(), \"no resize grip\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_fits_a_short_screen",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1366.0, 640.0));\n let h = layer_style_on_bevel(screen.size());\n assert!(screen.contains_rect(frame(&h)), \"{:?} fits on {screen:?}\", frame(&h));\n for button in [\"OK\", \"Cancel\"] {\n assert!(screen.contains_rect(h.get_by_label(button).rect()), \"{button} is on screen\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(screen.contains_rect(frame(&h)), \"{:?} fits on {screen:?}\", frame(&h));\n for button in [\"OK\", \"Cancel\"] {\n assert!(screen.contains_rect(h.get_by_label(button).rect()), \"{button} is on screen\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_is_laid_out_like_photoshops",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_is_laid_out_like_photoshops -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n let h = layer_style_on_bevel(egui::vec2(1400.0, 900.0));\n let at = |label: &str| h.get_by_label(label).rect();\n let frame = frame(&h);\n assert!(frame.width() > frame.height() * 1.3, \"wide and short: {:?}\", frame.size());\n // The list's rows are painted; its bar's fx button marks the column.\n let (list, page) = (at(\"Add a layer style\"), at(\"Depth\"));\n let [ok, cancel, new_style, preview] = [\"OK\", \"Cancel\", \"New Style\u2026\", \"Preview\"].map(at);\n assert!(list.right() < page.left(), \"the list is left of the page\");\n for (name, r) in [(\"OK\", ok), (\"Cancel\", cancel), (\"New Style\u2026\", new_style), (\"Preview\", preview)] {\n assert!(r.left() > page.right(), \"{name} is right of the page\");",
|
|
"expected_assertions": [
|
|
" assert!(frame.width() > frame.height() * 1.3, \"wide and short: {:?}\", frame.size());\n // The list's rows are painted; its bar's fx button marks the column.\n let (list, page) = (at(\"Add a layer style\"), at(\"Depth\"));\n let [ok, cancel, new_style, preview] = [\"OK\", \"Cancel\", \"New Style\u2026\", \"Preview\"].map(at);\n assert!(list.right() < page.left(), \"the list is left of the page\");\n for (name, r) in [(\"OK\", ok), (\"Cancel\", cancel), (\"New Style\u2026\", new_style), (\"Preview\", preview)] {\n assert!(r.left() > page.right(), \"{name} is right of the page\");\n }\n assert!(ok.top() < cancel.top() && cancel.top() < new_style.top() && new_style.top() < preview.top(), \"top to bottom\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_ok_cancel_and_enter",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_ok_cancel_and_enter -- --nocapture",
|
|
"fixture_and_action_excerpt": " let bevels = |h: &egui_kittest::Harness<'_, PhotocraftApp>| {\n let st = h.state().session.active().unwrap();\n let layer = st.doc.layer(st.active_layer.unwrap()).unwrap();\n layer.effects.items.iter().filter(|e| matches!(e, photocraft_doc::Effect::BevelEmboss { .. })).count()\n };\n for (how, applied) in [(\"OK\", 1), (\"Cancel\", 0), (\"Enter\", 1)] {\n use egui_kittest::kittest::Queryable;\n\n let mut h = layer_style_on_bevel(egui::vec2(1400.0, 900.0));\n if how == \"Enter\" {\n h.key_press(egui::Key::Enter);\n } else {",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.dialogs.is_empty(), \"{how} closes the dialog\");\n assert_eq!(bevels(&h), applied, \"{how}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_bin_deletes_the_selected_effect",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_bin_deletes_the_selected_effect -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n let mut h = layer_style_on_bevel(egui::vec2(1400.0, 900.0));\n let effects = |h: &egui_kittest::Harness<'_, PhotocraftApp>| h.state().ui.dialogs[0].fields[\"effects\"].as_array().map_or(0, Vec::len);\n assert_eq!(effects(&h), 1);\n h.get_by_label(\"Delete effect\").click();\n h.run_steps(3);\n assert_eq!(effects(&h), 0, \"Bevel & Emboss is gone from the list\");\n assert_eq!(h.state().ui.dialogs.len(), 1, \"the dialog stays open\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(effects(&h), 1);\n h.get_by_label(\"Delete effect\").click();\n h.run_steps(3);\n assert_eq!(effects(&h), 0, \"Bevel & Emboss is gone from the list\");\n assert_eq!(h.state().ui.dialogs.len(), 1, \"the dialog stays open\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "every_effect_row_shows_a_checkbox",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked every_effect_row_shows_a_checkbox -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 32, \"height\": 32})).unwrap();\n let l = Layer::raster(\"x\", photocraft_doc::PixelFormat::RGBA8);\n let fields = initial_fields(&l, Some(BLENDING), 120.0);\n let mut h = egui_kittest::Harness::builder().with_size(vec2(900.0, 700.0)).build_ui_state(\n move |ui, app: &mut PhotocraftApp| {\n if !ui.ctx().fonts(|f| f.families().contains(&egui::FontFamily::Name(\"medium\".into()))) {\n return;\n }\n let mut f = fields.clone();\n body(app, ui, &mut f, false);\n },",
|
|
"expected_assertions": [
|
|
" assert_eq!(rows, KINDS.len(), \"one empty checkbox per effect row\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "move_instance_reorders_within_its_kind",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked move_instance_reorders_within_its_kind -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n s.execute(\"layer.layerStyle.stroke\", json!({\"size\": 3})).unwrap();\n let st = s.active().unwrap();\n let mut f = initial_fields(st.doc.layer(st.active_layer.unwrap()).unwrap(), None, 120.0);\n add_instance(&mut f, \"dropShadow\");\n add_instance(&mut f, \"stroke\");\n assert_eq!(ids(&f), [\"fx1\", \"fx3\", \"fx2\"], \"a new stroke goes after the last stroke\");\n move_instance(&mut f, \"fx3\", -1);\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"]);\n move_instance(&mut f, \"fx3\", -1);\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"], \"already the first stroke\");\n move_instance(&mut f, \"fx2\", 1);",
|
|
"expected_assertions": [
|
|
" assert_eq!(ids(&f), [\"fx1\", \"fx3\", \"fx2\"], \"a new stroke goes after the last stroke\");\n move_instance(&mut f, \"fx3\", -1);\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"]);\n move_instance(&mut f, \"fx3\", -1);\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"], \"already the first stroke\");\n move_instance(&mut f, \"fx2\", 1);\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"], \"the only drop shadow stays put\");\n for (id, by) in [(\"fx1\", isize::MAX), (\"fx1\", isize::MIN), (\"nope\", 1)] {\n move_instance(&mut f, id, by);\n }\n assert_eq!(ids(&f), [\"fx3\", \"fx1\", \"fx2\"], \"out-of-range moves and unknown ids change nothing\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "fx_menu_adds_or_shows_an_effect",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked fx_menu_adds_or_shows_an_effect -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n s.execute(\"layer.layerStyle.stroke\", json!({\"size\": 3})).unwrap();\n s.execute(\"layer.layerStyle.satin\", json!({\"enabled\": false})).unwrap();\n let st = s.active().unwrap();\n let mut f = initial_fields(st.doc.layer(st.active_layer.unwrap()).unwrap(), None, 120.0);\n let before = effects_of(&f).len();\n pick_from_fx_menu(&mut f, \"stroke\");\n assert_eq!(effects_of(&f).len(), before + 1, \"a second stroke\");\n let satin = effects_of(&f).iter().find(|e| e[\"kind\"] == \"satin\").and_then(|e| e[\"id\"].as_str()).unwrap().to_string();\n pick_from_fx_menu(&mut f, \"satin\");\n assert_eq!(effects_of(&f).len(), before + 1, \"no second satin\");\n assert_eq!(f[\"selected\"], json!(satin));",
|
|
"expected_assertions": [
|
|
" assert_eq!(effects_of(&f).len(), before + 1, \"a second stroke\");\n let satin = effects_of(&f).iter().find(|e| e[\"kind\"] == \"satin\").and_then(|e| e[\"id\"].as_str()).unwrap().to_string();\n pick_from_fx_menu(&mut f, \"satin\");\n assert_eq!(effects_of(&f).len(), before + 1, \"no second satin\");\n assert_eq!(f[\"selected\"], json!(satin));\n assert_eq!(entry(&f, &satin).unwrap()[\"on\"], json!(true));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pending_style_is_the_dialogs_and_leaves_the_document_alone",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pending_style_is_the_dialogs_and_leaves_the_document_alone -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), Default::default());\n app.run(\"file.new\", json!({\"width\": 16, \"height\": 16})).unwrap();\n app.run(\"layer.new.layer\", json!({})).unwrap();\n let id = app.session.active().unwrap().active_layer.unwrap();\n let mut f = initial_fields(app.session.active().unwrap().doc.layer(id).unwrap(), Some(\"stroke\"), 120.0);\n set_param(&mut f, \"fx1\", \"size\", json!(9));\n let style = pending_style(&app, &f).expect(\"the pending style builds\");\n let sizes: Vec<f32> = style\n .effects\n .iter()\n .filter_map(|e| match e {\n Effect::Stroke(s) => Some(s.size),",
|
|
"expected_assertions": [
|
|
" assert_eq!(sizes, [9.0]);\n assert!(app.session.active().unwrap().doc.layer(id).unwrap().effects.items.is_empty(), \"the document is untouched\");\n let rgba = photocraft_engine::presets::styles::thumbnail(&app.session, &style, 32);\n assert_eq!(rgba.len(), 32 * 32 * 4);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "body_keeps_invalid_params_and_renders_without_panicking",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked body_keeps_invalid_params_and_renders_without_panicking -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n PhotocraftApp::setup_context(&ctx, crate::theme::ThemeKind::ALL[0]);\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), Default::default());\n for bad in [json!(7), json!(null), json!(\"x\")] {\n let mut fields = Map::new();\n fields.insert(\"selected\".into(), json!(\"fx1\"));\n fields.insert(\"effects\".into(), json!([{\"id\": \"fx1\", \"kind\": \"dropShadow\", \"on\": true, \"params\": bad.clone()}]));\n\n let mut out = ctx.run_ui(Default::default(), |ui| {\n body(&mut app, ui, &mut fields, false);\n });\n out.textures_delta.clear();",
|
|
"expected_assertions": [
|
|
" assert_eq!(entry(&fields, \"fx1\").unwrap()[\"params\"], bad);\n }\n for bad in [json!(7), json!([1])] {\n let mut fields = Map::new();\n assert_eq!(fields.get(\"p:blendingOptions\"), Some(&bad));\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "blending_page_renders_for_every_mode_and_odd_fields",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked blending_page_renders_for_every_mode_and_odd_fields -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n PhotocraftApp::setup_context(&ctx, crate::theme::ThemeKind::ALL[0]);\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), Default::default());\n let mut layer = photocraft_doc::Layer::new(\"L\", photocraft_doc::LayerContent::Adjustment(photocraft_doc::Adjustment::Invert));\n layer.advanced.knockout = photocraft_doc::Knockout::Deep;\n for mode in\n [photocraft_color::ColorMode::Rgb, photocraft_color::ColorMode::Cmyk, photocraft_color::ColorMode::Lab, photocraft_color::ColorMode::Grayscale]\n {\n let mut f = initial_fields(&layer, Some(BLENDING), 120.0);\n set_blending_fields(&mut f, &layer, mode);\n let mut out = ctx.run_ui(Default::default(), |ui| {\n body(&mut app, ui, &mut f, false);",
|
|
"expected_assertions": [
|
|
" assert_eq!(f[\"p:blendingOptions\"][\"knockout\"], \"deep\", \"{mode:?}\");\n // Hostile dialog state (only reachable through `ui.dialog.set`) still renders.\n let bo = f.get_mut(\"p:blendingOptions\").unwrap();\n bo[\"blendIfChannel\"] = json!(99);"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/cc865221894e21f846d92b721cce7421ea338363/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5493",
|
|
"pr": 5493,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Synthetic multi-shape CSH, duplicate names, inner holes and malformed second shape; empty temporary library/preferences",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked csh_import_makes_an_original_shape_available_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_invalid_second_shape_does_not_partially_import_a_set -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_multiple_shapes_with_matching_names_remain_individually_available -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_repeat_import_names_are_unique_and_survive_preferences_reload -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_same_winding_inner_subpath_stays_a_hole_after_place_and_reload -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked csh_open_imports_presets_and_shows_shapes_without_opening_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked malformed_csh_open_preserves_the_library -- --nocapture"
|
|
],
|
|
"expected": "Valid sets populate Shapes without a document; duplicate names stay individually addressable after reload; placed holes remain holes. Invalid later shape does not partially change library/revision. Malformed UI open preserves the library.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Retain inline-data authorization test separately; capture native Shapes panel as additional visual evidence.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked csh_import_makes_an_original_shape_available_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_invalid_second_shape_does_not_partially_import_a_set -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_multiple_shapes_with_matching_names_remain_individually_available -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_repeat_import_names_are_unique_and_survive_preferences_reload -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked csh_same_winding_inner_subpath_stays_a_hole_after_place_and_reload -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked csh_open_imports_presets_and_shows_shapes_without_opening_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked malformed_csh_open_preserves_the_library -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-5515",
|
|
"pr": 5515,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked select_subject_samples_the_selected_layer_else_the_composite -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked select_subject_repeat_reuses_the_mask_until_pixels_change -- --nocapture"
|
|
],
|
|
"expected": "select subject samples the selected layer else the composite; select subject repeat reuses the mask until pixels change",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked select_subject_samples_the_selected_layer_else_the_composite -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked select_subject_repeat_reuses_the_mask_until_pixels_change -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "select_subject_samples_the_selected_layer_else_the_composite",
|
|
"path": "crates/engine/src/smartselect_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked select_subject_samples_the_selected_layer_else_the_composite -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut s, inside) = disc(8);\n // A layer above holding only a small square in the corner: the disc is not on it.\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"paint.pencil\", json!({\"points\": [[10, 10], [30, 10]], \"size\": 3, \"color\": \"#000000\"})).unwrap();\n s.execute(\"select.subject\", json!({})).unwrap();\n assert!(cov(&s, 100, 80) < 0.5, \"the disc on the layer below was selected\");\n s.execute(\"select.deselect\", json!({})).unwrap();\n // No layer selected: the whole image, so the disc is found.\n s.execute(\"select.deselectLayers\", json!({})).unwrap();\n s.execute(\"select.subject\", json!({})).unwrap();\n assert!(sel_iou(&s, 200, 160, &inside) > 0.9);\n }",
|
|
"expected_assertions": [
|
|
" assert!(cov(&s, 100, 80) < 0.5, \"the disc on the layer below was selected\");\n s.execute(\"select.deselect\", json!({})).unwrap();\n // No layer selected: the whole image, so the disc is found.\n s.execute(\"select.deselectLayers\", json!({})).unwrap();\n assert!(sel_iou(&s, 200, 160, &inside) > 0.9);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/375d4894a119b6cd5933d53e8fe7f506d2783392/crates/engine/src/smartselect_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "select_subject_repeat_reuses_the_mask_until_pixels_change",
|
|
"path": "crates/engine/src/smartselect_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked select_subject_repeat_reuses_the_mask_until_pixels_change -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut s, _) = disc(8);\n let sel = |s: &Session| {\n let mut v = Vec::new();\n s.active().unwrap().doc.selection.as_ref().unwrap().read_region_into(Rect::new(0, 0, 200, 160), &mut v);\n v\n };\n let cached = |s: &Session| s.subject_cache.region.clone().unwrap();\n s.execute(\"select.subject\", json!({})).unwrap();\n let (first, mask) = (sel(&s), cached(&s));\n s.execute(\"select.deselect\", json!({})).unwrap();\n s.execute(\"select.subject\", json!({})).unwrap();\n assert!(std::sync::Arc::ptr_eq(&mask, &cached(&s)), \"the repeat recomputed the mask\");",
|
|
"expected_assertions": [
|
|
" assert!(std::sync::Arc::ptr_eq(&mask, &cached(&s)), \"the repeat recomputed the mask\");\n assert_eq!(sel(&s), first);\n // Another sampled target (the composite rather than the layer) is a miss.\n s.execute(\"select.subject\", json!({\"sampleAllLayers\": true})).unwrap();\n assert!(!std::sync::Arc::ptr_eq(&mask, &cached(&s)));\n // A pixel edit drops the entry; the next run recomputes it.\n s.edit(\"paint\", |doc, _| {\n let bg = doc.layers[0].surface_mut().unwrap();\n assert!(s.subject_cache.region.is_none());\n s.execute(\"select.subject\", json!({})).unwrap();\n assert_eq!(sel(&s), first);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/375d4894a119b6cd5933d53e8fe7f506d2783392/crates/engine/src/smartselect_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5650",
|
|
"pr": 5650,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked move_guide_turns_a_guide -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_panel_hover_outlines_layer_on_canvas -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked guide_drags_create_move_and_delete -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_dragged_out_of_a_ruler -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_moved_with_the_move_tool -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_guide_dropped_on_either_ruler_is_deleted -- --nocapture"
|
|
],
|
|
"expected": "move guide turns a guide; layer panel hover outlines layer on canvas; guide drags create move and delete; alt turns a guide dragged out of a ruler; alt turns a guide moved with the move tool; a guide dropped on either ruler is deleted",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked move_guide_turns_a_guide -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_panel_hover_outlines_layer_on_canvas -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked guide_drags_create_move_and_delete -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_dragged_out_of_a_ruler -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_moved_with_the_move_tool -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_guide_dropped_on_either_ruler_is_deleted -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "move_guide_turns_a_guide",
|
|
"path": "crates/engine/src/edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked move_guide_turns_a_guide -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 200, \"height\": 100})).unwrap();\n s.execute(\"view.newGuide\", json!({\"orientation\": \"horizontal\", \"position\": 30, \"color\": \"magenta\"})).unwrap();\n s.execute(\"view.newGuide\", json!({\"orientation\": \"horizontal\", \"position\": 70})).unwrap();\n s.execute(\"view.moveGuide\", json!({\"orientation\": \"horizontal\", \"index\": 0, \"position\": \"50%\", \"toOrientation\": \"vertical\"})).unwrap();\n let g = &s.active().unwrap().doc.guides;\n assert_eq!((g.horizontal.clone(), g.vertical.clone()), (vec![70.0], vec![100.0]), \"50% of the width\");\n assert_eq!(g.color(true, 100.0), Some([255, 0, 255]), \"the colour moves with the guide\");\n assert_eq!(g.color(false, 30.0), None);\n // The same orientation is a plain move.\n s.execute(\"view.moveGuide\", json!({\"orientation\": \"vertical\", \"index\": 0, \"position\": 20, \"toOrientation\": \"vertical\"})).unwrap();\n assert_eq!(s.active().unwrap().doc.guides.vertical, vec![20.0]);",
|
|
"expected_assertions": [
|
|
" assert_eq!((g.horizontal.clone(), g.vertical.clone()), (vec![70.0], vec![100.0]), \"50% of the width\");\n assert_eq!(g.color(true, 100.0), Some([255, 0, 255]), \"the colour moves with the guide\");\n assert_eq!(g.color(false, 30.0), None);\n // The same orientation is a plain move.\n s.execute(\"view.moveGuide\", json!({\"orientation\": \"vertical\", \"index\": 0, \"position\": 20, \"toOrientation\": \"vertical\"})).unwrap();\n assert_eq!(s.active().unwrap().doc.guides.vertical, vec![20.0]);\n s.undo();\n s.undo();\n let g = &s.active().unwrap().doc.guides;\n assert_eq!((g.horizontal.clone(), g.vertical.clone()), (vec![30.0, 70.0], vec![]), \"one undo step per move\");\n // Bad params are refused and leave the guides alone.\n assert!(s.execute(\"view.moveGuide\", json!({\"orientation\": \"horizontal\", \"index\": 0, \"position\": 5, \"toOrientation\": \"diagonal\"})).is_err());\n assert!(s.execute(\"view.moveGuide\", json!({\"orientation\": \"horizontal\", \"index\": 0, \"position\": 5, \"toOrientation\": 1})).is_err());\n assert!(s.execute(\"view.newGuide\", json!({\"orientation\": \"horizontal\", \"position\": 5, \"toOrientation\": \"vertical\"})).is_err());\n assert!(s.execute(\"view.moveGuide\", json!({\"orientation\": \"horizontal\", \"index\": 9, \"position\": 5, \"toOrientation\": \"vertical\"})).is_err());\n let g = &s.active().unwrap().doc.guides;\n assert_eq!((g.horizontal.clone(), g.vertical.clone()), (vec![30.0, 70.0], vec![]));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/engine/src/edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_panel_hover_outlines_layer_on_canvas",
|
|
"path": "crates/ui-egui/src/move_hover.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_panel_hover_outlines_layer_on_canvas -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.execute(\"file.new\", json!({\"width\": 64, \"height\": 64})).unwrap();\n app.session.execute(\"layer.new.layer\", json!({})).unwrap();\n app.session\n .edit(\"paint\", |doc, a| {\n doc.layer_mut(a.unwrap()).unwrap().surface_mut().unwrap().fill_rect(Rect::new(8, 8, 24, 24), &[1.0, 0.0, 0.0, 1.0]);\n Ok(())\n })\n .unwrap();\n let target_layer = app.session.active().unwrap().active_layer.unwrap();\n let a = Rect::new(8, 8, 24, 24);\n",
|
|
"expected_assertions": [
|
|
" assert_eq!(active_outline(&mut app, None, false, false), None);\n app.hover_layer = Some(target_layer);\n assert_eq!(active_outline(&mut app, None, false, false), Some(a));\n\n // When a drag or transform is in progress, no outline:\n app.guide_drag = Some(crate::rulers::GuideDrag { vertical: false, index: None, pos: 10.0, ..Default::default() });\n assert_eq!(active_outline(&mut app, None, false, false), None);\n app.guide_drag = None;\n\n // When rollover preference is disabled, no outline:\n assert_eq!(active_outline(&mut app, None, false, false), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/ui-egui/src/move_hover.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "guide_drags_create_move_and_delete",
|
|
"path": "crates/ui-egui/src/rulers.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked guide_drags_create_move_and_delete -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.session.execute(\"file.new\", json!({\"width\": 200, \"height\": 100})).unwrap();\n app.sync_views();\n finish_drag(&mut app, GuideDrag { vertical: true, index: None, pos: 50.0, ..Default::default() });\n finish_drag(&mut app, GuideDrag { vertical: false, index: None, pos: 500.0, ..Default::default() }); // off canvas: ignored\n assert_eq!(app.session.active().unwrap().doc.guides.vertical, vec![50.0]);\n assert!(app.session.active().unwrap().doc.guides.horizontal.is_empty());\n assert_eq!(guide_at(&app, 51.0, 10.0), Some((true, 0)));\n finish_drag(&mut app, GuideDrag { vertical: true, index: Some(0), pos: 120.0, ..Default::default() });\n assert_eq!(app.session.active().unwrap().doc.guides.vertical, vec![120.0]);\n finish_drag(&mut app, GuideDrag { vertical: true, index: Some(0), pos: -30.0, ..Default::default() });\n assert!(app.session.active().unwrap().doc.guides.vertical.is_empty());",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.session.active().unwrap().doc.guides.vertical, vec![50.0]);\n assert!(app.session.active().unwrap().doc.guides.horizontal.is_empty());\n assert_eq!(guide_at(&app, 51.0, 10.0), Some((true, 0)));\n finish_drag(&mut app, GuideDrag { vertical: true, index: Some(0), pos: 120.0, ..Default::default() });\n assert_eq!(app.session.active().unwrap().doc.guides.vertical, vec![120.0]);\n finish_drag(&mut app, GuideDrag { vertical: true, index: Some(0), pos: -30.0, ..Default::default() });\n assert!(app.session.active().unwrap().doc.guides.vertical.is_empty());\n app.ui.extras.lock_guides = true;\n assert_eq!(guide_at(&app, 0.0, 0.0), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/ui-egui/src/rulers.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "alt_turns_a_guide_dragged_out_of_a_ruler",
|
|
"path": "crates/ui-egui/src/rulers.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_dragged_out_of_a_ruler -- --nocapture",
|
|
"fixture_and_action_excerpt": " let full = Rect::from_min_size(Pos2::ZERO, vec2(400.0, 300.0));\n let rect = Rect::from_min_max(full.min + vec2(RULER, RULER), full.max);\n let xf = ViewXform { rect, zoom: 1.0, center: [128.0, 64.0], flip: false, rotation: 0.0, aspect: 1.0 };\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 256, \"height\": 128})).unwrap();\n let mut h = egui_kittest::Harness::builder().with_size(vec2(400.0, 300.0)).build_ui_state(move |ui, app| draw_rulers(app, ui, full, &xf), app);\n // \u2325 held for the whole drag (`event_modifiers` would let go of it after each event).\n let alt = egui::Modifiers::ALT;\n h.event(egui::Event::ModifiersChanged(alt));\n let (from, to) = (pos2(RULER / 2.0, 100.0), xf.to_screen(37.0, 51.0));\n h.event(egui::Event::PointerMoved(from));\n h.event(egui::Event::PointerButton { pos: from, button: egui::PointerButton::Primary, pressed: true, modifiers: alt });",
|
|
"expected_assertions": [
|
|
" assert!(h.state().guide_drag.is_some_and(|d| !d.shows_vertical()), \"drawn horizontal while \u2325 is held\");\n h.event(egui::Event::PointerButton { pos: to, button: egui::PointerButton::Primary, pressed: false, modifiers: alt });\n h.run_steps(2);\n let g = &h.state().session.active().unwrap().doc.guides;\n assert_eq!((g.vertical.clone(), g.horizontal.clone()), (vec![], vec![51.0]));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/ui-egui/src/rulers.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "alt_turns_a_guide_moved_with_the_move_tool",
|
|
"path": "crates/ui-egui/src/rulers.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked alt_turns_a_guide_moved_with_the_move_tool -- --nocapture",
|
|
"fixture_and_action_excerpt": " use crate::canvas::{ToolEvent, tool_event};\n let new_app = || {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 80, \"height\": 60})).unwrap();\n app.sync_views();\n app.ui.tool = crate::state::Tool::Move;\n app.run(\"view.newGuide\", json!({\"orientation\": \"vertical\", \"position\": 50})).unwrap();\n app\n };\n let guides = |app: &PhotocraftApp| {\n let g = &app.session.active().unwrap().doc.guides;\n (g.vertical.clone(), g.horizontal.clone())",
|
|
"expected_assertions": [
|
|
" assert!(app.guide_drag.is_some_and(|d| !d.shows_vertical() && d.pos == 17.0));\n tool_event(&mut app, ToolEvent::Up { x: 63.0, y: 17.0 }, alt);\n assert_eq!(guides(&app), (vec![], vec![17.0]));\n assert!(app.session.undo());\n assert_eq!(guides(&app), (vec![50.0], vec![]), \"one undo step\");\n\n // \u2325 let go before the release: still vertical, moved along x.\n let mut app = new_app();\n assert_eq!(guides(&app), (vec![63.0], vec![]));\n\n // An \u2325-click turns the guide where it was clicked.\n let mut app = new_app();\n assert_eq!(guides(&app), (vec![], vec![44.0]));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/ui-egui/src/rulers.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_guide_dropped_on_either_ruler_is_deleted",
|
|
"path": "crates/ui-egui/src/rulers.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_guide_dropped_on_either_ruler_is_deleted -- --nocapture",
|
|
"fixture_and_action_excerpt": " let full = Rect::from_min_size(Pos2::ZERO, vec2(400.0, 300.0));\n let rect = Rect::from_min_max(full.min + vec2(RULER, RULER), full.max);\n let xf = ViewXform { rect, zoom: 1.0, center: [128.0, 64.0], flip: false, rotation: 0.0, aspect: 1.0 };\n for (pointer, over) in [(pos2(RULER / 2.0, 150.0), true), (pos2(200.0, RULER / 2.0), true), (pos2(200.0, 150.0), false)] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 256, \"height\": 128})).unwrap();\n app.run(\"view.newGuide\", json!({\"orientation\": \"horizontal\", \"position\": 30})).unwrap();\n app.guide_drag = Some(GuideDrag { vertical: false, index: Some(0), pos: 64.0, ..Default::default() });\n let mut h = egui_kittest::Harness::builder().with_size(vec2(400.0, 300.0)).build_ui_state(move |ui, app| draw_rulers(app, ui, full, &xf), app);\n h.event(egui::Event::PointerMoved(pointer));\n h.run_steps(1);\n let d = h.state().guide_drag.unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(d.over_ruler, over, \"{pointer:?}\");\n let app = h.state_mut();\n app.guide_drag = None;\n finish_drag(app, d);\n assert_eq!(left, if over { vec![] } else { vec![64.0] }, \"{pointer:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/4b1bd6fb6d264f885cb9caa3b8a6578ee527bd7b/crates/ui-egui/src/rulers.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6026",
|
|
"pr": 6026,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked fixed_size_px_is_exactly_the_size -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked fixed_size_selects_exactly_the_entered_size -- --nocapture"
|
|
],
|
|
"expected": "fixed size px is exactly the size; fixed size selects exactly the entered size",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked fixed_size_px_is_exactly_the_size -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked fixed_size_selects_exactly_the_entered_size -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "fixed_size_px_is_exactly_the_size",
|
|
"path": "crates/ui-egui/src/canvas.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked fixed_size_px_is_exactly_the_size -- --nocapture",
|
|
"fixture_and_action_excerpt": " use super::fixed_size_px;\n // Down-right from (10.4, 20.6): 10 \u00d7 10 from the closest pixel edges.\n assert_eq!(fixed_size_px([10.4, 20.6], [20.4, 30.6], 10.0, 10.0), [10.0, 21.0, 20.0, 31.0]);\n // Up-left: the far corner is the low one; still exactly the size.\n assert_eq!(fixed_size_px([10.4, 20.6], [-53.6, -11.4], 64.0, 32.0), [-54.0, -11.0, 10.0, 21.0]);\n // 1 \u00d7 1 is one pixel, and a fractional size rounds to whole pixels.\n assert_eq!(fixed_size_px([3.5, 3.5], [4.5, 4.5], 1.0, 1.0), [4.0, 4.0, 5.0, 5.0]);\n assert_eq!(fixed_size_px([0.0, 0.0], [2.6, 2.4], 2.6, 2.4), [0.0, 0.0, 3.0, 2.0]);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(fixed_size_px([10.4, 20.6], [20.4, 30.6], 10.0, 10.0), [10.0, 21.0, 20.0, 31.0]);\n // Up-left: the far corner is the low one; still exactly the size.\n assert_eq!(fixed_size_px([10.4, 20.6], [-53.6, -11.4], 64.0, 32.0), [-54.0, -11.0, 10.0, 21.0]);\n // 1 \u00d7 1 is one pixel, and a fractional size rounds to whole pixels.\n assert_eq!(fixed_size_px([3.5, 3.5], [4.5, 4.5], 1.0, 1.0), [4.0, 4.0, 5.0, 5.0]);\n assert_eq!(fixed_size_px([0.0, 0.0], [2.6, 2.4], 2.6, 2.4), [0.0, 0.0, 3.0, 2.0]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/248ba660576f4896f69cbb6639353e2f1d295271/crates/ui-egui/src/canvas.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "fixed_size_selects_exactly_the_entered_size",
|
|
"path": "crates/ui-egui/src/marquee_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked fixed_size_selects_exactly_the_entered_size -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [Tool::RectMarquee, Tool::EllipseMarquee] {\n for (w, ht) in [(10, 10), (1, 1), (64, 32)] {\n let mut h = harness(tool);\n let o = &mut h.state_mut().ui.tool_options;\n o.marquee_style = \"fixedSize\".into();\n (o.marquee_width, o.marquee_height) = (w as f32, ht as f32);\n press_at(&mut h, 50.4, 60.6, Modifiers::NONE);\n assert!(readout(&h, w, ht), \"{tool:?} {w} \u00d7 {ht}: the readout shows the entered size\");\n release_at(&mut h, 90.0, 90.0, Modifiers::NONE);\n assert_eq!(selection(&h), Rect::new(50, 61, 50 + w, 61 + ht), \"{tool:?} {w} \u00d7 {ht}: dragged\");\n\n // A click: the button goes down and up at one point.",
|
|
"expected_assertions": [
|
|
" assert!(readout(&h, w, ht), \"{tool:?} {w} \u00d7 {ht}: the readout shows the entered size\");\n release_at(&mut h, 90.0, 90.0, Modifiers::NONE);\n assert_eq!(selection(&h), Rect::new(50, 61, 50 + w, 61 + ht), \"{tool:?} {w} \u00d7 {ht}: dragged\");\n\n // A click: the button goes down and up at one point.\n h.state_mut().run(\"select.deselect\", json!({})).unwrap();\n assert_eq!(selection(&h), Rect::new(121, 100, 121 + w, 100 + ht), \"{tool:?} {w} \u00d7 {ht}: clicked\");\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/248ba660576f4896f69cbb6639353e2f1d295271/crates/ui-egui/src/marquee_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6236",
|
|
"pr": 6236,
|
|
"subsystem": "Painting",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_press_opens_the_hud_not_the_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked quick_selections_shift_alt_right_opens_only_the_selection_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_hud_clamped_under_the_still_pointer_picks_nothing_until_it_moves -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_over_the_hud_picks_the_foreground_live_and_release_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked escape_restores_the_starting_colour -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked plain_right_click_still_opens_the_picker_and_alt_drag_still_resizes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_drag_does_not_resize_the_brush -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_control_channel_opens_and_closes_the_hud -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hue_strip_mesh_indices_stay_within_its_rows -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pick_at_maps_the_rects_and_ignores_the_gaps -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_through_the_control_channel_respects_the_erase_preference -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_control_channel_up_closes_the_hud_without_repeating_its_modifiers -- --nocapture"
|
|
],
|
|
"expected": "shift alt right press opens the hud not the picker; quick selections shift alt right opens only the selection menu; a hud clamped under the still pointer picks nothing until it moves; dragging over the hud picks the foreground live and release keeps it; escape restores the starting colour; plain right click still opens the picker and alt drag still resizes; shift alt right drag does not resize the brush; the control channel opens and closes the hud; hue strip mesh indices stay within its rows; pick at maps the rects and ignores the gaps; shift alt right through the control channel respects the erase preference; a control channel up closes the hud without repeating its modifiers",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_press_opens_the_hud_not_the_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked quick_selections_shift_alt_right_opens_only_the_selection_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_hud_clamped_under_the_still_pointer_picks_nothing_until_it_moves -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_over_the_hud_picks_the_foreground_live_and_release_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked escape_restores_the_starting_colour -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked plain_right_click_still_opens_the_picker_and_alt_drag_still_resizes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_drag_does_not_resize_the_brush -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_control_channel_opens_and_closes_the_hud -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hue_strip_mesh_indices_stay_within_its_rows -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked pick_at_maps_the_rects_and_ignores_the_gaps -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shift_alt_right_through_the_control_channel_respects_the_erase_preference -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_control_channel_up_closes_the_hud_without_repeating_its_modifiers -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "shift_alt_right_press_opens_the_hud_not_the_picker",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_alt_right_press_opens_the_hud_not_the_picker -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, SHIFT_ALT);\n let hud = h.state().ui.color_hud.expect(\"the HUD opened\");\n assert!(hud.hold);\n assert_eq!(hud.start, [0.0, 0.0, 1.0, 1.0], \"seeded from the foreground\");\n assert_eq!(h.state().ui.brush_picker, None, \"the Brush Preset picker stays closed\");\n // The HUD shows under the pointer, on screen.\n let (strip, square) = rects(&h);\n assert!(strip.height() > 100.0 && square.width() > 100.0);",
|
|
"expected_assertions": [
|
|
" assert!(hud.hold);\n assert_eq!(hud.start, [0.0, 0.0, 1.0, 1.0], \"seeded from the foreground\");\n assert_eq!(h.state().ui.brush_picker, None, \"the Brush Preset picker stays closed\");\n // The HUD shows under the pointer, on screen.\n let (strip, square) = rects(&h);\n assert!(strip.height() > 100.0 && square.width() > 100.0);\n assert!(square.right() < h.ctx.content_rect().right());\n // Nothing painted.\n assert!(!h.state().session.journal.iter().any(|(id, _)| id == \"paint.stroke\"));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "quick_selections_shift_alt_right_opens_only_the_selection_menu",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked quick_selections_shift_alt_right_opens_only_the_selection_menu -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n h.state_mut().ui.tool = Tool::QuickSelection;\n h.run_steps(1);\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, SHIFT_ALT);\n assert_eq!(h.state().ui.color_hud, None, \"no HUD for Quick Selection\");\n assert_eq!(h.state().ui.brush_picker, None, \"and no Brush Preset picker\");\n button(&mut h, c, false, SHIFT_ALT);\n assert_eq!(h.state().ui.color_hud, None, \"the release does not open it either\");\n assert!(h.state().ui.canvas_tool_menu.is_some(), \"the selection menu opens, once\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.color_hud, None, \"no HUD for Quick Selection\");\n assert_eq!(h.state().ui.brush_picker, None, \"and no Brush Preset picker\");\n button(&mut h, c, false, SHIFT_ALT);\n assert_eq!(h.state().ui.color_hud, None, \"the release does not open it either\");\n assert!(h.state().ui.canvas_tool_menu.is_some(), \"the selection menu opens, once\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_hud_clamped_under_the_still_pointer_picks_nothing_until_it_moves",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_hud_clamped_under_the_still_pointer_picks_nothing_until_it_moves -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness_size(1200, 800);\n let near = egui::pos2(h.state().last_canvas_rect.max.x - 10.0, h.state().last_canvas_rect.max.y - 10.0);\n h.event(egui::Event::PointerMoved(near));\n h.run_steps(1);\n button(&mut h, near, true, SHIFT_ALT);\n assert!(h.state().ui.color_hud.is_some_and(|hud| hud.just_opened), \"the HUD opened under the pointer\");\n let (_strip, square) = rects(&h);\n assert!(square.contains(near), \"the clamped HUD sits under the pointer: {near:?} in {square:?}\");\n h.run_steps(4);\n assert_eq!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"the stationary opening pointer picks nothing\");\n // Moving inside the HUD now picks, as during any other gesture.\n let to = square.min + vec2(1.0, square.height() - 1.0);",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.color_hud.is_some_and(|hud| hud.just_opened), \"the HUD opened under the pointer\");\n let (_strip, square) = rects(&h);\n assert!(square.contains(near), \"the clamped HUD sits under the pointer: {near:?} in {square:?}\");\n h.run_steps(4);\n assert_eq!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"the stationary opening pointer picks nothing\");\n // Moving inside the HUD now picks, as during any other gesture.\n let to = square.min + vec2(1.0, square.height() - 1.0);\n h.event(egui::Event::PointerMoved(to));\n assert_ne!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"the move picks\");\n button(&mut h, to, false, SHIFT_ALT);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dragging_over_the_hud_picks_the_foreground_live_and_release_keeps_it",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_over_the_hud_picks_the_foreground_live_and_release_keeps_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, SHIFT_ALT);\n let j0 = h.state().session.journal.len();\n let (_strip, square) = rects(&h);\n // Top-right of the square: full saturation, full value at the current hue (blue).\n let pick = egui::pos2(square.max.x - 1.0, square.min.y + 1.0);\n h.event(egui::Event::PointerMoved(pick));\n h.run_steps(2);\n let fg = foreground(&h);",
|
|
"expected_assertions": [
|
|
" assert!(fg[2] > 0.9 && fg[0] < 0.1 && fg[1] < 0.1, \"still blue at the top of the square: {fg:?}\");\n // Bottom-left: value 0 \u2192 black.\n h.event(egui::Event::PointerMoved(square.min + vec2(1.0, square.height() - 1.0)));\n h.run_steps(2);\n assert!(fg[..3].iter().all(|v| *v < 0.02), \"black at the bottom: {fg:?}\");\n // The hue strip: its middle is cyan-ish (180\u00b0), at the square's current s/v.\n let (strip, _) = rects(&h);\n h.event(egui::Event::PointerMoved(egui::pos2(square.max.x - 1.0, square.min.y + 1.0)));\n assert!(fg[2] > 0.5 && fg[0] < 0.5, \"hue moved off red: {fg:?}\");\n // The gesture's edits share one coalesce key (one history step, like the brush HUD).\n let sets: Vec<&serde_json::Value> = h.state().session.journal[j0..].iter().filter(|(id, _)| id == \"tools.setColors\").map(|(_, p)| p).collect();\n assert!(!sets.is_empty(), \"the picks are journaled\");\n let keys: Vec<&str> = sets.iter().map(|p| p[\"coalesce\"].as_str().unwrap()).collect();\n assert!(keys.windows(2).all(|w| w[0] == w[1]), \"one gesture, one key: {keys:?}\");\n // Releasing the right button closes the HUD and keeps the colour.\n let kept = foreground(&h);\n button(&mut h, strip.center(), false, SHIFT_ALT);\n assert_eq!(h.state().ui.color_hud, None);\n assert_eq!(foreground(&h), kept);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "escape_restores_the_starting_colour",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked escape_restores_the_starting_colour -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, SHIFT_ALT);\n let (_strip, square) = rects(&h);\n h.event(egui::Event::PointerMoved(square.center()));\n h.run_steps(2);\n assert_ne!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"the pick is live\");\n h.key_press(egui::Key::Escape);\n h.run_steps(2);\n assert_eq!(h.state().ui.color_hud, None);",
|
|
"expected_assertions": [
|
|
" assert_ne!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"the pick is live\");\n h.key_press(egui::Key::Escape);\n h.run_steps(2);\n assert_eq!(h.state().ui.color_hud, None);\n assert_eq!(foreground(&h), [0.0, 0.0, 1.0, 1.0], \"Escape restores the colour\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "plain_right_click_still_opens_the_picker_and_alt_drag_still_resizes",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked plain_right_click_still_opens_the_picker_and_alt_drag_still_resizes -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, Modifiers::NONE);\n button(&mut h, c, false, Modifiers::NONE);\n assert!(h.state().ui.brush_picker.is_some() && h.state().ui.color_hud.is_none());\n // Alt+right-drag (no Shift) resizes the brush, as before.\n h.state_mut().ui.brush_picker = None;\n h.run_steps(1);\n h.event(egui::Event::ModifiersChanged(Modifiers::ALT));\n h.event(egui::Event::PointerMoved(c));",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.brush_picker.is_some() && h.state().ui.color_hud.is_none());\n // Alt+right-drag (no Shift) resizes the brush, as before.\n h.state_mut().ui.brush_picker = None;\n h.run_steps(1);\n assert!(h.state().brush_resize.is_some_and(|r| r.secondary), \"Alt+right still resizes\");\n assert!(h.state().ui.color_hud.is_none());\n button(&mut h, c + vec2(40.0, 0.0), false, Modifiers::ALT);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shift_alt_right_drag_does_not_resize_the_brush",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_alt_right_drag_does_not_resize_the_brush -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness();\n let size0 = h.state().session.tools.brush.size;\n let c = h.state().last_canvas_rect.center();\n h.event(egui::Event::PointerMoved(c));\n h.run_steps(1);\n button(&mut h, c, true, SHIFT_ALT);\n for k in 1..=6 {\n h.event(egui::Event::PointerMoved(c + vec2(20.0 * k as f32, 0.0)));\n h.run_steps(1);\n }\n assert!(h.state().brush_resize.is_none(), \"the HUD gesture is not a resize\");\n assert_eq!(h.state().session.tools.brush.size, size0);",
|
|
"expected_assertions": [
|
|
" assert!(h.state().brush_resize.is_none(), \"the HUD gesture is not a resize\");\n assert_eq!(h.state().session.tools.brush.size, size0);\n button(&mut h, c + vec2(120.0, 0.0), false, SHIFT_ALT);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_control_channel_opens_and_closes_the_hud",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_control_channel_opens_and_closes_the_hud -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), Default::default());\n app.run(\"file.new\", json!({\"width\": 100, \"height\": 100})).unwrap();\n app.run(\"tools.setColors\", json!({\"foreground\": \"#ff0000\"})).unwrap();\n app.ui.tool = Tool::Brush;\n let ctx = egui::Context::default();\n let (req, _rx) = crate::control::ControlRequest::new(\n \"ui.pointer\",\n json!({\"button\": \"right\", \"shift\": true, \"alt\": true, \"events\": [{\"kind\": \"down\", \"x\": 50, \"y\": 50}, {\"kind\": \"up\", \"x\": 50, \"y\": 50}]}),\n );\n let _ = crate::control::handle(&mut app, &ctx, &req);\n assert!(app.ui.color_hud.is_none(), \"the Up event closed it\");\n assert!(app.ui.brush_picker.is_none(), \"the picker stayed closed\");",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.color_hud.is_none(), \"the Up event closed it\");\n assert!(app.ui.brush_picker.is_none(), \"the picker stayed closed\");\n // A down without its up leaves the HUD open for the next frame's edits.\n let (req, _rx) = crate::control::ControlRequest::new(\n \"ui.pointer\",\n assert!(app.ui.color_hud.is_some_and(|h| !h.hold));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "hue_strip_mesh_indices_stay_within_its_rows",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked hue_strip_mesh_indices_stay_within_its_rows -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mesh = hue_strip_mesh(Rect::from_min_size(Pos2::ZERO, vec2(HUE_W, SQUARE)));\n let rows = 13; // n + 1 rows, two vertices each\n assert_eq!(mesh.vertices.len(), 2 * rows);\n assert_eq!(mesh.indices.len(), 3 * 2 * (rows - 1), \"two triangles per band\");\n for (j, tri) in mesh.indices.chunks(3).enumerate() {\n // Band k = j/2 joins rows k and k+1: vertices 2k..=2k+3, nothing further ahead.\n let k = j / 2;\n for &i in tri {\n assert!((2 * k) as u32 <= i && i <= (2 * k + 3) as u32, \"band {k} uses index {i}: {tri:?}\");\n assert!((i as usize) < mesh.vertices.len(), \"index {i} out of range\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(mesh.vertices.len(), 2 * rows);\n assert_eq!(mesh.indices.len(), 3 * 2 * (rows - 1), \"two triangles per band\");\n for (j, tri) in mesh.indices.chunks(3).enumerate() {\n // Band k = j/2 joins rows k and k+1: vertices 2k..=2k+3, nothing further ahead.\n let k = j / 2;\n assert!((2 * k) as u32 <= i && i <= (2 * k + 3) as u32, \"band {k} uses index {i}: {tri:?}\");\n assert!((i as usize) < mesh.vertices.len(), \"index {i} out of range\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "pick_at_maps_the_rects_and_ignores_the_gaps",
|
|
"path": "crates/ui-egui/src/color_hud.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked pick_at_maps_the_rects_and_ignores_the_gaps -- --nocapture",
|
|
"fixture_and_action_excerpt": " let strip = Rect::from_min_size(Pos2::new(0.0, 0.0), vec2(HUE_W, SQUARE));\n let square = Rect::from_min_max(vec2(HUE_W + GAP, 0.0).to_pos2(), Pos2::new(HUE_W + GAP + SQUARE, SQUARE));\n assert_eq!(pick_at([120.0, 0.5, 0.5], strip, square, square.center()), Some([120.0, 0.5, 0.5]));\n let p = pick_at([120.0, 0.5, 0.5], strip, square, square.left_top() + vec2(1.0, 1.0)).expect(\"in the square\");\n assert!(p[0] == 120.0 && p[1] < 0.02 && p[2] > 0.98, \"top-left is saturated and bright: {p:?}\");\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, strip.center()), Some([180.0, 0.5, 0.5]));\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, Pos2::new(HUE_W + GAP / 2.0, 10.0)), None, \"the gap picks nothing\");\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, Pos2::new(1e9, -1e9)), None);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(pick_at([120.0, 0.5, 0.5], strip, square, square.center()), Some([120.0, 0.5, 0.5]));\n let p = pick_at([120.0, 0.5, 0.5], strip, square, square.left_top() + vec2(1.0, 1.0)).expect(\"in the square\");\n assert!(p[0] == 120.0 && p[1] < 0.02 && p[2] > 0.98, \"top-left is saturated and bright: {p:?}\");\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, strip.center()), Some([180.0, 0.5, 0.5]));\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, Pos2::new(HUE_W + GAP / 2.0, 10.0)), None, \"the gap picks nothing\");\n assert_eq!(pick_at([0.0, 0.5, 0.5], strip, square, Pos2::new(1e9, -1e9)), None);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/color_hud.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shift_alt_right_through_the_control_channel_respects_the_erase_preference",
|
|
"path": "crates/ui-egui/src/paint_mouse.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shift_alt_right_through_the_control_channel_respects_the_erase_preference -- --nocapture",
|
|
"fixture_and_action_excerpt": " // As on the canvas, with the right-erase preference the erase stroke wins over the HUD\n // for Brush/Eraser; without it, Shift+Alt+right opens the HUD (#6098).\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 120, \"height\": 80})).unwrap();\n app.ui.tool = Tool::Brush;\n let shift_alt = egui::Modifiers { shift: true, alt: true, ..Default::default() };\n app.run(\"prefs.set\", json!({\"path\": \"tools.rightClickWithPaintingTools\", \"value\": \"erase\"})).unwrap();\n assert!(pointer_secondary(&mut app, &egui::Context::default(), true, shift_alt, [10.0, 10.0]), \"the events reach the tool\");\n assert!(app.ui.color_hud.is_none(), \"no HUD with the erase preference\");\n assert!(app.secondary_erase, \"the down arms the erasing stroke\");\n pointer_secondary(&mut app, &egui::Context::default(), false, shift_alt, [10.0, 10.0]);\n // With the default preference the same gesture opens the HUD instead.",
|
|
"expected_assertions": [
|
|
" assert!(pointer_secondary(&mut app, &egui::Context::default(), true, shift_alt, [10.0, 10.0]), \"the events reach the tool\");\n assert!(app.ui.color_hud.is_none(), \"no HUD with the erase preference\");\n assert!(app.secondary_erase, \"the down arms the erasing stroke\");\n pointer_secondary(&mut app, &egui::Context::default(), false, shift_alt, [10.0, 10.0]);\n // With the default preference the same gesture opens the HUD instead.\n app.run(\"prefs.set\", json!({\"path\": \"tools.rightClickWithPaintingTools\", \"value\": \"brushPicker\"})).unwrap();\n assert!(!pointer_secondary(&mut app, &egui::Context::default(), true, shift_alt, [10.0, 10.0]));\n assert!(app.ui.color_hud.is_some_and(|h| !h.hold), \"the control-channel HUD opened\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/paint_mouse.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_control_channel_up_closes_the_hud_without_repeating_its_modifiers",
|
|
"path": "crates/ui-egui/src/paint_mouse.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_control_channel_up_closes_the_hud_without_repeating_its_modifiers -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Each control-channel request carries its own modifiers, so an Up sent after the keys\n // are released arrives without Shift+Alt: it must still close the HUD it opened, or the\n // HUD stays up and keeps picking from the hover (#6098 review).\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 120, \"height\": 80})).unwrap();\n app.ui.tool = Tool::Brush;\n let shift_alt = egui::Modifiers { shift: true, alt: true, ..Default::default() };\n assert!(!pointer_secondary(&mut app, &egui::Context::default(), true, shift_alt, [10.0, 10.0]));\n assert!(app.ui.color_hud.is_some_and(|h| !h.hold), \"the control-channel HUD opened\");\n assert!(!pointer_secondary(&mut app, &egui::Context::default(), false, egui::Modifiers::NONE, [10.0, 10.0]));\n assert!(app.ui.color_hud.is_none(), \"the Up closes it whatever the modifiers say\");\n // A real-mouse HUD belongs to the canvas gesture and waits for its own button release.",
|
|
"expected_assertions": [
|
|
" assert!(!pointer_secondary(&mut app, &egui::Context::default(), true, shift_alt, [10.0, 10.0]));\n assert!(app.ui.color_hud.is_some_and(|h| !h.hold), \"the control-channel HUD opened\");\n assert!(!pointer_secondary(&mut app, &egui::Context::default(), false, egui::Modifiers::NONE, [10.0, 10.0]));\n assert!(app.ui.color_hud.is_none(), \"the Up closes it whatever the modifiers say\");\n // A real-mouse HUD belongs to the canvas gesture and waits for its own button release.\n crate::color_hud::open(&mut app, [10.0, 10.0], true);\n pointer_secondary(&mut app, &egui::Context::default(), false, egui::Modifiers::NONE, [10.0, 10.0]);\n assert!(app.ui.color_hud.is_some_and(|h| h.hold), \"a held HUD is left to the canvas\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ce546dd4b5451a17b843ef1e129bdb40fbfe3160/crates/ui-egui/src/paint_mouse.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6510",
|
|
"pr": 6510,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-automation --locked canonical_windows_prefixes_match_without_ambient_resolution -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked windows_root_case_variants_keep_io_inside_the_grant -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked unix_root_prefixes_remain_case_sensitive -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked configured_parent_components_accept_resolved_absolute_paths -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked relative_configured_root_accepts_resolved_absolute_paths -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked trusted_root_names_are_not_validated_as_relative_request_names -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked linked_root_accepts_both_spellings_and_new_nested_exports -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked root_alias_tests_work_with_an_aliased_windows_temp -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked ungranted_absolute_aliases_and_link_escapes_are_refused -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked retargeting_root_alias_does_not_regrant_the_held_authority -- --nocapture"
|
|
],
|
|
"expected": "canonical windows prefixes match without ambient resolution; windows root case variants keep io inside the grant; unix root prefixes remain case sensitive; configured parent components accept resolved absolute paths; relative configured root accepts resolved absolute paths; trusted root names are not validated as relative request names; linked root accepts both spellings and new nested exports; root alias tests work with an aliased windows temp; ungranted absolute aliases and link escapes are refused; retargeting root alias does not regrant the held authority",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-automation --locked canonical_windows_prefixes_match_without_ambient_resolution -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked windows_root_case_variants_keep_io_inside_the_grant -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked unix_root_prefixes_remain_case_sensitive -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked configured_parent_components_accept_resolved_absolute_paths -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked relative_configured_root_accepts_resolved_absolute_paths -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked trusted_root_names_are_not_validated_as_relative_request_names -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked linked_root_accepts_both_spellings_and_new_nested_exports -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked root_alias_tests_work_with_an_aliased_windows_temp -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked ungranted_absolute_aliases_and_link_escapes_are_refused -- --nocapture",
|
|
"cargo test -p photocraft-automation --locked retargeting_root_alias_does_not_regrant_the_held_authority -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "canonical_windows_prefixes_match_without_ambient_resolution",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked canonical_windows_prefixes_match_without_ambient_resolution -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (request, root) in [\n (r\"c:\\root\\new.bin\", r\"\\\\?\\C:\\root\"),\n (r\"\\\\?\\C:\\root\\new.bin\", r\"C:\\root\"),\n (r\"\\\\server\\share\\root\\new.bin\", r\"\\\\?\\UNC\\SERVER\\SHARE\\root\"),\n (r\"c:\\ROOT\\new.bin\", r\"\\\\?\\C:\\root\"),\n (r\"\\\\?\\C:\\ROOT\\new.bin\", r\"c:\\root\"),\n (r\"\\\\server\\share\\ROOT\\new.bin\", r\"\\\\?\\UNC\\SERVER\\SHARE\\root\"),\n ] {\n let remaining = path_beneath_root(Path::new(request), Path::new(root)).unwrap();\n assert_eq!(remaining.as_path(), Path::new(\"new.bin\"));\n }\n for request in [r\"C:\\root-sibling\\new.bin\", r\"D:\\root\\new.bin\", r\"\\\\.\\C:\\root\\new.bin\", r\"\\\\other\\share\\root\\new.bin\"] {",
|
|
"expected_assertions": [
|
|
" assert_eq!(remaining.as_path(), Path::new(\"new.bin\"));\n }\n for request in [r\"C:\\root-sibling\\new.bin\", r\"D:\\root\\new.bin\", r\"\\\\.\\C:\\root\\new.bin\", r\"\\\\other\\share\\root\\new.bin\"] {\n assert!(path_beneath_root(Path::new(request), Path::new(r\"\\\\?\\C:\\root\")).is_none());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "windows_root_case_variants_keep_io_inside_the_grant",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked windows_root_case_variants_keep_io_inside_the_grant -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, workspace) = roots(\"root-case\");\n let configured = PathBuf::from(inside.to_string_lossy().to_ascii_uppercase());\n let canonical = PathBuf::from(std::fs::canonicalize(&inside).unwrap().to_string_lossy().to_ascii_uppercase());\n for spelling in [&configured, &canonical] {\n let path = spelling.join(\"new.bin\");\n workspace.write(&path.to_string_lossy(), b\"inside\").unwrap();\n assert_eq!(workspace.read(&path.to_string_lossy()).unwrap(), b\"inside\");\n assert!(workspace.write(&spelling.join(\"..\").join(\"outside\").join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n }\n assert_eq!(std::fs::read(inside.join(\"new.bin\")).unwrap(), b\"inside\");\n assert!(workspace.write(&configured.with_file_name(\"INSIDE-SIBLING\").join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!outside.join(\"blocked.bin\").exists());",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&path.to_string_lossy()).unwrap(), b\"inside\");\n assert!(workspace.write(&spelling.join(\"..\").join(\"outside\").join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n }\n assert_eq!(std::fs::read(inside.join(\"new.bin\")).unwrap(), b\"inside\");\n assert!(workspace.write(&configured.with_file_name(\"INSIDE-SIBLING\").join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!outside.join(\"blocked.bin\").exists());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "unix_root_prefixes_remain_case_sensitive",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked unix_root_prefixes_remain_case_sensitive -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert!(path_beneath_root(Path::new(\"/Root/new.bin\"), Path::new(\"/root\")).is_none());\n}",
|
|
"expected_assertions": [
|
|
" assert!(path_beneath_root(Path::new(\"/Root/new.bin\"), Path::new(\"/root\")).is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "configured_parent_components_accept_resolved_absolute_paths",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked configured_parent_components_accept_resolved_absolute_paths -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, _) = roots(\"resolved-parent-root\");\n let configured = inside.join(\"..\").join(\"inside\");\n let workspace = AuthorizedWorkspace::new(Some(&configured), Some(&configured)).unwrap();\n let resolved = std::fs::canonicalize(&inside).unwrap();\n workspace.write(&resolved.join(\"new.bin\").to_string_lossy(), b\"new\").unwrap();\n assert_eq!(workspace.read(&resolved.join(\"new.bin\").to_string_lossy()).unwrap(), b\"new\");\n workspace.write(&configured.join(\"launch-spelling.bin\").to_string_lossy(), b\"trusted prefix\").unwrap();\n assert_eq!(workspace.read(&configured.join(\"launch-spelling.bin\").to_string_lossy()).unwrap(), b\"trusted prefix\");\n assert_eq!(workspace.read(&resolved.join(\"launch-spelling.bin\").to_string_lossy()).unwrap(), b\"trusted prefix\");\n assert!(workspace.write(&configured.join(\"..\").join(\"outside/escaped.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!outside.join(\"escaped.bin\").exists());\n assert!(workspace.write(&outside.join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&resolved.join(\"new.bin\").to_string_lossy()).unwrap(), b\"new\");\n workspace.write(&configured.join(\"launch-spelling.bin\").to_string_lossy(), b\"trusted prefix\").unwrap();\n assert_eq!(workspace.read(&configured.join(\"launch-spelling.bin\").to_string_lossy()).unwrap(), b\"trusted prefix\");\n assert_eq!(workspace.read(&resolved.join(\"launch-spelling.bin\").to_string_lossy()).unwrap(), b\"trusted prefix\");\n assert!(workspace.write(&configured.join(\"..\").join(\"outside/escaped.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!outside.join(\"escaped.bin\").exists());\n assert!(workspace.write(&outside.join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!outside.join(\"blocked.bin\").exists());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "relative_configured_root_accepts_resolved_absolute_paths",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked relative_configured_root_accepts_resolved_absolute_paths -- --nocapture",
|
|
"fixture_and_action_excerpt": " let relative = PathBuf::from(\"target\").join(format!(\"automation-relative-root-{}\", std::process::id()));\n std::fs::create_dir_all(&relative).unwrap();\n let workspace = AuthorizedWorkspace::new(Some(&relative), Some(&relative)).unwrap();\n let resolved = std::fs::canonicalize(&relative).unwrap();\n workspace.write(&resolved.join(\"new.bin\").to_string_lossy(), b\"relative\").unwrap();\n assert_eq!(workspace.read(&resolved.join(\"new.bin\").to_string_lossy()).unwrap(), b\"relative\");\n std::fs::remove_file(resolved.join(\"new.bin\")).unwrap();\n drop(workspace);\n std::fs::remove_dir(resolved).unwrap();\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&resolved.join(\"new.bin\").to_string_lossy()).unwrap(), b\"relative\");\n std::fs::remove_file(resolved.join(\"new.bin\")).unwrap();\n drop(workspace);\n std::fs::remove_dir(resolved).unwrap();"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "trusted_root_names_are_not_validated_as_relative_request_names",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked trusted_root_names_are_not_validated_as_relative_request_names -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, _) = roots(\"trusted-root-names\");\n let root = inside.join(\"aux\");\n std::fs::create_dir(&root).unwrap();\n let alias = outside.join(\"CON\");\n link_directory(&root, &alias);\n let workspace = AuthorizedWorkspace::new(Some(&alias), Some(&alias)).unwrap();\n for spelling in [&root, &alias] {\n workspace.write(&spelling.join(\"new.bin\").to_string_lossy(), b\"trusted\").unwrap();\n assert_eq!(workspace.read(&spelling.join(\"new.bin\").to_string_lossy()).unwrap(), b\"trusted\");\n assert!(workspace.write(&spelling.join(\"NUL\").to_string_lossy(), b\"no\").is_err());\n }\n assert!(!root.join(\"NUL\").exists());",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&spelling.join(\"new.bin\").to_string_lossy()).unwrap(), b\"trusted\");\n assert!(workspace.write(&spelling.join(\"NUL\").to_string_lossy(), b\"no\").is_err());\n }\n assert!(!root.join(\"NUL\").exists());\n remove_directory_link(&alias);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "linked_root_accepts_both_spellings_and_new_nested_exports",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked linked_root_accepts_both_spellings_and_new_nested_exports -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, _) = roots(\"linked-root\");\n let link = outside.join(\"root-link\");\n link_directory(&inside, &link);\n let workspace = AuthorizedWorkspace::new(Some(&link), Some(&link)).unwrap();\n let resolved = std::fs::canonicalize(&inside).unwrap();\n for (i, spelling) in [resolved, link.clone()].iter().enumerate() {\n let name = format!(\"new-{i}.bin\");\n workspace.write(&spelling.join(&name).to_string_lossy(), b\"new\").unwrap();\n assert_eq!(workspace.read(&spelling.join(&name).to_string_lossy()).unwrap(), b\"new\");\n assert_eq!(workspace.read(&name).unwrap(), b\"new\");\n let mut export = workspace.export_sequence(&spelling.join(format!(\"frames-{i}\")).join(\"nested\").to_string_lossy()).unwrap();\n export.write(\"frame.png\", b\"frame\").unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&spelling.join(&name).to_string_lossy()).unwrap(), b\"new\");\n assert_eq!(workspace.read(&name).unwrap(), b\"new\");\n let mut export = workspace.export_sequence(&spelling.join(format!(\"frames-{i}\")).join(\"nested\").to_string_lossy()).unwrap();\n export.write(\"frame.png\", b\"frame\").unwrap();\n export.commit();\n assert_eq!(std::fs::read(inside.join(format!(\"frames-{i}/nested/frame.png\"))).unwrap(), b\"frame\");\n }\n remove_directory_link(&link);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "root_alias_tests_work_with_an_aliased_windows_temp",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked root_alias_tests_work_with_an_aliased_windows_temp -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, _) = roots(\"aliased-temp\");\n let temp_alias = outside.join(\"temp-alias\");\n link_directory(&inside, &temp_alias);\n let exe = std::env::current_exe().unwrap();\n for test in [\n \"workspace::tests::ungranted_absolute_aliases_and_link_escapes_are_refused\",\n \"workspace::tests::retargeting_root_alias_does_not_regrant_the_held_authority\",\n ] {\n // Set TEMP only in the child; changing the process environment races other tests.\n let output = std::process::Command::new(&exe).args([\"--exact\", test, \"--nocapture\"]).env(\"TEMP\", &temp_alias).env(\"TMP\", &temp_alias).output().unwrap();\n let stdout = String::from_utf8_lossy(&output.stdout);\n let stderr = String::from_utf8_lossy(&output.stderr);",
|
|
"expected_assertions": [
|
|
" assert!(output.status.success(), \"{test}: {stdout}\\n{stderr}\");\n assert!(stdout.contains(\"1 passed;\"), \"child must run the requested test: {stdout}\");\n }\n remove_directory_link(&temp_alias);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "ungranted_absolute_aliases_and_link_escapes_are_refused",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked ungranted_absolute_aliases_and_link_escapes_are_refused -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, workspace) = roots(\"request-alias\");\n // TEMP may use an 8.3 name or a junction. A grant through `alias` below recognises\n // that configured alias and the canonical target, not every other name for `inside`.\n let resolved_inside = std::fs::canonicalize(&inside).unwrap();\n let alias = outside.join(\"inside-alias\");\n link_directory(&inside, &alias);\n workspace.write(\"new.bin\", b\"inside\").unwrap();\n assert!(workspace.read(&alias.join(\"new.bin\").to_string_lossy()).is_err());\n assert!(workspace.write(&alias.join(\"ungranted.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!inside.join(\"ungranted.bin\").exists());\n std::fs::write(outside.join(\"secret.bin\"), b\"outside\").unwrap();\n let escape = inside.join(\"escape\");",
|
|
"expected_assertions": [
|
|
" assert!(workspace.read(&alias.join(\"new.bin\").to_string_lossy()).is_err());\n assert!(workspace.write(&alias.join(\"ungranted.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!inside.join(\"ungranted.bin\").exists());\n std::fs::write(outside.join(\"secret.bin\"), b\"outside\").unwrap();\n let escape = inside.join(\"escape\");\n link_directory(&outside, &escape);\n assert!(workspace.read(&escape.join(\"secret.bin\").to_string_lossy()).is_err());\n assert!(workspace.write(&escape.join(\"blocked.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(workspace.export_sequence(&escape.join(\"frames\").join(\"nested\").to_string_lossy()).is_err());\n assert!(!outside.join(\"blocked.bin\").exists());\n assert!(!outside.join(\"frames\").exists());\n assert_eq!(std::fs::read(outside.join(\"secret.bin\")).unwrap(), b\"outside\");\n let read_only = AuthorizedWorkspace::new(Some(&alias), Some(&outside)).unwrap();\n assert_eq!(read_only.read(&resolved_inside.join(\"new.bin\").to_string_lossy()).unwrap(), b\"inside\");\n assert!(read_only.write(&alias.join(\"denied.bin\").to_string_lossy(), b\"no\").is_err());\n assert!(!inside.join(\"denied.bin\").exists());\n remove_directory_link(&escape);\n remove_directory_link(&alias);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "retargeting_root_alias_does_not_regrant_the_held_authority",
|
|
"path": "crates/automation/src/workspace/tests.rs",
|
|
"package": "photocraft-automation",
|
|
"command": "cargo test -p photocraft-automation --locked retargeting_root_alias_does_not_regrant_the_held_authority -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (inside, outside, _) = roots(\"retargeted-root\");\n let resolved_inside = std::fs::canonicalize(&inside).unwrap();\n let alias = outside.join(\"root-alias\");\n link_directory(&inside, &alias);\n let workspace = AuthorizedWorkspace::new(Some(&alias), Some(&alias)).unwrap();\n remove_directory_link(&alias);\n link_directory(&outside, &alias);\n std::fs::write(outside.join(\"secret.bin\"), b\"secret\").unwrap();\n workspace.write(\"held.bin\", b\"held\").unwrap();\n assert_eq!(workspace.read(&resolved_inside.join(\"held.bin\").to_string_lossy()).unwrap(), b\"held\");\n assert!(workspace.read(&alias.join(\"secret.bin\").to_string_lossy()).is_err());\n workspace.write(&alias.join(\"held-alias.bin\").to_string_lossy(), b\"original grant\").unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(workspace.read(&resolved_inside.join(\"held.bin\").to_string_lossy()).unwrap(), b\"held\");\n assert!(workspace.read(&alias.join(\"secret.bin\").to_string_lossy()).is_err());\n workspace.write(&alias.join(\"held-alias.bin\").to_string_lossy(), b\"original grant\").unwrap();\n assert_eq!(std::fs::read(inside.join(\"held-alias.bin\")).unwrap(), b\"original grant\");\n assert!(!outside.join(\"held-alias.bin\").exists());\n assert_eq!(std::fs::read(outside.join(\"secret.bin\")).unwrap(), b\"secret\");\n remove_directory_link(&alias);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bb0a5e67474d36ae08d565251edb1ae780dd044/crates/automation/src/workspace/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6621",
|
|
"pr": 6621,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_ratio_rows_fit_the_frame_like_the_options_bar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_gear_rows_toggle_the_shield_options -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_reset_cancel_and_commit_act_on_the_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_lists_saved_presets_and_applies_one -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_closes_when_the_crop_is_no_longer_pending -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked right_click_on_a_pending_crop_opens_the_crop_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked right_click_without_a_pending_crop_opens_no_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_commit_crops_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_edit_undo_then_commit_crops_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_a_still_click_keeps_the_no_op -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_frame_edit_back_to_bounds_commits_a_real_crop -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked type_layers_offer_free_transform_but_not_distort_or_perspective -- --nocapture"
|
|
],
|
|
"expected": "crop menu ratio rows fit the frame like the options bar; crop menu gear rows toggle the shield options; crop menu reset cancel and commit act on the frame; crop menu lists saved presets and applies one; crop menu closes when the crop is no longer pending; right click on a pending crop opens the crop menu; right click without a pending crop opens no menu; reset then commit crops nothing; reset edit undo then commit crops nothing; reset then a still click keeps the no op; reset then frame edit back to bounds commits a real crop; type layers offer free transform but not distort or perspective",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_ratio_rows_fit_the_frame_like_the_options_bar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_gear_rows_toggle_the_shield_options -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_reset_cancel_and_commit_act_on_the_frame -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_lists_saved_presets_and_applies_one -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked crop_menu_closes_when_the_crop_is_no_longer_pending -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked right_click_on_a_pending_crop_opens_the_crop_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked right_click_without_a_pending_crop_opens_no_menu -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_commit_crops_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_edit_undo_then_commit_crops_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_a_still_click_keeps_the_no_op -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked reset_then_frame_edit_back_to_bounds_commits_a_real_crop -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked type_layers_offer_free_transform_but_not_distort_or_perspective -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "crop_menu_ratio_rows_fit_the_frame_like_the_options_bar",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked crop_menu_ratio_rows_fit_the_frame_like_the_options_bar -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = crop_app();\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert!(menu.crop && available(&app, &menu, \"crop.ratio.16:9\"));\n choose(&mut app, &Context::default(), \"crop.ratio.16:9\");\n assert_eq!(app.ui.tool_options.crop_ratio, \"16:9\");\n assert!((frame_ratio(&app) - 16.0 / 9.0).abs() < 1e-9, \"the frame is fitted to the ratio\");\n // The current ratio shows checked; the others do not.\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert!(mode_checked(&app, &menu, \"crop.ratio.16:9\") && !mode_checked(&app, &menu, \"crop.ratio.1:1\"));\n choose(&mut app, &Context::default(), \"crop.ratio.1:1\");",
|
|
"expected_assertions": [
|
|
" assert!(menu.crop && available(&app, &menu, \"crop.ratio.16:9\"));\n choose(&mut app, &Context::default(), \"crop.ratio.16:9\");\n assert_eq!(app.ui.tool_options.crop_ratio, \"16:9\");\n assert!((frame_ratio(&app) - 16.0 / 9.0).abs() < 1e-9, \"the frame is fitted to the ratio\");\n // The current ratio shows checked; the others do not.\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert!(mode_checked(&app, &menu, \"crop.ratio.16:9\") && !mode_checked(&app, &menu, \"crop.ratio.1:1\"));\n choose(&mut app, &Context::default(), \"crop.ratio.1:1\");\n assert!((frame_ratio(&app) - 1.0).abs() < 1e-9);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "crop_menu_gear_rows_toggle_the_shield_options",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked crop_menu_gear_rows_toggle_the_shield_options -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = crop_app();\n crop_open(&mut app);\n choose(&mut app, &Context::default(), CROP_SHOW_CROPPED);\n assert!(!app.ui.tool_options.crop_shield.show_cropped_area);\n crop_open(&mut app);\n assert!(!mode_checked(&app, app.ui.canvas_tool_menu.as_ref().unwrap(), CROP_SHOW_CROPPED), \"the row shows the option's state\");\n choose(&mut app, &Context::default(), CROP_CLASSIC);\n assert!(app.ui.tool_options.crop_shield.classic_mode);\n // As in the gear menu, Classic Mode greys out the other two options.\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert!(!entry_enabled(&app, &menu, CROP_SHOW_CROPPED) && !entry_enabled(&app, &menu, CROP_AUTO_CENTER));",
|
|
"expected_assertions": [
|
|
" assert!(!app.ui.tool_options.crop_shield.show_cropped_area);\n crop_open(&mut app);\n assert!(!mode_checked(&app, app.ui.canvas_tool_menu.as_ref().unwrap(), CROP_SHOW_CROPPED), \"the row shows the option's state\");\n choose(&mut app, &Context::default(), CROP_CLASSIC);\n assert!(app.ui.tool_options.crop_shield.classic_mode);\n // As in the gear menu, Classic Mode greys out the other two options.\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert!(!entry_enabled(&app, &menu, CROP_SHOW_CROPPED) && !entry_enabled(&app, &menu, CROP_AUTO_CENTER));\n assert!(entry_enabled(&app, &menu, CROP_CLASSIC));\n choose(&mut app, &Context::default(), CROP_CLASSIC);\n assert!(!app.ui.tool_options.crop_shield.classic_mode);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "crop_menu_reset_cancel_and_commit_act_on_the_frame",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked crop_menu_reset_cancel_and_commit_act_on_the_frame -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Reset: the whole canvas, still a pending frame.\n let mut app = crop_app();\n crop_open(&mut app);\n choose(&mut app, &Context::default(), CROP_RESET);\n assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 32.0, 32.0]));\n assert!(crate::crop_ui::pending(&app), \"Reset keeps the crop active, as in Photoshop\");\n // Cancel: the frame is dropped (the tool's next frame is the default one).\n crop_open(&mut app);\n choose(&mut app, &Context::default(), CROP_CANCEL);\n assert!(app.ui.crop_rect.is_none() && !crate::crop_ui::pending(&app));\n // Commit: the document is cropped to the frame.\n let mut app = crop_app();",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 32.0, 32.0]));\n assert!(crate::crop_ui::pending(&app), \"Reset keeps the crop active, as in Photoshop\");\n // Cancel: the frame is dropped (the tool's next frame is the default one).\n crop_open(&mut app);\n choose(&mut app, &Context::default(), CROP_CANCEL);\n assert!(app.ui.crop_rect.is_none() && !crate::crop_ui::pending(&app));\n // Commit: the document is cropped to the frame.\n let mut app = crop_app();\n crop_open(&mut app);\n assert_eq!(app.session.active().unwrap().doc.size, photocraft_doc::Size::new(20, 20));\n assert!(app.ui.crop_rect.is_none());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "crop_menu_lists_saved_presets_and_applies_one",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked crop_menu_lists_saved_presets_and_applies_one -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = crop_app();\n app.run(\"tool.presets.new\", json!({\"name\": \"Wide\", \"tool\": \"crop\", \"options\": {\"toolOptions\": {\"crop_ratio\": \"16:9\"}}})).unwrap();\n crop_open(&mut app);\n let menu = app.ui.canvas_tool_menu.clone().unwrap();\n assert_eq!(menu.crop_presets, [\"Wide\"]);\n assert!(available(&app, &menu, \"crop.preset.0\"));\n assert!(crop_rows(&menu).iter().flatten().any(|(label, _)| label == \"Wide\"), \"the preset is a row: {:?}\", crop_rows(&menu));\n choose(&mut app, &Context::default(), \"crop.preset.0\");\n // As in the options bar's dropdown: the preset fills the fields (the frame follows on the\n // next resize or ratio apply).\n assert_eq!(app.ui.tool_options.crop_ratio, \"16:9\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(menu.crop_presets, [\"Wide\"]);\n assert!(available(&app, &menu, \"crop.preset.0\"));\n assert!(crop_rows(&menu).iter().flatten().any(|(label, _)| label == \"Wide\"), \"the preset is a row: {:?}\", crop_rows(&menu));\n choose(&mut app, &Context::default(), \"crop.preset.0\");\n // As in the options bar's dropdown: the preset fills the fields (the frame follows on the\n // next resize or ratio apply).\n assert_eq!(app.ui.tool_options.crop_ratio, \"16:9\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "crop_menu_closes_when_the_crop_is_no_longer_pending",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked crop_menu_closes_when_the_crop_is_no_longer_pending -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = crop_app();\n crop_open(&mut app);\n assert!(app.ui.canvas_tool_menu.is_some());\n crate::crop_ui::cancel(&mut app);\n show(&mut app, &Context::default());\n assert!(app.ui.canvas_tool_menu.is_none(), \"the menu does not outlive the pending frame\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.canvas_tool_menu.is_some());\n crate::crop_ui::cancel(&mut app);\n show(&mut app, &Context::default());\n assert!(app.ui.canvas_tool_menu.is_none(), \"the menu does not outlive the pending frame\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "right_click_on_a_pending_crop_opens_the_crop_menu",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked right_click_on_a_pending_crop_opens_the_crop_menu -- --nocapture",
|
|
"fixture_and_action_excerpt": " let app = crop_app();\n let mut h = harness(app);\n let center = h.state().last_canvas_rect.center();\n right_click(&mut h, center, Modifiers::NONE);\n let menu = h.state().ui.canvas_tool_menu.clone().expect(\"right-click on a pending crop opens a menu\");\n assert!(menu.crop && !menu.pasteboard && !menu.transform);\n let ctx = h.ctx.clone();\n choose(h.state_mut(), &ctx, \"crop.ratio.16:9\");\n let r = h.state().ui.crop_rect.unwrap();\n assert!(((r[2] - r[0]) / (r[3] - r[1]) - 16.0 / 9.0).abs() < 1e-9, \"choosing 16:9 refits the frame\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(menu.crop && !menu.pasteboard && !menu.transform);\n let ctx = h.ctx.clone();\n choose(h.state_mut(), &ctx, \"crop.ratio.16:9\");\n let r = h.state().ui.crop_rect.unwrap();\n assert!(((r[2] - r[0]) / (r[3] - r[1]) - 16.0 / 9.0).abs() < 1e-9, \"choosing 16:9 refits the frame\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "right_click_without_a_pending_crop_opens_no_menu",
|
|
"path": "crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked right_click_without_a_pending_crop_opens_no_menu -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool = Tool::Crop;\n crate::crop_ui::ensure_frame(&mut app);\n assert!(app.ui.crop_rect.is_some() && !crate::crop_ui::pending(&app), \"the untouched default frame is not pending\");\n let mut h = harness(app);\n let center = h.state().last_canvas_rect.center();\n right_click(&mut h, center, Modifiers::NONE);\n assert!(h.state().ui.canvas_tool_menu.is_none(), \"no menu on the untouched default frame\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.crop_rect.is_some() && !crate::crop_ui::pending(&app), \"the untouched default frame is not pending\");\n let mut h = harness(app);\n let center = h.state().last_canvas_rect.center();\n right_click(&mut h, center, Modifiers::NONE);\n assert!(h.state().ui.canvas_tool_menu.is_none(), \"no menu on the untouched default frame\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/canvas_tool_menu.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reset_then_commit_crops_nothing",
|
|
"path": "crates/ui-egui/src/crop_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked reset_then_commit_crops_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(SampleType::U8);\n app.ui.tool_options.crop_delete = true;\n // A layer whose pixels reach past the right edge: a full-canvas crop with delete would\n // trim them.\n app.run(\"layer.new.layer\", json!({\"name\": \"over\"})).unwrap();\n app.run(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n app.run(\"layer.translate\", json!({\"dx\": 40, \"dy\": 0})).unwrap();\n let over = app.session.active().unwrap().doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n let past = over.surface().unwrap().content_bounds().x1;\n assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n // A drawn frame, then Reset: the whole canvas again, still pending.\n drag(&mut app, &[[10.0, 10.0], [50.0, 40.0]], NONE);",
|
|
"expected_assertions": [
|
|
" assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n // A drawn frame, then Reset: the whole canvas again, still pending.\n drag(&mut app, &[[10.0, 10.0], [50.0, 40.0]], NONE);\n reset(&mut app);\n assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 200.0, 100.0]));\n assert!(pending(&app), \"Reset keeps the crop pending\");\n let steps = app.session.active().unwrap().history.past_len();\n crate::canvas::commit_crop(&mut app);\n let st = app.session.active().unwrap();\n assert_eq!((st.doc.size, st.history.past_len()), (Size::new(200, 100), steps), \"a reset frame commits as a no-op\");\n assert!(app.ui.crop_rect.is_none(), \"the frame is gone\");\n let over = st.doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n assert_eq!(over.surface().unwrap().content_bounds().x1, past, \"pixels outside the canvas are kept\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/crop_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reset_edit_undo_then_commit_crops_nothing",
|
|
"path": "crates/ui-egui/src/crop_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked reset_edit_undo_then_commit_crops_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(SampleType::U8);\n app.ui.tool_options.crop_delete = true;\n app.run(\"layer.new.layer\", json!({\"name\": \"over\"})).unwrap();\n app.run(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n app.run(\"layer.translate\", json!({\"dx\": 40, \"dy\": 0})).unwrap();\n let over = app.session.active().unwrap().doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n let past = over.surface().unwrap().content_bounds().x1;\n assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n // Reset, then a gesture that shrinks the frame, then Undo back to the reset frame.\n reset(&mut app);\n drag(&mut app, &[[0.0, 0.0], [50.0, 40.0]], NONE);\n assert_eq!(app.ui.crop_rect, Some([50.0, 40.0, 200.0, 100.0]), \"the corner drag resizes the frame\");",
|
|
"expected_assertions": [
|
|
" assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n // Reset, then a gesture that shrinks the frame, then Undo back to the reset frame.\n reset(&mut app);\n drag(&mut app, &[[0.0, 0.0], [50.0, 40.0]], NONE);\n assert_eq!(app.ui.crop_rect, Some([50.0, 40.0, 200.0, 100.0]), \"the corner drag resizes the frame\");\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 200.0, 100.0]), \"Undo restores the reset frame\");\n assert!(pending(&app));\n let steps = app.session.active().unwrap().history.past_len();\n crate::canvas::commit_crop(&mut app);\n let st = app.session.active().unwrap();\n assert_eq!((st.doc.size, st.history.past_len()), (Size::new(200, 100), steps), \"the undone reset frame commits as a no-op\");\n assert!(app.ui.crop_rect.is_none(), \"the frame is gone\");\n let over = st.doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n assert_eq!(over.surface().unwrap().content_bounds().x1, past, \"pixels outside the canvas are kept\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/crop_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reset_then_a_still_click_keeps_the_no_op",
|
|
"path": "crates/ui-egui/src/crop_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked reset_then_a_still_click_keeps_the_no_op -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(SampleType::U8);\n app.ui.tool_options.crop_delete = true;\n app.run(\"layer.new.layer\", json!({\"name\": \"over\"})).unwrap();\n app.run(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n app.run(\"layer.translate\", json!({\"dx\": 40, \"dy\": 0})).unwrap();\n reset(&mut app);\n drag(&mut app, &[[100.0, 50.0], [100.0, 50.0]], NONE);\n assert!(app.crop.reset_frame, \"a click without a frame change keeps the reset marker\");\n let steps = app.session.active().unwrap().history.past_len();\n crate::canvas::commit_crop(&mut app);\n let st = app.session.active().unwrap();\n assert_eq!((st.doc.size, st.history.past_len()), (Size::new(200, 100), steps), \"the click leaves the no-op\");",
|
|
"expected_assertions": [
|
|
" assert!(app.crop.reset_frame, \"a click without a frame change keeps the reset marker\");\n let steps = app.session.active().unwrap().history.past_len();\n crate::canvas::commit_crop(&mut app);\n let st = app.session.active().unwrap();\n assert_eq!((st.doc.size, st.history.past_len()), (Size::new(200, 100), steps), \"the click leaves the no-op\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/crop_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reset_then_frame_edit_back_to_bounds_commits_a_real_crop",
|
|
"path": "crates/ui-egui/src/crop_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked reset_then_frame_edit_back_to_bounds_commits_a_real_crop -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(SampleType::U8);\n app.ui.tool_options.crop_delete = true;\n app.run(\"layer.new.layer\", json!({\"name\": \"over\"})).unwrap();\n app.run(\"edit.fill\", json!({\"color\": \"#ff0000\"})).unwrap();\n app.run(\"layer.translate\", json!({\"dx\": 40, \"dy\": 0})).unwrap();\n let over = app.session.active().unwrap().doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n let past = over.surface().unwrap().content_bounds().x1;\n assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n reset(&mut app);\n drag(&mut app, &[[0.0, 0.0], [50.0, 40.0]], NONE); // shrink: a real edit\n assert!(!app.crop.reset_frame, \"moving the frame ends the reset no-op\");\n drag(&mut app, &[[50.0, 40.0], [0.0, 0.0]], NONE); // back to the full bounds",
|
|
"expected_assertions": [
|
|
" assert!(past > 200, \"the layer reaches past the canvas: {past}\");\n reset(&mut app);\n drag(&mut app, &[[0.0, 0.0], [50.0, 40.0]], NONE); // shrink: a real edit\n assert!(!app.crop.reset_frame, \"moving the frame ends the reset no-op\");\n drag(&mut app, &[[50.0, 40.0], [0.0, 0.0]], NONE); // back to the full bounds\n assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 200.0, 100.0]));\n let steps = app.session.active().unwrap().history.past_len();\n crate::canvas::commit_crop(&mut app);\n let st = app.session.active().unwrap();\n assert_eq!(st.history.past_len(), steps + 1, \"the restored frame commits as a real crop\");\n let over = st.doc.layers.iter().rev().find(|l| l.name == \"over\").unwrap();\n assert_eq!(over.surface().unwrap().content_bounds().x1, 200, \"pixels outside the canvas are deleted\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/crop_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "type_layers_offer_free_transform_but_not_distort_or_perspective",
|
|
"path": "crates/ui-egui/src/transform_type_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked type_layers_offer_free_transform_but_not_distort_or_perspective -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n for selection in [false, true] {\n if selection {\n select_left_half(&mut app);\n }\n for id in [\"edit.freeTransform\", \"edit.transform.scale\", \"edit.transform.rotate\", \"edit.transform.skew\"] {\n assert!(crate::menus::is_enabled(&app, id), \"{id} (selection: {selection})\");\n }\n for id in [\"edit.transform.distort\", \"edit.transform.perspective\"] {\n assert!(!crate::menus::is_enabled(&app, id), \"{id} is greyed for editable type (selection: {selection})\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(crate::menus::is_enabled(&app, id), \"{id} (selection: {selection})\");\n }\n for id in [\"edit.transform.distort\", \"edit.transform.perspective\"] {\n assert!(!crate::menus::is_enabled(&app, id), \"{id} is greyed for editable type (selection: {selection})\");\n }\n }\n // The same rows in the marquee's canvas context menu.\n assert!(crate::canvas_tool_menu::available(&app, &menu, \"edit.freeTransform\"));\n assert!(!crate::canvas_tool_menu::available(&app, &menu, \"edit.transform.distort\"));\n assert!(!crate::canvas_tool_menu::available(&app, &menu, \"edit.transform.perspective\"));\n // Rasterized, the type is pixels and can be distorted.\n app.run(\"layer.rasterize.type\", json!({})).unwrap();\n assert!(crate::menus::is_enabled(&app, \"edit.transform.distort\") && crate::menus::is_enabled(&app, \"edit.transform.perspective\"));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ead45134d320cb1002724d5ef44f5c56588bbe1d/crates/ui-egui/src/transform_type_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-7648",
|
|
"pr": 7648,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked merge_shape_components_bakes_a_paths_operations -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_shape_components_on_a_shape_layer_rerenders_it -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merging_a_vector_mask_to_nothing_keeps_what_it_shows -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_changes_existing_components -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_on_a_joined_subpath_changes_its_component -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_leaves_the_first_component_combining -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_set_operation_params_change_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_merge_params_change_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_refuses_open_subpaths -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ui_set_drives_the_pen_path_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_selected_component_takes_the_picked_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked plus_and_minus_pick_combine_and_subtract -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_selection_selects_and_moves_components -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_stale_selection_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_first_component_keeps_combining -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_does_not_edit_a_hidden_component_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_a_live_shape_keeps_it_live -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_carries_on_an_open_shape_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_open_component_of_a_filled_shape_keeps_its_paint -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_carries_on_a_vector_masks_open_subpath -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked subtract_front_shape_cuts_a_hole_in_the_selected_shape_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_locked_shape_layer_keeps_the_drawn_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked switching_tools_ends_a_refused_draft_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked esc_ends_a_refused_draft_and_return_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_operation_without_a_selected_shape_starts_a_new_shape_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_mode_adds_subpaths_with_the_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_options_bar_menu_sets_the_operation_and_merges -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked merge_is_disabled_with_fewer_than_two_components -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_unknown_operation_falls_back_to_new_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_refuses_a_locked_shape_before_starting_a_stroke -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_stale_pen_commit_preserves_the_draft_until_retry -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_pen_commits_to_its_owner_across_document_changes -- --nocapture"
|
|
],
|
|
"expected": "merge shape components bakes a paths operations; merge shape components on a shape layer rerenders it; merging a vector mask to nothing keeps what it shows; set operation changes existing components; set operation on a joined subpath changes its component; set operation leaves the first component combining; bad set operation params change nothing; bad merge params change nothing; merge refuses open subpaths; ui set drives the pen path operation; a selected component takes the picked operation; plus and minus pick combine and subtract; path selection selects and moves components; a stale selection changes nothing; the first component keeps combining; the pen does not edit a hidden component selection; dragging a live shape keeps it live; the pen carries on an open shape path; an open component of a filled shape keeps its paint; the pen carries on a vector masks open subpath; subtract front shape cuts a hole in the selected shape layer; a locked shape layer keeps the drawn path; switching tools ends a refused draft once; esc ends a refused draft and return keeps it; an operation without a selected shape starts a new shape layer; path mode adds subpaths with the operation; the options bar menu sets the operation and merges; merge is disabled with fewer than two components; an unknown operation falls back to new layer; freeform refuses a locked shape before starting a stroke; failed stale pen commit preserves the draft until retry; stale pen commits to its owner across document changes",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked merge_shape_components_bakes_a_paths_operations -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_shape_components_on_a_shape_layer_rerenders_it -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merging_a_vector_mask_to_nothing_keeps_what_it_shows -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_changes_existing_components -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_on_a_joined_subpath_changes_its_component -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_operation_leaves_the_first_component_combining -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_set_operation_params_change_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked bad_merge_params_change_nothing -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_refuses_open_subpaths -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ui_set_drives_the_pen_path_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_selected_component_takes_the_picked_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked plus_and_minus_pick_combine_and_subtract -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_selection_selects_and_moves_components -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_stale_selection_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_first_component_keeps_combining -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_does_not_edit_a_hidden_component_selection -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_a_live_shape_keeps_it_live -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_carries_on_an_open_shape_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_open_component_of_a_filled_shape_keeps_its_paint -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_pen_carries_on_a_vector_masks_open_subpath -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked subtract_front_shape_cuts_a_hole_in_the_selected_shape_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_locked_shape_layer_keeps_the_drawn_path -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked switching_tools_ends_a_refused_draft_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked esc_ends_a_refused_draft_and_return_keeps_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_operation_without_a_selected_shape_starts_a_new_shape_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked path_mode_adds_subpaths_with_the_operation -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_options_bar_menu_sets_the_operation_and_merges -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked merge_is_disabled_with_fewer_than_two_components -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_unknown_operation_falls_back_to_new_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked freeform_refuses_a_locked_shape_before_starting_a_stroke -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked failed_stale_pen_commit_preserves_the_draft_until_retry -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_pen_commits_to_its_owner_across_document_changes -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "merge_shape_components_bakes_a_paths_operations",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merge_shape_components_bakes_a_paths_operations -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n s.execute(\"path.set\", json!({\"path\": square()})).unwrap();\n let hole = json!({\"subpaths\": [{\"closed\": true, \"knots\": [[25, 25], [45, 25], [45, 45], [25, 45]]}]});\n s.execute(\"path.set\", json!({\"path\": hole, \"op\": \"subtract\"})).unwrap();\n let before = work(&s);\n let r = s.execute(\"path.mergeShapeComponents\", json!({})).unwrap();\n assert_eq!(r[\"name\"], json!(\"work\"));\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Merge Shape Components\"));\n let merged = work(&s);\n assert_eq!(merged.subpaths.len(), 2, \"the outline and its hole\");\n for (x, y) in [(15, 15), (35, 35), (55, 50), (5, 5)] {\n assert!((covered(&merged, x, y) - covered(&before, x, y)).abs() < 0.01, \"({x}, {y})\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(r[\"name\"], json!(\"work\"));\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Merge Shape Components\"));\n let merged = work(&s);\n assert_eq!(merged.subpaths.len(), 2, \"the outline and its hole\");\n for (x, y) in [(15, 15), (35, 35), (55, 50), (5, 5)] {\n assert!((covered(&merged, x, y) - covered(&before, x, y)).abs() < 0.01, \"({x}, {y})\");\n }\n assert_eq!((covered(&merged, 35, 35), covered(&merged, 15, 15)), (0.0, 1.0), \"the hole stays a hole\");\n assert!(s.undo());\n assert_eq!(work(&s), before);\n // A saved path and a vector mask merge the same way; an inverted mask stays inverted.\n s.execute(\"path.set\", json!({\"name\": \"Mug\", \"path\": square()})).unwrap();\n s.execute(\"path.mergeShapeComponents\", json!({\"name\": \"Mug\"})).unwrap();\n assert!(vm.path.inverted && !vm.path.subpaths.is_empty());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merge_shape_components_on_a_shape_layer_rerenders_it",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merge_shape_components_on_a_shape_layer_rerenders_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let id = s.execute(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [10, 10, 50, 50], \"fill\": \"#ff0000\"})).unwrap()[\"layer\"].as_u64().unwrap();\n s.execute(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [25, 25, 20, 20], \"addTo\": id, \"op\": \"subtract\"})).unwrap();\n s.execute(\"path.mergeShapeComponents\", json!({\"name\": \"layer\", \"layer\": id})).unwrap();\n let st = s.active().unwrap();\n let photocraft_doc::LayerContent::Shape(ShapeLayer { path, cache, .. }) = &st.doc.layer(LayerId(id)).unwrap().content else { panic!(\"shape\") };\n assert_eq!(covered(path, 35, 35), 0.0);\n assert!(cache.is_some());\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(covered(path, 35, 35), 0.0);\n assert!(cache.is_some());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merging_a_vector_mask_to_nothing_keeps_what_it_shows",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merging_a_vector_mask_to_nothing_keeps_what_it_shows -- --nocapture",
|
|
"fixture_and_action_excerpt": " for inverted in [false, true] {\n let mut s = session();\n let id = s.active().unwrap().active_layer.unwrap().0;\n let mut cancelled = square();\n cancelled[\"subpaths\"].as_array_mut().unwrap().push(json!({\"closed\": true, \"op\": \"subtract\", \"knots\": [[10, 10], [60, 10], [60, 60], [10, 60]]}));\n cancelled[\"inverted\"] = json!(inverted);\n s.execute(\"layer.vectorMask.add\", json!({\"layer\": id, \"path\": cancelled})).unwrap();\n let mask = |s: &Session| s.active().unwrap().doc.layer(LayerId(id)).unwrap().vector_mask.clone().unwrap();\n let shown = |s: &Session| photocraft_vector::vector_mask_values(&mask(s), photocraft_geom::Rect::from_xywh(0, 0, 120, 100));\n let before = shown(&s);\n assert!(before.iter().all(|v| *v == if inverted { 1.0 } else { 0.0 }), \"inverted {inverted}\");\n s.execute(\"path.mergeShapeComponents\", json!({\"name\": \"layer\", \"layer\": id})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(before.iter().all(|v| *v == if inverted { 1.0 } else { 0.0 }), \"inverted {inverted}\");\n s.execute(\"path.mergeShapeComponents\", json!({\"name\": \"layer\", \"layer\": id})).unwrap();\n assert!(mask(&s).path.is_empty());\n assert_eq!(shown(&s), before, \"inverted {inverted}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "set_operation_changes_existing_components",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked set_operation_changes_existing_components -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let hole = json!({\"subpaths\": [{\"closed\": true, \"knots\": [[25, 25], [45, 25], [45, 45], [25, 45]]}]});\n s.execute(\"path.set\", json!({\"path\": square()})).unwrap();\n s.execute(\"path.set\", json!({\"path\": hole, \"op\": \"combine\"})).unwrap();\n assert_eq!(covered(&work(&s), 35, 35), 1.0);\n s.execute(\"path.setOperation\", json!({\"subpaths\": [1], \"op\": \"subtract\"})).unwrap();\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Path Operation\"));\n assert_eq!(covered(&work(&s), 35, 35), 0.0);\n assert_eq!(work(&s).subpaths[1].op, PathOp::Subtract);\n assert!(s.undo());\n assert_eq!(work(&s).subpaths[1].op, PathOp::Combine);\n",
|
|
"expected_assertions": [
|
|
" assert_eq!(covered(&work(&s), 35, 35), 1.0);\n s.execute(\"path.setOperation\", json!({\"subpaths\": [1], \"op\": \"subtract\"})).unwrap();\n assert_eq!(s.active().unwrap().history.undo_label(), Some(\"Path Operation\"));\n assert_eq!(covered(&work(&s), 35, 35), 0.0);\n assert_eq!(work(&s).subpaths[1].op, PathOp::Subtract);\n assert!(s.undo());\n assert_eq!(work(&s).subpaths[1].op, PathOp::Combine);\n\n let id = s.execute(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [10, 10, 50, 50], \"fill\": \"#ff0000\"})).unwrap()[\"layer\"].as_u64().unwrap();\n s.execute(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [25, 25, 20, 20], \"addTo\": id, \"op\": \"combine\"})).unwrap();\n assert_eq!(covered(path, 35, 35), 0.0);\n assert!(cache.is_some());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "set_operation_on_a_joined_subpath_changes_its_component",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked set_operation_on_a_joined_subpath_changes_its_component -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let mut p = square();\n let subs = p[\"subpaths\"].as_array_mut().unwrap();\n subs.push(json!({\"closed\": true, \"op\": \"combine\", \"knots\": [[70, 10], [110, 10], [110, 50], [70, 50]]}));\n subs.push(json!({\"closed\": true, \"op\": \"join\", \"knots\": [[80, 20], [80, 40], [100, 40], [100, 20]]}));\n s.execute(\"path.set\", json!({\"path\": p})).unwrap();\n s.execute(\"path.setOperation\", json!({\"subpaths\": [2], \"op\": \"exclude\"})).unwrap();\n let ops: Vec<_> = work(&s).subpaths.iter().map(|sp| sp.op).collect();\n assert_eq!(ops, [PathOp::Combine, PathOp::Exclude, PathOp::Join]);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(ops, [PathOp::Combine, PathOp::Exclude, PathOp::Join]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "set_operation_leaves_the_first_component_combining",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked set_operation_leaves_the_first_component_combining -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let hole = json!({\"subpaths\": [{\"closed\": true, \"knots\": [[25, 25], [45, 25], [45, 45], [25, 45]]}]});\n s.execute(\"path.set\", json!({\"path\": square()})).unwrap();\n s.execute(\"path.set\", json!({\"path\": hole, \"op\": \"combine\"})).unwrap();\n let steps = s.active().unwrap().history.entries().len();\n let e = s.execute(\"path.setOperation\", json!({\"subpaths\": [0], \"op\": \"subtract\"})).unwrap_err().to_string();\n assert!(e.contains(\"first component\"), \"{e}\");\n assert_eq!(s.active().unwrap().history.entries().len(), steps);\n s.execute(\"path.setOperation\", json!({\"subpaths\": [0, 1], \"op\": \"subtract\"})).unwrap();\n let ops: Vec<_> = work(&s).subpaths.iter().map(|sp| sp.op).collect();\n assert_eq!(ops, [PathOp::Combine, PathOp::Subtract]);\n assert_eq!((covered(&work(&s), 35, 35), covered(&work(&s), 15, 15)), (0.0, 1.0));",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(\"first component\"), \"{e}\");\n assert_eq!(s.active().unwrap().history.entries().len(), steps);\n s.execute(\"path.setOperation\", json!({\"subpaths\": [0, 1], \"op\": \"subtract\"})).unwrap();\n let ops: Vec<_> = work(&s).subpaths.iter().map(|sp| sp.op).collect();\n assert_eq!(ops, [PathOp::Combine, PathOp::Subtract]);\n assert_eq!((covered(&work(&s), 35, 35), covered(&work(&s), 15, 15)), (0.0, 1.0));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "bad_set_operation_params_change_nothing",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked bad_set_operation_params_change_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n s.execute(\"path.set\", json!({\"path\": square()})).unwrap();\n let steps = s.active().unwrap().history.entries().len();\n for (p, msg) in [\n (json!({\"subpaths\": [0]}), \"`op`\"),\n (json!({\"subpaths\": [0], \"op\": \"join\"}), \"`op`\"),\n (json!({\"subpaths\": [0], \"op\": 3}), \"`op`\"),\n (json!({\"op\": \"subtract\"}), \"`subpaths`\"),\n (json!({\"subpaths\": [], \"op\": \"subtract\"}), \"`subpaths`\"),\n (json!({\"subpaths\": [-1], \"op\": \"subtract\"}), \"index\"),\n (json!({\"subpaths\": [7], \"op\": \"subtract\"}), \"no subpath 7\"),\n (json!({\"subpaths\": [0], \"op\": \"subtract\", \"name\": \"Nope\"}), \"\"),",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(msg), \"{p}: {e}\");\n }\n assert_eq!(s.active().unwrap().history.entries().len(), steps);\n assert_eq!(work(&s).subpaths[0].op, PathOp::Combine);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "bad_merge_params_change_nothing",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked bad_merge_params_change_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n s.execute(\"path.set\", json!({\"path\": square()})).unwrap();\n let hole = json!({\"subpaths\": [{\"closed\": true, \"knots\": [[25, 25], [45, 25], [45, 45], [25, 45]]}]});\n s.execute(\"path.set\", json!({\"path\": hole, \"op\": \"subtract\"})).unwrap();\n let id = s.active().unwrap().active_layer.unwrap().0;\n s.execute(\"layer.vectorMask.add\", json!({\"layer\": id, \"path\": square()})).unwrap();\n let state = |s: &Session| {\n let d = s.active().unwrap();\n (d.doc.work_path.clone(), d.doc.paths.clone(), d.doc.layer(LayerId(id)).unwrap().vector_mask.clone(), d.history.entries().len())\n };\n let before = state(&s);\n for (p, msg) in [",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(msg), \"{p}: {e}\");\n assert!(state(&s) == before, \"{p}: nothing changed\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merge_refuses_open_subpaths",
|
|
"path": "crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merge_refuses_open_subpaths -- --nocapture",
|
|
"fixture_and_action_excerpt": " for open in [json!({\"closed\": false, \"knots\": [[10, 10], [60, 60]]}), json!({\"closed\": false, \"knots\": [[70, 70]]})] {\n let mut s = session();\n let mut mixed = square();\n mixed[\"subpaths\"].as_array_mut().unwrap().push(open);\n s.execute(\"path.set\", json!({\"path\": mixed})).unwrap();\n let id = s.execute(\"shape.create\", json!({\"kind\": \"rect\", \"rect\": [10, 10, 50, 50]})).unwrap()[\"layer\"].as_u64().unwrap();\n s.execute(\"shape.edit\", json!({\"layer\": id, \"path\": mixed})).unwrap();\n let state = |s: &Session| {\n let d = s.active().unwrap();\n let photocraft_doc::LayerContent::Shape(sh) = &d.doc.layer(LayerId(id)).unwrap().content else { panic!(\"shape\") };\n (d.doc.work_path.clone(), sh.path.clone(), d.history.entries().len())\n };",
|
|
"expected_assertions": [
|
|
" assert!(e.contains(\"open subpaths\"), \"{cmd} {p}: {e}\");\n assert!(state(&s) == before, \"{cmd} {p}: nothing changed\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/engine/src/cmd/path_edit_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "ui_set_drives_the_pen_path_operation",
|
|
"path": "crates/ui-egui/src/control/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked ui_set_drives_the_pen_path_operation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let ctx = egui::Context::default();\n assert_eq!(call(&mut app, &ctx, \"ui.set\", json!({\"tool\": \"pen\", \"penMode\": \"shape\", \"penPathOp\": \"subtract\"}))[\"ok\"], true);\n let o = &call(&mut app, &ctx, \"ui.inspect\", json!({}))[\"result\"][\"toolOptions\"];\n assert_eq!((o[\"vector_mode\"].clone(), o[\"pen_path_op\"].clone()), (json!(\"shape\"), json!(\"subtract\")));\n for bad in [json!({\"penPathOp\": \"melt\"}), json!({\"penPathOp\": 1}), json!({\"penMode\": \"pixels\"}), json!({\"penMode\": \"path\", \"penPathOp\": \"xor\"})] {\n assert_eq!(call(&mut app, &ctx, \"ui.set\", bad.clone())[\"ok\"], false, \"{bad}\");\n assert_eq!((app.ui.tool_options.vector_mode.as_str(), app.ui.tool_options.pen_path_op.as_str()), (\"shape\", \"subtract\"), \"{bad}: unchanged\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(call(&mut app, &ctx, \"ui.set\", json!({\"tool\": \"pen\", \"penMode\": \"shape\", \"penPathOp\": \"subtract\"}))[\"ok\"], true);\n let o = &call(&mut app, &ctx, \"ui.inspect\", json!({}))[\"result\"][\"toolOptions\"];\n assert_eq!((o[\"vector_mode\"].clone(), o[\"pen_path_op\"].clone()), (json!(\"shape\"), json!(\"subtract\")));\n for bad in [json!({\"penPathOp\": \"melt\"}), json!({\"penPathOp\": 1}), json!({\"penMode\": \"pixels\"}), json!({\"penMode\": \"path\", \"penPathOp\": \"xor\"})] {\n assert_eq!(call(&mut app, &ctx, \"ui.set\", bad.clone())[\"ok\"], false, \"{bad}\");\n assert_eq!((app.ui.tool_options.vector_mode.as_str(), app.ui.tool_options.pen_path_op.as_str()), (\"shape\", \"subtract\"), \"{bad}: unchanged\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/control/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_selected_component_takes_the_picked_operation",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_selected_component_takes_the_picked_operation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 20.0, 20.0, 120.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n square(&mut app, 60.0, 60.0, 40.0);\n let (id, sh) = shape(&app);\n assert_eq!(covered(&sh.path, 80, 80), 1.0);\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [80.0, 80.0], false);\n let (r, _, heads) = super::selected(&app).expect(\"the inner square is selected\");\n assert_eq!((r, heads), (PathRef::Layer(id.0), vec![1]));\n let steps = history(&app);\n super::set_op(&mut app, \"subtract\").unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(covered(&sh.path, 80, 80), 1.0);\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [80.0, 80.0], false);\n let (r, _, heads) = super::selected(&app).expect(\"the inner square is selected\");\n assert_eq!((r, heads), (PathRef::Layer(id.0), vec![1]));\n let steps = history(&app);\n super::set_op(&mut app, \"subtract\").unwrap();\n let (_, sh) = shape(&app);\n assert_eq!(ops(&sh.path), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!((covered(&sh.path, 80, 80), covered(&sh.path, 30, 30)), (0.0, 1.0), \"a hole\");\n assert_eq!(history(&app), steps + 1);\n assert_eq!(super::selected_op(&app), Some(\"subtract\"), \"the menu shows the component's\");\n // Picking what it already has adds no step; New Layer only sets the tool.\n super::set_op(&mut app, \"subtract\").unwrap();\n super::set_op(&mut app, \"newLayer\").unwrap();\n assert_eq!(history(&app), steps + 1);\n assert!(app.session.undo());\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine]);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "plus_and_minus_pick_combine_and_subtract",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked plus_and_minus_pick_combine_and_subtract -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let mut app = app();\n square(&mut app, 20.0, 20.0, 120.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n square(&mut app, 60.0, 60.0, 40.0);\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [80.0, 80.0], false);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!(app.ui.tool_options.pen_path_op, \"subtract\");\n key(&mut app, &ctx, Key::Equals, egui::Modifiers::SHIFT);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine]);",
|
|
"expected_assertions": [
|
|
" assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!(app.ui.tool_options.pen_path_op, \"subtract\");\n key(&mut app, &ctx, Key::Equals, egui::Modifiers::SHIFT);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine]);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n key(&mut app, &ctx, Key::Plus, egui::Modifiers::NONE);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine], \"the keypad's +\");\n // With nothing selected the Pen's next path takes it.\n app.ui.direct_selection = Default::default();\n app.ui.tool = Tool::Pen;\n assert_eq!(app.ui.tool_options.pen_path_op, \"subtract\");\n // The blend mode is the Move tool's to step.\n let blend = |app: &PhotocraftApp| app.session.active().unwrap().doc.layer(shape(app).0).unwrap().blend;\n let before = blend(&app);\n assert_eq!(blend(&app), before, \"the Pen picks Combine, not a blend mode\");\n assert_eq!(app.ui.tool_options.pen_path_op, \"combine\");\n app.ui.tool = Tool::Move;\n key(&mut app, &ctx, Key::Equals, egui::Modifiers::SHIFT);\n assert_ne!(blend(&app), before);\n assert_eq!(app.ui.tool_options.pen_path_op, \"combine\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "path_selection_selects_and_moves_components",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked path_selection_selects_and_moves_components -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 10.0, 10.0, 40.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n square(&mut app, 100.0, 10.0, 40.0);\n square(&mut app, 100.0, 100.0, 40.0);\n app.ui.tool = Tool::PathSelection;\n let heads = |app: &PhotocraftApp| super::selected(app).map(|(.., h)| h).unwrap_or_default();\n super::press(&mut app, [30.0, 30.0], false);\n super::press(&mut app, [120.0, 120.0], true);\n assert_eq!(heads(&app), [0, 2]);\n // Pressing a selected one keeps both, for the drag.\n super::press(&mut app, [120.0, 120.0], false);",
|
|
"expected_assertions": [
|
|
" assert_eq!(heads(&app), [0, 2]);\n // Pressing a selected one keeps both, for the drag.\n super::press(&mut app, [120.0, 120.0], false);\n assert_eq!(heads(&app), [0, 2]);\n crate::vector_ui::path_selection_finish(&mut app, [120.0, 120.0], [125.0, 130.0]);\n let (_, sh) = shape(&app);\n let first = |s: usize| sh.path.subpaths[s].knots[0].anchor;\n assert_eq!((first(0).x, first(0).y), (15.0, 20.0));\n assert_eq!((first(1).x, first(1).y), (100.0, 10.0), \"not selected: stays\");\n assert_eq!((first(2).x, first(2).y), (105.0, 110.0));\n super::press(&mut app, [125.0, 130.0], true);\n assert_eq!(heads(&app), [0]);\n super::press(&mut app, [190.0, 190.0], false);\n assert!(super::selected(&app).is_none(), \"a click off every component deselects\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_stale_selection_changes_nothing",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_stale_selection_changes_nothing -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 10.0, 10.0, 40.0);\n let (id, _) = shape(&app);\n app.ui.tool = Tool::PathSelection;\n app.ui.direct_selection = crate::direct_select::DirectSelection { target: Some(PathRef::Layer(id.0)), anchors: vec![[5, 0]], ..Default::default() };\n assert!(super::selected(&app).is_none());\n let steps = history(&app);\n super::set_op(&mut app, \"subtract\").unwrap();\n assert_eq!(history(&app), steps);\n assert_eq!(super::move_selected(&mut app, [3.0, 3.0]), None);\n}",
|
|
"expected_assertions": [
|
|
" assert!(super::selected(&app).is_none());\n let steps = history(&app);\n super::set_op(&mut app, \"subtract\").unwrap();\n assert_eq!(history(&app), steps);\n assert_eq!(super::move_selected(&mut app, [3.0, 3.0]), None);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_first_component_keeps_combining",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_first_component_keeps_combining -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let mut app = app();\n square(&mut app, 20.0, 20.0, 120.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n square(&mut app, 60.0, 60.0, 40.0);\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [30.0, 30.0], false);\n assert_eq!(super::selected(&app).map(|(.., h)| h), Some(vec![0]));\n let steps = history(&app);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n super::set_op(&mut app, \"intersect\").unwrap();\n assert_eq!(history(&app), steps, \"no step\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(super::selected(&app).map(|(.., h)| h), Some(vec![0]));\n let steps = history(&app);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n super::set_op(&mut app, \"intersect\").unwrap();\n assert_eq!(history(&app), steps, \"no step\");\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine]);\n assert_eq!(super::selected_op(&app), Some(\"combine\"), \"the menu shows what it draws as\");\n super::press(&mut app, [80.0, 80.0], true);\n super::set_op(&mut app, \"subtract\").unwrap();\n assert_eq!(history(&app), steps + 1);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!(super::selected_op(&app), None, \"they differ\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_pen_does_not_edit_a_hidden_component_selection",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_pen_does_not_edit_a_hidden_component_selection -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let mut app = app();\n square(&mut app, 20.0, 20.0, 120.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n square(&mut app, 60.0, 60.0, 40.0);\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [80.0, 80.0], false);\n assert!(super::selected(&app).is_some());\n app.ui.tool = Tool::Pen;\n let steps = history(&app);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n assert_eq!(app.ui.tool_options.pen_path_op, \"subtract\", \"the next path's\");",
|
|
"expected_assertions": [
|
|
" assert!(super::selected(&app).is_some());\n app.ui.tool = Tool::Pen;\n let steps = history(&app);\n key(&mut app, &ctx, Key::Minus, egui::Modifiers::NONE);\n assert_eq!(app.ui.tool_options.pen_path_op, \"subtract\", \"the next path's\");\n assert_eq!(super::selected_op(&app), None);\n assert_eq!(history(&app), steps);\n assert_eq!(ops(&shape(&app).1.path), [PathOp::Combine, PathOp::Combine]);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dragging_a_live_shape_keeps_it_live",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_a_live_shape_keeps_it_live -- --nocapture",
|
|
"fixture_and_action_excerpt": " for kind in [\"rect\", \"ellipse\"] {\n let mut app = app();\n app.run(\"shape.create\", json!({\"kind\": kind, \"rect\": [20, 20, 60, 40], \"fill\": \"#ff0000\"})).unwrap();\n assert!(shape(&app).1.live.is_some(), \"{kind}\");\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [50.0, 40.0], false);\n assert_eq!(super::selected(&app).map(|(.., h)| h), Some(vec![0]), \"{kind}\");\n let steps = history(&app);\n crate::vector_ui::path_selection_finish(&mut app, [50.0, 40.0], [60.0, 45.0]);\n let (_, sh) = shape(&app);\n assert_eq!(history(&app), steps + 1, \"{kind}\");\n let (x0, y0, ..) = sh.path.control_bounds().unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(shape(&app).1.live.is_some(), \"{kind}\");\n app.ui.tool = Tool::PathSelection;\n super::press(&mut app, [50.0, 40.0], false);\n assert_eq!(super::selected(&app).map(|(.., h)| h), Some(vec![0]), \"{kind}\");\n let steps = history(&app);\n crate::vector_ui::path_selection_finish(&mut app, [50.0, 40.0], [60.0, 45.0]);\n let (_, sh) = shape(&app);\n assert_eq!(history(&app), steps + 1, \"{kind}\");\n let (x0, y0, ..) = sh.path.control_bounds().unwrap();\n assert_eq!((x0.round(), y0.round()), (30.0, 25.0), \"{kind}: moved\");\n match sh.live {\n Some(photocraft_doc::vector::LiveShape::Rect { rect, .. } | photocraft_doc::vector::LiveShape::Ellipse { rect }) => {\n assert_eq!(rect, [30.0, 25.0, 60.0, 40.0], \"{kind}\")\n }\n other => panic!(\"{kind}: still live, got {other:?}\"),\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_pen_carries_on_an_open_shape_path",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_pen_carries_on_an_open_shape_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool_options.shape_fill = true;\n app.ui.tool_options.stroke_width = 0.0;\n for (x, y) in [(20.0, 20.0), (120.0, 20.0), (120.0, 120.0)] {\n click(&mut app, x, y);\n }\n assert!(pen_commit(&mut app, false));\n let (id, sh) = shape(&app);\n assert!(sh.fill.is_none() && sh.stroke.is_some(), \"an open path is stroked\");\n let count = app.session.active().unwrap().doc.layers.len();\n let steps = history(&app);\n click(&mut app, 120.0, 120.0); // its last anchor: carry on",
|
|
"expected_assertions": [
|
|
" assert!(pen_commit(&mut app, false));\n let (id, sh) = shape(&app);\n assert!(sh.fill.is_none() && sh.stroke.is_some(), \"an open path is stroked\");\n let count = app.session.active().unwrap().doc.layers.len();\n let steps = history(&app);\n click(&mut app, 120.0, 120.0); // its last anchor: carry on\n assert!(app.ui.pen.is_none(), \"closing commits\");\n let (same, sh) = shape(&app);\n assert_eq!((same, app.session.active().unwrap().doc.layers.len()), (id, count), \"no new layer\");\n assert_eq!(sh.path.subpaths.len(), 1);\n assert!(sh.path.subpaths[0].closed);\n assert_eq!(sh.path.subpaths[0].knots.len(), 4);\n assert!(sh.fill.is_some() && sh.stroke.is_none(), \"filled like a path drawn closed\");\n assert_eq!(history(&app), steps + 1);\n assert!(app.session.undo());\n assert!(!shape(&app).1.path.subpaths[0].closed);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_open_component_of_a_filled_shape_keeps_its_paint",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked an_open_component_of_a_filled_shape_keeps_its_paint -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 10.0, 10.0, 60.0);\n let (id, before) = shape(&app);\n // An open component added to the layer.\n app.ui.tool_options.pen_path_op = \"combine\".into();\n for (x, y) in [(100.0, 100.0), (150.0, 100.0)] {\n click(&mut app, x, y);\n }\n assert!(pen_commit(&mut app, false));\n app.ui.tool_options.shape_fill = false;\n click(&mut app, 100.0, 100.0); // its first anchor\n click(&mut app, 100.0, 150.0);",
|
|
"expected_assertions": [
|
|
" assert!(pen_commit(&mut app, false));\n app.ui.tool_options.shape_fill = false;\n click(&mut app, 100.0, 100.0); // its first anchor\n click(&mut app, 100.0, 150.0);\n assert!(pen_commit(&mut app, false));\n let (same, sh) = shape(&app);\n assert_eq!(same, id);\n assert_eq!(sh.path.subpaths.len(), 2);\n assert_eq!(sh.path.subpaths[1].knots.len(), 3);\n assert_eq!((sh.fill, sh.stroke), (before.fill, before.stroke));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_pen_carries_on_a_vector_masks_open_subpath",
|
|
"path": "crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_pen_carries_on_a_vector_masks_open_subpath -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool_options.vector_mode = \"path\".into();\n app.run(\"layer.new.layer\", json!({})).unwrap();\n let id = app.session.active().unwrap().active_layer.unwrap().0;\n let open = json!({\"subpaths\": [{\"closed\": false, \"knots\": [[20, 20], [120, 20]]}]});\n app.run(\"layer.vectorMask.add\", json!({\"layer\": id, \"path\": open})).unwrap();\n app.ui.vector_mask_target = true;\n click(&mut app, 120.0, 20.0);\n click(&mut app, 120.0, 120.0);\n assert!(pen_commit(&mut app, false));\n let st = app.session.active().unwrap();\n let mask = st.doc.layer(LayerId(id)).unwrap().vector_mask.clone().unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(pen_commit(&mut app, false));\n let st = app.session.active().unwrap();\n let mask = st.doc.layer(LayerId(id)).unwrap().vector_mask.clone().unwrap();\n assert_eq!(mask.path.subpaths.len(), 1);\n assert_eq!(mask.path.subpaths[0].knots.len(), 3);\n assert!(st.doc.work_path.is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/path_components/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "subtract_front_shape_cuts_a_hole_in_the_selected_shape_layer",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked subtract_front_shape_cuts_a_hole_in_the_selected_shape_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool_options.vector_mode = \"shape\".into();\n assert_eq!(app.ui.tool_options.pen_path_op, \"newLayer\", \"Photoshop's default in Shape mode\");\n square(&mut app, 20.0, 20.0, 100.0);\n let (id, _) = shape_path(&app);\n let count = layers(&app);\n app.ui.tool_options.pen_path_op = \"subtract\".into();\n square(&mut app, 50.0, 50.0, 40.0);\n let (same, path) = shape_path(&app);\n assert_eq!((same, layers(&app)), (id, count), \"no new layer\");\n assert_eq!(path.subpaths.iter().map(|s| s.op).collect::<Vec<_>>(), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!((covered(&path, 70, 70), covered(&path, 30, 30)), (0.0, 1.0), \"a hole in the body\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.tool_options.pen_path_op, \"newLayer\", \"Photoshop's default in Shape mode\");\n square(&mut app, 20.0, 20.0, 100.0);\n let (id, _) = shape_path(&app);\n let count = layers(&app);\n assert_eq!((same, layers(&app)), (id, count), \"no new layer\");\n assert_eq!(path.subpaths.iter().map(|s| s.op).collect::<Vec<_>>(), [PathOp::Combine, PathOp::Subtract]);\n assert_eq!((covered(&path, 70, 70), covered(&path, 30, 30)), (0.0, 1.0), \"a hole in the body\");\n app.session.undo();\n assert_eq!(shape_path(&app).1.subpaths.len(), 1, \"undo takes back only the hole\");\n app.session.redo();\n // Intersect and Exclude are stored the same way.\n for (op, want) in [(\"intersect\", PathOp::Intersect), (\"exclude\", PathOp::Exclude), (\"combine\", PathOp::Combine)] {\n assert_eq!(shape_path(&app).1.subpaths.last().map(|s| s.op), Some(want), \"{op}\");\n }\n assert_eq!(layers(&app), count);\n // New Layer makes another shape layer again.\n app.ui.tool_options.pen_path_op = \"newLayer\".into();\n square(&mut app, 10.0, 10.0, 30.0);\n assert_eq!(layers(&app), count + 1);\n assert_ne!(shape_path(&app).0, id);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_locked_shape_layer_keeps_the_drawn_path",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked a_locked_shape_layer_keeps_the_drawn_path -- --nocapture",
|
|
"fixture_and_action_excerpt": " for lock in [\"all\", \"pixels\"] {\n let mut app = app();\n app.ui.tool_options.vector_mode = \"shape\".into();\n square(&mut app, 20.0, 20.0, 100.0);\n let (id, body) = shape_path(&app);\n app.run(\"layer.lockLayers\", json!({lock: true})).unwrap();\n let steps = app.session.active().unwrap().history.past_len();\n app.ui.tool_options.pen_path_op = \"subtract\".into();\n square(&mut app, 50.0, 50.0, 40.0);\n let draft = app.ui.pen.clone().unwrap_or_else(|| panic!(\"{lock}: the draft is kept\"));\n // The four corners and the close's stand-in on the first: still a closed path.\n assert!(draft.knots.len() == 5 && super::closing(&draft), \"{lock}: {:?}\", draft.knots);",
|
|
"expected_assertions": [
|
|
" assert!(draft.knots.len() == 5 && super::closing(&draft), \"{lock}: {:?}\", draft.knots);\n assert!(app.ui.status_error, \"{lock}: {}\", app.ui.status);\n assert_eq!(shape_path(&app), (id, body.clone()), \"{lock}: the shape is unchanged\");\n assert_eq!(app.session.active().unwrap().history.past_len(), steps, \"{lock}: no History step\");\n // Undo takes back the lock, not the drawn path.\n app.session.undo();\n assert!(app.ui.pen.is_some(), \"{lock}\");\n assert!(super::pen_commit(&mut app, false), \"{lock}: {}\", app.ui.status); // \u21a9\n assert!(app.ui.pen.is_none(), \"{lock}\");\n let (same, path) = shape_path(&app);\n assert_eq!(same, id, \"{lock}\");\n assert_eq!(path.subpaths.iter().map(|s| (s.op, s.closed)).collect::<Vec<_>>(), [(PathOp::Combine, true), (PathOp::Subtract, true)], \"{lock}\");\n assert_eq!(covered(&path, 70, 70), 0.0, \"{lock}: the hole\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "switching_tools_ends_a_refused_draft_once",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked switching_tools_ends_a_refused_draft_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = egui_kittest::Harness::builder().with_size(vec2(1400.0, 900.0)).with_max_steps(64).build_eframe(|cc| {\n PhotocraftApp::setup_context(&cc.egui_ctx, Default::default());\n app()\n });\n h.run_steps(2);\n let (id, body, steps) = refused_hole(h.state_mut());\n h.state_mut().ui.tool = Tool::Brush;\n h.run_steps(2);\n assert_kept_as_work_path(h.state(), id, &body, steps);\n let status = h.state().ui.status.clone();\n h.run_steps(4);\n assert_eq!(h.state().ui.status, status, \"no retry\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().ui.status, status, \"no retry\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), steps + 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "esc_ends_a_refused_draft_and_return_keeps_it",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked esc_ends_a_refused_draft_and_return_keeps_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let key = |app: &mut PhotocraftApp, key: egui::Key| {\n let raw = egui::RawInput {\n events: vec![egui::Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: egui::Modifiers::NONE }],\n ..Default::default()\n };\n ctx.begin_pass(raw);\n crate::shortcuts::handle(app, &ctx);\n ctx.end_pass().textures_delta.clear();\n };\n for lang in crate::i18n::Lang::all() {\n crate::i18n::with_language(lang, || {",
|
|
"expected_assertions": [
|
|
" assert!(crate::i18n::has(lang, message), \"{}: {message}\", lang.code());\n }\n }\n let mut app = app();\n assert_eq!(app.ui.pen, draft, \"\u21a9 keeps the draft\");\n assert_eq!(app.session.active().unwrap().history.past_len(), steps);\n let refused = app.ui.status.clone();\n key(&mut app, egui::Key::Escape);\n assert_kept_as_work_path(&app, id, &body, steps);\n assert_eq!(app.ui.status, format!(\"{refused} ({})\", tl!(\"The path was kept as the Work Path\")));\n });\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_operation_without_a_selected_shape_starts_a_new_shape_layer",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked an_operation_without_a_selected_shape_starts_a_new_shape_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool_options.vector_mode = \"shape\".into();\n app.ui.tool_options.pen_path_op = \"subtract\".into();\n let count = layers(&app);\n square(&mut app, 20.0, 20.0, 100.0);\n let (id, path) = shape_path(&app);\n assert_eq!((layers(&app), path.subpaths.len()), (count + 1, 1));\n assert_eq!(covered(&path, 60, 60), 1.0, \"a lone first component draws\");\n square(&mut app, 50.0, 50.0, 40.0);\n assert_eq!((shape_path(&app).0, layers(&app)), (id, count + 1));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!((layers(&app), path.subpaths.len()), (count + 1, 1));\n assert_eq!(covered(&path, 60, 60), 1.0, \"a lone first component draws\");\n square(&mut app, 50.0, 50.0, 40.0);\n assert_eq!((shape_path(&app).0, layers(&app)), (id, count + 1));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "path_mode_adds_subpaths_with_the_operation",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked path_mode_adds_subpaths_with_the_operation -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n assert_eq!(pen_path_op(&app.ui.tool_options), Some(\"combine\"));\n square(&mut app, 20.0, 20.0, 100.0);\n square(&mut app, 30.0, 30.0, 10.0);\n app.ui.tool_options.pen_path_op = \"intersect\".into();\n square(&mut app, 50.0, 50.0, 100.0);\n assert_eq!(work(&app).subpaths.iter().map(|s| s.op).collect::<Vec<_>>(), [PathOp::Combine, PathOp::Combine, PathOp::Intersect]);\n // A selected saved path.\n app.run(\"path.set\", json!({\"name\": \"Saved\", \"path\": {\"subpaths\": [{\"closed\": true, \"knots\": [[2, 2], [60, 2], [60, 60]]}]}})).unwrap();\n app.ui.selected_path = Some(\"Saved\".into());\n app.ui.tool_options.pen_path_op = \"exclude\".into();\n square(&mut app, 10.0, 10.0, 20.0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(pen_path_op(&app.ui.tool_options), Some(\"combine\"));\n square(&mut app, 20.0, 20.0, 100.0);\n square(&mut app, 30.0, 30.0, 10.0);\n app.ui.tool_options.pen_path_op = \"intersect\".into();\n assert_eq!(work(&app).subpaths.iter().map(|s| s.op).collect::<Vec<_>>(), [PathOp::Combine, PathOp::Combine, PathOp::Intersect]);\n // A selected saved path.\n app.run(\"path.set\", json!({\"name\": \"Saved\", \"path\": {\"subpaths\": [{\"closed\": true, \"knots\": [[2, 2], [60, 2], [60, 60]]}]}})).unwrap();\n app.ui.selected_path = Some(\"Saved\".into());\n assert_eq!(saved.subpaths.last().map(|s| s.op), Some(PathOp::Exclude));\n // A targeted vector mask.\n let id = app.session.active().unwrap().active_layer.unwrap().0;\n app.run(\"layer.vectorMask.add\", json!({\"layer\": id, \"path\": {\"subpaths\": [{\"closed\": true, \"knots\": [[0, 0], [100, 0], [100, 100], [0, 100]]}]}})).unwrap();\n assert_eq!(vm.path.subpaths.iter().map(|s| s.op).collect::<Vec<_>>(), [PathOp::Combine, PathOp::Subtract]);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_options_bar_menu_sets_the_operation_and_merges",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_options_bar_menu_sets_the_operation_and_merges -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 20.0, 20.0, 100.0);\n app.ui.tool_options.pen_path_op = \"subtract\".into();\n square(&mut app, 50.0, 50.0, 40.0);\n app.ui.tool_options.pen_path_op = \"combine\".into();\n let mut h = egui_kittest::Harness::builder().with_size(vec2(1100.0, 400.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n if ui.ctx().fonts(|f| f.families().contains(&egui::FontFamily::Name(\"medium\".into()))) {\n ui.horizontal(|ui| super::options_bar(app, ui, Tool::Pen));\n }\n },\n app,",
|
|
"expected_assertions": [
|
|
" assert!(h.get_by_label(\"New Layer\").accesskit_node().is_disabled(), \"Path mode has no New Layer\");\n h.get_by_label(\"Exclude Overlapping Shapes\").click();\n h.run_steps(3);\n assert_eq!(h.state().ui.tool_options.pen_path_op, \"exclude\");\n assert!(h.query_by_label(\"Exclude Overlapping Shapes\").is_none(), \"choosing closes the menu\");\n // Merge Shape Components: the Work Path's hole stays a hole, now as plain outlines.\n let before = work(h.state());\n open(&mut h);\n assert_ne!(merged, before);\n assert_eq!((covered(&merged, 70, 70), covered(&merged, 30, 30)), (0.0, 1.0));\n // Shape mode offers New Layer.\n h.state_mut().ui.tool_options.vector_mode = \"shape\".into();\n h.run_steps(2);\n assert!(!h.get_by_label(\"New Layer\").accesskit_node().is_disabled());\n h.get_by_label(\"New Layer\").click();\n h.run_steps(3);\n assert_eq!(pen_path_op(&h.state().ui.tool_options), None);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merge_is_disabled_with_fewer_than_two_components",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked merge_is_disabled_with_fewer_than_two_components -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n square(&mut app, 20.0, 20.0, 100.0);\n let mut h = egui_kittest::Harness::builder().with_size(vec2(1100.0, 400.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n if ui.ctx().fonts(|f| f.families().contains(&egui::FontFamily::Name(\"medium\".into()))) {\n ui.horizontal(|ui| super::options_bar(app, ui, Tool::Pen));\n }\n },\n app,\n );\n PhotocraftApp::setup_context(&h.ctx, crate::theme::ThemeKind::Studio);\n h.run_steps(4);",
|
|
"expected_assertions": [
|
|
" assert!(h.get_by_label(\"Merge Shape Components\").accesskit_node().is_disabled());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_unknown_operation_falls_back_to_new_layer",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked an_unknown_operation_falls_back_to_new_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n app.ui.tool_options.pen_path_op = \"melt\".into();\n assert_eq!(pen_path_op(&app.ui.tool_options), Some(\"combine\"));\n app.ui.tool_options.vector_mode = \"shape\".into();\n assert_eq!(pen_path_op(&app.ui.tool_options), None);\n let count = layers(&app);\n square(&mut app, 20.0, 20.0, 50.0);\n square(&mut app, 30.0, 30.0, 50.0);\n assert_eq!(layers(&app), count + 2);\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(pen_path_op(&app.ui.tool_options), Some(\"combine\"));\n app.ui.tool_options.vector_mode = \"shape\".into();\n assert_eq!(pen_path_op(&app.ui.tool_options), None);\n let count = layers(&app);\n square(&mut app, 20.0, 20.0, 50.0);\n square(&mut app, 30.0, 30.0, 50.0);\n assert_eq!(layers(&app), count + 2);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "freeform_refuses_a_locked_shape_before_starting_a_stroke",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked freeform_refuses_a_locked_shape_before_starting_a_stroke -- --nocapture",
|
|
"fixture_and_action_excerpt": " use crate::canvas::{ToolEvent, tool_event};\n for lock in [\"all\", \"pixels\"] {\n let mut app = app();\n app.ui.tool_options.vector_mode = \"shape\".into();\n square(&mut app, 20.0, 20.0, 100.0);\n let (id, body) = shape_path(&app);\n app.run(\"layer.lockLayers\", json!({lock: true})).unwrap();\n let steps = app.session.active().unwrap().history.past_len();\n app.ui.tool = Tool::FreeformPen;\n app.ui.tool_options.pen_path_op = \"subtract\".into();\n tool_event(&mut app, ToolEvent::Down { x: 50.0, y: 50.0, pressure: 1.0 }, egui::Modifiers::NONE);\n assert!(app.drag.is_none(), \"{lock}: stroke was not started\");",
|
|
"expected_assertions": [
|
|
" assert!(app.drag.is_none(), \"{lock}: stroke was not started\");\n assert!(app.ui.status_error, \"{lock}\");\n assert_eq!(shape_path(&app), (id, body), \"{lock}\");\n assert_eq!(app.session.active().unwrap().history.past_len(), steps, \"{lock}\");\n app.session.undo();\n tool_event(&mut app, ToolEvent::Down { x: 50.0, y: 50.0, pressure: 1.0 }, egui::Modifiers::NONE);\n assert!(app.drag.is_some(), \"{lock}: unlocked stroke can start\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/pen_path_ops_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "failed_stale_pen_commit_preserves_the_draft_until_retry",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked failed_stale_pen_commit_preserves_the_draft_until_retry -- --nocapture",
|
|
"fixture_and_action_excerpt": " for action in [\"pen\", \"curvature\", \"undo\", \"commit\", \"command\"] {\n let mut app = app();\n app.run(\"path.set\", json!({\"name\": \"work\", \"path\": {\"subpaths\": [{\"closed\": false, \"knots\": [[5, 5], [10, 10]]}]}})).unwrap();\n let original = app.session.active().unwrap().doc.work_path.clone().unwrap();\n app.ui.tool = Tool::Pen;\n for (x, y) in [(20.0, 20.0), (80.0, 60.0)] {\n pen_down(&mut app, x, y, false);\n pen_up(&mut app);\n }\n let draft = app.ui.pen.clone();\n let owner = app.ui.pen_doc;\n app.session.execute(\"file.new\", json!({\"width\": 200, \"height\": 200})).unwrap();",
|
|
"expected_assertions": [
|
|
" \"undo\" => assert!(!pen_undo_last_point(&mut app)),\n \"commit\" => {\n pen_commit(&mut app, true);\n }\n assert!(app.run(\"file.close\", json!({})).is_err());\n }\n }\n assert_eq!(app.ui.pen, draft, \"{action}: failed save retains all anchors\");\n assert_eq!(app.ui.pen_doc, owner);\n assert_eq!(app.session.active_index(), Some(1));\n assert_eq!(app.session.documents()[0].doc.work_path.as_ref(), Some(&original));\n assert!(app.session.documents()[1].doc.work_path.is_none());\n assert!(app.ui.status_error);\n assert!(!crate::direct_select::candidates(&app).iter().any(|(target, _)| *target == crate::direct_select::PathRef::Pen));\n app.session.authorize = None;\n app.sync_views();\n assert!(app.ui.pen.is_none());\n assert_eq!(app.session.active_index(), Some(1));\n assert_eq!(app.ui.selected_path.as_deref(), Some(\"foreign named path\"));\n let saved = app.session.documents()[0].doc.work_path.clone().unwrap();\n assert_eq!(saved.subpaths.len(), original.subpaths.len() + 1);\n assert_eq!(saved.subpaths[0], original.subpaths[0]);\n app.sync_views();\n assert_eq!(app.session.documents()[0].doc.work_path.as_ref(), Some(&saved), \"retry never duplicates the path\");\n assert!(app.session.set_active(0));\n assert!(app.session.undo());\n assert_eq!(app.session.active().unwrap().doc.work_path.as_ref(), Some(&original));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stale_pen_commits_to_its_owner_across_document_changes",
|
|
"path": "crates/ui-egui/src/tools/vector_ui/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked stale_pen_commits_to_its_owner_across_document_changes -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_doc::{ColorMode, SampleType, Size};\n for tool in [Tool::Pen, Tool::CurvaturePen] {\n for action in [\"switch\", \"open\", \"closeOther\", \"pen\", \"curvature\", \"undo\", \"commit\"] {\n let mut app = app();\n app.run(\"file.new\", json!({\"width\": 200, \"height\": 200})).unwrap();\n app.ui.tool = tool;\n for (x, y) in [(20.0, 20.0), (80.0, 60.0), (120.0, 30.0)] {\n if tool == Tool::Pen {\n pen_down(&mut app, x, y, false);\n pen_up(&mut app);\n } else {\n curvature_down(&mut app, x, y);",
|
|
"expected_assertions": [
|
|
" assert!(app.session.set_active(0));\n match action {\n \"open\" => {\n app.services.import = Some(Box::new(|name, _, _| Ok((Document::new(name, Size::new(4, 4), ColorMode::Rgb, SampleType::U8), Vec::new()))));\n \"undo\" => assert!(!pen_undo_last_point(&mut app)),\n \"commit\" => {\n pen_commit(&mut app, true);\n }\n assert_eq!(path, &expected, \"{tool:?} {action}\");\n assert!(app.session.documents().iter().filter(|d| d.doc.id != owner).all(|d| d.doc.work_path.is_none()));\n if action != \"closeOther\" {\n assert_ne!(app.session.active().unwrap().doc.id, owner, \"the active document is restored\");\n }\n assert_eq!(app.ui.direct_selection, Default::default());\n let index = app.session.documents().iter().position(|d| d.doc.id == owner).unwrap();\n assert!(app.session.set_active(index));\n assert!(app.session.undo());\n assert!(app.session.active().unwrap().doc.work_path.is_none());\n assert!(app.session.redo());\n assert!(app.session.active().unwrap().doc.work_path.is_some());\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d24669d412f64ab079a668b0b8520ddbc607410c/crates/ui-egui/src/tools/vector_ui/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8074",
|
|
"pr": 8074,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked tool_options_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked interpolation_selection_is_reused_for_the_next_transform -- --nocapture"
|
|
],
|
|
"expected": "tool options survive a restart; interpolation selection is reused for the next transform",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked tool_options_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked interpolation_selection_is_reused_for_the_next_transform -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "tool_options_survive_a_restart",
|
|
"path": "crates/ui-egui/src/prefs_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked tool_options_survive_a_restart -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, store) = app_with_store();\n let ctx = egui::Context::default();\n tick(&mut app, &ctx);\n app.ui.tool_options.move_auto_select = false;\n app.ui.tool_options.feather = 12.0;\n app.ui.tool_options.transform_interpolation = Some(photocraft_engine::prefs::Interpolation::Nearest);\n crate::tool_memory::persist(&mut app, &ctx);\n tick(&mut app, &ctx);\n // Only what differs from the defaults is stored.\n assert_eq!(stored(&store)[\"toolOptions\"], json!({\"move_auto_select\": false, \"feather\": 12.0, \"transform_interpolation\": \"nearestNeighbor\"}));\n let saved = store.lock().unwrap().clone().unwrap();\n let (mut app2, _) = app_with_saved(Some(saved));",
|
|
"expected_assertions": [
|
|
" assert_eq!(stored(&store)[\"toolOptions\"], json!({\"move_auto_select\": false, \"feather\": 12.0, \"transform_interpolation\": \"nearestNeighbor\"}));\n let saved = store.lock().unwrap().clone().unwrap();\n let (mut app2, _) = app_with_saved(Some(saved));\n tick(&mut app2, &ctx);\n assert!(!app2.ui.tool_options.move_auto_select);\n assert_eq!(app2.ui.tool_options.feather, 12.0);\n assert_eq!(app2.ui.tool_options.transform_interpolation, Some(photocraft_engine::prefs::Interpolation::Nearest));\n assert_eq!(app2.ui.tool_options.tolerance, crate::state::ToolOptions::default().tolerance);\n // A hand-edited file: unreadable fields keep their defaults, the good ones still load.\n for bad in [json!(\"junk\"), json!({\"move_auto_select\": \"no\", \"feather\": 1e300, \"tolerance\": 5.0, \"unknown\": 1})] {\n let (mut app3, _) = app_with_saved(Some(json!({\"toolOptions\": bad}).to_string()));\n assert!(o.move_auto_select && o.feather == 0.0, \"{bad}\");\n assert_eq!(o.tolerance, if bad.is_object() { 5.0 } else { 32.0 });\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/290f924d0fecc3bf6bea159c0d9e86255d326a96/crates/ui-egui/src/prefs_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "interpolation_selection_is_reused_for_the_next_transform",
|
|
"path": "crates/ui-egui/src/transform_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked interpolation_selection_is_reused_for_the_next_transform -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui::accesskit::Role;\n use egui_kittest::{Harness, kittest::Queryable};\n\n let app = app_with_square(64, photocraft_geom::Rect::new(8, 8, 24, 24));\n let mut h = Harness::builder().with_size(vec2(2400.0, 360.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n if ui.ctx().fonts(|f| f.families().contains(&egui::FontFamily::Name(\"medium\".into()))) {\n ui.horizontal_centered(|ui| options_bar(app, ui));\n }\n },\n app,\n );",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.transform.is_some(), \"transform stays open while the bar renders\");\n\n h.get_by_role(Role::ComboBox).click();\n h.run();\n assert!(h.state().ui.transform.is_some(), \"opening interpolation dropdown keeps the transform open\");\n h.key_press(egui::Key::ArrowDown);\n h.run();\n assert!(h.state().ui.transform.is_some(), \"first interpolation step keeps the transform open\");\n h.key_press(egui::Key::ArrowDown);\n h.run();\n assert!(h.state().ui.transform.is_some(), \"second interpolation step keeps the transform open\");\n assert_eq!(h.state().ui.transform.as_ref().unwrap().interpolation, \"nearest\");\n assert_eq!(h.state().ui.tool_options.transform_interpolation, Some(photocraft_engine::prefs::Interpolation::Nearest));\n assert_eq!(h.state().session.prefs().general.image_interpolation, photocraft_engine::prefs::Interpolation::BicubicAutomatic);\n\n let transform = h.state_mut().ui.transform.as_mut().unwrap();\n transform.quad = transform.quad.map(|[x, y]| [x + 1.0, y]);\n assert!(h.state().ui.transform.is_none());\n begin(h.state_mut(), &ctx).unwrap();\n assert_eq!(h.state().ui.transform.as_ref().unwrap().interpolation, \"nearest\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/290f924d0fecc3bf6bea159c0d9e86255d326a96/crates/ui-egui/src/transform_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8896",
|
|
"pr": 8896,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Selected document/layer-mask fixtures in dialogs/select_mask_ui/tests.rs plus two-document controls; record viewport/theme/scale",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked opens_like_photoshop -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked opening_needs_a_selection_or_a_layer_mask -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked tools_make_edits_and_undo_and_redo_them -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_is_one_step_and_matches_the_command -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cancel_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked decontaminate_outputs_to_a_new_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hostile_control_params_are_errors -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_after_a_document_switch_changes_neither_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_after_a_layer_switch_leaves_the_new_layer_alone -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked renders_photoshops_layout -- --nocapture"
|
|
],
|
|
"expected": "Workspace needs valid selection/mask; tools/preview affect intended target. OK matches engine output in one history step; Cancel changes nothing; decontamination outputs a new layer. Hostile controls refuse; stale document/layer targets edit neither new target.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Native refinement \u2192 undo/redo \u2192 Cancel and commit are separate NOT RUN subcases. Capture the full workspace with reachable controls, not only an overlay helper.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked opens_like_photoshop -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked opening_needs_a_selection_or_a_layer_mask -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked tools_make_edits_and_undo_and_redo_them -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_is_one_step_and_matches_the_command -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cancel_changes_nothing -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked decontaminate_outputs_to_a_new_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hostile_control_params_are_errors -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_after_a_document_switch_changes_neither_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ok_after_a_layer_switch_leaves_the_new_layer_alone -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked renders_photoshops_layout -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-9493",
|
|
"pr": 9493,
|
|
"subsystem": "Selection, paths and transforms",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-compose --locked feather_at_the_canvas_edge_continues_the_mask_past_it -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked soft_shape_matches_an_equal_vector_mask -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked parallel_gaussian_matches_the_sequential_reference -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked padding_each_line_matches_padding_the_plane -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked benchmark_50mp_mask_blur -- --nocapture --ignored",
|
|
"cargo test -p photocraft-vector --locked a_maximum_feather_does_not_pad_the_whole_plane -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked a_failed_line_buffer_never_leaves_a_half_blurred_mask -- --nocapture"
|
|
],
|
|
"expected": "feather at the canvas edge continues the mask past it; soft shape matches an equal vector mask; parallel gaussian matches the sequential reference; padding each line matches padding the plane; benchmark 50mp mask blur; a maximum feather does not pad the whole plane; a failed line buffer never leaves a half blurred mask",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-compose --locked feather_at_the_canvas_edge_continues_the_mask_past_it -- --nocapture",
|
|
"cargo test -p photocraft-compose --locked soft_shape_matches_an_equal_vector_mask -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked parallel_gaussian_matches_the_sequential_reference -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked padding_each_line_matches_padding_the_plane -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked benchmark_50mp_mask_blur -- --nocapture --ignored",
|
|
"cargo test -p photocraft-vector --locked a_maximum_feather_does_not_pad_the_whole_plane -- --nocapture",
|
|
"cargo test -p photocraft-vector --locked a_failed_line_buffer_never_leaves_a_half_blurred_mask -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "feather_at_the_canvas_edge_continues_the_mask_past_it",
|
|
"path": "crates/compose/src/masks.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked feather_at_the_canvas_edge_continues_the_mask_past_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut layer = Layer::raster(\"edge\", PixelFormat::RGBA8);\n let mut mask = photocraft_doc::LayerMask::hide_all();\n mask.surface.fill_rect(Rect::new(40, 20, 120, 60), &[1.0]);\n mask.feather = 32.0;\n layer.mask = Some(mask);\n let canvas = Rect::new(0, 0, 160, 80);\n let tight = combined_mask(&layer, canvas).unwrap().read_region(canvas);\n let tall = combined_mask(&layer, Rect::new(0, -200, 160, 280)).unwrap().read_region(canvas);\n let worst = tight.iter().zip(&tall).map(|(a, b)| (a - b).abs()).fold(0.0_f32, f32::max);\n assert!(worst < 1e-4, \"the canvas edge changed the feather by {worst}\");\n\n let mut half = photocraft_doc::LayerMask::hide_all();",
|
|
"expected_assertions": [
|
|
" assert!(worst < 1e-4, \"the canvas edge changed the feather by {worst}\");\n\n let mut half = photocraft_doc::LayerMask::hide_all();\n half.surface.fill_rect(Rect::new(0, 0, 80, 80), &[1.0]);\n assert!(row.iter().zip(middle).all(|(a, b)| (a - b).abs() < 1e-5), \"row {y} differs from row 40\");\n }\n assert!(middle[0] > 0.99, \"the left edge stays white: {}\", middle[0]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/compose/src/masks.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "soft_shape_matches_an_equal_vector_mask",
|
|
"path": "crates/compose/src/soft_shape_tests.rs",
|
|
"package": "photocraft-compose",
|
|
"command": "cargo test -p photocraft-compose --locked soft_shape_matches_an_equal_vector_mask -- --nocapture",
|
|
"fixture_and_action_excerpt": " // 40 px reaches past the canvas edge: both feather it the same way there (#9475).\n for (density, feather) in [(1.0, 10.0), (0.45, 0.0), (0.3, 6.5), (0.0, 0.0), (1.0, 0.0), (0.5, 3.0), (1.0, 40.0)] {\n for depth in [SampleType::U8, SampleType::U16] {\n let (s, f) = (shape_doc(depth, density, feather, None), fill_doc(depth, density, feather));\n for y in [0, 45, 50, 100, 151, 199] {\n // An 8-bit shape keeps its rendering in 8-bit pixels (the fill layer's mask is\n // 16-bit), which can round its alpha one level apart, as at any anti-aliased edge.\n let d8 = max_diff(&row(&s, y), &row(&f, y));\n assert!(d8 <= i32::from(depth == SampleType::U8), \"{depth:?} density {density} feather {feather}, row {y}: {d8} levels\");\n // The compositor keeps masks at 16 bits (an 8-bit shape's pixels are 8-bit).\n if depth == SampleType::U16 {\n let d16 = max_diff(&row16(&s, y), &row16(&f, y));",
|
|
"expected_assertions": [
|
|
" assert!(d8 <= i32::from(depth == SampleType::U8), \"{depth:?} density {density} feather {feather}, row {y}: {d8} levels\");\n // The compositor keeps masks at 16 bits (an 8-bit shape's pixels are 8-bit).\n if depth == SampleType::U16 {\n let d16 = max_diff(&row16(&s, y), &row16(&f, y));\n assert!(d16 <= 2, \"{depth:?} density {density} feather {feather}, row {y}: {d16} 16-bit levels\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/compose/src/soft_shape_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "parallel_gaussian_matches_the_sequential_reference",
|
|
"path": "crates/vector/src/feather.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked parallel_gaussian_matches_the_sequential_reference -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h, sigma): (usize, usize, f32) = (320, 256, 13.0);\n let mut parallel: Vec<_> = (0..w * h).map(|i| ((i * 37 % 1009) as f32) / 1008.0).collect();\n let mut sequential = parallel.clone();\n let pass = BoxPass::for_sigma(sigma).unwrap();\n let source = parallel.clone();\n for halo in [0, 3 * (pass.r + 1)] {\n parallel.copy_from_slice(&source);\n sequential.copy_from_slice(&source);\n gaussian_sequential(&mut sequential, w, h, pass, halo);\n blur_plane(&mut parallel, w, h, pass, halo);\n assert_eq!(parallel, sequential, \"parallel blur must retain the exact per-line arithmetic (halo {halo})\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(parallel, sequential, \"parallel blur must retain the exact per-line arithmetic (halo {halo})\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/vector/src/feather.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "padding_each_line_matches_padding_the_plane",
|
|
"path": "crates/vector/src/feather.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked padding_each_line_matches_padding_the_plane -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h, sigma): (usize, usize, f32) = (90, 70, 9.0);\n let source: Vec<f32> = (0..w * h).map(|i| ((i * 37 % 1009) as f32) / 1008.0).collect();\n let pass = BoxPass::for_sigma(sigma).unwrap();\n let m = 3 * (pass.r + 1);\n let (pw, ph) = (w + 2 * m, h + 2 * m);\n let mut plane: Vec<f32> = (0..pw * ph).map(|i| source[((i / pw).clamp(m, m + h - 1) - m) * w + (i % pw).clamp(m, m + w - 1) - m]).collect();\n blur_plane(&mut plane, pw, ph, pass, 0);\n let want: Vec<f32> = (0..w * h).map(|i| plane[(i / w + m) * pw + i % w + m]).collect();\n let mut got = source;\n gaussian(&mut got, w, h, sigma);\n assert_eq!(got, want);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(got, want);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/vector/src/feather.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "benchmark_50mp_mask_blur",
|
|
"path": "crates/vector/src/feather.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked benchmark_50mp_mask_blur -- --nocapture --ignored",
|
|
"fixture_and_action_excerpt": " use std::time::Instant;\n\n let (w, h, sigma): (usize, usize, f32) = (6336, 7920, 1000.0);\n let pass = BoxPass::for_sigma(sigma).unwrap();\n let source: Vec<_> = (0..w * h).map(|i| ((i * 37 % 1009) as f32) / 1008.0).collect();\n let mut sequential = source.clone();\n let start = Instant::now();\n gaussian_sequential(&mut sequential, w, h, pass, 3 * (pass.r + 1));\n let sequential_time = start.elapsed();\n let mut parallel = source;\n let start = Instant::now();\n gaussian(&mut parallel, w, h, sigma);",
|
|
"expected_assertions": [
|
|
" assert_eq!(parallel, sequential);\n eprintln!(\"50 MP mask blur: sequential={sequential_time:?}, parallel={parallel_time:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/vector/src/feather.rs",
|
|
"ignored_requires_explicit_execution": true,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_maximum_feather_does_not_pad_the_whole_plane",
|
|
"path": "crates/vector/src/feather.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked a_maximum_feather_does_not_pad_the_whole_plane -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h) = (400usize, 400usize);\n let mut v: Vec<f32> = (0..w * h).map(|i| if (i % w) < w / 2 { 1.0 } else { 0.0 }).collect();\n gaussian(&mut v, w, h, feather_sigma(1000.0));\n let largest = LARGEST_BUFFER.load(std::sync::atomic::Ordering::Relaxed);\n assert!(largest <= w * h, \"the blur allocated a buffer of {largest} floats for a {w} \u00d7 {h} plane\");\n assert!(v.iter().all(|x| x.is_finite()));\n }",
|
|
"expected_assertions": [
|
|
" assert!(largest <= w * h, \"the blur allocated a buffer of {largest} floats for a {w} \u00d7 {h} plane\");\n assert!(v.iter().all(|x| x.is_finite()));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/vector/src/feather.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "a_failed_line_buffer_never_leaves_a_half_blurred_mask",
|
|
"path": "crates/vector/src/feather.rs",
|
|
"package": "photocraft-vector",
|
|
"command": "cargo test -p photocraft-vector --locked a_failed_line_buffer_never_leaves_a_half_blurred_mask -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (w, h, sigma): (usize, usize, f32) = (433, 211, 7.0);\n let source: Vec<f32> = (0..w * h).map(|i| ((i * 37 % 1009) as f32) / 1008.0).collect();\n let mut want = source.clone();\n gaussian(&mut want, w, h, sigma);\n for fail in [w, h] {\n FAIL_LINE_BUFFERS.store(fail, std::sync::atomic::Ordering::Relaxed);\n let mut got = source.clone();\n gaussian(&mut got, w, h, sigma);\n FAIL_LINE_BUFFERS.store(0, std::sync::atomic::Ordering::Relaxed);\n assert!(got == want || got == source, \"lines of {fail} failing left a partly blurred plane\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(got == want || got == source, \"lines of {fail} failing left a partly blurred plane\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/61a413d8df9e90ee545eb08e57c5615aa2b29cea/crates/vector/src/feather.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3139",
|
|
"pr": 3139,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Arabic, Hebrew, mixed Latin/digits and Persian joiner samples in bidi_label_tests.rs; record rendered font files",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked right_to_left_words_swap_places_but_keep_their_letters -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked numbers_and_latin_keep_reading_left_to_right -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked persian_joiners_stay_inside_their_word -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arabic_draws_first_word_rightmost_with_letters_joined -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hebrew_draws_first_word_rightmost -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_long_right_to_left_layer_name_keeps_its_beginning -- --nocapture"
|
|
],
|
|
"expected": "First RTL word is rightmost; Arabic joining and Persian joiners remain intact; Latin/digits retain direction; truncation keeps the beginning. Retain LTR-unchanged negative coverage.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Inspect Layers at 1\u00d7/2\u00d7. Missing fonts block rendered coverage; an early return is not a pass.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked right_to_left_words_swap_places_but_keep_their_letters -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked numbers_and_latin_keep_reading_left_to_right -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked persian_joiners_stay_inside_their_word -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arabic_draws_first_word_rightmost_with_letters_joined -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hebrew_draws_first_word_rightmost -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked a_long_right_to_left_layer_name_keeps_its_beginning -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-4783",
|
|
"pr": 4783,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-io --locked tysh_fallback_cannot_reintroduce_unusable_finite_or_nonfinite_transform -- --nocapture",
|
|
"cargo test -p photocraft-io --locked hostile_type_sizes_without_pixels_import_without_a_huge_render -- --nocapture",
|
|
"cargo test -p photocraft-text --locked overflowing_legacy_origin_does_not_escape_as_a_nonfinite_transform -- --nocapture",
|
|
"cargo test -p photocraft-text --locked reject_unusable_matrices_before_type_layout -- --nocapture"
|
|
],
|
|
"expected": "tysh fallback cannot reintroduce unusable finite or nonfinite transform; hostile type sizes without pixels import without a huge render; overflowing legacy origin does not escape as a nonfinite transform; reject unusable matrices before type layout",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-io --locked tysh_fallback_cannot_reintroduce_unusable_finite_or_nonfinite_transform -- --nocapture",
|
|
"cargo test -p photocraft-io --locked hostile_type_sizes_without_pixels_import_without_a_huge_render -- --nocapture",
|
|
"cargo test -p photocraft-text --locked overflowing_legacy_origin_does_not_escape_as_a_nonfinite_transform -- --nocapture",
|
|
"cargo test -p photocraft-text --locked reject_unusable_matrices_before_type_layout -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "tysh_fallback_cannot_reintroduce_unusable_finite_or_nonfinite_transform",
|
|
"path": "crates/io/src/blocks.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked tysh_fallback_cannot_reintroduce_unusable_finite_or_nonfinite_transform -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut tysh = vec![0u8; 52];\n tysh[..2].copy_from_slice(&1u16.to_be_bytes());\n for (i, value) in [1.0f64, 0.0, 0.0, 1.0, 30.0, 40.0].iter().enumerate() {\n tysh[2 + 8 * i..10 + 8 * i].copy_from_slice(&value.to_be_bytes());\n }\n assert!(parse_tysh(&tysh).is_some(), \"normal matrices still import\");\n for value in [1e62f64, -1e62, f64::INFINITY, f64::NAN] {\n tysh[2..10].copy_from_slice(&value.to_be_bytes());\n assert!(parse_tysh(&tysh).is_none(), \"invalid matrix {value} cannot reach UI\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(parse_tysh(&tysh).is_some(), \"normal matrices still import\");\n for value in [1e62f64, -1e62, f64::INFINITY, f64::NAN] {\n tysh[2..10].copy_from_slice(&value.to_be_bytes());\n assert!(parse_tysh(&tysh).is_none(), \"invalid matrix {value} cannot reach UI\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9d62726bed607bc540db9d09c8dc1be4f9895aa/crates/io/src/blocks.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "hostile_type_sizes_without_pixels_import_without_a_huge_render",
|
|
"path": "crates/io/tests/psd_type_bounds.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked hostile_type_sizes_without_pixels_import_without_a_huge_render -- --nocapture",
|
|
"fixture_and_action_excerpt": " // The import renders type layers that come without pixels; the model is untrusted, so an\n // absurd size or scale must not make opening the file allocate gigabytes (or fail).\n let scaled = |s: f64| Affine { m: [s, 0.0, 0.0, s, 10.0, 10.0] };\n for (size, transform, big) in\n [(12.0, scaled(1100.0), true), (1.0e30, scaled(1.0), false), (12.0, scaled(1.0e12), false), (f64::MAX, scaled(f64::MAX), false)]\n {\n let runs = vec![Run { len: 1, size, leading: None }];\n let data = tysh(\"M\", &runs, None, transform, [10.0, 10.0, 20.0, 20.0]);\n // Extremely large TySh transforms are now rejected before any layout or rendering.\n // Keep testing the import-time render cap for matrices within the safety gate.\n if !photocraft_text::psd::usable_tysh_transform(&transform.m) {\n assert!(photocraft_text::psd::text_layer_from_tysh(&data, 72.0).is_none(), \"unsafe transform must be rejected before layout\");",
|
|
"expected_assertions": [
|
|
" assert!(photocraft_text::psd::text_layer_from_tysh(&data, 72.0).is_none(), \"unsafe transform must be rejected before layout\");\n continue;\n }\n let mut t = photocraft_text::psd::text_layer_from_tysh(&data, 72.0).expect(\"valid TySh transform\");\n assert!(px > 64 * 1024 * 1024 && px <= 256 * 1024 * 1024, \"{ink:?}\");\n }\n t.cache = None;\n t.psd_raw = Some(std::sync::Arc::new(data));\n assert!(cache.content_bounds().is_empty(), \"size {size}: drew {:?}\", cache.content_bounds());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9d62726bed607bc540db9d09c8dc1be4f9895aa/crates/io/tests/psd_type_bounds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "overflowing_legacy_origin_does_not_escape_as_a_nonfinite_transform",
|
|
"path": "crates/text/src/psd.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked overflowing_legacy_origin_does_not_escape_as_a_nonfinite_transform -- --nocapture",
|
|
"fixture_and_action_excerpt": " let bounds = Descriptor::new(\"boundingBox\")\n .with(\"Left\", D::Double(1.0e308))\n .with(\"Top \", D::Double(1.0e308))\n .with(\"Rght\", D::Double(1.5e308))\n .with(\"Btom\", D::Double(1.5e308));\n let text = Descriptor::new(\"TxLr\").with(\"Txt \", D::Text(UnicodeString::new_nul(\"x\"))).with(\"boundingBox\", D::Descriptor(bounds)).with(\n \"EngineData\",\n D::RawData(\n b\"<< /EngineDict << /Rendered << /Shapes << /Children [ << /Cookie << /Photoshop << /PointBase [0.0 0.0] >> >> >> ] >> >> >> >>\".to_vec(),\n ),\n );\n let tysh = TySh { transform: Affine { m: [1.0e9, 0.0, -1.0e9, 0.0, 5000.0, 0.0] }, text, warp: None, bounds: [0.0; 4] };",
|
|
"expected_assertions": [
|
|
" assert!(engine_data(&tysh.text).is_some());\n assert!(legacy_point_origin(&tysh).is_none());\n let layer = text_layer_from_tysh(&write_tysh(&tysh), 72.0).unwrap();\n assert!(usable_tysh_transform(&layer.transform.m));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9d62726bed607bc540db9d09c8dc1be4f9895aa/crates/text/src/psd.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reject_unusable_matrices_before_type_layout",
|
|
"path": "crates/text/src/psd.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked reject_unusable_matrices_before_type_layout -- --nocapture",
|
|
"fixture_and_action_excerpt": " let original = TySh { transform: Affine { m: [1.0, 0.0, 0.0, 1.0, 30.0, 40.0] }, text: Descriptor::new(\"TxLr\"), warp: None, bounds: [0.0; 4] };\n let clean = write_tysh(&original);\n assert_eq!(parse_tysh(&clean).unwrap().transform, original.transform);\n for bad in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY, 1.315776645269349e62] {\n let mut bytes = clean.clone();\n bytes[2..10].copy_from_slice(&bad.to_be_bytes());\n assert!(parse_tysh(&bytes).is_none(), \"invalid matrix must not be rendered: {bad}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(parse_tysh(&clean).unwrap().transform, original.transform);\n for bad in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY, 1.315776645269349e62] {\n let mut bytes = clean.clone();\n bytes[2..10].copy_from_slice(&bad.to_be_bytes());\n assert!(parse_tysh(&bytes).is_none(), \"invalid matrix must not be rendered: {bad}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a9d62726bed607bc540db9d09c8dc1be4f9895aa/crates/text/src/psd.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8347",
|
|
"pr": 8347,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Trailing punctuation, centered/justified lines and forced breaks in text layout fixtures",
|
|
"action": [
|
|
"cargo test -p photocraft-text --locked hanging_marks_do_not_steer_the_alignment -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_centers_a_kerned_line_exactly -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_only_the_mark_list_trims -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_keeps_marks_after_a_forced_break_on_their_row -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_marks_stay_off_a_justified_paragraphs_last_line -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_leaves_plain_paragraphs_untouched -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked character_panel_hanging_checkbox_toggles_the_paragraph_style -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_style_paragraph_hanging_round_trips -- --nocapture"
|
|
],
|
|
"expected": "Listed marks hang without steering alignment; kerning-aware centering stays exact; unlisted marks/plain paragraphs are unchanged; forced breaks and justified last lines retain their asserted rules. Checkbox edits actual paragraph style.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "A stored boolean alone is not layout evidence.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-text --locked hanging_marks_do_not_steer_the_alignment -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_centers_a_kerned_line_exactly -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_only_the_mark_list_trims -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_keeps_marks_after_a_forced_break_on_their_row -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_marks_stay_off_a_justified_paragraphs_last_line -- --nocapture",
|
|
"cargo test -p photocraft-text --locked hanging_leaves_plain_paragraphs_untouched -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked character_panel_hanging_checkbox_toggles_the_paragraph_style -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked set_style_paragraph_hanging_round_trips -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-9457",
|
|
"pr": 9457,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-raw --locked gauss_gives_the_bits_of_the_tap_loop -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked box_mean_gives_the_bits_of_the_column_loop -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked the_tap_tables_give_the_bits_of_the_per_pixel_lookup -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked reduce_pair_gives_the_bits_of_two_reductions -- --nocapture"
|
|
],
|
|
"expected": "gauss gives the bits of the tap loop; box mean gives the bits of the column loop; the tap tables give the bits of the per pixel lookup; reduce pair gives the bits of two reductions",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-raw --locked gauss_gives_the_bits_of_the_tap_loop -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked box_mean_gives_the_bits_of_the_column_loop -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked the_tap_tables_give_the_bits_of_the_per_pixel_lookup -- --nocapture",
|
|
"cargo test -p photocraft-raw --locked reduce_pair_gives_the_bits_of_two_reductions -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "gauss_gives_the_bits_of_the_tap_loop",
|
|
"path": "crates/raw/src/tone.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked gauss_gives_the_bits_of_the_tap_loop -- --nocapture",
|
|
"fixture_and_action_excerpt": " // Sizes below, around and above the kernel (edges only, a few interior samples, mostly interior).\n for (w, h) in [(1, 1), (5, 3), (13, 40), (64, 7), (65, 70), (131, 97), (300, 41)] {\n let v = noise(w * h, (w * 31 + h) as u64);\n for sigma in [0.04, 0.42, 1.0, 2.1, 4.2, 8.4, 13.44] {\n assert!(same(&gauss(&v, w, h, sigma), &gauss_ref(&v, w, h, sigma)), \"{w}x{h} sigma {sigma}\");\n }\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(same(&gauss(&v, w, h, sigma), &gauss_ref(&v, w, h, sigma)), \"{w}x{h} sigma {sigma}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/2863c3281c2a22dade0ce92d42bf8900074f76c6/crates/raw/src/tone.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "box_mean_gives_the_bits_of_the_column_loop",
|
|
"path": "crates/raw/src/tone.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked box_mean_gives_the_bits_of_the_column_loop -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (w, h) in [(1, 1), (5, 3), (13, 40), (64, 7), (65, 70), (131, 97), (300, 41)] {\n let v = noise(w * h, (w * 17 + h) as u64);\n for r in [1, 2, 8, 32, 128] {\n assert!(same(&box_mean(&v, w, h, r), &box_mean_ref(&v, w, h, r)), \"{w}x{h} r {r}\");\n }\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(same(&box_mean(&v, w, h, r), &box_mean_ref(&v, w, h, r)), \"{w}x{h} r {r}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/2863c3281c2a22dade0ce92d42bf8900074f76c6/crates/raw/src/tone.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_tap_tables_give_the_bits_of_the_per_pixel_lookup",
|
|
"path": "crates/raw/src/tone.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked the_tap_tables_give_the_bits_of_the_per_pixel_lookup -- --nocapture",
|
|
"fixture_and_action_excerpt": " for ((sw, sh), (w, h)) in [((1, 1), (7, 5)), ((3, 2), (3, 2)), ((12, 9), (97, 61)), ((308, 205), (1232, 820)), ((1232, 616), (8256, 4128))] {\n let a = noise(sw * sh, 5);\n let b = noise(sw * sh, 6);\n let grid = Grid::new(sw, sh, w, h);\n let ab: Vec<[f32; 2]> = a.iter().zip(&b).map(|(a, b)| [*a, *b]).collect();\n for y in (0..h).step_by(if h > 1000 { 7 } else { 1 }) {\n for x in (0..w).step_by(if w > 1000 { 5 } else { 1 }) {\n let (ra, rb) = (bilinear_ref(&a, sw, sh, w, h, x, y), bilinear_ref(&b, sw, sh, w, h, x, y));\n assert_eq!(grid.at(&a, x, y).to_bits(), ra.to_bits(), \"{sw}x{sh} to {w}x{h} at {x},{y}\");\n let [pa, pb] = grid.at2(&ab, x, y);\n assert!(pa.to_bits() == ra.to_bits() && pb.to_bits() == rb.to_bits(), \"{sw}x{sh} to {w}x{h} at {x},{y}\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(grid.at(&a, x, y).to_bits(), ra.to_bits(), \"{sw}x{sh} to {w}x{h} at {x},{y}\");\n let [pa, pb] = grid.at2(&ab, x, y);\n assert!(pa.to_bits() == ra.to_bits() && pb.to_bits() == rb.to_bits(), \"{sw}x{sh} to {w}x{h} at {x},{y}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/2863c3281c2a22dade0ce92d42bf8900074f76c6/crates/raw/src/tone.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "reduce_pair_gives_the_bits_of_two_reductions",
|
|
"path": "crates/raw/src/tone.rs",
|
|
"package": "photocraft-raw",
|
|
"command": "cargo test -p photocraft-raw --locked reduce_pair_gives_the_bits_of_two_reductions -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (w, h) in [(1, 1), (7, 5), (100, 61), (1233, 77), (2500, 1700), (333, 2999)] {\n let v = noise(w * h, (w + 3 * h) as u64);\n for sides in [[1232, 2464], [100, 50], [7, 8], [1232, 1232], [3, 600]] {\n let pair = reduce_pair(w, h, sides, |i| v[i]);\n for (g, side) in sides.iter().enumerate() {\n let (sw, sh, one) = reduce(w, h, *side, |i| [v[i]]);\n let one: Vec<f32> = one.into_iter().map(|[v]| v).collect();\n assert!((sw, sh) == (pair[g].0, pair[g].1) && same(&one, &pair[g].2), \"{w}x{h} side {side}\");\n }\n }\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!((sw, sh) == (pair[g].0, pair[g].1) && same(&one, &pair[g].2), \"{w}x{h} side {side}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/2863c3281c2a22dade0ce92d42bf8900074f76c6/crates/raw/src/tone.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9478",
|
|
"pr": 9478,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Roman, ligature and half-width CJK fixtures in text/vertical_tests.rs; record fonts",
|
|
"action": [
|
|
"cargo test -p photocraft-text --locked latin_stands_upright_one_per_em_by_default -- --nocapture",
|
|
"cargo test -p photocraft-text --locked upright_roman_letters_stay_apart_without_ligatures -- --nocapture",
|
|
"cargo test -p photocraft-text --locked half_width_cjk_stays_rotated_beside_upright_roman -- --nocapture",
|
|
"cargo test -p photocraft-text --locked baseline_direction_round_trips -- --nocapture"
|
|
],
|
|
"expected": "Roman defaults upright at one-em advances without ligature collapse; half-width CJK retains specified rotation. Run BaselineDirection overrides sheet defaults and survives PSD persistence.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"qualification_gap": "Capture upright/rotated text at 1\u00d7/2\u00d7 and save/reopen PSD separately. Font-unavailable geometry is BLOCKED; the flag round-trip alone is insufficient.",
|
|
"tested_sha": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-text --locked latin_stands_upright_one_per_em_by_default -- --nocapture",
|
|
"cargo test -p photocraft-text --locked upright_roman_letters_stay_apart_without_ligatures -- --nocapture",
|
|
"cargo test -p photocraft-text --locked half_width_cjk_stays_rotated_beside_upright_roman -- --nocapture",
|
|
"cargo test -p photocraft-text --locked baseline_direction_round_trips -- --nocapture"
|
|
]
|
|
},
|
|
{
|
|
"id": "PR-9523",
|
|
"pr": 9523,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-text --locked closed_rectangle_left_edge_continues_past_the_top_left_seam -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_ellipse_upper_left_and_apex_cross_the_seam_in_both_directions -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_shows_one_lap_without_repeating_glyph_centres -- --nocapture",
|
|
"cargo test -p photocraft-text --locked open_path_clipping_offsets_and_end_tangents_stay_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_alignment_uses_one_lap_from_the_text_left_edge -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_start_offsets_wrap_and_invalid_coordinates_are_hidden -- --nocapture",
|
|
"cargo test -p photocraft-text --locked caret_projection_roundtrips_closed_seams_and_open_offsets -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_forward_hit_after_last_caret -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked open_path_hits_keep_endpoint_clamping -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_backward_hit_before_first_caret -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_upstream_caret_rectangle_left_edge_roundtrip -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_aligned_selection_highlights_every_visible_cluster -- --nocapture"
|
|
],
|
|
"expected": "closed rectangle left edge continues past the top left seam; closed ellipse upper left and apex cross the seam in both directions; closed path shows one lap without repeating glyph centres; open path clipping offsets and end tangents stay unchanged; closed path alignment uses one lap from the text left edge; closed path start offsets wrap and invalid coordinates are hidden; caret projection roundtrips closed seams and open offsets; closed path forward hit after last caret; open path hits keep endpoint clamping; closed path backward hit before first caret; closed path upstream caret rectangle left edge roundtrip; closed path aligned selection highlights every visible cluster",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-text --locked closed_rectangle_left_edge_continues_past_the_top_left_seam -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_ellipse_upper_left_and_apex_cross_the_seam_in_both_directions -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_shows_one_lap_without_repeating_glyph_centres -- --nocapture",
|
|
"cargo test -p photocraft-text --locked open_path_clipping_offsets_and_end_tangents_stay_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_alignment_uses_one_lap_from_the_text_left_edge -- --nocapture",
|
|
"cargo test -p photocraft-text --locked closed_path_start_offsets_wrap_and_invalid_coordinates_are_hidden -- --nocapture",
|
|
"cargo test -p photocraft-text --locked caret_projection_roundtrips_closed_seams_and_open_offsets -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_forward_hit_after_last_caret -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked open_path_hits_keep_endpoint_clamping -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_backward_hit_before_first_caret -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_upstream_caret_rectangle_left_edge_roundtrip -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked closed_path_aligned_selection_highlights_every_visible_cluster -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "closed_rectangle_left_edge_continues_past_the_top_left_seam",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked closed_rectangle_left_edge_continues_past_the_top_left_seam -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = Subpath::polygon(&[(0.0, 0.0), (100.0, 0.0), (100.0, 100.0), (0.0, 100.0)]);\n let start = arc_length_at(&p, false, 0.0, 50.0).unwrap();\n assert!((start - 350.0).abs() < 1e-6);\n let f = PathFrame::new(&p, start as f32, false).unwrap();\n let m = f.frame(75.0).expect(\"glyph after the seam remains on the closed path\");\n let q = centre(m, 75.0);\n assert!((q.0 - 25.0).abs() < 1e-6 && q.1.abs() < 1e-6, \"{q:?}\");\n assert_eq!(&m[..4], &[1.0, 0.0, -0.0, 1.0], \"text now travels right on the top side\");\n assert_eq!(f.apply(75.0, 0.0), q, \"caret and glyph use the same wrapped parameter\");\n}",
|
|
"expected_assertions": [
|
|
" assert!((start - 350.0).abs() < 1e-6);\n let f = PathFrame::new(&p, start as f32, false).unwrap();\n let m = f.frame(75.0).expect(\"glyph after the seam remains on the closed path\");\n let q = centre(m, 75.0);\n assert!((q.0 - 25.0).abs() < 1e-6 && q.1.abs() < 1e-6, \"{q:?}\");\n assert_eq!(&m[..4], &[1.0, 0.0, -0.0, 1.0], \"text now travels right on the top side\");\n assert_eq!(f.apply(75.0, 0.0), q, \"caret and glyph use the same wrapped parameter\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_ellipse_upper_left_and_apex_cross_the_seam_in_both_directions",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked closed_ellipse_upper_left_and_apex_cross_the_seam_in_both_directions -- --nocapture",
|
|
"fixture_and_action_excerpt": " for reverse in [false, true] {\n let mut p = ellipse();\n if reverse {\n p.knots.reverse();\n for k in &mut p.knots {\n std::mem::swap(&mut k.in_ctrl, &mut k.out_ctrl);\n }\n }\n for flip in [false, true] {\n let whole = PathFrame::new(&p, 0.0, flip).unwrap();\n let length = whole.length();\n for remaining in [0.001, 0.2, 30.0] {",
|
|
"expected_assertions": [
|
|
" assert!((actual.0 - point.0).hypot(actual.1 - point.1) < 1e-6);\n assert!((m[0] - tangent.0).abs() < 1e-6 && (m[1] - tangent.1).abs() < 1e-6);\n assert!((m[0] * m[3] - m[1] * m[2] - 1.0).abs() < 1e-6, \"no reflection or scale jump\");\n let before = f.apply(remaining - 0.001, 0.0);\n let after = f.apply(remaining + 0.001, 0.0);\n assert!((before.0 - after.0).hypot(before.1 - after.1) < 0.01, \"seam is continuous\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_shows_one_lap_without_repeating_glyph_centres",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked closed_path_shows_one_lap_without_repeating_glyph_centres -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = ellipse();\n let length = PathFrame::new(&p, 0.0, false).unwrap().length();\n let f = PathFrame::new(&p, (length - 5.0) as f32, false).unwrap();\n let mut points = Vec::new();\n for i in 0..100 {\n let x = length * i as f64 / 100.0;\n let m = f.frame(x).expect(\"one complete lap is available from the text origin\");\n points.push(centre(m, x));\n }\n for (i, a) in points.iter().enumerate() {\n assert!(points.iter().skip(i + 1).all(|b| (a.0 - b.0).hypot(a.1 - b.1) > 0.01));\n }",
|
|
"expected_assertions": [
|
|
" assert!(points.iter().skip(i + 1).all(|b| (a.0 - b.0).hypot(a.1 - b.1) > 0.01));\n }\n assert!(f.frame(length).is_none(), \"the first repeated location is overflow, not another lap\");\n assert!(f.frame(length + 20.0).is_none());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "open_path_clipping_offsets_and_end_tangents_stay_unchanged",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked open_path_clipping_offsets_and_end_tangents_stay_unchanged -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = Subpath::polyline(&[(0.0, 0.0), (100.0, 0.0)]);\n for flip in [false, true] {\n let f = PathFrame::new(&p, 25.0, flip).unwrap();\n assert!(f.frame(-26.0).is_none());\n assert!(f.frame(-25.0).is_some());\n assert!(f.frame(75.0).is_some());\n assert!(f.frame(76.0).is_none());\n let q = f.apply(100.0, 0.0);\n assert!((q.0 - if flip { -25.0 } else { 125.0 }).abs() < 1e-9 && q.1.abs() < 1e-9);\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(f.frame(-26.0).is_none());\n assert!(f.frame(-25.0).is_some());\n assert!(f.frame(75.0).is_some());\n assert!(f.frame(76.0).is_none());\n let q = f.apply(100.0, 0.0);\n assert!((q.0 - if flip { -25.0 } else { 125.0 }).abs() < 1e-9 && q.1.abs() < 1e-9);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_alignment_uses_one_lap_from_the_text_left_edge",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked closed_path_alignment_uses_one_lap_from_the_text_left_edge -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = ellipse();\n let length = PathFrame::new(&p, 0.0, false).unwrap().length();\n for left in [-length / 2.0, -length, 0.0] {\n let shape = TextShape::Path { path: p.clone(), start: (length - 5.0) as f32, flip: false };\n let warp = Warp::on_path_with_text_start(&shape, left).unwrap();\n assert!(matches!(warp.place_glyph(left + 0.5), Placement::Frame(_)));\n assert!(matches!(warp.place_glyph(left + length - 0.5), Placement::Frame(_)));\n assert_eq!(warp.place_glyph(left - 0.5), Placement::Hidden);\n assert_eq!(warp.place_glyph(left + length + 0.5), Placement::Hidden);\n // The origin and tangent at each text coordinate are independent of clipping alignment.\n let reference = Warp::on_path(&shape).unwrap();\n assert_eq!(warp.apply(left, 0.0), reference.apply(left, 0.0));",
|
|
"expected_assertions": [
|
|
" assert!(matches!(warp.place_glyph(left + 0.5), Placement::Frame(_)));\n assert!(matches!(warp.place_glyph(left + length - 0.5), Placement::Frame(_)));\n assert_eq!(warp.place_glyph(left - 0.5), Placement::Hidden);\n assert_eq!(warp.place_glyph(left + length + 0.5), Placement::Hidden);\n // The origin and tangent at each text coordinate are independent of clipping alignment.\n let reference = Warp::on_path(&shape).unwrap();\n assert_eq!(warp.apply(left, 0.0), reference.apply(left, 0.0));\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_start_offsets_wrap_and_invalid_coordinates_are_hidden",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked closed_path_start_offsets_wrap_and_invalid_coordinates_are_hidden -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = Subpath::polygon(&[(0.0, 0.0), (100.0, 0.0), (100.0, 100.0), (0.0, 100.0)]);\n for start in [-10.0, 0.0, 400.0, 790.0] {\n let f = PathFrame::new(&p, start, false).unwrap();\n let reference = PathFrame::new(&p, start.rem_euclid(400.0), false).unwrap();\n assert_eq!(f.frame(20.0), reference.frame(20.0));\n assert!(f.frame(f64::NAN).is_none());\n assert!(f.frame(f64::INFINITY).is_none());\n }\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(f.frame(20.0), reference.frame(20.0));\n assert!(f.frame(f64::NAN).is_none());\n assert!(f.frame(f64::INFINITY).is_none());\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "caret_projection_roundtrips_closed_seams_and_open_offsets",
|
|
"path": "crates/text/src/closed_path_tests.rs",
|
|
"package": "photocraft-text",
|
|
"command": "cargo test -p photocraft-text --locked caret_projection_roundtrips_closed_seams_and_open_offsets -- --nocapture",
|
|
"fixture_and_action_excerpt": " let p = ellipse();\n let length = PathFrame::new(&p, 0.0, false).unwrap().length();\n for flip in [false, true] {\n for left in [0.0, -length / 2.0, -length] {\n let shape = TextShape::Path { path: p.clone(), start: (length - 20.0) as f32, flip };\n let w = Warp::on_path_with_text_start(&shape, left).unwrap();\n for x in [left + 0.5, left + 50.0, left + length / 2.0, left + length - 0.5] {\n let point = w.apply(x, 0.0);\n let actual = w.path_text_x(point.0, point.1).unwrap();\n assert!((actual - x).abs() < 1e-6, \"caret must not jump to start after seam: {actual} vs {x}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!((actual - x).abs() < 1e-6, \"caret must not jump to start after seam: {actual} vs {x}\");\n }\n }\n let shape = TextShape::Path { path: Subpath::polyline(&[(0.0, 0.0), (100.0, 0.0)]), start: 25.0, flip };\n assert!((x - if flip { 35.0 } else { 15.0 }).abs() < 1e-9);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/text/src/closed_path_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_forward_hit_after_last_caret",
|
|
"path": "crates/ui-egui/src/type_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked closed_path_forward_hit_after_last_caret -- --nocapture",
|
|
"fixture_and_action_excerpt": " for align in [\"left\", \"center\", \"right\"] {\n let mut app = app();\n app.ui.tool_options.type_align = align.into();\n let path = photocraft_vector::shapes::rect(20.0, 20.0, 200.0, 100.0);\n app.run(\"path.set\", json!({\"path\": photocraft_engine::vector_cmds::path_json(&path)})).unwrap();\n pointer_up(&mut app, [20.0, 45.0], [20.0, 45.0]);\n insert(&mut app, \"ssssssssssss\");\n let id = LayerId(app.ui.text_edit.as_ref().unwrap().layer);\n let (l, _, _) = layout(&mut app, id).unwrap();\n let (last, _, _) = l.caret(12);\n let s = (575.0 + f64::from(last) + 2.0).rem_euclid(600.0);\n let (x, y) = closed_path_endpoint_test_point(s);",
|
|
"expected_assertions": [
|
|
" assert_eq!(offset_at(&mut app, id, x, y), 12, \"{align}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/ui-egui/src/type_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "open_path_hits_keep_endpoint_clamping",
|
|
"path": "crates/ui-egui/src/type_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked open_path_hits_keep_endpoint_clamping -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n let path = photocraft_doc::vector::Path::new(vec![photocraft_doc::vector::Subpath::polyline(&[(20.0, 100.0), (380.0, 100.0)])]);\n app.run(\"path.set\", json!({\"path\": photocraft_engine::vector_cmds::path_json(&path)})).unwrap();\n pointer_up(&mut app, [200.0, 100.0], [200.0, 100.0]);\n insert(&mut app, \"ssss\");\n let id = LayerId(app.ui.text_edit.as_ref().unwrap().layer);\n assert_eq!(offset_at(&mut app, id, 198.0, 100.0), 0);\n assert_eq!(offset_at(&mut app, id, 20.0, 100.0), 0);\n assert_eq!(offset_at(&mut app, id, 380.0, 100.0), 4);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(offset_at(&mut app, id, 198.0, 100.0), 0);\n assert_eq!(offset_at(&mut app, id, 20.0, 100.0), 0);\n assert_eq!(offset_at(&mut app, id, 380.0, 100.0), 4);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/ui-egui/src/type_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_backward_hit_before_first_caret",
|
|
"path": "crates/ui-egui/src/type_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked closed_path_backward_hit_before_first_caret -- --nocapture",
|
|
"fixture_and_action_excerpt": " for align in [\"left\", \"center\", \"right\"] {\n let mut app = app();\n app.ui.tool_options.type_align = align.into();\n let path = photocraft_vector::shapes::rect(20.0, 20.0, 200.0, 100.0);\n app.run(\"path.set\", json!({\"path\": photocraft_engine::vector_cmds::path_json(&path)})).unwrap();\n pointer_up(&mut app, [20.0, 45.0], [20.0, 45.0]);\n insert(&mut app, \"ssssssssssss\");\n let id = LayerId(app.ui.text_edit.as_ref().unwrap().layer);\n let (l, _, _) = layout(&mut app, id).unwrap();\n // The rectangle runs clockwise; the text origin is perimeter distance 575.\n // Project 2 px backward from the first caret, using an independent oracle.\n let (first, _, _) = l.caret(0);",
|
|
"expected_assertions": [
|
|
" assert_eq!(offset_at(&mut app, id, x, y), 0, \"{align}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/ui-egui/src/type_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_upstream_caret_rectangle_left_edge_roundtrip",
|
|
"path": "crates/ui-egui/src/type_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked closed_path_upstream_caret_rectangle_left_edge_roundtrip -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app();\n let path = photocraft_vector::shapes::rect(20.0, 20.0, 200.0, 100.0);\n app.run(\"path.set\", json!({\"path\": photocraft_engine::vector_cmds::path_json(&path)})).unwrap();\n pointer_up(&mut app, [20.0, 45.0], [20.0, 45.0]);\n insert(&mut app, \"ssssssssssss\");\n let id = LayerId(app.ui.text_edit.as_ref().unwrap().layer);\n let (layout, _, _) = layout(&mut app, id).unwrap();\n let shape = text_layer(&app.session.active().unwrap().doc, id).unwrap().shape.clone();\n let photocraft_doc::text::TextShape::Path { start, .. } = shape else {\n assert!(matches!(shape, photocraft_doc::text::TextShape::Path { .. }), \"outline click must attach path text\");\n return;\n };",
|
|
"expected_assertions": [
|
|
" assert!(matches!(shape, photocraft_doc::text::TextShape::Path { .. }), \"outline click must attach path text\");\n return;\n };\n // Independent rectangle perimeter oracle: never use the warp under test to\n assert!((f64::from(start) - 575.0).abs() < 0.5);\n let mut tested_after_seam = false;\n for index in [1, 4, 7, 10] {\n let (x, _, _) = layout.caret(index);\n assert_eq!(offset_at(&mut app, id, doc.x, doc.y), index, \"caret round trip at {index}\");\n }\n assert!(tested_after_seam, \"fixture must cross the seam\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/ui-egui/src/type_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "closed_path_aligned_selection_highlights_every_visible_cluster",
|
|
"path": "crates/ui-egui/src/type_tool.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked closed_path_aligned_selection_highlights_every_visible_cluster -- --nocapture",
|
|
"fixture_and_action_excerpt": " for align in [\"center\", \"right\"] {\n let mut app = app();\n app.ui.tool_options.type_align = align.into();\n let path = photocraft_vector::shapes::rect(20.0, 20.0, 200.0, 100.0);\n app.run(\"path.set\", json!({\"path\":photocraft_engine::vector_cmds::path_json(&path)})).unwrap();\n pointer_up(&mut app, [20.0, 45.0], [20.0, 45.0]);\n insert(&mut app, \"ssssssssssss\");\n let id = LayerId(app.ui.text_edit.as_ref().unwrap().layer);\n let (l, _, _) = layout(&mut app, id).unwrap();\n assert!(l.bounds().unwrap()[0] < 0.0, \"{align} must exercise negative text coordinates\");\n let text_layer = text_layer(&app.session.active().unwrap().doc, id).unwrap();\n let rendered = photocraft_text::render::layout_deform(&l, text_layer).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(l.bounds().unwrap()[0] < 0.0, \"{align} must exercise negative text coordinates\");\n let text_layer = text_layer(&app.session.active().unwrap().doc, id).unwrap();\n let rendered = photocraft_text::render::layout_deform(&l, text_layer).unwrap();\n let visible =\n assert_eq!(visible, l.clusters.len());\n let ed = app.ui.text_edit.as_mut().unwrap();\n ed.anchor = 0;\n ed.caret = 12;\n assert_eq!(highlights, visible, \"{align}: every visible selected cluster needs its highlight\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/728782c595e768bdb6febc7f30e4d1456d13fd36/crates/ui-egui/src/type_tool.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9594",
|
|
"pr": 9594,
|
|
"subsystem": "Type and typography",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked copied_type_keeps_its_pixel_size_across_resolutions_after_an_edit -- --nocapture"
|
|
],
|
|
"expected": "copied type keeps its pixel size across resolutions after an edit",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked copied_type_keeps_its_pixel_size_across_resolutions_after_an_edit -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "copied_type_keeps_its_pixel_size_across_resolutions_after_an_edit",
|
|
"path": "crates/engine/src/layer_copy_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked copied_type_keeps_its_pixel_size_across_resolutions_after_an_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (from, to) in [(72, 300), (300, 72)] {\n let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 400, \"height\": 200, \"resolution\": from})).unwrap();\n let t = LayerId(s.execute(\"type.create\", json!({\"text\": \"H\", \"size\": 24, \"x\": 128, \"y\": 100})).unwrap()[\"layer\"].as_u64().unwrap());\n let original = bounds(&s, 0, t);\n s.execute(\"file.new\", json!({\"width\": 400, \"height\": 200, \"resolution\": to})).unwrap();\n s.set_active(0);\n s.execute(\"layer.select\", json!({\"layer\": t.0})).unwrap();\n let id = copied(&s.execute(\"layer.copyToDocument\", json!({\"document\": 1})).unwrap());\n assert_eq!(bounds(&s, 1, id).size(), original.size(), \"{from}\u2192{to}: the copy\");\n s.execute(\"type.edit\", json!({\"layer\": id.0, \"text\": \"M\"})).unwrap();\n s.execute(\"type.edit\", json!({\"layer\": id.0, \"text\": \"H\"})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(bounds(&s, 1, id).size(), original.size(), \"{from}\u2192{to}: the copy\");\n s.execute(\"type.edit\", json!({\"layer\": id.0, \"text\": \"M\"})).unwrap();\n s.execute(\"type.edit\", json!({\"layer\": id.0, \"text\": \"H\"})).unwrap();\n let after = bounds(&s, 1, id);\n assert_eq!(after.size(), original.size(), \"{from}\u2192{to}: after an edit, {after:?} vs {original:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/46512521fec2b4b462c29d9fefd16398cb81212c/crates/engine/src/layer_copy_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9596",
|
|
"pr": 9596,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-io --locked a_kept_txt2_goes_with_the_last_type_layer -- --nocapture"
|
|
],
|
|
"expected": "a kept txt2 goes with the last type layer",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-io --locked a_kept_txt2_goes_with_the_last_type_layer -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "a_kept_txt2_goes_with_the_last_type_layer",
|
|
"path": "crates/io/src/psd_export.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked a_kept_txt2_goes_with_the_last_type_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut doc = Document::new(\"t\", photocraft_geom::Size::new(8, 6), ColorMode::Rgb, SampleType::U8);\n doc.layers.push(Layer::new(\"Layer 1\", LayerContent::Raster(Surface::new(doc.pixel_format()))));\n doc.metadata.psd_global_blocks = vec![(*b\"8BIM\", *b\"Txt2\", std::sync::Arc::new(b\"<< /0 << /1 (stale) >> >>\".to_vec()))];\n let file = document_to_psd(&doc);\n assert!(!file.global_blocks.iter().any(|b| b.key == *b\"Txt2\"), \"no type layers: no Txt2\");\n\n doc.layers.push(Layer::new(\"T\", LayerContent::Text(photocraft_doc::TextLayer::default())));\n let file = document_to_psd(&doc);\n assert!(file.global_blocks.iter().any(|b| b.key == *b\"Txt2\"), \"a type layer keeps its Txt2\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(!file.global_blocks.iter().any(|b| b.key == *b\"Txt2\"), \"no type layers: no Txt2\");\n\n doc.layers.push(Layer::new(\"T\", LayerContent::Text(photocraft_doc::TextLayer::default())));\n let file = document_to_psd(&doc);\n assert!(file.global_blocks.iter().any(|b| b.key == *b\"Txt2\"), \"a type layer keeps its Txt2\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/e62013cfd652fa60470a0f7a185fbc8f3d2a2c92/crates/io/src/psd_export.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3345",
|
|
"pr": 3345,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked native_gradient_icons_persist_reset_and_preserve_legacy_defaults -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked opaque_ramp_has_no_checkerboard_fringe_at_fractional_pixel_edges -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked genuinely_transparent_ramp_still_shows_checkerboard_at_both_scales -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked options_bar_swatch_opens_the_editor_and_reaches_the_gradients_panel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_options_bar_ribbon_opens_the_editor_only_in_classic_mode -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_ramp_covers_its_checkerboard_at_half_pixel_offsets -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_editor_opacity_commits_once_and_delete_preserves_minimum -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preset_editor_opacity_fields_do_not_edit_document_history -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked editor_browser_expands_groups_and_selects_without_opening_the_sidebar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_browser_replaces_color_and_opacity_preserves_geometry_and_undoes_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked classic_browser_and_editor_edit_the_tool_even_with_a_gradient_layer_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked picking_a_preset_discards_an_uncommitted_location_draft -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked toolbar_popup_selects_in_both_modes_without_creating_a_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked editor_browser_can_choose_presets_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked browser_new_saves_the_edited_layer_instead_of_the_tool_gradient -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked double_clicking_an_editor_preset_does_not_create_another_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_can_collapse_to_reach_controls_in_a_small_window_across_themes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked properties_dropdown_edits_the_layer_in_both_tool_modes_and_saves_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked style_icons_edit_the_selected_layer_with_one_undo_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_gradient_icons_apply_cancel_and_restart -- --nocapture"
|
|
],
|
|
"expected": "native gradient icons persist reset and preserve legacy defaults; opaque ramp has no checkerboard fringe at fractional pixel edges; genuinely transparent ramp still shows checkerboard at both scales; options bar swatch opens the editor and reaches the gradients panel; the options bar ribbon opens the editor only in classic mode; the ramp covers its checkerboard at half pixel offsets; selected editor opacity commits once and delete preserves minimum; preset editor opacity fields do not edit document history; editor browser expands groups and selects without opening the sidebar; layer browser replaces color and opacity preserves geometry and undoes once; classic browser and editor edit the tool even with a gradient layer selected; picking a preset discards an uncommitted location draft; toolbar popup selects in both modes without creating a layer; editor browser can choose presets without a document; browser new saves the edited layer instead of the tool gradient; double clicking an editor preset does not create another layer; presets can collapse to reach controls in a small window across themes; properties dropdown edits the layer in both tool modes and saves it; style icons edit the selected layer with one undo step; native gradient icons apply cancel and restart",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked native_gradient_icons_persist_reset_and_preserve_legacy_defaults -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked opaque_ramp_has_no_checkerboard_fringe_at_fractional_pixel_edges -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked genuinely_transparent_ramp_still_shows_checkerboard_at_both_scales -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked options_bar_swatch_opens_the_editor_and_reaches_the_gradients_panel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_options_bar_ribbon_opens_the_editor_only_in_classic_mode -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_ramp_covers_its_checkerboard_at_half_pixel_offsets -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked selected_editor_opacity_commits_once_and_delete_preserves_minimum -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preset_editor_opacity_fields_do_not_edit_document_history -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked editor_browser_expands_groups_and_selects_without_opening_the_sidebar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_browser_replaces_color_and_opacity_preserves_geometry_and_undoes_once -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked classic_browser_and_editor_edit_the_tool_even_with_a_gradient_layer_selected -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked picking_a_preset_discards_an_uncommitted_location_draft -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked toolbar_popup_selects_in_both_modes_without_creating_a_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked editor_browser_can_choose_presets_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked browser_new_saves_the_edited_layer_instead_of_the_tool_gradient -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked double_clicking_an_editor_preset_does_not_create_another_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_can_collapse_to_reach_controls_in_a_small_window_across_themes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked properties_dropdown_edits_the_layer_in_both_tool_modes_and_saves_it -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked style_icons_edit_the_selected_layer_with_one_undo_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked native_gradient_icons_apply_cancel_and_restart -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "native_gradient_icons_persist_reset_and_preserve_legacy_defaults",
|
|
"path": "crates/engine/src/prefs/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked native_gradient_icons_persist_reset_and_preserve_legacy_defaults -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let history = s.active().unwrap().history.past_len();\n assert!(!s.prefs().interface.native_gradient_icons);\n s.execute(\"prefs.set\", json!({\"path\": \"interface.nativeGradientIcons\", \"value\": true})).unwrap();\n let mut restarted = Session::new();\n restarted.load_prefs_json(&s.prefs_to_json()).unwrap();\n assert!(restarted.prefs().interface.native_gradient_icons);\n assert_eq!(s.active().unwrap().history.past_len(), history);\n s.execute(\"prefs.reset\", json!({\"path\": \"interface.nativeGradientIcons\"})).unwrap();\n assert!(!s.prefs().interface.native_gradient_icons);\n let before = s.prefs().to_json();\n for invalid in [json!(\"true\"), json!(1), Value::Null] {",
|
|
"expected_assertions": [
|
|
" assert!(!s.prefs().interface.native_gradient_icons);\n s.execute(\"prefs.set\", json!({\"path\": \"interface.nativeGradientIcons\", \"value\": true})).unwrap();\n let mut restarted = Session::new();\n restarted.load_prefs_json(&s.prefs_to_json()).unwrap();\n assert!(restarted.prefs().interface.native_gradient_icons);\n assert_eq!(s.active().unwrap().history.past_len(), history);\n s.execute(\"prefs.reset\", json!({\"path\": \"interface.nativeGradientIcons\"})).unwrap();\n assert!(!s.prefs().interface.native_gradient_icons);\n let before = s.prefs().to_json();\n for invalid in [json!(\"true\"), json!(1), Value::Null] {\n assert!(s.execute(\"prefs.set\", json!({\"values\": {\"interface.showTooltips\": false, \"interface.nativeGradientIcons\": invalid}})).is_err());\n assert_eq!(s.prefs().to_json(), before, \"invalid updates are atomic\");\n }\n restarted.load_prefs_json(r#\"{\"interface\":{\"showTooltips\":false}}\"#).unwrap();\n assert!(!restarted.prefs().interface.native_gradient_icons);\n assert!(!restarted.prefs().interface.show_tooltips);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/engine/src/prefs/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "opaque_ramp_has_no_checkerboard_fringe_at_fractional_pixel_edges",
|
|
"path": "crates/ui-egui/src/gradient_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked opaque_ramp_has_no_checkerboard_fringe_at_fractional_pixel_edges -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::Harness;\n for scale in [1.0, 2.0] {\n let edge = 20.0 + 0.3 / scale;\n let rect = Rect::from_min_size(pos2(edge, edge), vec2(96.0, 20.0));\n let Ok(mut h) = std::panic::catch_unwind(|| {\n Harness::builder().with_size(vec2(160.0, 80.0)).with_pixels_per_point(scale).wgpu().build_ui(move |ui| {\n paint_ramp(ui.painter(), rect, |_| [0.1, 0.25, 0.2, 1.0]);\n })\n }) else {\n eprintln!(\"skipping: no GPU adapter\");\n return;\n };",
|
|
"expected_assertions": [
|
|
" assert!(pixel[channel].abs_diff(background[channel]) <= 2, \"scale={scale} at ({right}, {y}): {pixel:?} vs {background:?}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "genuinely_transparent_ramp_still_shows_checkerboard_at_both_scales",
|
|
"path": "crates/ui-egui/src/gradient_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked genuinely_transparent_ramp_still_shows_checkerboard_at_both_scales -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::Harness;\n for scale in [1.0, 2.0] {\n let Ok(mut h) = std::panic::catch_unwind(|| {\n Harness::builder().with_size(vec2(160.0, 80.0)).with_pixels_per_point(scale).wgpu().build_ui(|ui| {\n paint_ramp(ui.painter(), Rect::from_min_size(pos2(20.0, 20.0), vec2(96.0, 20.0)), |_| [0.1, 0.25, 0.2, 0.0]);\n })\n }) else {\n eprintln!(\"skipping: no GPU adapter\");\n return;\n };\n h.run_steps(3);\n let image = h.render().unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(a[0].abs_diff(b[0]) >= 30, \"scale={scale}: {a:?} vs {b:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "options_bar_swatch_opens_the_editor_and_reaches_the_gradients_panel",
|
|
"path": "crates/ui-egui/src/gradient_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked options_bar_swatch_opens_the_editor_and_reaches_the_gradients_panel -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let mut app = app_with_gradient(\"linear\");\n app.ui.tool_options.gradient_classic = true;\n let mut h = Harness::builder().with_size(vec2(440.0, 560.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n if preset_swatch(app, ui) {\n app.ui.panels.gradient_editor = true;\n }\n let ctx = ui.ctx().clone();\n editor_window(app, &ctx);\n },\n app,",
|
|
"expected_assertions": [
|
|
" assert!(h.state().ui.panels.gradient_editor, \"the swatch opened the editor window\");\n // Collapse the embedded browser to reach the sidebar shortcut on a small screen.\n h.get_all_by_label(\"Presets\").last().unwrap().click();\n h.run_steps(8);\n assert!(h.state().ui.panels.color, \"the Gradients panel opened\");\n assert_eq!(h.state().ui.dock_tabs.color, 2, \"on the Gradients tab\");\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 1, \"no document layers edited\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_options_bar_ribbon_opens_the_editor_only_in_classic_mode",
|
|
"path": "crates/ui-egui/src/gradient_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_options_bar_ribbon_opens_the_editor_only_in_classic_mode -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n for classic in [false, true] {\n let mut app = app_with_gradient(\"linear\");\n app.ui.tool_options.gradient_classic = classic;\n let mut h = egui_kittest::Harness::builder().with_size(vec2(1400.0, 900.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n crate::panels::options_bar(app, ui);\n let ctx = ui.ctx().clone();\n editor_window(app, &ctx);\n },\n app,",
|
|
"expected_assertions": [
|
|
" assert!(!h.state().ui.panels.gradient_editor, \"classic={classic}: starts closed\");\n if classic {\n h.get_by_label(\"Gradient picker\").click();\n } else {\n assert_eq!(h.state().ui.panels.gradient_editor, classic, \"classic={classic}: ribbon behavior follows the mode\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_ramp_covers_its_checkerboard_at_half_pixel_offsets",
|
|
"path": "crates/ui-egui/src/gradient_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_ramp_covers_its_checkerboard_at_half_pixel_offsets -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n for ppp in [1.0, 2.0] {\n ctx.set_pixels_per_point(ppp);\n let r = Rect::from_min_size(pos2(10.0 + 0.5 / ppp, 7.0 + 0.5 / ppp), vec2(96.0, 20.0));\n // The new scale applies from the next frame.\n ctx.run_ui(egui::RawInput::default(), |_| {}).textures_delta.clear();\n let mut painted_at = 0.0;\n let mut out = ctx.run_ui(egui::RawInput::default(), |ui| {\n painted_at = ui.ctx().pixels_per_point();\n // Translucent, so the checkerboard is drawn under it.\n paint_ramp(ui.painter(), r, |u| [u, u, u, 0.5]);\n });",
|
|
"expected_assertions": [
|
|
" assert_eq!(painted_at, ppp);\n let checker = out\n .shapes\n .iter()\n assert_eq!(ramp, checker.round_to_pixels(ppp), \"{ppp}x: the ramp covers every pixel of the checker\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "selected_editor_opacity_commits_once_and_delete_preserves_minimum",
|
|
"path": "crates/ui-egui/src/gradient_ui/editor_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked selected_editor_opacity_commits_once_and_delete_preserves_minimum -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(true);\n select(&mut h, 0.5, true);\n let before = sink.fill(h.state()).unwrap();\n let history = h.state().session.active().unwrap().history.past_len();\n type_number(&mut h, 0, \"35\", false);\n assert_eq!(sink.fill(h.state()).unwrap(), before, \"typing previews until committed\");\n h.key_press(egui::Key::Enter);\n h.run_steps(3);\n let after = sink.fill(h.state()).unwrap();\n assert!(matches!(&after, Fill::Gradient { opacity_stops, .. } if (opacity_stops[1].1 - 0.35).abs() < 1e-5));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 1);\n let ramp = h.get_by_label(\"Gradient stops\").rect();",
|
|
"expected_assertions": [
|
|
" assert_eq!(sink.fill(h.state()).unwrap(), before, \"typing previews until committed\");\n h.key_press(egui::Key::Enter);\n h.run_steps(3);\n let after = sink.fill(h.state()).unwrap();\n assert!(matches!(&after, Fill::Gradient { opacity_stops, .. } if (opacity_stops[1].1 - 0.35).abs() < 1e-5));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history + 1);\n let ramp = h.get_by_label(\"Gradient stops\").rect();\n h.get_all_by_label(\"Delete\").find(|n| n.rect().top() > ramp.bottom()).unwrap().click();\n h.run_steps(3);\n assert_eq!(stops.len(), 3);\n assert_eq!(opacity_stops.len(), 2);\n select(&mut h, 0.0, true);\n let ramp = h.get_by_label(\"Gradient stops\").rect();\n assert!(h.get_all_by_label(\"Delete\").find(|n| n.rect().top() > ramp.bottom()).unwrap().accesskit_node().is_disabled());\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(sink.fill(h.state()).unwrap(), after);\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(sink.fill(h.state()).unwrap(), before);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(sink.fill(h.state()).unwrap(), after);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/editor_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preset_editor_opacity_fields_do_not_edit_document_history",
|
|
"path": "crates/ui-egui/src/gradient_ui/editor_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preset_editor_opacity_fields_do_not_edit_document_history -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(false);\n let before = h.state().session.active().unwrap().doc.clone();\n let history = h.state().session.active().unwrap().history.past_len();\n select(&mut h, 0.5, true);\n type_number(&mut h, 0, \"35\", true);\n assert!(matches!(sink.fill(h.state()).unwrap(), Fill::Gradient { opacity_stops, .. } if (opacity_stops[1].1 - 0.35).abs() < 1e-5));\n let ramp = h.get_by_label(\"Gradient stops\").rect();\n h.get_all_by_label(\"Delete\").find(|n| n.rect().top() > ramp.bottom()).unwrap().click();\n h.run_steps(3);\n assert!(matches!(sink.fill(h.state()).unwrap(), Fill::Gradient { stops, opacity_stops, .. } if stops.len() == 3 && opacity_stops.len() == 2));\n assert_eq!(h.state().session.active().unwrap().doc, before);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);",
|
|
"expected_assertions": [
|
|
" assert!(matches!(sink.fill(h.state()).unwrap(), Fill::Gradient { opacity_stops, .. } if (opacity_stops[1].1 - 0.35).abs() < 1e-5));\n let ramp = h.get_by_label(\"Gradient stops\").rect();\n h.get_all_by_label(\"Delete\").find(|n| n.rect().top() > ramp.bottom()).unwrap().click();\n h.run_steps(3);\n assert!(matches!(sink.fill(h.state()).unwrap(), Fill::Gradient { stops, opacity_stops, .. } if stops.len() == 3 && opacity_stops.len() == 2));\n assert_eq!(h.state().session.active().unwrap().doc, before);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), history);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/editor_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "editor_browser_expands_groups_and_selects_without_opening_the_sidebar",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked editor_browser_expands_groups_and_selects_without_opening_the_sidebar -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(false);\n let tab = h.state().ui.dock_tabs.color;\n h.get_by_label(\"Purples\").click();\n h.run_steps(3);\n h.get_by_label(\"Purple 03\").click();\n h.run_steps(3);\n assert_eq!(h.state().session.presets.gradient.name, \"Purple 03\");\n assert!(matches!(sink.fill(h.state()), Some(Fill::Gradient { stops, .. }) if stops.len() == 3));\n assert_eq!(h.state().ui.dock_tabs.color, tab);\n assert!(h.state().ui.panels.gradient_editor);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 1);\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.presets.gradient.name, \"Purple 03\");\n assert!(matches!(sink.fill(h.state()), Some(Fill::Gradient { stops, .. }) if stops.len() == 3));\n assert_eq!(h.state().ui.dock_tabs.color, tab);\n assert!(h.state().ui.panels.gradient_editor);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_browser_replaces_color_and_opacity_preserves_geometry_and_undoes_once",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_browser_replaces_color_and_opacity_preserves_geometry_and_undoes_once -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(true);\n let before = sink.fill(h.state()).unwrap();\n let count = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(3);\n let after = sink.fill(h.state()).unwrap();\n let Fill::Gradient { angle, scale, style, reverse, offset, dither, align, .. } = before.clone() else { panic!() };\n let Fill::Gradient { angle: a, scale: s, style: st, reverse: r, offset: o, dither: d, align: al, stops, opacity_stops, midpoints } = &after else {\n panic!()\n };\n assert_eq!((*a, *s, *st, *r, *o, *d, *al), (angle, scale, style, reverse, offset, dither, align));\n assert_eq!(stops.len(), 2);",
|
|
"expected_assertions": [
|
|
" assert_eq!((*a, *s, *st, *r, *o, *d, *al), (angle, scale, style, reverse, offset, dither, align));\n assert_eq!(stops.len(), 2);\n assert_eq!(opacity_stops, &vec![(0.0, 1.0), (1.0, 0.0)]);\n assert!(midpoints.is_empty());\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 2);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count + 1);\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(sink.fill(h.state()).unwrap(), before);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(sink.fill(h.state()).unwrap(), after);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "classic_browser_and_editor_edit_the_tool_even_with_a_gradient_layer_selected",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked classic_browser_and_editor_edit_the_tool_even_with_a_gradient_layer_selected -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, layer) = editor(true);\n h.state_mut().ui.tool_options.gradient_classic = true;\n h.run_steps(3);\n let before = layer.fill(h.state());\n let count = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(3);\n assert_eq!(layer.fill(h.state()), before);\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count);\n assert!(h.query_by_label(\"Gradient Options\").is_none());\n h.query_all_by_label(\"Color\").find(|n| n.accesskit_node().role() == egui::accesskit::Role::Button).unwrap().click();",
|
|
"expected_assertions": [
|
|
" assert_eq!(layer.fill(h.state()), before);\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count);\n assert!(h.query_by_label(\"Gradient Options\").is_none());\n h.query_all_by_label(\"Color\").find(|n| n.accesskit_node().role() == egui::accesskit::Role::Button).unwrap().click();\n h.run_steps(2);\n assert!(!h.state().ui.dialogs.is_empty());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "picking_a_preset_discards_an_uncommitted_location_draft",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked picking_a_preset_discards_an_uncommitted_location_draft -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(true);\n let count = h.state().session.active().unwrap().history.past_len();\n type_number(&mut h, 0, \"70\", false);\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(4);\n assert!(matches!(sink.fill(h.state()), Some(Fill::Gradient { stops, .. }) if stops[0].0 == 0.0));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count + 1);\n}",
|
|
"expected_assertions": [
|
|
" assert!(matches!(sink.fill(h.state()), Some(Fill::Gradient { stops, .. }) if stops[0].0 == 0.0));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count + 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "toolbar_popup_selects_in_both_modes_without_creating_a_layer",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked toolbar_popup_selects_in_both_modes_without_creating_a_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " for classic in [false, true] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 200, \"height\": 120})).unwrap();\n app.ui.tool = Tool::Gradient;\n app.ui.tool_options.gradient_classic = classic;\n let mut h = Harness::builder().with_size(vec2(1000.0, 800.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n if preset_swatch(app, ui) {\n app.ui.panels.gradient_editor = true;\n }\n },\n app,",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 1);\n assert!(!h.state().ui.panels.gradient_editor);\n assert!(h.query_by_label(\"Basics\").is_none(), \"popup closes after choosing a preset\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "editor_browser_can_choose_presets_without_a_document",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked editor_browser_can_choose_presets_without_a_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let mut h = Harness::builder().with_size(vec2(1000.0, 900.0)).build_ui_state(|ui, app: &mut PhotocraftApp| editor_window(app, ui.ctx()), app);\n PhotocraftApp::setup_context(&h.ctx, crate::theme::ThemeKind::ProMedium);\n h.state_mut().ui.panels.gradient_editor = true;\n h.run_steps(3);\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(3);\n assert!(h.state().session.active().is_none());\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n}",
|
|
"expected_assertions": [
|
|
" assert!(h.state().session.active().is_none());\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "browser_new_saves_the_edited_layer_instead_of_the_tool_gradient",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked browser_new_saves_the_edited_layer_instead_of_the_tool_gradient -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, sink) = editor(true);\n let before = sink.fill(h.state());\n let count = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(\"Create new gradient\").click();\n h.run_steps(3);\n let saved = h.state().session.presets.gradients.iter().flat_map(|g| &g.items).find(|p| p.name == \"Custom\").unwrap();\n assert_eq!(saved.stops.len(), 3);\n assert_eq!(saved.opacity, vec![(0.0, 0.25), (0.5, 0.6), (1.0, 1.0)]);\n assert_eq!(sink.fill(h.state()), before);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count);\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(saved.stops.len(), 3);\n assert_eq!(saved.opacity, vec![(0.0, 0.25), (0.5, 0.6), (1.0, 1.0)]);\n assert_eq!(sink.fill(h.state()), before);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "double_clicking_an_editor_preset_does_not_create_another_layer",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked double_clicking_an_editor_preset_does_not_create_another_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, _) = editor(true);\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(2);\n h.get_by_label(\"Foreground to Transparent\").click();\n h.run_steps(3);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 2);\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 2);\n assert_eq!(h.state().session.presets.gradient.name, \"Foreground to Transparent\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "presets_can_collapse_to_reach_controls_in_a_small_window_across_themes",
|
|
"path": "crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked presets_can_collapse_to_reach_controls_in_a_small_window_across_themes -- --nocapture",
|
|
"fixture_and_action_excerpt": " for theme in crate::theme::ThemeKind::ALL {\n let (mut h, _) = editor(true);\n PhotocraftApp::setup_context(&h.ctx, theme);\n h.set_size(vec2(440.0, 560.0));\n h.run_steps(4);\n h.get_by_label(\"Presets\").click();\n h.run_steps(8);\n let reset = h.get_by_label(\"Reset Alignment\").rect();\n assert!(reset.left() >= 0.0 && reset.right() <= 440.0 && reset.bottom() <= 560.0, \"{theme:?}: {reset:?}\");\n h.get_by_label(\"Reset Alignment\").click();\n h.run_steps(3);\n assert!(h.state().ui.panels.gradient_editor);",
|
|
"expected_assertions": [
|
|
" assert!(reset.left() >= 0.0 && reset.right() <= 440.0 && reset.bottom() <= 560.0, \"{theme:?}: {reset:?}\");\n h.get_by_label(\"Reset Alignment\").click();\n h.run_steps(3);\n assert!(h.state().ui.panels.gradient_editor);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/preset_browser_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "properties_dropdown_edits_the_layer_in_both_tool_modes_and_saves_it",
|
|
"path": "crates/ui-egui/src/gradient_ui/properties_panel.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked properties_dropdown_edits_the_layer_in_both_tool_modes_and_saves_it -- --nocapture",
|
|
"fixture_and_action_excerpt": " for classic in [false, true] {\n let mut app = app();\n app.ui.tool_options.gradient_classic = classic;\n let mut h = Harness::builder().with_size(vec2(1000.0, 800.0)).build_ui_state(\n |ui, app: &mut PhotocraftApp| {\n ui.set_width(280.0);\n panel(ui, app);\n },\n app,\n );\n PhotocraftApp::setup_context(&h.ctx, theme::ThemeKind::ProMedium);\n h.run_steps(3);",
|
|
"expected_assertions": [
|
|
" assert!(arrow.left() >= strip.right() && arrow.right() - strip.left() <= 280.0, \"{arrow:?} beside {strip:?}\");\n assert!((arrow.center().y - (strip.top() + 28.0)).abs() < 1.0);\n h.get_by_label(\"Presets\").click();\n h.run_steps(3);\n h.get_by_label(\"Create new gradient\").click();\n assert_eq!(saved.opacity, vec![(0.0, 0.2), (1.0, 1.0)]);\n assert_eq!(saved.resolve([0.0; 4], [0.0; 4])[0].1, [1.0, 0.0, 0.0, 0.2]);\n assert_eq!(fill(h.state()), original);\n h.key_press(egui::Key::Escape);\n h.run_steps(3);\n h.get_by_label(\"Presets\").click();\n assert!(matches!(fill(h.state()), Fill::Gradient { opacity_stops, .. } if opacity_stops == vec![(0.0, 1.0), (1.0, 0.0)]));\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count + 1);\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 2);\n assert!(h.query_by_label(\"Basics\").is_none());\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(fill(h.state()), original);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/properties_panel.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "style_icons_edit_the_selected_layer_with_one_undo_step",
|
|
"path": "crates/ui-egui/src/gradient_ui/properties_panel.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked style_icons_edit_the_selected_layer_with_one_undo_step -- --nocapture",
|
|
"fixture_and_action_excerpt": " for native_icons in [false, true] {\n let mut app = app();\n app.run(\"prefs.set\", json!({\"path\": \"interface.nativeGradientIcons\", \"value\": native_icons})).unwrap();\n let mut h = Harness::builder().with_size(vec2(280.0, 800.0)).build_ui_state(panel, app);\n PhotocraftApp::setup_context(&h.ctx, theme::ThemeKind::ProMedium);\n h.run_steps(3);\n for (style, name) in STYLES.into_iter().skip(1) {\n let before = fill(h.state());\n let count = h.state().session.active().unwrap().history.past_len();\n h.get_by_label(name).click();\n h.run_steps(3);\n let after = fill(h.state());",
|
|
"expected_assertions": [
|
|
" assert!(matches!(&after, Fill::Gradient { style: actual, .. } if *actual == style));\n assert_eq!(h.state().session.active().unwrap().doc.layers.len(), 2);\n assert_eq!(h.state().session.active().unwrap().history.past_len(), count + 1);\n h.state_mut().run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(fill(h.state()), before);\n h.state_mut().run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(fill(h.state()), after);\n h.run_steps(2);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/gradient_ui/properties_panel.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "native_gradient_icons_apply_cancel_and_restart",
|
|
"path": "crates/ui-egui/src/prefs_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked native_gradient_icons_apply_cancel_and_restart -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n let (mut app, store) = app_with_store();\n app.run(\"prefs.set\", json!({\"path\": \"interface.language\", \"value\": \"en\"})).unwrap();\n let id = open_preferences(&mut app, \"interface\");\n let mut h = Harness::builder().with_size(vec2(1280.0, 800.0)).build_eframe(move |cc| {\n PhotocraftApp::setup_context(&cc.egui_ctx, Default::default());\n app\n });\n h.run_steps(4);\n h.get_by_label(\"Use PhotoCraft-native gradient icons\").scroll_to_me();\n h.run_steps(4);\n for desired in [true, false] {",
|
|
"expected_assertions": [
|
|
" assert_eq!(h.state().session.prefs().interface.native_gradient_icons, !desired, \"draft waits for Apply\");\n h.get_by_label(\"Apply\").click();\n h.run_steps(4);\n assert_eq!(h.state().session.prefs().interface.native_gradient_icons, desired);\n assert_eq!(stored(&store)[\"interface\"][\"nativeGradientIcons\"], desired);\n let (restarted, _) = app_with_saved(store.lock().unwrap().clone());\n assert_eq!(restarted.session.prefs().interface.native_gradient_icons, desired);\n }\n h.get_by_label(\"Use PhotoCraft-native gradient icons\").click();\n h.run_steps(4);\n assert!(h.state().ui.dialogs.iter().all(|d| d.id != id));\n assert!(!h.state().session.prefs().interface.native_gradient_icons);\n assert_eq!(stored(&store)[\"interface\"][\"nativeGradientIcons\"], false);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/bfb691f84896fe68543980426632153dc4b4ea69/crates/ui-egui/src/prefs_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3461",
|
|
"pr": 3461,
|
|
"subsystem": "Actions and automation",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked recorded_eye_visibility_replays_on_another_document_and_duplicate_names -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shell_playback_resolves_recorded_eye_target_on_new_document -- --nocapture"
|
|
],
|
|
"expected": "recorded eye visibility replays on another document and duplicate names; shell playback resolves recorded eye target on new document",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked recorded_eye_visibility_replays_on_another_document_and_duplicate_names -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked shell_playback_resolves_recorded_eye_target_on_new_document -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "recorded_eye_visibility_replays_on_another_document_and_duplicate_names",
|
|
"path": "crates/engine/src/actions_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked recorded_eye_visibility_replays_on_another_document_and_duplicate_names -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n s.execute(\"layer.new.layer\", json!({\"name\": \"Same\"})).unwrap();\n let hidden = s.execute(\"layer.new.layer\", json!({\"name\": \"Same\"})).unwrap()[\"layer\"].as_u64().unwrap();\n s.execute(\"actions.record\", json!({\"name\": \"Hide\"})).unwrap();\n s.execute(\"layer.setProps\", json!({\"layer\": hidden, \"visible\": false, \"coalesce\": \"eye-sweep\"})).unwrap();\n s.execute(\"actions.stop\", json!({})).unwrap();\n s.execute(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n let keep = s.execute(\"layer.new.layer\", json!({\"name\": \"Same\"})).unwrap()[\"layer\"].as_u64().unwrap();\n let target = s.execute(\"layer.new.layer\", json!({\"name\": \"Same\"})).unwrap()[\"layer\"].as_u64().unwrap();\n s.execute(\"select.deselectLayers\", json!({})).unwrap();\n let result = s.execute(\"actions.play\", json!({\"action\": \"Hide\"})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(result.get(\"failed\").is_none(), \"{result}\");\n assert!(s.active().unwrap().doc.layer(photocraft_doc::LayerId(keep)).unwrap().visible);\n assert!(!s.active().unwrap().doc.layer(photocraft_doc::LayerId(target)).unwrap().visible);\n s.execute(\"edit.undo\", json!({})).unwrap();\n assert!(s.active().unwrap().doc.layer(photocraft_doc::LayerId(target)).unwrap().visible);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5d8cb2a39ad70e31260f1f3fc2010ca132daff65/crates/engine/src/actions_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "shell_playback_resolves_recorded_eye_target_on_new_document",
|
|
"path": "crates/ui-egui/src/actions.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked shell_playback_resolves_recorded_eye_target_on_new_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n app.run(\"layer.new.layer\", json!({\"name\": \"Target\"})).unwrap();\n app.run(\"actions.record\", json!({\"name\": \"Hide\"})).unwrap();\n let id = app.session.active().unwrap().active_layer.unwrap();\n app.run(\"layer.setProps\", json!({\"layer\": id.0, \"visible\": false})).unwrap();\n app.run(\"actions.stop\", json!({})).unwrap();\n app.run(\"file.new\", json!({\"width\": 8, \"height\": 8})).unwrap();\n app.run(\"layer.new.layer\", json!({\"name\": \"Target\"})).unwrap();\n let id = app.session.active().unwrap().active_layer.unwrap();\n let result = play(&mut app, &json!({\"action\": \"Hide\"})).unwrap();\n assert!(result.get(\"failed\").is_none(), \"{result}\");",
|
|
"expected_assertions": [
|
|
" assert!(result.get(\"failed\").is_none(), \"{result}\");\n assert!(!app.session.active().unwrap().doc.layer(id).unwrap().visible);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/5d8cb2a39ad70e31260f1f3fc2010ca132daff65/crates/ui-egui/src/actions.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-3520",
|
|
"pr": 3520,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked studio_dark_keeps_square_colour_chips -- --nocapture"
|
|
],
|
|
"expected": "studio dark keeps square colour chips",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked studio_dark_keeps_square_colour_chips -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "studio_dark_keeps_square_colour_chips",
|
|
"path": "crates/ui-egui/src/theme.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked studio_dark_keeps_square_colour_chips -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert!(!Tokens::for_kind(ThemeKind::Studio).round_chips);\n // Only the dark variant changes; the light palette retains its layout.\n assert!(Tokens::for_kind(ThemeKind::StudioLight).round_chips);\n assert!(!Tokens::for_kind(ThemeKind::Pro).round_chips);\n }",
|
|
"expected_assertions": [
|
|
" assert!(!Tokens::for_kind(ThemeKind::Studio).round_chips);\n // Only the dark variant changes; the light palette retains its layout.\n assert!(Tokens::for_kind(ThemeKind::StudioLight).round_chips);\n assert!(!Tokens::for_kind(ThemeKind::Pro).round_chips);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d36ec9a21e9c1ed70de2e0d185efd7e084644157/crates/ui-egui/src/theme.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4035",
|
|
"pr": 4035,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked flatten_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked stamp_visible_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked background_from_layer_keeps_the_inks_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked flatten_of_a_partly_transparent_layer_still_composites_over_white -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_down_separates_through_the_document_profile -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_visible_separates_through_the_document_profile -- --nocapture",
|
|
"cargo test -p photocraft-io --locked cmyk_merged_composite_reads_through_the_embedded_profile -- --nocapture"
|
|
],
|
|
"expected": "flatten keeps the inks of a single layer exactly; stamp visible keeps the inks of a single layer exactly; background from layer keeps the inks exactly; flatten of a partly transparent layer still composites over white; merge down separates through the document profile; merge visible separates through the document profile; cmyk merged composite reads through the embedded profile",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked flatten_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked stamp_visible_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked background_from_layer_keeps_the_inks_exactly -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked flatten_of_a_partly_transparent_layer_still_composites_over_white -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_down_separates_through_the_document_profile -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked merge_visible_separates_through_the_document_profile -- --nocapture",
|
|
"cargo test -p photocraft-io --locked cmyk_merged_composite_reads_through_the_embedded_profile -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "flatten_keeps_the_inks_of_a_single_layer_exactly",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked flatten_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"fixture_and_action_excerpt": " exact(\"Flatten Image\", |s| {\n s.execute(\"layer.flattenImage\", json!({})).unwrap();\n });\n}",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stamp_visible_keeps_the_inks_of_a_single_layer_exactly",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked stamp_visible_keeps_the_inks_of_a_single_layer_exactly -- --nocapture",
|
|
"fixture_and_action_excerpt": " exact(\"Stamp Visible\", |s| {\n s.execute(\"layer.stampVisible\", json!({})).unwrap();\n });\n}",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "background_from_layer_keeps_the_inks_exactly",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked background_from_layer_keeps_the_inks_exactly -- --nocapture",
|
|
"fixture_and_action_excerpt": " exact(\"Background from Layer\", |s| {\n s.execute(\"layer.new.layerFromBackground\", json!({})).unwrap();\n s.execute(\"layer.new.backgroundFromLayer\", json!({})).unwrap();\n });\n}",
|
|
"expected_assertions": [],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "flatten_of_a_partly_transparent_layer_still_composites_over_white",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked flatten_of_a_partly_transparent_layer_still_composites_over_white -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16] {\n let mut s = document(depth, true);\n s.edit(\"hole\", |doc, _| {\n doc.layers[0].surface_mut().unwrap().write_pixel(0, 0, &[0.0, 0.0, 0.0, 1.0, 0.0]);\n Ok(())\n })\n .unwrap();\n s.execute(\"layer.flattenImage\", json!({})).unwrap();\n let px = inks(&s)[0];\n // Transparent over white paper: no ink, not the hidden K.\n assert!(px.iter().all(|v| *v < 0.02), \"{depth}-bit: {px:?}\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(px.iter().all(|v| *v < 0.02), \"{depth}-bit: {px:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merge_down_separates_through_the_document_profile",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merge_down_separates_through_the_document_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16] {\n let d = drift(depth, true, 0, |s| {\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"layer.mergeDown\", json!({})).unwrap();\n });\n assert!(d <= ROUND_TRIP, \"{depth}-bit Merge Down: inks moved by {d}\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(d <= ROUND_TRIP, \"{depth}-bit Merge Down: inks moved by {d}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "merge_visible_separates_through_the_document_profile",
|
|
"path": "crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked merge_visible_separates_through_the_document_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16] {\n let d = drift(depth, true, 0, |s| {\n s.execute(\"layer.new.layer\", json!({})).unwrap();\n s.execute(\"layer.mergeVisible\", json!({})).unwrap();\n });\n assert!(d <= ROUND_TRIP, \"{depth}-bit Merge Visible: inks moved by {d}\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(d <= ROUND_TRIP, \"{depth}-bit Merge Visible: inks moved by {d}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/engine/tests/cmyk_flatten_profile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cmyk_merged_composite_reads_through_the_embedded_profile",
|
|
"path": "crates/io/tests/color.rs",
|
|
"package": "photocraft-io",
|
|
"command": "cargo test -p photocraft-io --locked cmyk_merged_composite_reads_through_the_embedded_profile -- --nocapture",
|
|
"fixture_and_action_excerpt": " // The merged image of a CMYK file tagged with a non-default profile is turned into RGB through\n // that profile, as the layers are, or every comparison against it is off (#3778).\n use photocraft_cms::{Intent, Transform};\n use photocraft_psd::{Compression, ImageResource, Version, testgen};\n let profile = photocraft_cms::synth::cmyk_profile(&photocraft_cms::synth::CmykParams {\n tvi: [0.26, 0.26, 0.26, 0.3],\n grid_a2b: 5,\n grid_b2a: 9,\n ..Default::default()\n });\n let reference = |p: &Profile, ink: &[f32; 4]| {\n let t = Transform::new(p, Builtin::Srgb.profile(), Intent::RelativeColorimetric, true).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!((px[k] - want[k]).abs() <= 2.0 / 255.0, \"{depth}-bit {ink:?}: {px:?} vs {want:?} (built-in {coated:?})\");\n }\n }\n assert!(seen_far, \"the fixture profile differs from the built-in one\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/15ebf8fc940031abdf772e5fdd687c8b55938639/crates/io/tests/color.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4042",
|
|
"pr": 4042,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked middle_drag_rotates_about_the_pointer_without_panning -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked middle_drag_ignores_invalid_or_stationary_input -- --nocapture"
|
|
],
|
|
"expected": "middle drag rotates about the pointer without panning; middle drag ignores invalid or stationary input",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked middle_drag_rotates_about_the_pointer_without_panning -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked middle_drag_ignores_invalid_or_stationary_input -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "middle_drag_rotates_about_the_pointer_without_panning",
|
|
"path": "crates/ui-egui/src/rotate_view.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked middle_drag_rotates_about_the_pointer_without_panning -- --nocapture",
|
|
"fixture_and_action_excerpt": " let rect = Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0));\n let pointer = pos2(600.0, 180.0);\n for flip in [false, true] {\n let mut view = View { zoom: 2.0, center: [130.0, 80.0], ..Default::default() };\n let xf = ViewXform { rect, zoom: 2.0, center: view.center, flip, rotation: 0.0, aspect: 1.25 };\n let original = xf.to_doc(pointer);\n assert!(middle_drag(&mut view, &xf, pointer, 90.0));\n assert!((view.rotation - 31.5).abs() < 0.001);\n let next = ViewXform { center: view.center, rotation: view.rotation, ..xf }.to_doc(pointer);\n assert!((next[0] - original[0]).abs() < 0.001 && (next[1] - original[1]).abs() < 0.001, \"{original:?} {next:?}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(middle_drag(&mut view, &xf, pointer, 90.0));\n assert!((view.rotation - 31.5).abs() < 0.001);\n let next = ViewXform { center: view.center, rotation: view.rotation, ..xf }.to_doc(pointer);\n assert!((next[0] - original[0]).abs() < 0.001 && (next[1] - original[1]).abs() < 0.001, \"{original:?} {next:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f05098562220a663d052ee3918fd36c8c3e17a51/crates/ui-egui/src/rotate_view.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "middle_drag_ignores_invalid_or_stationary_input",
|
|
"path": "crates/ui-egui/src/rotate_view.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked middle_drag_ignores_invalid_or_stationary_input -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut view = View::default();\n let xf = ViewXform {\n rect: Rect::from_min_size(pos2(0.0, 0.0), vec2(600.0, 400.0)),\n zoom: 1.0,\n center: view.center,\n flip: false,\n rotation: 0.0,\n aspect: 1.0,\n };\n assert!(!middle_drag(&mut view, &xf, pos2(200.0, 120.0), 0.0));\n assert!(!middle_drag(&mut view, &xf, pos2(200.0, 120.0), f32::NAN));\n assert!(!middle_drag(&mut view, &xf, pos2(f32::INFINITY, 120.0), 20.0));",
|
|
"expected_assertions": [
|
|
" assert!(!middle_drag(&mut view, &xf, pos2(200.0, 120.0), 0.0));\n assert!(!middle_drag(&mut view, &xf, pos2(200.0, 120.0), f32::NAN));\n assert!(!middle_drag(&mut view, &xf, pos2(f32::INFINITY, 120.0), 20.0));\n assert_eq!(view.rotation, 0.0);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/f05098562220a663d052ee3918fd36c8c3e17a51/crates/ui-egui/src/rotate_view.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4547",
|
|
"pr": 4547,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft --locked windows_and_linux_icons_keep_the_round_corners -- --nocapture"
|
|
],
|
|
"expected": "windows and linux icons keep the round corners",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft --locked windows_and_linux_icons_keep_the_round_corners -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "windows_and_linux_icons_keep_the_round_corners",
|
|
"path": "apps/photocraft/src/app_icon.rs",
|
|
"package": "photocraft",
|
|
"command": "cargo test -p photocraft --locked windows_and_linux_icons_keep_the_round_corners -- --nocapture",
|
|
"fixture_and_action_excerpt": " // rx=112 of 512 leaves (10, 10) of a 256 px render transparent; the old crop filled it (#4478).\n let png = include_bytes!(\"../../../assets/app-icon/hicolor/256x256/apps/ai.storyteller.photocraft.png\");\n let icon = eframe::icon_data::from_png_bytes(png).unwrap();\n assert_eq!(icon.width, 256);\n assert_eq!(icon.rgba[(10 * 256 + 10) * 4 + 3], 0, \"corner is transparent\");\n assert_eq!(icon.rgba[(128 * 256 + 2) * 4 + 3], 255, \"the tile is full bleed\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(icon.width, 256);\n assert_eq!(icon.rgba[(10 * 256 + 10) * 4 + 3], 0, \"corner is transparent\");\n assert_eq!(icon.rgba[(128 * 256 + 2) * 4 + 3], 255, \"the tile is full bleed\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/a08f7a2295488c2692f68902835a693322017b64/apps/photocraft/src/app_icon.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4883",
|
|
"pr": 4883,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked status_bounds_follow_the_actual_selection_and_active_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked status_dimensions_follow_ruler_units_and_document_resolution -- --nocapture"
|
|
],
|
|
"expected": "status bounds follow the actual selection and active layer; status dimensions follow ruler units and document resolution",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked status_bounds_follow_the_actual_selection_and_active_layer -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked status_dimensions_follow_ruler_units_and_document_resolution -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "status_bounds_follow_the_actual_selection_and_active_layer",
|
|
"path": "crates/ui-egui/src/chrome_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked status_bounds_follow_the_actual_selection_and_active_layer -- --nocapture",
|
|
"fixture_and_action_excerpt": " let d = doc();\n let id = d.layers[0].id;\n assert_eq!(status_bounds_text(&d, Some(id)), \"Layer: X 0 Y 0 W 2400 H 1500\");\n assert_eq!(status_bounds_text(&d, None), \"No selection or layer\");\n\n let mut s = photocraft_engine::Session::new();\n s.execute(\"file.new\", json!({\"width\": 120, \"height\": 80})).unwrap();\n s.execute(\"select.all\", json!({})).unwrap();\n let doc = &s.active().unwrap().doc;\n assert_eq!(status_bounds_text(doc, None), \"Selection: X 0 Y 0 W 120 H 80\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(status_bounds_text(&d, Some(id)), \"Layer: X 0 Y 0 W 2400 H 1500\");\n assert_eq!(status_bounds_text(&d, None), \"No selection or layer\");\n\n let mut s = photocraft_engine::Session::new();\n s.execute(\"file.new\", json!({\"width\": 120, \"height\": 80})).unwrap();\n assert_eq!(status_bounds_text(doc, None), \"Selection: X 0 Y 0 W 120 H 80\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ea500486fb40511d3b4782dfacbb89fbff846d8a/crates/ui-egui/src/chrome_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "status_dimensions_follow_ruler_units_and_document_resolution",
|
|
"path": "crates/ui-egui/src/chrome_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked status_dimensions_follow_ruler_units_and_document_resolution -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_engine::prefs::{PointSize, Unit, UnitsAndRulers};\n let mut d = doc();\n d.resolution_dpi = 300.0;\n for (unit, expected) in [\n (Unit::Pixels, \"2400 px x 1500 px (300 ppi)\"),\n (Unit::Inches, \"8 in x 5 in (300 ppi)\"),\n (Unit::Centimeters, \"20.32 cm x 12.7 cm (300 ppi)\"),\n (Unit::Millimeters, \"203.2 mm x 127 mm (300 ppi)\"),\n (Unit::Points, \"576 pt x 360 pt (300 ppi)\"),\n (Unit::Picas, \"48 pica x 30 pica (300 ppi)\"),\n (Unit::Percent, \"100 % x 100 % (300 ppi)\"),\n ] {",
|
|
"expected_assertions": [
|
|
" assert_eq!(status_info_text_with_units(&d, \"dimensions\", \"\", \"\", &units), expected);\n for (key, _) in STATUS_INFO.iter().filter(|(key, _)| *key != \"dimensions\" && *key != \"coordinates\") {\n assert_eq!(status_info_text_with_units(&d, key, \"Brush Tool\", \"sRGB\", &units), status_info_text(&d, key, \"Brush Tool\", \"sRGB\"));\n }\n }\n d.resolution_dpi = 240.0;\n assert_eq!(status_info_text_with_units(&d, \"dimensions\", \"\", \"\", &units), \"722.7 pt x 451.7 pt (240 ppi)\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ea500486fb40511d3b4782dfacbb89fbff846d8a/crates/ui-egui/src/chrome_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4890",
|
|
"pr": 4890,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked scrollbar_visibility_round_trips_and_old_preferences_keep_the_theme_default -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked scrollbar_visibility_applies_in_every_theme_and_survives_theme_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hidden_scrollbars_keep_wheel_scrolling_available -- --nocapture"
|
|
],
|
|
"expected": "scrollbar visibility round trips and old preferences keep the theme default; scrollbar visibility applies in every theme and survives theme changes; hidden scrollbars keep wheel scrolling available",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked scrollbar_visibility_round_trips_and_old_preferences_keep_the_theme_default -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked scrollbar_visibility_applies_in_every_theme_and_survives_theme_changes -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked hidden_scrollbars_keep_wheel_scrolling_available -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "scrollbar_visibility_round_trips_and_old_preferences_keep_the_theme_default",
|
|
"path": "crates/engine/src/prefs/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked scrollbar_visibility_round_trips_and_old_preferences_keep_the_theme_default -- --nocapture",
|
|
"fixture_and_action_excerpt": " let old = serde_json::from_value::<Preferences>(json!({\"interface\": {\"uiFontSize\": \"small\"}})).unwrap();\n assert_eq!(old.interface.scrollbar_visibility, ScrollbarVisibility::Default);\n assert_eq!(choices(\"interface.scrollbarVisibility\"), Some(ScrollbarVisibility::NAMES));\n let mut s = Session::new();\n for mode in ScrollbarVisibility::NAMES {\n s.execute(\"prefs.set\", json!({\"values\": {\"interface.scrollbarVisibility\": mode}})).unwrap();\n let saved = s.prefs().to_json();\n let loaded: Preferences = serde_json::from_value(saved.clone()).unwrap();\n assert_eq!(loaded.interface.scrollbar_visibility, s.prefs().interface.scrollbar_visibility);\n assert_eq!(saved[\"interface\"][\"scrollbarVisibility\"], json!(mode));\n }\n let before = s.prefs().to_json();",
|
|
"expected_assertions": [
|
|
" assert_eq!(old.interface.scrollbar_visibility, ScrollbarVisibility::Default);\n assert_eq!(choices(\"interface.scrollbarVisibility\"), Some(ScrollbarVisibility::NAMES));\n let mut s = Session::new();\n for mode in ScrollbarVisibility::NAMES {\n s.execute(\"prefs.set\", json!({\"values\": {\"interface.scrollbarVisibility\": mode}})).unwrap();\n assert_eq!(loaded.interface.scrollbar_visibility, s.prefs().interface.scrollbar_visibility);\n assert_eq!(saved[\"interface\"][\"scrollbarVisibility\"], json!(mode));\n }\n let before = s.prefs().to_json();\n assert!(s.execute(\"prefs.set\", json!({\"values\": {\"interface.scrollbarVisibility\": \"sometimes\"}})).is_err());\n assert_eq!(s.prefs().to_json(), before);\n s.execute(\"prefs.reset\", json!({\"path\": \"interface.scrollbarVisibility\"})).unwrap();\n assert_eq!(s.prefs().interface.scrollbar_visibility, ScrollbarVisibility::Default);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ab84cab7355ac999fb1be226950978bafec39605/crates/engine/src/prefs/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "scrollbar_visibility_applies_in_every_theme_and_survives_theme_changes",
|
|
"path": "crates/ui-egui/src/theme.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked scrollbar_visibility_applies_in_every_theme_and_survives_theme_changes -- --nocapture",
|
|
"fixture_and_action_excerpt": " use photocraft_engine::prefs::ScrollbarVisibility as Mode;\n let ctx = egui::Context::default();\n for kind in ThemeKind::ALL {\n apply(&ctx, kind);\n let original = ctx.global_style().spacing.scroll;\n sync_scrollbars(&ctx, Mode::Default);\n assert_eq!(ctx.global_style().spacing.scroll, original);\n sync_scrollbars(&ctx, Mode::Always);\n assert!(!ctx.global_style().spacing.scroll.floating);\n assert!(ctx.global_style().spacing.scroll.bar_width > 0.0);\n sync_scrollbars(&ctx, Mode::AutoHide);\n assert!(ctx.global_style().spacing.scroll.floating);",
|
|
"expected_assertions": [
|
|
" assert_eq!(ctx.global_style().spacing.scroll, original);\n sync_scrollbars(&ctx, Mode::Always);\n assert!(!ctx.global_style().spacing.scroll.floating);\n assert!(ctx.global_style().spacing.scroll.bar_width > 0.0);\n sync_scrollbars(&ctx, Mode::AutoHide);\n assert!(ctx.global_style().spacing.scroll.floating);\n assert_eq!(ctx.global_style().spacing.scroll.dormant_handle_opacity, 0.0);\n sync_scrollbars(&ctx, Mode::Hidden);\n assert_eq!(ctx.global_style().spacing.scroll.bar_width, 0.0);\n apply(&ctx, kind);\n sync_scrollbars(&ctx, Mode::Hidden);\n assert_eq!(ctx.global_style().spacing.scroll.bar_width, 0.0, \"theme changes retain the saved override\");\n sync_scrollbars(&ctx, Mode::Default);\n assert_eq!(ctx.global_style().spacing.scroll, original);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ab84cab7355ac999fb1be226950978bafec39605/crates/ui-egui/src/theme.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "hidden_scrollbars_keep_wheel_scrolling_available",
|
|
"path": "crates/ui-egui/src/theme.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked hidden_scrollbars_keep_wheel_scrolling_available -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(300.0, 120.0)).build_ui_state(\n |ui, offset: &mut f32| {\n let area = egui::ScrollArea::vertical().max_height(100.0).show(ui, |ui| {\n for i in 0..30 {\n ui.label(format!(\"Row {i}\"));\n }\n });\n *offset = area.state.offset.y;\n },\n 0.0,\n );\n sync_scrollbars(&h.ctx, photocraft_engine::prefs::ScrollbarVisibility::Hidden);",
|
|
"expected_assertions": [
|
|
" assert!(*h.state() > 0.0);\n assert_eq!(h.ctx.global_style().spacing.scroll.allocated_width(), 0.0);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/ab84cab7355ac999fb1be226950978bafec39605/crates/ui-egui/src/theme.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-4938",
|
|
"pr": 4938,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture"
|
|
],
|
|
"expected": "dragging the title bar moves the dialog; layer style keeps one size on every page; layer style fits a short screen",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "dragging_the_title_bar_moves_the_dialog",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_the_title_bar_moves_the_dialog -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n\n let app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let mut harness = Harness::builder().with_size(egui::vec2(1400.0, 1100.0)).build_ui_state(|ui, app| show(app, ui.ctx()), app);\n PhotocraftApp::setup_context(&harness.ctx, crate::theme::ThemeKind::ALL[0]);\n harness.state_mut().ui.open_dialog(DialogKind::LayerStyle, serde_json::Map::new());\n harness.run_steps(3);\n let before = harness.get_by_label(\"Layer Style\").rect();\n\n // Grab the title text itself: it must move the dialog, not select the text.\n let from = before.center();\n harness.hover_at(from);",
|
|
"expected_assertions": [
|
|
" assert!((moved - egui::vec2(-120.0, 80.0)).length() < 1.0, \"dialog moved by {moved:?}\");\n assert_eq!(harness.state().ui.dialogs.len(), 1, \"dragging must not close the dialog\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/63b7c921634835259139e4d3e7b9d3c396998b4d/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_keeps_one_size_on_every_page",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_keeps_one_size_on_every_page -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = layer_style_on_bevel(egui::vec2(1400.0, 900.0));\n let size = frame(&h).size();\n let dialog = h.state().ui.dialogs[0].id;\n for page in [\"blendingOptions\", \"styles\"] {\n h.state_mut().ui.dialog_mut(dialog).expect(\"still open\").fields.insert(\"selected\".into(), json!(page));\n h.run_steps(3);\n assert_eq!(frame(&h).size(), size, \"{page}\");\n }\n let grip = egui::Id::new((\"dialog\", dialog)).with(\"resize\").with(\"__resize_corner\");\n assert!(h.ctx.read_response(grip).is_none(), \"no resize grip\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(frame(&h).size(), size, \"{page}\");\n }\n let grip = egui::Id::new((\"dialog\", dialog)).with(\"resize\").with(\"__resize_corner\");\n assert!(h.ctx.read_response(grip).is_none(), \"no resize grip\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/63b7c921634835259139e4d3e7b9d3c396998b4d/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_fits_a_short_screen",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_fits_a_short_screen -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n\n let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1366.0, 640.0));\n let h = layer_style_on_bevel(screen.size());\n assert!(screen.contains_rect(frame(&h)), \"{:?} fits on {screen:?}\", frame(&h));\n for button in [\"OK\", \"Cancel\"] {\n assert!(screen.contains_rect(h.get_by_label(button).rect()), \"{button} is on screen\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(screen.contains_rect(frame(&h)), \"{:?} fits on {screen:?}\", frame(&h));\n for button in [\"OK\", \"Cancel\"] {\n assert!(screen.contains_rect(h.get_by_label(button).rect()), \"{button} is on screen\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/63b7c921634835259139e4d3e7b9d3c396998b4d/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5270",
|
|
"pr": 5270,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked gradient_overlay_takes_explicit_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_picker_control_binds_previews_confirms_and_cancels -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked every_exposed_color_field_uses_the_shared_picker_and_only_updates_its_target -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_cancel_ok_parent_cancel_and_apply_are_transactional_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked unchanged_ok_preserves_missing_parameters_and_imported_effect_snapshot -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_targets_and_invalid_colors_never_apply_or_leave_preview -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_off_and_parent_confirmation_and_cancellation_keep_their_contract -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked eyedropper_edits_only_the_picker_and_invalid_samples_leave_it_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked gradient_stop_colors_go_through_the_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ramp_adds_moves_and_deletes_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_delete_and_location -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stops_round_trip_through_the_field_grammar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked factory_from_to_become_two_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_fill_of_a_page_never_fails -- --nocapture"
|
|
],
|
|
"expected": "gradient overlay takes explicit stops; layer style picker control binds previews confirms and cancels; every exposed color field uses the shared picker and only updates its target; preview cancel ok parent cancel and apply are transactional at every depth; unchanged ok preserves missing parameters and imported effect snapshot; stale targets and invalid colors never apply or leave preview; preview off and parent confirmation and cancellation keep their contract; eyedropper edits only the picker and invalid samples leave it unchanged; gradient stop colors go through the picker; ramp adds moves and deletes stops; presets delete and location; stops round trip through the field grammar; factory from to become two stops; the fill of a page never fails",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked gradient_overlay_takes_explicit_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_picker_control_binds_previews_confirms_and_cancels -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked every_exposed_color_field_uses_the_shared_picker_and_only_updates_its_target -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_cancel_ok_parent_cancel_and_apply_are_transactional_at_every_depth -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked unchanged_ok_preserves_missing_parameters_and_imported_effect_snapshot -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stale_targets_and_invalid_colors_never_apply_or_leave_preview -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preview_off_and_parent_confirmation_and_cancellation_keep_their_contract -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked eyedropper_edits_only_the_picker_and_invalid_samples_leave_it_unchanged -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked gradient_stop_colors_go_through_the_picker -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked ramp_adds_moves_and_deletes_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_delete_and_location -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked stops_round_trip_through_the_field_grammar -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked factory_from_to_become_two_stops -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked the_fill_of_a_page_never_fails -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "gradient_overlay_takes_explicit_stops",
|
|
"path": "crates/engine/src/layer_style.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked gradient_overlay_takes_explicit_stops -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = session();\n let stops = json!([[0.0, \"#ff0000\"], [0.5, \"#00ff00\"], [1.0, \"#0000ff\"]]);\n s.execute(\"layer.layerStyle.gradientOverlay\", json!({\"stops\": stops, \"opacityStops\": [[0, 100], [1, 50]]})).unwrap();\n let Effect::GradientOverlay { gradient, .. } = &effects(&s)[0] else { panic!() };\n assert_eq!(gradient.stops.len(), 3);\n assert_eq!(gradient.stops[1], (0.5, photocraft_color::Color::rgb(0.0, 1.0, 0.0)));\n assert_eq!(gradient.opacity_stops, vec![(0.0, 1.0), (1.0, 0.5)]);\n // Editing the same overlay: new stops replace the list (sorted), unsorted input is sorted,\n // and a geometry-only edit keeps the three stops.\n s.execute(\"layer.layerStyle.gradientOverlay\", json!({\"stops\": [[1.0, \"#ffffff\"], [0.25, [0.0, 0.0, 0.0]]], \"opacityStops\": []})).unwrap();\n let Effect::GradientOverlay { gradient, .. } = &effects(&s)[0] else { panic!() };\n assert_eq!(gradient.stops.iter().map(|s| s.0).collect::<Vec<_>>(), vec![0.25, 1.0]);",
|
|
"expected_assertions": [
|
|
" assert_eq!(gradient.stops.len(), 3);\n assert_eq!(gradient.stops[1], (0.5, photocraft_color::Color::rgb(0.0, 1.0, 0.0)));\n assert_eq!(gradient.opacity_stops, vec![(0.0, 1.0), (1.0, 0.5)]);\n // Editing the same overlay: new stops replace the list (sorted), unsorted input is sorted,\n // and a geometry-only edit keeps the three stops.\n s.execute(\"layer.layerStyle.gradientOverlay\", json!({\"stops\": [[1.0, \"#ffffff\"], [0.25, [0.0, 0.0, 0.0]]], \"opacityStops\": []})).unwrap();\n assert_eq!(gradient.stops.iter().map(|s| s.0).collect::<Vec<_>>(), vec![0.25, 1.0]);\n assert!(gradient.opacity_stops.is_empty(), \"[] means opaque\");\n s.execute(\"layer.layerStyle.gradientOverlay\", json!({\"stops\": stops})).unwrap();\n // The dialog's path: the snapshot plus a geometry edit keeps the three stops.\n let fx = serde_json::to_value(&effects(&s)[0]).unwrap();\n assert_eq!((gradient.stops.len(), gradient.angle), (3, 45.0));\n let e = s.execute(\"layer.layerStyle.replace\", json!({\"effects\": [{\"kind\": \"gradientOverlay\", \"params\": {\"stops\": [[0, \"#ff0000\"]]}}]})).unwrap_err();\n assert!(matches!(e, EngineError::BadParams { .. }), \"{e}\");\n // A gradient stroke takes stops too.\n s.execute(\"layer.layerStyle.stroke\", json!({\"size\": 4, \"stops\": [[0, \"#ff0000\"], [0.5, \"#00ff00\"], [1, \"#0000ff\"]]})).unwrap();\n assert!(effects(&s).iter().any(|e| matches!(e, Effect::Stroke(st) if matches!(&st.paint, FxPaint::Gradient(g) if g.stops.len() == 3))));\n // Malformed lists are errors and change nothing.\n for bad in [\n json!({\"stops\": \"red\"}),\n assert!(matches!(e, EngineError::BadParams { .. }), \"{bad}: {e}\");\n }\n let Effect::GradientOverlay { gradient, .. } = &effects(&s)[0] else { panic!() };\n assert_eq!(gradient.stops.len(), 3, \"a refused edit keeps the gradient\");\n // Positions outside 0..1 are clamped.\n s.execute(\"layer.layerStyle.gradientOverlay\", json!({\"stops\": [[-1, \"#000000\"], [2, \"#ffffff\"]]})).unwrap();\n let Effect::GradientOverlay { gradient, .. } = &effects(&s)[0] else { panic!() };\n assert_eq!(gradient.stops.iter().map(|s| s.0).collect::<Vec<_>>(), vec![0.0, 1.0]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/engine/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "layer_style_picker_control_binds_previews_confirms_and_cancels",
|
|
"path": "crates/ui-egui/src/control.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_picker_control_binds_previews_confirms_and_cancels -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n let ctx = egui::Context::default();\n app.run(\"file.new\", json!({\"width\":16,\"height\":16})).unwrap();\n let parent = call(&mut app, &ctx, \"ui.dialog.open\", json!({\"kind\":\"layerStyle\",\"effect\":\"gradientOverlay\"}))[\"result\"][\"dialog\"].as_u64();\n let parent = parent.unwrap();\n let before = app.ui.dialogs[0].fields.clone();\n // The Gradient Overlay's colours are its stops (#5177): `stop` picks one.\n for stop in [0, 1] {\n let reply = call(&mut app, &ctx, \"ui.dialog.open\", json!({\"kind\":\"colorPicker\",\"parent\":parent,\"effect\":\"fx1\",\"field\":\"stops\",\"stop\":stop}));\n assert_eq!(reply[\"ok\"], true, \"{reply}\");\n let picker = app.ui.dialogs.last().unwrap().id;\n let inspected = call(&mut app, &ctx, \"ui.inspect\", json!({}));",
|
|
"expected_assertions": [
|
|
" assert_eq!(reply[\"ok\"], true, \"{reply}\");\n let picker = app.ui.dialogs.last().unwrap().id;\n let inspected = call(&mut app, &ctx, \"ui.inspect\", json!({}));\n assert!(inspected.to_string().contains(\"__layerStyleColor\"));\n assert_eq!(call(&mut app, &ctx, \"ui.dialog.confirm\", json!({\"dialog\":parent}))[\"ok\"], false);\n assert_eq!(call(&mut app, &ctx, \"ui.dialog.set\", json!({\"dialog\":picker,\"field\":\"color\",\"value\":\"#123456\"}))[\"ok\"], true);\n assert_eq!(call(&mut app, &ctx, \"ui.dialog.confirm\", json!({\"dialog\":picker}))[\"ok\"], true);\n assert_eq!(app.ui.dialogs[0].fields[\"effects\"][0][\"params\"][\"stops\"][stop][1], \"#123456\");\n }\n assert_ne!(app.ui.dialogs[0].fields, before);\n let bad = call(&mut app, &ctx, \"ui.dialog.open\", json!({\"kind\":\"colorPicker\",\"parent\":parent,\"effect\":\"fx1\",\"field\":\"stops\",\"stop\":\"x\"}));\n assert_eq!(bad[\"ok\"], false, \"{bad}\");\n let bad = call(&mut app, &ctx, \"ui.dialog.open\", json!({\"kind\":\"colorPicker\",\"parent\":parent,\"effect\":\"fx1\",\"field\":\"stops\",\"stop\":9}));\n assert_eq!(bad[\"ok\"], false, \"{bad}\");\n call(&mut app, &ctx, \"ui.dialog.open\", json!({\"kind\":\"colorPicker\",\"parent\":parent,\"effect\":\"fx1\",\"field\":\"stops\",\"stop\":1}));\n assert_eq!(call(&mut app, &ctx, \"ui.dialog.cancel\", json!({\"dialog\":parent}))[\"ok\"], true);\n assert!(app.ui.dialogs.is_empty());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/control.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "every_exposed_color_field_uses_the_shared_picker_and_only_updates_its_target",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked every_exposed_color_field_uses_the_shared_picker_and_only_updates_its_target -- --nocapture",
|
|
"fixture_and_action_excerpt": " for (kind, _) in layer_style::KINDS {\n for (field, _, p) in spec(kind) {\n if !matches!(p, P::Color) {\n continue;\n }\n let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(kind)).unwrap();\n let effect = selected(&app, parent);\n let original = fields(&app, parent);\n let tools = app.session.tools.clone();\n let doc = app.session.active().unwrap().doc.clone();\n let history = app.session.active().unwrap().history.past_len();",
|
|
"expected_assertions": [
|
|
" assert!(color_picker_ui::owns(&fields(&app, picker)));\n assert_eq!(fields(&app, picker)[\"__label\"], \"Color Picker (Layer Style Color)\");\n set_color(&mut app, picker, \"#23a567\");\n let shown = preview_fields(&app, parent, &original);\n assert_eq!(super::super::entry(&shown, &effect).unwrap()[\"params\"][field], \"#23a567\");\n assert_eq!(fields(&app, parent), original);\n dialogs::confirm(&mut app, picker).unwrap();\n let mut expected = original;\n set_param(&mut expected, &effect, field, json!(\"#23a567\"));\n assert_eq!(fields(&app, parent), expected, \"{kind}.{field}\");\n assert!(Arc::ptr_eq(&app.session.active().unwrap().doc, &doc));\n assert_eq!(app.session.active().unwrap().history.past_len(), history);\n assert_eq!(app.session.tools.foreground, tools.foreground);\n assert_eq!(app.session.tools.background, tools.background);\n }\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preview_cancel_ok_parent_cancel_and_apply_are_transactional_at_every_depth",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preview_cancel_ok_parent_cancel_and_apply_are_transactional_at_every_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " for depth in [8, 16, 32] {\n let mut app = app(depth);\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n let effect = selected(&app, parent);\n layer_style::add_instance(&mut app.ui.dialog_mut(parent).unwrap().fields, \"stroke\");\n let original = fields(&app, parent);\n let st = app.session.active().unwrap();\n let (doc, history, revision, dirty) = (st.doc.clone(), st.history.past_len(), st.revision, st.is_dirty());\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n set_color(&mut app, picker, \"#00ff00\");\n let (shown, key) = canvas::display_doc(&mut app, 0);\n assert!(!Arc::ptr_eq(&shown, &doc));",
|
|
"expected_assertions": [
|
|
" assert!(!Arc::ptr_eq(&shown, &doc));\n let again = canvas::display_doc(&mut app, 0);\n assert_eq!(key, again.1);\n assert!(Arc::ptr_eq(&shown, &again.0), \"unchanged preview is cached\");\n let pixel = photocraft_compose::flatten(&shown).get(3, 3);\n assert!(pixel[1] > pixel[0] && pixel[1] > pixel[2], \"live preview is green at {depth} bits\");\n let st = app.session.active().unwrap();\n assert_eq!((st.history.past_len(), st.revision, st.is_dirty()), (history, revision, dirty));\n assert!(Arc::ptr_eq(&st.doc, &doc));\n dialogs::cancel(&mut app, picker).unwrap();\n assert_eq!(fields(&app, parent), original);\n assert_ne!(canvas::display_doc(&mut app, 0).1, key);\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n set_color(&mut app, picker, \"#00ff00\");\n dialogs::confirm(&mut app, picker).unwrap();\n assert_eq!(app.session.active().unwrap().history.past_len(), history);\n dialogs::cancel(&mut app, parent).unwrap();\n assert!(Arc::ptr_eq(&canvas::display_doc(&mut app, 0).0, &doc));\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n let effect = selected(&app, parent);\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n assert!(pixel[1] > pixel[0]);\n app.run(\"edit.undo\", json!({})).unwrap();\n assert_eq!(app.session.active().unwrap().doc.layer(doc.layers[0].id).unwrap().effects.items.len(), 0);\n app.run(\"edit.redo\", json!({})).unwrap();\n assert_eq!(app.session.active().unwrap().doc.layer(doc.layers[0].id).unwrap().effects, applied.layer(doc.layers[0].id).unwrap().effects);\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "unchanged_ok_preserves_missing_parameters_and_imported_effect_snapshot",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked unchanged_ok_preserves_missing_parameters_and_imported_effect_snapshot -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(8);\n app.run(\"layer.layerStyle.stroke\", json!({\"size\":7,\"color\":\"#123456\",\"add\":true})).unwrap();\n app.run(\"layer.layerStyle.stroke\", json!({\"size\":9,\"color\":\"#abcdef\",\"add\":true})).unwrap();\n let parent = layer_style::open(&mut app, Some(\"stroke\")).unwrap();\n let original = fields(&app, parent);\n for effect in [\"fx1\", \"fx2\"] {\n let picker = open(&mut app, parent, effect, \"color\", None).unwrap();\n dialogs::confirm(&mut app, picker).unwrap();\n assert_eq!(fields(&app, parent), original);\n }\n let picker = open(&mut app, parent, \"fx2\", \"color\", None).unwrap();\n set_color(&mut app, picker, \"#223344\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(fields(&app, parent), original);\n }\n let picker = open(&mut app, parent, \"fx2\", \"color\", None).unwrap();\n set_color(&mut app, picker, \"#223344\");\n assert_eq!(super::super::entry(¤t, \"fx1\"), super::super::entry(&original, \"fx1\"));\n assert_eq!(super::super::entry(¤t, \"fx2\").unwrap()[\"fx\"], super::super::entry(&original, \"fx2\").unwrap()[\"fx\"]);\n dialogs::cancel(&mut app, parent).unwrap();\n let parent = layer_style::open(&mut app, Some(\"gradientOverlay\")).unwrap();\n let effect = selected(&app, parent);\n assert_eq!(fields(&app, parent), original);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stale_targets_and_invalid_colors_never_apply_or_leave_preview",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked stale_targets_and_invalid_colors_never_apply_or_leave_preview -- --nocapture",
|
|
"fixture_and_action_excerpt": " for change in [\"document\", \"parent\", \"effect\", \"kind\", \"color\", \"source\", \"malformed\", \"layer\", \"replaced\"] {\n let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n let effect = selected(&app, parent);\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n set_color(&mut app, picker, \"#00ff00\");\n match change {\n \"document\" => {\n app.run(\"file.new\", json!({\"width\":3,\"height\":3})).unwrap();\n }\n \"parent\" => {\n app.ui.close_dialog(parent);",
|
|
"expected_assertions": [
|
|
" assert!(dialogs::confirm(&mut app, picker).is_err(), \"{change}\");\n assert_eq!(app.ui.dialogs.iter().find(|d| d.id == parent).cloned(), current_parent);\n }\n let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n assert!(dialogs::confirm(&mut app, picker).is_err());\n assert_eq!(fields(&app, parent), original);\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n app.run(\"file.new\", json!({\"width\":3,\"height\":3})).unwrap();\n prune(&mut app);\n assert!(!app.ui.dialogs.iter().any(|d| d.id == picker));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preview_off_and_parent_confirmation_and_cancellation_keep_their_contract",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preview_off_and_parent_confirmation_and_cancellation_keep_their_contract -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n app.ui.dialog_mut(parent).unwrap().fields.insert(\"preview\".into(), json!(false));\n let effect = selected(&app, parent);\n let original = fields(&app, parent);\n let doc = app.session.active().unwrap().doc.clone();\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n set_color(&mut app, picker, \"#00ff00\");\n assert!(Arc::ptr_eq(&canvas::display_doc(&mut app, 0).0, &doc));\n assert!(dialogs::confirm(&mut app, parent).is_err());\n assert_eq!(fields(&app, parent), original);\n assert_eq!(app.ui.dialogs.len(), 2);",
|
|
"expected_assertions": [
|
|
" assert!(Arc::ptr_eq(&canvas::display_doc(&mut app, 0).0, &doc));\n assert!(dialogs::confirm(&mut app, parent).is_err());\n assert_eq!(fields(&app, parent), original);\n assert_eq!(app.ui.dialogs.len(), 2);\n dialogs::cancel(&mut app, parent).unwrap();\n assert!(app.ui.dialogs.is_empty());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "eyedropper_edits_only_the_picker_and_invalid_samples_leave_it_unchanged",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked eyedropper_edits_only_the_picker_and_invalid_samples_leave_it_unchanged -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(\"colorOverlay\")).unwrap();\n let effect = selected(&app, parent);\n let original = fields(&app, parent);\n let doc = app.session.active().unwrap().doc.clone();\n let tools = app.session.tools.clone();\n let picker = open(&mut app, parent, &effect, \"color\", None).unwrap();\n color_picker_ui::sample_at(&mut app, 4.0, 4.0);\n assert_eq!(fields(&app, picker)[\"color\"], \"#406080\");\n color_picker_ui::sample_at(&mut app, -100.0, -100.0);\n assert_eq!(fields(&app, picker)[\"color\"], \"#406080\");\n assert_eq!(fields(&app, parent), original);",
|
|
"expected_assertions": [
|
|
" assert_eq!(fields(&app, picker)[\"color\"], \"#406080\");\n color_picker_ui::sample_at(&mut app, -100.0, -100.0);\n assert_eq!(fields(&app, picker)[\"color\"], \"#406080\");\n assert_eq!(fields(&app, parent), original);\n assert!(Arc::ptr_eq(&app.session.active().unwrap().doc, &doc));\n assert_eq!(app.session.tools.foreground, tools.foreground);\n dialogs::cancel(&mut app, picker).unwrap();\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "gradient_stop_colors_go_through_the_picker",
|
|
"path": "crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked gradient_stop_colors_go_through_the_picker -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = app(8);\n let parent = layer_style::open(&mut app, Some(\"gradientOverlay\")).unwrap();\n let effect = selected(&app, parent);\n let three = json!([[0.0, \"#ff0000\"], [0.5, \"#00ff00\"], [1.0, \"#0000ff\"]]);\n super::super::set_param(&mut app.ui.dialog_mut(parent).unwrap().fields, &effect, \"stops\", three);\n assert!(open(&mut app, parent, &effect, \"stops\", Some(3)).is_err(), \"no fourth stop\");\n assert!(open(&mut app, parent, &effect, \"stops\", None).is_err(), \"stops is not a plain colour\");\n let picker = open(&mut app, parent, &effect, \"stops\", Some(1)).unwrap();\n set_color(&mut app, picker, \"#123456\");\n let current = fields(&app, parent);\n let shown = preview_fields(&app, parent, ¤t);\n assert_eq!(super::super::entry(&shown, &effect).unwrap()[\"params\"][\"stops\"][1][1], \"#123456\", \"previewed\");",
|
|
"expected_assertions": [
|
|
" assert!(open(&mut app, parent, &effect, \"stops\", Some(3)).is_err(), \"no fourth stop\");\n assert!(open(&mut app, parent, &effect, \"stops\", None).is_err(), \"stops is not a plain colour\");\n let picker = open(&mut app, parent, &effect, \"stops\", Some(1)).unwrap();\n set_color(&mut app, picker, \"#123456\");\n let current = fields(&app, parent);\n assert_eq!(super::super::entry(&shown, &effect).unwrap()[\"params\"][\"stops\"][1][1], \"#123456\", \"previewed\");\n assert_eq!(super::super::entry(&fields(&app, parent), &effect).unwrap()[\"params\"][\"stops\"][1][1], \"#00ff00\", \"not stored yet\");\n dialogs::confirm(&mut app, picker).unwrap();\n let stops = super::super::entry(&fields(&app, parent), &effect).unwrap()[\"params\"][\"stops\"].clone();\n assert_eq!(stops, json!([[0.0, \"#ff0000\"], [0.5, \"#123456\"], [1.0, \"#0000ff\"]]));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/color_picker/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "ramp_adds_moves_and_deletes_stops",
|
|
"path": "crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked ramp_adds_moves_and_deletes_stops -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, parent) = dialog_app();\n let effect = crate::layer_style::effects_of(&app.ui.dialogs[0].fields)[0][\"id\"].as_str().unwrap().to_string();\n set_param(&mut app.ui.dialog_mut(parent).unwrap().fields, &effect, KEY, json!([[0.0, \"#000000\"], [1.0, \"#ffffff\"]]));\n let mut h = harness(app, parent);\n assert!(h.query_by_label(\"Gradient stops\").is_some());\n let (_, bar): (String, Rect) = h.ctx.data(|d| d.get_temp(bar_id())).expect(\"the ramp was drawn\");\n // Add in the middle: a mid grey.\n let mid = pos2(bar.center().x, bar.bottom() + 9.0);\n press(&mut h, mid);\n release(&mut h, mid);\n let stops = stops_in(h.state(), parent);\n assert_eq!(stops.len(), 3, \"{stops:?}\");",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label(\"Gradient stops\").is_some());\n let (_, bar): (String, Rect) = h.ctx.data(|d| d.get_temp(bar_id())).expect(\"the ramp was drawn\");\n // Add in the middle: a mid grey.\n let mid = pos2(bar.center().x, bar.bottom() + 9.0);\n assert_eq!(stops.len(), 3, \"{stops:?}\");\n assert!((stops[1].0 - 0.5).abs() < 0.02 && (stops[1].1.to_rgb()[0] - 0.5).abs() < 0.06, \"{stops:?}\");\n // Drag it to a quarter.\n let quarter = pos2(bar.left() + bar.width() * 0.25, mid.y);\n press(&mut h, mid);\n assert_eq!(stops.len(), 3);\n assert!((stops[1].0 - 0.25).abs() < 0.03, \"{stops:?}\");\n // Drag it away: gone.\n let away = pos2(quarter.x, bar.bottom() + 90.0);\n press(&mut h, quarter);\n assert_eq!(stops.len(), 2, \"{stops:?}\");\n // The last two can't be dragged away.\n let first = pos2(bar.left(), mid.y);\n press(&mut h, first);\n assert_eq!(stops_in(h.state(), parent).len(), 2);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "presets_delete_and_location",
|
|
"path": "crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked presets_delete_and_location -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, parent) = dialog_app();\n let effect = crate::layer_style::effects_of(&app.ui.dialogs[0].fields)[0][\"id\"].as_str().unwrap().to_string();\n let name = app\n .session\n .presets\n .gradients\n .iter()\n .flat_map(|g| g.items.iter())\n .map(|p| p.name.clone())\n .find(|n| n.contains(\"Spectrum\") || n.contains(\"Rainbow\"))\n .or_else(|| app.session.presets.gradients.first().and_then(|g| g.items.first()).map(|p| p.name.clone()))\n .unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(apply_preset(&app, &mut f, &effect, &mut disp, &name), \"{name}\");\n assert!(!apply_preset(&app, &mut f, &effect, &mut disp, \"no such preset\"));\n let stops = stops_of(disp.get(KEY)).unwrap();\n assert!(stops.len() >= 2, \"{name}: {stops:?}\");\n app.ui.dialog_mut(parent).unwrap().fields = f;\n set_param(&mut app.ui.dialog_mut(parent).unwrap().fields, &effect, KEY, json!([[0.0, \"#ff0000\"], [0.5, \"#00ff00\"], [1.0, \"#0000ff\"]]));\n let mut h = harness(app, parent);\n assert_eq!(stops.iter().map(|s| super::super::hex(&s.1)).collect::<Vec<_>>(), [\"#ff0000\", \"#0000ff\"], \"{stops:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "stops_round_trip_through_the_field_grammar",
|
|
"path": "crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked stops_round_trip_through_the_field_grammar -- --nocapture",
|
|
"fixture_and_action_excerpt": " let stops = vec![(0.0, Color::rgb(1.0, 0.0, 0.0)), (0.5, Color::rgb(0.0, 1.0, 0.0)), (1.0, Color::rgb(0.0, 0.0, 1.0))];\n let v = stops_json(&stops);\n assert_eq!(v, json!([[0.0, \"#ff0000\"], [0.5, \"#00ff00\"], [1.0, \"#0000ff\"]]));\n assert_eq!(stops_of(Some(&v)), Some(stops));\n // Unsorted input is sorted, bad entries are skipped, fewer than two is nothing.\n let v = json!([[1.0, \"#ffffff\"], [\"x\", \"#ff0000\"], [0.25, \"#000000\"], [0.5, 7]]);\n assert_eq!(stops_of(Some(&v)).map(|s| s.iter().map(|x| x.0).collect::<Vec<_>>()), Some(vec![0.25, 1.0]));\n assert_eq!(stops_of(Some(&json!([[0.0, \"#000000\"]]))), None);\n assert_eq!(stops_of(Some(&json!(\"red\"))), None);\n assert_eq!(stops_of(None), None);\n let os = vec![(0.0, 1.0), (1.0, 0.5)];\n assert_eq!(opacity_json(&os), json!([[0.0, 100.0], [1.0, 50.0]]));",
|
|
"expected_assertions": [
|
|
" assert_eq!(v, json!([[0.0, \"#ff0000\"], [0.5, \"#00ff00\"], [1.0, \"#0000ff\"]]));\n assert_eq!(stops_of(Some(&v)), Some(stops));\n // Unsorted input is sorted, bad entries are skipped, fewer than two is nothing.\n let v = json!([[1.0, \"#ffffff\"], [\"x\", \"#ff0000\"], [0.25, \"#000000\"], [0.5, 7]]);\n assert_eq!(stops_of(Some(&v)).map(|s| s.iter().map(|x| x.0).collect::<Vec<_>>()), Some(vec![0.25, 1.0]));\n assert_eq!(stops_of(Some(&json!([[0.0, \"#000000\"]]))), None);\n assert_eq!(stops_of(Some(&json!(\"red\"))), None);\n assert_eq!(stops_of(None), None);\n let os = vec![(0.0, 1.0), (1.0, 0.5)];\n assert_eq!(opacity_json(&os), json!([[0.0, 100.0], [1.0, 50.0]]));\n assert_eq!(opacity_of(Some(&opacity_json(&os))), Some(os));\n assert_eq!(opacity_of(Some(&json!([]))), Some(vec![]), \"[] is opaque\");\n assert_eq!(opacity_of(Some(&json!([[0.0, 100.0]]))), None, \"one stop is not a list\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "factory_from_to_become_two_stops",
|
|
"path": "crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked factory_from_to_become_two_stops -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut p = json!({\"from\": \"#ff0000\", \"to\": \"#0000ff\", \"angle\": 90});\n from_to_to_stops(&mut p);\n assert_eq!(p, json!({\"stops\": [[0.0, \"#ff0000\"], [1.0, \"#0000ff\"]], \"opacityStops\": [], \"angle\": 90}));\n let mut p = json!({\"stops\": [[0.0, \"#000000\"], [0.5, \"#ff0000\"], [1.0, \"#ffffff\"]], \"from\": \"#123456\"});\n from_to_to_stops(&mut p);\n assert_eq!(p[\"stops\"].as_array().map(Vec::len), Some(3), \"explicit stops win over From/To\");\n assert!(p.get(\"from\").is_none());\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(p, json!({\"stops\": [[0.0, \"#ff0000\"], [1.0, \"#0000ff\"]], \"opacityStops\": [], \"angle\": 90}));\n let mut p = json!({\"stops\": [[0.0, \"#000000\"], [0.5, \"#ff0000\"], [1.0, \"#ffffff\"]], \"from\": \"#123456\"});\n from_to_to_stops(&mut p);\n assert_eq!(p[\"stops\"].as_array().map(Vec::len), Some(3), \"explicit stops win over From/To\");\n assert!(p.get(\"from\").is_none());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "the_fill_of_a_page_never_fails",
|
|
"path": "crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked the_fill_of_a_page_never_fails -- --nocapture",
|
|
"fixture_and_action_excerpt": " for v in [json!({}), json!({\"stops\": \"x\"}), json!({\"stops\": [[0.0, \"#ff0000\"]], \"opacityStops\": [[0.5, 20.0]]}), json!({\"stops\": null})] {\n let Fill::Gradient { stops, opacity_stops, .. } = fill_of(&v) else { panic!(\"{v}\") };\n assert_eq!(stops.len(), 2, \"{v}: the default black-to-white\");\n assert!(opacity_stops.is_empty() || opacity_stops.len() >= 2, \"{v}\");\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(stops.len(), 2, \"{v}: the default black-to-white\");\n assert!(opacity_stops.is_empty() || opacity_stops.len() >= 2, \"{v}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9db1c7ae1d48ce4f31622b5f9029c70c590842f8/crates/ui-egui/src/layer_style/gradient_field.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-5744",
|
|
"pr": 5744,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked torn_off_document_is_not_drawn_again_in_the_main_window -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked tab_reorder_keeps_floating_documents_in_place -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrange_layout_only_includes_docked_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_a_tab_off_the_strip_floats_it_in_a_window -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked views_and_windows_stay_with_their_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_in_window_takes_a_document_and_position -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_in_window_defaults_to_the_active_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_all_in_windows_gives_each_document_its_own_view -- --nocapture"
|
|
],
|
|
"expected": "torn off document is not drawn again in the main window; tab reorder keeps floating documents in place; arrange layout only includes docked documents; dragging a tab off the strip floats it in a window; views and windows stay with their documents; float in window takes a document and position; float in window defaults to the active document; float all in windows gives each document its own view",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked torn_off_document_is_not_drawn_again_in_the_main_window -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked tab_reorder_keeps_floating_documents_in_place -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked arrange_layout_only_includes_docked_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_a_tab_off_the_strip_floats_it_in_a_window -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked views_and_windows_stay_with_their_documents -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_in_window_takes_a_document_and_position -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_in_window_defaults_to_the_active_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked float_all_in_windows_gives_each_document_its_own_view -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "torn_off_document_is_not_drawn_again_in_the_main_window",
|
|
"path": "crates/ui-egui/src/canvas.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked torn_off_document_is_not_drawn_again_in_the_main_window -- --nocapture",
|
|
"fixture_and_action_excerpt": " for kind in [crate::theme::ThemeKind::Pro, crate::theme::ThemeKind::Studio] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 80, \"height\": 60, \"name\": \"floating\"})).unwrap();\n app.run(\"file.new\", json!({\"width\": 80, \"height\": 60, \"name\": \"docked\"})).unwrap();\n app.sync_views();\n let ctx = egui::Context::default();\n crate::menus::invoke(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({\"document\": 0})).unwrap();\n assert!(app.ui.windows[0].floating);\n assert_eq!(app.session.active_index(), Some(0), \"{kind:?}: the floated page remains active\");\n assert_eq!(main_canvas_document(&app), Some(1), \"{kind:?}: the main canvas picks a docked page instead\");\n let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(680.0, 480.0)).build_ui_state(\n |ui, (app, ready): &mut (PhotocraftApp, bool)| {",
|
|
"expected_assertions": [
|
|
" assert!(app.ui.windows[0].floating);\n assert_eq!(app.session.active_index(), Some(0), \"{kind:?}: the floated page remains active\");\n assert_eq!(main_canvas_document(&app), Some(1), \"{kind:?}: the main canvas picks a docked page instead\");\n let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(680.0, 480.0)).build_ui_state(\n |ui, (app, ready): &mut (PhotocraftApp, bool)| {\n if *ready {\n assert_eq!(tabs, Some(vec![1]), \"{kind:?}: only the docked document stays on the main tab strip\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/canvas.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "tab_reorder_keeps_floating_documents_in_place",
|
|
"path": "crates/ui-egui/src/canvas.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked tab_reorder_keeps_floating_documents_in_place -- --nocapture",
|
|
"fixture_and_action_excerpt": " let visible = [0, 2];\n assert_eq!(move_target_after_filter(&visible, 0, 1, 3), 2);\n assert_eq!(move_target_after_filter(&visible, 2, 0, 3), 0);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(move_target_after_filter(&visible, 0, 1, 3), 2);\n assert_eq!(move_target_after_filter(&visible, 2, 0, 3), 0);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/canvas.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "arrange_layout_only_includes_docked_documents",
|
|
"path": "crates/ui-egui/src/canvas.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked arrange_layout_only_includes_docked_documents -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n for name in [\"first\", \"floating\", \"last\"] {\n app.run(\"file.new\", json!({\"width\": 80, \"height\": 60, \"name\": name})).unwrap();\n }\n app.ui.view.arrange = \"threeUpStacked\".into();\n crate::menus::invoke(&mut app, &egui::Context::default(), \"window.arrange.floatInWindow\", json!({\"document\": 1})).unwrap();\n let rect = Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(800.0, 600.0));\n let shown: Vec<_> = arranged_cells(&app, rect).unwrap().into_iter().map(|(doc, _)| doc).collect();\n assert_eq!(shown, vec![0, 2]);\n\n crate::menus::invoke(&mut app, &egui::Context::default(), \"window.arrange.floatInWindow\", json!({\"document\": 0})).unwrap();\n crate::menus::invoke(&mut app, &egui::Context::default(), \"window.arrange.floatInWindow\", json!({\"document\": 2})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(shown, vec![0, 2]);\n\n crate::menus::invoke(&mut app, &egui::Context::default(), \"window.arrange.floatInWindow\", json!({\"document\": 0})).unwrap();\n crate::menus::invoke(&mut app, &egui::Context::default(), \"window.arrange.floatInWindow\", json!({\"document\": 2})).unwrap();\n assert!(arranged_cells(&app, rect).is_none(), \"the main canvas should be blank when every document is floating\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/canvas.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dragging_a_tab_off_the_strip_floats_it_in_a_window",
|
|
"path": "crates/ui-egui/src/canvas.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_a_tab_off_the_strip_floats_it_in_a_window -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::Queryable;\n let strip = Rect::from_min_size(egui::pos2(0.0, 0.0), egui::vec2(700.0, 26.0));\n assert!(!torn_off(strip, egui::pos2(50.0, 13.0)));\n assert!(!torn_off(strip, egui::pos2(50.0, 26.0 + TEAR_OFF - 1.0)), \"a wobble below the strip still reorders\");\n assert!(torn_off(strip, egui::pos2(50.0, 26.0 + TEAR_OFF + 1.0)));\n assert!(torn_off(strip, egui::pos2(50.0, -TEAR_OFF - 1.0)), \"dragged up, off the window's top\");\n for kind in [crate::theme::ThemeKind::Studio, crate::theme::ThemeKind::Pro] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n for name in [\"a\", \"b\", \"c\"] {\n app.run(\"file.new\", json!({\"width\": 8, \"height\": 8, \"name\": name})).unwrap();\n }\n app.sync_views();",
|
|
"expected_assertions": [
|
|
" assert!(!torn_off(strip, egui::pos2(50.0, 13.0)));\n assert!(!torn_off(strip, egui::pos2(50.0, 26.0 + TEAR_OFF - 1.0)), \"a wobble below the strip still reorders\");\n assert!(torn_off(strip, egui::pos2(50.0, 26.0 + TEAR_OFF + 1.0)));\n assert!(torn_off(strip, egui::pos2(50.0, -TEAR_OFF - 1.0)), \"dragged up, off the window's top\");\n for kind in [crate::theme::ThemeKind::Studio, crate::theme::ThemeKind::Pro] {\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n for name in [\"a\", \"b\", \"c\"] {\n assert_eq!(names, [\"a\", \"b\", \"c\"], \"{kind:?}: tearing off doesn't reorder\");\n assert_eq!(app.ui.windows.iter().map(|w| w.document).collect::<Vec<_>>(), [1], \"{kind:?}: b floats in its own window\");\n assert_eq!(app.session.active_index(), Some(1), \"{kind:?}: the torn-off document stays active\");\n assert!(app.ui.windows[0].floating, \"{kind:?}: the page belongs exclusively to its floating window\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/canvas.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "views_and_windows_stay_with_their_documents",
|
|
"path": "crates/ui-egui/src/file_open/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked views_and_windows_stay_with_their_documents -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, _) = app_with(Vec::new());\n for name in [\"a.psd\", \"b.psd\", \"c.psd\", \"d.psd\"] {\n app.open_bytes(name, b\"x\").unwrap();\n }\n for (i, v) in app.ui.views.iter_mut().enumerate() {\n v.zoom = i as f32 + 1.0;\n }\n app.ui.windows = (0..4)\n .map(|document| crate::state::DocWindow {\n id: document as u64,\n document,\n view: Default::default(),",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.run(\"document.move\", json!({\"document\": 0, \"to\": 3})).unwrap(), json!({\"document\": 3}));\n assert_eq!(doc_names(&app), [\"b.psd\", \"c.psd\", \"d.psd\", \"a.psd\"]);\n assert_eq!(zooms(&app), [2.0, 3.0, 4.0, 1.0]);\n assert_eq!(windows(&app), [(0, 3), (1, 0), (2, 1), (3, 2)]);\n // Out of range: an error, nothing moves.\n assert!(app.run(\"document.move\", json!({\"document\": 7, \"to\": 0})).is_err());\n assert_eq!(zooms(&app), [2.0, 3.0, 4.0, 1.0]);\n // Closing a middle tab takes its view and windows with it; the others keep theirs.\n app.run(\"file.close\", json!({\"document\": 1})).unwrap();\n assert_eq!(doc_names(&app), [\"b.psd\", \"d.psd\", \"a.psd\"]);\n assert_eq!(zooms(&app), [2.0, 4.0, 1.0]);\n assert_eq!(windows(&app), [(0, 2), (1, 0), (3, 1)]);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/file_open/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "float_in_window_takes_a_document_and_position",
|
|
"path": "crates/ui-egui/src/view_cmds/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked float_in_window_takes_a_document_and_position -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, ctx) = app_with(3);\n let r = menu(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({\"document\": 1, \"position\": [1950.0, 40.5]})).unwrap();\n let w = app.ui.windows.last().unwrap();\n assert_eq!(r, json!({\"window\": w.id}));\n assert_eq!((w.document, w.position), (1, Some([1950.0, 40.5])));\n assert!(w.floating);\n assert_eq!(app.session.active_index(), Some(1), \"the floated document stays active\");\n let again = menu(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({\"document\": 1})).unwrap();\n assert_eq!(again, r, \"tearing off the same document reuses its window\");\n assert_eq!(app.ui.windows.len(), 1);\n assert_eq!(app.ui.windows[0].position, Some([1950.0, 40.5]));\n for bad in [",
|
|
"expected_assertions": [
|
|
" assert_eq!(r, json!({\"window\": w.id}));\n assert_eq!((w.document, w.position), (1, Some([1950.0, 40.5])));\n assert!(w.floating);\n assert_eq!(app.session.active_index(), Some(1), \"the floated document stays active\");\n let again = menu(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({\"document\": 1})).unwrap();\n assert_eq!(again, r, \"tearing off the same document reuses its window\");\n assert_eq!(app.ui.windows.len(), 1);\n assert_eq!(app.ui.windows[0].position, Some([1950.0, 40.5]));\n for bad in [\n json!({\"document\": 3}),\n json!({\"document\": -1}),\n assert!(menu(&mut app, &ctx, \"window.arrange.floatInWindow\", bad.clone()).is_err(), \"{bad}\");\n }\n assert_eq!(app.ui.windows.len(), 1, \"rejected params open no window\");\n app.ui.windows[0].open = false;\n let reopened = menu(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({\"document\": 1})).unwrap();\n assert_ne!(reopened, r, \"a closed window can be floated again\");\n assert_eq!(app.ui.windows.last().map(|w| (w.document, w.position)), Some((1, None)));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/view_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "float_in_window_defaults_to_the_active_document",
|
|
"path": "crates/ui-egui/src/view_cmds/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked float_in_window_defaults_to_the_active_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, ctx) = app_with(3);\n app.session.set_active(1);\n let r = menu(&mut app, &ctx, \"window.arrange.floatInWindow\", json!({})).unwrap();\n let window = app.ui.windows.last().unwrap();\n assert_eq!(r, json!({\"window\": window.id}));\n assert_eq!(window.document, 1);\n assert!(window.floating);\n assert_eq!(app.session.active_index(), Some(1));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(r, json!({\"window\": window.id}));\n assert_eq!(window.document, 1);\n assert!(window.floating);\n assert_eq!(app.session.active_index(), Some(1));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/view_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "float_all_in_windows_gives_each_document_its_own_view",
|
|
"path": "crates/ui-egui/src/view_cmds/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked float_all_in_windows_gives_each_document_its_own_view -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, ctx) = app_with(3);\n menu(&mut app, &ctx, \"window.arrange.floatAllInWindows\", json!({})).unwrap();\n assert_eq!(app.ui.windows.iter().map(|w| w.document).collect::<Vec<_>>(), [0, 1, 2]);\n assert!(app.ui.windows.iter().all(|w| w.floating));\n}",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.windows.iter().map(|w| w.document).collect::<Vec<_>>(), [0, 1, 2]);\n assert!(app.ui.windows.iter().all(|w| w.floating));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/50b1f6734799cf7b5d45dd84868976afd31aa711/crates/ui-egui/src/view_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6387",
|
|
"pr": 6387,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked video_frames_to_layers_takes_every_tiff_page -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked video_frames_to_layers_refuses_a_tiff_with_an_incomplete_page_list -- --nocapture"
|
|
],
|
|
"expected": "video frames to layers takes every tiff page; video frames to layers refuses a tiff with an incomplete page list",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked video_frames_to_layers_takes_every_tiff_page -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked video_frames_to_layers_refuses_a_tiff_with_an_incomplete_page_list -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "video_frames_to_layers_takes_every_tiff_page",
|
|
"path": "crates/engine/src/video_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked video_frames_to_layers_takes_every_tiff_page -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = tmpdir(\"tiff-pages\");\n let path = format!(\"{dir}/pages.tif\");\n write_tiff(&path, &[(2, 2, 9, 1), (6, 4, 51, 0), (3, 5, 204, 0)]);\n let mut s = session();\n let r = s.execute(\"file.import.videoFramesToLayers\", json!({\"path\": path})).unwrap();\n assert_eq!(r[\"layers\"], 2, \"two pages, the thumbnail left out\");\n let doc = &s.active().unwrap().doc;\n for (name, (w, h), level) in [(\"Frame 1\", (6, 4), 51.0), (\"Frame 2\", (3, 5), 204.0)] {\n let l = doc.layers.iter().find(|l| l.name == name).unwrap_or_else(|| panic!(\"{name}\"));\n let surf = l.surface().unwrap();\n let b = surf.content_bounds();\n assert_eq!((b.width(), b.height()), (w, h), \"{name}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(r[\"layers\"], 2, \"two pages, the thumbnail left out\");\n let doc = &s.active().unwrap().doc;\n for (name, (w, h), level) in [(\"Frame 1\", (6, 4), 51.0), (\"Frame 2\", (3, 5), 204.0)] {\n let l = doc.layers.iter().find(|l| l.name == name).unwrap_or_else(|| panic!(\"{name}\"));\n assert_eq!((b.width(), b.height()), (w, h), \"{name}\");\n let px = surf.read_region(photocraft_geom::Rect::new(b.x0, b.y0, b.x0 + 1, b.y0 + 1));\n assert!((px[0] * 255.0 - level).abs() < 0.6 && px[3] == 1.0, \"{name}: {px:?}\");\n }\n let single = format!(\"{dir}/single.tif\");\n write_tiff(&single, &[(4, 4, 120, 0)]);\n assert_eq!(s.execute(\"file.import.videoFramesToLayers\", json!({\"path\": single})).unwrap()[\"layers\"], 1);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bfbbf816025942b74130adf16fb07265817b691/crates/engine/src/video_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "video_frames_to_layers_refuses_a_tiff_with_an_incomplete_page_list",
|
|
"path": "crates/engine/src/video_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked video_frames_to_layers_refuses_a_tiff_with_an_incomplete_page_list -- --nocapture",
|
|
"fixture_and_action_excerpt": " let dir = tmpdir(\"tiff-loop\");\n let path = format!(\"{dir}/loop.tif\");\n write_tiff(&path, &[(2, 2, 51, 0), (2, 2, 204, 0)]);\n // The last directory's next-IFD offset points back to the first directory.\n let mut f = std::fs::read(&path).unwrap();\n let first: [u8; 4] = f[4..8].try_into().unwrap();\n let end = f.len();\n f[end - 4..].copy_from_slice(&first);\n std::fs::write(&path, f).unwrap();\n let mut s = session();\n let before = s.active().unwrap().doc.layers.len();\n let err = s.execute(\"file.import.videoFramesToLayers\", json!({\"path\": path})).unwrap_err().to_string();",
|
|
"expected_assertions": [
|
|
" assert!(err.contains(\"only the first 2 pages\"), \"{err}\");\n assert_eq!(s.active().unwrap().doc.layers.len(), before, \"nothing imported\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8bfbbf816025942b74130adf16fb07265817b691/crates/engine/src/video_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-6449",
|
|
"pr": 6449,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked cmd_is_not_the_move_tool_for_selection_hand_zoom_pen_shape_or_type_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_and_alt_with_the_hand_tool_zoom_in_and_out_while_held -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_mid_pan_or_during_free_transform_is_not_the_hand_tools_zoom -- --nocapture"
|
|
],
|
|
"expected": "cmd is not the move tool for selection hand zoom pen shape or type tools; cmd and alt with the hand tool zoom in and out while held; cmd mid pan or during free transform is not the hand tools zoom",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked cmd_is_not_the_move_tool_for_selection_hand_zoom_pen_shape_or_type_tools -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_and_alt_with_the_hand_tool_zoom_in_and_out_while_held -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked cmd_mid_pan_or_during_free_transform_is_not_the_hand_tools_zoom -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "cmd_is_not_the_move_tool_for_selection_hand_zoom_pen_shape_or_type_tools",
|
|
"path": "crates/ui-egui/src/hold_keys/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked cmd_is_not_the_move_tool_for_selection_hand_zoom_pen_shape_or_type_tools -- --nocapture",
|
|
"fixture_and_action_excerpt": " for tool in [\n Tool::Hand,\n Tool::RotateView,\n Tool::Zoom,\n Tool::Pen,\n Tool::Rectangle,\n Tool::Type,\n Tool::VerticalType,\n Tool::Crop,\n Tool::PathSelection,\n Tool::DirectSelection,\n Tool::Move,",
|
|
"expected_assertions": [
|
|
" assert!(!cmd_moves(tool), \"{tool:?}\");\n let mut h = harness(tool);\n h.event(Event::ModifiersChanged(platform(Modifiers::COMMAND)));\n h.run_steps(1);\n assert_eq!(held_tool(h.state(), &h.ctx), (tool == Tool::Hand).then_some(Temporary::ZoomIn), \"{tool:?}\");\n }\n for tool in [Tool::Brush, Tool::Eraser, Tool::Gradient, Tool::CloneStamp, Tool::Eyedropper, Tool::MagneticLasso, Tool::QuickSelection] {\n assert!(cmd_moves(tool), \"{tool:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/25c38a0b69b7bff31badcdbe2ef9f2ff6aba1c63/crates/ui-egui/src/hold_keys/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cmd_and_alt_with_the_hand_tool_zoom_in_and_out_while_held",
|
|
"path": "crates/ui-egui/src/hold_keys/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked cmd_and_alt_with_the_hand_tool_zoom_in_and_out_while_held -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness(Tool::Hand);\n let z0 = h.state().ui.views[0].zoom;\n hold_mods(&mut h, Modifiers::COMMAND);\n assert_eq!(held_tool(h.state(), &h.ctx), Some(Temporary::ZoomIn));\n click(&mut h, 200.0, 150.0, Modifiers::COMMAND);\n let z1 = h.state().ui.views[0].zoom;\n assert!(z1 > z0, \"{z0} -> {z1}\");\n hold_mods(&mut h, Modifiers::ALT);\n assert_eq!(held_tool(h.state(), &h.ctx), Some(Temporary::ZoomOut));\n click(&mut h, 200.0, 150.0, Modifiers::ALT);\n let z2 = h.state().ui.views[0].zoom;\n assert!(z2 < z1, \"{z1} -> {z2}\");",
|
|
"expected_assertions": [
|
|
" assert_eq!(held_tool(h.state(), &h.ctx), Some(Temporary::ZoomIn));\n click(&mut h, 200.0, 150.0, Modifiers::COMMAND);\n let z1 = h.state().ui.views[0].zoom;\n assert!(z1 > z0, \"{z0} -> {z1}\");\n hold_mods(&mut h, Modifiers::ALT);\n assert_eq!(held_tool(h.state(), &h.ctx), Some(Temporary::ZoomOut));\n click(&mut h, 200.0, 150.0, Modifiers::ALT);\n let z2 = h.state().ui.views[0].zoom;\n assert!(z2 < z1, \"{z1} -> {z2}\");\n hold_mods(&mut h, Modifiers::COMMAND | Modifiers::ALT);\n assert_eq!(held_tool(h.state(), &h.ctx), Some(Temporary::ZoomOut), \"\u2325 turns \u2318's Zoom In around\");\n hold_mods(&mut h, Modifiers::NONE);\n assert_eq!(held_tool(h.state(), &h.ctx), None);\n // Released: a drag pans again.\n let (center, zoom) = (h.state().ui.views[0].center, h.state().ui.views[0].zoom);\n drag_with(&mut h, Modifiers::NONE, 200.0, 150.0, 260.0, 190.0);\n assert_ne!(h.state().ui.views[0].center, center, \"the Hand pans\");\n assert_eq!(h.state().ui.views[0].zoom, zoom);\n assert_eq!(h.state().ui.tool, Tool::Hand);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/25c38a0b69b7bff31badcdbe2ef9f2ff6aba1c63/crates/ui-egui/src/hold_keys/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "cmd_mid_pan_or_during_free_transform_is_not_the_hand_tools_zoom",
|
|
"path": "crates/ui-egui/src/hold_keys/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked cmd_mid_pan_or_during_free_transform_is_not_the_hand_tools_zoom -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut h = harness(Tool::Hand);\n let z0 = h.state().ui.views[0].zoom;\n press_at(&mut h, 200.0, 150.0);\n hold_mods(&mut h, Modifiers::COMMAND);\n let center = h.state().ui.views[0].center;\n move_to(&mut h, 300.0, 150.0);\n assert_ne!(h.state().ui.views[0].center, center, \"the drag kept panning after \u2318 went down\");\n release(&mut h, 300.0, 150.0, Modifiers::COMMAND);\n hold_mods(&mut h, Modifiers::NONE);\n assert_eq!(h.state().ui.views[0].zoom, z0, \"no zoom\");\n\n with_layer(&mut h);",
|
|
"expected_assertions": [
|
|
" assert_ne!(h.state().ui.views[0].center, center, \"the drag kept panning after \u2318 went down\");\n release(&mut h, 300.0, 150.0, Modifiers::COMMAND);\n hold_mods(&mut h, Modifiers::NONE);\n assert_eq!(h.state().ui.views[0].zoom, z0, \"no zoom\");\n\n with_layer(&mut h);\n let ctx = h.ctx.clone();\n assert!(h.state().ui.transform.is_some());\n hold_mods(&mut h, Modifiers::COMMAND);\n assert_eq!(held_tool(h.state(), &h.ctx), None);\n hold_mods(&mut h, Modifiers::NONE);\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/25c38a0b69b7bff31badcdbe2ef9f2ff6aba1c63/crates/ui-egui/src/hold_keys/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-7255",
|
|
"pr": 7255,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked trim_and_duplicate_merged_on_too_large_document_fail_gracefully_without_panic -- --nocapture"
|
|
],
|
|
"expected": "trim and duplicate merged on too large document fail gracefully without panic",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked trim_and_duplicate_merged_on_too_large_document_fail_gracefully_without_panic -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "trim_and_duplicate_merged_on_too_large_document_fail_gracefully_without_panic",
|
|
"path": "crates/engine/src/image_cmds.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked trim_and_duplicate_merged_on_too_large_document_fail_gracefully_without_panic -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut s = Session::new();\n s.execute(\"file.new\", json!({\"width\": 40000, \"height\": 30000, \"background\": \"transparent\"})).unwrap();\n let initial_layers = doc(&s).layers.len();\n let initial_bounds = doc(&s).bounds();\n let initial_rev = s.active().unwrap().revision;\n let initial_docs = s.documents().len();\n\n let trim_res = s.execute(\"image.trim\", json!({\"basedOn\": \"topLeft\"}));\n assert!(trim_res.is_err(), \"trim on too-large document must return error\");\n let err = trim_res.unwrap_err().to_string();\n assert!(err.contains(\"too large to trim\"), \"error should explain document is too large: {err}\");\n assert_eq!(doc(&s).layers.len(), initial_layers, \"layer count unchanged after failed trim\");",
|
|
"expected_assertions": [
|
|
" assert!(trim_res.is_err(), \"trim on too-large document must return error\");\n let err = trim_res.unwrap_err().to_string();\n assert!(err.contains(\"too large to trim\"), \"error should explain document is too large: {err}\");\n assert_eq!(doc(&s).layers.len(), initial_layers, \"layer count unchanged after failed trim\");\n assert_eq!(doc(&s).bounds(), initial_bounds, \"canvas size unchanged after failed trim\");\n assert_eq!(s.active().unwrap().revision, initial_rev, \"revision unchanged after failed trim\");\n\n let dup_res = s.execute(\"image.duplicate\", json!({\"mergedOnly\": true}));\n assert!(dup_res.is_err(), \"duplicate merged on too-large document must return error\");\n let dup_err = dup_res.unwrap_err().to_string();\n assert!(dup_err.contains(\"too large to duplicate merged\"), \"error should explain document is too large: {dup_err}\");\n assert_eq!(s.documents().len(), initial_docs, \"document count unchanged after failed duplicate\");\n assert_eq!(doc(&s).layers.len(), initial_layers, \"layer count unchanged after failed duplicate\");\n assert_eq!(doc(&s).bounds(), initial_bounds, \"canvas size unchanged after failed duplicate\");\n assert_eq!(s.active().unwrap().revision, initial_rev, \"revision unchanged after failed duplicate\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/1b810052bc3a876c1eaf1a8766870ffdba9f8a80/crates/engine/src/image_cmds.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-8931",
|
|
"pr": 8931,
|
|
"subsystem": "Compositing and filters",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-algo --locked the_description_is_the_cpus_blur -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_impulse_spreads_no_further_than_the_reach -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked output_depends_only_on_the_input_region -- --nocapture"
|
|
],
|
|
"expected": "the description is the cpus blur; an impulse spreads no further than the reach; output depends only on the input region",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-algo --locked the_description_is_the_cpus_blur -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked an_impulse_spreads_no_further_than_the_reach -- --nocapture",
|
|
"cargo test -p photocraft-algo --locked output_depends_only_on_the_input_region -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "the_description_is_the_cpus_blur",
|
|
"path": "crates/algo/src/separable.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked the_description_is_the_cpus_blur -- --nocapture",
|
|
"fixture_and_action_excerpt": " for radius in RADII {\n let params = FilterParams::GaussianBlur { radius };\n let blur = Separable::of(¶ms).unwrap();\n match &blur {\n Separable::Kernel(k) => {\n assert!(radius <= 4.0, \"radius {radius}\");\n assert_eq!(k, &blur::gaussian_kernel(radius));\n assert_eq!(k.len() % 2, 1);\n assert!((k.iter().sum::<f32>() - 1.0).abs() < 1e-5);\n }\n Separable::Boxes(b) => {\n assert!(radius > 4.0, \"radius {radius}\");",
|
|
"expected_assertions": [
|
|
" assert!(radius <= 4.0, \"radius {radius}\");\n assert_eq!(k, &blur::gaussian_kernel(radius));\n assert_eq!(k.len() % 2, 1);\n assert!((k.iter().sum::<f32>() - 1.0).abs() < 1e-5);\n }\n Separable::Boxes(b) => {\n assert!(radius > 4.0, \"radius {radius}\");\n assert_eq!(Some(b.clone()), blur::box_widths(¶ms));\n assert!(b.iter().all(|w| w % 2 == 1));\n }\n }\n let Halo::Radius(halo) = params.halo() else { panic!(\"a Gaussian has a radius halo\") };\n assert!(blur.reach() <= halo, \"radius {radius}: reach {} past the halo {halo}\", blur.reach());\n }\n assert_eq!(Separable::of(&FilterParams::BoxBlur { radius: 9.0 }), None, \"not a Gaussian (yet)\");\n assert_eq!(Separable::Boxes(vec![usize::MAX, 3]).reach(), i32::MAX, \"saturates\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d42dd4c6302c77c1f9dc46b7b53ffa5eb0047a13/crates/algo/src/separable.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_impulse_spreads_no_further_than_the_reach",
|
|
"path": "crates/algo/src/separable.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked an_impulse_spreads_no_further_than_the_reach -- --nocapture",
|
|
"fixture_and_action_excerpt": " for radius in RADII {\n let params = FilterParams::GaussianBlur { radius };\n let reach = Separable::of(¶ms).unwrap().reach();\n let fmt = PixelFormat::new(ColorMode::Rgb, SampleType::F32, true);\n let size = 2 * reach + 41;\n let canvas = Rect::new(0, 0, size, size);\n let mut s = Surface::new(fmt);\n let dot = Rect::new(size / 2, size / 2, size / 2 + 1, size / 2 + 1);\n s.fill_rect(dot, &[1.0, 1.0, 1.0, 1.0]);\n let out = crate::apply_in_with(&s, ¶ms, canvas, canvas, None, canvas, &Interrupt::NONE).unwrap();\n let mut px = Vec::new();\n out.read_region_into(canvas, &mut px);",
|
|
"expected_assertions": [
|
|
" assert!(dot.inflate(reach).contains_rect(&touched), \"radius {radius}: {touched:?} past the reach {reach}\");\n if matches!(Separable::of(¶ms), Some(Separable::Kernel(_))) {\n assert_eq!(touched, dot.inflate(reach), \"radius {radius}\");\n }\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d42dd4c6302c77c1f9dc46b7b53ffa5eb0047a13/crates/algo/src/separable.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "output_depends_only_on_the_input_region",
|
|
"path": "crates/algo/src/separable.rs",
|
|
"package": "photocraft-algo",
|
|
"command": "cargo test -p photocraft-algo --locked output_depends_only_on_the_input_region -- --nocapture",
|
|
"fixture_and_action_excerpt": " let fmt = PixelFormat::new(ColorMode::Rgb, SampleType::F32, true);\n let extent = Rect::new(0, 0, 300, 200);\n let noise = |seed: u32| {\n let mut s = Surface::new(fmt);\n for y in 0..200 {\n for x in 0..300 {\n let h = (x as u32).wrapping_mul(73_856_093) ^ (y as u32).wrapping_mul(19_349_663) ^ seed;\n let v = (h % 1000) as f32 / 999.0;\n s.fill_rect(Rect::new(x, y, x + 1, y + 1), &[v, 1.0 - v, (h % 7) as f32 / 6.0, (h % 5) as f32 / 4.0]);\n }\n }\n s",
|
|
"expected_assertions": [
|
|
" assert!(extent.contains_rect(&input) && input.contains_rect(&out));\n // Everything outside the input region replaced by other pixels.\n let mut b = noise(2);\n let mut inside = Vec::new();\n assert_eq!(blur(&a), blur(&b), \"radius {radius}, {out:?}\");\n }\n }\n assert_eq!(OperatorRegion { reach: 5, extent }.input(Rect::EMPTY), Rect::EMPTY);\n assert_eq!(OperatorRegion { reach: 5, extent }.input(Rect::new(400, 400, 410, 410)), Rect::EMPTY, \"out of reach of the extent\");\n assert_eq!(OperatorRegion { reach: -3, extent }.input(Rect::new(10, 10, 20, 20)), Rect::new(10, 10, 20, 20));\n assert_eq!(edge_extent(extent, Rect::new(-10, 50, 20, 60)), Rect::new(-10, 0, 300, 200));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/d42dd4c6302c77c1f9dc46b7b53ffa5eb0047a13/crates/algo/src/separable.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9004",
|
|
"pr": 9004,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Studio Dark and Studio Light at UI scales 100% and 200%, 1280x800 and 900x600 logical-point windows; synthetic document with two selected layers and Move tool. Capture disabled state with fewer selected layers too.",
|
|
"action": "Capture the six Move Align controls and Align and distribute ellipsis at each theme/scale/window combination. Measure icon artwork/hit rectangles from the captured scale and invoke Left Edges then Undo.",
|
|
"expected": "Artwork is 20 logical points within 28-point hit targets (40/56 physical pixels at 2x), without clipping or overlap. Enabled-state and command dispatch are unchanged; Left Edges aligns the selected layers and Undo restores their positions.",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": ""
|
|
},
|
|
{
|
|
"id": "PR-9015",
|
|
"pr": 9015,
|
|
"subsystem": "Platform and reliability",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p xtask --locked rejects_numeric_prerelease_identifiers_with_leading_zeroes -- --nocapture"
|
|
],
|
|
"expected": "rejects numeric prerelease identifiers with leading zeroes",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p xtask --locked rejects_numeric_prerelease_identifiers_with_leading_zeroes -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "rejects_numeric_prerelease_identifiers_with_leading_zeroes",
|
|
"path": "xtask/src/version.rs",
|
|
"package": "xtask",
|
|
"command": "cargo test -p xtask --locked rejects_numeric_prerelease_identifiers_with_leading_zeroes -- --nocapture",
|
|
"fixture_and_action_excerpt": " for version in [\"1.0.0-01\", \"1.0.0-rc.01\", \"1.0.0-00.1\"] {\n assert!(validate(version).is_err(), \"validator accepted invalid version {version}\");\n assert!(replace(MANIFEST, version).is_err(), \"accepted invalid version {version}\");\n }\n for version in [\"1.0.0-0\", \"1.0.0-rc.0\", \"1.0.0-01a\", \"1.0.0-01-2\"] {\n let updated = replace(MANIFEST, version).expect(\"valid prerelease\");\n assert_eq!(read(&updated).unwrap(), version);\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(validate(version).is_err(), \"validator accepted invalid version {version}\");\n assert!(replace(MANIFEST, version).is_err(), \"accepted invalid version {version}\");\n }\n for version in [\"1.0.0-0\", \"1.0.0-rc.0\", \"1.0.0-01a\", \"1.0.0-01-2\"] {\n let updated = replace(MANIFEST, version).expect(\"valid prerelease\");\n assert_eq!(read(&updated).unwrap(), version);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/afb4364a8795c42e6353762891b4890d878f9a68/xtask/src/version.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9172",
|
|
"pr": 9172,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-engine --locked new_gradient_fill_layer_defaults_to_foreground_to_transparent -- --nocapture"
|
|
],
|
|
"expected": "new gradient fill layer defaults to foreground to transparent",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-engine --locked new_gradient_fill_layer_defaults_to_foreground_to_transparent -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "new_gradient_fill_layer_defaults_to_foreground_to_transparent",
|
|
"path": "crates/engine/src/gradient_fill_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked new_gradient_fill_layer_defaults_to_foreground_to_transparent -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #8708: Photoshop's Layer \u203a New Fill Layer \u203a Gradient\u2026 starts from Foreground to\n // Transparent: the foreground at both ends, its opacity 100% to 0%. A `to` colour keeps a\n // two-colour gradient.\n let mut s = session(8, \"transparent\");\n s.tools.foreground = [0.2, 0.4, 0.6, 1.0];\n s.tools.background = [1.0, 1.0, 1.0, 1.0];\n s.execute(\"layer.newFillLayer.gradient\", json!({})).unwrap();\n let Fill::Gradient { stops, opacity_stops, .. } = active_fill(&s) else { panic!(\"not a gradient\") };\n let fg = Color::rgba(0.2, 0.4, 0.6, 1.0);\n assert_eq!(stops, vec![(0.0, fg), (1.0, fg)]);\n assert_eq!(opacity_stops, vec![(0.0, 1.0), (1.0, 0.0)]);\n s.execute(\"layer.newFillLayer.gradient\", json!({\"to\": \"#ff0000\"})).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(stops, vec![(0.0, fg), (1.0, fg)]);\n assert_eq!(opacity_stops, vec![(0.0, 1.0), (1.0, 0.0)]);\n s.execute(\"layer.newFillLayer.gradient\", json!({\"to\": \"#ff0000\"})).unwrap();\n let Fill::Gradient { stops, opacity_stops, .. } = active_fill(&s) else { panic!(\"not a gradient\") };\n assert_eq!(stops[1].1, Color::rgba(1.0, 0.0, 0.0, 1.0));\n assert!(opacity_stops.is_empty());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/8ebb04999d25790f71f9bd88f7a268a6a2754aec/crates/engine/src/gradient_fill_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9282",
|
|
"pr": 9282,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked adjustment_preset_menus_load_presets_and_read_custom_after_an_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked properties_preset_menus_load_every_setting_in_one_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preset_menus_say_they_are_photocrafts_own -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_apply_and_are_recognised -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_give_their_looks -- --nocapture"
|
|
],
|
|
"expected": "adjustment preset menus load presets and read custom after an edit; properties preset menus load every setting in one step; preset menus say they are photocrafts own; presets apply and are recognised; presets give their looks",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked adjustment_preset_menus_load_presets_and_read_custom_after_an_edit -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked properties_preset_menus_load_every_setting_in_one_step -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked preset_menus_say_they_are_photocrafts_own -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_apply_and_are_recognised -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked presets_give_their_looks -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "adjustment_preset_menus_load_presets_and_read_custom_after_an_edit",
|
|
"path": "crates/ui-egui/src/adjust_dialog.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked adjustment_preset_menus_load_presets_and_read_custom_after_an_edit -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::{NodeT, Queryable};\n for (kind, label, key) in [\n (\"levels\", \"Increase Contrast 2\", \"inBlack\"),\n (\"exposure\", \"Plus 1.0\", \"exposure\"),\n (\"blackWhite\", \"Red Filter\", \"reds\"),\n (\"channelMixer\", \"Black & White with Red Filter (RGB)\", \"monochrome\"),\n ] {\n let mut h = Harness::builder().with_size(egui::vec2(1200.0, 900.0)).build_ui_state(|ui, app| crate::dialogs::show(app, ui.ctx()), app_with_image());\n PhotocraftApp::setup_context(&h.ctx, crate::theme::ThemeKind::ALL[0]);\n let id = open(h.state_mut(), &format!(\"image.adjustments.{kind}\")).unwrap();\n h.run_steps(4);\n let preset = |h: &Harness<'_, PhotocraftApp>| {",
|
|
"expected_assertions": [
|
|
" assert_eq!(preset(&h).as_deref(), Some(\"Default\"), \"{kind} opens on Default\");\n h.query_all_by_role(egui::accesskit::Role::ComboBox).next().unwrap().click();\n h.run_steps(2);\n h.get_by_label(label).click();\n assert_eq!(preset(&h).as_deref(), Some(label), \"{kind}: the menu shows the preset\");\n let want = crate::adjust_presets::presets(kind, false)\n .iter()\n .find(|p| p.label == label)\n assert_eq!(fields[k], *v, \"{kind}: the preset's `{k}` is loaded\");\n }\n assert_eq!(fields[key], want[key]);\n let edit = match kind {\n \"levels\" => (\"gamma\", json!(1.37)),\n \"exposure\" => (\"offset\", json!(0.05)),\n assert_eq!(preset(&h).as_deref(), Some(\"Custom\"), \"{kind}: an edit is Custom\");\n crate::dialogs::confirm(h.state_mut(), id).unwrap();\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/20803d1f15900ed6ecc7b5c79b4c68f6c3d6dcce/crates/ui-egui/src/adjust_dialog.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "properties_preset_menus_load_every_setting_in_one_step",
|
|
"path": "crates/ui-egui/src/adjust_editors_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked properties_preset_menus_load_every_setting_in_one_step -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::kittest::NodeT;\n for (kind, label) in\n [(\"levels\", \"Increase Contrast 2\"), (\"exposure\", \"Plus 1.0\"), (\"blackWhite\", \"Red Filter\"), (\"channelMixer\", \"Black & White with Red Filter (RGB)\")]\n {\n let mut h = app_harness(kind, \"rgb\", 8);\n let steps = h.state().session.active().unwrap().history.past_len();\n let menu = h\n .query_all_by_role(egui::accesskit::Role::ComboBox)\n .find(|n| n.accesskit_node().value().as_deref() == Some(\"Default\"))\n .unwrap_or_else(|| panic!(\"{kind}: the Preset menu, at Default\"));\n menu.click();\n h.run_steps(2);",
|
|
"expected_assertions": [
|
|
" assert_eq!(got[k], *v, \"{kind}: the layer's `{k}`\");\n }\n assert_eq!(h.state().session.active().unwrap().history.past_len(), steps + 1, \"{kind}: one step\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/20803d1f15900ed6ecc7b5c79b4c68f6c3d6dcce/crates/ui-egui/src/adjust_editors_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "preset_menus_say_they_are_photocrafts_own",
|
|
"path": "crates/ui-egui/src/adjust_editors_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked preset_menus_say_they_are_photocrafts_own -- --nocapture",
|
|
"fixture_and_action_excerpt": " for kind in [\"levels\", \"exposure\", \"blackWhite\", \"channelMixer\"] {\n let mut h = app_harness(kind, \"rgb\", 8);\n let caption = h.get_by_label(\"PhotoCraft Preset:\");\n caption.hover();\n h.run_steps(30);\n assert!(h.query_by_label_contains(\"not Photoshop's presets\").is_some(), \"{kind}: the caption explains the presets are PhotoCraft's own\");\n }\n}",
|
|
"expected_assertions": [
|
|
" assert!(h.query_by_label_contains(\"not Photoshop's presets\").is_some(), \"{kind}: the caption explains the presets are PhotoCraft's own\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/20803d1f15900ed6ecc7b5c79b4c68f6c3d6dcce/crates/ui-egui/src/adjust_editors_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "presets_apply_and_are_recognised",
|
|
"path": "crates/ui-egui/src/adjust_presets.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked presets_apply_and_are_recognised -- --nocapture",
|
|
"fixture_and_action_excerpt": " for kind in [\"levels\", \"exposure\", \"blackWhite\", \"channelMixer\"] {\n let all = presets(kind, false);\n assert!(all.len() >= 5 && all[0].id == \"default\", \"{kind}\");\n for p in all {\n let s = settings(kind, p, false).unwrap_or_else(|| panic!(\"{kind} {}: valid params\", p.id));\n assert_eq!(matching(kind, &s, false).map(|m| m.id), Some(p.id), \"{kind} {}\", p.id);\n }\n let distinct: std::collections::HashSet<String> = all.iter().map(|p| settings(kind, p, false).unwrap().to_string()).collect();\n assert_eq!(distinct.len(), all.len(), \"{kind}: no two presets are the same\");\n assert_eq!(matching(kind, &json!({}), false).map(|p| p.id), Some(\"default\"), \"{kind}: untouched is Default\");\n }\n let mut v = settings(\"levels\", &LEVELS[3], false).unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(all.len() >= 5 && all[0].id == \"default\", \"{kind}\");\n for p in all {\n let s = settings(kind, p, false).unwrap_or_else(|| panic!(\"{kind} {}: valid params\", p.id));\n assert_eq!(matching(kind, &s, false).map(|m| m.id), Some(p.id), \"{kind} {}\", p.id);\n }\n let distinct: std::collections::HashSet<String> = all.iter().map(|p| settings(kind, p, false).unwrap().to_string()).collect();\n assert_eq!(distinct.len(), all.len(), \"{kind}: no two presets are the same\");\n assert_eq!(matching(kind, &json!({}), false).map(|p| p.id), Some(\"default\"), \"{kind}: untouched is Default\");\n }\n let mut v = settings(\"levels\", &LEVELS[3], false).unwrap();\n v[\"gamma\"] = json!(1.37);\n assert!(matching(\"levels\", &v, false).is_none(), \"an edit is Custom\");\n assert!(presets(\"blackWhite\", true).is_empty() && presets(\"channelMixer\", true).is_empty(), \"colour presets need colour\");\n assert_eq!(presets(\"levels\", true).len(), LEVELS.len());\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/20803d1f15900ed6ecc7b5c79b4c68f6c3d6dcce/crates/ui-egui/src/adjust_presets.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "presets_give_their_looks",
|
|
"path": "crates/ui-egui/src/adjust_presets.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked presets_give_their_looks -- --nocapture",
|
|
"fixture_and_action_excerpt": " let lv = |id: &str| settings(\"levels\", LEVELS.iter().find(|p| p.id == id).unwrap(), false).unwrap();\n let span = |v: &Value| v[\"inWhite\"].as_f64().unwrap() - v[\"inBlack\"].as_f64().unwrap();\n assert!(span(&lv(\"increaseContrast1\")) > span(&lv(\"increaseContrast2\")) && span(&lv(\"increaseContrast2\")) > span(&lv(\"increaseContrast3\")));\n assert!(lv(\"midtonesBrighter\")[\"gamma\"].as_f64().unwrap() > 1.0 && lv(\"midtonesDarker\")[\"gamma\"].as_f64().unwrap() < 1.0);\n let bw = |id: &str| settings(\"blackWhite\", BLACK_WHITE.iter().find(|p| p.id == id).unwrap(), false).unwrap();\n let w = |v: &Value, k: &str| v[k].as_f64().unwrap();\n assert!(w(&bw(\"redFilter\"), \"reds\") > w(&bw(\"redFilter\"), \"cyans\"), \"a red filter lightens reds over cyans\");\n assert!(w(&bw(\"blueFilter\"), \"blues\") > w(&bw(\"blueFilter\"), \"yellows\"), \"a blue filter lightens blues over yellows\");\n assert!(\n w(&bw(\"highContrastRedFilter\"), \"reds\") - w(&bw(\"highContrastRedFilter\"), \"blues\") > w(&bw(\"redFilter\"), \"reds\") - w(&bw(\"redFilter\"), \"blues\")\n );\n let ex = |id: &str| settings(\"exposure\", EXPOSURE.iter().find(|p| p.id == id).unwrap(), false).unwrap()[\"exposure\"].as_f64().unwrap();",
|
|
"expected_assertions": [
|
|
" assert!(span(&lv(\"increaseContrast1\")) > span(&lv(\"increaseContrast2\")) && span(&lv(\"increaseContrast2\")) > span(&lv(\"increaseContrast3\")));\n assert!(lv(\"midtonesBrighter\")[\"gamma\"].as_f64().unwrap() > 1.0 && lv(\"midtonesDarker\")[\"gamma\"].as_f64().unwrap() < 1.0);\n let bw = |id: &str| settings(\"blackWhite\", BLACK_WHITE.iter().find(|p| p.id == id).unwrap(), false).unwrap();\n let w = |v: &Value, k: &str| v[k].as_f64().unwrap();\n assert!(w(&bw(\"redFilter\"), \"reds\") > w(&bw(\"redFilter\"), \"cyans\"), \"a red filter lightens reds over cyans\");\n assert!(w(&bw(\"blueFilter\"), \"blues\") > w(&bw(\"blueFilter\"), \"yellows\"), \"a blue filter lightens blues over yellows\");\n assert!(\n w(&bw(\"highContrastRedFilter\"), \"reds\") - w(&bw(\"highContrastRedFilter\"), \"blues\") > w(&bw(\"redFilter\"), \"reds\") - w(&bw(\"redFilter\"), \"blues\")\n );\n let ex = |id: &str| settings(\"exposure\", EXPOSURE.iter().find(|p| p.id == id).unwrap(), false).unwrap()[\"exposure\"].as_f64().unwrap();\n assert_eq!([ex(\"minus2\"), ex(\"minus1\"), ex(\"plus1\"), ex(\"plus2\")], [-2.0, -1.0, 1.0, 2.0]);\n for p in &CHANNEL_MIXER[1..] {\n let s = settings(\"channelMixer\", p, false).unwrap();\n assert_eq!(s[\"monochrome\"], json!(true), \"{}\", p.id);\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/20803d1f15900ed6ecc7b5c79b4c68f6c3d6dcce/crates/ui-egui/src/adjust_presets.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9354",
|
|
"pr": 9354,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked screen_mode_button_is_inert_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked long_press_screen_mode_opens_the_modes_without_cycling -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked full_screen_modes_need_a_document -- --nocapture"
|
|
],
|
|
"expected": "screen mode button is inert without a document; long press screen mode opens the modes without cycling; full screen modes need a document",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked screen_mode_button_is_inert_without_a_document -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked long_press_screen_mode_opens_the_modes_without_cycling -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked full_screen_modes_need_a_document -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "screen_mode_button_is_inert_without_a_document",
|
|
"path": "crates/ui-egui/src/panels.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked screen_mode_button_is_inert_without_a_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", serde_json::json!({\"width\": 64, \"height\": 48})).unwrap();\n let ctx = egui::Context::default();\n PhotocraftApp::setup_context(&ctx, crate::theme::ThemeKind::ALL[0]);\n frame(&mut app, &ctx, 0.0, vec![]);\n frame(&mut app, &ctx, 0.1, vec![]);\n let bx = if Tokens::get(&ctx).pro { 30.0 } else { 36.0 };\n // Found while a document makes it clickable: the toolbar's last button.\n let at = ctx\n .viewport(|v| {\n v.prev_pass\n .widgets",
|
|
"expected_assertions": [
|
|
" assert_eq!(crate::view_cmds::is_enabled(&app, \"view.screenMode.cycle\"), Some(false));\n let pointer = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };\n let mut sent = Vec::new();\n for (t, events) in [(2.0, vec![egui::Event::PointerMoved(at), pointer(true)]), (2.1, vec![pointer(false)]), (2.15, vec![])] {\n assert!(!sent.iter().any(|c| matches!(c, egui::ViewportCommand::Fullscreen(_))), \"no screen mode change was sent: {sent:?}\");\n assert_eq!(app.ui.view.screen_mode, \"standard\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/41eb1de5cff17f5f5b9c22913e48b71565b56a2a/crates/ui-egui/src/panels.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "long_press_screen_mode_opens_the_modes_without_cycling",
|
|
"path": "crates/ui-egui/src/panels.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked long_press_screen_mode_opens_the_modes_without_cycling -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n // A document open: Full Screen Mode needs one (#9349), so without it a click can't cycle.\n app.run(\"file.new\", serde_json::json!({\"width\": 64, \"height\": 48})).unwrap();\n let ctx = egui::Context::default();\n PhotocraftApp::setup_context(&ctx, crate::theme::ThemeKind::ALL[0]);\n frame(&mut app, &ctx, 0.0, vec![]);\n frame(&mut app, &ctx, 0.1, vec![]);\n let bx = if Tokens::get(&ctx).pro { 30.0 } else { 36.0 };\n // The toolbar's last button: Change Screen Mode, after Quick Mask.\n let at = ctx\n .viewport(|v| {\n v.prev_pass",
|
|
"expected_assertions": [
|
|
" assert!(standard(&app));\n // Hold, then release: the list opens and stays open, and the mode is unchanged.\n frame(&mut app, &ctx, 1.0, vec![egui::Event::PointerMoved(at), pointer(at, true)]);\n frame(&mut app, &ctx, 1.2, vec![]);\n assert!(!menu_open(&ctx), \"not before the hold time\");\n frame(&mut app, &ctx, 1.4, vec![]);\n assert!(menu_open(&ctx), \"open while still held\");\n frame(&mut app, &ctx, 1.5, vec![pointer(at, false)]);\n frame(&mut app, &ctx, 1.55, vec![]);\n assert!(menu_open(&ctx), \"the release keeps it open\");\n assert!(standard(&app), \"the release doesn't cycle the mode\");\n // Escape closes it; a plain click cycles the mode and opens nothing.\n frame(\n &mut app,\n assert!(!menu_open(&ctx));\n frame(&mut app, &ctx, 3.0, vec![egui::Event::PointerMoved(at), pointer(at, true)]);\n frame(&mut app, &ctx, 3.1, vec![pointer(at, false)]);\n frame(&mut app, &ctx, 3.15, vec![]);\n assert!(!standard(&app), \"a click cycles\");\n assert!(!menu_open(&ctx));\n // Right-click opens it too.\n let secondary = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Secondary, pressed, modifiers: Default::default() };\n frame(&mut app, &ctx, 4.0, vec![secondary(true)]);\n assert!(menu_open(&ctx));\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/41eb1de5cff17f5f5b9c22913e48b71565b56a2a/crates/ui-egui/src/panels.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "full_screen_modes_need_a_document",
|
|
"path": "crates/ui-egui/src/view_cmds/tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked full_screen_modes_need_a_document -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, ctx) = app_with(0);\n for id in [\"view.screenMode.fullScreen\", \"view.screenMode.fullScreenWithMenuBar\", \"view.screenMode.cycle\"] {\n assert_eq!(is_enabled(&app, id), Some(false), \"{id} without a document\");\n }\n // #9354 review: run anyway (the toolbar list, automation), they are refused and Standard stays.\n for id in [\"view.screenMode.fullScreen\", \"view.screenMode.fullScreenWithMenuBar\"] {\n assert!(menu(&mut app, &ctx, id, json!({})).is_err(), \"{id} is refused without a document\");\n assert_eq!(app.ui.view.screen_mode, \"standard\", \"{id}\");\n }\n assert_eq!(is_enabled(&app, \"view.screenMode.standard\"), Some(true));\n let (mut with_doc, _) = app_with(1);\n for id in [\"view.screenMode.fullScreen\", \"view.screenMode.fullScreenWithMenuBar\", \"view.screenMode.cycle\"] {",
|
|
"expected_assertions": [
|
|
" assert_eq!(is_enabled(&app, id), Some(false), \"{id} without a document\");\n }\n // #9354 review: run anyway (the toolbar list, automation), they are refused and Standard stays.\n for id in [\"view.screenMode.fullScreen\", \"view.screenMode.fullScreenWithMenuBar\"] {\n assert!(menu(&mut app, &ctx, id, json!({})).is_err(), \"{id} is refused without a document\");\n assert_eq!(app.ui.view.screen_mode, \"standard\", \"{id}\");\n }\n assert_eq!(is_enabled(&app, \"view.screenMode.standard\"), Some(true));\n let (mut with_doc, _) = app_with(1);\n for id in [\"view.screenMode.fullScreen\", \"view.screenMode.fullScreenWithMenuBar\", \"view.screenMode.cycle\"] {\n assert_eq!(is_enabled(&with_doc, id), Some(true), \"{id} with a document\");\n }\n // The last document closed in Full Screen Mode: back to Standard.\n menu(&mut with_doc, &ctx, \"view.screenMode.fullScreen\", json!({})).unwrap();\n assert_eq!(with_doc.ui.view.screen_mode, \"fullScreen\", \"a document is still open\");\n with_doc.run(\"file.close\", json!({\"save\": false})).unwrap();\n assert!(with_doc.session.documents().is_empty());\n leave_full_screen_without_document(&mut with_doc, &ctx);\n assert_eq!(with_doc.ui.view.screen_mode, \"standard\");\n // A full screen mode reached anyway (automation) with no document drops back the same way.\n app.ui.view.screen_mode = \"fullScreenWithMenuBar\".into();\n assert_eq!(is_enabled(&app, \"view.screenMode.cycle\"), Some(true), \"Cycle can still leave it\");\n // #9354 review: and Cycle itself goes straight back to Standard, not on to Full Screen.\n menu(&mut app, &ctx, \"view.screenMode.cycle\", json!({})).unwrap();\n assert_eq!(app.ui.view.screen_mode, \"standard\", \"Cycle without a document returns to Standard\");\n app.ui.view.screen_mode = \"fullScreenWithMenuBar\".into();\n leave_full_screen_without_document(&mut app, &ctx);\n assert_eq!(app.ui.view.screen_mode, \"standard\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/41eb1de5cff17f5f5b9c22913e48b71565b56a2a/crates/ui-egui/src/view_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9418",
|
|
"pr": 9418,
|
|
"subsystem": "File fidelity and colour",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-cms --locked three_dl_without_a_header_reads_low_nodes_as_12_bit -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_three_point_shaper_is_not_a_node -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_declares_the_output_depth -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_header_mismatch_is_rejected -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_malformed_mesh_header_falls_back_to_inference -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_uses_declared_range_for_small_integer_codes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked color_lookup_mesh_3dl_honours_the_header -- --nocapture"
|
|
],
|
|
"expected": "three dl without a header reads low nodes as 12 bit; three dl mesh three point shaper is not a node; three dl mesh declares the output depth; three dl mesh header mismatch is rejected; three dl malformed mesh header falls back to inference; three dl mesh uses declared range for small integer codes; color lookup mesh 3dl honours the header",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-cms --locked three_dl_without_a_header_reads_low_nodes_as_12_bit -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_three_point_shaper_is_not_a_node -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_declares_the_output_depth -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_header_mismatch_is_rejected -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_malformed_mesh_header_falls_back_to_inference -- --nocapture",
|
|
"cargo test -p photocraft-cms --locked three_dl_mesh_uses_declared_range_for_small_integer_codes -- --nocapture",
|
|
"cargo test -p photocraft-engine --locked color_lookup_mesh_3dl_honours_the_header -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "three_dl_without_a_header_reads_low_nodes_as_12_bit",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_without_a_header_reads_low_nodes_as_12_bit -- --nocapture",
|
|
"fixture_and_action_excerpt": " let table = |peak: u32| -> String {\n let mut text = String::from(\"0 1023\\n\");\n for i in 0..8 {\n let on = |bit: u32| if i & bit != 0 { peak } else { 0 };\n text.push_str(&format!(\"{} {} {}\\n\", on(4), on(2), on(1)));\n }\n text\n };\n for peak in [255, 1023, 4095] {\n let white = parse_3dl(&table(peak)).unwrap().data[21..24].to_vec();\n assert_eq!(white, [peak as f32 / 4095.0; 3], \"peak {peak}\");\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(white, [peak as f32 / 4095.0; 3], \"peak {peak}\");\n }\n // A header keeps the inferred 10-bit depth. The bare `3DMESH` magic is a header without a\n // cube declaration; `Mesh 1 10` would declare a 3\u00b3 cube and refuse this 2\u00b3 table (#9078).\n assert_eq!(white, [1.0; 3]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "three_dl_mesh_three_point_shaper_is_not_a_node",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_mesh_three_point_shaper_is_not_a_node -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #9078: Photoshop loads a 3\u00b3 cube whose shaper line has three values; counting it as a\n // 28th node rejected the whole file.\n let l = parse_3dl(&mesh_3dl(1, 12, 3, 4095.0, true)).unwrap();\n assert_eq!(l.size, 3);\n assert_eq!(l.data.len(), 3 * 3 * 3 * 3);\n // The inverse identity: node (0,0,0) is full, node (2,2,2) black.\n assert!((l.data[0] - 1.0).abs() < 1e-6 && (l.data[1] - 1.0).abs() < 1e-6 && (l.data[2] - 1.0).abs() < 1e-6);\n let last = &l.data[l.data.len() - 3..];\n assert_eq!(last, [0.0, 0.0, 0.0]);\n // The same 27 nodes without the shaper row still load (the node-only control).\n assert_eq!(parse_3dl(&mesh_3dl(1, 12, 3, 4095.0, false)).unwrap().data, l.data);\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(l.size, 3);\n assert_eq!(l.data.len(), 3 * 3 * 3 * 3);\n // The inverse identity: node (0,0,0) is full, node (2,2,2) black.\n assert!((l.data[0] - 1.0).abs() < 1e-6 && (l.data[1] - 1.0).abs() < 1e-6 && (l.data[2] - 1.0).abs() < 1e-6);\n let last = &l.data[l.data.len() - 3..];\n assert_eq!(last, [0.0, 0.0, 0.0]);\n // The same 27 nodes without the shaper row still load (the node-only control).\n assert_eq!(parse_3dl(&mesh_3dl(1, 12, 3, 4095.0, false)).unwrap().data, l.data);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "three_dl_mesh_declares_the_output_depth",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_mesh_declares_the_output_depth -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #9073: identical node codes divide by the declared range, not by the largest value.\n let mut text_10 = String::new();\n let mut text_12 = String::new();\n for (n_bits, out_bits, dst) in [(2, 10, &mut text_10), (2, 12, &mut text_12)] {\n // A 5\u00b3 identity scaled to 10-bit codes (max 1023).\n *dst = format!(\"3DMESH\\nMesh {n_bits} {out_bits}\\n0 256 512 768 1023\\n\");\n for r in 0..5 {\n for g in 0..5 {\n for b in 0..5 {\n dst.push_str(&format!(\"{} {} {}\\n\", r * 255, g * 255, b * 255));\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(white_10.size, 5);\n let last_10 = &white_10.data[white_10.data.len() - 3..];\n let last_12 = &white_12.data[white_12.data.len() - 3..];\n assert!((last_10[0] - 1020.0 / 1023.0).abs() < 1e-6, \"{last_10:?}\");\n // 1020/4095 \u2248 0.249: white renders grey, as Photoshop measures it.\n assert!((last_12[0] - 1020.0 / 4095.0).abs() < 1e-6, \"{last_12:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "three_dl_mesh_header_mismatch_is_rejected",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_mesh_header_mismatch_is_rejected -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A Mesh header that disagrees with the row count is refused, not silently re-inferred.\n assert!(parse_3dl(\"3DMESH\\nMesh 1 12\\n0 0 0\\n0 0 1\\n\").is_err());\n // A node beyond the declared range is a wrong declaration: the old inference from the\n // largest value keeps the file loading as it did before the header was honoured.\n let mut text = String::from(\"3DMESH\\nMesh 1 10\\n\");\n for r in 0..3 {\n for g in 0..3 {\n for b in 0..3 {\n text.push_str(&format!(\"{} {} {}\\n\", r * 2047, g * 2047, b * 2047));\n }\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!(parse_3dl(\"3DMESH\\nMesh 1 12\\n0 0 0\\n0 0 1\\n\").is_err());\n // A node beyond the declared range is a wrong declaration: the old inference from the\n // largest value keeps the file loading as it did before the header was honoured.\n let mut text = String::from(\"3DMESH\\nMesh 1 10\\n\");\n assert!((last[0] - 4094.0 / 4095.0).abs() < 1e-6, \"{last:?}\");\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "three_dl_malformed_mesh_header_falls_back_to_inference",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_malformed_mesh_header_falls_back_to_inference -- --nocapture",
|
|
"fixture_and_action_excerpt": " // A `Mesh` line that is not exactly two integer fields is not a declaration: it is\n // ignored and the table is inferred as if headerless, rather than recovering numbers\n // from the wrong positions (#9078). A 2\u00b3 cube would otherwise be read as a 3\u00b3 cube.\n for header in [\"Mesh invalid 1 12\", \"Mesh 1 12 13\", \"Mesh 1 x\", \"Mesh 1\"] {\n let mut text = format!(\"3DMESH\\n{header}\\n\");\n for r in 0..2 {\n for g in 0..2 {\n for b in 0..2 {\n text.push_str(&format!(\"{} {} {}\\n\", r * 1023, g * 1023, b * 1023));\n }\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(l.size, 2, \"{header}\");\n assert_eq!(l.data, LutFile::identity(2).data, \"{header}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "three_dl_mesh_uses_declared_range_for_small_integer_codes",
|
|
"path": "crates/cms/src/lutfile.rs",
|
|
"package": "photocraft-cms",
|
|
"command": "cargo test -p photocraft-cms --locked three_dl_mesh_uses_declared_range_for_small_integer_codes -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #9073: under a valid `Mesh` declaration the node codes are integers in the declared\n // range, so a max value of 1 is 1/4095 of full output \u2014 not full output itself.\n let mut text = String::from(\"3DMESH\\nMesh 1 12\\n\");\n for r in 0..3 {\n for g in 0..3 {\n for b in 0..3 {\n let v = u8::from(r == 0 && g == 0 && b == 0);\n text.push_str(&format!(\"{v} {v} {v}\\n\"));\n }\n }\n }\n let l = parse_3dl(&text).unwrap();",
|
|
"expected_assertions": [
|
|
" assert_eq!(l.size, 3);\n // blue fastest: node (0,0,0) is the first entry, code 1 \u2192 1/4095.\n assert!((l.data[0] - 1.0 / 4095.0).abs() < 1e-6, \"{:?}\", &l.data[0..3]);\n assert!(l.data[3..].iter().all(|&v| v == 0.0), \"{:?}\", l.data);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/cms/src/lutfile.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "color_lookup_mesh_3dl_honours_the_header",
|
|
"path": "crates/engine/src/adjust_cmds/tests.rs",
|
|
"package": "photocraft-engine",
|
|
"command": "cargo test -p photocraft-engine --locked color_lookup_mesh_3dl_honours_the_header -- --nocapture",
|
|
"fixture_and_action_excerpt": " // #9078 / #9073: a Lustre .3dl whose `Mesh <inBits> <outBits>` line declares the cube edge\n // (2^inBits + 1) and the output range (up to 2^outBits - 1). The three-value shaper row used\n // to be counted as a 28th node (\"28 rows is not a cube\"), and 10-bit codes under a 12-bit\n // declaration divided by the inferred 1023 instead of the declared 4095.\n let mut lut = String::from(\"3DMESH\\nMesh 1 12\\n0 512 1023\\n\");\n for r in 0..3 {\n for g in 0..3 {\n for b in 0..3 {\n let v = [r, g, b].map(|c| (4095.0 - 4095.0 * c as f64 / 2.0).round() as i32);\n lut.push_str(&format!(\"{} {} {}\\n\", v[0], v[1], v[2]));\n }\n }",
|
|
"expected_assertions": [
|
|
" assert!((after[c] * 255.0 - want).abs() <= 1.0, \"channel {c}: {after:?}\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/da4b838e54f6073cda4798fa7b63b3b7214aaf93/crates/engine/src/adjust_cmds/tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9481",
|
|
"pr": 9481,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked new_effects_start_from_the_made_default -- --nocapture"
|
|
],
|
|
"expected": "new effects start from the made default",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked new_effects_start_from_the_made_default -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "new_effects_start_from_the_made_default",
|
|
"path": "crates/ui-egui/src/layer_style.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked new_effects_start_from_the_made_default -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", json!({\"width\": 32, \"height\": 32})).unwrap();\n app.run(\"layer.new.layer\", json!({})).unwrap();\n app.run(\"layer.layerStyle.makeDefault\", json!({\"kind\": \"stroke\", \"params\": {\"size\": 7, \"position\": \"outside\"}})).unwrap();\n\n let id = open(&mut app, Some(\"stroke\")).unwrap();\n let mut f = app.ui.dialogs.iter().find(|d| d.id == id).unwrap().fields.clone();\n add_instance(&mut f, \"stroke\");\n add_instance(&mut f, \"dropShadow\");\n let fx = effects_of(&f);\n let strokes: Vec<_> = fx.iter().filter(|e| e[\"kind\"] == json!(\"stroke\")).collect();\n assert_eq!(strokes.len(), 2);",
|
|
"expected_assertions": [
|
|
" assert_eq!(strokes.len(), 2);\n for e in strokes {\n assert_eq!((&e[\"params\"][\"size\"], &e[\"params\"][\"position\"]), (&json!(7), &json!(\"outside\")));\n assert_eq!(e[\"params\"][\"opacity\"], defaults(\"stroke\")[\"opacity\"], \"unsaved keys keep the factory value\");\n }\n let shadow = fx.iter().find(|e| e[\"kind\"] == json!(\"dropShadow\")).unwrap();\n assert_eq!(shadow[\"params\"][\"size\"], defaults(\"dropShadow\")[\"size\"]);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/7937adff961027154d795b8905e821244ae4f929/crates/ui-egui/src/layer_style.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9504",
|
|
"pr": 9504,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked cmd_z_is_recorded_while_capturing_and_undoes_otherwise -- --nocapture"
|
|
],
|
|
"expected": "cmd z is recorded while capturing and undoes otherwise",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked cmd_z_is_recorded_while_capturing_and_undoes_otherwise -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "cmd_z_is_recorded_while_capturing_and_undoes_otherwise",
|
|
"path": "crates/ui-egui/src/shortcut_capture_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked cmd_z_is_recorded_while_capturing_and_undoes_otherwise -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut h, id) = dialog(1.0, \"edit.search\", \"search\u2026\");\n capture(&mut h, &crate::shortcuts::pretty(\"Cmd+F\"), Key::ControlLeft, Modifiers::COMMAND, Key::Z);\n assert_eq!(field(&h, id, \"overrides\")[\"edit.search\"], json!(\"Cmd+Z\"));\n assert_eq!(field(&h, id, \"capture\"), json!(false));\n key(&mut h, Key::Z, true, Modifiers::COMMAND);\n h.run_steps(2);\n assert_ne!(field(&h, id, \"overrides\")[\"edit.search\"], json!(\"Cmd+Z\"), \"\u2318Z outside a capture undoes the change\");\n assert_eq!(field(&h, id, \"capture\"), json!(false), \"and doesn't wait for keys again\");\n // CodeRabbit on #9504: clearing the restored capture isn't a new edit, so Redo still works.\n h.run_steps(2);\n key(&mut h, Key::Z, true, Modifiers::COMMAND | Modifiers::SHIFT);\n h.run_steps(2);",
|
|
"expected_assertions": [
|
|
" assert_eq!(field(&h, id, \"overrides\")[\"edit.search\"], json!(\"Cmd+Z\"));\n assert_eq!(field(&h, id, \"capture\"), json!(false));\n key(&mut h, Key::Z, true, Modifiers::COMMAND);\n h.run_steps(2);\n assert_ne!(field(&h, id, \"overrides\")[\"edit.search\"], json!(\"Cmd+Z\"), \"\u2318Z outside a capture undoes the change\");\n assert_eq!(field(&h, id, \"capture\"), json!(false), \"and doesn't wait for keys again\");\n // CodeRabbit on #9504: clearing the restored capture isn't a new edit, so Redo still works.\n h.run_steps(2);\n key(&mut h, Key::Z, true, Modifiers::COMMAND | Modifiers::SHIFT);\n assert_eq!(field(&h, id, \"overrides\")[\"edit.search\"], json!(\"Cmd+Z\"), \"\u21e7\u2318Z redoes the recorded shortcut\");\n assert_eq!(field(&h, id, \"capture\"), json!(false));\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/993c9ed167c6acd9bc8f87c6cff6e2c7abba17a8/crates/ui-egui/src/shortcut_capture_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9517",
|
|
"pr": 9517,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_buttons_stay_on_a_short_window -- --nocapture"
|
|
],
|
|
"expected": "layer style buttons stay on a short window",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked layer_style_buttons_stay_on_a_short_window -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "layer_style_buttons_stay_on_a_short_window",
|
|
"path": "crates/ui-egui/src/dialogs.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_style_buttons_stay_on_a_short_window -- --nocapture",
|
|
"fixture_and_action_excerpt": " use egui_kittest::{Harness, kittest::Queryable};\n\n let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.run(\"file.new\", serde_json::json!({\"width\": 64, \"height\": 64})).unwrap();\n app.run(\"layer.new.layer\", serde_json::json!({})).unwrap();\n let mut h = Harness::builder().with_size(egui::vec2(1435.0, 858.0)).build_ui_state(|ui, app| show(app, ui.ctx()), app);\n PhotocraftApp::setup_context(&h.ctx, crate::theme::ThemeKind::ALL[0]);\n crate::layer_style::open(h.state_mut(), Some(\"bevelEmboss\")).unwrap();\n h.run_steps(4);\n for label in [\"OK\", \"Cancel\"] {\n let r = h.get_by_label(label).rect();\n assert!(r.bottom() <= 858.0, \"{label} is off the window: {r:?}\");",
|
|
"expected_assertions": [
|
|
" assert!(r.bottom() <= 858.0, \"{label} is off the window: {r:?}\");\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/81b434c6149732eadc94e0465fea81bd075facd4/crates/ui-egui/src/dialogs.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9597",
|
|
"pr": 9597,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked layer_rows_do_not_move_when_no_layer_is_selected -- --nocapture"
|
|
],
|
|
"expected": "layer rows do not move when no layer is selected",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked layer_rows_do_not_move_when_no_layer_is_selected -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "layer_rows_do_not_move_when_no_layer_is_selected",
|
|
"path": "crates/ui-egui/src/layer_pct_slider_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked layer_rows_do_not_move_when_no_layer_is_selected -- --nocapture",
|
|
"fixture_and_action_excerpt": " for theme in [crate::theme::ThemeKind::Studio, crate::theme::ThemeKind::Classic, crate::theme::ThemeKind::ProMedium] {\n let mut h = harness();\n PhotocraftApp::setup_context(&h.ctx, theme);\n h.run_steps(4);\n let row_top = |h: &Harness<'_, PhotocraftApp>| by_role(h, \"Paint\", Role::Button).map(|r| r.top());\n let selected = row_top(&h);\n h.state_mut().session.execute(\"select.deselectLayers\", json!({})).unwrap();\n h.run_steps(4);\n let none = row_top(&h);\n assert!(selected.is_some(), \"{theme:?}: the layer row\");\n assert_eq!(none, selected, \"{theme:?}: the row moved with no layer selected\");\n }",
|
|
"expected_assertions": [
|
|
" assert!(selected.is_some(), \"{theme:?}: the layer row\");\n assert_eq!(none, selected, \"{theme:?}: the row moved with no layer selected\");\n }\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/9429df26b371c04c2afa65228a60ded739b5fbc2/crates/ui-egui/src/layer_pct_slider_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9598",
|
|
"pr": 9598,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked twirl_counterclockwise_has_its_own_mirrored_icon -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_reversed_twirl_survives_replay_undo_and_redo -- --nocapture"
|
|
],
|
|
"expected": "twirl counterclockwise has its own mirrored icon; alt reversed twirl survives replay undo and redo",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked twirl_counterclockwise_has_its_own_mirrored_icon -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked alt_reversed_twirl_survives_replay_undo_and_redo -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "twirl_counterclockwise_has_its_own_mirrored_icon",
|
|
"path": "crates/ui-egui/src/liquify_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked twirl_counterclockwise_has_its_own_mirrored_icon -- --nocapture",
|
|
"fixture_and_action_excerpt": " assert_eq!(tool_icon(LiquifyTool::TwirlCcw), \"rotate-ccw\");\n let svg = |name: &str| crate::icon_data::ICONS.iter().find(|(n, _)| *n == name).map(|(_, b)| String::from_utf8_lossy(b).into_owned());\n let (cw, ccw) = (svg(\"rotate-cw\").unwrap(), svg(\"rotate-ccw\").expect(\"the rotate-ccw icon\"));\n assert!(ccw.contains(\"M3 12a9 9 0 1 0 9-9\") && cw.contains(\"M21 12a9 9 0 1 1-9-9\"), \"mirror images\");\n for t in [LiquifyTool::ForwardWarp, LiquifyTool::TwirlCw, LiquifyTool::TwirlCcw, LiquifyTool::Pucker, LiquifyTool::Bloat] {\n assert!(svg(tool_icon(t)).is_some(), \"{t:?}: {}\", tool_icon(t));\n }\n }",
|
|
"expected_assertions": [
|
|
" assert_eq!(tool_icon(LiquifyTool::TwirlCcw), \"rotate-ccw\");\n let svg = |name: &str| crate::icon_data::ICONS.iter().find(|(n, _)| *n == name).map(|(_, b)| String::from_utf8_lossy(b).into_owned());\n let (cw, ccw) = (svg(\"rotate-cw\").unwrap(), svg(\"rotate-ccw\").expect(\"the rotate-ccw icon\"));\n assert!(ccw.contains(\"M3 12a9 9 0 1 0 9-9\") && cw.contains(\"M21 12a9 9 0 1 1-9-9\"), \"mirror images\");\n for t in [LiquifyTool::ForwardWarp, LiquifyTool::TwirlCw, LiquifyTool::TwirlCcw, LiquifyTool::Pucker, LiquifyTool::Bloat] {\n assert!(svg(tool_icon(t)).is_some(), \"{t:?}: {}\", tool_icon(t));\n }\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/47aea89e9220b996f0d5a0d2bb8b5938100b4ad1/crates/ui-egui/src/liquify_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "alt_reversed_twirl_survives_replay_undo_and_redo",
|
|
"path": "crates/ui-egui/src/liquify_ui.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked alt_reversed_twirl_survives_replay_undo_and_redo -- --nocapture",
|
|
"fixture_and_action_excerpt": " let ctx = egui::Context::default();\n let mut app = app_with_layer();\n open(&mut app, &ctx).unwrap();\n control(&mut app, &json!({\"tool\": \"twirlCw\", \"size\": 36, \"rate\": 80})).unwrap();\n\n // Releasing Alt while dragging must not change the tool recorded at pointer-down.\n pointer(&mut app, ToolEvent::Down { x: 53.0, y: 40.0, pressure: 1.0 }, egui::Modifiers::ALT);\n pointer(&mut app, ToolEvent::Move { x: 58.0, y: 41.0, pressure: 1.0 }, egui::Modifiers::NONE);\n pointer(&mut app, ToolEvent::Up { x: 58.0, y: 41.0 }, egui::Modifiers::NONE);\n let d = app.distort.liquify.as_ref().unwrap();\n assert_eq!(d.opts.tool, LiquifyTool::TwirlCw, \"Alt must not change the selected tool\");\n assert_eq!(d.strokes.len(), 1);",
|
|
"expected_assertions": [
|
|
" assert_eq!(d.opts.tool, LiquifyTool::TwirlCw, \"Alt must not change the selected tool\");\n assert_eq!(d.strokes.len(), 1);\n assert_eq!(d.strokes[0].tool, LiquifyTool::TwirlCcw);\n assert_eq!(LiquifyField::from_strokes(d.canvas, d.cell, &d.strokes), d.field);\n\n // A following stroke without Alt records the original tool.\n pointer(&mut app, ToolEvent::Down { x: 70.0, y: 40.0, pressure: 1.0 }, egui::Modifiers::NONE);\n assert_eq!(d.strokes.len(), 2);\n assert_eq!(d.strokes[1].tool, LiquifyTool::TwirlCw);\n assert_eq!(LiquifyField::from_strokes(d.canvas, d.cell, &d.strokes), d.field);\n\n control(&mut app, &json!({\"undo\": true})).unwrap();\n let d = app.distort.liquify.as_ref().unwrap();\n assert_eq!(d.strokes.len(), 1);\n assert_eq!(d.strokes[0].tool, LiquifyTool::TwirlCcw);\n assert_eq!(d.redo[0].tool, LiquifyTool::TwirlCw);\n assert_eq!(LiquifyField::from_strokes(d.canvas, d.cell, &d.strokes), d.field);\n\n control(&mut app, &json!({\"redo\": true})).unwrap();\n let d = app.distort.liquify.as_ref().unwrap();\n assert_eq!(d.strokes.len(), 2);\n assert!(d.redo.is_empty());\n assert_eq!(d.strokes[0].tool, LiquifyTool::TwirlCcw);\n assert_eq!(d.strokes[1].tool, LiquifyTool::TwirlCw);\n assert_eq!(LiquifyField::from_strokes(d.canvas, d.cell, &d.strokes), d.field);\n }"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/47aea89e9220b996f0d5a0d2bb8b5938100b4ad1/crates/ui-egui/src/liquify_ui.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
},
|
|
{
|
|
"id": "PR-9606",
|
|
"pr": 9606,
|
|
"subsystem": "UI and workflow",
|
|
"fixture_setup": "Use the exact synthetic/temporary fixtures constructed by the listed changed regressions; source links and setup excerpts are retained below.",
|
|
"action": [
|
|
"cargo test -p photocraft-ui-egui --locked color_panel_options_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_outside_preference_change_reaches_the_live_panel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_splitter_resizes_and_survives_a_ui_state_round_trip -- --nocapture"
|
|
],
|
|
"expected": "color panel options survive a restart; an outside preference change reaches the live panel; dragging the splitter resizes and survives a ui state round trip",
|
|
"status": "NOT RUN",
|
|
"actual": "",
|
|
"evidence": "",
|
|
"tester": "",
|
|
"test_commands": [
|
|
"cargo test -p photocraft-ui-egui --locked color_panel_options_survive_a_restart -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked an_outside_preference_change_reaches_the_live_panel -- --nocapture",
|
|
"cargo test -p photocraft-ui-egui --locked dragging_the_splitter_resizes_and_survives_a_ui_state_round_trip -- --nocapture"
|
|
],
|
|
"source_regressions": [
|
|
{
|
|
"name": "color_panel_options_survive_a_restart",
|
|
"path": "crates/ui-egui/src/color_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked color_panel_options_survive_a_restart -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut first = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n first.ui.color_panel.mode = ColorPanelMode::HsbSliders;\n first.ui.color_panel.ramp = ColorRamp::GrayscaleRamp;\n crate::color_panel_ui::persist(&mut first);\n let saved = first.session.prefs().clone();\n\n let mut next = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n next.session.prefs.edit(|p| *p = saved);\n crate::color_panel_ui::restore(&mut next);\n assert_eq!((next.ui.color_panel.mode, next.ui.color_panel.ramp), (ColorPanelMode::HsbSliders, ColorRamp::GrayscaleRamp));\n\n let mut fresh = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());",
|
|
"expected_assertions": [
|
|
" assert_eq!((next.ui.color_panel.mode, next.ui.color_panel.ramp), (ColorPanelMode::HsbSliders, ColorRamp::GrayscaleRamp));\n\n let mut fresh = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n crate::color_panel_ui::restore(&mut fresh);\n assert_eq!(fresh.ui.color_panel.mode, ColorPanelMode::HueCube, \"no saved options: the default\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/6cc516a3d20120b678040050d95ccadc8d1dfd3f/crates/ui-egui/src/color_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "an_outside_preference_change_reaches_the_live_panel",
|
|
"path": "crates/ui-egui/src/color_panel_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked an_outside_preference_change_reaches_the_live_panel -- --nocapture",
|
|
"fixture_and_action_excerpt": " let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());\n app.ui.color_panel.mode = ColorPanelMode::HsbSliders;\n crate::color_panel_ui::persist(&mut app);\n // As prefs.set or a reset to defaults would: the stored options change under the panel.\n let mut other = app.ui.color_panel;\n other.mode = ColorPanelMode::GrayscaleSlider;\n app.session.prefs.edit(|p| p.color_panel = serde_json::to_value(other).unwrap());\n crate::color_panel_ui::persist(&mut app);\n assert_eq!(app.ui.color_panel.mode, ColorPanelMode::GrayscaleSlider, \"the live panel follows the preference\");\n let stored: crate::state::ColorPanelState = serde_json::from_value(app.session.prefs().color_panel.clone()).unwrap();\n assert_eq!(stored.mode, ColorPanelMode::GrayscaleSlider, \"and the preference isn't overwritten\");\n // A reset to defaults clears the stored options: the panel goes back to its defaults too.",
|
|
"expected_assertions": [
|
|
" assert_eq!(app.ui.color_panel.mode, ColorPanelMode::GrayscaleSlider, \"the live panel follows the preference\");\n let stored: crate::state::ColorPanelState = serde_json::from_value(app.session.prefs().color_panel.clone()).unwrap();\n assert_eq!(stored.mode, ColorPanelMode::GrayscaleSlider, \"and the preference isn't overwritten\");\n // A reset to defaults clears the stored options: the panel goes back to its defaults too.\n app.session.prefs.edit(|p| p.color_panel = serde_json::Value::Null);\n crate::color_panel_ui::persist(&mut app);\n assert_eq!(app.ui.color_panel.mode, ColorPanelMode::HueCube, \"reset: the default mode\");\n crate::color_panel_ui::persist(&mut app);\n assert_eq!(app.ui.color_panel.mode, ColorPanelMode::HueCube, \"and it stays reset\");\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/6cc516a3d20120b678040050d95ccadc8d1dfd3f/crates/ui-egui/src/color_panel_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
},
|
|
{
|
|
"name": "dragging_the_splitter_resizes_and_survives_a_ui_state_round_trip",
|
|
"path": "crates/ui-egui/src/dock_tests.rs",
|
|
"package": "photocraft-ui-egui",
|
|
"command": "cargo test -p photocraft-ui-egui --locked dragging_the_splitter_resizes_and_survives_a_ui_state_round_trip -- --nocapture",
|
|
"fixture_and_action_excerpt": " let (mut app, _, _) = app_with_layers();\n // CodeRabbit on #9606: the Color panel's options ride the same frames and preferences.\n app.ui.color_panel.mode = crate::state::ColorPanelMode::HsbSliders;\n let mut h = harness(app, vec2(1200.0, 800.0), ThemeKind::ProMedium);\n let props = rect_of(&h, Group::Properties);\n let color = rect_of(&h, Group::Color);\n let split = probe::hit_rect(&h.ctx, &craft_ui::docking::Hit::Divider(craft_ui::docking::Divider::Group(\"properties\".into())))\n .expect(\"divider below Properties\")\n .center();\n // Less than Properties has above its minimum, so the groups above don't give way.\n drag(&mut h, split, split - vec2(0.0, 40.0));\n let props2 = rect_of(&h, Group::Properties);",
|
|
"expected_assertions": [
|
|
" assert!((props2.height() - (props.height() - 40.0)).abs() < 2.0, \"{props:?} -> {props2:?}\");\n assert_eq!(rect_of(&h, Group::Color), color, \"the group above keeps its place\");\n\n // Save and restore the UI state (what `ui.inspect` / `ui.set` and workspaces carry).\n let saved = serde_json::to_value(&h.state().ui).unwrap();\n assert_eq!(drawn(&h2).0, drawn(&h).0);\n\n // Remembered in the preferences once the mouse is up, and restored at the next launch.\n let prefs = h.state().session.prefs_to_json();\n assert!(app3.ui.docking.is_some());\n assert_eq!(app3.ui.docking.as_ref().map(|w| &w.layout), h.state().ui.docking.as_ref().map(|w| &w.layout));\n crate::color_panel_ui::restore(&mut app3);\n assert_eq!(app3.ui.color_panel.mode, crate::state::ColorPanelMode::HsbSliders, \"the Color panel's mode too\");\n // \u2026unless Remember Workspace Changes is off.\n let mut s3 = photocraft_engine::Session::new();\n s3.load_prefs_json(&prefs).unwrap();\n assert!(app4.ui.docking.is_none());\n assert_eq!(app4.ui.dock, DockLayout::default());\n}"
|
|
],
|
|
"reviewed_source": "https://github.com/storytold/photocraft/blob/6cc516a3d20120b678040050d95ccadc8d1dfd3f/crates/ui-egui/src/dock_tests.rs",
|
|
"ignored_requires_explicit_execution": false,
|
|
"excerpt_label": "Historical reviewed-source context; not a separate executable case or execution result"
|
|
}
|
|
],
|
|
"tested_sha": ""
|
|
}
|
|
],
|
|
"acceptance_build": {
|
|
"source_sha": "f5b3f1238bb414b43851ebe86f3a58ce83bb9b48",
|
|
"base_sha": "5f9b4391874aabc9deb2fcb905267613e4d93ec8",
|
|
"version": "0.17.0-integration.20261029.f5b3f123",
|
|
"architecture": "Windows x64",
|
|
"ci_run": 40858867520,
|
|
"ci_url": "https://github.com/FredApps/photocraft/actions/runs/40858867520",
|
|
"packaging_lint_run": 40858747395,
|
|
"build_run": 40867283787,
|
|
"build_url": "https://github.com/FredApps/photocraft/actions/runs/40867283787",
|
|
"workflow_id": 390299892,
|
|
"workflow_restored_state": "disabled_manually",
|
|
"fonts_pin": "b076417b5880bd4154bd22f00695b1d28c6bea83",
|
|
"artifact_verified": true,
|
|
"artifact": {
|
|
"id": 12895845995,
|
|
"name": "release-windows-x64",
|
|
"job_id": 123425396034,
|
|
"url": "https://github.com/FredApps/photocraft/actions/runs/40867283787/artifacts/12895845995",
|
|
"source_sha": "f5b3f1238bb414b43851ebe86f3a58ce83bb9b48",
|
|
"filename": "photocraft-0.17.0-integration.20261029.f5b3f123-windows-x64-portable.zip",
|
|
"sha256": "4125eccd5b009f30dc2d72f64bfafcf32220dc5574f765d0b3664ac4d9f992ba",
|
|
"size_bytes": 127391123,
|
|
"github_artifact_digest": "sha256:d642eb3969b9b3afbf3898c71d08a979b3bef01b51d26bae32e384ed8a28bf4f",
|
|
"expires_at": "2027-01-27T11:41:10Z",
|
|
"zip_crc": "PASSED",
|
|
"portable_marker": "PRESENT",
|
|
"pe_headers": {
|
|
"photocraft.exe": {
|
|
"signature": "PE",
|
|
"machine": "0x8664 (x64)",
|
|
"size": 149296640
|
|
},
|
|
"photocraft-cli.exe": {
|
|
"signature": "PE",
|
|
"machine": "0x8664 (x64)",
|
|
"size": 107922432
|
|
}
|
|
},
|
|
"manual_gui": "NOT RUN"
|
|
},
|
|
"manual_tests": "NOT RUN",
|
|
"packaging_platform_blocker": "macOS universal job could not start: GitHub reports recent account payments failed or spending limit needs increase. No billing/settings changes attempted. Windows jobs continue independently.",
|
|
"other_platform_failures": [
|
|
{
|
|
"platform": "macOS universal",
|
|
"job_id": 123425395799,
|
|
"reason": "GitHub runner did not start: account payment/spending restriction; no settings changed."
|
|
},
|
|
{
|
|
"platform": "FreeBSD aarch64",
|
|
"job_id": 123425395796,
|
|
"reason": "VM provisioning failed because pkg could not find cmake in configured repositories; no PhotoCraft build executed."
|
|
}
|
|
],
|
|
"build_run_status": "in_progress",
|
|
"build_run_conclusion": null,
|
|
"windows_job_conclusion": "success",
|
|
"signing": "UNSIGNED: fork has no Windows signing secrets; no credentials/settings changed",
|
|
"packaging_cli_version_check": {
|
|
"status": "PASSED in GitHub packaging job",
|
|
"output": "photocraft-cli 0.17.0-integration.20261029.f5b3f123 (f5b3f1238, 2026-10-29)"
|
|
}
|
|
}
|
|
}
|