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.

116 lines
2.9 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package fastjson
  5. import (
  6. "bytes"
  7. "strings"
  8. "testing"
  9. "unicode/utf8"
  10. )
  11. var foldTests = []struct {
  12. fn func(s, t []byte) bool
  13. s, t string
  14. want bool
  15. }{
  16. {equalFoldRight, "", "", true},
  17. {equalFoldRight, "a", "a", true},
  18. {equalFoldRight, "", "a", false},
  19. {equalFoldRight, "a", "", false},
  20. {equalFoldRight, "a", "A", true},
  21. {equalFoldRight, "AB", "ab", true},
  22. {equalFoldRight, "AB", "ac", false},
  23. {equalFoldRight, "sbkKc", "ſbKKc", true},
  24. {equalFoldRight, "SbKkc", "ſbKKc", true},
  25. {equalFoldRight, "SbKkc", "ſbKK", false},
  26. {equalFoldRight, "e", "é", false},
  27. {equalFoldRight, "s", "S", true},
  28. {simpleLetterEqualFold, "", "", true},
  29. {simpleLetterEqualFold, "abc", "abc", true},
  30. {simpleLetterEqualFold, "abc", "ABC", true},
  31. {simpleLetterEqualFold, "abc", "ABCD", false},
  32. {simpleLetterEqualFold, "abc", "xxx", false},
  33. {asciiEqualFold, "a_B", "A_b", true},
  34. {asciiEqualFold, "aa@", "aa`", false}, // verify 0x40 and 0x60 aren't case-equivalent
  35. }
  36. func TestFold(t *testing.T) {
  37. for i, tt := range foldTests {
  38. if got := tt.fn([]byte(tt.s), []byte(tt.t)); got != tt.want {
  39. t.Errorf("%d. %q, %q = %v; want %v", i, tt.s, tt.t, got, tt.want)
  40. }
  41. truth := strings.EqualFold(tt.s, tt.t)
  42. if truth != tt.want {
  43. t.Errorf("strings.EqualFold doesn't agree with case %d", i)
  44. }
  45. }
  46. }
  47. func TestFoldAgainstUnicode(t *testing.T) {
  48. const bufSize = 5
  49. buf1 := make([]byte, 0, bufSize)
  50. buf2 := make([]byte, 0, bufSize)
  51. var runes []rune
  52. for i := 0x20; i <= 0x7f; i++ {
  53. runes = append(runes, rune(i))
  54. }
  55. runes = append(runes, kelvin, smallLongEss)
  56. funcs := []struct {
  57. name string
  58. fold func(s, t []byte) bool
  59. letter bool // must be ASCII letter
  60. simple bool // must be simple ASCII letter (not 'S' or 'K')
  61. }{
  62. {
  63. name: "equalFoldRight",
  64. fold: equalFoldRight,
  65. },
  66. {
  67. name: "asciiEqualFold",
  68. fold: asciiEqualFold,
  69. simple: true,
  70. },
  71. {
  72. name: "simpleLetterEqualFold",
  73. fold: simpleLetterEqualFold,
  74. simple: true,
  75. letter: true,
  76. },
  77. }
  78. for _, ff := range funcs {
  79. for _, r := range runes {
  80. if r >= utf8.RuneSelf {
  81. continue
  82. }
  83. if ff.letter && !isASCIILetter(byte(r)) {
  84. continue
  85. }
  86. if ff.simple && (r == 's' || r == 'S' || r == 'k' || r == 'K') {
  87. continue
  88. }
  89. for _, r2 := range runes {
  90. buf1 := append(buf1[:0], 'x')
  91. buf2 := append(buf2[:0], 'x')
  92. buf1 = buf1[:1+utf8.EncodeRune(buf1[1:bufSize], r)]
  93. buf2 = buf2[:1+utf8.EncodeRune(buf2[1:bufSize], r2)]
  94. buf1 = append(buf1, 'x')
  95. buf2 = append(buf2, 'x')
  96. want := bytes.EqualFold(buf1, buf2)
  97. if got := ff.fold(buf1, buf2); got != want {
  98. t.Errorf("%s(%q, %q) = %v; want %v", ff.name, buf1, buf2, got, want)
  99. }
  100. }
  101. }
  102. }
  103. }
  104. func isASCIILetter(b byte) bool {
  105. return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z')
  106. }