github.com/kamalshkeir/kencoding@v0.0.2-0.20230409043843-44b609a0475a/proto/message_test.go (about) 1 package proto 2 3 import ( 4 "bytes" 5 "math" 6 "testing" 7 ) 8 9 func TestAppendVarint(t *testing.T) { 10 m := AppendVarint(nil, 1, 42) 11 12 f, w, v, r, err := Parse(m) 13 if err != nil { 14 t.Fatal(err) 15 } 16 if len(r) != 0 { 17 t.Fatal("unexpected trailing bytes:", r) 18 } 19 if w != Varint { 20 t.Fatal("unexpected wire type:", t) 21 } 22 if f != 1 { 23 t.Fatal("unexpected field number:", f) 24 } 25 if u := v.Varint(); u != 42 { 26 t.Fatal("value mismatch, want 42 but got", u) 27 } 28 } 29 30 func TestAppendVarlen(t *testing.T) { 31 m := AppendVarlen(nil, 1, []byte("Hello World!")) 32 33 f, w, v, r, err := Parse(m) 34 if err != nil { 35 t.Fatal(err) 36 } 37 if len(r) != 0 { 38 t.Fatal("unexpected trailing bytes:", r) 39 } 40 if w != Varlen { 41 t.Fatal("unexpected wire type:", t) 42 } 43 if f != 1 { 44 t.Fatal("unexpected field number:", f) 45 } 46 if string(v) != "Hello World!" { 47 t.Fatalf("value mismatch, want \"Hello World!\" but got %q", v) 48 } 49 } 50 51 func TestAppendFixed32(t *testing.T) { 52 m := AppendFixed32(nil, 1, 42) 53 54 f, w, v, r, err := Parse(m) 55 if err != nil { 56 t.Fatal(err) 57 } 58 if len(r) != 0 { 59 t.Fatal("unexpected trailing bytes:", r) 60 } 61 if w != Fixed32 { 62 t.Fatal("unexpected wire type:", t) 63 } 64 if f != 1 { 65 t.Fatal("unexpected field number:", f) 66 } 67 if u := v.Fixed32(); u != 42 { 68 t.Fatal("value mismatch, want 42 but got", u) 69 } 70 } 71 72 func TestAppendFixed64(t *testing.T) { 73 m := AppendFixed64(nil, 1, 42) 74 75 f, w, v, r, err := Parse(m) 76 if err != nil { 77 t.Fatal(err) 78 } 79 if len(r) != 0 { 80 t.Fatal("unexpected trailing bytes:", r) 81 } 82 if w != Fixed64 { 83 t.Fatal("unexpected wire type:", t) 84 } 85 if f != 1 { 86 t.Fatal("unexpected field number:", f) 87 } 88 if u := v.Fixed64(); u != 42 { 89 t.Fatal("value mismatch, want 42 but got", u) 90 } 91 } 92 93 func TestDecodeFromAppend(t *testing.T) { 94 m := RawMessage(nil) 95 m = AppendVarint(m, 1, math.MaxUint64) 96 m = AppendVarlen(m, 2, []byte("Hello World!")) 97 m = AppendFixed32(m, 3, math.Float32bits(42.0)) 98 m = AppendFixed64(m, 4, math.Float64bits(1234.0)) 99 100 type M struct { 101 I int 102 S string 103 F32 float32 104 F64 float64 105 } 106 107 x := M{} 108 109 if err := Unmarshal(m, &x); err != nil { 110 t.Fatal(err) 111 } 112 if x.I != -1 { 113 t.Errorf("x.I=%d", x.I) 114 } 115 if x.S != "Hello World!" { 116 t.Errorf("x.S=%q", x.S) 117 } 118 if x.F32 != 42 { 119 t.Errorf("x.F32=%g", x.F32) 120 } 121 if x.F64 != 1234 { 122 t.Errorf("x.F64=%g", x.F64) 123 } 124 } 125 126 func TestDecodeFixture(t *testing.T) { 127 m := loadProtobuf(t, "message.pb") 128 m = assertParse(t, m, 1, Varint, makeVarint(10)) 129 m = assertParse(t, m, 2, Varint, makeVarint(20)) 130 m = assertParse(t, m, 3, Varint, makeVarint(30)) 131 m = assertParse(t, m, 4, Varlen, []byte("Hello World!")) 132 assertEmpty(t, m) 133 } 134 135 func assertParse(t *testing.T, m RawMessage, f FieldNumber, w WireType, b []byte) RawMessage { 136 t.Helper() 137 138 f0, w0, b0, m, err := Parse(m) 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 if f0 != f { 144 t.Errorf("field number mismatch, want %d but got %d", f, f0) 145 } 146 147 if w0 != w { 148 t.Errorf("wire type mismatch, want %d but got %d", w, w0) 149 } 150 151 if !bytes.Equal(b0, b) { 152 t.Errorf("value mismatch, want %v but got %v", b, b0) 153 } 154 155 return m 156 } 157 158 func assertEmpty(t *testing.T, m RawMessage) { 159 t.Helper() 160 161 if len(m) != 0 { 162 t.Errorf("unexpected content remained in the protobuf message: %v", m) 163 } 164 } 165 166 func BenchmarkScan(b *testing.B) { 167 m, _ := Marshal(&message{ 168 A: 1, 169 B: 2, 170 C: 3, 171 S: submessage{ 172 X: "hello", 173 Y: "world", 174 }, 175 }) 176 177 for i := 0; i < b.N; i++ { 178 Scan(m, func(f FieldNumber, t WireType, v RawValue) (bool, error) { 179 switch f { 180 case 1, 2, 3: 181 return true, nil 182 case 4: 183 err := Scan(v, func(f FieldNumber, t WireType, v RawValue) (bool, error) { 184 switch f { 185 case 1, 2: 186 return true, nil 187 default: 188 b.Error("invalid field number:", f) 189 return false, nil 190 } 191 }) 192 return err != nil, err 193 default: 194 b.Error("invalid field number:", f) 195 return false, nil 196 } 197 }) 198 } 199 }