mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-02-02 16:28:39 +08:00
fix golint issues in core/mapping (#497)
This commit is contained in:
parent
226513ed60
commit
334ee4213f
@ -10,10 +10,12 @@ const jsonTagKey = "json"
|
||||
|
||||
var jsonUnmarshaler = NewUnmarshaler(jsonTagKey)
|
||||
|
||||
// UnmarshalJsonBytes unmarshals content into v.
|
||||
func UnmarshalJsonBytes(content []byte, v interface{}) error {
|
||||
return unmarshalJsonBytes(content, v, jsonUnmarshaler)
|
||||
}
|
||||
|
||||
// UnmarshalJsonReader unmarshals content from reader into v.
|
||||
func UnmarshalJsonReader(reader io.Reader, v interface{}) error {
|
||||
return unmarshalJsonReader(reader, v, jsonUnmarshaler)
|
||||
}
|
||||
|
@ -485,41 +485,41 @@ func TestUnmarshalBytesMap(t *testing.T) {
|
||||
func TestUnmarshalBytesMapStruct(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": {"Id": 1, "name": "kevin"}}}`)
|
||||
content := []byte(`{"Persons": {"first": {"ID": 1, "name": "kevin"}}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalBytesMapStructPtr(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": {"Id": 1, "name": "kevin"}}}`)
|
||||
content := []byte(`{"Persons": {"first": {"ID": 1, "name": "kevin"}}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalBytesMapStructMissingPartial(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": {"Id": 1}}}`)
|
||||
content := []byte(`{"Persons": {"first": {"ID": 1}}}`)
|
||||
|
||||
assert.NotNil(t, UnmarshalJsonBytes(content, &c))
|
||||
}
|
||||
@ -527,21 +527,21 @@ func TestUnmarshalBytesMapStructMissingPartial(t *testing.T) {
|
||||
func TestUnmarshalBytesMapStructOptional(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": {"Id": 1}}}`)
|
||||
content := []byte(`{"Persons": {"first": {"ID": 1}}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
}
|
||||
|
||||
func TestUnmarshalBytesMapEmptyStructSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
@ -555,22 +555,22 @@ func TestUnmarshalBytesMapEmptyStructSlice(t *testing.T) {
|
||||
func TestUnmarshalBytesMapStructSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": [{"Id": 1, "name": "kevin"}]}}`)
|
||||
content := []byte(`{"Persons": {"first": [{"ID": 1, "name": "kevin"}]}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"][0].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalBytesMapEmptyStructPtrSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
@ -584,26 +584,26 @@ func TestUnmarshalBytesMapEmptyStructPtrSlice(t *testing.T) {
|
||||
func TestUnmarshalBytesMapStructPtrSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": [{"Id": 1, "name": "kevin"}]}}`)
|
||||
content := []byte(`{"Persons": {"first": [{"ID": 1, "name": "kevin"}]}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"][0].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalBytesMapStructPtrSliceMissingPartial(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": [{"Id": 1}]}}`)
|
||||
content := []byte(`{"Persons": {"first": [{"ID": 1}]}}`)
|
||||
|
||||
assert.NotNil(t, UnmarshalJsonBytes(content, &c))
|
||||
}
|
||||
@ -611,15 +611,15 @@ func TestUnmarshalBytesMapStructPtrSliceMissingPartial(t *testing.T) {
|
||||
func TestUnmarshalBytesMapStructPtrSliceOptional(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`{"Persons": {"first": [{"Id": 1}]}}`)
|
||||
content := []byte(`{"Persons": {"first": [{"ID": 1}]}}`)
|
||||
|
||||
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
}
|
||||
|
||||
func TestUnmarshalStructOptional(t *testing.T) {
|
||||
|
@ -33,23 +33,27 @@ var (
|
||||
)
|
||||
|
||||
type (
|
||||
// A Unmarshaler is used to unmarshal with given tag key.
|
||||
Unmarshaler struct {
|
||||
key string
|
||||
opts unmarshalOptions
|
||||
}
|
||||
|
||||
// UnmarshalOption defines the method to customize a Unmarshaler.
|
||||
UnmarshalOption func(*unmarshalOptions)
|
||||
|
||||
unmarshalOptions struct {
|
||||
fromString bool
|
||||
}
|
||||
|
||||
keyCache map[string][]string
|
||||
UnmarshalOption func(*unmarshalOptions)
|
||||
keyCache map[string][]string
|
||||
)
|
||||
|
||||
func init() {
|
||||
cacheKeys.Store(make(keyCache))
|
||||
}
|
||||
|
||||
// NewUnmarshaler returns a Unmarshaler.
|
||||
func NewUnmarshaler(key string, opts ...UnmarshalOption) *Unmarshaler {
|
||||
unmarshaler := Unmarshaler{
|
||||
key: key,
|
||||
@ -62,14 +66,17 @@ func NewUnmarshaler(key string, opts ...UnmarshalOption) *Unmarshaler {
|
||||
return &unmarshaler
|
||||
}
|
||||
|
||||
// UnmarshalKey unmarshals m into v with tag key.
|
||||
func UnmarshalKey(m map[string]interface{}, v interface{}) error {
|
||||
return keyUnmarshaler.Unmarshal(m, v)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals m into v.
|
||||
func (u *Unmarshaler) Unmarshal(m map[string]interface{}, v interface{}) error {
|
||||
return u.UnmarshalValuer(MapValuer(m), v)
|
||||
}
|
||||
|
||||
// UnmarshalValuer unmarshals m into v.
|
||||
func (u *Unmarshaler) UnmarshalValuer(m Valuer, v interface{}) error {
|
||||
return u.unmarshalWithFullName(m, v, "")
|
||||
}
|
||||
@ -590,6 +597,7 @@ func (u *Unmarshaler) parseOptionsWithContext(field reflect.StructField, m Value
|
||||
return key, optsWithContext, nil
|
||||
}
|
||||
|
||||
// WithStringValues customizes a Unmarshaler with number values from strings.
|
||||
func WithStringValues() UnmarshalOption {
|
||||
return func(opt *unmarshalOptions) {
|
||||
opt.fromString = true
|
||||
|
@ -754,13 +754,13 @@ func TestUnmarshalJsonNumberInt64(t *testing.T) {
|
||||
strValue := strconv.FormatInt(intValue, 10)
|
||||
var number = json.Number(strValue)
|
||||
m := map[string]interface{}{
|
||||
"Id": number,
|
||||
"ID": number,
|
||||
}
|
||||
var v struct {
|
||||
Id int64
|
||||
ID int64
|
||||
}
|
||||
assert.Nil(t, UnmarshalKey(m, &v))
|
||||
assert.Equal(t, intValue, v.Id)
|
||||
assert.Equal(t, intValue, v.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,13 +770,13 @@ func TestUnmarshalJsonNumberUint64(t *testing.T) {
|
||||
strValue := strconv.FormatUint(intValue, 10)
|
||||
var number = json.Number(strValue)
|
||||
m := map[string]interface{}{
|
||||
"Id": number,
|
||||
"ID": number,
|
||||
}
|
||||
var v struct {
|
||||
Id uint64
|
||||
ID uint64
|
||||
}
|
||||
assert.Nil(t, UnmarshalKey(m, &v))
|
||||
assert.Equal(t, intValue, v.Id)
|
||||
assert.Equal(t, intValue, v.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -786,15 +786,15 @@ func TestUnmarshalJsonNumberUint64Ptr(t *testing.T) {
|
||||
strValue := strconv.FormatUint(intValue, 10)
|
||||
var number = json.Number(strValue)
|
||||
m := map[string]interface{}{
|
||||
"Id": number,
|
||||
"ID": number,
|
||||
}
|
||||
var v struct {
|
||||
Id *uint64
|
||||
ID *uint64
|
||||
}
|
||||
ast := assert.New(t)
|
||||
ast.Nil(UnmarshalKey(m, &v))
|
||||
ast.NotNil(v.Id)
|
||||
ast.Equal(intValue, *v.Id)
|
||||
ast.NotNil(v.ID)
|
||||
ast.Equal(intValue, *v.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1061,38 +1061,38 @@ func TestUnmarshalWithOptionsAndSet(t *testing.T) {
|
||||
|
||||
func TestUnmarshalNestedKey(t *testing.T) {
|
||||
var c struct {
|
||||
Id int `json:"Persons.first.Id"`
|
||||
ID int `json:"Persons.first.ID"`
|
||||
}
|
||||
m := map[string]interface{}{
|
||||
"Persons": map[string]interface{}{
|
||||
"first": map[string]interface{}{
|
||||
"Id": 1,
|
||||
"ID": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
|
||||
assert.Equal(t, 1, c.Id)
|
||||
assert.Equal(t, 1, c.ID)
|
||||
}
|
||||
|
||||
func TestUnmarhsalNestedKeyArray(t *testing.T) {
|
||||
var c struct {
|
||||
First []struct {
|
||||
Id int
|
||||
ID int
|
||||
} `json:"Persons.first"`
|
||||
}
|
||||
m := map[string]interface{}{
|
||||
"Persons": map[string]interface{}{
|
||||
"first": []map[string]interface{}{
|
||||
{"Id": 1},
|
||||
{"Id": 2},
|
||||
{"ID": 1},
|
||||
{"ID": 2},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
|
||||
assert.Equal(t, 2, len(c.First))
|
||||
assert.Equal(t, 1, c.First[0].Id)
|
||||
assert.Equal(t, 1, c.First[0].ID)
|
||||
}
|
||||
|
||||
func TestUnmarshalAnonymousOptionalRequiredProvided(t *testing.T) {
|
||||
|
@ -45,6 +45,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// Deref dereferences a type, if pointer type, returns its element type.
|
||||
func Deref(t reflect.Type) reflect.Type {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
@ -53,6 +54,7 @@ func Deref(t reflect.Type) reflect.Type {
|
||||
return t
|
||||
}
|
||||
|
||||
// Repr returns the string representation of v.
|
||||
func Repr(v interface{}) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
@ -72,6 +74,7 @@ func Repr(v interface{}) string {
|
||||
return reprOfValue(val)
|
||||
}
|
||||
|
||||
// ValidatePtr validates v if it's a valid pointer.
|
||||
func ValidatePtr(v *reflect.Value) error {
|
||||
// sequence is very important, IsNil must be called after checking Kind() with reflect.Ptr,
|
||||
// panic otherwise
|
||||
|
@ -1,13 +1,17 @@
|
||||
package mapping
|
||||
|
||||
type (
|
||||
// A Valuer interface defines the way to get values from the underlying object with keys.
|
||||
Valuer interface {
|
||||
// Value gets the value associated with the given key.
|
||||
Value(key string) (interface{}, bool)
|
||||
}
|
||||
|
||||
// A MapValuer is a map that can use Value method to get values with given keys.
|
||||
MapValuer map[string]interface{}
|
||||
)
|
||||
|
||||
// Value gets the value associated with the given key from mv.
|
||||
func (mv MapValuer) Value(key string) (interface{}, bool) {
|
||||
v, ok := mv[key]
|
||||
return v, ok
|
||||
|
@ -13,15 +13,18 @@ import (
|
||||
const yamlTagKey = "json"
|
||||
|
||||
var (
|
||||
// ErrUnsupportedType is an error that indicates the config format is not supported.
|
||||
ErrUnsupportedType = errors.New("only map-like configs are suported")
|
||||
|
||||
yamlUnmarshaler = NewUnmarshaler(yamlTagKey)
|
||||
)
|
||||
|
||||
// UnmarshalYamlBytes unmarshals content into v.
|
||||
func UnmarshalYamlBytes(content []byte, v interface{}) error {
|
||||
return unmarshalYamlBytes(content, v, yamlUnmarshaler)
|
||||
}
|
||||
|
||||
// UnmarshalYamlReader unmarshals content from reader into v.
|
||||
func UnmarshalYamlReader(reader io.Reader, v interface{}) error {
|
||||
return unmarshalYamlReader(reader, v, yamlUnmarshaler)
|
||||
}
|
||||
|
@ -502,49 +502,49 @@ func TestUnmarshalYamlBytesMap(t *testing.T) {
|
||||
func TestUnmarshalYamlBytesMapStruct(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
Id: 1
|
||||
ID: 1
|
||||
name: kevin`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlBytesMapStructPtr(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
Id: 1
|
||||
ID: 1
|
||||
name: kevin`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlBytesMapStructMissingPartial(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
Id: 1`)
|
||||
ID: 1`)
|
||||
|
||||
assert.NotNil(t, UnmarshalYamlBytes(content, &c))
|
||||
}
|
||||
@ -552,41 +552,41 @@ func TestUnmarshalYamlBytesMapStructMissingPartial(t *testing.T) {
|
||||
func TestUnmarshalYamlBytesMapStructOptional(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
Id: 1`)
|
||||
ID: 1`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"].ID)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlBytesMapStructSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
- Id: 1
|
||||
- ID: 1
|
||||
name: kevin`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"][0].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlBytesMapEmptyStructSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
@ -601,25 +601,25 @@ func TestUnmarshalYamlBytesMapEmptyStructSlice(t *testing.T) {
|
||||
func TestUnmarshalYamlBytesMapStructPtrSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
- Id: 1
|
||||
- ID: 1
|
||||
name: kevin`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
assert.Equal(t, "kevin", c.Persons["first"][0].Name)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlBytesMapEmptyStructPtrSlice(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
@ -634,13 +634,13 @@ func TestUnmarshalYamlBytesMapEmptyStructPtrSlice(t *testing.T) {
|
||||
func TestUnmarshalYamlBytesMapStructPtrSliceMissingPartial(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
- Id: 1`)
|
||||
- ID: 1`)
|
||||
|
||||
assert.NotNil(t, UnmarshalYamlBytes(content, &c))
|
||||
}
|
||||
@ -648,17 +648,17 @@ func TestUnmarshalYamlBytesMapStructPtrSliceMissingPartial(t *testing.T) {
|
||||
func TestUnmarshalYamlBytesMapStructPtrSliceOptional(t *testing.T) {
|
||||
var c struct {
|
||||
Persons map[string][]*struct {
|
||||
Id int
|
||||
ID int
|
||||
Name string `json:"name,optional"`
|
||||
}
|
||||
}
|
||||
content := []byte(`Persons:
|
||||
first:
|
||||
- Id: 1`)
|
||||
- ID: 1`)
|
||||
|
||||
assert.Nil(t, UnmarshalYamlBytes(content, &c))
|
||||
assert.Equal(t, 1, len(c.Persons))
|
||||
assert.Equal(t, 1, c.Persons["first"][0].Id)
|
||||
assert.Equal(t, 1, c.Persons["first"][0].ID)
|
||||
}
|
||||
|
||||
func TestUnmarshalYamlStructOptional(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user