composition_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2011 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 norm
  5. import "testing"
  6. // TestCase is used for most tests.
  7. type TestCase struct {
  8. in []rune
  9. out []rune
  10. }
  11. func runTests(t *testing.T, name string, fm Form, tests []TestCase) {
  12. rb := reorderBuffer{}
  13. rb.init(fm, nil)
  14. for i, test := range tests {
  15. rb.setFlusher(nil, appendFlush)
  16. for j, rune := range test.in {
  17. b := []byte(string(rune))
  18. src := inputBytes(b)
  19. info := rb.f.info(src, 0)
  20. if j == 0 {
  21. rb.ss.first(info)
  22. } else {
  23. rb.ss.next(info)
  24. }
  25. if rb.insertFlush(src, 0, info) < 0 {
  26. t.Errorf("%s:%d: insert failed for rune %d", name, i, j)
  27. }
  28. }
  29. rb.doFlush()
  30. was := string(rb.out)
  31. want := string(test.out)
  32. if len(was) != len(want) {
  33. t.Errorf("%s:%d: length = %d; want %d", name, i, len(was), len(want))
  34. }
  35. if was != want {
  36. k, pfx := pidx(was, want)
  37. t.Errorf("%s:%d: \nwas %s%+q; \nwant %s%+q", name, i, pfx, was[k:], pfx, want[k:])
  38. }
  39. }
  40. }
  41. func TestFlush(t *testing.T) {
  42. const (
  43. hello = "Hello "
  44. world = "world!"
  45. )
  46. buf := make([]byte, maxByteBufferSize)
  47. p := copy(buf, hello)
  48. out := buf[p:]
  49. rb := reorderBuffer{}
  50. rb.initString(NFC, world)
  51. if i := rb.flushCopy(out); i != 0 {
  52. t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", i)
  53. }
  54. for i := range world {
  55. // No need to set streamSafe values for this test.
  56. rb.insertFlush(rb.src, i, rb.f.info(rb.src, i))
  57. n := rb.flushCopy(out)
  58. out = out[n:]
  59. p += n
  60. }
  61. was := buf[:p]
  62. want := hello + world
  63. if string(was) != want {
  64. t.Errorf(`output after flush was "%s"; want "%s"`, string(was), want)
  65. }
  66. if rb.nrune != 0 {
  67. t.Errorf("non-null size of info buffer (rb.nrune == %d)", rb.nrune)
  68. }
  69. if rb.nbyte != 0 {
  70. t.Errorf("non-null size of byte buffer (rb.nbyte == %d)", rb.nbyte)
  71. }
  72. }
  73. var insertTests = []TestCase{
  74. {[]rune{'a'}, []rune{'a'}},
  75. {[]rune{0x300}, []rune{0x300}},
  76. {[]rune{0x300, 0x316}, []rune{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220
  77. {[]rune{0x316, 0x300}, []rune{0x316, 0x300}},
  78. {[]rune{0x41, 0x316, 0x300}, []rune{0x41, 0x316, 0x300}},
  79. {[]rune{0x41, 0x300, 0x316}, []rune{0x41, 0x316, 0x300}},
  80. {[]rune{0x300, 0x316, 0x41}, []rune{0x316, 0x300, 0x41}},
  81. {[]rune{0x41, 0x300, 0x40, 0x316}, []rune{0x41, 0x300, 0x40, 0x316}},
  82. }
  83. func TestInsert(t *testing.T) {
  84. runTests(t, "TestInsert", NFD, insertTests)
  85. }
  86. var decompositionNFDTest = []TestCase{
  87. {[]rune{0xC0}, []rune{0x41, 0x300}},
  88. {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
  89. {[]rune{0x01C4}, []rune{0x01C4}},
  90. {[]rune{0x320E}, []rune{0x320E}},
  91. {[]rune("음ẻ과"), []rune{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}},
  92. }
  93. var decompositionNFKDTest = []TestCase{
  94. {[]rune{0xC0}, []rune{0x41, 0x300}},
  95. {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
  96. {[]rune{0x01C4}, []rune{0x44, 0x5A, 0x030C}},
  97. {[]rune{0x320E}, []rune{0x28, 0x1100, 0x1161, 0x29}},
  98. }
  99. func TestDecomposition(t *testing.T) {
  100. runTests(t, "TestDecompositionNFD", NFD, decompositionNFDTest)
  101. runTests(t, "TestDecompositionNFKD", NFKD, decompositionNFKDTest)
  102. }
  103. var compositionTest = []TestCase{
  104. {[]rune{0x41, 0x300}, []rune{0xC0}},
  105. {[]rune{0x41, 0x316}, []rune{0x41, 0x316}},
  106. {[]rune{0x41, 0x300, 0x35D}, []rune{0xC0, 0x35D}},
  107. {[]rune{0x41, 0x316, 0x300}, []rune{0xC0, 0x316}},
  108. // blocking starter
  109. {[]rune{0x41, 0x316, 0x40, 0x300}, []rune{0x41, 0x316, 0x40, 0x300}},
  110. {[]rune{0x1100, 0x1161}, []rune{0xAC00}},
  111. // parenthesized Hangul, alternate between ASCII and Hangul.
  112. {[]rune{0x28, 0x1100, 0x1161, 0x29}, []rune{0x28, 0xAC00, 0x29}},
  113. }
  114. func TestComposition(t *testing.T) {
  115. runTests(t, "TestComposition", NFC, compositionTest)
  116. }