在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.
 
 
 

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