在Go中轻松安全地从一种数据类型转换为另一种数据类型
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1288 lines
33 KiB

  1. // Copyright © 2014 Steve Francia <spf@spf13.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package cast
  6. import (
  7. "fmt"
  8. "html/template"
  9. "testing"
  10. "time"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. func TestToUintE(t *testing.T) {
  14. tests := []struct {
  15. input interface{}
  16. expect uint
  17. iserr bool
  18. }{
  19. {int(8), 8, false},
  20. {int8(8), 8, false},
  21. {int16(8), 8, false},
  22. {int32(8), 8, false},
  23. {int64(8), 8, false},
  24. {uint(8), 8, false},
  25. {uint8(8), 8, false},
  26. {uint16(8), 8, false},
  27. {uint32(8), 8, false},
  28. {uint64(8), 8, false},
  29. {float32(8.31), 8, false},
  30. {float64(8.31), 8, false},
  31. {true, 1, false},
  32. {false, 0, false},
  33. {"8", 8, false},
  34. {nil, 0, false},
  35. // errors
  36. {int(-8), 0, true},
  37. {int8(-8), 0, true},
  38. {int16(-8), 0, true},
  39. {int32(-8), 0, true},
  40. {int64(-8), 0, true},
  41. {float32(-8.31), 0, true},
  42. {float64(-8.31), 0, true},
  43. {"-8", 0, true},
  44. {"test", 0, true},
  45. {testing.T{}, 0, true},
  46. }
  47. for i, test := range tests {
  48. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  49. v, err := ToUintE(test.input)
  50. if test.iserr {
  51. assert.Error(t, err, errmsg)
  52. continue
  53. }
  54. assert.NoError(t, err, errmsg)
  55. assert.Equal(t, test.expect, v, errmsg)
  56. // Non-E test:
  57. v = ToUint(test.input)
  58. assert.Equal(t, test.expect, v, errmsg)
  59. }
  60. }
  61. func TestToUint64E(t *testing.T) {
  62. tests := []struct {
  63. input interface{}
  64. expect uint64
  65. iserr bool
  66. }{
  67. {int(8), 8, false},
  68. {int8(8), 8, false},
  69. {int16(8), 8, false},
  70. {int32(8), 8, false},
  71. {int64(8), 8, false},
  72. {uint(8), 8, false},
  73. {uint8(8), 8, false},
  74. {uint16(8), 8, false},
  75. {uint32(8), 8, false},
  76. {uint64(8), 8, false},
  77. {float32(8.31), 8, false},
  78. {float64(8.31), 8, false},
  79. {true, 1, false},
  80. {false, 0, false},
  81. {"8", 8, false},
  82. {nil, 0, false},
  83. // errors
  84. {int(-8), 0, true},
  85. {int8(-8), 0, true},
  86. {int16(-8), 0, true},
  87. {int32(-8), 0, true},
  88. {int64(-8), 0, true},
  89. {float32(-8.31), 0, true},
  90. {float64(-8.31), 0, true},
  91. {"-8", 0, true},
  92. {"test", 0, true},
  93. {testing.T{}, 0, true},
  94. }
  95. for i, test := range tests {
  96. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  97. v, err := ToUint64E(test.input)
  98. if test.iserr {
  99. assert.Error(t, err, errmsg)
  100. continue
  101. }
  102. assert.NoError(t, err, errmsg)
  103. assert.Equal(t, test.expect, v, errmsg)
  104. // Non-E test:
  105. v = ToUint64(test.input)
  106. assert.Equal(t, test.expect, v, errmsg)
  107. }
  108. }
  109. func TestToUint32E(t *testing.T) {
  110. tests := []struct {
  111. input interface{}
  112. expect uint32
  113. iserr bool
  114. }{
  115. {int(8), 8, false},
  116. {int8(8), 8, false},
  117. {int16(8), 8, false},
  118. {int32(8), 8, false},
  119. {int64(8), 8, false},
  120. {uint(8), 8, false},
  121. {uint8(8), 8, false},
  122. {uint16(8), 8, false},
  123. {uint32(8), 8, false},
  124. {uint64(8), 8, false},
  125. {float32(8.31), 8, false},
  126. {float64(8.31), 8, false},
  127. {true, 1, false},
  128. {false, 0, false},
  129. {"8", 8, false},
  130. {nil, 0, false},
  131. {int(-8), 0, true},
  132. {int8(-8), 0, true},
  133. {int16(-8), 0, true},
  134. {int32(-8), 0, true},
  135. {int64(-8), 0, true},
  136. {float32(-8.31), 0, true},
  137. {float64(-8.31), 0, true},
  138. {"-8", 0, true},
  139. // errors
  140. {"test", 0, true},
  141. {testing.T{}, 0, true},
  142. }
  143. for i, test := range tests {
  144. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  145. v, err := ToUint32E(test.input)
  146. if test.iserr {
  147. assert.Error(t, err, errmsg)
  148. continue
  149. }
  150. assert.NoError(t, err, errmsg)
  151. assert.Equal(t, test.expect, v, errmsg)
  152. // Non-E test:
  153. v = ToUint32(test.input)
  154. assert.Equal(t, test.expect, v, errmsg)
  155. }
  156. }
  157. func TestToUint16E(t *testing.T) {
  158. tests := []struct {
  159. input interface{}
  160. expect uint16
  161. iserr bool
  162. }{
  163. {int(8), 8, false},
  164. {int8(8), 8, false},
  165. {int16(8), 8, false},
  166. {int32(8), 8, false},
  167. {int64(8), 8, false},
  168. {uint(8), 8, false},
  169. {uint8(8), 8, false},
  170. {uint16(8), 8, false},
  171. {uint32(8), 8, false},
  172. {uint64(8), 8, false},
  173. {float32(8.31), 8, false},
  174. {float64(8.31), 8, false},
  175. {true, 1, false},
  176. {false, 0, false},
  177. {"8", 8, false},
  178. {nil, 0, false},
  179. // errors
  180. {int(-8), 0, true},
  181. {int8(-8), 0, true},
  182. {int16(-8), 0, true},
  183. {int32(-8), 0, true},
  184. {int64(-8), 0, true},
  185. {float32(-8.31), 0, true},
  186. {float64(-8.31), 0, true},
  187. {"-8", 0, true},
  188. {"test", 0, true},
  189. {testing.T{}, 0, true},
  190. }
  191. for i, test := range tests {
  192. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  193. v, err := ToUint16E(test.input)
  194. if test.iserr {
  195. assert.Error(t, err, errmsg)
  196. continue
  197. }
  198. assert.NoError(t, err, errmsg)
  199. assert.Equal(t, test.expect, v, errmsg)
  200. // Non-E test
  201. v = ToUint16(test.input)
  202. assert.Equal(t, test.expect, v, errmsg)
  203. }
  204. }
  205. func TestToUint8E(t *testing.T) {
  206. tests := []struct {
  207. input interface{}
  208. expect uint8
  209. iserr bool
  210. }{
  211. {int(8), 8, false},
  212. {int8(8), 8, false},
  213. {int16(8), 8, false},
  214. {int32(8), 8, false},
  215. {int64(8), 8, false},
  216. {uint(8), 8, false},
  217. {uint8(8), 8, false},
  218. {uint16(8), 8, false},
  219. {uint32(8), 8, false},
  220. {uint64(8), 8, false},
  221. {float32(8.31), 8, false},
  222. {float64(8.31), 8, false},
  223. {true, 1, false},
  224. {false, 0, false},
  225. {"8", 8, false},
  226. {nil, 0, false},
  227. // errors
  228. {int(-8), 0, true},
  229. {int8(-8), 0, true},
  230. {int16(-8), 0, true},
  231. {int32(-8), 0, true},
  232. {int64(-8), 0, true},
  233. {float32(-8.31), 0, true},
  234. {float64(-8.31), 0, true},
  235. {"-8", 0, true},
  236. {"test", 0, true},
  237. {testing.T{}, 0, true},
  238. }
  239. for i, test := range tests {
  240. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  241. v, err := ToUint8E(test.input)
  242. if test.iserr {
  243. assert.Error(t, err, errmsg)
  244. continue
  245. }
  246. assert.NoError(t, err, errmsg)
  247. assert.Equal(t, test.expect, v, errmsg)
  248. // Non-E test
  249. v = ToUint8(test.input)
  250. assert.Equal(t, test.expect, v, errmsg)
  251. }
  252. }
  253. func TestToIntE(t *testing.T) {
  254. tests := []struct {
  255. input interface{}
  256. expect int
  257. iserr bool
  258. }{
  259. {int(8), 8, false},
  260. {int8(8), 8, false},
  261. {int16(8), 8, false},
  262. {int32(8), 8, false},
  263. {int64(8), 8, false},
  264. {uint(8), 8, false},
  265. {uint8(8), 8, false},
  266. {uint16(8), 8, false},
  267. {uint32(8), 8, false},
  268. {uint64(8), 8, false},
  269. {float32(8.31), 8, false},
  270. {float64(8.31), 8, false},
  271. {true, 1, false},
  272. {false, 0, false},
  273. {"8", 8, false},
  274. {nil, 0, false},
  275. // errors
  276. {"test", 0, true},
  277. {testing.T{}, 0, true},
  278. }
  279. for i, test := range tests {
  280. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  281. v, err := ToIntE(test.input)
  282. if test.iserr {
  283. assert.Error(t, err, errmsg)
  284. continue
  285. }
  286. assert.NoError(t, err, errmsg)
  287. assert.Equal(t, test.expect, v, errmsg)
  288. // Non-E test
  289. v = ToInt(test.input)
  290. assert.Equal(t, test.expect, v, errmsg)
  291. }
  292. }
  293. func TestToInt64E(t *testing.T) {
  294. tests := []struct {
  295. input interface{}
  296. expect int64
  297. iserr bool
  298. }{
  299. {int(8), 8, false},
  300. {int8(8), 8, false},
  301. {int16(8), 8, false},
  302. {int32(8), 8, false},
  303. {int64(8), 8, false},
  304. {uint(8), 8, false},
  305. {uint8(8), 8, false},
  306. {uint16(8), 8, false},
  307. {uint32(8), 8, false},
  308. {uint64(8), 8, false},
  309. {float32(8.31), 8, false},
  310. {float64(8.31), 8, false},
  311. {true, 1, false},
  312. {false, 0, false},
  313. {"8", 8, false},
  314. {nil, 0, false},
  315. // errors
  316. {"test", 0, true},
  317. {testing.T{}, 0, true},
  318. }
  319. for i, test := range tests {
  320. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  321. v, err := ToInt64E(test.input)
  322. if test.iserr {
  323. assert.Error(t, err, errmsg)
  324. continue
  325. }
  326. assert.NoError(t, err, errmsg)
  327. assert.Equal(t, test.expect, v, errmsg)
  328. // Non-E test
  329. v = ToInt64(test.input)
  330. assert.Equal(t, test.expect, v, errmsg)
  331. }
  332. }
  333. func TestToInt32E(t *testing.T) {
  334. tests := []struct {
  335. input interface{}
  336. expect int32
  337. iserr bool
  338. }{
  339. {int(8), 8, false},
  340. {int8(8), 8, false},
  341. {int16(8), 8, false},
  342. {int32(8), 8, false},
  343. {int64(8), 8, false},
  344. {uint(8), 8, false},
  345. {uint8(8), 8, false},
  346. {uint16(8), 8, false},
  347. {uint32(8), 8, false},
  348. {uint64(8), 8, false},
  349. {float32(8.31), 8, false},
  350. {float64(8.31), 8, false},
  351. {true, 1, false},
  352. {false, 0, false},
  353. {"8", 8, false},
  354. {nil, 0, false},
  355. // errors
  356. {"test", 0, true},
  357. {testing.T{}, 0, true},
  358. }
  359. for i, test := range tests {
  360. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  361. v, err := ToInt32E(test.input)
  362. if test.iserr {
  363. assert.Error(t, err, errmsg)
  364. continue
  365. }
  366. assert.NoError(t, err, errmsg)
  367. assert.Equal(t, test.expect, v, errmsg)
  368. // Non-E test
  369. v = ToInt32(test.input)
  370. assert.Equal(t, test.expect, v, errmsg)
  371. }
  372. }
  373. func TestToInt16E(t *testing.T) {
  374. tests := []struct {
  375. input interface{}
  376. expect int16
  377. iserr bool
  378. }{
  379. {int(8), 8, false},
  380. {int8(8), 8, false},
  381. {int16(8), 8, false},
  382. {int32(8), 8, false},
  383. {int64(8), 8, false},
  384. {uint(8), 8, false},
  385. {uint8(8), 8, false},
  386. {uint16(8), 8, false},
  387. {uint32(8), 8, false},
  388. {uint64(8), 8, false},
  389. {float32(8.31), 8, false},
  390. {float64(8.31), 8, false},
  391. {true, 1, false},
  392. {false, 0, false},
  393. {"8", 8, false},
  394. {nil, 0, false},
  395. // errors
  396. {"test", 0, true},
  397. {testing.T{}, 0, true},
  398. }
  399. for i, test := range tests {
  400. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  401. v, err := ToInt16E(test.input)
  402. if test.iserr {
  403. assert.Error(t, err, errmsg)
  404. continue
  405. }
  406. assert.NoError(t, err, errmsg)
  407. assert.Equal(t, test.expect, v, errmsg)
  408. // Non-E test
  409. v = ToInt16(test.input)
  410. assert.Equal(t, test.expect, v, errmsg)
  411. }
  412. }
  413. func TestToInt8E(t *testing.T) {
  414. tests := []struct {
  415. input interface{}
  416. expect int8
  417. iserr bool
  418. }{
  419. {int(8), 8, false},
  420. {int8(8), 8, false},
  421. {int16(8), 8, false},
  422. {int32(8), 8, false},
  423. {int64(8), 8, false},
  424. {uint(8), 8, false},
  425. {uint8(8), 8, false},
  426. {uint16(8), 8, false},
  427. {uint32(8), 8, false},
  428. {uint64(8), 8, false},
  429. {float32(8.31), 8, false},
  430. {float64(8.31), 8, false},
  431. {true, 1, false},
  432. {false, 0, false},
  433. {"8", 8, false},
  434. {nil, 0, false},
  435. // errors
  436. {"test", 0, true},
  437. {testing.T{}, 0, true},
  438. }
  439. for i, test := range tests {
  440. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  441. v, err := ToInt8E(test.input)
  442. if test.iserr {
  443. assert.Error(t, err, errmsg)
  444. continue
  445. }
  446. assert.NoError(t, err, errmsg)
  447. assert.Equal(t, test.expect, v, errmsg)
  448. // Non-E test
  449. v = ToInt8(test.input)
  450. assert.Equal(t, test.expect, v, errmsg)
  451. }
  452. }
  453. func TestToFloat64E(t *testing.T) {
  454. tests := []struct {
  455. input interface{}
  456. expect float64
  457. iserr bool
  458. }{
  459. {int(8), 8, false},
  460. {int8(8), 8, false},
  461. {int16(8), 8, false},
  462. {int32(8), 8, false},
  463. {int64(8), 8, false},
  464. {uint(8), 8, false},
  465. {uint8(8), 8, false},
  466. {uint16(8), 8, false},
  467. {uint32(8), 8, false},
  468. {uint64(8), 8, false},
  469. {float32(8), 8, false},
  470. {float64(8.31), 8.31, false},
  471. {"8", 8, false},
  472. {true, 1, false},
  473. {false, 0, false},
  474. // errors
  475. {"test", 0, true},
  476. {testing.T{}, 0, true},
  477. }
  478. for i, test := range tests {
  479. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  480. v, err := ToFloat64E(test.input)
  481. if test.iserr {
  482. assert.Error(t, err, errmsg)
  483. continue
  484. }
  485. assert.NoError(t, err, errmsg)
  486. assert.Equal(t, test.expect, v, errmsg)
  487. // Non-E test
  488. v = ToFloat64(test.input)
  489. assert.Equal(t, test.expect, v, errmsg)
  490. }
  491. }
  492. func TestToFloat32E(t *testing.T) {
  493. tests := []struct {
  494. input interface{}
  495. expect float32
  496. iserr bool
  497. }{
  498. {int(8), 8, false},
  499. {int8(8), 8, false},
  500. {int16(8), 8, false},
  501. {int32(8), 8, false},
  502. {int64(8), 8, false},
  503. {uint(8), 8, false},
  504. {uint8(8), 8, false},
  505. {uint16(8), 8, false},
  506. {uint32(8), 8, false},
  507. {uint64(8), 8, false},
  508. {float32(8.31), 8.31, false},
  509. {float64(8.31), 8.31, false},
  510. {"8", 8, false},
  511. {true, 1, false},
  512. {false, 0, false},
  513. // errors
  514. {"test", 0, true},
  515. {testing.T{}, 0, true},
  516. }
  517. for i, test := range tests {
  518. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  519. v, err := ToFloat32E(test.input)
  520. if test.iserr {
  521. assert.Error(t, err, errmsg)
  522. continue
  523. }
  524. assert.NoError(t, err, errmsg)
  525. assert.Equal(t, test.expect, v, errmsg)
  526. // Non-E test
  527. v = ToFloat32(test.input)
  528. assert.Equal(t, test.expect, v, errmsg)
  529. }
  530. }
  531. func TestToStringE(t *testing.T) {
  532. type Key struct {
  533. k string
  534. }
  535. key := &Key{"foo"}
  536. tests := []struct {
  537. input interface{}
  538. expect string
  539. iserr bool
  540. }{
  541. {int(8), "8", false},
  542. {int8(8), "8", false},
  543. {int16(8), "8", false},
  544. {int32(8), "8", false},
  545. {int64(8), "8", false},
  546. {uint(8), "8", false},
  547. {uint8(8), "8", false},
  548. {uint16(8), "8", false},
  549. {uint32(8), "8", false},
  550. {uint64(8), "8", false},
  551. {float32(8.31), "8.31", false},
  552. {float64(8.31), "8.31", false},
  553. {true, "true", false},
  554. {false, "false", false},
  555. {nil, "", false},
  556. {[]byte("one time"), "one time", false},
  557. {"one more time", "one more time", false},
  558. {template.HTML("one time"), "one time", false},
  559. {template.URL("http://somehost.foo"), "http://somehost.foo", false},
  560. {template.JS("(1+2)"), "(1+2)", false},
  561. {template.CSS("a"), "a", false},
  562. {template.HTMLAttr("a"), "a", false},
  563. // errors
  564. {testing.T{}, "", true},
  565. {key, "", true},
  566. }
  567. for i, test := range tests {
  568. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  569. v, err := ToStringE(test.input)
  570. if test.iserr {
  571. assert.Error(t, err, errmsg)
  572. continue
  573. }
  574. assert.NoError(t, err, errmsg)
  575. assert.Equal(t, test.expect, v, errmsg)
  576. // Non-E test
  577. v = ToString(test.input)
  578. assert.Equal(t, test.expect, v, errmsg)
  579. }
  580. }
  581. type foo struct {
  582. val string
  583. }
  584. func (x foo) String() string {
  585. return x.val
  586. }
  587. func TestStringerToString(t *testing.T) {
  588. var x foo
  589. x.val = "bar"
  590. assert.Equal(t, "bar", ToString(x))
  591. }
  592. type fu struct {
  593. val string
  594. }
  595. func (x fu) Error() string {
  596. return x.val
  597. }
  598. func TestErrorToString(t *testing.T) {
  599. var x fu
  600. x.val = "bar"
  601. assert.Equal(t, "bar", ToString(x))
  602. }
  603. func TestStringMapStringSliceE(t *testing.T) {
  604. // ToStringMapString inputs/outputs
  605. var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  606. var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  607. var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  608. var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  609. // ToStringMapStringSlice inputs/outputs
  610. var stringMapStringSlice = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
  611. var stringMapInterfaceSlice = map[string][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
  612. var stringMapInterfaceInterfaceSlice = map[string]interface{}{"key 1": []interface{}{"value 1", "value 2", "value 3"}, "key 2": []interface{}{"value 1", "value 2", "value 3"}, "key 3": []interface{}{"value 1", "value 2", "value 3"}}
  613. var stringMapStringSingleSliceFieldsResult = map[string][]string{"key 1": {"value", "1"}, "key 2": {"value", "2"}, "key 3": {"value", "3"}}
  614. var interfaceMapStringSlice = map[interface{}][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
  615. var interfaceMapInterfaceSlice = map[interface{}][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
  616. var stringMapStringSliceMultiple = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
  617. var stringMapStringSliceSingle = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}, "key 3": {"value 3"}}
  618. var stringMapInterface1 = map[string]interface{}{"key 1": []string{"value 1"}, "key 2": []string{"value 2"}}
  619. var stringMapInterfaceResult1 = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}}
  620. var jsonStringMapString = `{"key 1": "value 1", "key 2": "value 2"}`
  621. var jsonStringMapStringArray = `{"key 1": ["value 1"], "key 2": ["value 2", "value 3"]}`
  622. var jsonStringMapStringArrayResult = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2", "value 3"}}
  623. type Key struct {
  624. k string
  625. }
  626. tests := []struct {
  627. input interface{}
  628. expect map[string][]string
  629. iserr bool
  630. }{
  631. {stringMapStringSlice, stringMapStringSlice, false},
  632. {stringMapInterfaceSlice, stringMapStringSlice, false},
  633. {stringMapInterfaceInterfaceSlice, stringMapStringSlice, false},
  634. {stringMapStringSliceMultiple, stringMapStringSlice, false},
  635. {stringMapStringSliceMultiple, stringMapStringSlice, false},
  636. {stringMapString, stringMapStringSliceSingle, false},
  637. {stringMapInterface, stringMapStringSliceSingle, false},
  638. {stringMapInterface1, stringMapInterfaceResult1, false},
  639. {interfaceMapStringSlice, stringMapStringSlice, false},
  640. {interfaceMapInterfaceSlice, stringMapStringSlice, false},
  641. {interfaceMapString, stringMapStringSingleSliceFieldsResult, false},
  642. {interfaceMapInterface, stringMapStringSingleSliceFieldsResult, false},
  643. {jsonStringMapStringArray, jsonStringMapStringArrayResult, false},
  644. // errors
  645. {nil, nil, true},
  646. {testing.T{}, nil, true},
  647. {map[interface{}]interface{}{"foo": testing.T{}}, nil, true},
  648. {map[interface{}]interface{}{Key{"foo"}: "bar"}, nil, true}, // ToStringE(Key{"foo"}) should fail
  649. {jsonStringMapString, nil, true},
  650. {"", nil, true},
  651. }
  652. for i, test := range tests {
  653. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  654. v, err := ToStringMapStringSliceE(test.input)
  655. if test.iserr {
  656. assert.Error(t, err, errmsg)
  657. continue
  658. }
  659. assert.NoError(t, err, errmsg)
  660. assert.Equal(t, test.expect, v, errmsg)
  661. // Non-E test
  662. v = ToStringMapStringSlice(test.input)
  663. assert.Equal(t, test.expect, v, errmsg)
  664. }
  665. }
  666. func TestToStringMapE(t *testing.T) {
  667. tests := []struct {
  668. input interface{}
  669. expect map[string]interface{}
  670. iserr bool
  671. }{
  672. {map[interface{}]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
  673. {map[string]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
  674. {`{"tag": "tags", "group": "groups"}`, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
  675. {`{"tag": "tags", "group": true}`, map[string]interface{}{"tag": "tags", "group": true}, false},
  676. // errors
  677. {nil, nil, true},
  678. {testing.T{}, nil, true},
  679. {"", nil, true},
  680. }
  681. for i, test := range tests {
  682. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  683. v, err := ToStringMapE(test.input)
  684. if test.iserr {
  685. assert.Error(t, err, errmsg)
  686. continue
  687. }
  688. assert.NoError(t, err, errmsg)
  689. assert.Equal(t, test.expect, v, errmsg)
  690. // Non-E test
  691. v = ToStringMap(test.input)
  692. assert.Equal(t, test.expect, v, errmsg)
  693. }
  694. }
  695. func TestToStringMapBoolE(t *testing.T) {
  696. tests := []struct {
  697. input interface{}
  698. expect map[string]bool
  699. iserr bool
  700. }{
  701. {map[interface{}]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
  702. {map[string]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
  703. {map[string]bool{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
  704. {`{"v1": true, "v2": false}`, map[string]bool{"v1": true, "v2": false}, false},
  705. // errors
  706. {nil, nil, true},
  707. {testing.T{}, nil, true},
  708. {"", nil, true},
  709. }
  710. for i, test := range tests {
  711. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  712. v, err := ToStringMapBoolE(test.input)
  713. if test.iserr {
  714. assert.Error(t, err, errmsg)
  715. continue
  716. }
  717. assert.NoError(t, err, errmsg)
  718. assert.Equal(t, test.expect, v, errmsg)
  719. // Non-E test
  720. v = ToStringMapBool(test.input)
  721. assert.Equal(t, test.expect, v, errmsg)
  722. }
  723. }
  724. func TestToStringMapIntE(t *testing.T) {
  725. tests := []struct {
  726. input interface{}
  727. expect map[string]int
  728. iserr bool
  729. }{
  730. {map[interface{}]interface{}{"v1": 1, "v2": 222}, map[string]int{"v1": 1, "v2": 222}, false},
  731. {map[string]interface{}{"v1": 342, "v2": 5141}, map[string]int{"v1": 342, "v2": 5141}, false},
  732. {map[string]int{"v1": 33, "v2": 88}, map[string]int{"v1": 33, "v2": 88}, false},
  733. {map[string]int32{"v1": int32(33), "v2": int32(88)}, map[string]int{"v1": 33, "v2": 88}, false},
  734. {map[string]uint16{"v1": uint16(33), "v2": uint16(88)}, map[string]int{"v1": 33, "v2": 88}, false},
  735. {map[string]float64{"v1": float64(8.22), "v2": float64(43.32)}, map[string]int{"v1": 8, "v2": 43}, false},
  736. {`{"v1": 67, "v2": 56}`, map[string]int{"v1": 67, "v2": 56}, false},
  737. // errors
  738. {nil, nil, true},
  739. {testing.T{}, nil, true},
  740. {"", nil, true},
  741. }
  742. for i, test := range tests {
  743. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  744. v, err := ToStringMapIntE(test.input)
  745. if test.iserr {
  746. assert.Error(t, err, errmsg)
  747. continue
  748. }
  749. assert.NoError(t, err, errmsg)
  750. assert.Equal(t, test.expect, v, errmsg)
  751. // Non-E test
  752. v = ToStringMapInt(test.input)
  753. assert.Equal(t, test.expect, v, errmsg)
  754. }
  755. }
  756. func TestToStringMapInt64E(t *testing.T) {
  757. tests := []struct {
  758. input interface{}
  759. expect map[string]int64
  760. iserr bool
  761. }{
  762. {map[interface{}]interface{}{"v1": int32(8), "v2": int32(888)}, map[string]int64{"v1": int64(8), "v2": int64(888)}, false},
  763. {map[string]interface{}{"v1": int64(45), "v2": int64(67)}, map[string]int64{"v1": 45, "v2": 67}, false},
  764. {map[string]int64{"v1": 33, "v2": 88}, map[string]int64{"v1": 33, "v2": 88}, false},
  765. {map[string]int{"v1": 33, "v2": 88}, map[string]int64{"v1": 33, "v2": 88}, false},
  766. {map[string]int32{"v1": int32(33), "v2": int32(88)}, map[string]int64{"v1": 33, "v2": 88}, false},
  767. {map[string]uint16{"v1": uint16(33), "v2": uint16(88)}, map[string]int64{"v1": 33, "v2": 88}, false},
  768. {map[string]float64{"v1": float64(8.22), "v2": float64(43.32)}, map[string]int64{"v1": 8, "v2": 43}, false},
  769. {`{"v1": 67, "v2": 56}`, map[string]int64{"v1": 67, "v2": 56}, false},
  770. // errors
  771. {nil, nil, true},
  772. {testing.T{}, nil, true},
  773. {"", nil, true},
  774. }
  775. for i, test := range tests {
  776. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  777. v, err := ToStringMapInt64E(test.input)
  778. if test.iserr {
  779. assert.Error(t, err, errmsg)
  780. continue
  781. }
  782. assert.NoError(t, err, errmsg)
  783. assert.Equal(t, test.expect, v, errmsg)
  784. // Non-E test
  785. v = ToStringMapInt64(test.input)
  786. assert.Equal(t, test.expect, v, errmsg)
  787. }
  788. }
  789. func TestToStringMapStringE(t *testing.T) {
  790. var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  791. var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  792. var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  793. var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
  794. var jsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}`
  795. var invalidJsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"`
  796. var emptyString = ""
  797. tests := []struct {
  798. input interface{}
  799. expect map[string]string
  800. iserr bool
  801. }{
  802. {stringMapString, stringMapString, false},
  803. {stringMapInterface, stringMapString, false},
  804. {interfaceMapString, stringMapString, false},
  805. {interfaceMapInterface, stringMapString, false},
  806. {jsonString, stringMapString, false},
  807. // errors
  808. {nil, nil, true},
  809. {testing.T{}, nil, true},
  810. {invalidJsonString, nil, true},
  811. {emptyString, nil, true},
  812. }
  813. for i, test := range tests {
  814. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  815. v, err := ToStringMapStringE(test.input)
  816. if test.iserr {
  817. assert.Error(t, err, errmsg)
  818. continue
  819. }
  820. assert.NoError(t, err, errmsg)
  821. assert.Equal(t, test.expect, v, errmsg)
  822. // Non-E test
  823. v = ToStringMapString(test.input)
  824. assert.Equal(t, test.expect, v, errmsg)
  825. }
  826. }
  827. func TestToBoolSliceE(t *testing.T) {
  828. tests := []struct {
  829. input interface{}
  830. expect []bool
  831. iserr bool
  832. }{
  833. {[]bool{true, false, true}, []bool{true, false, true}, false},
  834. {[]interface{}{true, false, true}, []bool{true, false, true}, false},
  835. {[]int{1, 0, 1}, []bool{true, false, true}, false},
  836. {[]string{"true", "false", "true"}, []bool{true, false, true}, false},
  837. // errors
  838. {nil, nil, true},
  839. {testing.T{}, nil, true},
  840. {[]string{"foo", "bar"}, nil, true},
  841. }
  842. for i, test := range tests {
  843. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  844. v, err := ToBoolSliceE(test.input)
  845. if test.iserr {
  846. assert.Error(t, err, errmsg)
  847. continue
  848. }
  849. assert.NoError(t, err, errmsg)
  850. assert.Equal(t, test.expect, v, errmsg)
  851. // Non-E test
  852. v = ToBoolSlice(test.input)
  853. assert.Equal(t, test.expect, v, errmsg)
  854. }
  855. }
  856. func TestToIntSliceE(t *testing.T) {
  857. tests := []struct {
  858. input interface{}
  859. expect []int
  860. iserr bool
  861. }{
  862. {[]int{1, 3}, []int{1, 3}, false},
  863. {[]interface{}{1.2, 3.2}, []int{1, 3}, false},
  864. {[]string{"2", "3"}, []int{2, 3}, false},
  865. {[2]string{"2", "3"}, []int{2, 3}, false},
  866. // errors
  867. {nil, nil, true},
  868. {testing.T{}, nil, true},
  869. {[]string{"foo", "bar"}, nil, true},
  870. }
  871. for i, test := range tests {
  872. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  873. v, err := ToIntSliceE(test.input)
  874. if test.iserr {
  875. assert.Error(t, err, errmsg)
  876. continue
  877. }
  878. assert.NoError(t, err, errmsg)
  879. assert.Equal(t, test.expect, v, errmsg)
  880. // Non-E test
  881. v = ToIntSlice(test.input)
  882. assert.Equal(t, test.expect, v, errmsg)
  883. }
  884. }
  885. func TestToSliceE(t *testing.T) {
  886. tests := []struct {
  887. input interface{}
  888. expect []interface{}
  889. iserr bool
  890. }{
  891. {[]interface{}{1, 3}, []interface{}{1, 3}, false},
  892. {[]map[string]interface{}{{"k1": 1}, {"k2": 2}}, []interface{}{map[string]interface{}{"k1": 1}, map[string]interface{}{"k2": 2}}, false},
  893. // errors
  894. {nil, nil, true},
  895. {testing.T{}, nil, true},
  896. }
  897. for i, test := range tests {
  898. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  899. v, err := ToSliceE(test.input)
  900. if test.iserr {
  901. assert.Error(t, err, errmsg)
  902. continue
  903. }
  904. assert.NoError(t, err, errmsg)
  905. assert.Equal(t, test.expect, v, errmsg)
  906. // Non-E test
  907. v = ToSlice(test.input)
  908. assert.Equal(t, test.expect, v, errmsg)
  909. }
  910. }
  911. func TestToStringSliceE(t *testing.T) {
  912. tests := []struct {
  913. input interface{}
  914. expect []string
  915. iserr bool
  916. }{
  917. {[]string{"a", "b"}, []string{"a", "b"}, false},
  918. {[]interface{}{1, 3}, []string{"1", "3"}, false},
  919. {interface{}(1), []string{"1"}, false},
  920. // errors
  921. {nil, nil, true},
  922. {testing.T{}, nil, true},
  923. }
  924. for i, test := range tests {
  925. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  926. v, err := ToStringSliceE(test.input)
  927. if test.iserr {
  928. assert.Error(t, err, errmsg)
  929. continue
  930. }
  931. assert.NoError(t, err, errmsg)
  932. assert.Equal(t, test.expect, v, errmsg)
  933. // Non-E test
  934. v = ToStringSlice(test.input)
  935. assert.Equal(t, test.expect, v, errmsg)
  936. }
  937. }
  938. func TestToDurationSliceE(t *testing.T) {
  939. tests := []struct {
  940. input interface{}
  941. expect []time.Duration
  942. iserr bool
  943. }{
  944. {[]string{"1s", "1m"}, []time.Duration{time.Second, time.Minute}, false},
  945. {[]int{1, 2}, []time.Duration{1, 2}, false},
  946. {[]interface{}{1, 3}, []time.Duration{1, 3}, false},
  947. {[]time.Duration{1, 3}, []time.Duration{1, 3}, false},
  948. // errors
  949. {nil, nil, true},
  950. {testing.T{}, nil, true},
  951. {[]string{"invalid"}, nil, true},
  952. }
  953. for i, test := range tests {
  954. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  955. v, err := ToDurationSliceE(test.input)
  956. if test.iserr {
  957. assert.Error(t, err, errmsg)
  958. continue
  959. }
  960. assert.NoError(t, err, errmsg)
  961. assert.Equal(t, test.expect, v, errmsg)
  962. // Non-E test
  963. v = ToDurationSlice(test.input)
  964. assert.Equal(t, test.expect, v, errmsg)
  965. }
  966. }
  967. func TestToBoolE(t *testing.T) {
  968. tests := []struct {
  969. input interface{}
  970. expect bool
  971. iserr bool
  972. }{
  973. {0, false, false},
  974. {nil, false, false},
  975. {"false", false, false},
  976. {"FALSE", false, false},
  977. {"False", false, false},
  978. {"f", false, false},
  979. {"F", false, false},
  980. {false, false, false},
  981. {"true", true, false},
  982. {"TRUE", true, false},
  983. {"True", true, false},
  984. {"t", true, false},
  985. {"T", true, false},
  986. {1, true, false},
  987. {true, true, false},
  988. {-1, true, false},
  989. // errors
  990. {"test", false, true},
  991. {testing.T{}, false, true},
  992. }
  993. for i, test := range tests {
  994. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  995. v, err := ToBoolE(test.input)
  996. if test.iserr {
  997. assert.Error(t, err, errmsg)
  998. continue
  999. }
  1000. assert.NoError(t, err, errmsg)
  1001. assert.Equal(t, test.expect, v, errmsg)
  1002. // Non-E test
  1003. v = ToBool(test.input)
  1004. assert.Equal(t, test.expect, v, errmsg)
  1005. }
  1006. }
  1007. func BenchmarkTooBool(b *testing.B) {
  1008. for i := 0; i < b.N; i++ {
  1009. if !ToBool(true) {
  1010. b.Fatal("ToBool returned false")
  1011. }
  1012. }
  1013. }
  1014. func TestIndirectPointers(t *testing.T) {
  1015. x := 13
  1016. y := &x
  1017. z := &y
  1018. assert.Equal(t, ToInt(y), 13)
  1019. assert.Equal(t, ToInt(z), 13)
  1020. }
  1021. func TestToTimeEE(t *testing.T) {
  1022. tests := []struct {
  1023. input interface{}
  1024. expect time.Time
  1025. iserr bool
  1026. }{
  1027. {"2009-11-10 23:00:00 +0000 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // Time.String()
  1028. {"Tue Nov 10 23:00:00 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // ANSIC
  1029. {"Tue Nov 10 23:00:00 UTC 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // UnixDate
  1030. {"Tue Nov 10 23:00:00 +0000 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RubyDate
  1031. {"10 Nov 09 23:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC822
  1032. {"10 Nov 09 23:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC822Z
  1033. {"Tuesday, 10-Nov-09 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC850
  1034. {"Tue, 10 Nov 2009 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC1123
  1035. {"Tue, 10 Nov 2009 23:00:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC1123Z
  1036. {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC3339
  1037. {"2018-10-21T23:21:29+0200", time.Date(2018, 10, 21, 21, 21, 29, 0, time.UTC), false}, // RFC3339 without timezone hh:mm colon
  1038. {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC3339Nano
  1039. {"11:00PM", time.Date(0, 1, 1, 23, 0, 0, 0, time.UTC), false}, // Kitchen
  1040. {"Nov 10 23:00:00", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // Stamp
  1041. {"Nov 10 23:00:00.000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampMilli
  1042. {"Nov 10 23:00:00.000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampMicro
  1043. {"Nov 10 23:00:00.000000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampNano
  1044. {"2016-03-06 15:28:01-00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false}, // RFC3339 without T
  1045. {"2016-03-06 15:28:01-0000", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false}, // RFC3339 without T or timezone hh:mm colon
  1046. {"2016-03-06 15:28:01", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
  1047. {"2016-03-06 15:28:01 -0000", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
  1048. {"2016-03-06 15:28:01 -00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
  1049. {"2006-01-02", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
  1050. {"02 Jan 2006", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
  1051. {1472574600, time.Date(2016, 8, 30, 16, 30, 0, 0, time.UTC), false},
  1052. {int(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
  1053. {int64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
  1054. {int32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
  1055. {uint(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
  1056. {uint64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
  1057. {uint32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
  1058. {time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
  1059. // errors
  1060. {"2006", time.Time{}, true},
  1061. {testing.T{}, time.Time{}, true},
  1062. }
  1063. for i, test := range tests {
  1064. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  1065. v, err := ToTimeE(test.input)
  1066. if test.iserr {
  1067. assert.Error(t, err, errmsg)
  1068. continue
  1069. }
  1070. assert.NoError(t, err, errmsg)
  1071. assert.Equal(t, test.expect, v.UTC(), errmsg)
  1072. // Non-E test
  1073. v = ToTime(test.input)
  1074. assert.Equal(t, test.expect, v.UTC(), errmsg)
  1075. }
  1076. }
  1077. func TestToDurationE(t *testing.T) {
  1078. var td time.Duration = 5
  1079. tests := []struct {
  1080. input interface{}
  1081. expect time.Duration
  1082. iserr bool
  1083. }{
  1084. {time.Duration(5), td, false},
  1085. {int(5), td, false},
  1086. {int64(5), td, false},
  1087. {int32(5), td, false},
  1088. {int16(5), td, false},
  1089. {int8(5), td, false},
  1090. {uint(5), td, false},
  1091. {uint64(5), td, false},
  1092. {uint32(5), td, false},
  1093. {uint16(5), td, false},
  1094. {uint8(5), td, false},
  1095. {float64(5), td, false},
  1096. {float32(5), td, false},
  1097. {string("5"), td, false},
  1098. {string("5ns"), td, false},
  1099. {string("5us"), time.Microsecond * td, false},
  1100. {string("5µs"), time.Microsecond * td, false},
  1101. {string("5ms"), time.Millisecond * td, false},
  1102. {string("5s"), time.Second * td, false},
  1103. {string("5m"), time.Minute * td, false},
  1104. {string("5h"), time.Hour * td, false},
  1105. // errors
  1106. {"test", 0, true},
  1107. {testing.T{}, 0, true},
  1108. }
  1109. for i, test := range tests {
  1110. errmsg := fmt.Sprintf("i = %d", i) // assert helper message
  1111. v, err := ToDurationE(test.input)
  1112. if test.iserr {
  1113. assert.Error(t, err, errmsg)
  1114. continue
  1115. }
  1116. assert.NoError(t, err, errmsg)
  1117. assert.Equal(t, test.expect, v, errmsg)
  1118. // Non-E test
  1119. v = ToDuration(test.input)
  1120. assert.Equal(t, test.expect, v, errmsg)
  1121. }
  1122. }