github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/annotation/value_mapping_test.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package annotation 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "strconv" 24 "testing" 25 26 "github.com/cloudwego/dynamicgo/internal/rt" 27 "github.com/cloudwego/dynamicgo/thrift" 28 "github.com/cloudwego/thriftgo/parser" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestAPIJSConv(t *testing.T) { 33 p, err := thrift.NewDescritorFromPath(context.Background(), "../../testdata/idl/example3.thrift") 34 if err != nil { 35 t.Fatal(err) 36 } 37 fmt.Printf("%#+v\n", p) 38 req := p.Functions()["ExampleMethod"].Request().Struct().FieldByKey("req") 39 h := req.Type().Struct().FieldById(1) 40 hm := h.HTTPMappings() 41 require.Equal(t, []thrift.HttpMapping(nil), hm) 42 vm := req.Type().Struct().FieldById(6).ValueMappingType() 43 require.Equal(t, JSConv, vm) 44 } 45 46 func init() { 47 thrift.RegisterAnnotation(NewValueMappingAnnotation2(thrift.MakeAnnoID(thrift.AnnoKindValueMapping, thrift.AnnoScopeField, APIJSConv2)), "test.js_conv2") 48 } 49 50 const APIJSConv2 = thrift.AnnoType(999) 51 52 type ValueMappingAnnotation2 struct { 53 typ thrift.AnnoID 54 } 55 56 func NewValueMappingAnnotation2(typ thrift.AnnoID) ValueMappingAnnotation2 { 57 return ValueMappingAnnotation2{ 58 typ: typ, 59 } 60 } 61 62 func (self ValueMappingAnnotation2) ID() thrift.AnnoID { 63 return self.typ 64 } 65 66 func (self ValueMappingAnnotation2) Make(ctx context.Context, values []parser.Annotation, ast interface{}) (interface{}, error) { 67 if len(values) != 1 { 68 return nil, errors.New("ValueMappingAnnotation2 must have one value") 69 } 70 switch self.typ.Type() { 71 case APIJSConv2: 72 return apiJSConv2{}, nil 73 default: 74 return nil, errNotImplemented("error") 75 } 76 } 77 78 type apiJSConv2 struct { 79 apiJSConv 80 } 81 82 func (m apiJSConv2) Write(ctx context.Context, p *thrift.BinaryProtocol, field *thrift.FieldDescriptor, in []byte) error { 83 if len(in) == 0 { 84 return errors.New("empty value") 85 } 86 if in[0] == '"' { 87 in = in[1 : len(in)-1] 88 } 89 switch t := field.Type().Type(); t { 90 case thrift.BYTE, thrift.I16, thrift.I32, thrift.I64: 91 i, err := strconv.ParseInt(rt.Mem2Str(in), 10, 64) 92 if err != nil { 93 return err 94 } 95 if err := p.WriteInt(t, int(i)); err != nil { 96 return err 97 } 98 return nil 99 case thrift.DOUBLE: 100 f, err := strconv.ParseFloat(rt.Mem2Str(in), 64) 101 if err != nil { 102 return err 103 } 104 if err := p.WriteDouble(f); err != nil { 105 return err 106 } 107 return nil 108 default: 109 return fmt.Errorf("unsupported type %s", t) 110 } 111 } 112 113 func TestJSConv2(t *testing.T) { 114 path := "a/b/main.thrift" 115 content := ` 116 namespace go kitex.test.server 117 struct Base { 118 1: required string required_field 119 2: optional string test1 (test.js_conv2="") 120 3: string pass 121 } 122 123 service ExampleService { 124 string ExampleMethod(1: Base req) 125 } 126 ` 127 includes := map[string]string{ 128 path: content, 129 } 130 p, err := thrift.NewDescritorFromContent(context.Background(), path, content, includes, true) 131 if err != nil { 132 t.Fatal(err) 133 } 134 req := p.Functions()["ExampleMethod"].Request().Struct().Fields()[0].Type() 135 require.Equal(t, apiJSConv2{}, req.Struct().FieldById(2).ValueMapping()) 136 require.Equal(t, APIJSConv2, req.Struct().FieldById(2).ValueMappingType()) 137 }