Beispiel #1
0
func TestEnumWithDuplicateValuesWire(t *testing.T) {
	tests := []struct {
		e te.EnumWithDuplicateValues
		v wire.Value
	}{
		{te.EnumWithDuplicateValuesP, wire.NewValueI32(0)},
		{te.EnumWithDuplicateValuesQ, wire.NewValueI32(-1)},
		{te.EnumWithDuplicateValuesR, wire.NewValueI32(0)},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.e, tt.v, "EnumWithDuplicateValues")
	}
}
Beispiel #2
0
func TestEnumDefaultWire(t *testing.T) {
	tests := []struct {
		e te.EnumDefault
		v wire.Value
	}{
		{te.EnumDefaultFoo, wire.NewValueI32(0)},
		{te.EnumDefaultBar, wire.NewValueI32(1)},
		{te.EnumDefaultBaz, wire.NewValueI32(2)},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.e, tt.v, "EnumDefault")
	}
}
Beispiel #3
0
func (v *PrimitiveRequiredStruct) ToWire() (wire.Value, error) {
	var (
		fields [8]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	w, err = wire.NewValueBool(v.BoolField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 1, Value: w}
	i++
	w, err = wire.NewValueI8(v.ByteField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 2, Value: w}
	i++
	w, err = wire.NewValueI16(v.Int16Field), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 3, Value: w}
	i++
	w, err = wire.NewValueI32(v.Int32Field), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 4, Value: w}
	i++
	w, err = wire.NewValueI64(v.Int64Field), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 5, Value: w}
	i++
	w, err = wire.NewValueDouble(v.DoubleField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 6, Value: w}
	i++
	w, err = wire.NewValueString(v.StringField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 7, Value: w}
	i++
	if v.BinaryField == nil {
		return w, errors.New("field BinaryField of PrimitiveRequiredStruct is required")
	}
	w, err = wire.NewValueBinary(v.BinaryField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 8, Value: w}
	i++
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #4
0
func TestUnionFromWireInconsistencies(t *testing.T) {
	tests := []struct {
		desc    string
		input   wire.Value
		success *tu.Document
		failure string
	}{
		{
			desc: "multiple recognized fields",
			input: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBinary([]byte{1, 2, 3})},
				{ID: 2, Value: wire.NewValueString("hello")},
			}}),
			failure: "should have exactly one field: got 2 fields",
		},
		{
			desc: "recognized and unrecognized fields",
			input: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBinary([]byte{1, 2, 3})},
				{ID: 3, Value: wire.NewValueString("hello")},
			}}),
			success: &tu.Document{Pdf: []byte{1, 2, 3}},
		},
		{
			desc: "recognized field duplicates",
			input: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBinary([]byte{1, 2, 3})},
				{ID: 1, Value: wire.NewValueBinary([]byte{4, 5, 6})},
			}}),
			success: &tu.Document{Pdf: []byte{4, 5, 6}},
		},
		{
			desc: "only unrecognized fields",
			input: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueI32(42)}, // also a type mismatch
				{ID: 3, Value: wire.NewValueString("hello")},
			}}),
			failure: "should have exactly one field: got 0 fields",
		},
		{
			desc:    "no fields",
			input:   wire.NewValueStruct(wire.Struct{}),
			failure: "should have exactly one field: got 0 fields",
		},
	}

	for _, tt := range tests {
		var o tu.Document
		err := o.FromWire(tt.input)
		if tt.success != nil {
			if assert.NoError(t, err, tt.desc) {
				assert.Equal(t, tt.success, &o, tt.desc)
			}
		} else {
			if assert.Error(t, err, tt.desc) {
				assert.Contains(t, err.Error(), tt.failure, tt.desc)
			}
		}
	}
}
Beispiel #5
0
func TestStructFromWireUnrecognizedField(t *testing.T) {
	tests := []struct {
		desc string
		give wire.Value

		want      ts.ContactInfo
		wantError string
	}{
		{
			desc: "unknown field",
			give: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
				{ID: 2, Value: wire.NewValueI32(42)},
			}}),
			want: ts.ContactInfo{EmailAddress: "foo"},
		},
		{
			desc: "only unknown field",
			give: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueString("bar")},
			}}),
			wantError: "field EmailAddress of ContactInfo is required",
		},
		{
			desc: "wrong type for recognized field",
			give: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(42)},
				{ID: 1, Value: wire.NewValueString("foo")},
			}}),
			want: ts.ContactInfo{EmailAddress: "foo"},
		},
	}

	for _, tt := range tests {
		var o ts.ContactInfo
		err := o.FromWire(tt.give)
		if tt.wantError != "" {
			if assert.Error(t, err, tt.desc) {
				assert.Contains(t, err.Error(), tt.wantError)
			}
		} else {
			if assert.NoError(t, err, tt.desc) {
				assert.Equal(t, tt.want, o)
			}
		}
	}
}
Beispiel #6
0
func (m _Map_I32_I32_MapItemList) ForEach(f func(wire.MapItem) error) error {
	for k, v := range m {
		kw, err := wire.NewValueI32(k), error(nil)
		if err != nil {
			return err
		}
		vw, err := wire.NewValueI32(v), error(nil)
		if err != nil {
			return err
		}
		err = f(wire.MapItem{Key: kw, Value: vw})
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #7
0
func (v *ThriftTest_TestMulti_Args) ToWire() (wire.Value, error) {
	var (
		fields [6]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.Arg0 != nil {
		w, err = wire.NewValueI8(*(v.Arg0)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	if v.Arg1 != nil {
		w, err = wire.NewValueI32(*(v.Arg1)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	if v.Arg2 != nil {
		w, err = wire.NewValueI64(*(v.Arg2)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 3, Value: w}
		i++
	}
	if v.Arg3 != nil {
		w, err = wire.NewValueMap(_Map_I16_String_MapItemList(v.Arg3)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	if v.Arg4 != nil {
		w, err = v.Arg4.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 5, Value: w}
		i++
	}
	if v.Arg5 != nil {
		w, err = v.Arg5.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 6, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #8
0
func (v _Set_I32_ValueList) ForEach(f func(wire.Value) error) error {
	for x := range v {
		w, err := wire.NewValueI32(x), error(nil)
		if err != nil {
			return err
		}
		err = f(w)
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #9
0
func (m _Map_EnumWithDuplicateValues_I32_MapItemList) ForEach(f func(wire.MapItem) error) error {
	for k, v := range m {
		kw, err := k.ToWire()
		if err != nil {
			return err
		}
		vw, err := wire.NewValueI32(v), error(nil)
		if err != nil {
			return err
		}
		err = f(wire.MapItem{Key: kw, Value: vw})
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #10
0
func (v *ThriftTest_TestI32_Args) ToWire() (wire.Value, error) {
	var (
		fields [1]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.Thing != nil {
		w, err = wire.NewValueI32(*(v.Thing)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #11
0
func TestDisableEnveloperEncode(t *testing.T) {
	rand := rand.New(rand.NewSource(time.Now().Unix()))

	tests := []struct {
		value wire.Value
		want  []byte
	}{
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			[]byte{0x00},
		},
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(42)},
			}}),
			[]byte{
				0x08, 0x00, 0x01,
				0x00, 0x00, 0x00, 0x2a,
				0x00,
			},
		},
	}

	for _, tt := range tests {
		e := wire.Envelope{Value: tt.value, Type: wire.Call}
		generate(&e.Name, rand)
		generate(&e.SeqID, rand)

		var buffer bytes.Buffer
		proto := disableEnvelopingProtocol{protocol.Binary, wire.Reply}
		if !assert.NoError(t, proto.EncodeEnveloped(e, &buffer)) {
			continue
		}

		assert.Equal(t, tt.want, buffer.Bytes())

		gotE, err := proto.DecodeEnveloped(bytes.NewReader(tt.want))
		if !assert.NoError(t, err) {
			continue
		}

		assert.Equal(t, wire.Reply, gotE.Type)
		assert.True(t, wire.ValuesAreEqual(tt.value, gotE.Value))
	}
}
Beispiel #12
0
func (m _Map_I32_Map_I32_I32_MapItemList) ForEach(f func(wire.MapItem) error) error {
	for k, v := range m {
		if v == nil {
			return fmt.Errorf("invalid [%v]: value is nil", k)
		}
		kw, err := wire.NewValueI32(k), error(nil)
		if err != nil {
			return err
		}
		vw, err := wire.NewValueMap(_Map_I32_I32_MapItemList(v)), error(nil)
		if err != nil {
			return err
		}
		err = f(wire.MapItem{Key: kw, Value: vw})
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #13
0
func (v *ThriftTest_TestI32_Result) ToWire() (wire.Value, error) {
	var (
		fields [1]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.Success != nil {
		w, err = wire.NewValueI32(*(v.Success)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 0, Value: w}
		i++
	}
	if i != 1 {
		return wire.Value{}, fmt.Errorf("ThriftTest_TestI32_Result should have exactly one field: got %v fields", i)
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #14
0
func (v *HandshakeResponse) ToWire() (wire.Value, error) {
	var (
		fields [4]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	w, err = wire.NewValueString(v.Name), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 1, Value: w}
	i++
	w, err = wire.NewValueI32(v.APIVersion), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 2, Value: w}
	i++
	if v.Features == nil {
		return w, errors.New("field Features of HandshakeResponse is required")
	}
	w, err = wire.NewValueList(_List_Feature_ValueList(v.Features)), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 3, Value: w}
	i++
	if v.LibraryVersion != nil {
		w, err = wire.NewValueString(*(v.LibraryVersion)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #15
0
func (v *Node) ToWire() (wire.Value, error) {
	var (
		fields [2]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	w, err = wire.NewValueI32(v.Value), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 1, Value: w}
	i++
	if v.Tail != nil {
		w, err = v.Tail.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #16
0
func TestOptionalEnum(t *testing.T) {
	foo := te.EnumDefaultFoo

	tests := []struct {
		s te.StructWithOptionalEnum
		v wire.Value
	}{
		{
			te.StructWithOptionalEnum{E: &foo},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(0)},
			}}),
		},
		{
			te.StructWithOptionalEnum{},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.s, tt.v, "StructWithOptionalEnum")
	}
}
Beispiel #17
0
func TestClient(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	internalError := exception.ExceptionTypeInternalError
	unknownMethod := exception.ExceptionTypeUnknownMethod

	tests := []struct {
		desc string

		// Either transportError or decode* can be set.
		transportError error
		decodeEnvelope wire.Envelope
		decodeError    error

		wantError error // expected error if any
	}{
		{
			desc: "nothing went wrong",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Reply,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
		},
		{
			desc:        "decode error",
			decodeError: errors.New("great sadness"),
			wantError:   errors.New("great sadness"),
		},
		{
			desc: "internal error",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Exception,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("great sadness")},
					{ID: 2, Value: wire.NewValueI32(6)}, // Internal error
				}}),
			},
			wantError: &exception.TApplicationException{
				Message: ptr.String("great sadness"),
				Type:    &internalError,
			},
		},
		{
			desc: "unknown method",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Exception,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString(`unknown method "hello"`)},
					{ID: 2, Value: wire.NewValueI32(1)}, // Internal error
				}}),
			},
			wantError: &exception.TApplicationException{
				Message: ptr.String(`unknown method "hello"`),
				Type:    &unknownMethod,
			},
		},
		{
			desc: "unknown envelope type",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.EnvelopeType(12),
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			wantError: errUnknownEnvelopeType(12),
		},
		{
			desc:           "transport error",
			transportError: errors.New("great sadness"),
			wantError:      errors.New("great sadness"),
		},
	}

	for _, tt := range tests {
		proto := NewMockProtocol(mockCtrl)
		proto.EXPECT().EncodeEnveloped(
			wire.Envelope{
				Name:  "hello",
				Type:  wire.Call,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("world")},
				}}),
			},
			gomock.Any(),
		).Do(func(_ wire.Envelope, w io.Writer) {
			_, err := w.Write([]byte{1, 2, 3})
			assert.NoError(t, err, tt.desc)
		}).Return(nil)

		transport := envelopetest.NewMockTransport(mockCtrl)
		if tt.transportError != nil {
			transport.EXPECT().Send([]byte{1, 2, 3}).Return(nil, tt.transportError)
		} else {
			transport.EXPECT().Send([]byte{1, 2, 3}).Return([]byte{4, 5, 6}, nil)
			proto.EXPECT().DecodeEnveloped(gomock.Any()).
				Return(tt.decodeEnvelope, tt.decodeError)
		}

		client := NewClient(proto, transport)
		_, err := client.Send("hello", wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
			{ID: 1, Value: wire.NewValueString("world")},
		}}))
		assert.Equal(t, tt.wantError, err)
	}
}
Beispiel #18
0
func vi32(i int32) wire.Value {
	return wire.NewValueI32(i)
}
Beispiel #19
0
func (v ExceptionType) ToWire() (wire.Value, error) {
	return wire.NewValueI32(int32(v)), nil
}
Beispiel #20
0
func TestStructValidation(t *testing.T) {
	tests := []struct {
		desc        string
		serialize   thriftType
		deserialize wire.Value
		typ         reflect.Type // must be set if serialize is not
		wantError   string
	}{
		{
			desc: "Point: missing X",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueDouble(42)},
			}}),
			typ:       reflect.TypeOf(ts.Point{}),
			wantError: "field Y of Point is required",
		},
		{
			desc: "Point: missing Y",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueDouble(42)},
			}}),
			typ:       reflect.TypeOf(ts.Point{}),
			wantError: "field X of Point is required",
		},
		{
			desc: "Size: missing width",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueDouble(42)},
			}}),
			typ:       reflect.TypeOf(ts.Size{}),
			wantError: "field Height of Size is required",
		},
		{
			desc: "Size: missing height",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueDouble(42)},
			}}),
			typ:       reflect.TypeOf(ts.Size{}),
			wantError: "field Width of Size is required",
		},
		{
			desc:      "Frame: missing topLeft",
			serialize: &ts.Frame{Size: &ts.Size{Width: 1, Height: 2}},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueDouble(1)},
						{ID: 2, Value: wire.NewValueDouble(2)},
					}}),
				},
			}}),
			wantError: "field TopLeft of Frame is required",
		},
		{
			desc:      "Frame: missing Size",
			serialize: &ts.Frame{TopLeft: &ts.Point{X: 1, Y: 2}},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueDouble(1)},
						{ID: 2, Value: wire.NewValueDouble(2)},
					}}),
				},
			}}),
			wantError: "field Size of Frame is required",
		},
		{
			desc: "Frame: topLeft: missing y",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueDouble(1)},
					}}),
				},
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueDouble(1)},
						{ID: 2, Value: wire.NewValueDouble(2)},
					}}),
				},
			}}),
			typ:       reflect.TypeOf(ts.Frame{}),
			wantError: "field Y of Point is required",
		},
		{
			desc:        "Graph: missing edges",
			serialize:   &ts.Graph{Edges: nil},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			wantError:   "field Edges of Graph is required",
		},
		{
			desc: "Graph: edges: misssing end",
			serialize: &ts.Graph{
				Edges: []*ts.Edge{
					{StartPoint: &ts.Point{X: 1, Y: 2}, EndPoint: &ts.Point{X: 3, Y: 4}},
					{StartPoint: &ts.Point{X: 5, Y: 6}},
				},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TStruct, []wire.Value{
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{
									ID: 1,
									Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
										{ID: 1, Value: wire.NewValueDouble(1)},
										{ID: 2, Value: wire.NewValueDouble(2)},
									}}),
								},
								{
									ID: 2,
									Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
										{ID: 1, Value: wire.NewValueDouble(3)},
										{ID: 2, Value: wire.NewValueDouble(4)},
									}}),
								},
							}}),
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{
									ID: 1,
									Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
										{ID: 1, Value: wire.NewValueDouble(1)},
										{ID: 2, Value: wire.NewValueDouble(2)},
									}}),
								},
							}}),
						}),
					),
				},
			}}),
			wantError: "field EndPoint of Edge is required",
		},
		{
			desc: "User: contact: missing emailAddress",
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("hello")},
				{
					ID:    2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
				},
			}}),
			typ:       reflect.TypeOf(ts.User{}),
			wantError: "field EmailAddress of ContactInfo is required",
		},
		{
			desc: "PrimitiveContainersRequired: missing list",
			serialize: &tc.PrimitiveContainersRequired{
				SetOfInts: map[int32]struct{}{
					1: {},
					2: {},
					3: {},
				},
				MapOfIntsToDoubles: map[int64]float64{1: 2.3, 4: 5.6},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 2,
					Value: wire.NewValueSet(
						wire.ValueListFromSlice(wire.TI32, []wire.Value{
							wire.NewValueI32(1),
							wire.NewValueI32(2),
							wire.NewValueI32(3),
						}),
					),
				},
				{
					ID: 3,
					Value: wire.NewValueMap(
						wire.MapItemListFromSlice(wire.TI64, wire.TDouble, []wire.MapItem{
							{
								Key:   wire.NewValueI64(1),
								Value: wire.NewValueDouble(2.3),
							},
							{
								Key:   wire.NewValueI64(4),
								Value: wire.NewValueDouble(5.6),
							},
						}),
					),
				},
			}}),
			wantError: "field ListOfStrings of PrimitiveContainersRequired is required",
		},
		{
			desc: "PrimitiveContainersRequired: missing set",
			serialize: &tc.PrimitiveContainersRequired{
				ListOfStrings:      []string{"hello", "world"},
				MapOfIntsToDoubles: map[int64]float64{1: 2.3, 4: 5.6},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{
							wire.NewValueString("hello"),
							wire.NewValueString("world"),
						}),
					),
				},
				{
					ID: 3,
					Value: wire.NewValueMap(
						wire.MapItemListFromSlice(wire.TI64, wire.TDouble, []wire.MapItem{
							{
								Key:   wire.NewValueI64(1),
								Value: wire.NewValueDouble(2.3),
							},
							{
								Key:   wire.NewValueI64(4),
								Value: wire.NewValueDouble(5.6),
							},
						}),
					),
				},
			}}),
			wantError: "field SetOfInts of PrimitiveContainersRequired is required",
		},
		{
			desc: "PrimitiveContainersRequired: missing map",
			serialize: &tc.PrimitiveContainersRequired{
				ListOfStrings: []string{"hello", "world"},
				SetOfInts: map[int32]struct{}{
					1: {},
					2: {},
					3: {},
				},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{
							wire.NewValueString("hello"),
							wire.NewValueString("world"),
						}),
					),
				},
				{
					ID: 2,
					Value: wire.NewValueSet(
						wire.ValueListFromSlice(wire.TI32, []wire.Value{
							wire.NewValueI32(1),
							wire.NewValueI32(2),
							wire.NewValueI32(3),
						}),
					),
				},
			}}),
			wantError: "field MapOfIntsToDoubles of PrimitiveContainersRequired is required",
		},
		{
			desc:        "Document: empty",
			serialize:   &tu.Document{},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			wantError:   "Document should have exactly one field: got 0 fields",
		},
		{
			desc: "Document: multiple",
			serialize: &tu.Document{
				Pdf:       td.PDF{},
				PlainText: stringp("hello"),
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID:    1,
					Value: wire.NewValueBinary([]byte{}),
				},
				{
					ID:    2,
					Value: wire.NewValueString("hello"),
				},
			}}),
			wantError: "Document should have exactly one field: got 2 fields",
		},
		{
			desc:        "ArbitraryValue: empty",
			serialize:   &tu.ArbitraryValue{},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			wantError:   "ArbitraryValue should have exactly one field: got 0 fields",
		},
		{
			desc: "ArbitraryValue: primitives",
			serialize: &tu.ArbitraryValue{
				BoolValue:   boolp(true),
				Int64Value:  int64p(42),
				StringValue: stringp(""),
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI64(42)},
				{ID: 3, Value: wire.NewValueString("")},
			}}),
			wantError: "ArbitraryValue should have exactly one field: got 3 fields",
		},
		{
			desc: "ArbitraryValue: full",
			serialize: &tu.ArbitraryValue{
				BoolValue:   boolp(true),
				Int64Value:  int64p(42),
				StringValue: stringp(""),
				ListValue: []*tu.ArbitraryValue{
					{BoolValue: boolp(true)},
					{Int64Value: int64p(42)},
					{StringValue: stringp("")},
				},
				MapValue: map[string]*tu.ArbitraryValue{
					"bool":   {BoolValue: boolp(true)},
					"int":    {Int64Value: int64p(42)},
					"string": {StringValue: stringp("")},
				},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI64(42)},
				{ID: 3, Value: wire.NewValueString("")},
				{
					ID: 4,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TStruct, []wire.Value{
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueBool(true)},
							}}),
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 2, Value: wire.NewValueI64(42)},
							}}),
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 3, Value: wire.NewValueString("")},
							}}),
						}),
					),
				},
				{
					ID: 5,
					Value: wire.NewValueMap(
						wire.MapItemListFromSlice(wire.TBinary, wire.TStruct, []wire.MapItem{
							{
								Key: wire.NewValueString("bool"),
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 1, Value: wire.NewValueBool(true)},
								}}),
							},
							{
								Key: wire.NewValueString("int"),
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 2, Value: wire.NewValueI64(42)},
								}}),
							},
							{
								Key: wire.NewValueString("string"),
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 3, Value: wire.NewValueString("")},
								}}),
							},
						}),
					),
				},
			}}),
			wantError: "ArbitraryValue should have exactly one field: got 5 fields",
		},
		{
			desc: "ArbitraryValue: error inside a list",
			serialize: &tu.ArbitraryValue{
				ListValue: []*tu.ArbitraryValue{
					{BoolValue: boolp(true)},
					{},
				},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 4,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TStruct, []wire.Value{
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueBool(true)},
							}}),
							wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
						})),
				},
			}}),
			wantError: "ArbitraryValue should have exactly one field: got 0 fields",
		},
		{
			desc: "ArbitraryValue: error inside a map value",
			serialize: &tu.ArbitraryValue{
				MapValue: map[string]*tu.ArbitraryValue{
					"bool":  {BoolValue: boolp(true)},
					"empty": {},
				},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 5,
					Value: wire.NewValueMap(
						wire.MapItemListFromSlice(wire.TBinary, wire.TStruct, []wire.MapItem{
							{
								Key: wire.NewValueString("bool"),
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 1, Value: wire.NewValueBool(true)},
								}}),
							},
							{
								Key:   wire.NewValueString("empty"),
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
							},
						}),
					),
				},
			}}),
			wantError: "ArbitraryValue should have exactly one field: got 0 fields",
		},
		{
			desc: "FrameGroup: error inside a set",
			serialize: &td.FrameGroup{
				&ts.Frame{
					TopLeft: &ts.Point{X: 1, Y: 2},
					Size:    &ts.Size{Width: 3, Height: 4},
				},
				&ts.Frame{TopLeft: &ts.Point{X: 5, Y: 6}},
			},
			deserialize: wire.NewValueSet(
				wire.ValueListFromSlice(wire.TStruct, []wire.Value{
					wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{
									ID:    1,
									Value: wire.NewValueDouble(1),
								},
								{
									ID:    2,
									Value: wire.NewValueDouble(2),
								},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{
									ID:    1,
									Value: wire.NewValueDouble(3),
								},
								{
									ID:    2,
									Value: wire.NewValueDouble(4),
								},
							}}),
						},
					}}),
					wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{
									ID:    1,
									Value: wire.NewValueDouble(5),
								},
								{
									ID:    2,
									Value: wire.NewValueDouble(6),
								},
							}}),
						},
					}}),
				}),
			),
			wantError: "field Size of Frame is required",
		},
		{
			desc: "EdgeMap: error inside a map key",
			serialize: &td.EdgeMap{
				{
					Key:   &ts.Edge{StartPoint: &ts.Point{X: 1, Y: 2}},
					Value: &ts.Edge{StartPoint: &ts.Point{X: 3, Y: 4}, EndPoint: &ts.Point{X: 5, Y: 6}},
				},
			},
			deserialize: wire.NewValueMap(
				wire.MapItemListFromSlice(wire.TStruct, wire.TStruct, []wire.MapItem{
					{
						Key: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
							{
								ID: 1,
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 1, Value: wire.NewValueDouble(1)},
									{ID: 2, Value: wire.NewValueDouble(2)},
								}}),
							},
						}}),
						Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
							{
								ID: 1,
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 1, Value: wire.NewValueDouble(3)},
									{ID: 2, Value: wire.NewValueDouble(4)},
								}}),
							},
							{
								ID: 2,
								Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
									{ID: 1, Value: wire.NewValueDouble(5)},
									{ID: 2, Value: wire.NewValueDouble(6)},
								}}),
							},
						}}),
					},
				}),
			),
			wantError: "field EndPoint of Edge is required",
		},
	}

	for _, tt := range tests {
		var typ reflect.Type
		if tt.serialize != nil {
			typ = reflect.TypeOf(tt.serialize).Elem()
			v, err := tt.serialize.ToWire()
			if err == nil {
				err = wire.EvaluateValue(v)
			}
			if assert.Error(t, err, "%v: expected failure but got %v", tt.desc, v) {
				assert.Contains(t, err.Error(), tt.wantError, tt.desc)
			}
		} else {
			typ = tt.typ
		}

		if typ == nil {
			t.Fatalf("invalid test %q: either typ or serialize must be set", tt.desc)
		}

		x := reflect.New(typ)
		args := []reflect.Value{reflect.ValueOf(tt.deserialize)}
		e := x.MethodByName("FromWire").Call(args)[0].Interface()
		if assert.NotNil(t, e, "%v: expected failure but got %v", tt.desc, x) {
			assert.Contains(t, e.(error).Error(), tt.wantError, tt.desc)
		}
	}
}
Beispiel #21
0
func TestStructWithDefaults(t *testing.T) {
	enumDefaultFoo := te.EnumDefaultFoo
	enumDefaultBar := te.EnumDefaultBar
	enumDefaultBaz := te.EnumDefaultBaz

	tests := []struct {
		give     *ts.DefaultsStruct
		giveWire wire.Value

		wantToWire   wire.Value
		wantFromWire *ts.DefaultsStruct
	}{
		{
			give:     &ts.DefaultsStruct{},
			giveWire: wire.NewValueStruct(wire.Struct{}),

			wantToWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(100)},
				{ID: 2, Value: wire.NewValueI32(200)},
				{ID: 3, Value: wire.NewValueI32(1)},
				{ID: 4, Value: wire.NewValueI32(2)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{
							wire.NewValueString("hello"),
							wire.NewValueString("world"),
						}),
					),
				},
				{
					ID: 6,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TDouble, []wire.Value{
							wire.NewValueDouble(1.0),
							wire.NewValueDouble(2.0),
							wire.NewValueDouble(3.0),
						}),
					),
				},
				{
					ID: 7,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(100.0)},
								{ID: 2, Value: wire.NewValueDouble(200.0)},
							}}),
						},
					}}),
				},
				{
					ID: 8,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(3.0)},
								{ID: 2, Value: wire.NewValueDouble(4.0)},
							}}),
						},
					}}),
				},
			}}),
			wantFromWire: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(100),
				OptionalPrimitive: int32p(200),
				RequiredEnum:      &enumDefaultBar,
				OptionalEnum:      &enumDefaultBaz,
				RequiredList:      []string{"hello", "world"},
				OptionalList:      []float64{1.0, 2.0, 3.0},
				RequiredStruct: &ts.Frame{
					TopLeft: &ts.Point{X: 1.0, Y: 2.0},
					Size:    &ts.Size{Width: 100.0, Height: 200.0},
				},
				OptionalStruct: &ts.Edge{
					StartPoint: &ts.Point{X: 1.0, Y: 2.0},
					EndPoint:   &ts.Point{X: 3.0, Y: 4.0},
				},
			},
		},
		{
			give: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(0),
				OptionalEnum:      &enumDefaultFoo,
				RequiredList:      []string{},
			},
			giveWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(0)},
				{ID: 4, Value: wire.NewValueI32(0)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{}),
					),
				},
			}}),

			wantToWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(0)},
				{ID: 2, Value: wire.NewValueI32(200)},
				{ID: 3, Value: wire.NewValueI32(1)},
				{ID: 4, Value: wire.NewValueI32(0)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{}),
					),
				},
				{
					ID: 6,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TDouble, []wire.Value{
							wire.NewValueDouble(1.0),
							wire.NewValueDouble(2.0),
							wire.NewValueDouble(3.0),
						}),
					),
				},
				{
					ID: 7,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(100.0)},
								{ID: 2, Value: wire.NewValueDouble(200.0)},
							}}),
						},
					}}),
				},
				{
					ID: 8,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(3.0)},
								{ID: 2, Value: wire.NewValueDouble(4.0)},
							}}),
						},
					}}),
				},
			}}),
			wantFromWire: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(0),
				OptionalPrimitive: int32p(200),
				RequiredEnum:      &enumDefaultBar,
				OptionalEnum:      &enumDefaultFoo,
				RequiredList:      []string{},
				OptionalList:      []float64{1.0, 2.0, 3.0},
				RequiredStruct: &ts.Frame{
					TopLeft: &ts.Point{X: 1.0, Y: 2.0},
					Size:    &ts.Size{Width: 100.0, Height: 200.0},
				},
				OptionalStruct: &ts.Edge{
					StartPoint: &ts.Point{X: 1.0, Y: 2.0},
					EndPoint:   &ts.Point{X: 3.0, Y: 4.0},
				},
			},
		},
	}

	for _, tt := range tests {
		if gotWire, err := tt.give.ToWire(); assert.NoError(
			t, err, "%v.ToWire() failed", tt.give) {
			assert.True(
				t, wire.ValuesAreEqual(tt.wantToWire, gotWire),
				"%v.ToWire() != %v", tt.give, tt.wantToWire)
		}

		var gotFromWire ts.DefaultsStruct
		if err := gotFromWire.FromWire(tt.giveWire); assert.NoError(t, err) {
			assert.Equal(t, tt.wantFromWire, &gotFromWire)
		}
	}
}
Beispiel #22
0
func (v *PrimitiveOptionalStruct) ToWire() (wire.Value, error) {
	var (
		fields [8]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.BoolField != nil {
		w, err = wire.NewValueBool(*(v.BoolField)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	if v.ByteField != nil {
		w, err = wire.NewValueI8(*(v.ByteField)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	if v.Int16Field != nil {
		w, err = wire.NewValueI16(*(v.Int16Field)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 3, Value: w}
		i++
	}
	if v.Int32Field != nil {
		w, err = wire.NewValueI32(*(v.Int32Field)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	if v.Int64Field != nil {
		w, err = wire.NewValueI64(*(v.Int64Field)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 5, Value: w}
		i++
	}
	if v.DoubleField != nil {
		w, err = wire.NewValueDouble(*(v.DoubleField)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 6, Value: w}
		i++
	}
	if v.StringField != nil {
		w, err = wire.NewValueString(*(v.StringField)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 7, Value: w}
		i++
	}
	if v.BinaryField != nil {
		w, err = wire.NewValueBinary(v.BinaryField), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 8, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #23
0
func (v *DefaultsStruct) ToWire() (wire.Value, error) {
	var (
		fields [8]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.RequiredPrimitive == nil {
		v.RequiredPrimitive = ptr.Int32(100)
	}
	{
		w, err = wire.NewValueI32(*(v.RequiredPrimitive)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	if v.OptionalPrimitive == nil {
		v.OptionalPrimitive = ptr.Int32(200)
	}
	{
		w, err = wire.NewValueI32(*(v.OptionalPrimitive)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	if v.RequiredEnum == nil {
		v.RequiredEnum = _EnumDefault_ptr(enums.EnumDefaultBar)
	}
	{
		w, err = v.RequiredEnum.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 3, Value: w}
		i++
	}
	if v.OptionalEnum == nil {
		v.OptionalEnum = _EnumDefault_ptr(enums.EnumDefaultBaz)
	}
	{
		w, err = v.OptionalEnum.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	if v.RequiredList == nil {
		v.RequiredList = []string{"hello", "world"}
	}
	{
		w, err = wire.NewValueList(_List_String_ValueList(v.RequiredList)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 5, Value: w}
		i++
	}
	if v.OptionalList == nil {
		v.OptionalList = []float64{1, 2, 3}
	}
	{
		w, err = wire.NewValueList(_List_Double_ValueList(v.OptionalList)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 6, Value: w}
		i++
	}
	if v.RequiredStruct == nil {
		v.RequiredStruct = &Frame{Size: &Size{Height: 200, Width: 100}, TopLeft: &Point{X: 1, Y: 2}}
	}
	{
		w, err = v.RequiredStruct.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 7, Value: w}
		i++
	}
	if v.OptionalStruct == nil {
		v.OptionalStruct = &Edge{EndPoint: &Point{X: 3, Y: 4}, StartPoint: &Point{X: 1, Y: 2}}
	}
	{
		w, err = v.OptionalStruct.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 8, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Beispiel #24
0
func TestClient(t *testing.T) {
	tests := []struct {
		desc                 string
		giveRequestBody      envelope.Enveloper // outgoing request body
		giveResponseEnvelope *wire.Envelope     // returned on DecodeEnveloped()
		giveResponseBody     *wire.Value        // return on Decode()
		clientOptions        []ClientOption

		expectCall          bool           // whether outbound.Call is expected
		wantRequestEnvelope *wire.Envelope // expect EncodeEnveloped(x)
		wantRequestBody     *wire.Value    // expect Encode(x)
		wantError           string         // whether an error is expected
	}{
		{
			desc:            "happy case",
			clientOptions:   []ClientOption{Enveloped},
			giveRequestBody: fakeEnveloper(wire.Call),
			wantRequestEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Call,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			expectCall: true,
			giveResponseEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Reply,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
		},
		{
			desc:             "happy case without enveloping",
			giveRequestBody:  fakeEnveloper(wire.Call),
			wantRequestBody:  valueptr(wire.NewValueStruct(wire.Struct{})),
			expectCall:       true,
			giveResponseBody: valueptr(wire.NewValueStruct(wire.Struct{})),
		},
		{
			desc:            "wrong envelope type for request",
			clientOptions:   []ClientOption{Enveloped},
			giveRequestBody: fakeEnveloper(wire.Reply),
			wantError: `failed to encode "thrift" request body for procedure ` +
				`"MyService::someMethod" of service "service": unexpected envelope type: Reply`,
		},
		{
			desc:            "TApplicationException",
			clientOptions:   []ClientOption{Enveloped},
			giveRequestBody: fakeEnveloper(wire.Call),
			wantRequestEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Call,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			expectCall: true,
			giveResponseEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Exception,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("great sadness")},
					{ID: 2, Value: wire.NewValueI32(7)},
				}}),
			},
			wantError: `thrift request to procedure "MyService::someMethod" of ` +
				`service "service" encountered an internal failure: ` +
				"TApplicationException{Message: great sadness, Type: PROTOCOL_ERROR}",
		},
		{
			desc:            "wrong envelope type for response",
			clientOptions:   []ClientOption{Enveloped},
			giveRequestBody: fakeEnveloper(wire.Call),
			wantRequestEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Call,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			expectCall: true,
			giveResponseEnvelope: &wire.Envelope{
				Name:  "someMethod",
				SeqID: 1,
				Type:  wire.Call,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			wantError: `failed to decode "thrift" response body for procedure ` +
				`"MyService::someMethod" of service "service": unexpected envelope type: Call`,
		},
	}

	for _, tt := range tests {
		mockCtrl := gomock.NewController(t)
		defer mockCtrl.Finish()

		proto := NewMockProtocol(mockCtrl)

		if tt.wantRequestEnvelope != nil {
			proto.EXPECT().EncodeEnveloped(*tt.wantRequestEnvelope, gomock.Any()).
				Do(func(_ wire.Envelope, w io.Writer) {
					_, err := w.Write([]byte("irrelevant"))
					require.NoError(t, err, "Write() failed")
				}).Return(nil)
		}

		if tt.wantRequestBody != nil {
			proto.EXPECT().Encode(*tt.wantRequestBody, gomock.Any()).
				Do(func(_ wire.Value, w io.Writer) {
					_, err := w.Write([]byte("irrelevant"))
					require.NoError(t, err, "Write() failed")
				}).Return(nil)
		}

		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()

		trans := transporttest.NewMockUnaryOutbound(mockCtrl)
		if tt.expectCall {
			trans.EXPECT().Call(ctx,
				transporttest.NewRequestMatcher(t, &transport.Request{
					Caller:    "caller",
					Service:   "service",
					Encoding:  Encoding,
					Procedure: "MyService::someMethod",
					Body:      bytes.NewReader([]byte("irrelevant")),
				}),
			).Return(&transport.Response{
				Body: ioutil.NopCloser(bytes.NewReader([]byte("irrelevant"))),
			}, nil)
		}

		if tt.giveResponseEnvelope != nil {
			proto.EXPECT().DecodeEnveloped(gomock.Any()).Return(*tt.giveResponseEnvelope, nil)
		}

		if tt.giveResponseBody != nil {
			proto.EXPECT().Decode(gomock.Any(), wire.TStruct).Return(*tt.giveResponseBody, nil)
		}

		opts := tt.clientOptions
		opts = append(opts, Protocol(proto))
		c := New(Config{
			Service: "MyService",
			Channel: channel.MultiOutbound("caller", "service",
				transport.Outbounds{
					Unary: trans,
				}),
		}, opts...)

		_, _, err := c.Call(ctx, nil, tt.giveRequestBody)
		if tt.wantError != "" {
			if assert.Error(t, err, "%v: expected failure", tt.desc) {
				assert.Contains(t, err.Error(), tt.wantError, "%v: error mismatch", tt.desc)
			}
		} else {
			assert.NoError(t, err, "%v: expected success", tt.desc)
		}
	}
}
Beispiel #25
0
// ReadValue reads a value off the given type off the wire starting at the
// given offset.
//
// Returns the Value, the new offset, and an error if there was a decode error.
func (br *Reader) ReadValue(t wire.Type, off int64) (wire.Value, int64, error) {
	switch t {
	case wire.TBool:
		b, off, err := br.readByte(off)
		if err != nil {
			return wire.Value{}, off, err
		}

		if b != 0 && b != 1 {
			return wire.Value{}, off, decodeErrorf(
				"invalid value %q for bool field", b,
			)
		}

		return wire.NewValueBool(b == 1), off, nil

	case wire.TI8:
		b, off, err := br.readByte(off)
		return wire.NewValueI8(int8(b)), off, err

	case wire.TDouble:
		value, off, err := br.readInt64(off)
		d := math.Float64frombits(uint64(value))
		return wire.NewValueDouble(d), off, err

	case wire.TI16:
		n, off, err := br.readInt16(off)
		return wire.NewValueI16(n), off, err

	case wire.TI32:
		n, off, err := br.readInt32(off)
		return wire.NewValueI32(n), off, err

	case wire.TI64:
		n, off, err := br.readInt64(off)
		return wire.NewValueI64(n), off, err

	case wire.TBinary:
		v, off, err := br.readBytes(off)
		return wire.NewValueBinary(v), off, err

	case wire.TStruct:
		s, off, err := br.readStruct(off)
		return wire.NewValueStruct(s), off, err

	case wire.TMap:
		m, off, err := br.readMap(off)
		return wire.NewValueMap(m), off, err

	case wire.TSet:
		s, off, err := br.readSet(off)
		return wire.NewValueSet(s), off, err

	case wire.TList:
		l, off, err := br.readList(off)
		return wire.NewValueList(l), off, err

	default:
		return wire.Value{}, off, decodeErrorf("unknown ttype %v", t)
	}
}
Beispiel #26
0
func TestReadReply(t *testing.T) {
	tests := []struct {
		desc      string
		bs        []byte
		want      wire.Value
		wantSeqID int32
		wantErr   string
	}{
		{
			desc:    "Invalid envelope",
			bs:      []byte{0},
			wantErr: "unexpected EOF",
		},
		{
			desc: "Unexpected envelope type",
			bs: []byte{
				0x80, 0x01, 0x00, 0x01, // version|type:4 = 1 | call
				0x00, 0x00, 0x00, 0x03, // name length = 3
				'a', 'b', 'c', // "abc"
				0x00, 0x00, 0x04, 0xd2, // seqID:4 = 1234

				// <struct>
				0x00, // stop
			},
			want:      wire.NewValueStruct(wire.Struct{}),
			wantSeqID: 1234,
			wantErr:   "unknown envelope",
		},
		{
			desc: "Valid reply",
			bs: []byte{
				0x80, 0x01, 0x00, 0x02, // version|type:4 = 2 | reply
				0x00, 0x00, 0x00, 0x03, // name length = 3
				'a', 'b', 'c', // "abc"
				0x00, 0x00, 0x04, 0xd2, // seqID:4 = 1234

				// <struct>
				0x00, // stop
			},
			want:      wire.NewValueStruct(wire.Struct{}),
			wantSeqID: 1234,
		},
		{
			desc: "Invalid exception",
			bs: []byte{
				0x80, 0x01, 0x00, 0x03, // version|type:4 = 3 | exception
				0x00, 0x00, 0x00, 0x03, // name length = 3
				'a', 'b', 'c', // "abc"
				0x00, 0x00, 0x04, 0xd2, // seqID:4 = 1234

				// <struct> (invalid)
				0x08,       // type:1 = i32
				0x00, 0x01, // id:2 = 1
				0x00, 0x00, 0x00, 0x01, // value = 1
				0x00, // stop
			},
			want: wire.NewValueStruct(wire.Struct{
				Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueI32(1)},
				},
			}),
			wantSeqID: 1234,
			// TODO: This should probably fail to decode. Right now, it's being ignored.
			// wantErr:   "failed to decode exception",
			wantErr: "TApplicationException{}",
		},
		{
			desc: "Valid exception",
			bs: []byte{
				0x80, 0x01, 0x00, 0x03, // version|type:4 = 3 | exception
				0x00, 0x00, 0x00, 0x03, // name length = 3
				'a', 'b', 'c', // "abc"
				0x00, 0x00, 0x04, 0xd2, // seqID:4 = 1234

				// <struct>
				0x0b,       // type:1 = string
				0x00, 0x01, // id:2 = 1
				0x00, 0x00, 0x00, 0x06, // length = 3
				'e', 'r', 'r', 'M', 's', 'g', // "errMsg"
				0x08,       // type:1 = i32
				0x00, 0x02, // id:2 = 2
				0x00, 0x00, 0x00, 0x01, // value = 1 (unknown method)
				0x00, // stop
			},
			want: wire.NewValueStruct(wire.Struct{
				Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("errMsg")},
					{ID: 2, Value: wire.NewValueI32(1)},
				},
			}),
			wantSeqID: 1234,
			wantErr:   "TApplicationException{Message: errMsg, Type: UNKNOWN_METHOD}",
		},
	}

	for _, tt := range tests {
		result, seqID, err := ReadReply(protocol.Binary, bytes.NewReader(tt.bs))
		if tt.wantErr != "" {
			if assert.Error(t, err, tt.desc) {
				assert.Contains(t, err.Error(), tt.wantErr, "%v: error mismatch", tt.desc)
			}
		} else {
			assert.NoError(t, err, tt.desc)
		}
		assert.Equal(t, tt.want, result, "%v: result mismatch", tt.desc)
		assert.Equal(t, tt.wantSeqID, seqID, "%v: seqID mismatch", tt.desc)
	}
}
Beispiel #27
0
func TestCrazyTown(t *testing.T) {
	tests := []struct {
		desc string
		x    tc.ContainersOfContainers
		v    wire.Value
	}{
		{
			"ListOfLists",
			tc.ContainersOfContainers{
				ListOfLists: [][]int32{
					{1, 2, 3},
					{4, 5, 6},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueList(
					wire.ValueListFromSlice(wire.TList, []wire.Value{
						wire.NewValueList(
							wire.ValueListFromSlice(wire.TI32, []wire.Value{
								wire.NewValueI32(1),
								wire.NewValueI32(2),
								wire.NewValueI32(3),
							}),
						),
						wire.NewValueList(
							wire.ValueListFromSlice(wire.TI32, []wire.Value{
								wire.NewValueI32(4),
								wire.NewValueI32(5),
								wire.NewValueI32(6),
							}),
						),
					}),
				)},
			}}),
		},
		{
			"ListOfSets",
			tc.ContainersOfContainers{
				ListOfSets: []map[int32]struct{}{
					{
						1: struct{}{},
						2: struct{}{},
						3: struct{}{},
					},
					{
						4: struct{}{},
						5: struct{}{},
						6: struct{}{},
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueList(
					wire.ValueListFromSlice(wire.TSet, []wire.Value{
						wire.NewValueSet(
							wire.ValueListFromSlice(wire.TI32, []wire.Value{
								wire.NewValueI32(1),
								wire.NewValueI32(2),
								wire.NewValueI32(3),
							}),
						),
						wire.NewValueSet(
							wire.ValueListFromSlice(wire.TI32, []wire.Value{
								wire.NewValueI32(4),
								wire.NewValueI32(5),
								wire.NewValueI32(6),
							}),
						),
					}),
				)},
			}}),
		},
		{
			"ListOfMaps",
			tc.ContainersOfContainers{
				ListOfMaps: []map[int32]int32{
					{
						1: 100,
						2: 200,
						3: 300,
					},
					{
						4: 400,
						5: 500,
						6: 600,
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 3, Value: wire.NewValueList(
					wire.ValueListFromSlice(wire.TMap, []wire.Value{
						wire.NewValueMap(
							wire.MapItemListFromSlice(wire.TI32, wire.TI32, []wire.MapItem{
								{Key: wire.NewValueI32(1), Value: wire.NewValueI32(100)},
								{Key: wire.NewValueI32(2), Value: wire.NewValueI32(200)},
								{Key: wire.NewValueI32(3), Value: wire.NewValueI32(300)},
							}),
						),
						wire.NewValueMap(
							wire.MapItemListFromSlice(wire.TI32, wire.TI32, []wire.MapItem{
								{Key: wire.NewValueI32(4), Value: wire.NewValueI32(400)},
								{Key: wire.NewValueI32(5), Value: wire.NewValueI32(500)},
								{Key: wire.NewValueI32(6), Value: wire.NewValueI32(600)},
							}),
						),
					}),
				)},
			}}),
		},
		{
			"SetOfSets",
			tc.ContainersOfContainers{
				SetOfSets: []map[string]struct{}{
					{
						"1": struct{}{},
						"2": struct{}{},
						"3": struct{}{},
					},
					{
						"4": struct{}{},
						"5": struct{}{},
						"6": struct{}{},
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 4, Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TSet, []wire.Value{
						wire.NewValueSet(
							wire.ValueListFromSlice(wire.TBinary, []wire.Value{
								wire.NewValueString("1"),
								wire.NewValueString("2"),
								wire.NewValueString("3"),
							}),
						),
						wire.NewValueSet(
							wire.ValueListFromSlice(wire.TBinary, []wire.Value{
								wire.NewValueString("4"),
								wire.NewValueString("5"),
								wire.NewValueString("6"),
							}),
						),
					}),
				)},
			}}),
		},
		{
			"SetOfLists",
			tc.ContainersOfContainers{
				SetOfLists: [][]string{
					{"1", "2", "3"},
					{"4", "5", "6"},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 5, Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TList, []wire.Value{
						wire.NewValueList(
							wire.ValueListFromSlice(wire.TBinary, []wire.Value{
								wire.NewValueString("1"),
								wire.NewValueString("2"),
								wire.NewValueString("3"),
							}),
						),
						wire.NewValueList(
							wire.ValueListFromSlice(wire.TBinary, []wire.Value{
								wire.NewValueString("4"),
								wire.NewValueString("5"),
								wire.NewValueString("6"),
							}),
						),
					}),
				)},
			}}),
		},
		{
			"SetOfMaps",
			tc.ContainersOfContainers{
				SetOfMaps: []map[string]string{
					{
						"1": "one",
						"2": "two",
						"3": "three",
					},
					{
						"4": "four",
						"5": "five",
						"6": "six",
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 6, Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TMap, []wire.Value{
						wire.NewValueMap(
							wire.MapItemListFromSlice(wire.TBinary, wire.TBinary, []wire.MapItem{
								{Key: wire.NewValueString("1"), Value: wire.NewValueString("one")},
								{Key: wire.NewValueString("2"), Value: wire.NewValueString("two")},
								{Key: wire.NewValueString("3"), Value: wire.NewValueString("three")},
							}),
						),
						wire.NewValueMap(
							wire.MapItemListFromSlice(wire.TBinary, wire.TBinary, []wire.MapItem{
								{Key: wire.NewValueString("4"), Value: wire.NewValueString("four")},
								{Key: wire.NewValueString("5"), Value: wire.NewValueString("five")},
								{Key: wire.NewValueString("6"), Value: wire.NewValueString("six")},
							}),
						),
					}),
				)},
			}}),
		},
		{
			"MapOfMapToInt",
			tc.ContainersOfContainers{
				MapOfMapToInt: []struct {
					Key   map[string]int32
					Value int64
				}{
					{
						Key:   map[string]int32{"1": 1, "2": 2, "3": 3},
						Value: 123,
					},
					{
						Key:   map[string]int32{"4": 4, "5": 5, "6": 6},
						Value: 456,
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 7, Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TMap, wire.TI64, []wire.MapItem{
						{
							Key: wire.NewValueMap(
								wire.MapItemListFromSlice(wire.TBinary, wire.TI32, []wire.MapItem{
									{Key: wire.NewValueString("1"), Value: wire.NewValueI32(1)},
									{Key: wire.NewValueString("2"), Value: wire.NewValueI32(2)},
									{Key: wire.NewValueString("3"), Value: wire.NewValueI32(3)},
								}),
							),
							Value: wire.NewValueI64(123),
						},
						{
							Key: wire.NewValueMap(
								wire.MapItemListFromSlice(wire.TBinary, wire.TI32, []wire.MapItem{
									{Key: wire.NewValueString("4"), Value: wire.NewValueI32(4)},
									{Key: wire.NewValueString("5"), Value: wire.NewValueI32(5)},
									{Key: wire.NewValueString("6"), Value: wire.NewValueI32(6)},
								}),
							),
							Value: wire.NewValueI64(456),
						},
					}),
				)},
			}}),
		},
		{
			"MapOfListToSet",
			tc.ContainersOfContainers{
				MapOfListToSet: []struct {
					Key   []int32
					Value map[int64]struct{}
				}{
					{
						Key: []int32{1, 2, 3},
						Value: map[int64]struct{}{
							1: {},
							2: {},
							3: {},
						},
					},
					{
						Key: []int32{4, 5, 6},
						Value: map[int64]struct{}{
							4: {},
							5: {},
							6: {},
						},
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 8, Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TList, wire.TSet, []wire.MapItem{
						{
							Key: wire.NewValueList(
								wire.ValueListFromSlice(wire.TI32, []wire.Value{
									wire.NewValueI32(1),
									wire.NewValueI32(2),
									wire.NewValueI32(3),
								}),
							),
							Value: wire.NewValueSet(
								wire.ValueListFromSlice(wire.TI64, []wire.Value{
									wire.NewValueI64(1),
									wire.NewValueI64(2),
									wire.NewValueI64(3),
								}),
							),
						},
						{
							Key: wire.NewValueList(
								wire.ValueListFromSlice(wire.TI32, []wire.Value{
									wire.NewValueI32(4),
									wire.NewValueI32(5),
									wire.NewValueI32(6),
								}),
							),
							Value: wire.NewValueSet(
								wire.ValueListFromSlice(wire.TI64, []wire.Value{
									wire.NewValueI64(4),
									wire.NewValueI64(5),
									wire.NewValueI64(6),
								}),
							),
						},
					}),
				)},
			}}),
		},
		{
			"MapOfSetToListOfDouble",
			tc.ContainersOfContainers{
				MapOfSetToListOfDouble: []struct {
					Key   map[int32]struct{}
					Value []float64
				}{
					{
						Key: map[int32]struct{}{
							1: {},
							2: {},
							3: {},
						},
						Value: []float64{1.0, 2.0, 3.0},
					},
					{
						Key: map[int32]struct{}{
							4: {},
							5: {},
							6: {},
						},
						Value: []float64{4.0, 5.0, 6.0},
					},
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 9, Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TSet, wire.TList, []wire.MapItem{
						{
							Key: wire.NewValueSet(
								wire.ValueListFromSlice(wire.TI32, []wire.Value{
									wire.NewValueI32(1),
									wire.NewValueI32(2),
									wire.NewValueI32(3),
								}),
							),
							Value: wire.NewValueList(
								wire.ValueListFromSlice(wire.TDouble, []wire.Value{
									wire.NewValueDouble(1.0),
									wire.NewValueDouble(2.0),
									wire.NewValueDouble(3.0),
								}),
							),
						},
						{
							Key: wire.NewValueSet(
								wire.ValueListFromSlice(wire.TI32, []wire.Value{
									wire.NewValueI32(4),
									wire.NewValueI32(5),
									wire.NewValueI32(6),
								}),
							),
							Value: wire.NewValueList(
								wire.ValueListFromSlice(wire.TDouble, []wire.Value{
									wire.NewValueDouble(4.0),
									wire.NewValueDouble(5.0),
									wire.NewValueDouble(6.0),
								}),
							),
						},
					}),
				)},
			}}),
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.x, tt.v, tt.desc)
	}
}
Beispiel #28
0
func TestCollectionsOfPrimitives(t *testing.T) {
	tests := []struct {
		desc string
		p    tc.PrimitiveContainers
		v    wire.Value
	}{
		// Lists /////////////////////////////////////////////////////////////
		{
			"empty list",
			tc.PrimitiveContainers{ListOfInts: []int64{}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID:    2,
				Value: wire.NewValueList(wire.ValueListFromSlice(wire.TI64, []wire.Value{})),
			}}}),
		},
		{
			"list of ints",
			tc.PrimitiveContainers{ListOfInts: []int64{1, 2, 3}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 2,
				Value: wire.NewValueList(
					wire.ValueListFromSlice(wire.TI64, []wire.Value{
						wire.NewValueI64(1),
						wire.NewValueI64(2),
						wire.NewValueI64(3),
					}),
				),
			}}}),
		},
		{
			"list of binary",
			tc.PrimitiveContainers{
				ListOfBinary: [][]byte{
					[]byte("foo"), {}, []byte("bar"), []byte("baz"),
				},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 1,
				Value: wire.NewValueList(
					wire.ValueListFromSlice(wire.TBinary, []wire.Value{
						wire.NewValueBinary([]byte("foo")),
						wire.NewValueBinary([]byte{}),
						wire.NewValueBinary([]byte("bar")),
						wire.NewValueBinary([]byte("baz")),
					}),
				),
			}}}),
		},
		// Sets //////////////////////////////////////////////////////////////
		{
			"empty set",
			tc.PrimitiveContainers{SetOfStrings: map[string]struct{}{}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 3,
				Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TBinary, []wire.Value{}),
				),
			}}}),
		},
		{
			"set of strings",
			tc.PrimitiveContainers{SetOfStrings: map[string]struct{}{
				"foo": {},
				"bar": {},
				"baz": {},
			}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 3,
				Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TBinary, []wire.Value{
						wire.NewValueString("foo"),
						wire.NewValueString("bar"),
						wire.NewValueString("baz"),
					}),
				),
			}}}),
		},
		{
			"set of bytes",
			tc.PrimitiveContainers{SetOfBytes: map[int8]struct{}{
				-1:  {},
				1:   {},
				125: {},
			}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 4,
				Value: wire.NewValueSet(
					wire.ValueListFromSlice(wire.TI8, []wire.Value{
						wire.NewValueI8(-1),
						wire.NewValueI8(1),
						wire.NewValueI8(125),
					}),
				),
			}}}),
		},
		// Maps //////////////////////////////////////////////////////////////
		{
			"empty map",
			tc.PrimitiveContainers{MapOfStringToBool: map[string]bool{}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 6,
				Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TBinary, wire.TBool, []wire.MapItem{}),
				),
			}}}),
		},
		{
			"map of int to string",
			tc.PrimitiveContainers{MapOfIntToString: map[int32]string{
				-1:    "foo",
				1234:  "bar",
				-9876: "baz",
			}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 5,
				Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TI32, wire.TBinary, []wire.MapItem{
						{Key: wire.NewValueI32(-1), Value: wire.NewValueString("foo")},
						{Key: wire.NewValueI32(1234), Value: wire.NewValueString("bar")},
						{Key: wire.NewValueI32(-9876), Value: wire.NewValueString("baz")},
					}),
				),
			}}}),
		},
		{
			"map of string to bool",
			tc.PrimitiveContainers{MapOfStringToBool: map[string]bool{
				"foo": true,
				"bar": false,
				"baz": true,
			}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
				ID: 6,
				Value: wire.NewValueMap(
					wire.MapItemListFromSlice(wire.TBinary, wire.TBool, []wire.MapItem{
						{Key: wire.NewValueString("foo"), Value: wire.NewValueBool(true)},
						{Key: wire.NewValueString("bar"), Value: wire.NewValueBool(false)},
						{Key: wire.NewValueString("baz"), Value: wire.NewValueBool(true)},
					}),
				),
			}}}),
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.p, tt.v, tt.desc)
	}
}
Beispiel #29
0
func TestEnumContainers(t *testing.T) {
	tests := []struct {
		s tc.EnumContainers
		v wire.Value
	}{
		{
			tc.EnumContainers{
				ListOfEnums: []te.EnumDefault{
					te.EnumDefaultFoo,
					te.EnumDefaultBar,
				},
			},
			singleFieldStruct(1, wire.NewValueList(
				wire.ValueListFromSlice(wire.TI32, []wire.Value{
					wire.NewValueI32(0),
					wire.NewValueI32(1),
				}),
			)),
		},
		{
			tc.EnumContainers{
				SetOfEnums: map[te.EnumWithValues]struct{}{
					te.EnumWithValuesX: {},
					te.EnumWithValuesZ: {},
				},
			},
			singleFieldStruct(2, wire.NewValueSet(
				wire.ValueListFromSlice(wire.TI32, []wire.Value{
					wire.NewValueI32(123),
					wire.NewValueI32(789),
				}),
			)),
		},
		{
			tc.EnumContainers{
				MapOfEnums: map[te.EnumWithDuplicateValues]int32{
					te.EnumWithDuplicateValuesP: 123,
					te.EnumWithDuplicateValuesQ: 456,
				},
			},
			singleFieldStruct(3, wire.NewValueMap(
				wire.MapItemListFromSlice(wire.TI32, wire.TI32, []wire.MapItem{
					{Key: wire.NewValueI32(0), Value: wire.NewValueI32(123)},
					{Key: wire.NewValueI32(-1), Value: wire.NewValueI32(456)},
				}),
			)),
		},
		{
			// this is the same as the one above except we're using "R" intsead
			// of "P" (they both have the same value)
			tc.EnumContainers{
				MapOfEnums: map[te.EnumWithDuplicateValues]int32{
					te.EnumWithDuplicateValuesR: 123,
					te.EnumWithDuplicateValuesQ: 456,
				},
			},
			singleFieldStruct(3, wire.NewValueMap(

				wire.MapItemListFromSlice(wire.TI32, wire.TI32, []wire.MapItem{
					{Key: wire.NewValueI32(0), Value: wire.NewValueI32(123)},
					{Key: wire.NewValueI32(-1), Value: wire.NewValueI32(456)},
				}),
			)),
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, &tt.s, tt.v, "EnumContainers")
	}
}
Beispiel #30
0
func (v MyEnum2) ToWire() (wire.Value, error) {
	return wire.NewValueI32(int32(v)), nil
}