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 }