Files
ss/internal/yamlutil/yamlutil_test.go
2026-07-19 20:01:38 +08:00

104 lines
2.8 KiB
Go

package yamlutil
import (
"testing"
"gopkg.in/yaml.v3"
)
func TestUnmarshal_NoDuplicates(t *testing.T) {
data := []byte("a: 1\nb: 2\n")
var out map[string]interface{}
if err := Unmarshal(data, &out); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
if out["a"] != 1 || out["b"] != 2 {
t.Fatalf("unexpected result: %#v", out)
}
}
func TestUnmarshal_DuplicateKeyLastWins(t *testing.T) {
// Mirrors the real bug: a duplicate top-level key that gopkg.in/yaml.v3
// rejects outright, but PyYAML (and this package) tolerate by letting
// the later occurrence win.
data := []byte(`external-controller-cors:
allow-origins:
- "*"
allow-private-network: true
allow-origins:
- tauri://localhost
- https://yacd.metacubex.one
`)
// Confirm plain yaml.Unmarshal actually fails on this input, i.e. that
// the test is exercising the real bug.
var control map[string]interface{}
if err := yaml.Unmarshal(data, &control); err == nil {
t.Fatalf("expected plain yaml.Unmarshal to fail on duplicate keys, it didn't")
}
var out map[string]interface{}
if err := Unmarshal(data, &out); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
cors, ok := out["external-controller-cors"].(map[string]interface{})
if !ok {
t.Fatalf("expected external-controller-cors map, got %#v", out["external-controller-cors"])
}
origins, ok := cors["allow-origins"].([]interface{})
if !ok || len(origins) != 2 {
t.Fatalf("expected last allow-origins (2 entries) to win, got %#v", cors["allow-origins"])
}
if origins[0] != "tauri://localhost" {
t.Fatalf("expected last-occurrence value to win, got %#v", origins)
}
if cors["allow-private-network"] != true {
t.Fatalf("expected sibling key to survive dedupe, got %#v", cors)
}
}
func TestUnmarshal_NestedDuplicates(t *testing.T) {
data := []byte(`outer:
inner:
x: 1
x: 2
inner:
y: 3
`)
var out map[string]interface{}
if err := Unmarshal(data, &out); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
outer := out["outer"].(map[string]interface{})
inner := outer["inner"].(map[string]interface{})
if _, hasX := inner["x"]; hasX {
t.Fatalf("expected last 'inner' occurrence to fully replace the first, got %#v", inner)
}
if inner["y"] != 3 {
t.Fatalf("expected inner.y == 3, got %#v", inner)
}
}
func TestUnmarshal_Empty(t *testing.T) {
var out map[string]interface{}
if err := Unmarshal([]byte(""), &out); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
if out != nil {
t.Fatalf("expected nil map for empty input, got %#v", out)
}
}
func TestUnmarshal_Sequence(t *testing.T) {
data := []byte("- a: 1\n a: 2\n- b: 3\n")
var out []map[string]interface{}
if err := Unmarshal(data, &out); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
if len(out) != 2 || out[0]["a"] != 2 || out[1]["b"] != 3 {
t.Fatalf("unexpected result: %#v", out)
}
}