fix(banks): enforce unique bank display names in-model + B3 review minors

This commit is contained in:
2026-07-25 01:29:47 -04:00
parent cbfc13c4e0
commit ccf65415c9
6 changed files with 169 additions and 22 deletions
+53
View File
@@ -92,6 +92,8 @@ static void testCreateRenameReorder() {
CHECK(book.renameBank("b", "Beta-renamed"));
CHECK(book.bank("b")->displayName == "Beta-renamed");
CHECK(!book.renameBank("missing", "x"));
// Renaming back to a non-colliding name keeps working.
CHECK(book.renameBank("b", "Beta"));
// Reorder: move "c" to the front of the named region (ordinal 1).
CHECK(book.reorderBank("c", 1));
@@ -113,6 +115,56 @@ static void testCreateRenameReorder() {
CHECK(!book.reorderBank("missing", 1));
}
static void testDisplayNameUniqueness() {
BankBook book;
CHECK(book.createBank("a", "Drums"));
// A unique name is accepted.
CHECK(book.createBank("b", "Bass"));
// Exact duplicate rejected, no mutation (size unchanged, the collided id absent).
CHECK(!book.createBank("c", "Drums"));
CHECK(book.bank("c") == nullptr);
CHECK(book.size() == 3); // pool + a + b only
// Trimmed + case-insensitive collisions: "drums", " Drums ", "DRUMS" all collide.
CHECK(!book.createBank("c", "drums"));
CHECK(!book.createBank("c", " Drums "));
CHECK(!book.createBank("c", "DRUMS"));
CHECK(book.bank("c") == nullptr);
// The pool's reserved name "Pool" (and its variants) cannot be taken by a new bank.
CHECK(!book.createBank("c", "Pool"));
CHECK(!book.createBank("c", " pool "));
CHECK(book.bank("c") == nullptr);
// -- renameBank uniqueness --------------------------------------------------
// Rename to a name used by ANOTHER bank is rejected (no mutation).
CHECK(!book.renameBank("b", "Drums"));
CHECK(book.bank("b")->displayName == "Bass"); // unchanged
CHECK(!book.renameBank("b", "drums")); // case-insensitive collision too
CHECK(!book.renameBank("b", " Drums ")); // trimmed collision too
// Renaming a bank to its OWN current name is a no-op success (not a rejection).
CHECK(book.renameBank("a", "Drums"));
CHECK(book.bank("a")->displayName == "Drums");
// Re-casing/-spacing its own name is likewise allowed (it collides only with self).
CHECK(book.renameBank("a", " drums "));
CHECK(book.bank("a")->displayName == " drums ");
// Renaming to the pool's reserved name is rejected (pool is the "other" bank here).
CHECK(!book.renameBank("b", "Pool"));
CHECK(book.bank("b")->displayName == "Bass");
// A genuinely fresh unique name still renames fine.
CHECK(book.renameBank("b", "Low End"));
CHECK(book.bank("b")->displayName == "Low End");
// After the rejections, the previously-freed name is now reusable by a new bank.
CHECK(book.createBank("c", "Bass"));
CHECK(book.bank("c")->displayName == "Bass");
}
static void testMoveSourceLosesDestGains() {
BankBook book;
CHECK(book.createBank("drums", "Drums"));
@@ -473,6 +525,7 @@ int main() {
testPoolSeededAndDefaults();
testPoolPrivileges();
testCreateRenameReorder();
testDisplayNameUniqueness();
testMoveSourceLosesDestGains();
testCopySourceRetainedDestGains();
testMoveDestCollapse();