Harden chunk map export and retire completed plans
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -140,6 +141,62 @@ func TestCodecRejectsInvalidDurableBoundaries(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeEnforcesRequiredSchemaFieldsAndTypes(t *testing.T) {
|
||||
request := acceptedBuildRequest(t)
|
||||
request.Plan.Annotations = nil
|
||||
var err error
|
||||
request.Chunks, err = source.MaterializeChunkPlan(request.Source, request.Plan)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
artifact, err := Serialize(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
mutate func(map[string]any)
|
||||
}{
|
||||
{name: "missing plan annotations", mutate: func(value map[string]any) { delete(value, "plan_annotations") }},
|
||||
{name: "null plan annotations", mutate: func(value map[string]any) { value["plan_annotations"] = nil }},
|
||||
{name: "missing first index", mutate: func(value map[string]any) { delete(chunkDocument(value, 0), "index") }},
|
||||
{name: "null first index", mutate: func(value map[string]any) { chunkDocument(value, 0)["index"] = nil }},
|
||||
{name: "missing empty chunk annotations", mutate: func(value map[string]any) { delete(chunkDocument(value, 1), "annotations") }},
|
||||
{name: "null empty chunk annotations", mutate: func(value map[string]any) { chunkDocument(value, 1)["annotations"] = nil }},
|
||||
{name: "explicit empty llm profile", mutate: func(value map[string]any) {
|
||||
value["producer"].(map[string]any)["llm_profile"] = ""
|
||||
}},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
value := decodeJSONDocument(t, artifact.Content)
|
||||
test.mutate(value)
|
||||
content, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := New().Decode(content); err == nil {
|
||||
t.Fatalf("Decode(%s) error = nil, want schema rejection", content)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDoesNotMutateValue(t *testing.T) {
|
||||
value, err := Build(acceptedBuildRequest(t))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value.Chunks[0].Annotations["dnd/scenes"] = json.RawMessage(" { \n \"kind\" : \"narrative\" \n } ")
|
||||
before := clone(value)
|
||||
if _, err := New().Encode(value); err != nil {
|
||||
t.Fatalf("Encode() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(value, before) {
|
||||
t.Fatalf("Encode() mutated value:\nbefore: %#v\nafter: %#v", before, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChunkMapOwnershipIsIndependent(t *testing.T) {
|
||||
request := acceptedBuildRequest(t)
|
||||
first, err := Build(request)
|
||||
@@ -157,6 +214,21 @@ func TestChunkMapOwnershipIsIndependent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func decodeJSONDocument(t *testing.T, content []byte) map[string]any {
|
||||
t.Helper()
|
||||
decoder := json.NewDecoder(bytes.NewReader(content))
|
||||
decoder.UseNumber()
|
||||
var value map[string]any
|
||||
if err := decoder.Decode(&value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func chunkDocument(value map[string]any, index int) map[string]any {
|
||||
return value["chunks"].([]any)[index].(map[string]any)
|
||||
}
|
||||
|
||||
func acceptedBuildRequest(t *testing.T) BuildRequest {
|
||||
t.Helper()
|
||||
document := &source.SourceDocument{
|
||||
|
||||
Reference in New Issue
Block a user