mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-01 22:20:00 -06:00
* Dev profile: line tables only for workspace crates, no debug info for dependencies * xtask ci: dev-profile gate, nextest, tests without examples, wasm --keep-going * One integration-test binary per crate * xtask ci: run effectcraft-gpu's shared-device tests in one cargo test process * xtask ci: run every stage and report all failures * xtask ci: name the stage type (clippy type_complexity) * xtask ci: run every test pass and report all failures * cargo fmt
86 lines
3.9 KiB
Rust
86 lines
3.9 KiB
Rust
//! Composition Settings: saving, picking and deleting your own presets (egui_kittest).
|
|
|
|
use effectcraft_engine::Session;
|
|
use effectcraft_ui_egui::{Dialog, EffectcraftApp};
|
|
use egui::{Event, Key, Modifiers, PointerButton, Pos2, pos2};
|
|
use egui_kittest::Harness;
|
|
use serde_json::json;
|
|
|
|
fn harness() -> Harness<'static, EffectcraftApp> {
|
|
let mut s = Session::default();
|
|
s.execute("comp.new", json!({"name": "Edit", "width": 2560, "height": 1440, "frameRate": 60, "duration": 4})).unwrap();
|
|
let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).with_step_dt(1.0 / 60.0).build_eframe(|_| EffectcraftApp::new(s));
|
|
h.run_steps(3);
|
|
h
|
|
}
|
|
|
|
fn center(h: &Harness<'_, EffectcraftApp>, id: &str) -> Pos2 {
|
|
let e = h.state().auto.find(id).unwrap_or_else(|| panic!("no {id}"));
|
|
pos2(e.rect[0] + e.rect[2] / 2.0, e.rect[1] + e.rect[3] / 2.0)
|
|
}
|
|
|
|
fn click(h: &mut Harness<'_, EffectcraftApp>, id: &str) {
|
|
let p = center(h, id);
|
|
h.input_mut().events.push(Event::PointerMoved(p));
|
|
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
|
|
h.run_steps(1);
|
|
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });
|
|
// The automation registry still holds the previous frame's elements: one more frame.
|
|
h.run_steps(3);
|
|
}
|
|
|
|
fn key(h: &mut Harness<'_, EffectcraftApp>, key: Key) {
|
|
h.input_mut().events.push(Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });
|
|
h.input_mut().events.push(Event::Key { key, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::NONE });
|
|
h.run_steps(3);
|
|
}
|
|
|
|
fn open_settings(h: &mut Harness<'_, EffectcraftApp>) {
|
|
let ctx = h.ctx.clone();
|
|
effectcraft_ui_egui::menus::invoke(h.state_mut(), &ctx, "comp.settings", json!({})).unwrap();
|
|
h.run_steps(3);
|
|
assert_eq!(h.state().dialog, Some(Dialog::CompSettings));
|
|
}
|
|
|
|
fn preset_names(h: &Harness<'_, EffectcraftApp>) -> Vec<String> {
|
|
h.state().session.prefs.comp_presets.iter().map(|q| q.name.clone()).collect()
|
|
}
|
|
|
|
/// Save the comp's size and rate as a preset (Enter saves without pressing OK), then delete it.
|
|
#[test]
|
|
fn composition_settings_save_and_delete_your_own_preset() {
|
|
let mut h = harness();
|
|
open_settings(&mut h);
|
|
assert!(h.state().auto.find("dialog.comp.presetDelete").is_none(), "nothing of yours to delete yet");
|
|
click(&mut h, "dialog.comp.presetSave");
|
|
// Choose Name opens with the keyboard in its field.
|
|
h.input_mut().events.push(Event::Text("1440p 60".into()));
|
|
h.run_steps(2);
|
|
key(&mut h, Key::Enter);
|
|
assert_eq!(preset_names(&h), ["1440p 60"]);
|
|
let q = &h.state().session.prefs.comp_presets[0];
|
|
assert_eq!((q.width, q.height, q.pixel_aspect, q.frame_rate), (2560, 1440, 1.0, 60.0));
|
|
assert_eq!(h.state().dialog, Some(Dialog::CompSettings), "Enter in the name field doesn't press OK");
|
|
assert!(h.state().auto.find("dialog.comp.presetName").is_none(), "the name row closes");
|
|
// The comp's values are now that preset, so it can be deleted.
|
|
click(&mut h, "dialog.comp.presetDelete");
|
|
assert!(preset_names(&h).is_empty());
|
|
assert!(h.state().auto.find("dialog.comp.presetDelete").is_none());
|
|
}
|
|
|
|
/// A built-in preset's name can't be taken; Cancel closes the name row without saving.
|
|
#[test]
|
|
fn a_preset_name_cannot_be_a_built_in_one() {
|
|
let mut h = harness();
|
|
open_settings(&mut h);
|
|
click(&mut h, "dialog.comp.presetSave");
|
|
click(&mut h, "dialog.comp.presetName");
|
|
h.input_mut().events.push(Event::Text("HDTV 1080 24".into()));
|
|
h.run_steps(2);
|
|
click(&mut h, "dialog.comp.presetNameSave");
|
|
assert!(preset_names(&h).is_empty(), "the built-in name is refused");
|
|
click(&mut h, "dialog.comp.presetNameCancel");
|
|
assert!(h.state().auto.find("dialog.comp.presetName").is_none());
|
|
assert!(preset_names(&h).is_empty());
|
|
}
|