test_core_slice.odin 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package test_core_slice
  2. import "core:slice"
  3. import "core:strings"
  4. import "core:testing"
  5. import "core:fmt"
  6. import "core:os"
  7. import "core:math/rand"
  8. TEST_count := 0
  9. TEST_fail := 0
  10. when ODIN_TEST {
  11. expect :: testing.expect
  12. log :: testing.log
  13. } else {
  14. expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
  15. TEST_count += 1
  16. if !condition {
  17. TEST_fail += 1
  18. fmt.printf("[%v] %v\n", loc, message)
  19. return
  20. }
  21. }
  22. log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
  23. fmt.printf("[%v] ", loc)
  24. fmt.printf("log: %v\n", v)
  25. }
  26. }
  27. main :: proc() {
  28. t := testing.T{}
  29. test_sort_with_indices(&t)
  30. test_binary_search(&t)
  31. fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
  32. if TEST_fail > 0 {
  33. os.exit(1)
  34. }
  35. }
  36. @test
  37. test_sort_with_indices :: proc(t: ^testing.T) {
  38. seed := rand.uint64()
  39. fmt.printf("Random seed: %v\n", seed)
  40. // Test sizes are all prime.
  41. test_sizes :: []int{7, 13, 347, 1031, 10111, 100003}
  42. for test_size in test_sizes {
  43. fmt.printf("Sorting %v random u64 values along with index.\n", test_size)
  44. r := rand.create(seed)
  45. vals := make([]u64, test_size)
  46. r_idx := make([]int, test_size) // Reverse index
  47. defer {
  48. delete(vals)
  49. delete(r_idx)
  50. }
  51. // Set up test values
  52. for _, i in vals {
  53. vals[i] = rand.uint64(&r)
  54. }
  55. // Sort
  56. f_idx := slice.sort_with_indices(vals)
  57. defer delete(f_idx)
  58. // Verify sorted test values
  59. rand.init(&r, seed)
  60. for v, i in f_idx {
  61. r_idx[v] = i
  62. }
  63. last: u64
  64. for v, i in vals {
  65. if i > 0 {
  66. val_pass := v >= last
  67. expect(t, val_pass, "Expected values to have been sorted.")
  68. if !val_pass {
  69. break
  70. }
  71. }
  72. idx_pass := vals[r_idx[i]] == rand.uint64(&r)
  73. expect(t, idx_pass, "Expected index to have been sorted.")
  74. if !idx_pass {
  75. break
  76. }
  77. last = v
  78. }
  79. }
  80. }
  81. @test
  82. test_sort_by_indices :: proc(t: ^testing.T) {
  83. seed := rand.uint64()
  84. fmt.printf("Random seed: %v\n", seed)
  85. // Test sizes are all prime.
  86. test_sizes :: []int{7, 13, 347, 1031, 10111, 100003}
  87. for test_size in test_sizes {
  88. fmt.printf("Sorting %v random u64 values along with index.\n", test_size)
  89. r := rand.create(seed)
  90. vals := make([]u64, test_size)
  91. r_idx := make([]int, test_size) // Reverse index
  92. defer {
  93. delete(vals)
  94. delete(r_idx)
  95. }
  96. // Set up test values
  97. for _, i in vals {
  98. vals[i] = rand.uint64(&r)
  99. }
  100. // Sort
  101. f_idx := slice.sort_with_indices(vals)
  102. defer delete(f_idx)
  103. // Verify sorted test values
  104. rand.init(&r, seed)
  105. {
  106. indices := make([]int, test_size)
  107. defer delete(indices)
  108. for _, i in indices {
  109. indices[i] = i
  110. }
  111. sorted_indices := slice.sort_by_indices(indices, f_idx)
  112. defer delete(sorted_indices)
  113. for v, i in sorted_indices {
  114. idx_pass := v == f_idx[i]
  115. expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
  116. if !idx_pass {
  117. break
  118. }
  119. }
  120. }
  121. {
  122. indices := make([]int, test_size)
  123. defer delete(indices)
  124. for _, i in indices {
  125. indices[i] = i
  126. }
  127. slice.sort_by_indices_overwrite(indices, f_idx)
  128. for v, i in indices {
  129. idx_pass := v == f_idx[i]
  130. expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
  131. if !idx_pass {
  132. break
  133. }
  134. }
  135. }
  136. {
  137. indices := make([]int, test_size)
  138. swap := make([]int, test_size)
  139. defer {
  140. delete(indices)
  141. delete(swap)
  142. }
  143. for _, i in indices {
  144. indices[i] = i
  145. }
  146. slice.sort_by_indices(indices, swap, f_idx)
  147. for v, i in swap {
  148. idx_pass := v == f_idx[i]
  149. expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
  150. if !idx_pass {
  151. break
  152. }
  153. }
  154. }
  155. }
  156. }
  157. @test
  158. test_binary_search :: proc(t: ^testing.T) {
  159. builder := strings.Builder{}
  160. defer strings.builder_destroy(&builder)
  161. test_search :: proc(t: ^testing.T, b: ^strings.Builder, s: []i32, v: i32) -> (int, bool) {
  162. log(t, fmt.sbprintf(b, "Searching for %v in %v", v, s))
  163. strings.builder_reset(b)
  164. index, found := slice.binary_search(s, v)
  165. log(t, fmt.sbprintf(b, "index: %v, found: %v", index, found))
  166. strings.builder_reset(b )
  167. return index, found
  168. }
  169. index: int
  170. found: bool
  171. s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
  172. index, found = test_search(t, &builder, s, 13)
  173. expect(t, index == 9, "Expected index to be 9.")
  174. expect(t, found == true, "Expected found to be true.")
  175. index, found = test_search(t, &builder, s, 4)
  176. expect(t, index == 7, "Expected index to be 7.")
  177. expect(t, found == false, "Expected found to be false.")
  178. index, found = test_search(t, &builder, s, 100)
  179. expect(t, index == 13, "Expected index to be 13.")
  180. expect(t, found == false, "Expected found to be false.")
  181. index, found = test_search(t, &builder, s, 1)
  182. expect(t, index >= 1 && index <= 4, "Expected index to be 1, 2, 3, or 4.")
  183. expect(t, found == true, "Expected found to be true.")
  184. index, found = test_search(t, &builder, s, -1)
  185. expect(t, index == 0, "Expected index to be 0.")
  186. expect(t, found == false, "Expected found to be false.")
  187. a := []i32{}
  188. index, found = test_search(t, &builder, a, 13)
  189. expect(t, index == 0, "Expected index to be 0.")
  190. expect(t, found == false, "Expected found to be false.")
  191. b := []i32{1}
  192. index, found = test_search(t, &builder, b, 13)
  193. expect(t, index == 1, "Expected index to be 1.")
  194. expect(t, found == false, "Expected found to be false.")
  195. index, found = test_search(t, &builder, b, 1)
  196. expect(t, index == 0, "Expected index to be 0.")
  197. expect(t, found == true, "Expected found to be true.")
  198. index, found = test_search(t, &builder, b, 0)
  199. expect(t, index == 0, "Expected index to be 0.")
  200. expect(t, found == false, "Expected found to be false.")
  201. }