github.com/segmentio/encoding@v0.4.0/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  }