Files
sow-tools/internal/topdata/autogen_lock_identity_test.go
T
archvillainette 3315f8b7eb
test / test (push) Successful in 1m31s
build-binaries / build-binaries (push) Successful in 2m16s
build-image / publish (push) Successful in 57s
crucible build parity (#14)
forces build parity with crucible = local builds and CI/CD builds use different tools.

Reviewed-on: #14
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-21 13:17:58 +00:00

115 lines
4.5 KiB
Go

package topdata
import (
"testing"
"git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project"
)
func accConsumer() project.AutogenConsumerConfig {
return project.AutogenConsumerConfig{
ID: "accessory_visualeffects", Producer: "accessory_visualeffects",
Dataset: "visualeffects", Mode: "accessory_visualeffects", Optional: true,
AccessoryVisualeffects: project.AccessoryVisualeffectsConfig{
Groups: map[string]project.AccessoryVisualeffectGroupConfig{
"head_accessories": {ModelColumns: []string{"Imp_HeadCon_Node"}},
},
GroupTokenSource: "folder_name", CategoryFrom: "immediate_parent",
Delimiter: "/", Case: "preserve",
StripModelPrefixes: []string{"hfx_"},
KeyFormat: "{dataset}:{group}{delimiter}{category_segment}{stem}",
LabelFormat: "{group}{delimiter}{category_segment}{stem}",
ModelColumn: "Imp_HeadCon_Node",
},
}
}
func vfxEntry() autogenManifestEntry {
return autogenManifestEntry{
Source: "head_accessories/hat/hfx_bandana.mdl", Group: "head_accessories",
Subgroup: "hat", ModelStem: "hfx_bandana",
}
}
func vfxDataset(lock map[string]int) nativeCollectedDataset {
return nativeCollectedDataset{
Dataset: nativeDataset{Name: "visualeffects", Kind: nativeDatasetBase},
Columns: []string{"Label", "Imp_HeadCon_Node"},
Rows: nil,
LockData: lock,
}
}
func TestAccessoryLockKeyIsModelAnchored(t *testing.T) {
got := accessoryVisualeffectLockKey("visualeffects", vfxEntry())
want := "visualeffects:head_accessories/hat/hfx_bandana.mdl"
if got != want {
t.Fatalf("lock key = %q, want %q", got, want)
}
}
// A config-only change (here: a different key_format) must NOT move the ID,
// because identity is the model path, not the presentation key.
func TestConfigOnlyChangeKeepsLockID(t *testing.T) {
lockKey := "visualeffects:head_accessories/hat/hfx_bandana.mdl"
collected := []nativeCollectedDataset{vfxDataset(map[string]int{lockKey: 555})}
c := accConsumer()
c.AccessoryVisualeffects.KeyFormat = "{dataset}:{stem}" // config-only change
got, err := augmentWithAutogeneratedAccessoryVisualeffects(collected, []autogenManifestEntry{vfxEntry()}, c, nil)
if err != nil {
t.Fatalf("augment failed: %v", err)
}
if got[0].LockData[lockKey] != 555 {
t.Fatalf("expected ID preserved at 555, got %#v", got[0].LockData)
}
}
// A model re-export (same path) keeps its ID — content change != identity change.
func TestModelReExportKeepsLockID(t *testing.T) {
lockKey := "visualeffects:head_accessories/hat/hfx_bandana.mdl"
collected := []nativeCollectedDataset{vfxDataset(map[string]int{lockKey: 777})}
got, err := augmentWithAutogeneratedAccessoryVisualeffects(collected, []autogenManifestEntry{vfxEntry()}, accConsumer(), nil)
if err != nil {
t.Fatalf("augment failed: %v", err)
}
if got[0].LockData[lockKey] != 777 {
t.Fatalf("expected ID 777 preserved, got %#v", got[0].LockData)
}
}
// A removed model frees its old ID; the surviving model keeps its lock entry.
func TestModelRemovalPrunesStaleLockKey(t *testing.T) {
keep := "visualeffects:head_accessories/hat/hfx_bandana.mdl"
gone := "visualeffects:head_accessories/hat/hfx_removed.mdl"
collected := []nativeCollectedDataset{vfxDataset(map[string]int{keep: 1, gone: 2})}
got, err := augmentWithAutogeneratedAccessoryVisualeffects(collected, []autogenManifestEntry{vfxEntry()}, accConsumer(), nil)
if err != nil {
t.Fatalf("augment failed: %v", err)
}
if _, present := got[0].LockData[gone]; present {
t.Fatalf("expected removed model's lock key pruned, got %#v", got[0].LockData)
}
if got[0].LockData[keep] != 1 {
t.Fatalf("expected surviving model ID 1 kept, got %#v", got[0].LockData)
}
}
// Cutover: a lock that only has the OLD config-derived key adopts that ID under
// the new model-path key, with zero shift, and prunes the old key.
func TestCutoverRemapPreservesID(t *testing.T) {
oldKey := "visualeffects:head_accessories/hat/bandana" // {dataset}:{group}/{category}/{stem-without-hfx_}
newKey := "visualeffects:head_accessories/hat/hfx_bandana.mdl"
collected := []nativeCollectedDataset{vfxDataset(map[string]int{oldKey: 4242})}
got, err := augmentWithAutogeneratedAccessoryVisualeffects(collected, []autogenManifestEntry{vfxEntry()}, accConsumer(), nil)
if err != nil {
t.Fatalf("augment failed: %v", err)
}
if got[0].LockData[newKey] != 4242 {
t.Fatalf("expected cutover to carry ID 4242 to new key, got %#v", got[0].LockData)
}
if _, present := got[0].LockData[oldKey]; present {
t.Fatalf("expected old config key pruned after cutover, got %#v", got[0].LockData)
}
}