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