iterutil_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package iterutil
  2. import (
  3. "iter"
  4. "testing"
  5. )
  6. // toSeq maintains order in the sequence
  7. func toSeq[T any](s []T) iter.Seq[T] {
  8. return func(yield func(T) bool) {
  9. for _, v := range s {
  10. if !yield(v) {
  11. return
  12. }
  13. }
  14. }
  15. }
  16. type pair struct {
  17. first int
  18. second string
  19. }
  20. func TestCombine(t *testing.T) {
  21. type testCase struct {
  22. name string
  23. input1 []int
  24. input2 []string
  25. expected []pair
  26. }
  27. tests := []testCase{
  28. {
  29. name: "empty slices",
  30. input1: []int{},
  31. input2: []string{},
  32. expected: []pair{},
  33. },
  34. {
  35. name: "different string length slice",
  36. input1: []int{1, 2, 3},
  37. input2: []string{"a", "b"},
  38. expected: []pair{
  39. {1, "a"},
  40. {2, "b"},
  41. },
  42. },
  43. {
  44. name: "different int length slice",
  45. input1: []int{1, 2},
  46. input2: []string{"a", "b", "c"},
  47. expected: []pair{
  48. {1, "a"},
  49. {2, "b"},
  50. },
  51. },
  52. {
  53. name: "same length slices",
  54. input1: []int{1, 2, 3},
  55. input2: []string{"a", "b", "c"},
  56. expected: []pair{
  57. {1, "a"},
  58. {2, "b"},
  59. {3, "c"},
  60. },
  61. },
  62. }
  63. for _, test := range tests {
  64. t.Run(test.name, func(t *testing.T) {
  65. result := Combine(toSeq(test.input1), toSeq(test.input2))
  66. for f, s := range result {
  67. if !isPairIn(test.expected, pair{f, s}) {
  68. t.Errorf("expected %v, got %v", test.expected, pair{f, s})
  69. }
  70. }
  71. })
  72. }
  73. }
  74. func TestConcat(t *testing.T) {
  75. type testCase struct {
  76. name string
  77. input1 []int
  78. input2 []int
  79. expected []int
  80. }
  81. tests := []testCase{
  82. {
  83. name: "empty slices",
  84. input1: []int{},
  85. input2: []int{},
  86. expected: []int{},
  87. },
  88. {
  89. name: "non-empty first slice",
  90. input1: []int{1, 2, 3},
  91. input2: []int{},
  92. expected: []int{1, 2, 3},
  93. },
  94. {
  95. name: "non-empty second slice",
  96. input1: []int{},
  97. input2: []int{4, 5, 6},
  98. expected: []int{4, 5, 6},
  99. },
  100. {
  101. name: "non-empty both slices",
  102. input1: []int{1, 2, 3},
  103. input2: []int{4, 5, 6},
  104. expected: []int{1, 2, 3, 4, 5, 6},
  105. },
  106. }
  107. for _, test := range tests {
  108. t.Run(test.name, func(t *testing.T) {
  109. results := Concat(toSeq(test.input1), toSeq(test.input2))
  110. // it is safe to compare this way due to the way a slice sequence iterator
  111. // obeys the ordering of the slice
  112. index := 0
  113. for result := range results {
  114. if result != test.expected[index] {
  115. t.Errorf("expected %v, got %v", test.expected[index], result)
  116. }
  117. index++
  118. }
  119. })
  120. }
  121. }
  122. func isPairIn(pairs []pair, p pair) bool {
  123. for _, pair := range pairs {
  124. if pair.first == p.first && pair.second == p.second {
  125. return true
  126. }
  127. }
  128. return false
  129. }