Clash.Meta/common/structure/structure_test.go

270 lines
4.8 KiB
Go
Raw Normal View History

2018-09-30 16:30:11 +08:00
package structure
import (
"strconv"
2018-09-30 16:30:11 +08:00
"testing"
2021-11-08 13:29:37 +08:00
"github.com/stretchr/testify/assert"
2018-09-30 16:30:11 +08:00
)
2021-10-10 23:44:09 +08:00
var (
decoder = NewDecoder(Option{TagName: "test"})
weakTypeDecoder = NewDecoder(Option{TagName: "test", WeaklyTypedInput: true})
)
2018-09-30 16:30:11 +08:00
type Baz struct {
Foo int `test:"foo"`
Bar string `test:"bar"`
}
type BazSlice struct {
Foo int `test:"foo"`
Bar []string `test:"bar"`
}
type BazOptional struct {
Foo int `test:"foo,omitempty"`
Bar string `test:"bar,omitempty"`
}
func TestStructure_Basic(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": 1,
"bar": "test",
"extra": false,
}
goal := &Baz{
Foo: 1,
Bar: "test",
}
s := &Baz{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.Nil(t, err)
assert.Equal(t, goal, s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_Slice(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": 1,
"bar": []string{"one", "two"},
}
goal := &BazSlice{
Foo: 1,
Bar: []string{"one", "two"},
}
s := &BazSlice{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.Nil(t, err)
assert.Equal(t, goal, s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_Optional(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": 1,
}
goal := &BazOptional{
Foo: 1,
}
s := &BazOptional{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.Nil(t, err)
assert.Equal(t, goal, s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_MissingKey(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": 1,
}
s := &Baz{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.NotNilf(t, err, "should throw error: %#v", s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_ParamError(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{}
2018-09-30 16:30:11 +08:00
s := Baz{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.NotNilf(t, err, "should throw error: %#v", s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_SliceTypeError(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": 1,
"bar": []int{1, 2},
}
s := &BazSlice{}
err := decoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.NotNilf(t, err, "should throw error: %#v", s)
2018-09-30 16:30:11 +08:00
}
func TestStructure_WeakType(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2018-09-30 16:30:11 +08:00
"foo": "1",
"bar": []int{1},
}
goal := &BazSlice{
Foo: 1,
Bar: []string{"1"},
}
s := &BazSlice{}
err := weakTypeDecoder.Decode(rawMap, s)
2021-11-08 13:29:37 +08:00
assert.Nil(t, err)
assert.Equal(t, goal, s)
}
func TestStructure_Nest(t *testing.T) {
2022-03-16 12:10:13 +08:00
rawMap := map[string]any{
2021-11-08 13:29:37 +08:00
"foo": 1,
2018-09-30 16:30:11 +08:00
}
2021-11-08 13:29:37 +08:00
goal := BazOptional{
Foo: 1,
2018-09-30 16:30:11 +08:00
}
2021-11-08 13:29:37 +08:00
s := &struct {
BazOptional
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Equal(t, s.BazOptional, goal)
2018-09-30 16:30:11 +08:00
}
func TestStructure_SliceNilValue(t *testing.T) {
rawMap := map[string]any{
"foo": 1,
"bar": []any{"bar", nil},
}
goal := &BazSlice{
Foo: 1,
Bar: []string{"bar", ""},
}
s := &BazSlice{}
err := weakTypeDecoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Equal(t, goal.Bar, s.Bar)
s = &BazSlice{}
err = decoder.Decode(rawMap, s)
assert.NotNil(t, err)
}
func TestStructure_SliceNilValueComplex(t *testing.T) {
rawMap := map[string]any{
"bar": []any{map[string]any{"bar": "foo"}, nil},
}
s := &struct {
Bar []map[string]any `test:"bar"`
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Nil(t, s.Bar[1])
ss := &struct {
Bar []Baz `test:"bar"`
}{}
err = decoder.Decode(rawMap, ss)
assert.NotNil(t, err)
}
func TestStructure_SliceCap(t *testing.T) {
rawMap := map[string]any{
"foo": []string{},
}
s := &struct {
Foo []string `test:"foo,omitempty"`
Bar []string `test:"bar,omitempty"`
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.NotNil(t, s.Foo) // structure's Decode will ensure value not nil when input has value even it was set an empty array
assert.Nil(t, s.Bar)
}
func TestStructure_Base64(t *testing.T) {
rawMap := map[string]any{
"foo": "AQID",
}
s := &struct {
Foo []byte `test:"foo"`
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Equal(t, []byte{1, 2, 3}, s.Foo)
}
func TestStructure_Pointer(t *testing.T) {
rawMap := map[string]any{
"foo": "foo",
}
s := &struct {
Foo *string `test:"foo,omitempty"`
Bar *string `test:"bar,omitempty"`
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.NotNil(t, s.Foo)
assert.Equal(t, "foo", *s.Foo)
assert.Nil(t, s.Bar)
}
type num struct {
a int
}
func (n *num) UnmarshalText(text []byte) (err error) {
n.a, err = strconv.Atoi(string(text))
return
}
func TestStructure_TextUnmarshaller(t *testing.T) {
rawMap := map[string]any{
"num": "255",
"num_p": "127",
}
s := &struct {
Num num `test:"num"`
NumP *num `test:"num_p"`
}{}
err := decoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Equal(t, 255, s.Num.a)
assert.NotNil(t, s.NumP)
assert.Equal(t, s.NumP.a, 127)
// test WeaklyTypedInput
rawMap["num"] = 256
err = decoder.Decode(rawMap, s)
assert.NotNilf(t, err, "should throw error: %#v", s)
err = weakTypeDecoder.Decode(rawMap, s)
assert.Nil(t, err)
assert.Equal(t, 256, s.Num.a)
// test invalid input
rawMap["num_p"] = "abc"
err = decoder.Decode(rawMap, s)
assert.NotNilf(t, err, "should throw error: %#v", s)
}