Unit test
This commit is contained in:
@@ -8897,6 +8897,148 @@ func TestBuildBaseitemsAllowsKeyOnlyOverrideBeforeSameKeyIsRelocatedAndReadded(t
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildNativeKeepsGeneratedIDsStableAcrossRepeatedBuilds(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
writeFeatGeneratedHarness(t, root, map[string]string{
|
||||
"skill_focus.json": `{
|
||||
"family": "skill_focus",
|
||||
"family_key": "skill_focus",
|
||||
"template": "masterfeats:skillfocus",
|
||||
"name_prefix": "Skill Focus",
|
||||
"label_prefix": "FEAT_SKILL_FOCUS",
|
||||
"constant_prefix": "FEAT_SKILL_FOCUS",
|
||||
"default_fields": {
|
||||
"CRValue": "0.5",
|
||||
"ReqSkillMinRanks": "1",
|
||||
"ALLCLASSESCANUSE": "1",
|
||||
"TOOLSCATEGORIES": "6",
|
||||
"PreReqEpic": "0",
|
||||
"ReqAction": "1"
|
||||
},
|
||||
"apply_after_modules": true,
|
||||
"child_ref_field": "REQSKILL",
|
||||
"child_source": {
|
||||
"dataset": "skills",
|
||||
"predicate": "accessible"
|
||||
}
|
||||
}` + "\n",
|
||||
}, map[string]int{
|
||||
"feat:skill_focus_intimidate": 1333,
|
||||
})
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "baseitems", "modules", "10_vanillaoverrides"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "baseitems", "base.json"), `{
|
||||
"output": "baseitems.2da",
|
||||
"columns": ["label", "MaxRange"],
|
||||
"rows": [
|
||||
{"id": 58, "key": "baseitems:shortspear", "label": "shortspear", "MaxRange": "100"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "baseitems", "lock.json"), `{
|
||||
"baseitems:shortspear": 126
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "baseitems", "modules", "10_vanillaoverrides", "ovr_baseitems_spear.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"id": 58,
|
||||
"key": "baseitems:spear",
|
||||
"label": "spear"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "baseitems", "modules", "add_baseitems_shortspear.json"), `{
|
||||
"entries": {
|
||||
"baseitems:shortspear": {
|
||||
"label": "shortspear",
|
||||
"MaxRange": "255"
|
||||
}
|
||||
}
|
||||
}`+"\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:intimidate", "Label": "Intimidate", "Name": "8756", "Description": "8786", "Icon": "isk_x2inti", "Untrained": "1", "KeyAbility": "CHA", "ArmorCheckPenalty": "0", "AllClassesCanUse": "1", "Category": "****", "MaxCR": "****", "Constant": "SKILL_INTIMIDATE", "HostileSkill": "1", "HideFromLevelUp": "0"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{
|
||||
"skills:intimidate": 18
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "base.json"), `{
|
||||
"output": "feat.2da",
|
||||
"compare_reference": false,
|
||||
"columns": [
|
||||
"LABEL","FEAT","DESCRIPTION","ICON","MINATTACKBONUS","MINSTR","MINDEX","MININT","MINWIS","MINCON","MINCHA",
|
||||
"MINSPELLLVL","PREREQFEAT1","PREREQFEAT2","GAINMULTIPLE","EFFECTSSTACK","ALLCLASSESCANUSE","CATEGORY","MAXCR",
|
||||
"SPELLID","SUCCESSOR","CRValue","USESPERDAY","MASTERFEAT","TARGETSELF","OrReqFeat0","OrReqFeat1","OrReqFeat2",
|
||||
"OrReqFeat3","OrReqFeat4","REQSKILL","ReqSkillMinRanks","REQSKILL2","ReqSkillMinRanks2","Constant","TOOLSCATEGORIES",
|
||||
"HostileFeat","MinLevel","MinLevelClass","MaxLevel","MinFortSave","PreReqEpic","ReqAction"
|
||||
],
|
||||
"rows": [
|
||||
{"id": 39, "key": "feat:stunning_fist", "LABEL": "FEAT_STUNNING_FIST", "MASTERFEAT": "****", "Constant": "FEAT_STUNNING_FIST"},
|
||||
{"id": 916, "key": "feat:skill_focus_intimidate", "LABEL": "FEAT_SKILL_FOCUS_INTIMIDATE", "REQSKILL": 24, "MASTERFEAT": 4, "Constant": "FEAT_SKILL_FOCUS_INTIMIDATE"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "lock.json"), `{
|
||||
"feat:skill_focus_intimidate": 1333,
|
||||
"feat:stunning_fist": 1116
|
||||
}`+"\n")
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "feat", "modules", "00_removed"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "modules", "00_removed", "rmv_feat_intimidate.json"), `{
|
||||
"overrides": [
|
||||
{"id": 916, "null": true, "key": null}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "modules", "00_removed", "rmv_feat_stunningfist.json"), `{
|
||||
"overrides": [
|
||||
{"id": 39, "null": true, "key": null}
|
||||
]
|
||||
}`+"\n")
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "feat", "modules", "activecombat"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "modules", "activecombat", "add_feat_stunning_fist.json"), `{
|
||||
"entries": {
|
||||
"feat:stunning_fist": {
|
||||
"LABEL": "FEAT_STUNNING_FIST",
|
||||
"Constant": "FEAT_STUNNING_FIST"
|
||||
}
|
||||
}
|
||||
}`+"\n")
|
||||
mkdirAll(t, filepath.Join(root, "reference"))
|
||||
writeFile(t, filepath.Join(root, "reference", "build.py"), "print('ok')\n")
|
||||
|
||||
expectedBaseitems := map[string]int{
|
||||
"baseitems:spear": 58,
|
||||
"baseitems:shortspear": 126,
|
||||
}
|
||||
expectedFeat := map[string]int{
|
||||
"feat:skill_focus_intimidate": 1333,
|
||||
"feat:stunning_fist": 1116,
|
||||
}
|
||||
for run := 1; run <= 10; run++ {
|
||||
if _, err := BuildNative(testProject(root), nil); err != nil {
|
||||
t.Fatalf("BuildNative run %d failed: %v", run, err)
|
||||
}
|
||||
assertLockIDs(t, run, filepath.Join(root, "topdata", "data", "baseitems", "lock.json"), expectedBaseitems)
|
||||
assertLockIDs(t, run, filepath.Join(root, "topdata", "data", "feat", "lock.json"), expectedFeat)
|
||||
}
|
||||
}
|
||||
|
||||
func assertLockIDs(t *testing.T, run int, path string, expected map[string]int) {
|
||||
t.Helper()
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("run %d: read lockfile %s: %v", run, path, err)
|
||||
}
|
||||
lockData := map[string]int{}
|
||||
if err := json.Unmarshal(raw, &lockData); err != nil {
|
||||
t.Fatalf("run %d: parse lockfile %s: %v\n%s", run, path, err, string(raw))
|
||||
}
|
||||
for key, want := range expected {
|
||||
if got := lockData[key]; got != want {
|
||||
t.Fatalf("run %d: expected %s to stay locked to id %d, got %d in %s:\n%s", run, key, want, got, path, string(raw))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildSkillsIgnoresStaleBaseSpanLockDuringInitialLoad(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "skills", "modules"))
|
||||
|
||||
Reference in New Issue
Block a user