Add comprehensive test coverage for Ableton automation, fader policies, and pad sound export logic

This commit is contained in:
2026-07-14 11:27:57 +02:00
parent 4cda706b69
commit d582adb3fc
3 changed files with 117 additions and 0 deletions

View File

@@ -86,3 +86,38 @@ test('uses absolute automation targets for Session clip envelopes', () => {
assert.equal(envelopes[0].Automation.Events.FloatEvent[2]['@Time'], 1);
assert.deepEqual(envelopes[0].LoopSlot, { Value: {} });
});
test('does not create Session envelopes without recorded parameter events', () => {
const withoutPan = {
...occurrence,
faderAutomation: occurrence.faderAutomation.filter(
(point) => point.parameter !== FaderParam.PAN,
),
};
const envelopes = buildClipEnvelopes(
withoutPan,
{ [FaderParam.PAN]: [{ session: 23000 }] },
track,
false,
);
assert.deepEqual(envelopes, []);
});
test('keeps research-only group parameters out of Live target envelopes', () => {
const researchOccurrence = {
...occurrence,
faderAutomation: [
{ parameter: FaderParam.TIM, position: 0, value: 0.25, flags: 0 },
{ parameter: FaderParam.ATK, position: 0, value: 0.5, flags: 0 },
{ parameter: FaderParam.REL, position: 0, value: 0.75, flags: 0 },
],
};
const targets = {
[FaderParam.TIM]: [{ session: 23000 }],
[FaderParam.ATK]: [{ session: 23001 }],
[FaderParam.REL]: [{ session: 23002 }],
};
assert.deepEqual(buildClipEnvelopes(researchOccurrence, targets, track, false), []);
});

View File

@@ -0,0 +1,35 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
FADER_POLICIES,
convertGroupFaderValue,
getFaderPolicy,
} from '../src/lib/exporters/ableton/faderPolicies';
import { AblTrack } from '../src/lib/transformers/ableton';
import { FaderParam } from '../src/types/types';
const track = { volume: 0.4 } as AblTrack;
test('defines an explicit policy for every EP group fader parameter', () => {
assert.equal(Object.keys(FADER_POLICIES).length, 12);
for (let parameter = FaderParam.LVL; parameter <= FaderParam.MOD; parameter++) {
assert.ok(getFaderPolicy(parameter));
}
});
test('separates Live targets, note transforms and unsupported group parameters', () => {
assert.equal(getFaderPolicy(FaderParam.PAN).renderStrategy, 'target');
assert.equal(getFaderPolicy(FaderParam.VEL).renderStrategy, 'note');
assert.equal(getFaderPolicy(FaderParam.TIM).renderStrategy, 'unsupported');
assert.equal(getFaderPolicy(FaderParam.ATK).renderStrategy, 'unsupported');
assert.equal(getFaderPolicy(FaderParam.REL).renderStrategy, 'unsupported');
});
test('uses one group-fader conversion path for mixer and pad targets', () => {
assert.equal(convertGroupFaderValue(FaderParam.LVL, 0.5, { track }), 0.2);
assert.equal(convertGroupFaderValue(FaderParam.PAN, 0.75, { track }), 0.5);
assert.equal(
convertGroupFaderValue(FaderParam.PTC, 0.75, { track, valueOffset: 7 }),
9.5,
);
});

View File

@@ -0,0 +1,47 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
getPadEnvelopeState,
getPadSoundState,
} from '../src/lib/exporters/ableton/padSound';
import { AblTrack } from '../src/lib/transformers/ableton';
const track = {
volume: 0.75,
pitch: -3,
playMode: 'key',
pan: 0.25,
trimLeft: 100,
trimRight: 1000,
attack: 64,
release: 128,
timeStretch: 'bars',
timeStretchBpm: 92,
timeStretchBars: 2,
rootNote: 48,
soundLength: 4,
} as AblTrack;
test('keeps static pad sound settings separate from group fader state', () => {
assert.deepEqual(getPadSoundState(track), {
amp: 0.75,
pitch: -3,
playMode: 'key',
pan: 0.25,
trimStart: 100,
trimEnd: 1000,
envelope: { attack: 64, release: 128 },
time: { mode: 'bars', bpm: 92, bars: 2 },
rootNote: 48,
soundLength: 4,
});
});
test('maps only pad ENV values into the static Classic envelope', () => {
const envelope = getPadEnvelopeState(getPadSoundState(track));
assert.equal(envelope.classicAttackMs, (64 / 255) * 4000);
assert.equal(envelope.classicReleaseMs, (128 / 255) * 4000);
assert.equal(envelope.oneShotFadeInMs, 0);
assert.equal(envelope.oneShotFadeOutMs, 5);
});