Files
zip/codec_test.go
T
zeekay 17589a6d6d A type can state its own ZAP wire, so an id can cross
zip.Codecs renders MarshalZAP/UnmarshalZAP from LayoutOf — the third
reader the derivation's doc already named, after the plane that encodes
against it and the .zap schema that states it.

bytes_fixed[N] is refused by the reflective encoder on purpose: an id is
the case that should force a type to declare its own wire. Until it does,
a reply holding an ids.ID cannot cross the plane at all. Wire is consulted
at the root of Marshal and Unmarshal only, so the emitted set is closed
downward and a parent reaches each nested value by its method.

The emitted file restates Wire rather than importing zip, so a leaf module
states its wire on the ZAP builder alone. The bytes are held equal to the
reflective encoder's, field for field, which is what lets a codec roll out
one pod at a time.
2026-08-29 18:40:44 -07:00

51 lines
1.5 KiB
Go

package zip_test
import (
"os"
"os/exec"
"path/filepath"
"reflect"
"testing"
"github.com/zap-proto/zip"
"github.com/zap-proto/zip/internal/codec"
)
// TestTheCodecIsCheckedIn regenerates internal/codec/zap_gen.go and requires the
// file on disk to match. The generated codec is the wire those types speak, so a
// change to the types that nobody regenerated is a wire that moved under its
// readers — and this is where that is noticed, not in a rolling deploy.
func TestTheCodecIsCheckedIn(t *testing.T) {
got, err := zip.Codecs(reflect.TypeOf(codec.Trunk{}), reflect.TypeOf(codec.Ided{}))
if err != nil {
t.Fatal(err)
}
if len(got) != 1 {
t.Fatalf("got %d packages, want 1", len(got))
}
path := filepath.Join("internal", "codec", "zap_gen.go")
want, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
if string(got[0].Source) != string(want) {
if os.Getenv("WRITE") != "" {
if err := os.WriteFile(path, got[0].Source, 0o644); err != nil {
t.Fatal(err)
}
t.Fatal("wrote " + path + "; run again")
}
t.Errorf("%s is stale; regenerate with WRITE=1 go test -run TestTheCodecIsCheckedIn ./...", path)
}
}
// TestTheEmittedSourceCompiles builds the package the emitter wrote. format.Source
// only proves it PARSES; a codec that names a field that moved, or converts a
// value the type will not take, parses and does not build.
func TestTheEmittedSourceCompiles(t *testing.T) {
out, err := exec.Command("go", "build", "./internal/codec").CombinedOutput()
if err != nil {
t.Fatalf("go build ./internal/codec: %v\n%s", err, out)
}
}