AEP import: doc comments on the quick-win test helpers and tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
vangel76andClaude Opus 5.5 committed 2026-11-05 19:28:55 +01:00
1 parent d10991eff3
commit 495221aac6
3 files changed
+24

No files matched your search

+2
View File
@@ -133,6 +133,8 @@ struct ParamOut<'a> {
col: &'a mut Collector,
}
/// Imports one parameter of `fx` into its EffectCraft property: its keyframes, the value in its
/// record or the `pard` default, with a loss for what cannot be read or mapped.
fn import_param(fx: &AepEffect<'_, '_>, map: &EffectMap, p: &EffectParam<'_, '_>, cx: &LayerCtx<'_>, shown: &str, out: ParamOut<'_>) {
let ParamOut { group, refs, col } = out;
if carries_nothing(p) {
@@ -10,6 +10,7 @@ use effectcraft_keyframe::Value;
const ECHO_OPS: &[&str] = &["Add", "Maximum", "Minimum", "Screen", "Composite In Back", "Composite In Front", "Blend"];
/// Echo with the definitions After Effects 2026 wrote and the stored `values`.
fn echo(values: Vec<(usize, f64)>) -> Fx {
Fx {
match_name: "ADBE Echo",
@@ -26,6 +27,7 @@ fn echo(values: Vec<(usize, f64)>) -> Fx {
}
}
/// HDR Highlight Compression's Amount, set and default.
#[test]
fn hdr_highlight_compression_amount() {
let fx = |values| Fx {
@@ -43,6 +45,7 @@ fn hdr_highlight_compression_amount() {
}
}
/// Echo's values and operator, set and default.
#[test]
fn echo_values_and_operator() {
// `echo-01-set-all` (without its Decay 20, below) and `echo-09-pop5-6`.
@@ -61,6 +64,7 @@ fn echo_values_and_operator() {
assert_eq!((num(&g, "numberOfEchoes"), v(&g, "echoOperator")), (1.0, Value::Enum(0)));
}
/// Echo values beyond EffectCraft's ranges are imported as stored and reported.
#[test]
fn echo_values_beyond_effectcrafts_range_are_reported() {
// `echo-03-max`: 30 000 echoes and Decay 100; EffectCraft's Echo uses at most 255 and 1.
@@ -75,6 +79,7 @@ fn echo_values_beyond_effectcrafts_range_are_reported() {
near(&g, "decay", 100.0);
}
/// Linear Wipe's values, set and default.
#[test]
fn linear_wipe_values() {
let fx = |values| Fx {
@@ -99,6 +104,7 @@ fn linear_wipe_values() {
near(&run(&fx(vec![]), "ec.transition.linearwipe").0.expect("imported"), "angle", 90.0);
}
/// Offset's Blend With Original as a percentage and its centre as a point.
#[test]
fn offset_blend_is_a_fraction_and_the_centre_a_point() {
let fx = |values| Fx {
@@ -118,6 +124,7 @@ fn offset_blend_is_a_fraction_and_the_centre_a_point() {
near(&run(&fx(vec![(2, 0.25)]), "ec.distort.offset").0.expect("imported"), "blend", 25.0);
}
/// Color Stabilizer's points, Sample Size and Stabilize, default and set.
#[test]
fn color_stabilizer_points_sample_size_and_stabilize() {
let fx = |values| Fx {
+15
View File
@@ -37,6 +37,7 @@ pub enum Default {
Color([u8; 4]),
}
/// The parameter type code `pard` byte 15 holds for `k`.
fn kind_code(k: ParamKind) -> u8 {
match k {
ParamKind::Layer => 0,
@@ -57,10 +58,12 @@ fn kind_code(k: ParamKind) -> u8 {
}
}
/// `v` as a big-endian 16.16 fixed-point value.
fn fixed(v: f64) -> [u8; 4] {
((v * 65536.0).round() as i32).to_be_bytes()
}
/// The 148-byte parameter definition (`pard`) of `d`: type, name, default and range.
pub fn pard(d: &Def) -> Chunk<'static> {
let mut b = vec![0u8; 148];
b[15] = kind_code(d.kind);
@@ -99,6 +102,7 @@ pub fn tdmn(name: &str) -> Chunk<'static> {
Chunk::data(*b"tdmn", b)
}
/// A UTF-8 string chunk (`Utf8`).
fn utf8(s: &str) -> Chunk<'static> {
Chunk::data(*b"Utf8", s.as_bytes().to_vec())
}
@@ -137,10 +141,13 @@ pub struct Fx {
pub data: Vec<(usize, Vec<u8>)>,
}
/// The match name of parameter `i` of `fx` (`<match>-NNNN`).
fn param_name(fx: &Fx, i: usize) -> String {
format!("{}-{i:04}", fx.match_name)
}
/// The effect's `sspc`: its name, the parameter definitions (`parT`) and the stored values
/// (`tdgp`), each value record copied from `template`.
fn sspc(fx: &Fx, template: &Chunk<'_>) -> Chunk<'static> {
let n = fx.defs.len() + 2;
let mut part = vec![
@@ -194,6 +201,7 @@ fn find_glow_template(chunks: &[Chunk<'_>]) -> Option<Chunk<'static>> {
None
}
/// Replaces every Glow (`ADBE Glo2` with its `sspc`) below `chunks` with `fx`; the number replaced.
fn replace_glow(chunks: &mut [Chunk<'_>], fx: &Fx, template: &Chunk<'_>) -> usize {
let mut n = 0;
for ch in chunks {
@@ -239,10 +247,12 @@ pub fn losses(r: &ImportResult, category: LossCategory, match_name: &str) -> Vec
r.report.losses.iter().filter(|l| l.category == category).flat_map(|l| l.details.clone()).filter(|d| d.contains(&tag)).collect()
}
/// The value of property `id` of `g` (panics when it is missing).
pub fn v(g: &PropGroup, id: &str) -> Value {
g.prop(id).unwrap_or_else(|| panic!("no {id} in {}", g.match_id)).value.clone()
}
/// The scalar value of property `id` of `g`.
pub fn num(g: &PropGroup, id: &str) -> f64 {
match v(g, id) {
Value::Scalar(x) => x,
@@ -250,11 +260,13 @@ pub fn num(g: &PropGroup, id: &str) -> f64 {
}
}
/// Asserts that property `id` of `g` is `want` (relative 1e-6).
pub fn near(g: &PropGroup, id: &str, want: f64) {
let got = num(g, id);
assert!((got - want).abs() <= want.abs().max(1.0) * 1e-6, "{} {id}: {got} != {want}", g.match_id);
}
/// Asserts that the point property `id` of `g` is `want` (within 0.01).
pub fn pt(g: &PropGroup, id: &str, want: [f64; 2]) {
let Value::Vec2(a) = v(g, id) else { panic!("{id}") };
assert!((a[0] - want[0]).abs() < 1e-2 && (a[1] - want[1]).abs() < 1e-2, "{} {id}: {a:?} != {want:?}", g.match_id);
@@ -265,14 +277,17 @@ pub fn slider(kind: ParamKind, name: &'static str, default: f64, valid: (f64, f6
Def { kind, name, default: Default::Number(default), valid, items: &[] }
}
/// A popup definition: default item (1-based) and items.
pub fn popup(name: &'static str, default: u32, items: &'static [&'static str]) -> Def {
Def { kind: ParamKind::Popup, name, default: Default::Index(default), valid: (0.0, 0.0), items }
}
/// A definition of another kind (angle, point, colour, ...) with `default`.
pub fn other(kind: ParamKind, name: &'static str, default: Default) -> Def {
Def { kind, name, default, valid: (0.0, 0.0), items: &[] }
}
/// The definitions written here read back as the reader decodes After Effects' `pard`.
#[test]
fn pard_layout_decodes_as_written() {
// Echo's Decay (float, valid 0..100, default 1), Linear Wipe's Feather (fixed, valid max