func (g *generateServiceBuilder) buildFunction(spec *compile.FunctionSpec) (*api.Function, error) { args, err := g.buildFieldGroup(compile.FieldGroup(spec.ArgsSpec)) if err != nil { return nil, err } function := &api.Function{ Name: goCase(spec.Name), ThriftName: spec.Name, Arguments: args, } if spec.OneWay { function.OneWay = ptr.Bool(spec.OneWay) } if spec.ResultSpec != nil { var err error result := spec.ResultSpec if result.ReturnType != nil { function.ReturnType, err = g.buildType(result.ReturnType, true) if err != nil { return nil, err } } if len(result.Exceptions) > 0 { function.Exceptions, err = g.buildFieldGroup(result.Exceptions) if err != nil { return nil, err } } } return function, nil }
func TestStruct(t *testing.T) { tests := []struct { desc string x thriftType }{ { "StructCollision", &tc.StructCollision{ CollisionField: true, CollisionField2: "true", }, }, { "StructCollision2 (struct_collision)", &tc.StructCollision2{ CollisionField: true, CollisionField2: "such trueness", }, }, { "PrimitiveContainers", &tc.PrimitiveContainers{ A: []string{"arbre", "fleur"}, B: map[string]struct{}{ "croissant": {}, "baguette": {}, }, C: map[string]string{ "voiture": "bleue", "cammion": "rouge", }, }, }, { "StructConstant (struct_constant)", tc.StructConstant, }, { "UnionCollision .CollisionField", &tc.UnionCollision{ CollisionField: ptr.Bool(true), }, }, { "UnionCollision .collision_field", &tc.UnionCollision{ CollisionField2: ptr.String("so true"), }, }, { "UnionCollision2 (union_collision) .CollisionField", &tc.UnionCollision2{ CollisionField: &[]bool{true}[0], }, }, { "UnionCollision (union_collision) .collision_field", &tc.UnionCollision2{ CollisionField2: ptr.String("true indeed"), }, }, } for _, tt := range tests { roundTrip(t, tt.x, tt.desc) } }
func TestBuildFunction(t *testing.T) { tests := []struct { desc string spec *compile.FunctionSpec want *api.Function }{ { desc: "returns and throws", spec: &compile.FunctionSpec{ Name: "getValue", ArgsSpec: compile.ArgsSpec{ { ID: 1, Name: "key", Type: &compile.StringSpec{}, }, }, ResultSpec: &compile.ResultSpec{ ReturnType: &compile.BinarySpec{}, Exceptions: compile.FieldGroup{ { ID: 1, Name: "doesNotExist", Type: &compile.StructSpec{ Name: "KeyDoesNotExist", File: "idl/keyvalue.thrift", Type: ast.ExceptionType, Fields: compile.FieldGroup{ { ID: 1, Name: "message", Type: &compile.StringSpec{}, }, }, }, }, }, }, }, want: &api.Function{ Name: "GetValue", ThriftName: "getValue", Arguments: []*api.Argument{ { Name: "Key", Type: &api.Type{PointerType: &api.Type{SimpleType: simpleType(api.SimpleTypeString)}}, }, }, ReturnType: &api.Type{SliceType: &api.Type{SimpleType: simpleType(api.SimpleTypeByte)}}, Exceptions: []*api.Argument{ { Name: "DoesNotExist", Type: &api.Type{ PointerType: &api.Type{ ReferenceType: &api.TypeReference{ Name: "KeyDoesNotExist", ImportPath: "go.uber.org/thriftrw/gen/testdata/keyvalue", }, }, }, }, }, }, }, { desc: "no return, no throw", spec: &compile.FunctionSpec{ Name: "setValue", ArgsSpec: compile.ArgsSpec{ { ID: 1, Name: "key", Type: &compile.StringSpec{}, }, { ID: 2, Name: "value", Type: &compile.BinarySpec{}, }, }, ResultSpec: &compile.ResultSpec{}, }, want: &api.Function{ Name: "SetValue", ThriftName: "setValue", Arguments: []*api.Argument{ { Name: "Key", Type: &api.Type{PointerType: &api.Type{SimpleType: simpleType(api.SimpleTypeString)}}, }, { Name: "Value", Type: &api.Type{SliceType: &api.Type{SimpleType: simpleType(api.SimpleTypeByte)}}, }, }, }, }, { desc: "oneway", spec: &compile.FunctionSpec{ Name: "clearCache", OneWay: true, ArgsSpec: compile.ArgsSpec{ { ID: 1, Name: "delayMS", Type: &compile.I64Spec{}, }, }, }, want: &api.Function{ Name: "ClearCache", ThriftName: "clearCache", OneWay: ptr.Bool(true), Arguments: []*api.Argument{ { Name: "DelayMS", Type: &api.Type{PointerType: &api.Type{SimpleType: simpleType(api.SimpleTypeInt64)}}, }, }, }, }, } for _, tt := range tests { spec := tt.spec err := spec.Link(compile.EmptyScope("foo")) if !assert.NoError(t, err, "%v: invalid test: scope must link", tt.desc) { continue } importer := thriftPackageImporter{ ImportPrefix: "go.uber.org/thriftrw/gen/testdata", ThriftRoot: "idl", } g := newGenerateServiceBuilder(importer) got, err := g.buildFunction(spec) if assert.NoError(t, err, tt.desc) { assert.Equal(t, tt.want, got, tt.desc) } } }
"go.uber.org/thriftrw/gen/testdata/containers" "go.uber.org/thriftrw/gen/testdata/enums" "go.uber.org/thriftrw/gen/testdata/exceptions" "go.uber.org/thriftrw/gen/testdata/structs" "go.uber.org/thriftrw/gen/testdata/typedefs" "go.uber.org/thriftrw/gen/testdata/unions" "go.uber.org/thriftrw/ptr" ) const Home enums.RecordType = enums.RecordTypeHomeAddress const Name enums.RecordType = enums.RecordTypeName const WorkAddress enums.RecordType = enums.RecordTypeWorkAddress var ArbitraryValue *unions.ArbitraryValue = &unions.ArbitraryValue{ListValue: []*unions.ArbitraryValue{&unions.ArbitraryValue{BoolValue: ptr.Bool(true)}, &unions.ArbitraryValue{Int64Value: ptr.Int64(2)}, &unions.ArbitraryValue{StringValue: ptr.String("hello")}, &unions.ArbitraryValue{MapValue: map[string]*unions.ArbitraryValue{"foo": &unions.ArbitraryValue{StringValue: ptr.String("bar")}}}}} const BeginningOfTime typedefs.Timestamp = typedefs.Timestamp(0) var ContainersOfContainers *containers.ContainersOfContainers = &containers.ContainersOfContainers{ListOfLists: [][]int32{[]int32{1, 2, 3}, []int32{4, 5, 6}}, ListOfMaps: []map[int32]int32{map[int32]int32{1: 2, 3: 4, 5: 6}, map[int32]int32{7: 8, 9: 10, 11: 12}}, ListOfSets: []map[int32]struct{}{map[int32]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}, map[int32]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}}, MapOfListToSet: []struct { Key []int32 Value map[int64]struct{} }{{Key: []int32{1, 2, 3}, Value: map[int64]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}}, {Key: []int32{4, 5, 6}, Value: map[int64]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}}}, MapOfMapToInt: []struct { Key map[string]int32 Value int64 }{{Key: map[string]int32{"1": 1, "2": 2, "3": 3}, Value: 100}, {Key: map[string]int32{"4": 4, "5": 5, "6": 6}, Value: 200}}, MapOfSetToListOfDouble: []struct { Key map[int32]struct{} Value []float64 }{{Key: map[int32]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}, Value: []float64{1.2, 3.4}}, {Key: map[int32]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}, Value: []float64{5.6, 7.8}}}, SetOfLists: [][]string{[]string{"1", "2", "3"}, []string{"4", "5", "6"}}, SetOfMaps: []map[string]string{map[string]string{"1": "2", "3": "4", "5": "6"}, map[string]string{"7": "8", "9": "10", "11": "12"}}, SetOfSets: []map[string]struct{}{map[string]struct{}{"1": struct{}{}, "2": struct{}{}, "3": struct{}{}}, map[string]struct{}{"4": struct{}{}, "5": struct{}{}, "6": struct{}{}}}} var EmptyException *exceptions.EmptyException = &exceptions.EmptyException{}