Add candidate artifact codec decoding

This commit is contained in:
2026-08-09 00:57:03 +00:00
parent ee600975f0
commit 557809f364
13 changed files with 198 additions and 1 deletions

View File

@@ -107,6 +107,39 @@ func TestCodecSupportsEmptyListsAndCandidateSemanticFailures(t *testing.T) {
}
}
func TestCodecCandidateDecodeOwnsValues(t *testing.T) {
codec := New()
input := validList()
content, err := codec.EncodeCandidate(input)
if err != nil {
t.Fatal(err)
}
first, err := codec.DecodeCandidate(content)
if err != nil {
t.Fatal(err)
}
second, err := codec.DecodeCandidate(content)
if err != nil {
t.Fatal(err)
}
nameOffset := bytes.Index(content, []byte("The Old Tavern"))
if nameOffset < 0 {
t.Fatal("candidate JSON does not contain location name")
}
content[nameOffset] = 'X'
if first.Occurrences[0].Name != "The Old Tavern" {
t.Fatal("DecodeCandidate() retained input bytes")
}
first.Occurrences[0].Name = "changed"
first.Occurrences[0].SourceRefs[0].SourceID = "changed"
if input.Occurrences[0].Name != "The Old Tavern" || input.Occurrences[0].SourceRefs[0].SourceID != "session-alpha" {
t.Fatal("DecodeCandidate() retained input values")
}
if second.Occurrences[0].Name != "The Old Tavern" || second.Occurrences[0].SourceRefs[0].SourceID != "session-alpha" {
t.Fatal("DecodeCandidate() returned aliased values")
}
}
func TestCodecRejectsStructuralJSONBeforeSemanticApproval(t *testing.T) {
valid := `{"occurrences":[{"location_id":"location:sha256:0000000000000000000000000000000000000000000000000000000000000000","name":"The Tavern","kind":"visited","source_refs":[{"source_id":"session","start_unit_id":1,"end_unit_id":1}]}]}`
for _, test := range []struct{ name, raw, want string }{