You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.1 KiB
83 lines
2.1 KiB
|
2 weeks ago
|
package codec_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/hex"
|
||
|
|
"encoding/json"
|
||
|
|
"math"
|
||
|
|
"os"
|
||
|
|
"strconv"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
datekeys "g.activething.com/go/DateKeys"
|
||
|
|
"g.activething.com/go/DateKeys/codec"
|
||
|
|
)
|
||
|
|
|
||
|
|
// cborVectors is the generic part of testdata/vectors/cbor.json, which
|
||
|
|
// internal/testkit.CBORVectors generates.
|
||
|
|
type cborVectors struct {
|
||
|
|
Walk struct {
|
||
|
|
MaxDepth int `json:"max_depth"`
|
||
|
|
MaxLen int `json:"max_len"`
|
||
|
|
} `json:"walk"`
|
||
|
|
Accept []struct {
|
||
|
|
Name string `json:"name"`
|
||
|
|
Hex string `json:"hex"`
|
||
|
|
Value json.RawMessage `json:"value"`
|
||
|
|
} `json:"accept"`
|
||
|
|
Reject []struct {
|
||
|
|
Name string `json:"name"`
|
||
|
|
Hex string `json:"hex"`
|
||
|
|
Error string `json:"error"`
|
||
|
|
} `json:"reject"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// The shared vectors of the CBOR profile (spec §58): Walk accepts exactly the
|
||
|
|
// accept list, with the value recorded for unsigned integers (a decimal string
|
||
|
|
// above 2^53-1), and rejects the reject list with the recorded code.
|
||
|
|
func TestSharedVectors(t *testing.T) {
|
||
|
|
b, err := os.ReadFile("../testdata/vectors/cbor.json")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
var f cborVectors
|
||
|
|
if err := json.Unmarshal(b, &f); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if len(f.Accept) == 0 || len(f.Reject) == 0 || f.Walk.MaxDepth == 0 || f.Walk.MaxLen == 0 {
|
||
|
|
t.Fatal("incomplete vector file")
|
||
|
|
}
|
||
|
|
for _, v := range f.Accept {
|
||
|
|
in, err := hex.DecodeString(v.Hex)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := codec.Walk(in, f.Walk.MaxDepth, f.Walk.MaxLen); err != nil {
|
||
|
|
t.Errorf("%s: %v", v.Name, err)
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if v.Value == nil {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
n, err := codec.NewDecoder(in).Uint(math.MaxUint64)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("%s: %v", v.Name, err)
|
||
|
|
}
|
||
|
|
want := strconv.FormatUint(n, 10)
|
||
|
|
if n > codec.MaxSafeUint {
|
||
|
|
want = strconv.Quote(want)
|
||
|
|
}
|
||
|
|
if string(v.Value) != want {
|
||
|
|
t.Errorf("%s: value %s, want %s", v.Name, v.Value, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, v := range f.Reject {
|
||
|
|
in, err := hex.DecodeString(v.Hex)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if got := datekeys.Code(codec.Walk(in, f.Walk.MaxDepth, f.Walk.MaxLen)); got != v.Error {
|
||
|
|
t.Errorf("%s: got %q, want %s", v.Name, got, v.Error)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|