github.com/philpearl/plenc@v0.0.15/plenccodec/descriptor_test.go (about) 1 package plenccodec_test 2 3 import ( 4 _ "embed" 5 "encoding/json" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/google/go-cmp/cmp" 11 "github.com/philpearl/plenc" 12 "github.com/philpearl/plenc/plenccodec" 13 ) 14 15 //go:embed descriptor_test.json 16 var expTestDescriptor string 17 18 func TestDescriptor(t *testing.T) { 19 type sub struct { 20 A int8 `plenc:"1"` 21 B string `plenc:"2"` 22 } 23 24 // maps are rendered as a list of keys and values because maps like this 25 // don't have a valid JSON representation 26 type mykey struct { 27 A int `plenc:"1"` 28 B int `plenc:"2"` 29 } 30 type mymap map[mykey]string 31 32 type my struct { 33 A int `plenc:"1"` 34 B float32 `plenc:"2"` 35 C string `plenc:"3"` 36 D uint `plenc:"4"` 37 E []float64 `plenc:"5"` 38 F []sub `plenc:"6"` 39 G [][]uint32 `plenc:"7"` 40 H [][]float32 `plenc:"8"` 41 I *uint `plenc:"9"` 42 J mymap `plenc:"10"` 43 K []byte `plenc:"11"` 44 L map[float32]float32 `plenc:"12"` 45 M *int `plenc:"13"` 46 N time.Time `plenc:"14"` 47 O bool `plenc:"15" json:"elephant"` 48 P map[string]any `plenc:"16"` 49 Q int32 `plenc:"17,flat"` 50 R time.Time `plenc:"18,flattime"` 51 S map[string]int `plenc:"19"` 52 } 53 54 plenc.RegisterCodec(reflect.TypeOf(map[string]any{}), plenccodec.JSONMapCodec{}) 55 plenc.RegisterCodec(reflect.TypeOf([]any{}), plenccodec.JSONArrayCodec{}) 56 plenc.RegisterCodecWithTag(reflect.TypeOf(time.Time{}), "flattime", plenccodec.BQTimestampCodec{}) 57 58 c, err := plenc.CodecForType(reflect.TypeOf(my{})) 59 if err != nil { 60 t.Fatal(err) 61 } 62 d := c.Descriptor() 63 64 // Check we can encode and decode a Descriptor! 65 descData, err := plenc.Marshal(nil, &d) 66 if err != nil { 67 t.Fatal(err) 68 } 69 var dd plenccodec.Descriptor 70 if err := plenc.Unmarshal(descData, &dd); err != nil { 71 t.Fatal(err) 72 } 73 if diff := cmp.Diff(d, dd); diff != "" { 74 t.Fatal(diff) 75 } 76 77 // Now test we can use the descriptor 78 var seven uint = 7 79 in := my{ 80 A: 1, 81 B: 3.7, 82 C: "this is my hat", 83 D: 9898, 84 E: []float64{1, 2.3, 3.7}, 85 F: []sub{ 86 {A: 1, B: "one"}, 87 {A: 2, B: "two"}, 88 {A: 3}, 89 }, 90 G: [][]uint32{ 91 {1, 2}, 92 {3, 4}, 93 }, 94 H: [][]float32{ 95 {1, 2}, 96 {3, 4}, 97 }, 98 I: &seven, 99 J: mymap{ 100 mykey{A: 9, B: 4}: "nine", 101 }, 102 K: []byte{0, 1, 2, 3}, 103 // Map order is random, so we'll just have one entry in the map. I have 104 // tested with two! 105 L: map[float32]float32{ 106 3.14: 13.37, 107 }, 108 N: time.Date(1970, 3, 15, 0, 0, 0, 1337e5, time.UTC), 109 O: true, 110 P: map[string]any{ 111 "array": []any{1, 1.3, "cheese", json.Number("1337")}, 112 }, 113 Q: 123, 114 R: time.Date(1970, 3, 15, 0, 0, 0, 1337e5, time.UTC), 115 S: map[string]int{ 116 "one": 1, 117 "two": 2, 118 }, 119 } 120 121 data, err := plenc.Marshal(nil, in) 122 if err != nil { 123 t.Fatal(err) 124 } 125 126 { 127 // Check we can decode that plenc 128 var out my 129 if err := plenc.Unmarshal(data, &out); err != nil { 130 t.Fatal(err) 131 } 132 if diff := cmp.Diff(in, out); diff != "" { 133 t.Fatal(diff) 134 } 135 } 136 137 var j plenccodec.JSONOutput 138 139 if err := d.Read(&j, data); err != nil { 140 t.Fatal(err, string(j.Done())) 141 } 142 out := string(j.Done()) 143 144 if diff := cmp.Diff(expTestDescriptor, out); diff != "" { 145 t.Log(out) 146 t.Fatal(diff) 147 } 148 }