mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
M14.4: scripting tests for layer/comp settings, import + save, console snapshot; Project.saveAs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
78cd313d3c
commit
d880746fec
@@ -220,6 +220,35 @@ mod tests {
|
||||
assert!(bytes.starts_with(b"GIF89a"));
|
||||
}
|
||||
|
||||
/// importFile, layers.add(footage) and project save/open from a script.
|
||||
#[test]
|
||||
fn script_imports_footage_and_saves() {
|
||||
let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../target/test-out/host-script-import");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let q = |n: &str| serde_json::to_string(&dir.join(n).to_string_lossy()).unwrap();
|
||||
let mut s = super::session();
|
||||
let code = format!(
|
||||
r#"
|
||||
var c = app.project.items.addComp("Src", 32, 32, 1, 1, 10);
|
||||
c.layers.addSolid([0, 1, 0], "G", 32, 32, 1);
|
||||
app.run("comp.saveFrameAs", {{comp: c.id, path: {png}}});
|
||||
var still = app.project.importFile(new ImportOptions(new File({png})));
|
||||
var main = app.project.items.addComp("Main", 64, 64, 1, 1, 10);
|
||||
var l = main.layers.add(still);
|
||||
app.project.save(new File({proj}));
|
||||
[still instanceof FootageItem, still.width, still.mainSource.isStill, l.source.name, app.project.file.name]
|
||||
"#,
|
||||
png = q("frame.png"),
|
||||
proj = q("p.ecproj")
|
||||
);
|
||||
let r = s.execute("script.run", json!({"code": code})).unwrap();
|
||||
assert_eq!(r["ok"], json!(true), "{r}");
|
||||
assert_eq!(r["result"], json!([true, 32, true, "frame.png", "p.ecproj"]), "{r}");
|
||||
let r = s.execute("script.run", json!({"code": format!("app.open(new File({})); app.project.numItems", q("p.ecproj"))})).unwrap();
|
||||
assert_eq!(r["result"], json!(5), "{r}"); // Src, Solids, G, frame.png, Main
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expression_syntax_errors_disable_the_expression() {
|
||||
let mut s = super::session();
|
||||
|
||||
@@ -1571,6 +1571,7 @@ Project.prototype = {
|
||||
else __call("file.save", {});
|
||||
return true;
|
||||
},
|
||||
saveAs: function (file) { return this.save(file); },
|
||||
saveWithDialog: function () { if (this.file) return this.save(); return false; },
|
||||
close: function (opt) {
|
||||
if (opt === CloseOptions.SAVE_CHANGES && this.file) this.save();
|
||||
|
||||
@@ -390,3 +390,59 @@ fn schedule_task_runs_after_the_script() {
|
||||
);
|
||||
assert_eq!(o.output, vec!["now", "later"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layer_switches_timing_and_comp_settings() {
|
||||
let mut s = session();
|
||||
let o = ok(
|
||||
&mut s,
|
||||
r#"
|
||||
var c = app.project.items.addComp("S", 320, 240, 1, 5, 30);
|
||||
var matte = c.layers.addText("M");
|
||||
var fill = c.layers.addSolid([1, 1, 1], "Fill", 320, 240, 1);
|
||||
fill.moveToEnd();
|
||||
fill.setTrackMatte(matte, TrackMatteType.LUMA);
|
||||
var t1 = fill.trackMatteType == TrackMatteType.LUMA && fill.hasTrackMatte && fill.trackMatteLayer.name == "M";
|
||||
fill.stretch = 200;
|
||||
fill.label = 3;
|
||||
c.width = 400;
|
||||
c.duration = 8;
|
||||
c.bgColor = [0.1, 0.2, 0.3];
|
||||
c.time = 2;
|
||||
c.workAreaStart = 1;
|
||||
c.workAreaDuration = 3;
|
||||
var extra = c.layers.addNull();
|
||||
extra.remove();
|
||||
fill.selected = true;
|
||||
var sel = c.selectedLayers.length;
|
||||
fill.transform.opacity.expression = "thisLayer.nope(";
|
||||
var err = fill.transform.opacity.expressionError;
|
||||
fill.transform.opacity.expressionEnabled = false;
|
||||
var copy = c.duplicate();
|
||||
var f = app.project.items.addFolder("Bin");
|
||||
copy.parentFolder = f;
|
||||
[t1, fill.stretch, fill.label, c.width, c.duration, c.bgColor[2], c.time, c.workAreaStart, c.workAreaDuration,
|
||||
c.numLayers, sel, err.length > 0, fill.transform.opacity.expressionEnabled, copy.name, f.numItems, copy.parentFolder.name]
|
||||
"#,
|
||||
);
|
||||
let v = o.result;
|
||||
assert_eq!(v[0], json!(true), "{v}");
|
||||
assert_eq!(v[1], json!(200));
|
||||
assert_eq!(v[2], json!(3));
|
||||
assert_eq!(v[3], json!(400));
|
||||
assert_eq!(v[4], json!(8));
|
||||
assert!((v[5].as_f64().unwrap() - 0.3).abs() < 1e-6);
|
||||
assert_eq!(v[6], json!(2));
|
||||
assert_eq!(v[7], json!(1));
|
||||
assert_eq!(v[8], json!(3));
|
||||
assert_eq!(v[9], json!(2));
|
||||
assert_eq!(v[10], json!(1));
|
||||
assert_eq!(v[11], json!(true));
|
||||
assert_eq!(v[12], json!(false));
|
||||
assert_eq!(v[13], json!("S 2"));
|
||||
assert_eq!(v[14], json!(1));
|
||||
assert_eq!(v[15], json!("Bin"));
|
||||
// Removing the copy through the object model.
|
||||
let o = ok(&mut s, "var n = app.project.numItems; app.project.item(1).remove(); n - app.project.numItems");
|
||||
assert_eq!(o.result, json!(1));
|
||||
}
|
||||
|
||||
@@ -42,3 +42,27 @@ fn script_console_runs_scripts() {
|
||||
click(&mut h, "scriptConsole.clear");
|
||||
assert!(h.state().ui.script_console.log.is_empty());
|
||||
}
|
||||
|
||||
/// Headless look at the panel (wgpu offscreen); run with
|
||||
/// `SC_SNAPSHOT=/abs/out.png cargo test -p effectcraft-ui-egui --test ui_script_console -- --ignored`.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn script_console_snapshot() {
|
||||
let s = effectcraft_host::session();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_| EffectcraftApp::new(s));
|
||||
h.state_mut().show_panel(PanelKind::ScriptConsole);
|
||||
h.run_steps(2);
|
||||
for code in ["var c = app.project.items.addComp('Console', 320, 180, 1, 2, 24); writeLn('made ' + c.name); c.id", "c.layers.addText('Hi').name", "nope()"] {
|
||||
h.state_mut().ui.script_console.input = code.into();
|
||||
h.run_steps(1);
|
||||
click(&mut h, "scriptConsole.run");
|
||||
}
|
||||
h.state_mut().ui.script_console.input = "app.project.numItems".into();
|
||||
h.run_steps(3);
|
||||
let img = h.render().expect("render");
|
||||
let out = std::env::var("SC_SNAPSHOT").unwrap_or_else(|_| concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/test-out/script_console.png").into());
|
||||
if let Some(d) = std::path::Path::new(&out).parent() {
|
||||
std::fs::create_dir_all(d).unwrap();
|
||||
}
|
||||
img.save(&out).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user