result_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. package help
  2. import (
  3. "math"
  4. "reflect"
  5. "testing"
  6. "unsafe"
  7. )
  8. func TestAll(t *testing.T) {
  9. input := []int{2, 4, 6, 8}
  10. r1 := From(input).All(func(i interface{}) bool {
  11. return i.(int)%2 == 0
  12. })
  13. r2 := From(input).All(func(i interface{}) bool {
  14. return i.(int)%2 != 0
  15. })
  16. if !r1 {
  17. t.Errorf("From(%v).All()=%v", input, r1)
  18. }
  19. if r2 {
  20. t.Errorf("From(%v).All()=%v", input, r2)
  21. }
  22. }
  23. func TestAllT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  24. mustPanicWithError(t, "AllT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  25. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).AllT(func(item int) int { return item + 2 })
  26. })
  27. }
  28. func TestAny(t *testing.T) {
  29. tests := []struct {
  30. input interface{}
  31. want bool
  32. }{
  33. {[]int{1, 2, 2, 3, 1}, true},
  34. {[9]int{1, 1, 1, 2, 1, 2, 3, 4, 2}, true},
  35. {"sstr", true},
  36. {[]int{}, false},
  37. }
  38. for _, test := range tests {
  39. if r := From(test.input).Any(); r != test.want {
  40. t.Errorf("From(%v).Any()=%v expected %v", test.input, r, test.want)
  41. }
  42. }
  43. }
  44. func TestAnyWith(t *testing.T) {
  45. tests := []struct {
  46. input interface{}
  47. want bool
  48. }{
  49. {[]int{1, 2, 2, 3, 1}, false},
  50. {[9]int{1, 1, 1, 2, 1, 2, 3, 4, 2}, true},
  51. {[]int{}, false},
  52. }
  53. for _, test := range tests {
  54. if r := From(test.input).AnyWith(func(i interface{}) bool {
  55. return i.(int) == 4
  56. }); r != test.want {
  57. t.Errorf("From(%v).Any()=%v expected %v", test.input, r, test.want)
  58. }
  59. }
  60. }
  61. func TestAnyWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  62. mustPanicWithError(t, "AnyWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  63. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).AnyWithT(func(item int) int { return item + 2 })
  64. })
  65. }
  66. func TestAverage(t *testing.T) {
  67. tests := []struct {
  68. input interface{}
  69. want float64
  70. }{
  71. {[]int{1, 2, 2, 3, 1}, 1.8},
  72. {[5]uint{1, 2, 5, 7, 10}, 5.},
  73. {[]float32{1., 1.}, 1.},
  74. }
  75. for _, test := range tests {
  76. if r := From(test.input).Average(); r != test.want {
  77. t.Errorf("From(%v).Average()=%v expected %v", test.input, r, test.want)
  78. }
  79. }
  80. }
  81. func TestAverageForNaN(t *testing.T) {
  82. if r := From([]int{}).Average(); !math.IsNaN(r) {
  83. t.Errorf("From([]int{}).Average()=%v expected %v", r, math.NaN())
  84. }
  85. }
  86. func TestContains(t *testing.T) {
  87. tests := []struct {
  88. input interface{}
  89. value interface{}
  90. want bool
  91. }{
  92. {[]int{1, 2, 2, 3, 1}, 10, false},
  93. {[5]uint{1, 2, 5, 7, 10}, uint(5), true},
  94. {[]float32{}, 1., false},
  95. }
  96. for _, test := range tests {
  97. if r := From(test.input).Contains(test.value); r != test.want {
  98. t.Errorf("From(%v).Contains(%v)=%v expected %v", test.input, test.value, r, test.want)
  99. }
  100. }
  101. }
  102. func TestCount(t *testing.T) {
  103. tests := []struct {
  104. input interface{}
  105. want int
  106. }{
  107. {[]int{1, 2, 2, 3, 1}, 5},
  108. {[7]uint{1, 2, 5, 7, 10, 12, 15}, 7},
  109. {[]float32{}, 0},
  110. }
  111. for _, test := range tests {
  112. if r := From(test.input).Count(); r != test.want {
  113. t.Errorf("From(%v).Count()=%v expected %v", test.input, r, test.want)
  114. }
  115. }
  116. }
  117. func TestCountWith(t *testing.T) {
  118. tests := []struct {
  119. input interface{}
  120. want int
  121. }{
  122. {[]int{1, 2, 2, 3, 1}, 4},
  123. {[]int{}, 0},
  124. }
  125. for _, test := range tests {
  126. if r := From(test.input).CountWith(func(i interface{}) bool {
  127. return i.(int) <= 2
  128. }); r != test.want {
  129. t.Errorf("From(%v).CountWith()=%v expected %v", test.input, r, test.want)
  130. }
  131. }
  132. }
  133. func TestCountWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  134. mustPanicWithError(t, "CountWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  135. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).CountWithT(func(item int) int { return item + 2 })
  136. })
  137. }
  138. func TestFirst(t *testing.T) {
  139. tests := []struct {
  140. input interface{}
  141. want interface{}
  142. }{
  143. {[]int{1, 2, 2, 3, 1}, 1},
  144. {[]int{}, nil},
  145. }
  146. for _, test := range tests {
  147. if r := From(test.input).First(); r != test.want {
  148. t.Errorf("From(%v).First()=%v expected %v", test.input, r, test.want)
  149. }
  150. }
  151. }
  152. func TestFirstWith(t *testing.T) {
  153. tests := []struct {
  154. input interface{}
  155. want interface{}
  156. }{
  157. {[]int{1, 2, 2, 3, 1}, 3},
  158. {[]int{}, nil},
  159. }
  160. for _, test := range tests {
  161. if r := From(test.input).FirstWith(func(i interface{}) bool {
  162. return i.(int) > 2
  163. }); r != test.want {
  164. t.Errorf("From(%v).FirstWith()=%v expected %v", test.input, r, test.want)
  165. }
  166. }
  167. }
  168. func TestFirstWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  169. mustPanicWithError(t, "FirstWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  170. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).FirstWithT(func(item int) int { return item + 2 })
  171. })
  172. }
  173. func TestForEach(t *testing.T) {
  174. tests := []struct {
  175. input interface{}
  176. want interface{}
  177. }{
  178. {[5]int{1, 2, 2, 35, 111}, []int{2, 4, 4, 70, 222}},
  179. {[]int{}, []int{}},
  180. }
  181. for _, test := range tests {
  182. output := []int{}
  183. From(test.input).ForEach(func(item interface{}) {
  184. output = append(output, item.(int)*2)
  185. })
  186. if !reflect.DeepEqual(output, test.want) {
  187. t.Fatalf("From(%#v).ForEach()=%#v expected=%#v", test.input, output, test.want)
  188. }
  189. }
  190. }
  191. func TestForEachT_PanicWhenActionFnIsInvalid(t *testing.T) {
  192. mustPanicWithError(t, "ForEachT: parameter [actionFn] has a invalid function signature. Expected: 'func(T)', actual: 'func(int,int)'", func() {
  193. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ForEachT(func(item, idx int) { item = item + 2 })
  194. })
  195. }
  196. func TestForEachIndexed(t *testing.T) {
  197. tests := []struct {
  198. input interface{}
  199. want interface{}
  200. }{
  201. {[5]int{1, 2, 2, 35, 111}, []int{1, 3, 4, 38, 115}},
  202. {[]int{}, []int{}},
  203. }
  204. for _, test := range tests {
  205. output := []int{}
  206. From(test.input).ForEachIndexed(func(index int, item interface{}) {
  207. output = append(output, item.(int)+index)
  208. })
  209. if !reflect.DeepEqual(output, test.want) {
  210. t.Fatalf("From(%#v).ForEachIndexed()=%#v expected=%#v", test.input, output, test.want)
  211. }
  212. }
  213. }
  214. func TestForEachIndexedT_PanicWhenActionFnIsInvalid(t *testing.T) {
  215. mustPanicWithError(t, "ForEachIndexedT: parameter [actionFn] has a invalid function signature. Expected: 'func(int,T)', actual: 'func(int)'", func() {
  216. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ForEachIndexedT(func(item int) { item = item + 2 })
  217. })
  218. }
  219. func TestLast(t *testing.T) {
  220. tests := []struct {
  221. input interface{}
  222. want interface{}
  223. }{
  224. {[]int{1, 2, 2, 3, 1}, 1},
  225. {[]int{}, nil},
  226. }
  227. for _, test := range tests {
  228. if r := From(test.input).Last(); r != test.want {
  229. t.Errorf("From(%v).Last()=%v expected %v", test.input, r, test.want)
  230. }
  231. }
  232. }
  233. func TestLastWith(t *testing.T) {
  234. tests := []struct {
  235. input interface{}
  236. want interface{}
  237. }{
  238. {[]int{1, 2, 2, 3, 1, 4, 2, 5, 1, 1}, 5},
  239. {[]int{}, nil},
  240. }
  241. for _, test := range tests {
  242. if r := From(test.input).LastWith(func(i interface{}) bool {
  243. return i.(int) > 2
  244. }); r != test.want {
  245. t.Errorf("From(%v).LastWith()=%v expected %v", test.input, r, test.want)
  246. }
  247. }
  248. }
  249. func TestLastWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  250. mustPanicWithError(t, "LastWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  251. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).LastWithT(func(item int) int { return item + 2 })
  252. })
  253. }
  254. func TestMax(t *testing.T) {
  255. tests := []struct {
  256. input interface{}
  257. want interface{}
  258. }{
  259. {[]int{1, 2, 2, 3, 1}, 3},
  260. {[]int{1}, 1},
  261. {[]int{}, nil},
  262. }
  263. for _, test := range tests {
  264. if r := From(test.input).Max(); r != test.want {
  265. t.Errorf("From(%v).Max()=%v expected %v", test.input, r, test.want)
  266. }
  267. }
  268. }
  269. func TestMin(t *testing.T) {
  270. tests := []struct {
  271. input interface{}
  272. want interface{}
  273. }{
  274. {[]int{1, 2, 2, 3, 0}, 0},
  275. {[]int{1}, 1},
  276. {[]int{}, nil},
  277. }
  278. for _, test := range tests {
  279. if r := From(test.input).Min(); r != test.want {
  280. t.Errorf("From(%v).Min()=%v expected %v", test.input, r, test.want)
  281. }
  282. }
  283. }
  284. func TestResults(t *testing.T) {
  285. input := []int{1, 2, 3}
  286. want := []interface{}{1, 2, 3}
  287. if r := From(input).Results(); !reflect.DeepEqual(r, want) {
  288. t.Errorf("From(%v).Raw()=%v expected %v", input, r, want)
  289. }
  290. }
  291. func TestSequenceEqual(t *testing.T) {
  292. tests := []struct {
  293. input interface{}
  294. input2 interface{}
  295. want bool
  296. }{
  297. {[]int{1, 2, 2, 3, 1}, []int{4, 6}, false},
  298. {[]int{1, -1, 100}, []int{1, -1, 100}, true},
  299. {[]int{}, []int{}, true},
  300. }
  301. for _, test := range tests {
  302. if r := From(test.input).SequenceEqual(From(test.input2)); r != test.want {
  303. t.Errorf("From(%v).SequenceEqual(%v)=%v expected %v", test.input, test.input2, r, test.want)
  304. }
  305. }
  306. }
  307. func TestSingle(t *testing.T) {
  308. tests := []struct {
  309. input interface{}
  310. want interface{}
  311. }{
  312. {[]int{1, 2, 2, 3, 1}, nil},
  313. {[]int{1}, 1},
  314. {[]int{}, nil},
  315. }
  316. for _, test := range tests {
  317. if r := From(test.input).Single(); r != test.want {
  318. t.Errorf("From(%v).Single()=%v expected %v", test.input, r, test.want)
  319. }
  320. }
  321. }
  322. func TestSingleWith(t *testing.T) {
  323. tests := []struct {
  324. input interface{}
  325. want interface{}
  326. }{
  327. {[]int{1, 2, 2, 3, 1}, 3},
  328. {[]int{1, 1, 1}, nil},
  329. {[]int{5, 1, 1, 10, 2, 2}, nil},
  330. {[]int{}, nil},
  331. }
  332. for _, test := range tests {
  333. if r := From(test.input).SingleWith(func(i interface{}) bool {
  334. return i.(int) > 2
  335. }); r != test.want {
  336. t.Errorf("From(%v).SingleWith()=%v expected %v", test.input, r, test.want)
  337. }
  338. }
  339. }
  340. func TestSingleWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) {
  341. mustPanicWithError(t, "SingleWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() {
  342. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).SingleWithT(func(item int) int { return item + 2 })
  343. })
  344. }
  345. func TestSumInts(t *testing.T) {
  346. tests := []struct {
  347. input interface{}
  348. want int64
  349. }{
  350. {[]int{1, 2, 2, 3, 1}, 9},
  351. {[]int{1}, 1},
  352. {[]int{}, 0},
  353. }
  354. for _, test := range tests {
  355. if r := From(test.input).SumInts(); r != test.want {
  356. t.Errorf("From(%v).SumInts()=%v expected %v", test.input, r, test.want)
  357. }
  358. }
  359. }
  360. func TestSumUInts(t *testing.T) {
  361. tests := []struct {
  362. input interface{}
  363. want uint64
  364. }{
  365. {[]uint{1, 2, 2, 3, 1}, 9},
  366. {[]uint{1}, 1},
  367. {[]uint{}, 0},
  368. }
  369. for _, test := range tests {
  370. if r := From(test.input).SumUInts(); r != test.want {
  371. t.Errorf("From(%v).SumInts()=%v expected %v", test.input, r, test.want)
  372. }
  373. }
  374. }
  375. func TestSumFloats(t *testing.T) {
  376. tests := []struct {
  377. input interface{}
  378. want float64
  379. }{
  380. {[]float32{1., 2., 2., 3., 1.}, 9.},
  381. {[]float64{1.}, 1.},
  382. {[]float32{}, 0.},
  383. }
  384. for _, test := range tests {
  385. if r := From(test.input).SumFloats(); r != test.want {
  386. t.Errorf("From(%v).SumFloats()=%v expected %v", test.input, r, test.want)
  387. }
  388. }
  389. }
  390. func TestToChannel(t *testing.T) {
  391. c := make(chan interface{})
  392. input := []int{1, 2, 3, 4, 5}
  393. go func() {
  394. From(input).ToChannel(c)
  395. }()
  396. result := []int{}
  397. for value := range c {
  398. result = append(result, value.(int))
  399. }
  400. if !reflect.DeepEqual(result, input) {
  401. t.Errorf("From(%v).ToChannel()=%v expected %v", input, result, input)
  402. }
  403. }
  404. func TestToChannelT(t *testing.T) {
  405. c := make(chan string)
  406. input := []string{"1", "2", "3", "4", "5"}
  407. go From(input).ToChannelT(c)
  408. result := []string{}
  409. for value := range c {
  410. result = append(result, value)
  411. }
  412. if !reflect.DeepEqual(result, input) {
  413. t.Errorf("From(%v).ToChannelT()=%v expected %v", input, result, input)
  414. }
  415. }
  416. func TestToMap(t *testing.T) {
  417. input := make(map[int]bool)
  418. input[1] = true
  419. input[2] = false
  420. input[3] = true
  421. result := make(map[int]bool)
  422. From(input).ToMap(&result)
  423. if !reflect.DeepEqual(result, input) {
  424. t.Errorf("From(%v).ToMap()=%v expected %v", input, result, input)
  425. }
  426. }
  427. func TestToMapBy(t *testing.T) {
  428. input := make(map[int]bool)
  429. input[1] = true
  430. input[2] = false
  431. input[3] = true
  432. result := make(map[int]bool)
  433. From(input).ToMapBy(&result,
  434. func(i interface{}) interface{} {
  435. return i.(KeyValue).Key
  436. },
  437. func(i interface{}) interface{} {
  438. return i.(KeyValue).Value
  439. })
  440. if !reflect.DeepEqual(result, input) {
  441. t.Errorf("From(%v).ToMapBy()=%v expected %v", input, result, input)
  442. }
  443. }
  444. func TestToMapByT_PanicWhenKeySelectorFnIsInvalid(t *testing.T) {
  445. mustPanicWithError(t, "ToMapByT: parameter [keySelectorFn] has a invalid function signature. Expected: 'func(T)T', actual: 'func(int,int)int'", func() {
  446. result := make(map[int]bool)
  447. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ToMapByT(
  448. &result,
  449. func(item, j int) int { return item + 2 },
  450. func(item int) int { return item + 2 },
  451. )
  452. })
  453. }
  454. func TestToMapByT_PanicWhenValueSelectorFnIsInvalid(t *testing.T) {
  455. mustPanicWithError(t, "ToMapByT: parameter [valueSelectorFn] has a invalid function signature. Expected: 'func(T)T', actual: 'func(int,int)int'", func() {
  456. result := make(map[int]bool)
  457. From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ToMapByT(
  458. &result,
  459. func(item int) int { return item + 2 },
  460. func(item, j int) int { return item + 2 },
  461. )
  462. })
  463. }
  464. func TestToSlice(t *testing.T) {
  465. tests := []struct {
  466. input []int
  467. output []int
  468. want []int
  469. wantedOutputCap int
  470. outputIsANewSlice bool
  471. }{
  472. // output is nil slice
  473. {
  474. []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  475. nil,
  476. []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  477. 16,
  478. true},
  479. // output is empty slice (cap=0)
  480. {
  481. []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  482. []int{},
  483. []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  484. 16,
  485. true},
  486. // ToSlice() overwrites existing elements and reslices.
  487. {[]int{1, 2, 3},
  488. []int{99, 98, 97, 96, 95},
  489. []int{1, 2, 3},
  490. 5,
  491. false},
  492. // cap(out)>len(result): we get the same slice, resliced. cap unchanged.
  493. {[]int{1, 2, 3, 4, 5},
  494. make([]int, 0, 11),
  495. []int{1, 2, 3, 4, 5},
  496. 11,
  497. false},
  498. // cap(out)==len(result): we get the same slice, cap unchanged.
  499. {[]int{1, 2, 3, 4, 5},
  500. make([]int, 0, 5),
  501. []int{1, 2, 3, 4, 5},
  502. 5,
  503. false},
  504. // cap(out)<len(result): we get a new slice with len(out)=len(result) and cap doubled: cap(out')==2*cap(out)
  505. {[]int{1, 2, 3, 4, 5},
  506. make([]int, 0, 4),
  507. []int{1, 2, 3, 4, 5},
  508. 8,
  509. true},
  510. // cap(out)<<len(result): trigger capacity to double more than once (26 -> 52 -> 104)
  511. {make([]int, 100),
  512. make([]int, 0, 26),
  513. make([]int, 100),
  514. 104,
  515. true},
  516. // len(out) > len(result): we get the same slice with len(out)=len(result) and cap unchanged: cap(out')==cap(out)
  517. {[]int{1, 2, 3, 4, 5},
  518. make([]int, 0, 50),
  519. []int{1, 2, 3, 4, 5},
  520. 50,
  521. false},
  522. }
  523. for c, test := range tests {
  524. initialOutputValue := test.output
  525. From(test.input).ToSlice(&test.output)
  526. modifiedOutputValue := test.output
  527. // test slice values
  528. if !reflect.DeepEqual(test.output, test.want) {
  529. t.Fatalf("case #%d: From(%#v).ToSlice()=%#v expected=%#v", c, test.input, test.output, test.want)
  530. }
  531. // test capacity of output slice
  532. if cap(test.output) != test.wantedOutputCap {
  533. t.Fatalf("case #%d: cap(output)=%d expected=%d", c, cap(test.output), test.wantedOutputCap)
  534. }
  535. // test if a new slice is allocated
  536. inPtr := (*reflect.SliceHeader)(unsafe.Pointer(&initialOutputValue)).Data
  537. outPtr := (*reflect.SliceHeader)(unsafe.Pointer(&modifiedOutputValue)).Data
  538. isNewSlice := inPtr != outPtr
  539. if isNewSlice != test.outputIsANewSlice {
  540. t.Fatalf("case #%d: isNewSlice=%v (in=0x%X out=0x%X) expected=%v", c, isNewSlice, inPtr, outPtr, test.outputIsANewSlice)
  541. }
  542. }
  543. }