test_core_strings.odin 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package test_core_strings
  2. import "core:strings"
  3. import "core:testing"
  4. import "base:runtime"
  5. @test
  6. test_index_any_small_string_not_found :: proc(t: ^testing.T) {
  7. index := strings.index_any(".", "/:\"")
  8. testing.expect(t, index == -1, "index_any should be negative")
  9. }
  10. @test
  11. test_index_any_larger_string_not_found :: proc(t: ^testing.T) {
  12. index := strings.index_any("aaaaaaaa.aaaaaaaa", "/:\"")
  13. testing.expect(t, index == -1, "index_any should be negative")
  14. }
  15. @test
  16. test_index_any_small_string_found :: proc(t: ^testing.T) {
  17. index := strings.index_any(".", "/:.\"")
  18. testing.expect(t, index == 0, "index_any should be 0")
  19. }
  20. @test
  21. test_index_any_larger_string_found :: proc(t: ^testing.T) {
  22. index := strings.index_any("aaaaaaaa:aaaaaaaa", "/:\"")
  23. testing.expect(t, index == 8, "index_any should be 8")
  24. }
  25. @test
  26. test_last_index_any_small_string_found :: proc(t: ^testing.T) {
  27. index := strings.last_index_any(".", "/:.\"")
  28. testing.expect(t, index == 0, "last_index_any should be 0")
  29. }
  30. @test
  31. test_last_index_any_small_string_not_found :: proc(t: ^testing.T) {
  32. index := strings.last_index_any(".", "/:\"")
  33. testing.expect(t, index == -1, "last_index_any should be -1")
  34. }
  35. Cut_Test :: struct {
  36. input: string,
  37. offset: int,
  38. length: int,
  39. output: string,
  40. }
  41. cut_tests :: []Cut_Test{
  42. {"some example text", 0, 0, "some example text" },
  43. {"some example text", 0, 4, "some" },
  44. {"some example text", 2, 2, "me" },
  45. {"some example text", 5, 7, "example" },
  46. {"some example text", 5, 0, "example text" },
  47. {"恥ずべきフクロウ", 0, 0, "恥ずべきフクロウ" },
  48. {"恥ずべきフクロウ", 4, 0, "フクロウ" },
  49. }
  50. @test
  51. test_cut :: proc(t: ^testing.T) {
  52. for test in cut_tests {
  53. res := strings.cut(test.input, test.offset, test.length)
  54. testing.expectf(
  55. t,
  56. res == test.output,
  57. "cut(\"%v\", %v, %v) expected to return \"%v\", got \"%v\"",
  58. test.input, test.offset, test.length, test.output, res,
  59. )
  60. }
  61. }
  62. Case_Kind :: enum {
  63. Lower_Space_Case,
  64. Upper_Space_Case,
  65. Lower_Snake_Case,
  66. Upper_Snake_Case,
  67. Lower_Kebab_Case,
  68. Upper_Kebab_Case,
  69. Camel_Case,
  70. Pascal_Case,
  71. Ada_Case,
  72. }
  73. Case_Proc :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error)
  74. test_cases := [Case_Kind]struct{s: string, p: Case_Proc}{
  75. .Lower_Space_Case = {"hellope world", to_lower_space_case},
  76. .Upper_Space_Case = {"HELLOPE WORLD", to_upper_space_case},
  77. .Lower_Snake_Case = {"hellope_world", to_snake_case},
  78. .Upper_Snake_Case = {"HELLOPE_WORLD", to_upper_snake_case},
  79. .Lower_Kebab_Case = {"hellope-world", to_kebab_case},
  80. .Upper_Kebab_Case = {"HELLOPE-WORLD", to_upper_kebab_case},
  81. .Camel_Case = {"hellopeWorld", to_camel_case},
  82. .Pascal_Case = {"HellopeWorld", to_pascal_case},
  83. .Ada_Case = {"Hellope_World", to_ada_case},
  84. }
  85. to_lower_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
  86. return strings.to_delimiter_case(r, ' ', false, allocator)
  87. }
  88. to_upper_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
  89. return strings.to_delimiter_case(r, ' ', true, allocator)
  90. }
  91. // NOTE: we have these wrappers as having #optional_allocator_error changes the type to not be equivalent
  92. to_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_snake_case(r, allocator) }
  93. to_upper_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_upper_snake_case(r, allocator) }
  94. to_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_kebab_case(r, allocator) }
  95. to_upper_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_upper_kebab_case(r, allocator) }
  96. to_camel_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_camel_case(r, allocator) }
  97. to_pascal_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_pascal_case(r, allocator) }
  98. to_ada_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_ada_case(r, allocator) }
  99. @test
  100. test_case_conversion :: proc(t: ^testing.T) {
  101. for entry in test_cases {
  102. for test_case, case_kind in test_cases {
  103. result, err := entry.p(test_case.s, context.allocator)
  104. testing.expectf(t, err == nil, "ERROR: We got the allocation error '{}'\n", err)
  105. defer delete(result)
  106. testing.expectf(t, result == entry.s, "ERROR: Input `{}` to converter {} does not match `{}`, got `{}`.\n", test_case.s, case_kind, entry.s, result)
  107. }
  108. }
  109. }
  110. @(test)
  111. test_substring :: proc(t: ^testing.T) {
  112. Case :: struct {
  113. s: string,
  114. start: int,
  115. end: int,
  116. sub: string,
  117. ok: bool,
  118. }
  119. cases := []Case {
  120. {ok = true},
  121. {s = "", start = -1, ok = false},
  122. {s = "", end = -1, ok = false},
  123. {s = "", end = +1, ok = false},
  124. {s = "Hello", end = len("Hello"), sub = "Hello", ok = true},
  125. {s = "Hello", start = 1, end = len("Hello"), sub = "ello", ok = true},
  126. {s = "Hello", start = 1, end = len("Hello") - 1, sub = "ell", ok = true},
  127. {s = "Hello", end = len("Hello") + 1, sub = "Hello", ok = false},
  128. {s = "小猫咪", start = 0, end = 3, sub = "小猫咪", ok = true},
  129. {s = "小猫咪", start = 1, end = 3, sub = "猫咪", ok = true},
  130. {s = "小猫咪", start = 1, end = 5, sub = "猫咪", ok = false},
  131. {s = "小猫咪", start = 1, end = 1, sub = "", ok = true},
  132. }
  133. for tc in cases {
  134. sub, ok := strings.substring(tc.s, tc.start, tc.end)
  135. testing.expectf(t, ok == tc.ok, "expected %v[%v:%v] to return ok: %v", tc.s, tc.start, tc.end, tc.ok)
  136. testing.expectf(t, sub == tc.sub, "expected %v[%v:%v] to return sub: %v, got: %v", tc.s, tc.start, tc.end, tc.sub, sub)
  137. }
  138. }