parser/metadecoders: Add CSV targetType (map or slice) option to transform.Unmarshal

Closes #8859
This commit is contained in:
Joe Mooring 2025-04-21 10:33:20 -07:00 committed by GitHub
parent ad787614e8
commit db72a1f075
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 166 additions and 9 deletions

View file

@ -379,3 +379,119 @@ Markdown: {{ $markdown }}|
b.AssertFileContent("public/index.html", "Markdown: ## Heading 2\n|")
}
func TestUnmarshalCSV(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
-- layouts/all.html --
{{ $opts := OPTS }}
{{ with resources.Get "pets.csv" | transform.Unmarshal $opts }}
{{ jsonify . }}
{{ end }}
-- assets/pets.csv --
DATA
`
// targetType = map
f := strings.ReplaceAll(files, "OPTS", `dict "targetType" "map"`)
f = strings.ReplaceAll(f, "DATA",
"name,type,breed,age\nSpot,dog,Collie,3\nFelix,cat,Malicious,7",
)
b := hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`[{"age":"3","breed":"Collie","name":"Spot","type":"dog"},{"age":"7","breed":"Malicious","name":"Felix","type":"cat"}]`,
)
// targetType = map (no data)
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "map"`)
f = strings.ReplaceAll(f, "DATA", "")
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html", "")
// targetType = slice
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "slice"`)
f = strings.ReplaceAll(f, "DATA",
"name,type,breed,age\nSpot,dog,Collie,3\nFelix,cat,Malicious,7",
)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`[["name","type","breed","age"],["Spot","dog","Collie","3"],["Felix","cat","Malicious","7"]]`,
)
// targetType = slice (no data)
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "slice"`)
f = strings.ReplaceAll(f, "DATA", "")
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html", "")
// targetType not specified
f = strings.ReplaceAll(files, "OPTS", "dict")
f = strings.ReplaceAll(f, "DATA",
"name,type,breed,age\nSpot,dog,Collie,3\nFelix,cat,Malicious,7",
)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`[["name","type","breed","age"],["Spot","dog","Collie","3"],["Felix","cat","Malicious","7"]]`,
)
// targetType not specified (no data)
f = strings.ReplaceAll(files, "OPTS", "dict")
f = strings.ReplaceAll(f, "DATA", "")
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html", "")
// targetType = foo
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "foo"`)
_, err := hugolib.TestE(t, f)
if err == nil {
t.Errorf("expected error")
} else {
if !strings.Contains(err.Error(), `invalid targetType: expected either slice or map, received foo`) {
t.Log(err.Error())
t.Errorf("error message does not match expected error message")
}
}
// targetType = foo (no data)
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "foo"`)
f = strings.ReplaceAll(f, "DATA", "")
_, err = hugolib.TestE(t, f)
if err == nil {
t.Errorf("expected error")
} else {
if !strings.Contains(err.Error(), `invalid targetType: expected either slice or map, received foo`) {
t.Log(err.Error())
t.Errorf("error message does not match expected error message")
}
}
// targetType = map (error: expected at least a header row and one data row)
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "map"`)
_, err = hugolib.TestE(t, f)
if err == nil {
t.Errorf("expected error")
} else {
if !strings.Contains(err.Error(), `expected at least a header row and one data row`) {
t.Log(err.Error())
t.Errorf("error message does not match expected error message")
}
}
// targetType = map (error: header row contains duplicate field names)
f = strings.ReplaceAll(files, "OPTS", `dict "targetType" "map"`)
f = strings.ReplaceAll(f, "DATA",
"name,name,breed,age\nSpot,dog,Collie,3\nFelix,cat,Malicious,7",
)
_, err = hugolib.TestE(t, f)
if err == nil {
t.Errorf("expected error")
} else {
if !strings.Contains(err.Error(), `header row contains duplicate field names`) {
t.Log(err.Error())
t.Errorf("error message does not match expected error message")
}
}
}