cast_test.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // Copyright 2021 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cast
  15. import (
  16. "fmt"
  17. "reflect"
  18. "testing"
  19. )
  20. func TestMapConvert_Funcs(t *testing.T) {
  21. source := map[interface{}]interface{}{
  22. "QUERY_TABLE": "VBAP",
  23. "ROWCOUNT": 10,
  24. "FIELDS": []interface{}{
  25. map[interface{}]interface{}{"FIELDNAME": "MANDT"},
  26. map[interface{}]interface{}{"FIELDNAME": "VBELN"},
  27. map[interface{}]interface{}{"FIELDNAME": "POSNR"},
  28. },
  29. }
  30. exp := map[string]interface{}{
  31. "QUERY_TABLE": "VBAP",
  32. "ROWCOUNT": 10,
  33. "FIELDS": []interface{}{
  34. map[string]interface{}{"FIELDNAME": "MANDT"},
  35. map[string]interface{}{"FIELDNAME": "VBELN"},
  36. map[string]interface{}{"FIELDNAME": "POSNR"},
  37. },
  38. }
  39. got := ConvertMap(source)
  40. if !reflect.DeepEqual(exp, got) {
  41. t.Errorf("result mismatch:\n\nexp=%s\n\ngot=%s\n\n", exp, got)
  42. }
  43. }
  44. func TestToTypedSlice(t *testing.T) {
  45. var tests = []struct {
  46. s interface{}
  47. r interface{}
  48. e string
  49. }{
  50. {
  51. s: []interface{}{"abc", 123},
  52. r: []string{"abc", "123"},
  53. },
  54. {
  55. s: []interface{}{"addd", "bbb"},
  56. r: []string{"addd", "bbb"},
  57. },
  58. {
  59. s: []interface{}{nil, "bbb", "ddd"},
  60. e: "cannot convert []interface {}([<nil> bbb ddd]) to string slice for the 0 element: <nil>",
  61. },
  62. }
  63. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  64. for i, tt := range tests {
  65. result, err := ToTypedSlice(tt.s, func(input interface{}, ssn Strictness) (interface{}, error) {
  66. if input == nil {
  67. return nil, nil
  68. } else {
  69. return fmt.Sprintf("%v", input), nil
  70. }
  71. }, "string", CONVERT_SAMEKIND)
  72. if !reflect.DeepEqual(tt.e, errstring(err)) {
  73. t.Errorf("%d: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.e, err)
  74. } else if tt.e == "" && !reflect.DeepEqual(tt.r, result) {
  75. t.Errorf("%d\n\nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.r, result)
  76. }
  77. }
  78. }
  79. func errstring(err error) string {
  80. if err != nil {
  81. return err.Error()
  82. }
  83. return ""
  84. }
  85. func TestMapToStructStrict(t *testing.T) {
  86. type args struct {
  87. input interface{}
  88. output interface{}
  89. expect interface{}
  90. }
  91. type Result struct {
  92. Foo string `json:"foo"`
  93. Bar string `json:"bar"`
  94. }
  95. tests := []struct {
  96. name string
  97. args args
  98. wantErr bool
  99. }{
  100. {
  101. name: "normal parse",
  102. args: args{
  103. input: map[string]interface{}{
  104. "foo": "foo",
  105. "bar": "bar",
  106. },
  107. output: &Result{},
  108. expect: &Result{
  109. Foo: "foo",
  110. Bar: "bar",
  111. },
  112. },
  113. wantErr: false,
  114. },
  115. {
  116. name: "input have more than keys",
  117. args: args{
  118. input: map[string]interface{}{
  119. "foo": "foo",
  120. "bar": "bar",
  121. "foobar": "foobar",
  122. },
  123. output: &Result{},
  124. },
  125. wantErr: true,
  126. },
  127. {
  128. name: "input have less keys",
  129. args: args{
  130. input: map[string]interface{}{
  131. "foo": "foo",
  132. },
  133. output: &Result{},
  134. expect: &Result{
  135. Foo: "foo",
  136. },
  137. },
  138. wantErr: false,
  139. },
  140. {
  141. name: "input have unused keys",
  142. args: args{
  143. input: map[string]interface{}{
  144. "foo": "foo",
  145. "foobar": "foobar",
  146. },
  147. output: &Result{},
  148. },
  149. wantErr: true,
  150. },
  151. }
  152. for _, tt := range tests {
  153. t.Run(tt.name, func(t *testing.T) {
  154. err := MapToStructStrict(tt.args.input, tt.args.output)
  155. if (err != nil) != tt.wantErr {
  156. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  157. }
  158. if tt.wantErr == false && !reflect.DeepEqual(tt.args.output, tt.args.expect) {
  159. t.Errorf(" got = %v, want %v", tt.args.output, tt.args.expect)
  160. }
  161. })
  162. }
  163. }
  164. func TestMapToStruct(t *testing.T) {
  165. type args struct {
  166. input interface{}
  167. output interface{}
  168. expect interface{}
  169. }
  170. type Result struct {
  171. Foo string `json:"foo"`
  172. Bar string `json:"bar"`
  173. }
  174. tests := []struct {
  175. name string
  176. args args
  177. wantErr bool
  178. }{
  179. {
  180. name: "normal parse",
  181. args: args{
  182. input: map[string]interface{}{
  183. "foo": "foo",
  184. "bar": "bar",
  185. },
  186. output: &Result{},
  187. expect: &Result{
  188. Foo: "foo",
  189. Bar: "bar",
  190. },
  191. },
  192. wantErr: false,
  193. },
  194. {
  195. name: "input have more than keys",
  196. args: args{
  197. input: map[string]interface{}{
  198. "foo": "foo",
  199. "bar": "bar",
  200. "foobar": "foobar",
  201. },
  202. output: &Result{},
  203. expect: &Result{
  204. Foo: "foo",
  205. Bar: "bar",
  206. },
  207. },
  208. wantErr: false,
  209. },
  210. {
  211. name: "input have less keys",
  212. args: args{
  213. input: map[string]interface{}{
  214. "foo": "foo",
  215. },
  216. output: &Result{},
  217. expect: &Result{
  218. Foo: "foo",
  219. },
  220. },
  221. wantErr: false,
  222. },
  223. {
  224. name: "input have unused keys",
  225. args: args{
  226. input: map[string]interface{}{
  227. "foo": "foo",
  228. "foobar": "foobar",
  229. },
  230. output: &Result{},
  231. expect: &Result{
  232. Foo: "foo",
  233. },
  234. },
  235. wantErr: false,
  236. },
  237. }
  238. for _, tt := range tests {
  239. t.Run(tt.name, func(t *testing.T) {
  240. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  241. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  242. }
  243. })
  244. }
  245. }
  246. func TestMapToStructNotCaseSensitive(t *testing.T) {
  247. type args struct {
  248. input interface{}
  249. output interface{}
  250. expect interface{}
  251. }
  252. type Result struct {
  253. Foo string `json:"foo"`
  254. Bar string
  255. }
  256. tests := []struct {
  257. name string
  258. args args
  259. wantErr bool
  260. }{
  261. {
  262. name: "normal parse",
  263. args: args{
  264. input: map[string]interface{}{
  265. "foo": "foo",
  266. "bar": "bar",
  267. },
  268. output: &Result{},
  269. expect: &Result{
  270. Foo: "foo",
  271. Bar: "bar",
  272. },
  273. },
  274. wantErr: false,
  275. },
  276. {
  277. name: "not case sensitive",
  278. args: args{
  279. input: map[string]interface{}{
  280. "FOO": "foo",
  281. "BAR": "bar",
  282. },
  283. output: &Result{},
  284. expect: &Result{
  285. Foo: "foo",
  286. Bar: "bar",
  287. },
  288. },
  289. wantErr: false,
  290. },
  291. {
  292. name: "keys must match",
  293. args: args{
  294. input: map[string]interface{}{
  295. "foo": "foo",
  296. "BARS": "bars",
  297. },
  298. output: &Result{},
  299. expect: &Result{
  300. Foo: "foo",
  301. },
  302. },
  303. wantErr: false,
  304. },
  305. }
  306. for _, tt := range tests {
  307. t.Run(tt.name, func(t *testing.T) {
  308. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  309. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  310. }
  311. })
  312. }
  313. }
  314. func TestMapToStructTag(t *testing.T) {
  315. type args struct {
  316. input interface{}
  317. output interface{}
  318. expect interface{}
  319. }
  320. type Result struct {
  321. Foo string `json:"fo"`
  322. Bar string
  323. }
  324. tests := []struct {
  325. name string
  326. args args
  327. wantErr bool
  328. }{
  329. {
  330. name: "normal parse",
  331. args: args{
  332. input: map[string]interface{}{
  333. "fo": "foo",
  334. "bar": "bar",
  335. },
  336. output: &Result{},
  337. expect: &Result{
  338. Foo: "foo",
  339. Bar: "bar",
  340. },
  341. },
  342. wantErr: false,
  343. },
  344. {
  345. name: "key tag not match",
  346. args: args{
  347. input: map[string]interface{}{
  348. "FOO": "foo",
  349. "BAR": "bar",
  350. },
  351. output: &Result{},
  352. expect: &Result{
  353. Bar: "bar",
  354. },
  355. },
  356. wantErr: false,
  357. },
  358. {
  359. name: "key tag not match",
  360. args: args{
  361. input: map[string]interface{}{
  362. "foo": "foo",
  363. "BARS": "bars",
  364. },
  365. output: &Result{},
  366. expect: &Result{},
  367. },
  368. wantErr: false,
  369. },
  370. }
  371. for _, tt := range tests {
  372. t.Run(tt.name, func(t *testing.T) {
  373. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  374. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  375. }
  376. })
  377. }
  378. }