Fix lockfile generation, Key authoring hardening, and generic table injection
This commit is contained in:
@@ -5975,6 +5975,372 @@ func TestResolveOverrideTargetPrefersIDOverKey(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrunesLockedIDThatTargetsManualBaseSpace(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "base.json"), `{
|
||||
"output": "dense.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": [
|
||||
{"id": 0, "Label": "****", "Value": "****"},
|
||||
{"id": 1, "key": "dense:base", "Label": "Base", "Value": "base"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "lock.json"), `{
|
||||
"dense:new": 0,
|
||||
"dense:base": 1
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "entries.json"), `{
|
||||
"entries": {
|
||||
"dense:new": {
|
||||
"Label": "New",
|
||||
"Value": "new"
|
||||
}
|
||||
}
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "dense.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read dense.2da: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "0\t****\t****\n") {
|
||||
t.Fatalf("expected manual null row 0 to be preserved, got:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "2\tNew\tnew\n") {
|
||||
t.Fatalf("expected generated entry to be regenerated after base boundary, got:\n%s", text)
|
||||
}
|
||||
lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "dense", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read lock: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(lockRaw), `"dense:new": 2`) {
|
||||
t.Fatalf("expected invalid low lock id to be regenerated at row 2, got:\n%s", string(lockRaw))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrunesBaseKeyAfterOverrideRenamesRow(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "base.json"), `{
|
||||
"output": "dense.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": [
|
||||
{"id": 0, "key": "dense:old", "Label": "Old", "Value": "old"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "lock.json"), `{
|
||||
"dense:old": 0
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "rename.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"id": 0,
|
||||
"key": "dense:new",
|
||||
"Label": "New",
|
||||
"Value": "new"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "dense.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read dense.2da: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(got), "0\tNew\tnew\n") {
|
||||
t.Fatalf("expected renamed row override to win, got:\n%s", string(got))
|
||||
}
|
||||
lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "dense", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read lock: %v", err)
|
||||
}
|
||||
lockText := string(lockRaw)
|
||||
if strings.Contains(lockText, `"dense:old"`) {
|
||||
t.Fatalf("expected old base key to be pruned after row rename, got:\n%s", lockText)
|
||||
}
|
||||
if !strings.Contains(lockText, `"dense:new": 0`) {
|
||||
t.Fatalf("expected new override key to be locked to row 0, got:\n%s", lockText)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDuplicateBaseKeyUsesSurvivingRowAfterOverrideRename(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "base.json"), `{
|
||||
"output": "dense.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": [
|
||||
{"id": 3, "key": "dense:duplicate", "Label": "Renamed", "Value": "renamed"},
|
||||
{"id": 7, "key": "dense:duplicate", "Label": "Survivor", "Value": "survivor"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "lock.json"), `{
|
||||
"dense:duplicate": 3
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "rename.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"id": 3,
|
||||
"key": "dense:renamed",
|
||||
"Label": "Renamed",
|
||||
"Value": "renamed"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "dense.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read dense.2da: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "3\tRenamed\trenamed\n") || !strings.Contains(text, "7\tSurvivor\tsurvivor\n") {
|
||||
t.Fatalf("expected renamed and surviving duplicate-key rows to keep distinct ids, got:\n%s", text)
|
||||
}
|
||||
lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "dense", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read lock: %v", err)
|
||||
}
|
||||
lockText := string(lockRaw)
|
||||
if !strings.Contains(lockText, `"dense:renamed": 3`) {
|
||||
t.Fatalf("expected renamed key to keep original row id, got:\n%s", lockText)
|
||||
}
|
||||
if !strings.Contains(lockText, `"dense:duplicate": 7`) {
|
||||
t.Fatalf("expected surviving duplicate key to lock to surviving row id, got:\n%s", lockText)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDuplicateBaseKeyUsesEarlierSurvivingRowAfterOverrideRename(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "base.json"), `{
|
||||
"output": "dense.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": [
|
||||
{"id": 3, "key": "dense:duplicate", "Label": "Survivor", "Value": "survivor"},
|
||||
{"id": 7, "key": "dense:duplicate", "Label": "Renamed", "Value": "renamed"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "lock.json"), `{
|
||||
"dense:duplicate": 7
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "rename.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"id": 7,
|
||||
"key": "dense:renamed",
|
||||
"Label": "Renamed",
|
||||
"Value": "renamed"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "dense.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read dense.2da: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "3\tSurvivor\tsurvivor\n") || !strings.Contains(text, "7\tRenamed\trenamed\n") {
|
||||
t.Fatalf("expected surviving and renamed duplicate-key rows to keep distinct ids, got:\n%s", text)
|
||||
}
|
||||
lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "dense", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read lock: %v", err)
|
||||
}
|
||||
lockText := string(lockRaw)
|
||||
if !strings.Contains(lockText, `"dense:renamed": 7`) {
|
||||
t.Fatalf("expected renamed key to keep original row id, got:\n%s", lockText)
|
||||
}
|
||||
if !strings.Contains(lockText, `"dense:duplicate": 3`) {
|
||||
t.Fatalf("expected surviving duplicate key to lock to surviving row id, got:\n%s", lockText)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildAutoAllocatedRowsReserveExplicitModuleIDs(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "base.json"), `{
|
||||
"output": "dense.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": [
|
||||
{"id": 0, "key": "dense:base", "Label": "Base", "Value": "base"},
|
||||
{"id": 1, "Label": "****", "Value": "****"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "lock.json"), `{
|
||||
"dense:base": 0
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "a_entries.json"), `{
|
||||
"entries": {
|
||||
"dense:auto": {
|
||||
"Label": "Auto",
|
||||
"Value": "auto"
|
||||
}
|
||||
}
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "dense", "modules", "z_explicit.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"key": "dense:explicit",
|
||||
"id": 2,
|
||||
"Label": "Explicit",
|
||||
"Value": "explicit"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "dense.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read dense.2da: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "2\tExplicit\texplicit\n") {
|
||||
t.Fatalf("expected explicit module id 2 to be preserved, got:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "3\tAuto\tauto\n") {
|
||||
t.Fatalf("expected auto entry to skip explicit module id 2, got:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildGeneratedApplyAfterPrunesLowLockedID(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "feat", "generated"))
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "feat", "modules"))
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "masterfeats"))
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "skills"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "masterfeats", "base.json"), `{
|
||||
"output": "masterfeats.2da",
|
||||
"columns": ["Label", "STRREF", "DESCRIPTION"],
|
||||
"rows": [
|
||||
{"id": 10, "key": "masterfeats:skillfocus", "Label": "SkillFocus", "STRREF": "100", "DESCRIPTION": "1000"},
|
||||
{"id": 11, "key": "masterfeats:greaterskillfocus", "Label": "GreaterSkillFocus", "STRREF": "101", "DESCRIPTION": "1001"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "masterfeats", "lock.json"), `{
|
||||
"masterfeats:skillfocus": 10,
|
||||
"masterfeats:greaterskillfocus": 11
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "base.json"), `{
|
||||
"output": "skills.2da",
|
||||
"columns": ["Label", "HideFromLevelUp"],
|
||||
"rows": [
|
||||
{"id": 0, "key": "skills:profession_herbalist", "Label": "Profession Herbalist", "HideFromLevelUp": "0"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{
|
||||
"skills:profession_herbalist": 0
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "base.json"), `{
|
||||
"output": "feat.2da",
|
||||
"columns": ["Label", "FEAT", "MASTERFEAT", "REQSKILL", "Constant"],
|
||||
"rows": [
|
||||
{"id": 0, "Label": "****", "FEAT": "****", "MASTERFEAT": "****", "REQSKILL": "****", "Constant": "****"},
|
||||
{"id": 10, "key": "feat:skillfocus", "Label": "SkillFocus", "FEAT": "100", "MASTERFEAT": "10", "REQSKILL": "****", "Constant": "FEAT_SKILL_FOCUS"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "lock.json"), `{
|
||||
"feat:skillfocus": 10,
|
||||
"feat:skillfocus_professionherbalist": 0,
|
||||
"feat:greaterskillfocus_professionherbalist": 0
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "modules", "removed.json"), `{
|
||||
"overrides": [
|
||||
{
|
||||
"key": null,
|
||||
"id": 0,
|
||||
"Label": "****",
|
||||
"FEAT": "****",
|
||||
"MASTERFEAT": "****",
|
||||
"REQSKILL": "****",
|
||||
"Constant": "****"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "generated", "greater_skill_focus.json"), `{
|
||||
"family": "greater_skill_focus",
|
||||
"family_key": "greaterskillfocus",
|
||||
"template": "masterfeats:greaterskillfocus",
|
||||
"apply_after_modules": true,
|
||||
"child_ref_field": "REQSKILL",
|
||||
"child_source": {
|
||||
"dataset": "skills",
|
||||
"predicate": "accessible"
|
||||
},
|
||||
"label_prefix": "GREATER_SKILL_FOCUS",
|
||||
"name_prefix": "Greater Skill Focus",
|
||||
"constant_prefix": "FEAT_GREATER_SKILL_FOCUS"
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "feat", "generated", "skill_focus.json"), `{
|
||||
"family": "skill_focus",
|
||||
"family_key": "skillfocus",
|
||||
"template": "masterfeats:skillfocus",
|
||||
"apply_after_modules": true,
|
||||
"child_ref_field": "REQSKILL",
|
||||
"child_source": {
|
||||
"dataset": "skills",
|
||||
"predicate": "accessible"
|
||||
},
|
||||
"label_prefix": "SKILL_FOCUS",
|
||||
"name_prefix": "Skill Focus",
|
||||
"constant_prefix": "FEAT_SKILL_FOCUS",
|
||||
"template_fields": ["FEAT", "MASTERFEAT"]
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(filepath.Join(result.Output2DADir, "feat.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read feat.2da: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "0\t****\t****\t****\t****\t****\n") {
|
||||
t.Fatalf("expected manual null row 0 to be preserved, got:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "11\tGREATER_SKILL_FOCUS_PROFESSION_HERBALIST\t16777216\t11\t0\tFEAT_GREATER_SKILL_FOCUS_PROFESSION_HERBALIST\n") {
|
||||
t.Fatalf("expected greater skill focus to regenerate after base boundary, got:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "12\tSKILL_FOCUS_PROFESSION_HERBALIST\t****\t****\t0\tFEAT_SKILL_FOCUS_PROFESSION_HERBALIST\n") {
|
||||
t.Fatalf("expected skill focus to regenerate after base boundary, got:\n%s", text)
|
||||
}
|
||||
lockRaw, err := os.ReadFile(filepath.Join(root, "topdata", "data", "feat", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read lock: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(lockRaw), `"feat:skillfocus_profession_herbalist": 12`) {
|
||||
t.Fatalf("expected generated skill focus lock id to be regenerated at row 12, got:\n%s", string(lockRaw))
|
||||
}
|
||||
if !strings.Contains(string(lockRaw), `"feat:greaterskillfocus_profession_herbalist": 11`) {
|
||||
t.Fatalf("expected generated greater skill focus lock id to be regenerated at row 11, got:\n%s", string(lockRaw))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildCanonicalBaseitemsMatchesReference(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data"))
|
||||
@@ -6179,6 +6545,7 @@ func TestBuildInjectsExpansionDataIntoTargetDataset(t *testing.T) {
|
||||
"value": "po_cclaw_",
|
||||
"data": {
|
||||
"portraits": {
|
||||
"key": "portraits:cclaw_",
|
||||
"BaseResRef": "cclaw_",
|
||||
"Sex": 4,
|
||||
"Race": 10,
|
||||
@@ -6257,6 +6624,7 @@ func TestBuildExpansionDataDoesNotDuplicatePortraitRows(t *testing.T) {
|
||||
"value": "po_zk_",
|
||||
"data": {
|
||||
"portraits": {
|
||||
"key": "portraits:zk_",
|
||||
"BaseResRef": "zk_",
|
||||
"Sex": 4,
|
||||
"Race": 23,
|
||||
@@ -6271,6 +6639,7 @@ func TestBuildExpansionDataDoesNotDuplicatePortraitRows(t *testing.T) {
|
||||
"value": "po_zk_",
|
||||
"data": {
|
||||
"portraits": {
|
||||
"key": "portraits:zk_",
|
||||
"BaseResRef": "zk_",
|
||||
"Sex": 4,
|
||||
"Race": 23,
|
||||
@@ -6307,6 +6676,124 @@ func TestBuildExpansionDataDoesNotDuplicatePortraitRows(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildExpansionDataIsGlobalAndPrunesStaleInjectedLocks(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "source", "modules"))
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "target"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "source", "base.json"), `{
|
||||
"output": "source.2da",
|
||||
"columns": ["Label", "Link"],
|
||||
"rows": []
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "source", "lock.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "target", "base.json"), `{
|
||||
"output": "target.2da",
|
||||
"columns": ["Label", "Value"],
|
||||
"rows": []
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "target", "lock.json"), "{}\n")
|
||||
|
||||
modulePath := filepath.Join(root, "topdata", "data", "source", "modules", "inject.json")
|
||||
writeFile(t, modulePath, `{
|
||||
"entries": {
|
||||
"source:one": {
|
||||
"Label": "One",
|
||||
"Link": {
|
||||
"value": "target-one",
|
||||
"data": {
|
||||
"target": {
|
||||
"key": "target:one",
|
||||
"Label": "Target One",
|
||||
"Value": "one"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`+"\n")
|
||||
|
||||
result, err := BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
targetBytes, err := os.ReadFile(filepath.Join(result.Output2DADir, "target.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read target.2da: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(targetBytes), "0\t\"Target One\"\tone\n") {
|
||||
t.Fatalf("expected injected target row, got:\n%s", string(targetBytes))
|
||||
}
|
||||
lockBytes, err := os.ReadFile(filepath.Join(root, "topdata", "data", "target", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read target lock.json: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(lockBytes), `"target:one": 0`) {
|
||||
t.Fatalf("expected lock entry for injected target row, got:\n%s", string(lockBytes))
|
||||
}
|
||||
|
||||
writeFile(t, modulePath, `{
|
||||
"entries": {
|
||||
"source:one": {
|
||||
"Label": "One",
|
||||
"Link": {
|
||||
"value": "target-two",
|
||||
"data": {
|
||||
"target": {
|
||||
"key": "target:two",
|
||||
"Label": "Target Two",
|
||||
"Value": "two"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`+"\n")
|
||||
result, err = BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative after alteration failed: %v", err)
|
||||
}
|
||||
targetBytes, err = os.ReadFile(filepath.Join(result.Output2DADir, "target.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read altered target.2da: %v", err)
|
||||
}
|
||||
targetText := string(targetBytes)
|
||||
if strings.Contains(targetText, "Target One") || !strings.Contains(targetText, "0\t\"Target Two\"\ttwo\n") {
|
||||
t.Fatalf("expected altered injected target row only, got:\n%s", targetText)
|
||||
}
|
||||
lockBytes, err = os.ReadFile(filepath.Join(root, "topdata", "data", "target", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read altered target lock.json: %v", err)
|
||||
}
|
||||
lockText := string(lockBytes)
|
||||
if strings.Contains(lockText, "target:one") || !strings.Contains(lockText, `"target:two": 0`) {
|
||||
t.Fatalf("expected stale injected lock to be pruned after alteration, got:\n%s", lockText)
|
||||
}
|
||||
|
||||
if err := os.Remove(modulePath); err != nil {
|
||||
t.Fatalf("remove injection module: %v", err)
|
||||
}
|
||||
result, err = BuildNative(testProject(root), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative after deletion failed: %v", err)
|
||||
}
|
||||
targetBytes, err = os.ReadFile(filepath.Join(result.Output2DADir, "target.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read deleted target.2da: %v", err)
|
||||
}
|
||||
if strings.Contains(string(targetBytes), "Target Two") {
|
||||
t.Fatalf("expected injected target row to be removed after module deletion, got:\n%s", string(targetBytes))
|
||||
}
|
||||
lockBytes, err = os.ReadFile(filepath.Join(root, "topdata", "data", "target", "lock.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read deleted target lock.json: %v", err)
|
||||
}
|
||||
if strings.Contains(string(lockBytes), "target:two") {
|
||||
t.Fatalf("expected injected target lock to be pruned after module deletion, got:\n%s", string(lockBytes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateProjectRejectsUnknownMetadataKey(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "placeables"))
|
||||
|
||||
Reference in New Issue
Block a user