Q-W1 code-review follow-ups: restore 104 trailing newlines, relocate reasampler_uid.h to core/wire, drop ext_keys namespaces shim, add slot_map_tests, golden serialize literals for 4 modules, namespaces.h/pragma-once ordering sweep. 60/60 green.
This commit is contained in:
+33
-129
@@ -42,6 +42,29 @@ static Sample sampleWith(const std::string& seed) { return sampleWith(seed, "has
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Golden byte-literal (Q-W1 follow-up): pins the EXACT serialized bytes for a
|
||||
// small fixture (a freshly-seeded book: pool only, one sample), not just
|
||||
// self-consistent re-serialization — a format drift that both writer and
|
||||
// reader agree on would slip past the round-trip tests but not this. The
|
||||
// format is frozen as-shipped; the literal below is the captured current
|
||||
// output.
|
||||
static void testSerializeGoldenLiteral() {
|
||||
BankBook book;
|
||||
CHECK(book.pool().index.add(sampleWith("g1")) == AddResult::Added);
|
||||
CHECK(book.serialize() ==
|
||||
"{\"version\":1,\"activeBank\":\"pool\",\"banks\":[{\"id\":\"pool\","
|
||||
"\"displayName\":\"Pool\",\"ordinal\":0,\"index\":{\"version\":1,"
|
||||
"\"samples\":[{\"id\":\"id-g1\",\"displayName\":\"sample g1\","
|
||||
"\"relativePath\":\"bank/g1.wav\",\"sourceMode\":0,\"sourceRange\":{"
|
||||
"\"startSeconds\":0,\"endSeconds\":0,\"startPpq\":0,\"endPpq\":0},"
|
||||
"\"trackGuids\":[],\"wetDry\":1,\"channelCount\":2,\"sampleRate\":48000,"
|
||||
"\"lengthSeconds\":0,\"lengthBeats\":0,\"captureTempo\":0,"
|
||||
"\"captureTimeSigNum\":0,\"captureTimeSigDenom\":0,\"key\":null,"
|
||||
"\"rootNote\":null,\"loop\":null,\"levels\":{\"peakDb\":0,\"rmsDb\":0,"
|
||||
"\"lufs\":0},\"clipped\":false,\"tier\":0,\"contentHash\":\"hash-g1\","
|
||||
"\"provenance\":null,\"createdTimestamp\":1753080000}]},\"slots\":[]}]}");
|
||||
}
|
||||
|
||||
static void testPoolSeededAndDefaults() {
|
||||
BankBook book;
|
||||
// Pool present as bank-zero with fixed id + name + ordinal 0.
|
||||
@@ -790,123 +813,13 @@ static void testUpdateSampleInPlace() {
|
||||
// ===========================================================================
|
||||
// L7 — SlotMap (gap-preserving display positions) + BankBook ordering/reorder/replace
|
||||
// ===========================================================================
|
||||
|
||||
// --- SlotMap unit behaviour --------------------------------------------------
|
||||
|
||||
static void testSlotMapDenseAppend() {
|
||||
SlotMap m;
|
||||
m.append("a");
|
||||
m.append("b");
|
||||
m.append("c");
|
||||
CHECK(m.slotOf("a") == 0);
|
||||
CHECK(m.slotOf("b") == 1);
|
||||
CHECK(m.slotOf("c") == 2);
|
||||
CHECK(m.maxSlot() == 2);
|
||||
CHECK((m.orderedIds() == std::vector<std::string>{"a", "b", "c"}));
|
||||
CHECK(m.idAt(1) == "b");
|
||||
CHECK(m.slotOf("nope") == -1);
|
||||
}
|
||||
|
||||
static void testSlotMapRemoveLeavesGap() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); // 0,1,2
|
||||
CHECK(m.remove("b")); // slot 1 now EMPTY (no re-pack)
|
||||
CHECK(m.slotOf("a") == 0);
|
||||
CHECK(m.slotOf("c") == 2); // c did NOT shift down
|
||||
CHECK(m.idAt(1).empty()); // gap preserved
|
||||
CHECK((m.orderedIds() == std::vector<std::string>{"a", "c"}));
|
||||
CHECK(!m.remove("b")); // already gone
|
||||
}
|
||||
|
||||
static void testSlotMapAppendAfterGapGoesToFrontier() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); // 0,1,2
|
||||
m.remove("a"); // slot 0 empty
|
||||
m.append("d"); // append goes AFTER last occupied (2) -> 3
|
||||
CHECK(m.slotOf("d") == 3); // did NOT fill the slot-0 gap
|
||||
CHECK(m.idAt(0).empty());
|
||||
}
|
||||
|
||||
static void testSlotMapReorderIntoEmpty() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); // 0,1,2
|
||||
m.remove("b"); // slot 1 empty
|
||||
CHECK(m.reorder("c", 1)); // c -> empty slot 1; its slot 2 empties
|
||||
CHECK(m.slotOf("c") == 1);
|
||||
CHECK(m.idAt(2).empty());
|
||||
CHECK(m.slotOf("a") == 0); // untouched
|
||||
}
|
||||
|
||||
static void testSlotMapReorderOntoOccupiedInsertsAndShifts() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); m.append("d"); // 0,1,2,3
|
||||
CHECK(m.reorder("d", 1)); // d onto occupied slot 1 -> insert-before, shift b,c up
|
||||
CHECK(m.slotOf("a") == 0); // before the target: unchanged
|
||||
CHECK(m.slotOf("d") == 1); // took the target slot
|
||||
CHECK(m.slotOf("b") == 2); // shifted +1
|
||||
CHECK(m.slotOf("c") == 3); // shifted +1
|
||||
CHECK((m.orderedIds() == std::vector<std::string>{"a", "d", "b", "c"}));
|
||||
}
|
||||
|
||||
static void testSlotMapReorderPreservesInteriorGapAboveTarget() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); // 0,1,2
|
||||
m.remove("b"); // gap at 1: a@0, c@2
|
||||
m.append("d"); // d@3
|
||||
CHECK(m.reorder("d", 0)); // d onto occupied slot 0 -> a shifts to 1, c shifts to 3
|
||||
CHECK(m.slotOf("d") == 0);
|
||||
CHECK(m.slotOf("a") == 1); // shifted from 0 -> 1
|
||||
CHECK(m.slotOf("c") == 3); // shifted from 2 -> 3 (gap at 2 preserved as a +1 of its own)
|
||||
CHECK(m.idAt(2).empty()); // interior gap above the target survives
|
||||
}
|
||||
|
||||
static void testSlotMapReorderUnmappedIsNoOp() {
|
||||
SlotMap m;
|
||||
m.append("a");
|
||||
CHECK(!m.reorder("ghost", 0)); // not mapped -> false, no mutation
|
||||
CHECK(m.slotOf("a") == 0);
|
||||
}
|
||||
|
||||
static void testSlotMapNegativeTargetClampsToZero() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); // 0,1
|
||||
CHECK(m.reorder("b", -3)); // clamp to 0 -> insert-before a
|
||||
CHECK(m.slotOf("b") == 0);
|
||||
CHECK(m.slotOf("a") == 1);
|
||||
}
|
||||
|
||||
static void testSlotMapResetDenseSkipsDupesAndEmpties() {
|
||||
SlotMap m;
|
||||
m.resetDense({"a", "", "b", "a", "c"}); // "" and the second "a" dropped
|
||||
CHECK((m.orderedIds() == std::vector<std::string>{"a", "b", "c"}));
|
||||
CHECK(m.slotOf("a") == 0);
|
||||
CHECK(m.slotOf("c") == 2);
|
||||
}
|
||||
|
||||
static void testSlotMapReconcileDropsStaleAppendsNew() {
|
||||
SlotMap m;
|
||||
m.append("a"); m.append("b"); m.append("c"); // 0,1,2
|
||||
m.reconcile({"a", "c", "d"}); // b left the index (drop), d is new (append)
|
||||
CHECK(m.slotOf("a") == 0); // kept at its slot
|
||||
CHECK(m.slotOf("c") == 2); // kept at its slot (gap where b was)
|
||||
CHECK(m.slotOf("b") == -1); // stale marker dropped
|
||||
CHECK(m.slotOf("d") == 3); // appended after the frontier
|
||||
CHECK(m.idAt(1).empty()); // b's slot stays empty
|
||||
}
|
||||
|
||||
static void testSlotMapEqualityAndFromEntries() {
|
||||
SlotMap a;
|
||||
a.append("x"); a.append("y");
|
||||
SlotMap b = SlotMap::fromEntries({{"x", 0}, {"y", 1}});
|
||||
CHECK(a == b);
|
||||
// Defensive repair: duplicate id (first wins), slot conflict (later dropped),
|
||||
// empty id / negative slot dropped.
|
||||
SlotMap c = SlotMap::fromEntries({{"x", 0}, {"x", 5}, {"y", 0}, {"", 9}, {"z", -1}, {"w", 2}});
|
||||
CHECK(c.slotOf("x") == 0); // first x wins
|
||||
CHECK(c.slotOf("y") == -1); // slot 0 already taken -> dropped
|
||||
CHECK(c.slotOf("w") == 2); // valid
|
||||
CHECK(c.slotOf("z") == -1); // negative slot dropped
|
||||
}
|
||||
//
|
||||
// Pure SlotMap-only unit behaviour (add/remove/query, reorder gap-preservation,
|
||||
// resetDense/reconcile, equality/fromEntries, serialize golden literal + round
|
||||
// trip) now lives in test_slot_map.cpp (Q-W1 follow-up), extracted per the house
|
||||
// every-pure-module-has-a-_tests rule. This file keeps the BankBook-level
|
||||
// integration coverage below: reorderSample / reconcileSlots / JSON round-trip
|
||||
// WITH a full book.
|
||||
|
||||
// --- BankBook L7: JSON round-trip WITH positions -----------------------------
|
||||
|
||||
@@ -1081,6 +994,7 @@ static void testReplaceSampleInPoolPassesGuard() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
testSerializeGoldenLiteral();
|
||||
testPoolSeededAndDefaults();
|
||||
testPoolPrivileges();
|
||||
testCreateRenameReorder();
|
||||
@@ -1117,18 +1031,8 @@ int main() {
|
||||
testRemoveAllBanksLatentScope();
|
||||
testUpdateSampleInPlace();
|
||||
|
||||
// L7 — SlotMap + ordering/reorder/replace + slot round-trip/migration.
|
||||
testSlotMapDenseAppend();
|
||||
testSlotMapRemoveLeavesGap();
|
||||
testSlotMapAppendAfterGapGoesToFrontier();
|
||||
testSlotMapReorderIntoEmpty();
|
||||
testSlotMapReorderOntoOccupiedInsertsAndShifts();
|
||||
testSlotMapReorderPreservesInteriorGapAboveTarget();
|
||||
testSlotMapReorderUnmappedIsNoOp();
|
||||
testSlotMapNegativeTargetClampsToZero();
|
||||
testSlotMapResetDenseSkipsDupesAndEmpties();
|
||||
testSlotMapReconcileDropsStaleAppendsNew();
|
||||
testSlotMapEqualityAndFromEntries();
|
||||
// L7 — BankBook ordering/reorder/replace + slot round-trip/migration.
|
||||
// (Pure SlotMap-only unit behaviour lives in slot_map_tests.)
|
||||
testBankBookSlotsRoundTrip();
|
||||
testMigrationDefaultsToInsertionOrderDense();
|
||||
testOrderedSampleIdsReconcilesLazily();
|
||||
|
||||
Reference in New Issue
Block a user