Example #1
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
}
Example #2
0
func (v *UnionCollision2) ToWire() (wire.Value, error) {
	var (
		fields [2]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.CollisionField != nil {
		w, err = wire.NewValueBool(*(v.CollisionField)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	if v.CollisionField2 != nil {
		w, err = wire.NewValueString(*(v.CollisionField2)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	if i != 1 {
		return wire.Value{}, fmt.Errorf("UnionCollision2 should have exactly one field: got %v fields", i)
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Example #3
0
func (v *Function) ToWire() (wire.Value, error) {
	var (
		fields [6]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.NewValueString(v.ThriftName), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 2, Value: w}
	i++
	if v.Arguments == nil {
		return w, errors.New("field Arguments of Function is required")
	}
	w, err = wire.NewValueList(_List_Argument_ValueList(v.Arguments)), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 3, Value: w}
	i++
	if v.ReturnType != nil {
		w, err = v.ReturnType.ToWire()
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	if v.Exceptions != nil {
		w, err = wire.NewValueList(_List_Argument_ValueList(v.Exceptions)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 5, Value: w}
		i++
	}
	if v.OneWay != nil {
		w, err = wire.NewValueBool(*(v.OneWay)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 6, Value: w}
		i++
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Example #4
0
func (v *ArbitraryValue) ToWire() (wire.Value, error) {
	var (
		fields [5]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	if v.BoolValue != nil {
		w, err = wire.NewValueBool(*(v.BoolValue)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 1, Value: w}
		i++
	}
	if v.Int64Value != nil {
		w, err = wire.NewValueI64(*(v.Int64Value)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 2, Value: w}
		i++
	}
	if v.StringValue != nil {
		w, err = wire.NewValueString(*(v.StringValue)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 3, Value: w}
		i++
	}
	if v.ListValue != nil {
		w, err = wire.NewValueList(_List_ArbitraryValue_ValueList(v.ListValue)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 4, Value: w}
		i++
	}
	if v.MapValue != nil {
		w, err = wire.NewValueMap(_Map_String_ArbitraryValue_MapItemList(v.MapValue)), error(nil)
		if err != nil {
			return w, err
		}
		fields[i] = wire.Field{ID: 5, Value: w}
		i++
	}
	if i != 1 {
		return wire.Value{}, fmt.Errorf("ArbitraryValue should have exactly one field: got %v fields", i)
	}
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Example #5
0
func (m _Map_String_Bool_MapItemList) ForEach(f func(wire.MapItem) error) error {
	for k, v := range m {
		kw, err := wire.NewValueString(k), error(nil)
		if err != nil {
			return err
		}
		vw, err := wire.NewValueBool(v), error(nil)
		if err != nil {
			return err
		}
		err = f(wire.MapItem{Key: kw, Value: vw})
		if err != nil {
			return err
		}
	}
	return nil
}
Example #6
0
func (v *StructCollision2) ToWire() (wire.Value, error) {
	var (
		fields [2]wire.Field
		i      int = 0
		w      wire.Value
		err    error
	)
	w, err = wire.NewValueBool(v.CollisionField), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 1, Value: w}
	i++
	w, err = wire.NewValueString(v.CollisionField2), error(nil)
	if err != nil {
		return w, err
	}
	fields[i] = wire.Field{ID: 2, Value: w}
	i++
	return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil
}
Example #7
0
func vbool(b bool) wire.Value {
	return wire.NewValueBool(b)
}
Example #8
0
func TestArgsAndResultValidation(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: "SetValue: args: value: empty",
			serialize: tv.KeyValue_SetValue_Helper.Args(
				(*tv.Key)(stringp("foo")),
				&tu.ArbitraryValue{},
			),
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
				{
					ID:    2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
				},
			}}),
			wantError: "ArbitraryValue should have exactly one field: got 0 fields",
		},
		{
			desc: "SetValueV2: args: missing value",
			typ:  reflect.TypeOf(tv.KeyValue_SetValueV2_Args{}),
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueBool(true)},
					}}),
				},
			}}),
			wantError: "field Key of KeyValue_SetValueV2_Args is required",
		},
		{
			desc: "SetValueV2: args: missing key",
			typ:  reflect.TypeOf(tv.KeyValue_SetValueV2_Args{}),
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
			}}),
			wantError: "field Value of KeyValue_SetValueV2_Args is required",
		},
		{
			desc:        "getValue: result: empty",
			serialize:   &tv.KeyValue_GetValue_Result{},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			wantError:   "KeyValue_GetValue_Result should have exactly one field: got 0 fields",
		},
		{
			desc: "getValue: result: multiple",
			serialize: &tv.KeyValue_GetValue_Result{
				DoesNotExist: &tx.DoesNotExistException{Key: "foo"},
				Success:      &tu.ArbitraryValue{BoolValue: boolp(true)},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 0,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueBool(true)},
					}}),
				},
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueString("foo")},
					}}),
				},
			}}),
			wantError: "KeyValue_GetValue_Result should have exactly one field: got 2 fields",
		},
		{
			desc: "deleteValue: result: multiple",
			serialize: &tv.KeyValue_DeleteValue_Result{
				DoesNotExist:  &tx.DoesNotExistException{Key: "foo"},
				InternalError: &tv.InternalError{},
			},
			deserialize: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueString("foo")},
					}}),
				},
				{
					ID:    2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
				},
			}}),
			wantError: "KeyValue_DeleteValue_Result should have at most one field: got 2 fields",
		},
	}

	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)
		}
	}
}
Example #9
0
func TestServiceArgsAndResult(t *testing.T) {
	tests := []struct {
		desc         string
		x            serviceType
		value        wire.Value
		methodName   string
		envelopeType wire.EnvelopeType
	}{
		{
			desc: "setValue args",
			x: &tv.KeyValue_SetValue_Args{
				Key:   (*tv.Key)(stringp("foo")),
				Value: &tu.ArbitraryValue{BoolValue: boolp(true)},
			},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueBool(true)},
					}}),
				},
			}}),
			methodName:   "setValue",
			envelopeType: wire.Call,
		},
		{
			desc:         "setValue result",
			x:            &tv.KeyValue_SetValue_Result{},
			value:        wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			methodName:   "setValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "getValue args",
			x:    &tv.KeyValue_GetValue_Args{Key: (*tv.Key)(stringp("foo"))},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
			}}),
			methodName:   "getValue",
			envelopeType: wire.Call,
		},
		{
			desc: "getValue result success",
			x: &tv.KeyValue_GetValue_Result{
				Success: &tu.ArbitraryValue{Int64Value: int64p(42)},
			},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 0,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 2, Value: wire.NewValueI64(42)},
					}}),
				},
			}}),
			methodName:   "getValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "getValue result failure",
			x: &tv.KeyValue_GetValue_Result{
				DoesNotExist: &tx.DoesNotExistException{Key: "foo"},
			},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueString("foo")},
					}}),
				},
			}}),
			methodName:   "getValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "deleteValue args",
			x:    &tv.KeyValue_DeleteValue_Args{Key: (*tv.Key)(stringp("foo"))},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("foo")},
			}}),
			methodName:   "deleteValue",
			envelopeType: wire.Call,
		},
		{
			desc:         "deleteValue result success",
			x:            &tv.KeyValue_DeleteValue_Result{},
			value:        wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			methodName:   "deleteValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "deleteValue result failure",
			x: &tv.KeyValue_DeleteValue_Result{
				DoesNotExist: &tx.DoesNotExistException{Key: "foo"},
			},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueString("foo")},
					}}),
				},
			}}),
			methodName:   "deleteValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "deleteValue result failure 2",
			x: &tv.KeyValue_DeleteValue_Result{
				InternalError: &tv.InternalError{Message: stringp("foo")},
			},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueString("foo")},
					}}),
				},
			}}),
			methodName:   "deleteValue",
			envelopeType: wire.Reply,
		},
		{
			desc: "size result",
			x:    &tv.KeyValue_Size_Result{Success: int64p(42)},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 0, Value: wire.NewValueI64(42)},
			}}),
			methodName:   "size",
			envelopeType: wire.Reply,
		},
		{
			desc:         "oneway empty args",
			x:            &tv.Cache_Clear_Args{},
			value:        wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			methodName:   "clear",
			envelopeType: wire.OneWay,
		},
		{
			desc: "oneway with args",
			x:    &tv.Cache_ClearAfter_Args{DurationMS: ptr.Int64(42)},
			value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI64(42)},
			}}),
			methodName:   "clearAfter",
			envelopeType: wire.OneWay,
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, tt.x, tt.value, tt.desc)
		assert.Equal(t, tt.methodName, tt.x.MethodName(), tt.desc)
		assert.Equal(t, tt.envelopeType, tt.x.EnvelopeType(), tt.desc)
	}
}
Example #10
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)
	}
}
Example #11
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)
	}
}
Example #12
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
}
Example #13
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)
		}
	}
}
Example #14
0
func TestStructRoundTripAndString(t *testing.T) {
	tests := []struct {
		desc string
		x    interface {
			thriftType
			String() string
		}
		v wire.Value
		s string
	}{
		{
			"PrimitiveRequiredStruct",
			&ts.PrimitiveRequiredStruct{
				BoolField:   true,
				ByteField:   1,
				Int16Field:  2,
				Int32Field:  3,
				Int64Field:  4,
				DoubleField: 5.0,
				StringField: "foo",
				BinaryField: []byte("bar"),
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"",
		},
		{
			"PrimitiveOptionalStruct: all fields",
			&ts.PrimitiveOptionalStruct{
				BoolField:   boolp(true),
				ByteField:   bytep(1),
				Int16Field:  int16p(2),
				Int32Field:  int32p(3),
				Int64Field:  int64p(4),
				DoubleField: doublep(5.0),
				StringField: stringp("foo"),
				BinaryField: []byte("bar"),
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"",
		},
		{
			"PrimitiveOptionalStruct: bool",
			&ts.PrimitiveOptionalStruct{BoolField: boolp(true)},
			singleFieldStruct(1, wire.NewValueBool(true)),
			"",
		},
		{
			"PrimitiveOptionalStruct: byte",
			&ts.PrimitiveOptionalStruct{ByteField: bytep(1)},
			singleFieldStruct(2, wire.NewValueI8(1)),
			"",
		},
		{
			"PrimitiveOptionalStruct: int16",
			&ts.PrimitiveOptionalStruct{Int16Field: int16p(2)},
			singleFieldStruct(3, wire.NewValueI16(2)),
			"",
		},
		{
			"PrimitiveOptionalStruct: int32",
			&ts.PrimitiveOptionalStruct{Int32Field: int32p(3)},
			singleFieldStruct(4, wire.NewValueI32(3)),
			"",
		},
		{
			"PrimitiveOptionalStruct: int64",
			&ts.PrimitiveOptionalStruct{Int64Field: int64p(4)},
			singleFieldStruct(5, wire.NewValueI64(4)),
			"",
		},
		{
			"PrimitiveOptionalStruct: double",
			&ts.PrimitiveOptionalStruct{DoubleField: doublep(5.0)},
			singleFieldStruct(6, wire.NewValueDouble(5.0)),
			"",
		},
		{
			"PrimitiveOptionalStruct: string",
			&ts.PrimitiveOptionalStruct{StringField: stringp("foo")},
			singleFieldStruct(7, wire.NewValueString("foo")),
			"",
		},
		{
			"PrimitiveOptionalStruct: binary",
			&ts.PrimitiveOptionalStruct{BinaryField: []byte("bar")},
			singleFieldStruct(8, wire.NewValueBinary([]byte("bar"))),
			"",
		},
		{
			"PrimitiveContainersRequired",
			&tc.PrimitiveContainersRequired{
				ListOfStrings:      []string{"foo", "bar", "baz"},
				SetOfInts:          map[int32]struct{}{1: {}, 2: {}},
				MapOfIntsToDoubles: map[int64]float64{1: 2.0, 3: 4.0},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{
					ID: 1,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value([]wire.Value{
							wire.NewValueString("foo"),
							wire.NewValueString("bar"),
							wire.NewValueString("baz"),
						})),
					),
				},
				{
					ID: 2,
					Value: wire.NewValueSet(
						wire.ValueListFromSlice(wire.TI32, []wire.Value{
							wire.NewValueI32(1),
							wire.NewValueI32(2),
						}),
					),
				},
				{
					ID: 3,
					Value: wire.NewValueMap(
						wire.MapItemListFromSlice(wire.TI64, wire.TDouble, []wire.MapItem{
							{
								Key:   wire.NewValueI64(1),
								Value: wire.NewValueDouble(2.0),
							},
							{
								Key:   wire.NewValueI64(3),
								Value: wire.NewValueDouble(4.0),
							},
						}),
					),
				},
			}}),
			"",
		},
		{
			"Frame",
			&ts.Frame{
				TopLeft: &ts.Point{X: 1, Y: 2},
				Size:    &ts.Size{Width: 100, Height: 200},
			},
			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)},
					}}),
				},
			}}),
			"Frame{TopLeft: Point{X: 1, Y: 2}, Size: Size{Width: 100, Height: 200}}",
		},
		{
			"User: optional field missing",
			&ts.User{Name: "Foo Bar"},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("Foo Bar")},
			}}),
			"User{Name: Foo Bar}",
		},
		{
			"User: optional field present",
			&ts.User{
				Name:    "Foo Bar",
				Contact: &ts.ContactInfo{EmailAddress: "*****@*****.**"},
			},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueString("Foo Bar")},
				{ID: 2, Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("*****@*****.**")},
				}})},
			}}),
			"User{Name: Foo Bar, Contact: ContactInfo{EmailAddress: [email protected]}}",
		},
		{
			"List: self-referential struct",
			&ts.List{Value: 1, Tail: &ts.List{Value: 2}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(1)},
				{
					ID: 2,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{ID: 1, Value: wire.NewValueI32(2)},
					}}),
				},
			}}),
			"Node{Value: 1, Tail: Node{Value: 2}}",
		},
		{
			"Document: PDF",
			&tu.Document{Pdf: []byte{1, 2, 3}},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBinary([]byte{1, 2, 3})},
			}}),
			"Document{Pdf: [1 2 3]}",
		},
		{
			"Document: PlainText",
			&tu.Document{PlainText: stringp("hello")},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueString("hello")},
			}}),
			"Document{PlainText: hello}",
		},
		{
			"ArbitraryValue: bool",
			&tu.ArbitraryValue{BoolValue: boolp(true)},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
			}}),
			"ArbitraryValue{BoolValue: true}",
		},
		{
			"ArbitraryValue: i64",
			&tu.ArbitraryValue{Int64Value: int64p(42)},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueI64(42)},
			}}),
			"ArbitraryValue{Int64Value: 42}",
		},
		{
			"ArbitraryValue: string",
			&tu.ArbitraryValue{StringValue: stringp("hello")},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 3, Value: wire.NewValueString("hello")},
			}}),
			"ArbitraryValue{StringValue: hello}",
		},
		{
			"ArbitraryValue: list",
			&tu.ArbitraryValue{ListValue: []*tu.ArbitraryValue{
				{BoolValue: boolp(true)},
				{Int64Value: int64p(42)},
				{StringValue: stringp("hello")},
			}},
			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{
							{ID: 2, Value: wire.NewValueI64(42)},
						}}),
						wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
							{ID: 3, Value: wire.NewValueString("hello")},
						}}),
					}),
				)},
			}}),
			"ArbitraryValue{ListValue: [ArbitraryValue{BoolValue: true} ArbitraryValue{Int64Value: 42} ArbitraryValue{StringValue: hello}]}",
		},
		{
			"ArbitraryValue: map",
			&tu.ArbitraryValue{MapValue: map[string]*tu.ArbitraryValue{
				"bool":   {BoolValue: boolp(true)},
				"int64":  {Int64Value: int64p(42)},
				"string": {StringValue: stringp("hello")},
			}},
			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("int64"),
							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("hello")},
							}}),
						},
					}),
				)},
			}}),
			"",
		},
		{
			"EmptyStruct",
			&ts.EmptyStruct{},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			"",
		},
		{
			"EmptyUnion",
			&tu.EmptyUnion{},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			"",
		},
		{
			"EmptyException",
			&tx.EmptyException{},
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			"",
		},
	}

	for _, tt := range tests {
		assertRoundTrip(t, tt.x, tt.v, tt.desc)
		if tt.s != "" {
			assert.Equal(t, tt.s, tt.x.String(), "ToString: %v", tt.desc)
		} else {
			assert.NotPanics(t, func() { _ = tt.x.String() }, "ToString: %v", tt.desc)
		}
	}
}
Example #15
0
func TestPrimitiveRequiredMissingFields(t *testing.T) {
	tests := []struct {
		desc      string
		v         wire.Value
		wantError string
	}{
		{
			"bool",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field BoolField of PrimitiveRequiredStruct is required",
		},
		{
			"byte",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field ByteField of PrimitiveRequiredStruct is required",
		},
		{
			"int16",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field Int16Field of PrimitiveRequiredStruct is required",
		},
		{
			"int32",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field Int32Field of PrimitiveRequiredStruct is required",
		},
		{
			"int64",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field Int64Field of PrimitiveRequiredStruct is required",
		},
		{
			"double",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 7, Value: wire.NewValueString("foo")},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field DoubleField of PrimitiveRequiredStruct is required",
		},
		{
			"string",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 8, Value: wire.NewValueBinary([]byte("bar"))},
			}}),
			"field StringField of PrimitiveRequiredStruct is required",
		},
		{
			"binary",
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueBool(true)},
				{ID: 2, Value: wire.NewValueI8(1)},
				{ID: 3, Value: wire.NewValueI16(2)},
				{ID: 4, Value: wire.NewValueI32(3)},
				{ID: 5, Value: wire.NewValueI64(4)},
				{ID: 6, Value: wire.NewValueDouble(5.0)},
				{ID: 7, Value: wire.NewValueString("foo")},
			}}),
			"field BinaryField of PrimitiveRequiredStruct is required",
		},
	}

	for _, tt := range tests {
		var s ts.PrimitiveRequiredStruct
		err := s.FromWire(tt.v)
		if assert.Error(t, err, tt.desc) {
			assert.Contains(t, err.Error(), tt.wantError, tt.desc)
		}
	}
}