github.com/metacubex/mihomo@v1.18.5/common/structure/structure_test.go (about)

     1  package structure
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  )
     8  
     9  var (
    10  	decoder         = NewDecoder(Option{TagName: "test"})
    11  	weakTypeDecoder = NewDecoder(Option{TagName: "test", WeaklyTypedInput: true})
    12  )
    13  
    14  type Baz struct {
    15  	Foo int    `test:"foo"`
    16  	Bar string `test:"bar"`
    17  }
    18  
    19  type BazSlice struct {
    20  	Foo int      `test:"foo"`
    21  	Bar []string `test:"bar"`
    22  }
    23  
    24  type BazOptional struct {
    25  	Foo int    `test:"foo,omitempty"`
    26  	Bar string `test:"bar,omitempty"`
    27  }
    28  
    29  func TestStructure_Basic(t *testing.T) {
    30  	rawMap := map[string]any{
    31  		"foo":   1,
    32  		"bar":   "test",
    33  		"extra": false,
    34  	}
    35  
    36  	goal := &Baz{
    37  		Foo: 1,
    38  		Bar: "test",
    39  	}
    40  
    41  	s := &Baz{}
    42  	err := decoder.Decode(rawMap, s)
    43  	assert.Nil(t, err)
    44  	assert.Equal(t, goal, s)
    45  }
    46  
    47  func TestStructure_Slice(t *testing.T) {
    48  	rawMap := map[string]any{
    49  		"foo": 1,
    50  		"bar": []string{"one", "two"},
    51  	}
    52  
    53  	goal := &BazSlice{
    54  		Foo: 1,
    55  		Bar: []string{"one", "two"},
    56  	}
    57  
    58  	s := &BazSlice{}
    59  	err := decoder.Decode(rawMap, s)
    60  	assert.Nil(t, err)
    61  	assert.Equal(t, goal, s)
    62  }
    63  
    64  func TestStructure_Optional(t *testing.T) {
    65  	rawMap := map[string]any{
    66  		"foo": 1,
    67  	}
    68  
    69  	goal := &BazOptional{
    70  		Foo: 1,
    71  	}
    72  
    73  	s := &BazOptional{}
    74  	err := decoder.Decode(rawMap, s)
    75  	assert.Nil(t, err)
    76  	assert.Equal(t, goal, s)
    77  }
    78  
    79  func TestStructure_MissingKey(t *testing.T) {
    80  	rawMap := map[string]any{
    81  		"foo": 1,
    82  	}
    83  
    84  	s := &Baz{}
    85  	err := decoder.Decode(rawMap, s)
    86  	assert.NotNilf(t, err, "should throw error: %#v", s)
    87  }
    88  
    89  func TestStructure_ParamError(t *testing.T) {
    90  	rawMap := map[string]any{}
    91  	s := Baz{}
    92  	err := decoder.Decode(rawMap, s)
    93  	assert.NotNilf(t, err, "should throw error: %#v", s)
    94  }
    95  
    96  func TestStructure_SliceTypeError(t *testing.T) {
    97  	rawMap := map[string]any{
    98  		"foo": 1,
    99  		"bar": []int{1, 2},
   100  	}
   101  
   102  	s := &BazSlice{}
   103  	err := decoder.Decode(rawMap, s)
   104  	assert.NotNilf(t, err, "should throw error: %#v", s)
   105  }
   106  
   107  func TestStructure_WeakType(t *testing.T) {
   108  	rawMap := map[string]any{
   109  		"foo": "1",
   110  		"bar": []int{1},
   111  	}
   112  
   113  	goal := &BazSlice{
   114  		Foo: 1,
   115  		Bar: []string{"1"},
   116  	}
   117  
   118  	s := &BazSlice{}
   119  	err := weakTypeDecoder.Decode(rawMap, s)
   120  	assert.Nil(t, err)
   121  	assert.Equal(t, goal, s)
   122  }
   123  
   124  func TestStructure_Nest(t *testing.T) {
   125  	rawMap := map[string]any{
   126  		"foo": 1,
   127  	}
   128  
   129  	goal := BazOptional{
   130  		Foo: 1,
   131  	}
   132  
   133  	s := &struct {
   134  		BazOptional
   135  	}{}
   136  	err := decoder.Decode(rawMap, s)
   137  	assert.Nil(t, err)
   138  	assert.Equal(t, s.BazOptional, goal)
   139  }
   140  
   141  func TestStructure_SliceNilValue(t *testing.T) {
   142  	rawMap := map[string]any{
   143  		"foo": 1,
   144  		"bar": []any{"bar", nil},
   145  	}
   146  
   147  	goal := &BazSlice{
   148  		Foo: 1,
   149  		Bar: []string{"bar", ""},
   150  	}
   151  
   152  	s := &BazSlice{}
   153  	err := weakTypeDecoder.Decode(rawMap, s)
   154  	assert.Nil(t, err)
   155  	assert.Equal(t, goal.Bar, s.Bar)
   156  
   157  	s = &BazSlice{}
   158  	err = decoder.Decode(rawMap, s)
   159  	assert.NotNil(t, err)
   160  }
   161  
   162  func TestStructure_SliceNilValueComplex(t *testing.T) {
   163  	rawMap := map[string]any{
   164  		"bar": []any{map[string]any{"bar": "foo"}, nil},
   165  	}
   166  
   167  	s := &struct {
   168  		Bar []map[string]any `test:"bar"`
   169  	}{}
   170  
   171  	err := decoder.Decode(rawMap, s)
   172  	assert.Nil(t, err)
   173  	assert.Nil(t, s.Bar[1])
   174  
   175  	ss := &struct {
   176  		Bar []Baz `test:"bar"`
   177  	}{}
   178  
   179  	err = decoder.Decode(rawMap, ss)
   180  	assert.NotNil(t, err)
   181  }