Revert r215321.
[official-gcc.git] / libgo / go / fmt / scan_test.go
blobd903f0c3ff74cfcf254729439b2293ad1ba3cf1e
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.
5 package fmt_test
7 import (
8 "bufio"
9 "bytes"
10 "errors"
11 . "fmt"
12 "io"
13 "math"
14 "reflect"
15 "regexp"
16 "strings"
17 "testing"
18 "unicode/utf8"
21 type ScanTest struct {
22 text string
23 in interface{}
24 out interface{}
27 type ScanfTest struct {
28 format string
29 text string
30 in interface{}
31 out interface{}
34 type ScanfMultiTest struct {
35 format string
36 text string
37 in []interface{}
38 out []interface{}
39 err string
42 var (
43 boolVal bool
44 intVal int
45 int8Val int8
46 int16Val int16
47 int32Val int32
48 int64Val int64
49 uintVal uint
50 uint8Val uint8
51 uint16Val uint16
52 uint32Val uint32
53 uint64Val uint64
54 float32Val float32
55 float64Val float64
56 stringVal string
57 bytesVal []byte
58 runeVal rune
59 complex64Val complex64
60 complex128Val complex128
61 renamedBoolVal renamedBool
62 renamedIntVal renamedInt
63 renamedInt8Val renamedInt8
64 renamedInt16Val renamedInt16
65 renamedInt32Val renamedInt32
66 renamedInt64Val renamedInt64
67 renamedUintVal renamedUint
68 renamedUint8Val renamedUint8
69 renamedUint16Val renamedUint16
70 renamedUint32Val renamedUint32
71 renamedUint64Val renamedUint64
72 renamedUintptrVal renamedUintptr
73 renamedStringVal renamedString
74 renamedBytesVal renamedBytes
75 renamedFloat32Val renamedFloat32
76 renamedFloat64Val renamedFloat64
77 renamedComplex64Val renamedComplex64
78 renamedComplex128Val renamedComplex128
81 type FloatTest struct {
82 text string
83 in float64
84 out float64
87 // Xs accepts any non-empty run of the verb character
88 type Xs string
90 func (x *Xs) Scan(state ScanState, verb rune) error {
91 tok, err := state.Token(true, func(r rune) bool { return r == verb })
92 if err != nil {
93 return err
95 s := string(tok)
96 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
97 return errors.New("syntax error for xs")
99 *x = Xs(s)
100 return nil
103 var xVal Xs
105 // IntString accepts an integer followed immediately by a string.
106 // It tests the embedding of a scan within a scan.
107 type IntString struct {
108 i int
109 s string
112 func (s *IntString) Scan(state ScanState, verb rune) error {
113 if _, err := Fscan(state, &s.i); err != nil {
114 return err
117 tok, err := state.Token(true, nil)
118 if err != nil {
119 return err
121 s.s = string(tok)
122 return nil
125 var intStringVal IntString
127 // myStringReader implements Read but not ReadRune, allowing us to test our readRune wrapper
128 // type that creates something that can read runes given only Read().
129 type myStringReader struct {
130 r *strings.Reader
133 func (s *myStringReader) Read(p []byte) (n int, err error) {
134 return s.r.Read(p)
137 func newReader(s string) *myStringReader {
138 return &myStringReader{strings.NewReader(s)}
141 var scanTests = []ScanTest{
142 // Basic types
143 {"T\n", &boolVal, true}, // boolean test vals toggle to be sure they are written
144 {"F\n", &boolVal, false}, // restored to zero value
145 {"21\n", &intVal, 21},
146 {"0\n", &intVal, 0},
147 {"000\n", &intVal, 0},
148 {"0x10\n", &intVal, 0x10},
149 {"-0x10\n", &intVal, -0x10},
150 {"0377\n", &intVal, 0377},
151 {"-0377\n", &intVal, -0377},
152 {"0\n", &uintVal, uint(0)},
153 {"000\n", &uintVal, uint(0)},
154 {"0x10\n", &uintVal, uint(0x10)},
155 {"0377\n", &uintVal, uint(0377)},
156 {"22\n", &int8Val, int8(22)},
157 {"23\n", &int16Val, int16(23)},
158 {"24\n", &int32Val, int32(24)},
159 {"25\n", &int64Val, int64(25)},
160 {"127\n", &int8Val, int8(127)},
161 {"-21\n", &intVal, -21},
162 {"-22\n", &int8Val, int8(-22)},
163 {"-23\n", &int16Val, int16(-23)},
164 {"-24\n", &int32Val, int32(-24)},
165 {"-25\n", &int64Val, int64(-25)},
166 {"-128\n", &int8Val, int8(-128)},
167 {"+21\n", &intVal, +21},
168 {"+22\n", &int8Val, int8(+22)},
169 {"+23\n", &int16Val, int16(+23)},
170 {"+24\n", &int32Val, int32(+24)},
171 {"+25\n", &int64Val, int64(+25)},
172 {"+127\n", &int8Val, int8(+127)},
173 {"26\n", &uintVal, uint(26)},
174 {"27\n", &uint8Val, uint8(27)},
175 {"28\n", &uint16Val, uint16(28)},
176 {"29\n", &uint32Val, uint32(29)},
177 {"30\n", &uint64Val, uint64(30)},
178 {"255\n", &uint8Val, uint8(255)},
179 {"32767\n", &int16Val, int16(32767)},
180 {"2.3\n", &float64Val, 2.3},
181 {"2.3e1\n", &float32Val, float32(2.3e1)},
182 {"2.3e2\n", &float64Val, 2.3e2},
183 {"2.3p2\n", &float64Val, 2.3 * 4},
184 {"2.3p+2\n", &float64Val, 2.3 * 4},
185 {"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
186 {"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
187 {"2.35\n", &stringVal, "2.35"},
188 {"2345678\n", &bytesVal, []byte("2345678")},
189 {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
190 {"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
191 {"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
192 {"hello\n", &stringVal, "hello"},
194 // Carriage-return followed by newline. (We treat \r\n as \n always.)
195 {"hello\r\n", &stringVal, "hello"},
196 {"27\r\n", &uint8Val, uint8(27)},
198 // Renamed types
199 {"true\n", &renamedBoolVal, renamedBool(true)},
200 {"F\n", &renamedBoolVal, renamedBool(false)},
201 {"101\n", &renamedIntVal, renamedInt(101)},
202 {"102\n", &renamedIntVal, renamedInt(102)},
203 {"103\n", &renamedUintVal, renamedUint(103)},
204 {"104\n", &renamedUintVal, renamedUint(104)},
205 {"105\n", &renamedInt8Val, renamedInt8(105)},
206 {"106\n", &renamedInt16Val, renamedInt16(106)},
207 {"107\n", &renamedInt32Val, renamedInt32(107)},
208 {"108\n", &renamedInt64Val, renamedInt64(108)},
209 {"109\n", &renamedUint8Val, renamedUint8(109)},
210 {"110\n", &renamedUint16Val, renamedUint16(110)},
211 {"111\n", &renamedUint32Val, renamedUint32(111)},
212 {"112\n", &renamedUint64Val, renamedUint64(112)},
213 {"113\n", &renamedUintptrVal, renamedUintptr(113)},
214 {"114\n", &renamedStringVal, renamedString("114")},
215 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
217 // Custom scanners.
218 {" vvv ", &xVal, Xs("vvv")},
219 {" 1234hello", &intStringVal, IntString{1234, "hello"}},
221 // Fixed bugs
222 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
225 var scanfTests = []ScanfTest{
226 {"%v", "TRUE\n", &boolVal, true},
227 {"%t", "false\n", &boolVal, false},
228 {"%v", "-71\n", &intVal, -71},
229 {"%v", "0377\n", &intVal, 0377},
230 {"%v", "0x44\n", &intVal, 0x44},
231 {"%d", "72\n", &intVal, 72},
232 {"%c", "a\n", &runeVal, 'a'},
233 {"%c", "\u5072\n", &runeVal, '\u5072'},
234 {"%c", "\u1234\n", &runeVal, '\u1234'},
235 {"%d", "73\n", &int8Val, int8(73)},
236 {"%d", "+74\n", &int16Val, int16(74)},
237 {"%d", "75\n", &int32Val, int32(75)},
238 {"%d", "76\n", &int64Val, int64(76)},
239 {"%b", "1001001\n", &intVal, 73},
240 {"%o", "075\n", &intVal, 075},
241 {"%x", "a75\n", &intVal, 0xa75},
242 {"%v", "71\n", &uintVal, uint(71)},
243 {"%d", "72\n", &uintVal, uint(72)},
244 {"%d", "73\n", &uint8Val, uint8(73)},
245 {"%d", "74\n", &uint16Val, uint16(74)},
246 {"%d", "75\n", &uint32Val, uint32(75)},
247 {"%d", "76\n", &uint64Val, uint64(76)},
248 {"%b", "1001001\n", &uintVal, uint(73)},
249 {"%o", "075\n", &uintVal, uint(075)},
250 {"%x", "a75\n", &uintVal, uint(0xa75)},
251 {"%x", "A75\n", &uintVal, uint(0xa75)},
252 {"%U", "U+1234\n", &intVal, int(0x1234)},
253 {"%U", "U+4567\n", &uintVal, uint(0x4567)},
255 // Strings
256 {"%s", "using-%s\n", &stringVal, "using-%s"},
257 {"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
258 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
259 {"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
261 // Byte slices
262 {"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
263 {"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
264 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
265 {"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
267 // Renamed types
268 {"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
269 {"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
270 {"%v", "101\n", &renamedIntVal, renamedInt(101)},
271 {"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
272 {"%o", "0146\n", &renamedIntVal, renamedInt(102)},
273 {"%v", "103\n", &renamedUintVal, renamedUint(103)},
274 {"%d", "104\n", &renamedUintVal, renamedUint(104)},
275 {"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
276 {"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
277 {"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
278 {"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
279 {"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
280 {"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
281 {"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
282 {"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
283 {"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
284 {"%s", "114\n", &renamedStringVal, renamedString("114")},
285 {"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
286 {"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
287 {"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
288 {"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
289 {"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
291 // Interesting formats
292 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal, 118},
293 {"%% %%:%d", "% %:119\n", &intVal, 119},
295 // Corner cases
296 {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
298 // Custom scanner.
299 {"%s", " sss ", &xVal, Xs("sss")},
300 {"%2s", "sssss", &xVal, Xs("ss")},
302 // Fixed bugs
303 {"%d\n", "27\n", &intVal, 27}, // ok
304 {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
305 {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
306 {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
309 var overflowTests = []ScanTest{
310 {"128", &int8Val, 0},
311 {"32768", &int16Val, 0},
312 {"-129", &int8Val, 0},
313 {"-32769", &int16Val, 0},
314 {"256", &uint8Val, 0},
315 {"65536", &uint16Val, 0},
316 {"1e100", &float32Val, 0},
317 {"1e500", &float64Val, 0},
318 {"(1e100+0i)", &complex64Val, 0},
319 {"(1+1e100i)", &complex64Val, 0},
320 {"(1-1e500i)", &complex128Val, 0},
323 var truth bool
324 var i, j, k int
325 var f float64
326 var s, t string
327 var c complex128
328 var x, y Xs
329 var z IntString
330 var r1, r2, r3 rune
332 var multiTests = []ScanfMultiTest{
333 {"", "", []interface{}{}, []interface{}{}, ""},
334 {"%d", "23", args(&i), args(23), ""},
335 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
336 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
337 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
338 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
339 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
340 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
341 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
342 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
344 // Custom scanners.
345 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
346 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
348 // Errors
349 {"%t", "23 18", args(&i), nil, "bad verb"},
350 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
351 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
352 {"%c", "\u0100", args(&int8Val), nil, "overflow"},
353 {"X%d", "10X", args(&intVal), nil, "input does not match format"},
355 // Bad UTF-8: should see every byte.
356 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
358 // Fixed bugs
359 {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
362 func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
363 for _, test := range scanTests {
364 var r io.Reader
365 if name == "StringReader" {
366 r = strings.NewReader(test.text)
367 } else {
368 r = newReader(test.text)
370 n, err := scan(r, test.in)
371 if err != nil {
372 m := ""
373 if n > 0 {
374 m = Sprintf(" (%d fields ok)", n)
376 t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
377 continue
379 if n != 1 {
380 t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
381 continue
383 // The incoming value may be a pointer
384 v := reflect.ValueOf(test.in)
385 if p := v; p.Kind() == reflect.Ptr {
386 v = p.Elem()
388 val := v.Interface()
389 if !reflect.DeepEqual(val, test.out) {
390 t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
395 func TestScan(t *testing.T) {
396 testScan("StringReader", t, Fscan)
399 func TestMyReaderScan(t *testing.T) {
400 testScan("myStringReader", t, Fscan)
403 func TestScanln(t *testing.T) {
404 testScan("StringReader", t, Fscanln)
407 func TestMyReaderScanln(t *testing.T) {
408 testScan("myStringReader", t, Fscanln)
411 func TestScanf(t *testing.T) {
412 for _, test := range scanfTests {
413 n, err := Sscanf(test.text, test.format, test.in)
414 if err != nil {
415 t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
416 continue
418 if n != 1 {
419 t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
420 continue
422 // The incoming value may be a pointer
423 v := reflect.ValueOf(test.in)
424 if p := v; p.Kind() == reflect.Ptr {
425 v = p.Elem()
427 val := v.Interface()
428 if !reflect.DeepEqual(val, test.out) {
429 t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
434 func TestScanOverflow(t *testing.T) {
435 // different machines and different types report errors with different strings.
436 re := regexp.MustCompile("overflow|too large|out of range|not representable")
437 for _, test := range overflowTests {
438 _, err := Sscan(test.text, test.in)
439 if err == nil {
440 t.Errorf("expected overflow scanning %q", test.text)
441 continue
443 if !re.MatchString(err.Error()) {
444 t.Errorf("expected overflow error scanning %q: %s", test.text, err)
449 func verifyNaN(str string, t *testing.T) {
450 var f float64
451 var f32 float32
452 var f64 float64
453 text := str + " " + str + " " + str
454 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
455 if err != nil {
456 t.Errorf("got error scanning %q: %s", text, err)
458 if n != 3 {
459 t.Errorf("count error scanning %q: got %d", text, n)
461 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
462 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
466 func TestNaN(t *testing.T) {
467 for _, s := range []string{"nan", "NAN", "NaN"} {
468 verifyNaN(s, t)
472 func verifyInf(str string, t *testing.T) {
473 var f float64
474 var f32 float32
475 var f64 float64
476 text := str + " " + str + " " + str
477 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
478 if err != nil {
479 t.Errorf("got error scanning %q: %s", text, err)
481 if n != 3 {
482 t.Errorf("count error scanning %q: got %d", text, n)
484 sign := 1
485 if str[0] == '-' {
486 sign = -1
488 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
489 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
493 func TestInf(t *testing.T) {
494 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
495 verifyInf(s, t)
499 func testScanfMulti(name string, t *testing.T) {
500 sliceType := reflect.TypeOf(make([]interface{}, 1))
501 for _, test := range multiTests {
502 var r io.Reader
503 if name == "StringReader" {
504 r = strings.NewReader(test.text)
505 } else {
506 r = newReader(test.text)
508 n, err := Fscanf(r, test.format, test.in...)
509 if err != nil {
510 if test.err == "" {
511 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
512 } else if strings.Index(err.Error(), test.err) < 0 {
513 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
515 continue
517 if test.err != "" {
518 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
520 if n != len(test.out) {
521 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
522 continue
524 // Convert the slice of pointers into a slice of values
525 resultVal := reflect.MakeSlice(sliceType, n, n)
526 for i := 0; i < n; i++ {
527 v := reflect.ValueOf(test.in[i]).Elem()
528 resultVal.Index(i).Set(v)
530 result := resultVal.Interface()
531 if !reflect.DeepEqual(result, test.out) {
532 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
537 func TestScanfMulti(t *testing.T) {
538 testScanfMulti("StringReader", t)
541 func TestMyReaderScanfMulti(t *testing.T) {
542 testScanfMulti("myStringReader", t)
545 func TestScanMultiple(t *testing.T) {
546 var a int
547 var s string
548 n, err := Sscan("123abc", &a, &s)
549 if n != 2 {
550 t.Errorf("Sscan count error: expected 2: got %d", n)
552 if err != nil {
553 t.Errorf("Sscan expected no error; got %s", err)
555 if a != 123 || s != "abc" {
556 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
558 n, err = Sscan("asdf", &s, &a)
559 if n != 1 {
560 t.Errorf("Sscan count error: expected 1: got %d", n)
562 if err == nil {
563 t.Errorf("Sscan expected error; got none: %s", err)
565 if s != "asdf" {
566 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
570 // Empty strings are not valid input when scanning a string.
571 func TestScanEmpty(t *testing.T) {
572 var s1, s2 string
573 n, err := Sscan("abc", &s1, &s2)
574 if n != 1 {
575 t.Errorf("Sscan count error: expected 1: got %d", n)
577 if err == nil {
578 t.Error("Sscan <one item> expected error; got none")
580 if s1 != "abc" {
581 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
583 n, err = Sscan("", &s1, &s2)
584 if n != 0 {
585 t.Errorf("Sscan count error: expected 0: got %d", n)
587 if err == nil {
588 t.Error("Sscan <empty> expected error; got none")
590 // Quoted empty string is OK.
591 n, err = Sscanf(`""`, "%q", &s1)
592 if n != 1 {
593 t.Errorf("Sscanf count error: expected 1: got %d", n)
595 if err != nil {
596 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
600 func TestScanNotPointer(t *testing.T) {
601 r := strings.NewReader("1")
602 var a int
603 _, err := Fscan(r, a)
604 if err == nil {
605 t.Error("expected error scanning non-pointer")
606 } else if strings.Index(err.Error(), "pointer") < 0 {
607 t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
611 func TestScanlnNoNewline(t *testing.T) {
612 var a int
613 _, err := Sscanln("1 x\n", &a)
614 if err == nil {
615 t.Error("expected error scanning string missing newline")
616 } else if strings.Index(err.Error(), "newline") < 0 {
617 t.Errorf("expected newline error scanning string missing newline, got: %s", err)
621 func TestScanlnWithMiddleNewline(t *testing.T) {
622 r := strings.NewReader("123\n456\n")
623 var a, b int
624 _, err := Fscanln(r, &a, &b)
625 if err == nil {
626 t.Error("expected error scanning string with extra newline")
627 } else if strings.Index(err.Error(), "newline") < 0 {
628 t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
632 // eofCounter is a special Reader that counts reads at end of file.
633 type eofCounter struct {
634 reader *strings.Reader
635 eofCount int
638 func (ec *eofCounter) Read(b []byte) (n int, err error) {
639 n, err = ec.reader.Read(b)
640 if n == 0 {
641 ec.eofCount++
643 return
646 // TestEOF verifies that when we scan, we see at most EOF once per call to a
647 // Scan function, and then only when it's really an EOF.
648 func TestEOF(t *testing.T) {
649 ec := &eofCounter{strings.NewReader("123\n"), 0}
650 var a int
651 n, err := Fscanln(ec, &a)
652 if err != nil {
653 t.Error("unexpected error", err)
655 if n != 1 {
656 t.Error("expected to scan one item, got", n)
658 if ec.eofCount != 0 {
659 t.Error("expected zero EOFs", ec.eofCount)
660 ec.eofCount = 0 // reset for next test
662 n, err = Fscanln(ec, &a)
663 if err == nil {
664 t.Error("expected error scanning empty string")
666 if n != 0 {
667 t.Error("expected to scan zero items, got", n)
669 if ec.eofCount != 1 {
670 t.Error("expected one EOF, got", ec.eofCount)
674 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
675 // This was a buglet: we used to get "expected integer".
676 func TestEOFAtEndOfInput(t *testing.T) {
677 var i, j int
678 n, err := Sscanf("23", "%d %d", &i, &j)
679 if n != 1 || i != 23 {
680 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
682 if err != io.EOF {
683 t.Errorf("Sscanf expected EOF; got %q", err)
685 n, err = Sscan("234", &i, &j)
686 if n != 1 || i != 234 {
687 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
689 if err != io.EOF {
690 t.Errorf("Sscan expected EOF; got %q", err)
692 // Trailing space is tougher.
693 n, err = Sscan("234 ", &i, &j)
694 if n != 1 || i != 234 {
695 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
697 if err != io.EOF {
698 t.Errorf("Sscan expected EOF; got %q", err)
702 var eofTests = []struct {
703 format string
704 v interface{}
706 {"%s", &stringVal},
707 {"%q", &stringVal},
708 {"%x", &stringVal},
709 {"%v", &stringVal},
710 {"%v", &bytesVal},
711 {"%v", &intVal},
712 {"%v", &uintVal},
713 {"%v", &boolVal},
714 {"%v", &float32Val},
715 {"%v", &complex64Val},
716 {"%v", &renamedStringVal},
717 {"%v", &renamedBytesVal},
718 {"%v", &renamedIntVal},
719 {"%v", &renamedUintVal},
720 {"%v", &renamedBoolVal},
721 {"%v", &renamedFloat32Val},
722 {"%v", &renamedComplex64Val},
725 func TestEOFAllTypes(t *testing.T) {
726 for i, test := range eofTests {
727 if _, err := Sscanf("", test.format, test.v); err != io.EOF {
728 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
730 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF {
731 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
736 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
737 // calls to Fscan do not lose runes.
738 func TestUnreadRuneWithBufio(t *testing.T) {
739 r := bufio.NewReader(strings.NewReader("123αb"))
740 var i int
741 var a string
742 n, err := Fscanf(r, "%d", &i)
743 if n != 1 || err != nil {
744 t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
746 if i != 123 {
747 t.Errorf("expected 123; got %d", i)
749 n, err = Fscanf(r, "%s", &a)
750 if n != 1 || err != nil {
751 t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
753 if a != "αb" {
754 t.Errorf("expected αb; got %q", a)
758 type TwoLines string
760 // Scan attempts to read two lines into the object. Scanln should prevent this
761 // because it stops at newline; Scan and Scanf should be fine.
762 func (t *TwoLines) Scan(state ScanState, verb rune) error {
763 chars := make([]rune, 0, 100)
764 for nlCount := 0; nlCount < 2; {
765 c, _, err := state.ReadRune()
766 if err != nil {
767 return err
769 chars = append(chars, c)
770 if c == '\n' {
771 nlCount++
774 *t = TwoLines(string(chars))
775 return nil
778 func TestMultiLine(t *testing.T) {
779 input := "abc\ndef\n"
780 // Sscan should work
781 var tscan TwoLines
782 n, err := Sscan(input, &tscan)
783 if n != 1 {
784 t.Errorf("Sscan: expected 1 item; got %d", n)
786 if err != nil {
787 t.Errorf("Sscan: expected no error; got %s", err)
789 if string(tscan) != input {
790 t.Errorf("Sscan: expected %q; got %q", input, tscan)
792 // Sscanf should work
793 var tscanf TwoLines
794 n, err = Sscanf(input, "%s", &tscanf)
795 if n != 1 {
796 t.Errorf("Sscanf: expected 1 item; got %d", n)
798 if err != nil {
799 t.Errorf("Sscanf: expected no error; got %s", err)
801 if string(tscanf) != input {
802 t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
804 // Sscanln should not work
805 var tscanln TwoLines
806 n, err = Sscanln(input, &tscanln)
807 if n != 0 {
808 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
810 if err == nil {
811 t.Error("Sscanln: expected error; got none")
812 } else if err != io.ErrUnexpectedEOF {
813 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
817 // simpleReader is a strings.Reader that implements only Read, not ReadRune.
818 // Good for testing readahead.
819 type simpleReader struct {
820 sr *strings.Reader
823 func (s *simpleReader) Read(b []byte) (n int, err error) {
824 return s.sr.Read(b)
827 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
828 // 3481.
829 func TestLineByLineFscanf(t *testing.T) {
830 r := &simpleReader{strings.NewReader("1\n2\n")}
831 var i, j int
832 n, err := Fscanf(r, "%v\n", &i)
833 if n != 1 || err != nil {
834 t.Fatalf("first read: %d %q", n, err)
836 n, err = Fscanf(r, "%v\n", &j)
837 if n != 1 || err != nil {
838 t.Fatalf("second read: %d %q", n, err)
840 if i != 1 || j != 2 {
841 t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
845 // RecursiveInt accepts a string matching %d.%d.%d....
846 // and parses it into a linked list.
847 // It allows us to benchmark recursive descent style scanners.
848 type RecursiveInt struct {
849 i int
850 next *RecursiveInt
853 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
854 _, err = Fscan(state, &r.i)
855 if err != nil {
856 return
858 next := new(RecursiveInt)
859 _, err = Fscanf(state, ".%v", next)
860 if err != nil {
861 if err == io.ErrUnexpectedEOF {
862 err = nil
864 return
866 r.next = next
867 return
870 // scanInts performs the same scanning task as RecursiveInt.Scan
871 // but without recurring through scanner, so we can compare
872 // performance more directly.
873 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
874 r.next = nil
875 _, err = Fscan(b, &r.i)
876 if err != nil {
877 return
879 c, _, err := b.ReadRune()
880 if err != nil {
881 if err == io.EOF {
882 err = nil
884 return
886 if c != '.' {
887 return
889 next := new(RecursiveInt)
890 err = scanInts(next, b)
891 if err == nil {
892 r.next = next
894 return
897 func makeInts(n int) []byte {
898 var buf bytes.Buffer
899 Fprintf(&buf, "1")
900 for i := 1; i < n; i++ {
901 Fprintf(&buf, ".%d", i+1)
903 return buf.Bytes()
906 func TestScanInts(t *testing.T) {
907 testScanInts(t, scanInts)
908 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
909 _, err = Fscan(b, r)
910 return
914 // 800 is small enough to not overflow the stack when using gccgo on a
915 // platform that does not support split stack.
916 const intCount = 800
918 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
919 r := new(RecursiveInt)
920 ints := makeInts(intCount)
921 buf := bytes.NewBuffer(ints)
922 err := scan(r, buf)
923 if err != nil {
924 t.Error("unexpected error", err)
926 i := 1
927 for ; r != nil; r = r.next {
928 if r.i != i {
929 t.Fatalf("bad scan: expected %d got %d", i, r.i)
933 if i-1 != intCount {
934 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
938 func BenchmarkScanInts(b *testing.B) {
939 b.ResetTimer()
940 ints := makeInts(intCount)
941 var r RecursiveInt
942 for i := b.N - 1; i >= 0; i-- {
943 buf := bytes.NewBuffer(ints)
944 b.StartTimer()
945 scanInts(&r, buf)
946 b.StopTimer()
950 func BenchmarkScanRecursiveInt(b *testing.B) {
951 b.ResetTimer()
952 ints := makeInts(intCount)
953 var r RecursiveInt
954 for i := b.N - 1; i >= 0; i-- {
955 buf := bytes.NewBuffer(ints)
956 b.StartTimer()
957 Fscan(buf, &r)
958 b.StopTimer()