...

Source file src/github.com/redis/go-redis/v9/internal/proto/writer_test.go

Documentation: github.com/redis/go-redis/v9/internal/proto

     1  package proto_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding"
     6  	"fmt"
     7  	"net"
     8  	"testing"
     9  	"time"
    10  
    11  	. "github.com/bsm/ginkgo/v2"
    12  	. "github.com/bsm/gomega"
    13  
    14  	"github.com/redis/go-redis/v9/internal/proto"
    15  	"github.com/redis/go-redis/v9/internal/util"
    16  )
    17  
    18  type MyType struct{}
    19  
    20  var _ encoding.BinaryMarshaler = (*MyType)(nil)
    21  
    22  func (t *MyType) MarshalBinary() ([]byte, error) {
    23  	return []byte("hello"), nil
    24  }
    25  
    26  var _ = Describe("WriteBuffer", func() {
    27  	var buf *bytes.Buffer
    28  	var wr *proto.Writer
    29  
    30  	BeforeEach(func() {
    31  		buf = new(bytes.Buffer)
    32  		wr = proto.NewWriter(buf)
    33  	})
    34  
    35  	It("should write args", func() {
    36  		err := wr.WriteArgs([]interface{}{
    37  			"string",
    38  			12,
    39  			34.56,
    40  			[]byte{'b', 'y', 't', 'e', 's'},
    41  			true,
    42  			nil,
    43  		})
    44  		Expect(err).NotTo(HaveOccurred())
    45  
    46  		Expect(buf.Bytes()).To(Equal([]byte("*6\r\n" +
    47  			"$6\r\nstring\r\n" +
    48  			"$2\r\n12\r\n" +
    49  			"$5\r\n34.56\r\n" +
    50  			"$5\r\nbytes\r\n" +
    51  			"$1\r\n1\r\n" +
    52  			"$0\r\n" +
    53  			"\r\n")))
    54  	})
    55  
    56  	It("should append time", func() {
    57  		tm := time.Date(2019, 1, 1, 9, 45, 10, 222125, time.UTC)
    58  		err := wr.WriteArgs([]interface{}{tm})
    59  		Expect(err).NotTo(HaveOccurred())
    60  
    61  		Expect(buf.Len()).To(Equal(41))
    62  	})
    63  
    64  	It("should append marshalable args", func() {
    65  		err := wr.WriteArgs([]interface{}{&MyType{}})
    66  		Expect(err).NotTo(HaveOccurred())
    67  
    68  		Expect(buf.Len()).To(Equal(15))
    69  	})
    70  
    71  	It("should append net.IP", func() {
    72  		ip := net.ParseIP("192.168.1.1")
    73  		err := wr.WriteArgs([]interface{}{ip})
    74  		Expect(err).NotTo(HaveOccurred())
    75  		Expect(buf.String()).To(Equal(fmt.Sprintf("*1\r\n$16\r\n%s\r\n", bytes.NewBuffer(ip))))
    76  	})
    77  })
    78  
    79  type discard struct{}
    80  
    81  func (discard) Write(b []byte) (int, error) {
    82  	return len(b), nil
    83  }
    84  
    85  func (discard) WriteString(s string) (int, error) {
    86  	return len(s), nil
    87  }
    88  
    89  func (discard) WriteByte(c byte) error {
    90  	return nil
    91  }
    92  
    93  func BenchmarkWriteBuffer_Append(b *testing.B) {
    94  	buf := proto.NewWriter(discard{})
    95  	args := []interface{}{"hello", "world", "foo", "bar"}
    96  
    97  	for i := 0; i < b.N; i++ {
    98  		err := buf.WriteArgs(args)
    99  		if err != nil {
   100  			b.Fatal(err)
   101  		}
   102  	}
   103  }
   104  
   105  var _ = Describe("WriteArg", func() {
   106  	var buf *bytes.Buffer
   107  	var wr *proto.Writer
   108  
   109  	BeforeEach(func() {
   110  		buf = new(bytes.Buffer)
   111  		wr = proto.NewWriter(buf)
   112  	})
   113  
   114  	t := time.Date(2025, 2, 8, 00, 00, 00, 0, time.UTC)
   115  
   116  	args := map[any]string{
   117  		"hello":                                "$5\r\nhello\r\n",
   118  		util.ToPtr("hello"):                    "$5\r\nhello\r\n",
   119  		(*string)(nil):                         "$0\r\n\r\n",
   120  		int(10):                                "$2\r\n10\r\n",
   121  		util.ToPtr(int(10)):                    "$2\r\n10\r\n",
   122  		(*int)(nil):                            "$1\r\n0\r\n",
   123  		int8(10):                               "$2\r\n10\r\n",
   124  		util.ToPtr(int8(10)):                   "$2\r\n10\r\n",
   125  		(*int8)(nil):                           "$1\r\n0\r\n",
   126  		int16(10):                              "$2\r\n10\r\n",
   127  		util.ToPtr(int16(10)):                  "$2\r\n10\r\n",
   128  		(*int16)(nil):                          "$1\r\n0\r\n",
   129  		int32(10):                              "$2\r\n10\r\n",
   130  		util.ToPtr(int32(10)):                  "$2\r\n10\r\n",
   131  		(*int32)(nil):                          "$1\r\n0\r\n",
   132  		int64(10):                              "$2\r\n10\r\n",
   133  		util.ToPtr(int64(10)):                  "$2\r\n10\r\n",
   134  		(*int64)(nil):                          "$1\r\n0\r\n",
   135  		uint(10):                               "$2\r\n10\r\n",
   136  		util.ToPtr(uint(10)):                   "$2\r\n10\r\n",
   137  		(*uint)(nil):                           "$1\r\n0\r\n",
   138  		uint8(10):                              "$2\r\n10\r\n",
   139  		util.ToPtr(uint8(10)):                  "$2\r\n10\r\n",
   140  		(*uint8)(nil):                          "$0\r\n\r\n",
   141  		uint16(10):                             "$2\r\n10\r\n",
   142  		util.ToPtr(uint16(10)):                 "$2\r\n10\r\n",
   143  		(*uint16)(nil):                         "$1\r\n0\r\n",
   144  		uint32(10):                             "$2\r\n10\r\n",
   145  		util.ToPtr(uint32(10)):                 "$2\r\n10\r\n",
   146  		(*uint32)(nil):                         "$1\r\n0\r\n",
   147  		uint64(10):                             "$2\r\n10\r\n",
   148  		util.ToPtr(uint64(10)):                 "$2\r\n10\r\n",
   149  		(*uint64)(nil):                         "$1\r\n0\r\n",
   150  		float32(10.3):                          "$18\r\n10.300000190734863\r\n",
   151  		util.ToPtr(float32(10.3)):              "$18\r\n10.300000190734863\r\n",
   152  		(*float32)(nil):                        "$1\r\n0\r\n",
   153  		float64(10.3):                          "$4\r\n10.3\r\n",
   154  		util.ToPtr(float64(10.3)):              "$4\r\n10.3\r\n",
   155  		(*float64)(nil):                        "$1\r\n0\r\n",
   156  		bool(true):                             "$1\r\n1\r\n",
   157  		bool(false):                            "$1\r\n0\r\n",
   158  		util.ToPtr(bool(true)):                 "$1\r\n1\r\n",
   159  		util.ToPtr(bool(false)):                "$1\r\n0\r\n",
   160  		(*bool)(nil):                           "$1\r\n0\r\n",
   161  		time.Time(t):                           "$20\r\n2025-02-08T00:00:00Z\r\n",
   162  		util.ToPtr(time.Time(t)):               "$20\r\n2025-02-08T00:00:00Z\r\n",
   163  		(*time.Time)(nil):                      "$20\r\n0001-01-01T00:00:00Z\r\n",
   164  		time.Duration(time.Second):             "$10\r\n1000000000\r\n",
   165  		util.ToPtr(time.Duration(time.Second)): "$10\r\n1000000000\r\n",
   166  		(*time.Duration)(nil):                  "$1\r\n0\r\n",
   167  		(encoding.BinaryMarshaler)(&MyType{}):  "$5\r\nhello\r\n",
   168  		(encoding.BinaryMarshaler)(nil):        "$0\r\n\r\n",
   169  	}
   170  
   171  	for arg, expect := range args {
   172  		arg, expect := arg, expect
   173  		It(fmt.Sprintf("should write arg of type %T", arg), func() {
   174  			err := wr.WriteArg(arg)
   175  			Expect(err).NotTo(HaveOccurred())
   176  			Expect(buf.String()).To(Equal(expect))
   177  		})
   178  	}
   179  })
   180  

View as plain text