profile_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2016 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 precis
  5. import (
  6. "fmt"
  7. "math/rand"
  8. "testing"
  9. "unicode"
  10. "golang.org/x/text/internal/testtext"
  11. "golang.org/x/text/transform"
  12. )
  13. // copyOrbit is a Transformer for the sole purpose of testing the apply method,
  14. // testing that apply will always call Span for the prefix of the input that
  15. // remains identical and then call Transform for the remainder. It will produce
  16. // inconsistent output for other usage patterns.
  17. // Provided that copyOrbit is used this way, the first t bytes of the output
  18. // will be identical to the input and the remaining output will be the result
  19. // of calling caseOrbit on the remaining input bytes.
  20. type copyOrbit int
  21. func (t copyOrbit) Reset() {}
  22. func (t copyOrbit) Span(src []byte, atEOF bool) (n int, err error) {
  23. if int(t) == len(src) {
  24. return int(t), nil
  25. }
  26. return int(t), transform.ErrEndOfSpan
  27. }
  28. // Transform implements transform.Transformer specifically for testing the apply method.
  29. // See documentation of copyOrbit before using this method.
  30. func (t copyOrbit) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
  31. n := copy(dst, src)
  32. for i, c := range dst[:n] {
  33. dst[i] = orbitCase(c)
  34. }
  35. return n, n, nil
  36. }
  37. func orbitCase(c byte) byte {
  38. if unicode.IsLower(rune(c)) {
  39. return byte(unicode.ToUpper(rune(c)))
  40. } else {
  41. return byte(unicode.ToLower(rune(c)))
  42. }
  43. }
  44. func TestBuffers(t *testing.T) {
  45. want := "Those who cannot remember the past are condemned to compute it."
  46. spans := rand.Perm(len(want) + 1)
  47. // Compute the result of applying copyOrbit(span) transforms in reverse.
  48. input := []byte(want)
  49. for i := len(spans) - 1; i >= 0; i-- {
  50. for j := spans[i]; j < len(input); j++ {
  51. input[j] = orbitCase(input[j])
  52. }
  53. }
  54. // Apply the copyOrbit(span) transforms.
  55. b := buffers{src: input}
  56. for _, n := range spans {
  57. b.apply(copyOrbit(n))
  58. if n%11 == 0 {
  59. b.apply(transform.Nop)
  60. }
  61. }
  62. if got := string(b.src); got != want {
  63. t.Errorf("got %q; want %q", got, want)
  64. }
  65. }
  66. type compareTestCase struct {
  67. a string
  68. b string
  69. result bool
  70. }
  71. var compareTestCases = []struct {
  72. name string
  73. p *Profile
  74. cases []compareTestCase
  75. }{
  76. {"Nickname", Nickname, []compareTestCase{
  77. {"a", "b", false},
  78. {" Swan of Avon ", "swan of avon", true},
  79. {"Foo", "foo", true},
  80. {"foo", "foo", true},
  81. {"Foo Bar", "foo bar", true},
  82. {"foo bar", "foo bar", true},
  83. {"\u03A3", "\u03C3", true},
  84. {"\u03A3", "\u03C2", false},
  85. {"\u03C3", "\u03C2", false},
  86. {"Richard \u2163", "richard iv", true},
  87. {"Å", "å", true},
  88. {"ff", "ff", true}, // because of NFKC
  89. {"ß", "sS", false},
  90. // After applying the Nickname profile, \u00a8 becomes \u0020\u0308,
  91. // however because the nickname profile is not idempotent, applying it again
  92. // to \u0020\u0308 results in \u0308.
  93. {"\u00a8", "\u0020\u0308", true},
  94. {"\u00a8", "\u0308", true},
  95. {"\u0020\u0308", "\u0308", true},
  96. }},
  97. }
  98. func doCompareTests(t *testing.T, fn func(t *testing.T, p *Profile, tc compareTestCase)) {
  99. for _, g := range compareTestCases {
  100. for i, tc := range g.cases {
  101. name := fmt.Sprintf("%s:%d:%+q", g.name, i, tc.a)
  102. testtext.Run(t, name, func(t *testing.T) {
  103. fn(t, g.p, tc)
  104. })
  105. }
  106. }
  107. }
  108. func TestCompare(t *testing.T) {
  109. doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
  110. if result := p.Compare(tc.a, tc.b); result != tc.result {
  111. t.Errorf("got %v; want %v", result, tc.result)
  112. }
  113. })
  114. }
  115. func TestCompareString(t *testing.T) {
  116. doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
  117. a, err := p.CompareKey(tc.a)
  118. if err != nil {
  119. t.Errorf("Unexpected error when creating key: %v", err)
  120. return
  121. }
  122. b, err := p.CompareKey(tc.b)
  123. if err != nil {
  124. t.Errorf("Unexpected error when creating key: %v", err)
  125. return
  126. }
  127. if result := (a == b); result != tc.result {
  128. t.Errorf("got %v; want %v", result, tc.result)
  129. }
  130. })
  131. }