Fix validator screaming about new columns

This commit is contained in:
2026-05-24 12:06:47 +02:00
parent 334cd427c0
commit 91ab34ddff
2 changed files with 97 additions and 23 deletions
+41 -12
View File
@@ -432,10 +432,14 @@ func validateDataObject(path string, obj map[string]any, report *ValidationRepor
validateRowsFile(path, obj, report, false)
return
}
if _, hasColumns := obj["columns"]; hasColumns {
validateColumnsFile(path, obj, report)
return
}
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityWarning,
Path: path,
Message: "module file does not use a recognized canonical shape yet; expected one of entries, overrides, or rows",
Message: "module file does not use a recognized canonical shape yet; expected one of columns, entries, overrides, or rows",
})
return
}
@@ -832,17 +836,44 @@ func validateRowsFile(path string, obj map[string]any, report *ValidationReport,
if rowsList, ok := rows.([]any); ok {
validateRowCollection(path, obj, rowsList, report)
}
if columns, ok := obj["columns"]; ok {
if list, ok := columns.([]any); !ok {
if _, ok := obj["columns"]; ok {
validateColumnsFile(path, obj, report)
} else if requireColumns {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityError,
Path: path,
Message: "base dataset file must contain columns",
})
}
}
func validateColumnsFile(path string, obj map[string]any, report *ValidationReport) {
columns, ok := obj["columns"]
if !ok {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityError,
Path: path,
Message: "columns file must contain a columns array",
})
return
}
list, ok := columns.([]any)
if !ok {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityError,
Path: path,
Message: "columns must be a JSON array when present",
})
} else {
return
}
for _, raw := range list {
column, ok := raw.(string)
if !ok {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityError,
Path: path,
Message: "columns must contain only strings",
})
continue
}
if isAuthoringOnlyField(column) && !preserveLegacyWikiColumnForPath(path, column) {
@@ -854,14 +885,6 @@ func validateRowsFile(path string, obj map[string]any, report *ValidationReport,
}
}
}
} else if requireColumns {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityError,
Path: path,
Message: "base dataset file must contain columns",
})
}
}
func validateEntriesFile(path string, obj map[string]any, report *ValidationReport) {
entries, ok := obj["entries"]
@@ -899,6 +922,9 @@ func validateEntriesFile(path string, obj map[string]any, report *ValidationRepo
validateInlineTextUsage(path, key, entry, report)
}
}
if _, ok := obj["columns"]; ok {
validateColumnsFile(path, obj, report)
}
}
func validateOverridesFile(path string, obj map[string]any, report *ValidationReport) {
@@ -922,6 +948,9 @@ func validateOverridesFile(path string, obj map[string]any, report *ValidationRe
container := map[string]any{"rows": overrideList}
validateRowCollection(path, container, overrideList, report)
}
if _, ok := obj["columns"]; ok {
validateColumnsFile(path, obj, report)
}
}
func validateStateObject(path string, obj map[string]any, report *ValidationReport) {
+45
View File
@@ -134,6 +134,51 @@ func TestValidateProjectRejectsDuplicateJSONKeys(t *testing.T) {
}
}
func TestValidateProjectAcceptsModuleColumnExpansionFile(t *testing.T) {
root := testProjectRoot(t)
mkdirAll(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "modules"))
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
writeFile(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "base.json"), `{
"output": "racialtypes.2da",
"columns": ["Label"],
"rows": []
}`+"\n")
writeFile(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "modules", "00_newcolumns.json"), `{
"columns": ["ECL", "AvailableHeadsMale", "AvailableSkinColors"]
}`+"\n")
report := ValidateProject(testProject(root))
text := diagnosticsText(report.Diagnostics)
if strings.Contains(text, "module file does not use a recognized canonical shape") {
t.Fatalf("expected module column expansion file to validate as canonical, got:\n%s", text)
}
if report.HasErrors() {
t.Fatalf("expected module column expansion file to avoid validation errors, got:\n%s", text)
}
}
func TestValidateProjectRejectsInvalidModuleColumnExpansionFile(t *testing.T) {
root := testProjectRoot(t)
mkdirAll(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "modules"))
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
writeFile(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "base.json"), `{
"output": "racialtypes.2da",
"columns": ["Label"],
"rows": []
}`+"\n")
writeFile(t, filepath.Join(root, "topdata", "data", "racialtypes", "core", "modules", "00_badcolumns.json"), `{
"columns": "ECL"
}`+"\n")
report := ValidateProject(testProject(root))
if !report.HasErrors() {
t.Fatalf("expected invalid module columns file to fail validation, got:\n%s", diagnosticsText(report.Diagnostics))
}
if !diagnosticsContain(report.Diagnostics, "columns must be a JSON array when present") {
t.Fatalf("expected columns array diagnostic, got:\n%s", diagnosticsText(report.Diagnostics))
}
}
func TestValidateProjectRejectsDuplicateEntryKeysAcrossModules(t *testing.T) {
root := testProjectRoot(t)
mkdirAll(t, filepath.Join(root, "topdata", "data", "baseitems", "modules"))