test(encoding/form): add unit test and code style modift (#2467)
* test(encoding/form): add unit test and code style modift * fix test * add populateRepeatedField testpull/2384/head
parent
590c469081
commit
a1a2b9dbd9
@ -0,0 +1,217 @@ |
||||
package form |
||||
|
||||
import ( |
||||
"fmt" |
||||
"net/url" |
||||
"reflect" |
||||
"strconv" |
||||
"testing" |
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
|
||||
"github.com/go-kratos/kratos/v2/internal/testdata/complex" |
||||
) |
||||
|
||||
func TestDecodeValues(t *testing.T) { |
||||
form, err := url.ParseQuery("a=19&age=18&b=true&bool=false&byte=MTIz&bytes=MTIz&count=3&d=22.22&double=12.33&duration=" + |
||||
"2m0.000000022s&field=1%2C2&float=12.34&id=2233&int32=32&int64=64&numberOne=2233&price=11.23&sex=woman&simples=3344&" + |
||||
"simples=5566&string=go-kratos×tamp=1970-01-01T00%3A00%3A20.000000002Z&uint32=32&uint64=64&very_simple.component=5566") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
comp := &complex.Complex{} |
||||
err = DecodeValues(comp, form) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
if comp.Id != int64(2233) { |
||||
t.Errorf("want %v, got %v", int64(2233), comp.Id) |
||||
} |
||||
if comp.NoOne != "2233" { |
||||
t.Errorf("want %v, got %v", "2233", comp.NoOne) |
||||
} |
||||
if comp.Simple == nil { |
||||
t.Fatalf("want %v, got %v", nil, comp.Simple) |
||||
} |
||||
if comp.Simple.Component != "5566" { |
||||
t.Errorf("want %v, got %v", "5566", comp.Simple.Component) |
||||
} |
||||
if len(comp.Simples) != 2 { |
||||
t.Fatalf("want %v, got %v", 2, len(comp.Simples)) |
||||
} |
||||
if comp.Simples[0] != "3344" { |
||||
t.Errorf("want %v, got %v", "3344", comp.Simples[0]) |
||||
} |
||||
if comp.Simples[1] != "5566" { |
||||
t.Errorf("want %v, got %v", "5566", comp.Simples[1]) |
||||
} |
||||
} |
||||
|
||||
func TestGetFieldDescriptor(t *testing.T) { |
||||
comp := &complex.Complex{} |
||||
|
||||
field := getFieldDescriptor(comp.ProtoReflect(), "id") |
||||
if field.Kind() != protoreflect.Int64Kind { |
||||
t.Errorf("want: %d, got: %d", protoreflect.Int64Kind, field.Kind()) |
||||
} |
||||
|
||||
field = getFieldDescriptor(comp.ProtoReflect(), "simples") |
||||
if field.Kind() != protoreflect.StringKind { |
||||
t.Errorf("want: %d, got: %d", protoreflect.StringKind, field.Kind()) |
||||
} |
||||
} |
||||
|
||||
func TestPopulateRepeatedField(t *testing.T) { |
||||
query, err := url.ParseQuery("simples=3344&simples=5566") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
comp := &complex.Complex{} |
||||
field := getFieldDescriptor(comp.ProtoReflect(), "simples") |
||||
|
||||
err = populateRepeatedField(field, comp.ProtoReflect().Mutable(field).List(), query["simples"]) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
if !reflect.DeepEqual([]string{"3344", "5566"}, comp.GetSimples()) { |
||||
t.Errorf("want: %v, got: %v", []string{"3344", "5566"}, comp.GetSimples()) |
||||
} |
||||
} |
||||
|
||||
func TestPopulateMapField(t *testing.T) { |
||||
query, err := url.ParseQuery("map%5Bkratos%5D=https://go-kratos.dev/") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
comp := &complex.Complex{} |
||||
field := getFieldDescriptor(comp.ProtoReflect(), "map") |
||||
// Fill the comp map field with the url query values
|
||||
err = populateMapField(field, comp.ProtoReflect().Mutable(field).Map(), []string{"kratos"}, query["map[kratos]"]) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
// Get the comp map field value
|
||||
if query["map[kratos]"][0] != comp.Map["kratos"] { |
||||
t.Errorf("want: %s, got: %s", query["map[kratos]"], comp.Map["kratos"]) |
||||
} |
||||
} |
||||
|
||||
func TestParseField(t *testing.T) { |
||||
tests := []struct { |
||||
name string |
||||
fieldName string |
||||
protoReflectKind protoreflect.Kind |
||||
value string |
||||
targetProtoReflectValue protoreflect.Value |
||||
targetErr error |
||||
}{ |
||||
{ |
||||
name: "BoolKind", |
||||
fieldName: "b", |
||||
protoReflectKind: protoreflect.BoolKind, |
||||
value: "true", |
||||
targetProtoReflectValue: protoreflect.ValueOfBool(true), |
||||
targetErr: nil, |
||||
}, |
||||
{ |
||||
name: "BoolKind", |
||||
fieldName: "b", |
||||
protoReflectKind: protoreflect.BoolKind, |
||||
value: "a", |
||||
targetProtoReflectValue: protoreflect.Value{}, |
||||
targetErr: &strconv.NumError{Func: "ParseBool", Num: "a", Err: strconv.ErrSyntax}, |
||||
}, |
||||
{ |
||||
name: "EnumKind", |
||||
fieldName: "sex", |
||||
protoReflectKind: protoreflect.EnumKind, |
||||
value: "1", |
||||
targetProtoReflectValue: protoreflect.ValueOfEnum(1), |
||||
targetErr: nil, |
||||
}, |
||||
{ |
||||
name: "EnumKind", |
||||
fieldName: "sex", |
||||
protoReflectKind: protoreflect.EnumKind, |
||||
value: "2", |
||||
targetProtoReflectValue: protoreflect.Value{}, |
||||
targetErr: fmt.Errorf("%q is not a valid value", "2"), |
||||
}, |
||||
} |
||||
for _, test := range tests { |
||||
t.Run(test.name, func(t *testing.T) { |
||||
comp := &complex.Complex{} |
||||
field := getFieldDescriptor(comp.ProtoReflect(), test.fieldName) |
||||
if test.protoReflectKind != field.Kind() { |
||||
t.Fatalf("want: %d, got: %d", test.protoReflectKind, field.Kind()) |
||||
} |
||||
val, err := parseField(field, test.value) |
||||
if !reflect.DeepEqual(test.targetErr, err) { |
||||
t.Fatalf("want: %s, got: %s", test.targetErr, err) |
||||
} |
||||
if !reflect.DeepEqual(test.targetProtoReflectValue, val) { |
||||
t.Errorf("want: %s, got: %s", test.targetProtoReflectValue, val) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func TestJsonSnakeCase(t *testing.T) { |
||||
tests := []struct { |
||||
camelCase string |
||||
snakeCase string |
||||
}{ |
||||
{ |
||||
"userId", "user_id", |
||||
}, |
||||
{ |
||||
"user", "user", |
||||
}, |
||||
{ |
||||
"userIdAndUsername", "user_id_and_username", |
||||
}, |
||||
{ |
||||
"", "", |
||||
}, |
||||
} |
||||
for _, test := range tests { |
||||
t.Run(test.camelCase, func(t *testing.T) { |
||||
snake := jsonSnakeCase(test.camelCase) |
||||
if snake != test.snakeCase { |
||||
t.Errorf("want: %s, got: %s", test.snakeCase, snake) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func TestIsASCIIUpper(t *testing.T) { |
||||
tests := []struct { |
||||
b byte |
||||
upper bool |
||||
}{ |
||||
{ |
||||
'A', true, |
||||
}, |
||||
{ |
||||
'a', false, |
||||
}, |
||||
{ |
||||
',', false, |
||||
}, |
||||
{ |
||||
'1', false, |
||||
}, |
||||
{ |
||||
' ', false, |
||||
}, |
||||
} |
||||
for _, test := range tests { |
||||
t.Run(string(test.b), func(t *testing.T) { |
||||
upper := isASCIIUpper(test.b) |
||||
if test.upper != upper { |
||||
t.Errorf("'%s' is not ascii upper", string(test.b)) |
||||
} |
||||
}) |
||||
} |
||||
} |
Loading…
Reference in new issue