cast_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. // Copyright 2021-2023 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. "encoding/hex"
  17. "errors"
  18. "fmt"
  19. "net"
  20. "reflect"
  21. "testing"
  22. "github.com/stretchr/testify/assert"
  23. )
  24. func TestToStringAlways(t *testing.T) {
  25. tests := []struct {
  26. input any
  27. want string
  28. }{
  29. {
  30. "test",
  31. "test",
  32. },
  33. {
  34. 100,
  35. "100",
  36. },
  37. {
  38. nil,
  39. "",
  40. },
  41. }
  42. for _, tt := range tests {
  43. assert.Equal(t, tt.want, ToStringAlways(tt.input))
  44. }
  45. }
  46. func TestToString(t *testing.T) {
  47. tests := []struct {
  48. input any
  49. sn Strictness
  50. want string
  51. }{
  52. {
  53. "test",
  54. CONVERT_SAMEKIND,
  55. "test",
  56. },
  57. {
  58. []byte("test"),
  59. CONVERT_SAMEKIND,
  60. "test",
  61. },
  62. {
  63. true,
  64. CONVERT_ALL,
  65. "true",
  66. },
  67. {
  68. nil,
  69. CONVERT_ALL,
  70. "",
  71. },
  72. {
  73. 100,
  74. CONVERT_ALL,
  75. "100",
  76. },
  77. {
  78. int8(100),
  79. CONVERT_ALL,
  80. "100",
  81. },
  82. {
  83. int16(100),
  84. CONVERT_ALL,
  85. "100",
  86. },
  87. {
  88. int32(100),
  89. CONVERT_ALL,
  90. "100",
  91. },
  92. {
  93. int64(100),
  94. CONVERT_ALL,
  95. "100",
  96. },
  97. {
  98. uint(100),
  99. CONVERT_ALL,
  100. "100",
  101. },
  102. {
  103. uint8(100),
  104. CONVERT_ALL,
  105. "100",
  106. },
  107. {
  108. uint16(100),
  109. CONVERT_ALL,
  110. "100",
  111. },
  112. {
  113. uint32(100),
  114. CONVERT_ALL,
  115. "100",
  116. },
  117. {
  118. uint64(100),
  119. CONVERT_ALL,
  120. "100",
  121. },
  122. {
  123. float32(100.001),
  124. CONVERT_ALL,
  125. "100.001",
  126. },
  127. {
  128. 100.001,
  129. CONVERT_ALL,
  130. "100.001",
  131. },
  132. {
  133. // Stringer test case
  134. net.IPv4(0, 0, 0, 0),
  135. CONVERT_ALL,
  136. "0.0.0.0",
  137. },
  138. {
  139. errors.New("test"),
  140. CONVERT_ALL,
  141. "test",
  142. },
  143. }
  144. for _, tt := range tests {
  145. got, err := ToString(tt.input, tt.sn)
  146. assert.NoError(t, err)
  147. assert.Equal(t, tt.want, got)
  148. }
  149. _, err := ToString(struct{}{}, STRICT)
  150. assert.Error(t, err)
  151. }
  152. func TestToIntResult(t *testing.T) {
  153. tests := []struct {
  154. input any
  155. want int64
  156. }{
  157. {
  158. 100,
  159. 100,
  160. },
  161. {
  162. int8(100),
  163. 100,
  164. },
  165. {
  166. int16(100),
  167. 100,
  168. },
  169. {
  170. int32(100),
  171. 100,
  172. },
  173. {
  174. int64(100),
  175. 100,
  176. },
  177. {
  178. uint(100),
  179. 100,
  180. },
  181. {
  182. uint8(100),
  183. 100,
  184. },
  185. {
  186. uint16(100),
  187. 100,
  188. },
  189. {
  190. uint32(100),
  191. 100,
  192. },
  193. {
  194. uint64(100),
  195. 100,
  196. },
  197. {
  198. float32(100),
  199. 100,
  200. },
  201. {
  202. float64(100),
  203. 100,
  204. },
  205. {
  206. "100",
  207. 100,
  208. },
  209. {
  210. false,
  211. 0,
  212. },
  213. {
  214. nil,
  215. 0,
  216. },
  217. }
  218. for _, tt := range tests {
  219. var (
  220. got any
  221. err error
  222. )
  223. got, err = ToInt(tt.input, CONVERT_ALL)
  224. assert.NoError(t, err)
  225. assert.Equal(t, int(tt.want), got)
  226. got, err = ToInt8(tt.input, CONVERT_ALL)
  227. assert.NoError(t, err)
  228. assert.Equal(t, int8(tt.want), got)
  229. got, err = ToInt16(tt.input, CONVERT_ALL)
  230. assert.NoError(t, err)
  231. assert.Equal(t, int16(tt.want), got)
  232. got, err = ToInt32(tt.input, CONVERT_ALL)
  233. assert.NoError(t, err)
  234. assert.Equal(t, int32(tt.want), got)
  235. got, err = ToInt64(tt.input, CONVERT_ALL)
  236. assert.NoError(t, err)
  237. assert.Equal(t, tt.want, got)
  238. }
  239. errTests := []any{
  240. true,
  241. nil,
  242. "1",
  243. }
  244. for _, input := range errTests {
  245. _, err := ToInt(input, STRICT)
  246. assert.Error(t, err)
  247. _, err = ToInt8(input, STRICT)
  248. assert.Error(t, err)
  249. _, err = ToInt16(input, STRICT)
  250. assert.Error(t, err)
  251. _, err = ToInt32(input, STRICT)
  252. assert.Error(t, err)
  253. _, err = ToInt64(input, STRICT)
  254. assert.Error(t, err)
  255. }
  256. }
  257. func TestToUintResult(t *testing.T) {
  258. tests := []struct {
  259. input any
  260. want uint64
  261. }{
  262. {
  263. 100,
  264. 100,
  265. },
  266. {
  267. int8(100),
  268. 100,
  269. },
  270. {
  271. int16(100),
  272. 100,
  273. },
  274. {
  275. int32(100),
  276. 100,
  277. },
  278. {
  279. int64(100),
  280. 100,
  281. },
  282. {
  283. uint(100),
  284. 100,
  285. },
  286. {
  287. uint8(100),
  288. 100,
  289. },
  290. {
  291. uint16(100),
  292. 100,
  293. },
  294. {
  295. uint32(100),
  296. 100,
  297. },
  298. {
  299. uint64(100),
  300. 100,
  301. },
  302. {
  303. float32(100),
  304. 100,
  305. },
  306. {
  307. float64(100),
  308. 100,
  309. },
  310. {
  311. "100",
  312. 100,
  313. },
  314. {
  315. false,
  316. 0,
  317. },
  318. {
  319. nil,
  320. 0,
  321. },
  322. }
  323. for _, tt := range tests {
  324. var (
  325. got any
  326. err error
  327. )
  328. got, err = ToUint8(tt.input, CONVERT_ALL)
  329. assert.NoError(t, err)
  330. assert.Equal(t, uint8(tt.want), got)
  331. got, err = ToUint16(tt.input, CONVERT_ALL)
  332. assert.NoError(t, err)
  333. assert.Equal(t, uint16(tt.want), got)
  334. got, err = ToUint32(tt.input, CONVERT_ALL)
  335. assert.NoError(t, err)
  336. assert.Equal(t, uint32(tt.want), got)
  337. got, err = ToUint64(tt.input, CONVERT_ALL)
  338. assert.NoError(t, err)
  339. assert.Equal(t, tt.want, got)
  340. }
  341. errTests := []any{
  342. -1,
  343. int8(-1),
  344. int16(-1),
  345. int32(-1),
  346. int64(-1),
  347. float32(-1),
  348. float64(-1),
  349. true,
  350. nil,
  351. "1",
  352. }
  353. for _, input := range errTests {
  354. _, err := ToUint8(input, STRICT)
  355. assert.Error(t, err)
  356. _, err = ToUint16(input, STRICT)
  357. assert.Error(t, err)
  358. _, err = ToUint32(input, STRICT)
  359. assert.Error(t, err)
  360. _, err = ToUint64(input, STRICT)
  361. assert.Error(t, err)
  362. }
  363. }
  364. func TestMapConvert(t *testing.T) {
  365. source := map[interface{}]interface{}{
  366. "QUERY_TABLE": "VBAP",
  367. "ROWCOUNT": 10,
  368. "FIELDS": []interface{}{
  369. map[interface{}]interface{}{"FIELDNAME": "MANDT"},
  370. map[interface{}]interface{}{"FIELDNAME": "VBELN"},
  371. map[interface{}]interface{}{"FIELDNAME": "POSNR"},
  372. },
  373. }
  374. assert.Equal(t, map[string]interface{}{
  375. "QUERY_TABLE": "VBAP",
  376. "ROWCOUNT": 10,
  377. "FIELDS": []interface{}{
  378. map[string]interface{}{"FIELDNAME": "MANDT"},
  379. map[string]interface{}{"FIELDNAME": "VBELN"},
  380. map[string]interface{}{"FIELDNAME": "POSNR"},
  381. },
  382. }, ConvertMap(source))
  383. }
  384. func TestToTypedSlice(t *testing.T) {
  385. tests := []struct {
  386. s interface{}
  387. r interface{}
  388. e string
  389. }{
  390. {
  391. s: []interface{}{"abc", 123},
  392. r: []string{"abc", "123"},
  393. },
  394. {
  395. s: []interface{}{"addd", "bbb"},
  396. r: []string{"addd", "bbb"},
  397. },
  398. {
  399. s: []interface{}{nil, "bbb", "ddd"},
  400. e: "cannot convert []interface {}([<nil> bbb ddd]) to string slice for the 0 element: <nil>",
  401. },
  402. }
  403. t.Logf("The test bucket size is %d.", len(tests))
  404. for i, tt := range tests {
  405. result, err := ToTypedSlice(tt.s, func(input interface{}, ssn Strictness) (interface{}, error) {
  406. if input == nil {
  407. return nil, nil
  408. } else {
  409. return fmt.Sprintf("%v", input), nil
  410. }
  411. }, "string", CONVERT_SAMEKIND)
  412. errString := func(err error) string {
  413. if err != nil {
  414. return err.Error()
  415. }
  416. return ""
  417. }
  418. if !reflect.DeepEqual(tt.e, errString(err)) {
  419. t.Errorf("%d: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.e, err)
  420. } else if tt.e == "" && !reflect.DeepEqual(tt.r, result) {
  421. t.Errorf("%d\n\nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.r, result)
  422. }
  423. }
  424. }
  425. func TestMapToStructStrict(t *testing.T) {
  426. type args struct {
  427. input interface{}
  428. output interface{}
  429. expect interface{}
  430. }
  431. type Result struct {
  432. Foo string `json:"foo"`
  433. Bar string `json:"bar"`
  434. }
  435. tests := []struct {
  436. name string
  437. args args
  438. wantErr bool
  439. }{
  440. {
  441. name: "normal parse",
  442. args: args{
  443. input: map[string]interface{}{
  444. "foo": "foo",
  445. "bar": "bar",
  446. },
  447. output: &Result{},
  448. expect: &Result{
  449. Foo: "foo",
  450. Bar: "bar",
  451. },
  452. },
  453. wantErr: false,
  454. },
  455. {
  456. name: "input have more than keys",
  457. args: args{
  458. input: map[string]interface{}{
  459. "foo": "foo",
  460. "bar": "bar",
  461. "foobar": "foobar",
  462. },
  463. output: &Result{},
  464. },
  465. wantErr: true,
  466. },
  467. {
  468. name: "input have less keys",
  469. args: args{
  470. input: map[string]interface{}{
  471. "foo": "foo",
  472. },
  473. output: &Result{},
  474. expect: &Result{
  475. Foo: "foo",
  476. },
  477. },
  478. wantErr: false,
  479. },
  480. {
  481. name: "input have unused keys",
  482. args: args{
  483. input: map[string]interface{}{
  484. "foo": "foo",
  485. "foobar": "foobar",
  486. },
  487. output: &Result{},
  488. },
  489. wantErr: true,
  490. },
  491. }
  492. for _, tt := range tests {
  493. t.Run(tt.name, func(t *testing.T) {
  494. err := MapToStructStrict(tt.args.input, tt.args.output)
  495. if (err != nil) != tt.wantErr {
  496. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  497. }
  498. if tt.wantErr == false && !reflect.DeepEqual(tt.args.output, tt.args.expect) {
  499. t.Errorf(" got = %v, want %v", tt.args.output, tt.args.expect)
  500. }
  501. })
  502. }
  503. }
  504. func TestMapToStruct(t *testing.T) {
  505. type args struct {
  506. input interface{}
  507. output interface{}
  508. expect interface{}
  509. }
  510. type Result struct {
  511. Foo string `json:"foo"`
  512. Bar string `json:"bar"`
  513. }
  514. tests := []struct {
  515. name string
  516. args args
  517. wantErr bool
  518. }{
  519. {
  520. name: "normal parse",
  521. args: args{
  522. input: map[string]interface{}{
  523. "foo": "foo",
  524. "bar": "bar",
  525. },
  526. output: &Result{},
  527. expect: &Result{
  528. Foo: "foo",
  529. Bar: "bar",
  530. },
  531. },
  532. wantErr: false,
  533. },
  534. {
  535. name: "input have more than keys",
  536. args: args{
  537. input: map[string]interface{}{
  538. "foo": "foo",
  539. "bar": "bar",
  540. "foobar": "foobar",
  541. },
  542. output: &Result{},
  543. expect: &Result{
  544. Foo: "foo",
  545. Bar: "bar",
  546. },
  547. },
  548. wantErr: false,
  549. },
  550. {
  551. name: "input have less keys",
  552. args: args{
  553. input: map[string]interface{}{
  554. "foo": "foo",
  555. },
  556. output: &Result{},
  557. expect: &Result{
  558. Foo: "foo",
  559. },
  560. },
  561. wantErr: false,
  562. },
  563. {
  564. name: "input have unused keys",
  565. args: args{
  566. input: map[string]interface{}{
  567. "foo": "foo",
  568. "foobar": "foobar",
  569. },
  570. output: &Result{},
  571. expect: &Result{
  572. Foo: "foo",
  573. },
  574. },
  575. wantErr: false,
  576. },
  577. }
  578. for _, tt := range tests {
  579. t.Run(tt.name, func(t *testing.T) {
  580. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  581. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  582. }
  583. })
  584. }
  585. }
  586. func TestMapToStructNotCaseSensitive(t *testing.T) {
  587. type args struct {
  588. input interface{}
  589. output interface{}
  590. expect interface{}
  591. }
  592. type Result struct {
  593. Foo string `json:"foo"`
  594. Bar string
  595. }
  596. tests := []struct {
  597. name string
  598. args args
  599. wantErr bool
  600. }{
  601. {
  602. name: "normal parse",
  603. args: args{
  604. input: map[string]interface{}{
  605. "foo": "foo",
  606. "bar": "bar",
  607. },
  608. output: &Result{},
  609. expect: &Result{
  610. Foo: "foo",
  611. Bar: "bar",
  612. },
  613. },
  614. wantErr: false,
  615. },
  616. {
  617. name: "not case sensitive",
  618. args: args{
  619. input: map[string]interface{}{
  620. "FOO": "foo",
  621. "BAR": "bar",
  622. },
  623. output: &Result{},
  624. expect: &Result{
  625. Foo: "foo",
  626. Bar: "bar",
  627. },
  628. },
  629. wantErr: false,
  630. },
  631. {
  632. name: "keys must match",
  633. args: args{
  634. input: map[string]interface{}{
  635. "foo": "foo",
  636. "BARS": "bars",
  637. },
  638. output: &Result{},
  639. expect: &Result{
  640. Foo: "foo",
  641. },
  642. },
  643. wantErr: false,
  644. },
  645. }
  646. for _, tt := range tests {
  647. t.Run(tt.name, func(t *testing.T) {
  648. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  649. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  650. }
  651. })
  652. }
  653. }
  654. func TestMapToStructTag(t *testing.T) {
  655. type args struct {
  656. input interface{}
  657. output interface{}
  658. expect interface{}
  659. }
  660. type Result struct {
  661. Foo string `json:"fo"`
  662. Bar string
  663. }
  664. tests := []struct {
  665. name string
  666. args args
  667. wantErr bool
  668. }{
  669. {
  670. name: "normal parse",
  671. args: args{
  672. input: map[string]interface{}{
  673. "fo": "foo",
  674. "bar": "bar",
  675. },
  676. output: &Result{},
  677. expect: &Result{
  678. Foo: "foo",
  679. Bar: "bar",
  680. },
  681. },
  682. wantErr: false,
  683. },
  684. {
  685. name: "key tag not match",
  686. args: args{
  687. input: map[string]interface{}{
  688. "FOO": "foo",
  689. "BAR": "bar",
  690. },
  691. output: &Result{},
  692. expect: &Result{
  693. Bar: "bar",
  694. },
  695. },
  696. wantErr: false,
  697. },
  698. {
  699. name: "key tag not match",
  700. args: args{
  701. input: map[string]interface{}{
  702. "foo": "foo",
  703. "BARS": "bars",
  704. },
  705. output: &Result{},
  706. expect: &Result{},
  707. },
  708. wantErr: false,
  709. },
  710. }
  711. for _, tt := range tests {
  712. t.Run(tt.name, func(t *testing.T) {
  713. if err := MapToStruct(tt.args.input, tt.args.output); (err != nil) != tt.wantErr {
  714. t.Errorf("MapToStructure() error = %v, wantErr %v", err, tt.wantErr)
  715. }
  716. })
  717. }
  718. }
  719. func TestToByteA(t *testing.T) {
  720. bytea, _ := hex.DecodeString("736f6d6520646174612077697468200020616e6420efbbbf")
  721. tests := []struct {
  722. input interface{}
  723. output []byte
  724. err string
  725. }{
  726. {
  727. input: "foo",
  728. err: "illegal string foo, must be base64 encoded string",
  729. }, {
  730. input: []byte("foo"),
  731. output: []byte("foo"),
  732. err: "",
  733. }, {
  734. input: 1,
  735. output: nil,
  736. err: "cannot convert int(1) to bytes",
  737. }, {
  738. input: "c29tZSBkYXRhIHdpdGggACBhbmQg77u/",
  739. output: bytea,
  740. },
  741. }
  742. for i, tt := range tests {
  743. r, err := ToByteA(tt.input, CONVERT_SAMEKIND)
  744. if err != nil {
  745. if err.Error() != tt.err {
  746. t.Errorf("%d, ToByteA() error = %v, wantErr %v", i, err, tt.err)
  747. continue
  748. }
  749. } else {
  750. if !reflect.DeepEqual(r, tt.output) {
  751. t.Errorf("%d: ToByteA() = %x, want %x", i, r, tt.output)
  752. }
  753. }
  754. }
  755. }