1 // Copyright 2009 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.
14 // Validate the constants redefined from unicode.
16 if MaxRune != unicode.MaxRune {
17 panic("utf8.MaxRune is wrong")
19 if RuneError != unicode.ReplacementChar {
20 panic("utf8.RuneError is wrong")
24 // Validate the constants redefined from unicode.
25 func TestConstants(t *testing.T) {
26 if MaxRune != unicode.MaxRune {
27 t.Errorf("utf8.MaxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune)
29 if RuneError != unicode.ReplacementChar {
30 t.Errorf("utf8.RuneError is wrong: %x should be %x", RuneError, unicode.ReplacementChar)
39 var utf8map = []Utf8Map{
57 {0x0800, "\xe0\xa0\x80"},
58 {0x0801, "\xe0\xa0\x81"},
59 {0xd7ff, "\xed\x9f\xbf"}, // last code point before surrogate half.
60 {0xe000, "\xee\x80\x80"}, // first code point after surrogate half.
61 {0xfffe, "\xef\xbf\xbe"},
62 {0xffff, "\xef\xbf\xbf"},
63 {0x10000, "\xf0\x90\x80\x80"},
64 {0x10001, "\xf0\x90\x80\x81"},
65 {0x10fffe, "\xf4\x8f\xbf\xbe"},
66 {0x10ffff, "\xf4\x8f\xbf\xbf"},
67 {0xFFFD, "\xef\xbf\xbd"},
70 var surrogateMap = []Utf8Map{
71 {0xd800, "\xed\xa0\x80"}, // surrogate min decodes to (RuneError, 1)
72 {0xdfff, "\xed\xbf\xbf"}, // surrogate max decodes to (RuneError, 1)
75 var testStrings = []string{
79 "日a本b語ç日ð本Ê語þ日¥本¼語i日©",
80 "日a本b語ç日ð本Ê語þ日¥本¼語i日©日a本b語ç日ð本Ê語þ日¥本¼語i日©日a本b語ç日ð本Ê語þ日¥本¼語i日©",
84 func TestFullRune(t *testing.T) {
85 for _, m := range utf8map {
88 t.Errorf("FullRune(%q) (%U) = false, want true", b, m.r)
91 if !FullRuneInString(s) {
92 t.Errorf("FullRuneInString(%q) (%U) = false, want true", s, m.r)
96 t.Errorf("FullRune(%q) = true, want false", b1)
99 if FullRuneInString(s1) {
100 t.Errorf("FullRune(%q) = true, want false", s1)
105 func TestEncodeRune(t *testing.T) {
106 for _, m := range utf8map {
109 n := EncodeRune(buf[0:], m.r)
111 if !bytes.Equal(b, b1) {
112 t.Errorf("EncodeRune(%#04x) = %q want %q", m.r, b1, b)
117 func TestDecodeRune(t *testing.T) {
118 for _, m := range utf8map {
120 r, size := DecodeRune(b)
121 if r != m.r || size != len(b) {
122 t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, m.r, len(b))
125 r, size = DecodeRuneInString(s)
126 if r != m.r || size != len(b) {
127 t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", s, r, size, m.r, len(b))
130 // there's an extra byte that bytes left behind - make sure trailing byte works
131 r, size = DecodeRune(b[0:cap(b)])
132 if r != m.r || size != len(b) {
133 t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, m.r, len(b))
136 r, size = DecodeRuneInString(s)
137 if r != m.r || size != len(b) {
138 t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, m.r, len(b))
141 // make sure missing bytes fail
143 if wantsize >= len(b) {
146 r, size = DecodeRune(b[0 : len(b)-1])
147 if r != RuneError || size != wantsize {
148 t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b[0:len(b)-1], r, size, RuneError, wantsize)
150 s = m.str[0 : len(m.str)-1]
151 r, size = DecodeRuneInString(s)
152 if r != RuneError || size != wantsize {
153 t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, RuneError, wantsize)
156 // make sure bad sequences fail
162 r, size = DecodeRune(b)
163 if r != RuneError || size != 1 {
164 t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, RuneError, 1)
167 r, size = DecodeRune(b)
168 if r != RuneError || size != 1 {
169 t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, RuneError, 1)
175 func TestDecodeSurrogateRune(t *testing.T) {
176 for _, m := range surrogateMap {
178 r, size := DecodeRune(b)
179 if r != RuneError || size != 1 {
180 t.Errorf("DecodeRune(%q) = %x, %d want %x, %d", b, r, size, RuneError, 1)
183 r, size = DecodeRuneInString(s)
184 if r != RuneError || size != 1 {
185 t.Errorf("DecodeRune(%q) = %x, %d want %x, %d", b, r, size, RuneError, 1)
190 // Check that DecodeRune and DecodeLastRune correspond to
191 // the equivalent range loop.
192 func TestSequencing(t *testing.T) {
193 for _, ts := range testStrings {
194 for _, m := range utf8map {
195 for _, s := range []string{ts + m.str, m.str + ts, ts + m.str + ts} {
202 // Check that a range loop and a []int conversion visit the same runes.
203 // Not really a test of this package, but the assumption is used here and
204 // it's good to verify
205 func TestIntConversion(t *testing.T) {
206 for _, ts := range testStrings {
208 if RuneCountInString(ts) != len(runes) {
209 t.Errorf("%q: expected %d runes; got %d", ts, len(runes), RuneCountInString(ts))
213 for _, r := range ts {
215 t.Errorf("%q[%d]: expected %c (%U); got %c (%U)", ts, i, runes[i], runes[i], r, r)
222 func testSequence(t *testing.T, s string) {
227 index := make([]info, len(s))
231 for i, r := range s {
233 t.Errorf("Sequence(%q) mismatched index %d, want %d", s, si, i)
236 index[j] = info{i, r}
238 r1, size1 := DecodeRune(b[i:])
240 t.Errorf("DecodeRune(%q) = %#04x, want %#04x", s[i:], r1, r)
243 r2, size2 := DecodeRuneInString(s[i:])
245 t.Errorf("DecodeRuneInString(%q) = %#04x, want %#04x", s[i:], r2, r)
249 t.Errorf("DecodeRune/DecodeRuneInString(%q) size mismatch %d/%d", s[i:], size1, size2)
255 for si = len(s); si > 0; {
256 r1, size1 := DecodeLastRune(b[0:si])
257 r2, size2 := DecodeLastRuneInString(s[0:si])
259 t.Errorf("DecodeLastRune/DecodeLastRuneInString(%q, %d) size mismatch %d/%d", s, si, size1, size2)
262 if r1 != index[j].r {
263 t.Errorf("DecodeLastRune(%q, %d) = %#04x, want %#04x", s, si, r1, index[j].r)
266 if r2 != index[j].r {
267 t.Errorf("DecodeLastRuneInString(%q, %d) = %#04x, want %#04x", s, si, r2, index[j].r)
271 if si != index[j].index {
272 t.Errorf("DecodeLastRune(%q) index mismatch at %d, want %d", s, si, index[j].index)
278 t.Errorf("DecodeLastRune(%q) finished at %d, not 0", s, si)
282 // Check that negative runes encode as U+FFFD.
283 func TestNegativeRune(t *testing.T) {
284 errorbuf := make([]byte, UTFMax)
285 errorbuf = errorbuf[0:EncodeRune(errorbuf, RuneError)]
286 buf := make([]byte, UTFMax)
287 buf = buf[0:EncodeRune(buf, -1)]
288 if !bytes.Equal(buf, errorbuf) {
289 t.Errorf("incorrect encoding [% x] for -1; expected [% x]", buf, errorbuf)
293 type RuneCountTest struct {
298 var runecounttests = []RuneCountTest{
305 func TestRuneCount(t *testing.T) {
306 for _, tt := range runecounttests {
307 if out := RuneCountInString(tt.in); out != tt.out {
308 t.Errorf("RuneCountInString(%q) = %d, want %d", tt.in, out, tt.out)
310 if out := RuneCount([]byte(tt.in)); out != tt.out {
311 t.Errorf("RuneCount(%q) = %d, want %d", tt.in, out, tt.out)
316 type RuneLenTest struct {
321 var runelentests = []RuneLenTest{
334 func TestRuneLen(t *testing.T) {
335 for _, tt := range runelentests {
336 if size := RuneLen(tt.r); size != tt.size {
337 t.Errorf("RuneLen(%#U) = %d, want %d", tt.r, size, tt.size)
342 type ValidTest struct {
347 var validTests = []ValidTest{
355 {string([]byte{66, 250}), false},
356 {string([]byte{66, 250, 67}), false},
358 {string("\xF4\x8F\xBF\xBF"), true}, // U+10FFFF
359 {string("\xF4\x90\x80\x80"), false}, // U+10FFFF+1; out of range
360 {string("\xF7\xBF\xBF\xBF"), false}, // 0x1FFFFF; out of range
361 {string("\xFB\xBF\xBF\xBF\xBF"), false}, // 0x3FFFFFF; out of range
362 {string("\xc0\x80"), false}, // U+0000 encoded in two bytes: incorrect
363 {string("\xed\xa0\x80"), false}, // U+D800 high surrogate (sic)
364 {string("\xed\xbf\xbf"), false}, // U+DFFF low surrogate (sic)
367 func TestValid(t *testing.T) {
368 for _, tt := range validTests {
369 if Valid([]byte(tt.in)) != tt.out {
370 t.Errorf("Valid(%q) = %v; want %v", tt.in, !tt.out, tt.out)
372 if ValidString(tt.in) != tt.out {
373 t.Errorf("ValidString(%q) = %v; want %v", tt.in, !tt.out, tt.out)
378 type ValidRuneTest struct {
383 var validrunetests = []ValidRuneTest{
394 {MaxRune + 1, false},
398 func TestValidRune(t *testing.T) {
399 for _, tt := range validrunetests {
400 if ok := ValidRune(tt.r); ok != tt.ok {
401 t.Errorf("ValidRune(%#U) = %t, want %t", tt.r, ok, tt.ok)
406 func BenchmarkRuneCountTenASCIIChars(b *testing.B) {
407 for i := 0; i < b.N; i++ {
408 RuneCountInString("0123456789")
412 func BenchmarkRuneCountTenJapaneseChars(b *testing.B) {
413 for i := 0; i < b.N; i++ {
414 RuneCountInString("日本語日本語日本語日")
418 func BenchmarkEncodeASCIIRune(b *testing.B) {
419 buf := make([]byte, UTFMax)
420 for i := 0; i < b.N; i++ {
425 func BenchmarkEncodeJapaneseRune(b *testing.B) {
426 buf := make([]byte, UTFMax)
427 for i := 0; i < b.N; i++ {
432 func BenchmarkDecodeASCIIRune(b *testing.B) {
434 for i := 0; i < b.N; i++ {
439 func BenchmarkDecodeJapaneseRune(b *testing.B) {
441 for i := 0; i < b.N; i++ {