From 18066ee0dd58f3b897efc5d71ef01adba8a2e650 Mon Sep 17 00:00:00 2001 From: vickydotbat Date: Thu, 14 May 2026 08:34:50 +0200 Subject: [PATCH] Lock normalization --- internal/topdata/native.go | 5 +-- internal/topdata/topdata_test.go | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/internal/topdata/native.go b/internal/topdata/native.go index 8a6131e..e55504c 100644 --- a/internal/topdata/native.go +++ b/internal/topdata/native.go @@ -748,10 +748,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) { lockData[key] = rowID lockModified = true } - } else if lockedID, ok := lockData[key]; ok { - row["id"] = lockedID - rowID = lockedID - } else { + } else if _, ok := lockData[key]; !ok { lockData[key] = rowID lockModified = true lockAdded++ diff --git a/internal/topdata/topdata_test.go b/internal/topdata/topdata_test.go index bcccfc7..9bc5b97 100644 --- a/internal/topdata/topdata_test.go +++ b/internal/topdata/topdata_test.go @@ -8336,6 +8336,63 @@ func TestBuildSkillsKeyNullRemovesIdentityWithoutNullingRow(t *testing.T) { } } +func TestBuildSkillsIgnoresStaleBaseSpanLockDuringInitialLoad(t *testing.T) { + root := testProjectRoot(t) + mkdirAll(t, filepath.Join(root, "topdata", "data", "skills", "modules")) + writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n") + writeFile(t, filepath.Join(root, "topdata", "data", "skills", "base.json"), `{ + "output": "skills.2da", + "columns": ["Label", "Name", "Description", "Icon", "Untrained", "KeyAbility", "ArmorCheckPenalty", "AllClassesCanUse", "Category", "MaxCR", "Constant", "HostileSkill", "HideFromLevelUp"], + "rows": [ + {"id": 18, "key": "skills:taunt", "Label": "Taunt", "Name": "342", "Description": "366", "Icon": "isk_taunt", "Untrained": "1", "KeyAbility": "CHA", "ArmorCheckPenalty": "0", "AllClassesCanUse": "1", "Category": "****", "MaxCR": "1", "Constant": "SKILL_TAUNT", "HostileSkill": "1", "HideFromLevelUp": "0"}, + {"id": 24, "key": "skills:intimidate", "Label": "Intimidate", "Name": "8756", "Description": "8786", "Icon": "isk_X2Inti", "Untrained": "1", "KeyAbility": "CHA", "ArmorCheckPenalty": "0", "AllClassesCanUse": "1", "Category": "****", "MaxCR": "****", "Constant": "SKILL_INTIMIDATE", "HostileSkill": "0", "HideFromLevelUp": "0"} + ] +}`+"\n") + writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{ + "skills:intimidate": 18, + "skills:taunt": 18 +}`+"\n") + writeFile(t, filepath.Join(root, "topdata", "data", "skills", "modules", "ovr_taunttointimidate.json"), `{ + "overrides": [ + { + "id": 18, + "key": "skills:intimidate", + "Label": "Intimidate", + "Constant": "SKILL_INTIMIDATE", + "HideFromLevelUp": "0" + } + ] +}`+"\n") + writeFile(t, filepath.Join(root, "topdata", "data", "skills", "modules", "rmv_removedskills.json"), `{ + "overrides": [ + { + "id": 24, + "key": null, + "Label": null, + "Constant": null, + "HideFromLevelUp": "1" + } + ] +}`+"\n") + mkdirAll(t, filepath.Join(root, "reference")) + writeFile(t, filepath.Join(root, "reference", "build.py"), "print('ok')\n") + + if _, err := buildNativeUnchecked(testProject(root), NativeBuildOptions{BuildWiki: false}, nil, nil); err != nil { + t.Fatalf("buildNativeUnchecked failed: %v", err) + } + lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "skills", "lock.json")) + if err != nil { + t.Fatalf("read skills lock: %v", err) + } + lockText := string(lockRaw) + if !strings.Contains(lockText, `"skills:intimidate": 18`) { + t.Fatalf("expected intimidate to remain locked to row 18, got:\n%s", lockText) + } + if strings.Contains(lockText, `"skills:taunt"`) { + t.Fatalf("expected stale taunt alias to be pruned, got:\n%s", lockText) + } +} + func TestBuildCanonicalSkillsMatchesReference(t *testing.T) { root := testProjectRoot(t) mkdirAll(t, filepath.Join(root, "topdata", "data"))