package materializer import ( "strings" "testing" ) func TestCanonicalSha256_StableAcrossMapOrder(t *testing.T) { a := map[string]any{"b": 2, "a": 1, "c": map[string]any{"y": "Y", "x": "X"}} b := map[string]any{"a": 1, "c": map[string]any{"x": "X", "y": "Y"}, "b": 2} hashA, err := CanonicalSha256(a) if err != nil { t.Fatalf("hash a: %v", err) } hashB, err := CanonicalSha256(b) if err != nil { t.Fatalf("hash b: %v", err) } if hashA != hashB { t.Fatalf("identical objects produced different hashes:\n a=%s\n b=%s", hashA, hashB) } if len(hashA) != 64 || strings.Trim(hashA, "0123456789abcdef") != "" { t.Fatalf("hash isn't a 64-char hex string: %q", hashA) } } func TestCanonicalSha256_DistinctsDifferentInputs(t *testing.T) { a := map[string]any{"k": "v"} b := map[string]any{"k": "v2"} hashA, _ := CanonicalSha256(a) hashB, _ := CanonicalSha256(b) if hashA == hashB { t.Fatalf("different inputs collided: %s", hashA) } } func TestCanonicalSha256_ArrayOrderMatters(t *testing.T) { a := map[string]any{"k": []any{1, 2, 3}} b := map[string]any{"k": []any{3, 2, 1}} hashA, _ := CanonicalSha256(a) hashB, _ := CanonicalSha256(b) if hashA == hashB { t.Fatal("array order should change the hash, but did not") } }