YAML Configuration Refactor
This commit is contained in:
@@ -9,6 +9,156 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadYAMLConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFile), `
|
||||
module:
|
||||
name: Test Module
|
||||
resref: testmod
|
||||
paths:
|
||||
source: src
|
||||
assets: assets
|
||||
build: output
|
||||
haks:
|
||||
- name: core
|
||||
priority: 1
|
||||
max_bytes: 1024
|
||||
split: false
|
||||
include:
|
||||
- core/**
|
||||
`)
|
||||
|
||||
proj, err := Load(root)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if proj.ConfigSource.Name != ConfigFile || proj.ConfigSource.Format != "yaml" || proj.ConfigSource.Legacy {
|
||||
t.Fatalf("unexpected config source: %#v", proj.ConfigSource)
|
||||
}
|
||||
if got, want := proj.Config.Module.Name, "Test Module"; got != want {
|
||||
t.Fatalf("expected module name %q, got %q", want, got)
|
||||
}
|
||||
if got, want := proj.BuildDir(), filepath.Join(root, "output"); got != want {
|
||||
t.Fatalf("expected build dir %s, got %s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadYMLConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFileYML), `
|
||||
module:
|
||||
name: Test Module
|
||||
resref: testmod
|
||||
paths:
|
||||
source: src
|
||||
build: build
|
||||
`)
|
||||
|
||||
proj, err := Load(root)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if proj.ConfigSource.Name != ConfigFileYML || proj.ConfigSource.Format != "yaml" || proj.ConfigSource.Legacy {
|
||||
t.Fatalf("unexpected config source: %#v", proj.ConfigSource)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadLegacyJSONConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, LegacyConfigFile), `{
|
||||
"module": {
|
||||
"name": "Legacy Module",
|
||||
"resref": "legacy"
|
||||
},
|
||||
"paths": {
|
||||
"source": "src",
|
||||
"build": "build"
|
||||
}
|
||||
}`+"\n")
|
||||
|
||||
proj, err := Load(root)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if proj.ConfigSource.Name != LegacyConfigFile || proj.ConfigSource.Format != "json" || !proj.ConfigSource.Legacy {
|
||||
t.Fatalf("unexpected config source: %#v", proj.ConfigSource)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPrefersYAMLOverLegacyJSON(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, LegacyConfigFile), `{
|
||||
"module": {
|
||||
"name": "Legacy Module",
|
||||
"resref": "legacy"
|
||||
}
|
||||
}`+"\n")
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFile), `
|
||||
module:
|
||||
name: YAML Module
|
||||
resref: yamlmod
|
||||
paths:
|
||||
source: src
|
||||
build: build
|
||||
`)
|
||||
|
||||
proj, err := Load(root)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if proj.ConfigSource.Name != ConfigFile {
|
||||
t.Fatalf("expected YAML config to win, got %#v", proj.ConfigSource)
|
||||
}
|
||||
if got, want := proj.Config.Module.ResRef, "yamlmod"; got != want {
|
||||
t.Fatalf("expected resref %q, got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRejectsMalformedYAML(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFile), "module:\n name: Test\n resref: bad\n")
|
||||
|
||||
if _, err := Load(root); err == nil {
|
||||
t.Fatal("expected malformed YAML error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRejectsUnknownYAMLFields(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFile), `
|
||||
module:
|
||||
name: Test Module
|
||||
resref: testmod
|
||||
paths:
|
||||
source: src
|
||||
build: build
|
||||
unexpected: true
|
||||
`)
|
||||
|
||||
err := loadAndValidate(root)
|
||||
if err == nil {
|
||||
t.Fatal("expected unknown field error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "field unexpected not found") {
|
||||
t.Fatalf("expected unknown field error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindRootUsesYAMLConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
child := filepath.Join(root, "nested", "dir")
|
||||
mkdirAll(t, child)
|
||||
writeProjectFile(t, filepath.Join(root, ConfigFile), "module:\n name: Test\n resref: test\n")
|
||||
|
||||
got, err := FindRoot(child)
|
||||
if err != nil {
|
||||
t.Fatalf("FindRoot returned error: %v", err)
|
||||
}
|
||||
if got != root {
|
||||
t.Fatalf("expected root %s, got %s", root, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTopDataAssetsDirPrefersExplicitConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
@@ -242,6 +392,60 @@ func TestValidateLayoutRejectsInvalidAutogenConsumerConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsDuplicateHAKNames(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
mkdirAll(t, filepath.Join(root, "build"))
|
||||
|
||||
proj := &Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Test", ResRef: "test"},
|
||||
Paths: PathConfig{Source: "src", Build: "build"},
|
||||
HAKs: []HAKConfig{
|
||||
{Name: "core", Priority: 1, Include: []string{"core/**"}},
|
||||
{Name: "CORE", Priority: 2, Include: []string{"other/**"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("expected duplicate hak validation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "duplicated") {
|
||||
t.Fatalf("expected duplicate validation error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsAmbiguousMusicPrefixes(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "assets"))
|
||||
mkdirAll(t, filepath.Join(root, "build"))
|
||||
|
||||
proj := &Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Test", ResRef: "test"},
|
||||
Paths: PathConfig{Assets: "assets", Build: "build"},
|
||||
Music: MusicConfig{
|
||||
Prefixes: map[string]string{
|
||||
"envi/music": "mus_",
|
||||
"/envi/music": "mus2_",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("expected music prefix validation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "normalize to the same path") {
|
||||
t.Fatalf("expected ambiguous prefix validation error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanAllowsMissingAssetsDir(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
@@ -320,3 +524,18 @@ func TestCloneWithHAKNamesRejectsUnknownHAKs(t *testing.T) {
|
||||
t.Fatal("expected error for unknown hak name")
|
||||
}
|
||||
}
|
||||
|
||||
func loadAndValidate(root string) error {
|
||||
proj, err := Load(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return proj.ValidateLayout()
|
||||
}
|
||||
|
||||
func writeProjectFile(t *testing.T, path, content string) {
|
||||
t.Helper()
|
||||
if err := os.WriteFile(path, []byte(strings.TrimPrefix(content, "\n")), 0o644); err != nil {
|
||||
t.Fatalf("write %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user