1package proto_test
2
3import (
4	"bytes"
5	"encoding"
6	"testing"
7	"time"
8
9	"github.com/go-redis/redis/v8/internal/proto"
10
11	. "github.com/onsi/ginkgo"
12	. "github.com/onsi/gomega"
13)
14
15type MyType struct{}
16
17var _ encoding.BinaryMarshaler = (*MyType)(nil)
18
19func (t *MyType) MarshalBinary() ([]byte, error) {
20	return []byte("hello"), nil
21}
22
23var _ = Describe("WriteBuffer", func() {
24	var buf *bytes.Buffer
25	var wr *proto.Writer
26
27	BeforeEach(func() {
28		buf = new(bytes.Buffer)
29		wr = proto.NewWriter(buf)
30	})
31
32	It("should write args", func() {
33		err := wr.WriteArgs([]interface{}{
34			"string",
35			12,
36			34.56,
37			[]byte{'b', 'y', 't', 'e', 's'},
38			true,
39			nil,
40		})
41		Expect(err).NotTo(HaveOccurred())
42
43		Expect(buf.Bytes()).To(Equal([]byte("*6\r\n" +
44			"$6\r\nstring\r\n" +
45			"$2\r\n12\r\n" +
46			"$5\r\n34.56\r\n" +
47			"$5\r\nbytes\r\n" +
48			"$1\r\n1\r\n" +
49			"$0\r\n" +
50			"\r\n")))
51	})
52
53	It("should append time", func() {
54		tm := time.Date(2019, 01, 01, 9, 45, 10, 222125, time.UTC)
55		err := wr.WriteArgs([]interface{}{tm})
56		Expect(err).NotTo(HaveOccurred())
57
58		Expect(buf.Len()).To(Equal(41))
59	})
60
61	It("should append marshalable args", func() {
62		err := wr.WriteArgs([]interface{}{&MyType{}})
63		Expect(err).NotTo(HaveOccurred())
64
65		Expect(buf.Len()).To(Equal(15))
66	})
67})
68
69type discard struct{}
70
71func (discard) Write(b []byte) (int, error) {
72	return len(b), nil
73}
74
75func (discard) WriteString(s string) (int, error) {
76	return len(s), nil
77}
78
79func (discard) WriteByte(c byte) error {
80	return nil
81}
82
83func BenchmarkWriteBuffer_Append(b *testing.B) {
84	buf := proto.NewWriter(discard{})
85	args := []interface{}{"hello", "world", "foo", "bar"}
86
87	for i := 0; i < b.N; i++ {
88		err := buf.WriteArgs(args)
89		if err != nil {
90			b.Fatal(err)
91		}
92	}
93}
94