Skip to content

Commit ce71fe0

Browse files
authored
fix/slice: support empty slice, include empty string (#70)
and fix `go vet` warnings
1 parent 86f2173 commit ce71fe0

File tree

11 files changed

+103
-32
lines changed

11 files changed

+103
-32
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ GO ?= go
22
GOFMT ?= gofmt -s
33
GOLINT ?= ~/go/bin/golint
44
GOFILES := $(shell find . -name "*.go")
5-
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
5+
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples)
66

77
.PHONY: fmt
88
fmt:
@@ -15,7 +15,7 @@ lint:
1515
$(GOLINT) $(GOFILES)
1616

1717
test:
18-
$(GO) test -v ./...
18+
$(GO) test $(VETPACKAGES)
1919

2020
cover:
21-
$(GO) test -coverprofile=prof.out && $(GO) tool cover -html=prof.out && rm prof.out
21+
$(GO) test $(VETPACKAGES) -coverprofile=prof.out && $(GO) tool cover -html=prof.out && rm prof.out

codec_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ func TestMarshalUTF8String(t *testing.T) {
5858
})
5959
}
6060

61+
func TestMarshalEmptyUTF8String(t *testing.T) {
62+
testMarshalBasic(t, "", func(v []byte) (interface{}, error) {
63+
return ToUTF8String(v)
64+
})
65+
}
66+
6167
func TestMarshalInt32Slice(t *testing.T) {
6268
testMarshalBasicSlice(t, []int32{123, 456}, func(v []byte) (interface{}, error) {
6369
return ToInt32Slice(v)
@@ -145,13 +151,16 @@ func testMarshalBasic(t *testing.T, expected interface{}, converter func(v []byt
145151
input := expected
146152
codec := NewCodec(0x10)
147153
inputBuf, _ := codec.Marshal(input)
148-
testPrintf("inputBuf=%v\n", utils.FormatBytes(inputBuf))
154+
testPrintf("inputBuf=%# x\n", inputBuf)
149155

150156
testDecoder(0x10, inputBuf, func(v []byte) (interface{}, error) {
151157
flag = true
152158
value, err := converter(v)
153159
testPrintf("value=%v\n", value)
154-
assert.NoError(t, err, fmt.Sprintf("decode error:%v", err))
160+
if err != nil {
161+
assert.Nil(t, err, ">>>>err is not nil>>>>")
162+
}
163+
// assert.NoError(t, err, fmt.Sprintf("decode error:%v", err))
155164
assert.Equal(t, expected, value, fmt.Sprintf("value does not match(%v): %v", expected, value))
156165
return value, err
157166
})

encoder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (enc *encoder) writeTag() {
213213
func (enc *encoder) writeLengthBuf() {
214214
// vallen := enc.valBuf.Len()
215215
vallen := len(enc.valbuf)
216-
if vallen < 1 {
216+
if vallen < 0 {
217217
panic("length must greater than 0")
218218
}
219219

encoder_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,22 @@ func TestEncoderPrimitiveBinary(t *testing.T) {
139139
}
140140
}
141141
}
142+
143+
// 0x01 (is a node, sequence id=1)
144+
// 0x04 (pvarint, node value length is 4 bytes)
145+
// 0x59, 0x6F, 0x4D, 0x6F (utf-8 string: "YoMo")
146+
func TestEncoderPrimitiveBinaryWithEmptyValue(t *testing.T) {
147+
expected := []byte{0x01, 0x00}
148+
// 0x01 - SeqID=1
149+
var prim = NewPrimitivePacketEncoder(0x01)
150+
// Value = 0x0123FF
151+
prim.SetBytes([]byte{})
152+
153+
res := prim.Encode()
154+
155+
for i, p := range res {
156+
if p != expected[i] {
157+
t.Errorf("i=%v, expected=%v, actual=%v", i, expected[i], res[i])
158+
}
159+
}
160+
}

observable.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ func (o *observableImpl) Subscribe(key byte) Observable {
173173
resultBuffer = append(resultBuffer, b)
174174
l, e := common.DecodeLength(resultBuffer[1 : length+1]) //l 是value占字节,s是l占字节
175175

176+
if l == 0 {
177+
next <- resultBuffer
178+
reject = true
179+
break
180+
}
181+
176182
if e != nil {
177183
length++
178184
} else {

primitive_packet.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"github.com/yomorun/y3-codec-golang/pkg/encoding"
77
)
88

9-
// 描述最小的Packet大小为3个字节
10-
const primitivePacketBufferMinimalLength = 3
9+
// the minimal length of a packet is 2 bytes
10+
const primitivePacketBufferMinimalLength = 2
1111

1212
// PrimitivePacket 定义了值类型的节点,是Codec中的最小单位,以`TLV结构`进行数据描述
1313
type PrimitivePacket basePacket

primitive_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import (
44
"testing"
55
)
66

7-
// 每个Packet最小长度是3个bytes
7+
// 每个Packet最小长度是2个bytes
88
func TestLackLengthPacket(t *testing.T) {
9-
buf := []byte{0x01, 0x01}
9+
buf := []byte{0x01}
1010
expected := "invalid y3 packet minimal size"
1111
_, _, _, err := DecodePrimitivePacket(buf)
1212
if err.Error() != expected {

structure_decoder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (d *structDecoderImpl) decodeStructFromNodePacket(fieldType reflect.Type, f
187187

188188
obtainedValue, flag := d.takeValueByKey(fieldName, fieldType, dataVal)
189189
if !flag {
190-
if d.config.ZeroFields == false {
190+
if !d.config.ZeroFields {
191191
return fmt.Errorf("not fond fieldName:%#x", fieldName)
192192
}
193193
// 用空值填充找不到的字段
@@ -217,7 +217,7 @@ func (d *structDecoderImpl) getKind(val reflect.Value) reflect.Kind {
217217
func (d *structDecoderImpl) takeValueByKey(fieldName string, fieldType reflect.Type, node *NodePacket) (reflect.Value, bool) {
218218
key := utils.KeyOf(fieldName)
219219
flag, isNode, packet := d.matchingKey(key, node)
220-
if flag == false {
220+
if !flag {
221221
return reflect.Indirect(reflect.ValueOf(packet)), false
222222
}
223223
if isNode {

structure_decoder_test.go

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,14 @@ func TestArray(t *testing.T) {
139139
t.Parallel()
140140

141141
input := tester.ArrayTestData{
142-
"foo",
143-
[2]string{"foo", "bar"},
144-
[2]int32{1, 2},
145-
[2]int64{1, 2},
146-
[2]uint32{1, 2},
147-
[2]uint64{1, 2},
148-
[2]float32{1, 2},
149-
[2]float64{1, 2},
142+
Vfoo: "foo",
143+
Vbar: [2]string{"foo", "bar"},
144+
Vint32Array: [2]int32{1, 2},
145+
Vint64Array: [2]int64{1, 2},
146+
Vuint32Array: [2]uint32{1, 2},
147+
Vuint64Array: [2]uint64{1, 2},
148+
Vfloat32Array: [2]float32{1, 2},
149+
Vfloat64Array: [2]float64{1, 2},
150150
}
151151
inputBuf, _ := newStructEncoder(0x3f, structEncoderOptionRoot(utils.RootToken)).Encode(input)
152152

@@ -170,14 +170,46 @@ func TestSlice(t *testing.T) {
170170
t.Parallel()
171171

172172
input := tester.SliceTestData{
173-
"foo",
174-
[]string{"foo", "bar"},
175-
[]int32{1, 2},
176-
[]int64{1, 2},
177-
[]uint32{1, 2},
178-
[]uint64{1, 2},
179-
[]float32{1, 2},
180-
[]float64{1, 2},
173+
Vfoo: "foo",
174+
Vbar: []string{"foo", "bar"},
175+
Vint32Slice: []int32{1, 2},
176+
Vint64Slice: []int64{1, 2},
177+
Vuint32Slice: []uint32{1, 2},
178+
Vuint64Slice: []uint64{1, 2},
179+
Vfloat32Slice: []float32{1, 2},
180+
Vfloat64Slice: []float64{1, 2},
181+
}
182+
183+
inputBuf, _ := newStructEncoder(0x3f, structEncoderOptionRoot(utils.RootToken)).Encode(input)
184+
185+
var result tester.SliceTestData
186+
_, err := newStructDecoder(&result).Decode(inputBuf)
187+
if err != nil {
188+
t.Errorf("got an err: %s", err.Error())
189+
t.FailNow()
190+
}
191+
192+
testSliceString(t, result.Vbar, input.Vbar)
193+
testSliceInt32(t, result.Vint32Slice, input.Vint32Slice)
194+
testSliceInt64(t, result.Vint64Slice, input.Vint64Slice)
195+
testSliceUint32(t, result.Vuint32Slice, input.Vuint32Slice)
196+
testSliceUint64(t, result.Vuint64Slice, input.Vuint64Slice)
197+
testSliceFloat32(t, result.Vfloat32Slice, input.Vfloat32Slice)
198+
testSliceFloat64(t, result.Vfloat64Slice, input.Vfloat64Slice)
199+
}
200+
201+
func TestEmptySlice(t *testing.T) {
202+
t.Parallel()
203+
204+
input := tester.SliceTestData{
205+
Vfoo: "foo",
206+
Vbar: []string{},
207+
Vint32Slice: []int32{},
208+
Vint64Slice: []int64{},
209+
Vuint32Slice: []uint32{},
210+
Vuint64Slice: []uint64{},
211+
Vfloat32Slice: []float32{},
212+
Vfloat64Slice: []float64{},
181213
}
182214

183215
inputBuf, _ := newStructEncoder(0x3f, structEncoderOptionRoot(utils.RootToken)).Encode(input)
@@ -373,9 +405,12 @@ func TestRootSliceWithSliceStruct(t *testing.T) {
373405
func TestNested(t *testing.T) {
374406
t.Parallel()
375407

376-
input := tester.NestedTestData{tester.Sub1NestedTestData{tester.Sub2NestedTestData{tester.Sub3NestedTestData{
377-
BasicList: []tester.BasicTestData{newBasic(), newBasic()},
378-
}}}}
408+
input := tester.NestedTestData{
409+
SubNested: tester.Sub1NestedTestData{
410+
SubNested: tester.Sub2NestedTestData{
411+
SubNested: tester.Sub3NestedTestData{
412+
BasicList: []tester.BasicTestData{newBasic(), newBasic()},
413+
}}}}
379414

380415
inputBuf, _ := newStructEncoder(0x3f, structEncoderOptionRoot(utils.RootToken)).Encode(input)
381416

tester.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func (t *observableTester) Init(callback func(v []byte) (interface{}, error)) *o
4242
go func() {
4343
for c := range consumer {
4444
if c != 0 {
45+
//TODO: Why empty branch?
46+
testPrintf("TODO: Empty branch reached\n")
4547
}
4648
}
4749
}()

0 commit comments

Comments
 (0)