effectcraft/crates/engine/src/tests_fidelity.rs

84 lines
4.7 KiB
Rust

//! Render-fidelity commands: project colour settings, footage colour profile, slip edit.
use effectcraft_project::{BitDepth, ColorSpace};
use serde_json::json;
use crate::Session;
#[test]
fn project_colour_settings_are_undoable() {
let mut s = Session::default();
s.execute("file.projectSettings", json!({"bitDepth": 32, "workingSpace": "rec2020", "linearize": true, "blendLinear": true})).unwrap();
let st = &s.project.settings;
assert_eq!((st.bit_depth, st.working_space, st.linearize, st.blend_linear), (BitDepth::Bpc32, Some(ColorSpace::Rec2020), true, true));
s.execute("file.projectSettings", json!({"workingSpace": "Display P3"})).unwrap();
assert_eq!(s.project.settings.working_space, Some(ColorSpace::DisplayP3));
s.execute("file.projectSettings", json!({"workingSpace": "none"})).unwrap();
assert_eq!(s.project.settings.working_space, None);
assert!(s.execute("file.projectSettings", json!({"workingSpace": "acescg-ish"})).is_err());
assert!(s.undo());
assert_eq!(s.project.settings.working_space, Some(ColorSpace::DisplayP3));
assert!(s.undo() && s.undo());
assert_eq!(s.project.settings.bit_depth, BitDepth::Bpc8);
assert!(!s.project.settings.blend_linear);
// The Project panel's depth button cycles 8 → 16 → 32 → 8.
for want in ["16 bpc", "32 bpc", "8 bpc"] {
assert_eq!(s.execute("file.cycleBitDepth", json!({})).unwrap(), json!(want));
}
}
#[test]
fn footage_colour_profile_is_interpreted() {
let mut s = Session::default();
let id = s.execute("file.importPlaceholder", json!({"name": "clip", "width": 64, "height": 36, "frameRate": 24, "duration": 2})).unwrap();
let item = id["item"].as_u64().or_else(|| id.as_u64()).map(effectcraft_project::ItemId).unwrap_or_else(|| *s.project.items.keys().last().unwrap());
let profile = |s: &Session| match &s.project.item(item).unwrap().kind {
effectcraft_project::ItemKind::Footage(f) => f.color_profile,
_ => panic!("not footage"),
};
s.execute("file.interpretFootage", json!({"items": [item.0], "colorProfile": "rec2020"})).unwrap();
assert_eq!(profile(&s), Some(ColorSpace::Rec2020));
s.execute("file.interpretFootage", json!({"items": [item.0], "colorProfile": "auto"})).unwrap();
assert_eq!(profile(&s), None);
assert!(s.undo());
assert_eq!(profile(&s), Some(ColorSpace::Rec2020));
}
#[test]
fn slip_moves_the_source_under_fixed_in_and_out() {
use effectcraft_time::Tick;
let mut s = Session::default();
s.execute("comp.new", json!({"name": "Main", "width": 100, "height": 100, "frameRate": 30, "duration": 10})).unwrap();
let nested = s.execute("comp.new", json!({"name": "Nested", "duration": 4, "open": false})).unwrap()["comp"].as_u64().unwrap();
s.execute("layer.addItem", json!({"item": nested})).unwrap();
let id = s.active_comp().unwrap().layers[0].id.0;
// Trim to 1 s .. 3 s of a 4 s source.
s.execute("layer.timing", json!({"layers": [id], "in": 1.0, "out": 3.0})).unwrap();
let get = |s: &Session| s.active_comp().unwrap().layers[0].clone();
let before = get(&s);
assert_eq!((before.start_time, before.in_point.seconds(), before.out_point.seconds()), (Tick::ZERO, 1.0, 3.0));
// Slip the source 0.5 s later: in/out stay, the source (start) moves.
s.execute("layer.slip", json!({"layers": [id], "delta": 0.5})).unwrap();
let l = get(&s);
assert_eq!((l.start_time.seconds(), l.in_point, l.out_point), (0.5, before.in_point, before.out_point));
// The source time at comp 2 s is now 1.5 s.
assert_eq!(l.layer_time(Tick::from_seconds_f64(2.0)).seconds(), 1.5);
// Clamped so the source still covers in..out: at most start = in (1 s).
let r = s.execute("layer.slip", json!({"layers": [id], "delta": 5.0})).unwrap();
assert_eq!(get(&s).start_time.seconds(), 1.0);
assert_eq!(r["slipped"][0]["delta"], json!(0.5));
// Alt+PageUp / Alt+PageDown nudge by a frame.
s.execute("layer.slipBack", json!({"layers": [id]})).unwrap();
assert!((get(&s).start_time.seconds() - (1.0 - 1.0 / 30.0)).abs() < 1e-9);
s.execute("layer.slipForward", json!({"layers": [id]})).unwrap();
assert_eq!(get(&s).start_time.seconds(), 1.0);
// Undo walks back through the slips.
assert!(s.undo() && s.undo() && s.undo() && s.undo());
assert_eq!(get(&s).start_time, Tick::ZERO);
assert_eq!(crate::find_command("layer.slipBack").and_then(|c| c.shortcut), Some("Alt+PageUp"));
assert_eq!(crate::find_command("layer.slipForward").and_then(|c| c.shortcut), Some("Alt+PageDown"));
// Layers without a source duration can't slip.
s.execute("layer.newSolid", json!({"color": "#ff0000"})).unwrap();
assert!(s.execute("layer.slip", json!({"delta": 0.5})).is_err());
}