github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/unicode/utf16/utf16_test.go (about) 1 // Copyright 2010 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 utf16_test 6 7 import ( 8 "internal/testenv" 9 "reflect" 10 "testing" 11 "unicode" 12 . "unicode/utf16" 13 ) 14 15 // Validate the constants redefined from unicode. 16 func TestConstants(t *testing.T) { 17 if MaxRune != unicode.MaxRune { 18 t.Errorf("utf16.maxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune) 19 } 20 if ReplacementChar != unicode.ReplacementChar { 21 t.Errorf("utf16.replacementChar is wrong: %x should be %x", ReplacementChar, unicode.ReplacementChar) 22 } 23 } 24 25 type encodeTest struct { 26 in []rune 27 out []uint16 28 } 29 30 var encodeTests = []encodeTest{ 31 {[]rune{1, 2, 3, 4}, []uint16{1, 2, 3, 4}}, 32 {[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}, 33 []uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff}}, 34 {[]rune{'a', 'b', 0xd7ff, 0xd800, 0xdfff, 0xe000, 0x110000, -1}, 35 []uint16{'a', 'b', 0xd7ff, 0xfffd, 0xfffd, 0xe000, 0xfffd, 0xfffd}}, 36 } 37 38 func TestEncode(t *testing.T) { 39 for _, tt := range encodeTests { 40 out := Encode(tt.in) 41 if !reflect.DeepEqual(out, tt.out) { 42 t.Errorf("Encode(%x) = %x; want %x", tt.in, out, tt.out) 43 } 44 } 45 } 46 47 func TestAppendRune(t *testing.T) { 48 for _, tt := range encodeTests { 49 var out []uint16 50 for _, u := range tt.in { 51 out = AppendRune(out, u) 52 } 53 if !reflect.DeepEqual(out, tt.out) { 54 t.Errorf("AppendRune(%x) = %x; want %x", tt.in, out, tt.out) 55 } 56 } 57 } 58 59 func TestEncodeRune(t *testing.T) { 60 for i, tt := range encodeTests { 61 j := 0 62 for _, r := range tt.in { 63 r1, r2 := EncodeRune(r) 64 if r < 0x10000 || r > unicode.MaxRune { 65 if j >= len(tt.out) { 66 t.Errorf("#%d: ran out of tt.out", i) 67 break 68 } 69 if r1 != unicode.ReplacementChar || r2 != unicode.ReplacementChar { 70 t.Errorf("EncodeRune(%#x) = %#x, %#x; want 0xfffd, 0xfffd", r, r1, r2) 71 } 72 j++ 73 } else { 74 if j+1 >= len(tt.out) { 75 t.Errorf("#%d: ran out of tt.out", i) 76 break 77 } 78 if r1 != rune(tt.out[j]) || r2 != rune(tt.out[j+1]) { 79 t.Errorf("EncodeRune(%#x) = %#x, %#x; want %#x, %#x", r, r1, r2, tt.out[j], tt.out[j+1]) 80 } 81 j += 2 82 dec := DecodeRune(r1, r2) 83 if dec != r { 84 t.Errorf("DecodeRune(%#x, %#x) = %#x; want %#x", r1, r2, dec, r) 85 } 86 } 87 } 88 if j != len(tt.out) { 89 t.Errorf("#%d: EncodeRune didn't generate enough output", i) 90 } 91 } 92 } 93 94 type decodeTest struct { 95 in []uint16 96 out []rune 97 } 98 99 var decodeTests = []decodeTest{ 100 {[]uint16{1, 2, 3, 4}, []rune{1, 2, 3, 4}}, 101 {[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff}, 102 []rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}}, 103 {[]uint16{0xd800, 'a'}, []rune{0xfffd, 'a'}}, 104 {[]uint16{0xdfff}, []rune{0xfffd}}, 105 } 106 107 func TestAllocationsDecode(t *testing.T) { 108 testenv.SkipIfOptimizationOff(t) 109 110 for _, tt := range decodeTests { 111 allocs := testing.AllocsPerRun(10, func() { 112 out := Decode(tt.in) 113 if out == nil { 114 t.Errorf("Decode(%x) = nil", tt.in) 115 } 116 }) 117 if allocs > 0 { 118 t.Errorf("Decode allocated %v times", allocs) 119 } 120 } 121 } 122 123 func TestDecode(t *testing.T) { 124 for _, tt := range decodeTests { 125 out := Decode(tt.in) 126 if !reflect.DeepEqual(out, tt.out) { 127 t.Errorf("Decode(%x) = %x; want %x", tt.in, out, tt.out) 128 } 129 } 130 } 131 132 var decodeRuneTests = []struct { 133 r1, r2 rune 134 want rune 135 }{ 136 {0xd800, 0xdc00, 0x10000}, 137 {0xd800, 0xdc01, 0x10001}, 138 {0xd808, 0xdf45, 0x12345}, 139 {0xdbff, 0xdfff, 0x10ffff}, 140 {0xd800, 'a', 0xfffd}, // illegal, replacement rune substituted 141 } 142 143 func TestDecodeRune(t *testing.T) { 144 for i, tt := range decodeRuneTests { 145 got := DecodeRune(tt.r1, tt.r2) 146 if got != tt.want { 147 t.Errorf("%d: DecodeRune(%q, %q) = %v; want %v", i, tt.r1, tt.r2, got, tt.want) 148 } 149 } 150 } 151 152 var surrogateTests = []struct { 153 r rune 154 want bool 155 }{ 156 // from https://en.wikipedia.org/wiki/UTF-16 157 {'\u007A', false}, // LATIN SMALL LETTER Z 158 {'\u6C34', false}, // CJK UNIFIED IDEOGRAPH-6C34 (water) 159 {'\uFEFF', false}, // Byte Order Mark 160 {'\U00010000', false}, // LINEAR B SYLLABLE B008 A (first non-BMP code point) 161 {'\U0001D11E', false}, // MUSICAL SYMBOL G CLEF 162 {'\U0010FFFD', false}, // PRIVATE USE CHARACTER-10FFFD (last Unicode code point) 163 164 {rune(0xd7ff), false}, // surr1-1 165 {rune(0xd800), true}, // surr1 166 {rune(0xdc00), true}, // surr2 167 {rune(0xe000), false}, // surr3 168 {rune(0xdfff), true}, // surr3-1 169 } 170 171 func TestIsSurrogate(t *testing.T) { 172 for i, tt := range surrogateTests { 173 got := IsSurrogate(tt.r) 174 if got != tt.want { 175 t.Errorf("%d: IsSurrogate(%q) = %v; want %v", i, tt.r, got, tt.want) 176 } 177 } 178 } 179 180 func BenchmarkDecodeValidASCII(b *testing.B) { 181 // "hello world" 182 data := []uint16{104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100} 183 for i := 0; i < b.N; i++ { 184 Decode(data) 185 } 186 } 187 188 func BenchmarkDecodeValidJapaneseChars(b *testing.B) { 189 // "日本語日本語日本語" 190 data := []uint16{26085, 26412, 35486, 26085, 26412, 35486, 26085, 26412, 35486} 191 for i := 0; i < b.N; i++ { 192 Decode(data) 193 } 194 } 195 196 func BenchmarkDecodeRune(b *testing.B) { 197 rs := make([]rune, 10) 198 // U+1D4D0 to U+1D4D4: MATHEMATICAL BOLD SCRIPT CAPITAL LETTERS 199 for i, u := range []rune{'𝓐', '𝓑', '𝓒', '𝓓', '𝓔'} { 200 rs[2*i], rs[2*i+1] = EncodeRune(u) 201 } 202 203 b.ResetTimer() 204 for i := 0; i < b.N; i++ { 205 for j := 0; j < 5; j++ { 206 DecodeRune(rs[2*j], rs[2*j+1]) 207 } 208 } 209 } 210 211 func BenchmarkEncodeValidASCII(b *testing.B) { 212 data := []rune{'h', 'e', 'l', 'l', 'o'} 213 for i := 0; i < b.N; i++ { 214 Encode(data) 215 } 216 } 217 218 func BenchmarkEncodeValidJapaneseChars(b *testing.B) { 219 data := []rune{'日', '本', '語'} 220 for i := 0; i < b.N; i++ { 221 Encode(data) 222 } 223 } 224 225 func BenchmarkAppendRuneValidASCII(b *testing.B) { 226 data := []rune{'h', 'e', 'l', 'l', 'o'} 227 a := make([]uint16, 0, len(data)*2) 228 for i := 0; i < b.N; i++ { 229 for _, u := range data { 230 a = AppendRune(a, u) 231 } 232 a = a[:0] 233 } 234 } 235 236 func BenchmarkAppendRuneValidJapaneseChars(b *testing.B) { 237 data := []rune{'日', '本', '語'} 238 a := make([]uint16, 0, len(data)*2) 239 for i := 0; i < b.N; i++ { 240 for _, u := range data { 241 a = AppendRune(a, u) 242 } 243 a = a[:0] 244 } 245 } 246 247 func BenchmarkEncodeRune(b *testing.B) { 248 for i := 0; i < b.N; i++ { 249 for _, u := range []rune{'𝓐', '𝓑', '𝓒', '𝓓', '𝓔'} { 250 EncodeRune(u) 251 } 252 } 253 }