mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
69 lines
3.5 KiB
Rust
69 lines
3.5 KiB
Rust
//! Window ▸ Script Console: the panel shows, runs JavaScript through `script.run` (persistent
|
|
//! context) and logs output, results and errors (egui_kittest, UI logic only).
|
|
|
|
use effectcraft_ui_egui::EffectcraftApp;
|
|
use effectcraft_ui_egui::dock::PanelKind;
|
|
use egui_kittest::Harness;
|
|
|
|
fn click(h: &mut Harness<'_, EffectcraftApp>, id: &str) {
|
|
let e = h.state().auto.find(id).unwrap_or_else(|| panic!("no {id}")).clone();
|
|
let c = egui::pos2(e.rect[0] + e.rect[2] / 2.0, e.rect[1] + e.rect[3] / 2.0);
|
|
h.input_mut().events.push(egui::Event::PointerMoved(c));
|
|
for pressed in [true, false] {
|
|
h.input_mut().events.push(egui::Event::PointerButton { pos: c, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() });
|
|
}
|
|
h.run_steps(2);
|
|
}
|
|
|
|
#[test]
|
|
fn script_console_runs_scripts() {
|
|
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(3);
|
|
for id in ["scriptConsole.input", "scriptConsole.output", "scriptConsole.run", "scriptConsole.clear"] {
|
|
assert!(h.state().auto.find(id).is_some(), "missing {id}");
|
|
}
|
|
h.state_mut().ui.script_console.input = "var c = app.project.items.addComp('Console', 320, 180, 1, 2, 24); writeLn('made'); c.name".into();
|
|
h.run_steps(1);
|
|
click(&mut h, "scriptConsole.run");
|
|
assert!(h.state().session.project.items.values().any(|i| i.name == "Console"));
|
|
// Variables persist between runs; errors are logged with their line.
|
|
h.state_mut().ui.script_console.input = "c.numLayers + 5".into();
|
|
click(&mut h, "scriptConsole.run");
|
|
h.state_mut().ui.script_console.input = "nope()".into();
|
|
click(&mut h, "scriptConsole.run");
|
|
let log: Vec<(String, String)> = h.state().ui.script_console.log.iter().map(|l| (l.kind.clone(), l.text.clone())).collect();
|
|
assert!(log.contains(&("output".into(), "made".into())), "{log:?}");
|
|
assert!(log.contains(&("result".into(), "\"Console\"".into())), "{log:?}");
|
|
assert!(log.contains(&("result".into(), "5".into())), "{log:?}");
|
|
assert!(log.iter().any(|(k, t)| k == "error" && t.contains("line 1") && t.contains("nope")), "{log:?}");
|
|
assert!(h.state_mut().session.undo(), "console edits are undoable");
|
|
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();
|
|
}
|