package validator import ( "os" "path/filepath" "testing" "gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project" ) func TestValidateProjectWarnsForCrossHAKDuplicateAssets(t *testing.T) { root := t.TempDir() mustMkdir(t, filepath.Join(root, "src")) mustMkdir(t, filepath.Join(root, "assets", "low")) mustMkdir(t, filepath.Join(root, "assets", "high")) mustMkdir(t, filepath.Join(root, "build")) mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{ "module": { "name": "Test Assets", "resref": "testassets" }, "paths": { "source": "src", "assets": "assets", "build": "build" }, "haks": [ { "name": "low", "priority": 1, "max_bytes": 0, "split": false, "include": ["low/**"] }, { "name": "high", "priority": 2, "max_bytes": 0, "split": false, "include": ["high/**"] } ] } `) mustWriteFile(t, filepath.Join(root, "assets", "low", "shared.mdl"), "low") mustWriteFile(t, filepath.Join(root, "assets", "high", "shared.mdl"), "high") p, err := project.Load(root) if err != nil { t.Fatalf("load project: %v", err) } if err := p.ValidateLayout(); err != nil { t.Fatalf("validate layout: %v", err) } if err := p.Scan(); err != nil { t.Fatalf("scan: %v", err) } report := ValidateProject(p) if report.HasErrors() { t.Fatalf("expected warnings only, got errors: %#v", report.Diagnostics) } if report.WarningCount() != 1 { t.Fatalf("expected 1 warning, got %d (%#v)", report.WarningCount(), report.Diagnostics) } } func TestValidateProjectErrorsForSameHAKDuplicateAssets(t *testing.T) { root := t.TempDir() mustMkdir(t, filepath.Join(root, "src")) mustMkdir(t, filepath.Join(root, "assets", "core", "a")) mustMkdir(t, filepath.Join(root, "assets", "core", "b")) mustMkdir(t, filepath.Join(root, "build")) mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{ "module": { "name": "Test Assets", "resref": "testassets" }, "paths": { "source": "src", "assets": "assets", "build": "build" }, "haks": [ { "name": "core", "priority": 1, "max_bytes": 0, "split": false, "include": ["core/**"] } ] } `) mustWriteFile(t, filepath.Join(root, "assets", "core", "a", "shared.mdl"), "one") mustWriteFile(t, filepath.Join(root, "assets", "core", "b", "shared.mdl"), "two") p, err := project.Load(root) if err != nil { t.Fatalf("load project: %v", err) } if err := p.ValidateLayout(); err != nil { t.Fatalf("validate layout: %v", err) } if err := p.Scan(); err != nil { t.Fatalf("scan: %v", err) } report := ValidateProject(p) if !report.HasErrors() { t.Fatalf("expected same-hak duplicate to be an error, got %#v", report.Diagnostics) } if report.ErrorCount() != 1 { t.Fatalf("expected 1 error, got %d (%#v)", report.ErrorCount(), report.Diagnostics) } if report.WarningCount() != 0 { t.Fatalf("expected no warnings, got %d (%#v)", report.WarningCount(), report.Diagnostics) } } func TestValidateProjectWarnsForUppercaseResourceNames(t *testing.T) { root := t.TempDir() mustMkdir(t, filepath.Join(root, "src", "blueprints", "items")) mustMkdir(t, filepath.Join(root, "assets", "vfx")) mustMkdir(t, filepath.Join(root, "build")) mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{ "module": { "name": "Test Module", "resref": "testmod" }, "paths": { "source": "src", "assets": "assets", "build": "build" } } `) mustWriteFile(t, filepath.Join(root, "src", "blueprints", "items", "I_ELVENCHAIN.uti.json"), `{ "file_type": "UTI ", "file_version": "V3.2", "root": {"struct_type": 0, "fields": []} } `) mustWriteFile(t, filepath.Join(root, "assets", "vfx", "SPELL_FIRE.tga"), "fire") p, err := project.Load(root) if err != nil { t.Fatalf("load project: %v", err) } if err := p.ValidateLayout(); err != nil { t.Fatalf("validate layout: %v", err) } if err := p.Scan(); err != nil { t.Fatalf("scan: %v", err) } report := ValidateProject(p) if report.WarningCount() < 2 { t.Fatalf("expected lowercase warnings, got %#v", report.Diagnostics) } } func TestValidateProjectWarnsForMissingScriptReferences(t *testing.T) { root := t.TempDir() mustMkdir(t, filepath.Join(root, "src", "dialogs")) mustMkdir(t, filepath.Join(root, "assets")) mustMkdir(t, filepath.Join(root, "build")) mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{ "module": { "name": "Test Module", "resref": "testmod" }, "paths": { "source": "src", "assets": "assets", "build": "build" } } `) mustWriteFile(t, filepath.Join(root, "src", "dialogs", "merchant.dlg.json"), `{ "file_type": "DLG ", "file_version": "V3.2", "root": { "struct_type": 0, "fields": [ { "label": "Script", "type": "ResRef", "value": "open_store" } ] } } `) p, err := project.Load(root) if err != nil { t.Fatalf("load project: %v", err) } if err := p.ValidateLayout(); err != nil { t.Fatalf("validate layout: %v", err) } if err := p.Scan(); err != nil { t.Fatalf("scan: %v", err) } report := ValidateProject(p) if report.HasErrors() { t.Fatalf("expected warnings only, got errors: %#v", report.Diagnostics) } if report.WarningCount() == 0 { t.Fatalf("expected missing-script warning, got %#v", report.Diagnostics) } } func mustMkdir(t *testing.T, path string) { t.Helper() if err := os.MkdirAll(path, 0o755); err != nil { t.Fatalf("mkdir %s: %v", path, err) } } func mustWriteFile(t *testing.T, path, data string) { t.Helper() if err := os.WriteFile(path, []byte(data), 0o644); err != nil { t.Fatalf("write %s: %v", path, err) } }