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.
21 type ScanTest
struct {
27 type ScanfTest
struct {
34 type ScanfMultiTest
struct {
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 {
87 // Xs accepts any non-empty run of the verb character
90 func (x
*Xs
) Scan(state ScanState
, verb rune
) error
{
91 tok
, err
:= state
.Token(true, func(r rune
) bool { return r
== verb
})
96 if !regexp
.MustCompile("^" + string(verb
) + "+$").MatchString(s
) {
97 return errors
.New("syntax error for 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 {
112 func (s
*IntString
) Scan(state ScanState
, verb rune
) error
{
113 if _
, err
:= Fscan(state
, &s
.i
); err
!= nil {
117 tok
, err
:= state
.Token(true, 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 {
133 func (s
*myStringReader
) Read(p
[]byte) (n
int, err error
) {
137 func newReader(s
string) *myStringReader
{
138 return &myStringReader
{strings
.NewReader(s
)}
141 var scanTests
= []ScanTest
{
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},
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)},
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"))},
218 {" vvv ", &xVal
, Xs("vvv")},
219 {" 1234hello", &intStringVal
, IntString
{1234, "hello"}},
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)},
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"},
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")},
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},
296 {"%x", "FFFFFFFF\n", &uint32Val
, uint32(0xFFFFFFFF)},
299 {"%s", " sss ", &xVal
, Xs("sss")},
300 {"%2s", "sssss", &xVal
, Xs("ss")},
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},
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'), ""},
345 {"%e%f", "eefffff", args(&x
, &y
), args(Xs("ee"), Xs("fffff")), ""},
346 {"%4v%s", "12abcd", args(&z
, &s
), args(IntString
{12, "ab"}, "cd"), ""},
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
), ""},
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
{
365 if name
== "StringReader" {
366 r
= strings
.NewReader(test
.text
)
368 r
= newReader(test
.text
)
370 n
, err
:= scan(r
, test
.in
)
374 m
= Sprintf(" (%d fields ok)", n
)
376 t
.Errorf("%s got error scanning %q: %s%s", name
, test
.text
, err
, m
)
380 t
.Errorf("%s count error on entry %q: got %d", name
, test
.text
, n
)
383 // The incoming value may be a pointer
384 v
:= reflect
.ValueOf(test
.in
)
385 if p
:= v
; p
.Kind() == reflect
.Ptr
{
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
)
415 t
.Errorf("got error scanning (%q, %q): %s", test
.format
, test
.text
, err
)
419 t
.Errorf("count error on entry (%q, %q): got %d", test
.format
, test
.text
, n
)
422 // The incoming value may be a pointer
423 v
:= reflect
.ValueOf(test
.in
)
424 if p
:= v
; p
.Kind() == reflect
.Ptr
{
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
)
440 t
.Errorf("expected overflow scanning %q", test
.text
)
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
) {
453 text
:= str
+ " " + str
+ " " + str
454 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
456 t
.Errorf("got error scanning %q: %s", text
, err
)
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"} {
472 func verifyInf(str
string, t
*testing
.T
) {
476 text
:= str
+ " " + str
+ " " + str
477 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
479 t
.Errorf("got error scanning %q: %s", text
, err
)
482 t
.Errorf("count error scanning %q: got %d", text
, n
)
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"} {
499 func testScanfMulti(name
string, t
*testing
.T
) {
500 sliceType
:= reflect
.TypeOf(make([]interface{}, 1))
501 for _
, test
:= range multiTests
{
503 if name
== "StringReader" {
504 r
= strings
.NewReader(test
.text
)
506 r
= newReader(test
.text
)
508 n
, err
:= Fscanf(r
, test
.format
, test
.in
...)
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
)
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
)
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
) {
548 n
, err
:= Sscan("123abc", &a
, &s
)
550 t
.Errorf("Sscan count error: expected 2: got %d", n
)
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
)
560 t
.Errorf("Sscan count error: expected 1: got %d", n
)
563 t
.Errorf("Sscan expected error; got none: %s", err
)
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
) {
573 n
, err
:= Sscan("abc", &s1
, &s2
)
575 t
.Errorf("Sscan count error: expected 1: got %d", n
)
578 t
.Error("Sscan <one item> expected error; got none")
581 t
.Errorf("Sscan wrong values: got %q expected \"abc\"", s1
)
583 n
, err
= Sscan("", &s1
, &s2
)
585 t
.Errorf("Sscan count error: expected 0: got %d", n
)
588 t
.Error("Sscan <empty> expected error; got none")
590 // Quoted empty string is OK.
591 n
, err
= Sscanf(`""`, "%q", &s1
)
593 t
.Errorf("Sscanf count error: expected 1: got %d", n
)
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")
603 _
, err
:= Fscan(r
, a
)
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
) {
613 _
, err
:= Sscanln("1 x\n", &a
)
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")
624 _
, err
:= Fscanln(r
, &a
, &b
)
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
638 func (ec
*eofCounter
) Read(b
[]byte) (n
int, err error
) {
639 n
, err
= ec
.reader
.Read(b
)
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}
651 n
, err
:= Fscanln(ec
, &a
)
653 t
.Error("unexpected error", err
)
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
)
664 t
.Error("expected error scanning empty string")
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
) {
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
)
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
)
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
)
698 t
.Errorf("Sscan expected EOF; got %q", err
)
702 var eofTests
= []struct {
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"))
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
)
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
)
754 t
.Errorf("expected αb; got %q", a
)
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()
769 chars
= append(chars
, c
)
774 *t
= TwoLines(string(chars
))
778 func TestMultiLine(t
*testing
.T
) {
779 input
:= "abc\ndef\n"
782 n
, err
:= Sscan(input
, &tscan
)
784 t
.Errorf("Sscan: expected 1 item; got %d", n
)
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
794 n
, err
= Sscanf(input
, "%s", &tscanf
)
796 t
.Errorf("Sscanf: expected 1 item; got %d", n
)
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
806 n
, err
= Sscanln(input
, &tscanln
)
808 t
.Errorf("Sscanln: expected 0 items; got %d: %q", n
, tscanln
)
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 {
823 func (s
*simpleReader
) Read(b
[]byte) (n
int, err error
) {
827 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
829 func TestLineByLineFscanf(t
*testing
.T
) {
830 r
:= &simpleReader
{strings
.NewReader("1\n2\n")}
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 {
853 func (r
*RecursiveInt
) Scan(state ScanState
, verb rune
) (err error
) {
854 _
, err
= Fscan(state
, &r
.i
)
858 next
:= new(RecursiveInt
)
859 _
, err
= Fscanf(state
, ".%v", next
)
861 if err
== io
.ErrUnexpectedEOF
{
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
) {
875 _
, err
= Fscan(b
, &r
.i
)
879 c
, _
, err
:= b
.ReadRune()
889 next
:= new(RecursiveInt
)
890 err
= scanInts(next
, b
)
897 func makeInts(n
int) []byte {
900 for i
:= 1; i
< n
; i
++ {
901 Fprintf(&buf
, ".%d", i
+1)
906 func TestScanInts(t
*testing
.T
) {
907 testScanInts(t
, scanInts
)
908 testScanInts(t
, func(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
914 // 800 is small enough to not overflow the stack when using gccgo on a
915 // platform that does not support split stack.
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
)
924 t
.Error("unexpected error", err
)
927 for ; r
!= nil; r
= r
.next
{
929 t
.Fatalf("bad scan: expected %d got %d", i
, r
.i
)
934 t
.Fatalf("bad scan count: expected %d got %d", intCount
, i
-1)
938 func BenchmarkScanInts(b
*testing
.B
) {
940 ints
:= makeInts(intCount
)
942 for i
:= b
.N
- 1; i
>= 0; i
-- {
943 buf
:= bytes
.NewBuffer(ints
)
950 func BenchmarkScanRecursiveInt(b
*testing
.B
) {
952 ints
:= makeInts(intCount
)
954 for i
:= b
.N
- 1; i
>= 0; i
-- {
955 buf
:= bytes
.NewBuffer(ints
)