mirror of
https://github.com/zap-proto/zip.git
synced 2026-10-19 15:38:57 +00:00
A field of type [N]byte lays out as bytes_fixed[N] and the schema states N. The same type as a LIST element stated bytes_fixed[0]: sliceElemOf copied the element's kind and its nested layout but not its length, and LayoutOf then spelled the element with a literal zero. Nothing failed — the layout was accepted and the schema was published — so what a peer read was a contract to take no bytes per element, and a codec generated from it would have done exactly that. This is the shape every chain reply is full of: a list of ids. It is seven ops on a Lux node alone. The refusal in that position was wrong too. Reflection does not carry bytes_fixed anywhere, on purpose — an id is the case that should make a type declare its own wire — and a field says so, naming MarshalZAP. An element instead reported that a kind had no wire form, which is true of nothing and tells the reader nothing. It now gives the same answer a field does.
47 lines
1.4 KiB
Go
47 lines
1.4 KiB
Go
package zapenc
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A list of ids is the shape every chain reply is full of, and it is exactly
|
|
// the shape bytes_fixed exists for. The element has to keep its WIDTH — the
|
|
// schema is the contract a generated codec is built from, and bytes_fixed[0]
|
|
// is a contract to read nothing — and the refusal has to be the one that says
|
|
// what to do about it, not the one that says a kind has no wire form.
|
|
type fixedList struct {
|
|
Nodes [][20]byte
|
|
Chains [][32]byte
|
|
}
|
|
|
|
func TestFixedListElementKeepsItsWidth(t *testing.T) {
|
|
sh, err := LayoutOf(reflect.TypeOf(fixedList{}))
|
|
if err != nil {
|
|
t.Fatalf("LayoutOf: %v", err)
|
|
}
|
|
want := map[string]string{
|
|
"Nodes": "list<bytes_fixed[20]>",
|
|
"Chains": "list<bytes_fixed[32]>",
|
|
}
|
|
for _, s := range sh.Slots {
|
|
if s.Type != want[s.Name] {
|
|
t.Errorf("%s: schema says %s, want %s", s.Name, s.Type, want[s.Name])
|
|
}
|
|
if s.Elem != strings.TrimSuffix(strings.TrimPrefix(want[s.Name], "list<"), ">") {
|
|
t.Errorf("%s: element says %q", s.Name, s.Elem)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFixedListRefusalNamesTheFix(t *testing.T) {
|
|
_, err := Marshal(&fixedList{Nodes: [][20]byte{{1}}})
|
|
if err == nil {
|
|
t.Fatal("the reflective codec must refuse bytes_fixed, in a list as in a field")
|
|
}
|
|
if !strings.Contains(err.Error(), "MarshalZAP") {
|
|
t.Fatalf("the refusal has to name the fix, got: %v", err)
|
|
}
|
|
}
|