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.
22 type ScanTest
struct {
28 type ScanfTest
struct {
35 type ScanfMultiTest
struct {
60 complex64Val complex64
61 complex128Val complex128
62 renamedBoolVal renamedBool
63 renamedIntVal renamedInt
64 renamedInt8Val renamedInt8
65 renamedInt16Val renamedInt16
66 renamedInt32Val renamedInt32
67 renamedInt64Val renamedInt64
68 renamedUintVal renamedUint
69 renamedUint8Val renamedUint8
70 renamedUint16Val renamedUint16
71 renamedUint32Val renamedUint32
72 renamedUint64Val renamedUint64
73 renamedUintptrVal renamedUintptr
74 renamedStringVal renamedString
75 renamedBytesVal renamedBytes
76 renamedFloat32Val renamedFloat32
77 renamedFloat64Val renamedFloat64
78 renamedComplex64Val renamedComplex64
79 renamedComplex128Val renamedComplex128
82 // Xs accepts any non-empty run of the verb character
85 func (x
*Xs
) Scan(state ScanState
, verb rune
) error
{
86 tok
, err
:= state
.Token(true, func(r rune
) bool { return r
== verb
})
91 if !regexp
.MustCompile("^" + string(verb
) + "+$").MatchString(s
) {
92 return errors
.New("syntax error for xs")
100 // IntString accepts an integer followed immediately by a string.
101 // It tests the embedding of a scan within a scan.
102 type IntString
struct {
107 func (s
*IntString
) Scan(state ScanState
, verb rune
) error
{
108 if _
, err
:= Fscan(state
, &s
.i
); err
!= nil {
112 tok
, err
:= state
.Token(true, nil)
120 var intStringVal IntString
122 var scanTests
= []ScanTest
{
124 {"T\n", &boolVal
, true}, // boolean test vals toggle to be sure they are written
125 {"F\n", &boolVal
, false}, // restored to zero value
126 {"21\n", &intVal
, 21},
128 {"000\n", &intVal
, 0},
129 {"0x10\n", &intVal
, 0x10},
130 {"-0x10\n", &intVal
, -0x10},
131 {"0377\n", &intVal
, 0377},
132 {"-0377\n", &intVal
, -0377},
133 {"0\n", &uintVal
, uint(0)},
134 {"000\n", &uintVal
, uint(0)},
135 {"0x10\n", &uintVal
, uint(0x10)},
136 {"0377\n", &uintVal
, uint(0377)},
137 {"22\n", &int8Val
, int8(22)},
138 {"23\n", &int16Val
, int16(23)},
139 {"24\n", &int32Val
, int32(24)},
140 {"25\n", &int64Val
, int64(25)},
141 {"127\n", &int8Val
, int8(127)},
142 {"-21\n", &intVal
, -21},
143 {"-22\n", &int8Val
, int8(-22)},
144 {"-23\n", &int16Val
, int16(-23)},
145 {"-24\n", &int32Val
, int32(-24)},
146 {"-25\n", &int64Val
, int64(-25)},
147 {"-128\n", &int8Val
, int8(-128)},
148 {"+21\n", &intVal
, +21},
149 {"+22\n", &int8Val
, int8(+22)},
150 {"+23\n", &int16Val
, int16(+23)},
151 {"+24\n", &int32Val
, int32(+24)},
152 {"+25\n", &int64Val
, int64(+25)},
153 {"+127\n", &int8Val
, int8(+127)},
154 {"26\n", &uintVal
, uint(26)},
155 {"27\n", &uint8Val
, uint8(27)},
156 {"28\n", &uint16Val
, uint16(28)},
157 {"29\n", &uint32Val
, uint32(29)},
158 {"30\n", &uint64Val
, uint64(30)},
159 {"255\n", &uint8Val
, uint8(255)},
160 {"32767\n", &int16Val
, int16(32767)},
161 {"2.3\n", &float64Val
, 2.3},
162 {"2.3e1\n", &float32Val
, float32(2.3e1
)},
163 {"2.3e2\n", &float64Val
, 2.3e2
},
164 {"2.3p2\n", &float64Val
, 2.3 * 4},
165 {"2.3p+2\n", &float64Val
, 2.3 * 4},
166 {"2.3p+66\n", &float64Val
, 2.3 * (1 << 32) * (1 << 32) * 4},
167 {"2.3p-66\n", &float64Val
, 2.3 / ((1 << 32) * (1 << 32) * 4)},
168 {"2.35\n", &stringVal
, "2.35"},
169 {"2345678\n", &bytesVal
, []byte("2345678")},
170 {"(3.4e1-2i)\n", &complex128Val
, 3.4e1
- 2i
},
171 {"-3.45e1-3i\n", &complex64Val
, complex64(-3.45e1
- 3i
)},
172 {"-.45e1-1e2i\n", &complex128Val
, complex128(-.45e1
- 100i
)},
173 {"hello\n", &stringVal
, "hello"},
175 // Carriage-return followed by newline. (We treat \r\n as \n always.)
176 {"hello\r\n", &stringVal
, "hello"},
177 {"27\r\n", &uint8Val
, uint8(27)},
180 {"true\n", &renamedBoolVal
, renamedBool(true)},
181 {"F\n", &renamedBoolVal
, renamedBool(false)},
182 {"101\n", &renamedIntVal
, renamedInt(101)},
183 {"102\n", &renamedIntVal
, renamedInt(102)},
184 {"103\n", &renamedUintVal
, renamedUint(103)},
185 {"104\n", &renamedUintVal
, renamedUint(104)},
186 {"105\n", &renamedInt8Val
, renamedInt8(105)},
187 {"106\n", &renamedInt16Val
, renamedInt16(106)},
188 {"107\n", &renamedInt32Val
, renamedInt32(107)},
189 {"108\n", &renamedInt64Val
, renamedInt64(108)},
190 {"109\n", &renamedUint8Val
, renamedUint8(109)},
191 {"110\n", &renamedUint16Val
, renamedUint16(110)},
192 {"111\n", &renamedUint32Val
, renamedUint32(111)},
193 {"112\n", &renamedUint64Val
, renamedUint64(112)},
194 {"113\n", &renamedUintptrVal
, renamedUintptr(113)},
195 {"114\n", &renamedStringVal
, renamedString("114")},
196 {"115\n", &renamedBytesVal
, renamedBytes([]byte("115"))},
199 {" vvv ", &xVal
, Xs("vvv")},
200 {" 1234hello", &intStringVal
, IntString
{1234, "hello"}},
203 {"2147483648\n", &int64Val
, int64(2147483648)}, // was: integer overflow
206 var scanfTests
= []ScanfTest
{
207 {"%v", "TRUE\n", &boolVal
, true},
208 {"%t", "false\n", &boolVal
, false},
209 {"%v", "-71\n", &intVal
, -71},
210 {"%v", "0377\n", &intVal
, 0377},
211 {"%v", "0x44\n", &intVal
, 0x44},
212 {"%d", "72\n", &intVal
, 72},
213 {"%c", "a\n", &runeVal
, 'a'},
214 {"%c", "\u5072\n", &runeVal
, '\u5072'},
215 {"%c", "\u1234\n", &runeVal
, '\u1234'},
216 {"%d", "73\n", &int8Val
, int8(73)},
217 {"%d", "+74\n", &int16Val
, int16(74)},
218 {"%d", "75\n", &int32Val
, int32(75)},
219 {"%d", "76\n", &int64Val
, int64(76)},
220 {"%b", "1001001\n", &intVal
, 73},
221 {"%o", "075\n", &intVal
, 075},
222 {"%x", "a75\n", &intVal
, 0xa75},
223 {"%v", "71\n", &uintVal
, uint(71)},
224 {"%d", "72\n", &uintVal
, uint(72)},
225 {"%d", "73\n", &uint8Val
, uint8(73)},
226 {"%d", "74\n", &uint16Val
, uint16(74)},
227 {"%d", "75\n", &uint32Val
, uint32(75)},
228 {"%d", "76\n", &uint64Val
, uint64(76)},
229 {"%b", "1001001\n", &uintVal
, uint(73)},
230 {"%o", "075\n", &uintVal
, uint(075)},
231 {"%x", "a75\n", &uintVal
, uint(0xa75)},
232 {"%x", "A75\n", &uintVal
, uint(0xa75)},
233 {"%U", "U+1234\n", &intVal
, int(0x1234)},
234 {"%U", "U+4567\n", &uintVal
, uint(0x4567)},
237 {"%s", "using-%s\n", &stringVal
, "using-%s"},
238 {"%x", "7573696e672d2578\n", &stringVal
, "using-%x"},
239 {"%X", "7573696E672D2558\n", &stringVal
, "using-%X"},
240 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal
, "quoted\twith\\doubles"},
241 {"%q", "`quoted with backs`\n", &stringVal
, "quoted with backs"},
244 {"%s", "bytes-%s\n", &bytesVal
, []byte("bytes-%s")},
245 {"%x", "62797465732d2578\n", &bytesVal
, []byte("bytes-%x")},
246 {"%X", "62797465732D2558\n", &bytesVal
, []byte("bytes-%X")},
247 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal
, []byte("bytes\rwith\vdoubles")},
248 {"%q", "`bytes with backs`\n", &bytesVal
, []byte("bytes with backs")},
251 {"%v\n", "true\n", &renamedBoolVal
, renamedBool(true)},
252 {"%t\n", "F\n", &renamedBoolVal
, renamedBool(false)},
253 {"%v", "101\n", &renamedIntVal
, renamedInt(101)},
254 {"%c", "\u0101\n", &renamedIntVal
, renamedInt('\u0101')},
255 {"%o", "0146\n", &renamedIntVal
, renamedInt(102)},
256 {"%v", "103\n", &renamedUintVal
, renamedUint(103)},
257 {"%d", "104\n", &renamedUintVal
, renamedUint(104)},
258 {"%d", "105\n", &renamedInt8Val
, renamedInt8(105)},
259 {"%d", "106\n", &renamedInt16Val
, renamedInt16(106)},
260 {"%d", "107\n", &renamedInt32Val
, renamedInt32(107)},
261 {"%d", "108\n", &renamedInt64Val
, renamedInt64(108)},
262 {"%x", "6D\n", &renamedUint8Val
, renamedUint8(109)},
263 {"%o", "0156\n", &renamedUint16Val
, renamedUint16(110)},
264 {"%d", "111\n", &renamedUint32Val
, renamedUint32(111)},
265 {"%d", "112\n", &renamedUint64Val
, renamedUint64(112)},
266 {"%d", "113\n", &renamedUintptrVal
, renamedUintptr(113)},
267 {"%s", "114\n", &renamedStringVal
, renamedString("114")},
268 {"%q", "\"1155\"\n", &renamedBytesVal
, renamedBytes([]byte("1155"))},
269 {"%g", "116e1\n", &renamedFloat32Val
, renamedFloat32(116e1
)},
270 {"%g", "-11.7e+1", &renamedFloat64Val
, renamedFloat64(-11.7e+1)},
271 {"%g", "11+6e1i\n", &renamedComplex64Val
, renamedComplex64(11 + 6e1i
)},
272 {"%g", "-11.+7e+1i", &renamedComplex128Val
, renamedComplex128(-11. + 7e+1i
)},
274 // Interesting formats
275 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal
, 118},
276 {"%% %%:%d", "% %:119\n", &intVal
, 119},
277 {"%d%%", "42%", &intVal
, 42}, // %% at end of string.
280 {"%x", "FFFFFFFF\n", &uint32Val
, uint32(0xFFFFFFFF)},
283 {"%s", " sss ", &xVal
, Xs("sss")},
284 {"%2s", "sssss", &xVal
, Xs("ss")},
287 {"%d\n", "27\n", &intVal
, 27}, // ok
288 {"%d\n", "28 \n", &intVal
, 28}, // was: "unexpected newline"
289 {"%v", "0", &intVal
, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
290 {"%v", "0", &uintVal
, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
291 {"%c", " ", &uintVal
, uint(' ')}, // %c must accept a blank.
292 {"%c", "\t", &uintVal
, uint('\t')}, // %c must accept any space.
293 {"%c", "\n", &uintVal
, uint('\n')}, // %c must accept any space.
296 {"%d", "27", &intVal
, 27},
297 {"%d", "27 ", &intVal
, 27},
298 {"%d", " 27", &intVal
, 27},
299 {"%d", " 27 ", &intVal
, 27},
301 {"X%d", "X27", &intVal
, 27},
302 {"X%d", "X27 ", &intVal
, 27},
303 {"X%d", "X 27", &intVal
, 27},
304 {"X%d", "X 27 ", &intVal
, 27},
306 {"X %d", "X27", &intVal
, nil}, // expected space in input to match format
307 {"X %d", "X27 ", &intVal
, nil}, // expected space in input to match format
308 {"X %d", "X 27", &intVal
, 27},
309 {"X %d", "X 27 ", &intVal
, 27},
311 {"%dX", "27X", &intVal
, 27},
312 {"%dX", "27 X", &intVal
, nil}, // input does not match format
313 {"%dX", " 27X", &intVal
, 27},
314 {"%dX", " 27 X", &intVal
, nil}, // input does not match format
316 {"%d X", "27X", &intVal
, nil}, // expected space in input to match format
317 {"%d X", "27 X", &intVal
, 27},
318 {"%d X", " 27X", &intVal
, nil}, // expected space in input to match format
319 {"%d X", " 27 X", &intVal
, 27},
321 {"X %d X", "X27X", &intVal
, nil}, // expected space in input to match format
322 {"X %d X", "X27 X", &intVal
, nil}, // expected space in input to match format
323 {"X %d X", "X 27X", &intVal
, nil}, // expected space in input to match format
324 {"X %d X", "X 27 X", &intVal
, 27},
326 {"X %s X", "X27X", &stringVal
, nil}, // expected space in input to match format
327 {"X %s X", "X27 X", &stringVal
, nil}, // expected space in input to match format
328 {"X %s X", "X 27X", &stringVal
, nil}, // unexpected EOF
329 {"X %s X", "X 27 X", &stringVal
, "27"},
331 {"X%sX", "X27X", &stringVal
, nil}, // unexpected EOF
332 {"X%sX", "X27 X", &stringVal
, nil}, // input does not match format
333 {"X%sX", "X 27X", &stringVal
, nil}, // unexpected EOF
334 {"X%sX", "X 27 X", &stringVal
, nil}, // input does not match format
336 {"X%s", "X27", &stringVal
, "27"},
337 {"X%s", "X27 ", &stringVal
, "27"},
338 {"X%s", "X 27", &stringVal
, "27"},
339 {"X%s", "X 27 ", &stringVal
, "27"},
341 {"X%dX", "X27X", &intVal
, 27},
342 {"X%dX", "X27 X", &intVal
, nil}, // input does not match format
343 {"X%dX", "X 27X", &intVal
, 27},
344 {"X%dX", "X 27 X", &intVal
, nil}, // input does not match format
346 {"X%dX", "X27X", &intVal
, 27},
347 {"X%dX", "X27X ", &intVal
, 27},
348 {"X%dX", " X27X", &intVal
, nil}, // input does not match format
349 {"X%dX", " X27X ", &intVal
, nil}, // input does not match format
351 {"X%dX\n", "X27X", &intVal
, 27},
352 {"X%dX \n", "X27X ", &intVal
, 27},
353 {"X%dX\n", "X27X\n", &intVal
, 27},
354 {"X%dX\n", "X27X \n", &intVal
, 27},
356 {"X%dX \n", "X27X", &intVal
, 27},
357 {"X%dX \n", "X27X ", &intVal
, 27},
358 {"X%dX \n", "X27X\n", &intVal
, 27},
359 {"X%dX \n", "X27X \n", &intVal
, 27},
361 {"X%c", "X\n", &runeVal
, '\n'},
362 {"X%c", "X \n", &runeVal
, ' '},
363 {"X %c", "X!", &runeVal
, nil}, // expected space in input to match format
364 {"X %c", "X\n", &runeVal
, nil}, // newline in input does not match format
365 {"X %c", "X !", &runeVal
, '!'},
366 {"X %c", "X \n", &runeVal
, '\n'},
368 {" X%dX", "X27X", &intVal
, nil}, // expected space in input to match format
369 {" X%dX", "X27X ", &intVal
, nil}, // expected space in input to match format
370 {" X%dX", " X27X", &intVal
, 27},
371 {" X%dX", " X27X ", &intVal
, 27},
373 {"X%dX ", "X27X", &intVal
, 27},
374 {"X%dX ", "X27X ", &intVal
, 27},
375 {"X%dX ", " X27X", &intVal
, nil}, // input does not match format
376 {"X%dX ", " X27X ", &intVal
, nil}, // input does not match format
378 {" X%dX ", "X27X", &intVal
, nil}, // expected space in input to match format
379 {" X%dX ", "X27X ", &intVal
, nil}, // expected space in input to match format
380 {" X%dX ", " X27X", &intVal
, 27},
381 {" X%dX ", " X27X ", &intVal
, 27},
383 {"%d\nX", "27\nX", &intVal
, 27},
384 {"%dX\n X", "27X\n X", &intVal
, 27},
387 var overflowTests
= []ScanTest
{
388 {"128", &int8Val
, 0},
389 {"32768", &int16Val
, 0},
390 {"-129", &int8Val
, 0},
391 {"-32769", &int16Val
, 0},
392 {"256", &uint8Val
, 0},
393 {"65536", &uint16Val
, 0},
394 {"1e100", &float32Val
, 0},
395 {"1e500", &float64Val
, 0},
396 {"(1e100+0i)", &complex64Val
, 0},
397 {"(1+1e100i)", &complex64Val
, 0},
398 {"(1-1e500i)", &complex128Val
, 0},
410 var multiTests
= []ScanfMultiTest
{
411 {"", "", []interface{}{}, []interface{}{}, ""},
412 {"%d", "23", args(&i
), args(23), ""},
413 {"%2s%3s", "22333", args(&s
, &t
), args("22", "333"), ""},
414 {"%2d%3d", "44555", args(&i
, &j
), args(44, 555), ""},
415 {"%2d.%3d", "66.777", args(&i
, &j
), args(66, 777), ""},
416 {"%d, %d", "23, 18", args(&i
, &j
), args(23, 18), ""},
417 {"%3d22%3d", "33322333", args(&i
, &j
), args(333, 333), ""},
418 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c
, &f
), args((3 + 2i
), 2.5), ""},
419 {"%d%s", "123abc", args(&i
, &s
), args(123, "abc"), ""},
420 {"%c%c%c", "2\u50c2X", args(&r1
, &r2
, &r3
), args('2', '\u50c2', 'X'), ""},
421 {"%5s%d", " 1234567 ", args(&s
, &i
), args("12345", 67), ""},
422 {"%5s%d", " 12 34 567 ", args(&s
, &i
), args("12", 34), ""},
425 {"%e%f", "eefffff", args(&x
, &y
), args(Xs("ee"), Xs("fffff")), ""},
426 {"%4v%s", "12abcd", args(&z
, &s
), args(IntString
{12, "ab"}, "cd"), ""},
429 {"%t", "23 18", args(&i
), nil, "bad verb"},
430 {"%d %d %d", "23 18", args(&i
, &j
), args(23, 18), "too few operands"},
431 {"%d %d", "23 18 27", args(&i
, &j
, &k
), args(23, 18), "too many operands"},
432 {"%c", "\u0100", args(&int8Val
), nil, "overflow"},
433 {"X%d", "10X", args(&intVal
), nil, "input does not match format"},
434 {"%d%", "42%", args(&intVal
), args(42), "missing verb: % at end of format string"},
435 {"%d% ", "42%", args(&intVal
), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct.
437 // Bad UTF-8: should see every byte.
438 {"%c%c%c", "\xc2X\xc2", args(&r1
, &r2
, &r3
), args(utf8
.RuneError
, 'X', utf8
.RuneError
), ""},
441 {"%v%v", "FALSE23", args(&truth
, &i
), args(false, 23), ""},
444 var readers
= []struct {
446 f
func(string) io
.Reader
448 {"StringReader", func(s
string) io
.Reader
{
449 return strings
.NewReader(s
)
451 {"ReaderOnly", func(s
string) io
.Reader
{
452 return struct{ io
.Reader
}{strings
.NewReader(s
)}
454 {"OneByteReader", func(s
string) io
.Reader
{
455 return iotest
.OneByteReader(strings
.NewReader(s
))
457 {"DataErrReader", func(s
string) io
.Reader
{
458 return iotest
.DataErrReader(strings
.NewReader(s
))
462 func testScan(t
*testing
.T
, f
func(string) io
.Reader
, scan
func(r io
.Reader
, a
...interface{}) (int, error
)) {
463 for _
, test
:= range scanTests
{
465 n
, err
:= scan(r
, test
.in
)
469 m
= Sprintf(" (%d fields ok)", n
)
471 t
.Errorf("got error scanning %q: %s%s", test
.text
, err
, m
)
475 t
.Errorf("count error on entry %q: got %d", test
.text
, n
)
478 // The incoming value may be a pointer
479 v
:= reflect
.ValueOf(test
.in
)
480 if p
:= v
; p
.Kind() == reflect
.Ptr
{
484 if !reflect
.DeepEqual(val
, test
.out
) {
485 t
.Errorf("scanning %q: expected %#v got %#v, type %T", test
.text
, test
.out
, val
, val
)
490 func TestScan(t
*testing
.T
) {
491 for _
, r
:= range readers
{
492 t
.Run(r
.name
, func(t
*testing
.T
) {
493 testScan(t
, r
.f
, Fscan
)
498 func TestScanln(t
*testing
.T
) {
499 for _
, r
:= range readers
{
500 t
.Run(r
.name
, func(t
*testing
.T
) {
501 testScan(t
, r
.f
, Fscanln
)
506 func TestScanf(t
*testing
.T
) {
507 for _
, test
:= range scanfTests
{
508 n
, err
:= Sscanf(test
.text
, test
.format
, test
.in
)
511 t
.Errorf("Sscanf(%q, %q): unexpected error: %v", test
.text
, test
.format
, err
)
516 t
.Errorf("Sscanf(%q, %q): unexpected success", test
.text
, test
.format
)
520 t
.Errorf("Sscanf(%q, %q): parsed %d field, want 1", test
.text
, test
.format
, n
)
523 // The incoming value may be a pointer
524 v
:= reflect
.ValueOf(test
.in
)
525 if p
:= v
; p
.Kind() == reflect
.Ptr
{
529 if !reflect
.DeepEqual(val
, test
.out
) {
530 t
.Errorf("Sscanf(%q, %q): parsed value %T(%#v), want %T(%#v)", test
.text
, test
.format
, val
, val
, test
.out
, test
.out
)
535 func TestScanOverflow(t
*testing
.T
) {
536 // different machines and different types report errors with different strings.
537 re
:= regexp
.MustCompile("overflow|too large|out of range|not representable")
538 for _
, test
:= range overflowTests
{
539 _
, err
:= Sscan(test
.text
, test
.in
)
541 t
.Errorf("expected overflow scanning %q", test
.text
)
544 if !re
.MatchString(err
.Error()) {
545 t
.Errorf("expected overflow error scanning %q: %s", test
.text
, err
)
550 func verifyNaN(str
string, t
*testing
.T
) {
554 text
:= str
+ " " + str
+ " " + str
555 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
557 t
.Errorf("got error scanning %q: %s", text
, err
)
560 t
.Errorf("count error scanning %q: got %d", text
, n
)
562 if !math
.IsNaN(float64(f
)) ||
!math
.IsNaN(float64(f32
)) ||
!math
.IsNaN(f64
) {
563 t
.Errorf("didn't get NaNs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
567 func TestNaN(t
*testing
.T
) {
568 for _
, s
:= range []string{"nan", "NAN", "NaN"} {
573 func verifyInf(str
string, t
*testing
.T
) {
577 text
:= str
+ " " + str
+ " " + str
578 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
580 t
.Errorf("got error scanning %q: %s", text
, err
)
583 t
.Errorf("count error scanning %q: got %d", text
, n
)
589 if !math
.IsInf(float64(f
), sign
) ||
!math
.IsInf(float64(f32
), sign
) ||
!math
.IsInf(f64
, sign
) {
590 t
.Errorf("didn't get right Infs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
594 func TestInf(t
*testing
.T
) {
595 for _
, s
:= range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
600 func testScanfMulti(t
*testing
.T
, f
func(string) io
.Reader
) {
601 sliceType
:= reflect
.TypeOf(make([]interface{}, 1))
602 for _
, test
:= range multiTests
{
604 n
, err
:= Fscanf(r
, test
.format
, test
.in
...)
607 t
.Errorf("got error scanning (%q, %q): %q", test
.format
, test
.text
, err
)
608 } else if !strings
.Contains(err
.Error(), test
.err
) {
609 t
.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test
.format
, test
.text
, err
, test
.err
)
614 t
.Errorf("expected error %q error scanning (%q, %q)", test
.err
, test
.format
, test
.text
)
616 if n
!= len(test
.out
) {
617 t
.Errorf("count error on entry (%q, %q): expected %d got %d", test
.format
, test
.text
, len(test
.out
), n
)
620 // Convert the slice of pointers into a slice of values
621 resultVal
:= reflect
.MakeSlice(sliceType
, n
, n
)
622 for i
:= 0; i
< n
; i
++ {
623 v
:= reflect
.ValueOf(test
.in
[i
]).Elem()
624 resultVal
.Index(i
).Set(v
)
626 result
:= resultVal
.Interface()
627 if !reflect
.DeepEqual(result
, test
.out
) {
628 t
.Errorf("scanning (%q, %q): expected %#v got %#v", test
.format
, test
.text
, test
.out
, result
)
633 func TestScanfMulti(t
*testing
.T
) {
634 for _
, r
:= range readers
{
635 t
.Run(r
.name
, func(t
*testing
.T
) {
636 testScanfMulti(t
, r
.f
)
641 func TestScanMultiple(t
*testing
.T
) {
644 n
, err
:= Sscan("123abc", &a
, &s
)
646 t
.Errorf("Sscan count error: expected 2: got %d", n
)
649 t
.Errorf("Sscan expected no error; got %s", err
)
651 if a
!= 123 || s
!= "abc" {
652 t
.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a
, s
)
654 n
, err
= Sscan("asdf", &s
, &a
)
656 t
.Errorf("Sscan count error: expected 1: got %d", n
)
659 t
.Errorf("Sscan expected error; got none: %s", err
)
662 t
.Errorf("Sscan wrong values: got %q expected \"asdf\"", s
)
666 // Empty strings are not valid input when scanning a string.
667 func TestScanEmpty(t
*testing
.T
) {
669 n
, err
:= Sscan("abc", &s1
, &s2
)
671 t
.Errorf("Sscan count error: expected 1: got %d", n
)
674 t
.Error("Sscan <one item> expected error; got none")
677 t
.Errorf("Sscan wrong values: got %q expected \"abc\"", s1
)
679 n
, err
= Sscan("", &s1
, &s2
)
681 t
.Errorf("Sscan count error: expected 0: got %d", n
)
684 t
.Error("Sscan <empty> expected error; got none")
686 // Quoted empty string is OK.
687 n
, err
= Sscanf(`""`, "%q", &s1
)
689 t
.Errorf("Sscanf count error: expected 1: got %d", n
)
692 t
.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err
)
696 func TestScanNotPointer(t
*testing
.T
) {
697 r
:= strings
.NewReader("1")
699 _
, err
:= Fscan(r
, a
)
701 t
.Error("expected error scanning non-pointer")
702 } else if !strings
.Contains(err
.Error(), "pointer") {
703 t
.Errorf("expected pointer error scanning non-pointer, got: %s", err
)
707 func TestScanlnNoNewline(t
*testing
.T
) {
709 _
, err
:= Sscanln("1 x\n", &a
)
711 t
.Error("expected error scanning string missing newline")
712 } else if !strings
.Contains(err
.Error(), "newline") {
713 t
.Errorf("expected newline error scanning string missing newline, got: %s", err
)
717 func TestScanlnWithMiddleNewline(t
*testing
.T
) {
718 r
:= strings
.NewReader("123\n456\n")
720 _
, err
:= Fscanln(r
, &a
, &b
)
722 t
.Error("expected error scanning string with extra newline")
723 } else if !strings
.Contains(err
.Error(), "newline") {
724 t
.Errorf("expected newline error scanning string with extra newline, got: %s", err
)
728 // eofCounter is a special Reader that counts reads at end of file.
729 type eofCounter
struct {
730 reader
*strings
.Reader
734 func (ec
*eofCounter
) Read(b
[]byte) (n
int, err error
) {
735 n
, err
= ec
.reader
.Read(b
)
742 // TestEOF verifies that when we scan, we see at most EOF once per call to a
743 // Scan function, and then only when it's really an EOF.
744 func TestEOF(t
*testing
.T
) {
745 ec
:= &eofCounter
{strings
.NewReader("123\n"), 0}
747 n
, err
:= Fscanln(ec
, &a
)
749 t
.Error("unexpected error", err
)
752 t
.Error("expected to scan one item, got", n
)
754 if ec
.eofCount
!= 0 {
755 t
.Error("expected zero EOFs", ec
.eofCount
)
756 ec
.eofCount
= 0 // reset for next test
758 n
, err
= Fscanln(ec
, &a
)
760 t
.Error("expected error scanning empty string")
763 t
.Error("expected to scan zero items, got", n
)
765 if ec
.eofCount
!= 1 {
766 t
.Error("expected one EOF, got", ec
.eofCount
)
770 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
771 // This was a buglet: we used to get "expected integer".
772 func TestEOFAtEndOfInput(t
*testing
.T
) {
774 n
, err
:= Sscanf("23", "%d %d", &i
, &j
)
775 if n
!= 1 || i
!= 23 {
776 t
.Errorf("Sscanf expected one value of 23; got %d %d", n
, i
)
779 t
.Errorf("Sscanf expected EOF; got %q", err
)
781 n
, err
= Sscan("234", &i
, &j
)
782 if n
!= 1 || i
!= 234 {
783 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
786 t
.Errorf("Sscan expected EOF; got %q", err
)
788 // Trailing space is tougher.
789 n
, err
= Sscan("234 ", &i
, &j
)
790 if n
!= 1 || i
!= 234 {
791 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
794 t
.Errorf("Sscan expected EOF; got %q", err
)
798 var eofTests
= []struct {
811 {"%v", &complex64Val
},
812 {"%v", &renamedStringVal
},
813 {"%v", &renamedBytesVal
},
814 {"%v", &renamedIntVal
},
815 {"%v", &renamedUintVal
},
816 {"%v", &renamedBoolVal
},
817 {"%v", &renamedFloat32Val
},
818 {"%v", &renamedComplex64Val
},
821 func TestEOFAllTypes(t
*testing
.T
) {
822 for i
, test
:= range eofTests
{
823 if _
, err
:= Sscanf("", test
.format
, test
.v
); err
!= io
.EOF
{
824 t
.Errorf("#%d: %s %T not eof on empty string: %s", i
, test
.format
, test
.v
, err
)
826 if _
, err
:= Sscanf(" ", test
.format
, test
.v
); err
!= io
.EOF
{
827 t
.Errorf("#%d: %s %T not eof on trailing blanks: %s", i
, test
.format
, test
.v
, err
)
832 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
833 // calls to Fscan do not lose runes.
834 func TestUnreadRuneWithBufio(t
*testing
.T
) {
835 r
:= bufio
.NewReader(strings
.NewReader("123αb"))
838 n
, err
:= Fscanf(r
, "%d", &i
)
839 if n
!= 1 || err
!= nil {
840 t
.Errorf("reading int expected one item, no errors; got %d %q", n
, err
)
843 t
.Errorf("expected 123; got %d", i
)
845 n
, err
= Fscanf(r
, "%s", &a
)
846 if n
!= 1 || err
!= nil {
847 t
.Errorf("reading string expected one item, no errors; got %d %q", n
, err
)
850 t
.Errorf("expected αb; got %q", a
)
856 // Scan attempts to read two lines into the object. Scanln should prevent this
857 // because it stops at newline; Scan and Scanf should be fine.
858 func (t
*TwoLines
) Scan(state ScanState
, verb rune
) error
{
859 chars
:= make([]rune
, 0, 100)
860 for nlCount
:= 0; nlCount
< 2; {
861 c
, _
, err
:= state
.ReadRune()
865 chars
= append(chars
, c
)
870 *t
= TwoLines(string(chars
))
874 func TestMultiLine(t
*testing
.T
) {
875 input
:= "abc\ndef\n"
878 n
, err
:= Sscan(input
, &tscan
)
880 t
.Errorf("Sscan: expected 1 item; got %d", n
)
883 t
.Errorf("Sscan: expected no error; got %s", err
)
885 if string(tscan
) != input
{
886 t
.Errorf("Sscan: expected %q; got %q", input
, tscan
)
888 // Sscanf should work
890 n
, err
= Sscanf(input
, "%s", &tscanf
)
892 t
.Errorf("Sscanf: expected 1 item; got %d", n
)
895 t
.Errorf("Sscanf: expected no error; got %s", err
)
897 if string(tscanf
) != input
{
898 t
.Errorf("Sscanf: expected %q; got %q", input
, tscanf
)
900 // Sscanln should not work
902 n
, err
= Sscanln(input
, &tscanln
)
904 t
.Errorf("Sscanln: expected 0 items; got %d: %q", n
, tscanln
)
907 t
.Error("Sscanln: expected error; got none")
908 } else if err
!= io
.ErrUnexpectedEOF
{
909 t
.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err
)
913 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
915 func TestLineByLineFscanf(t
*testing
.T
) {
916 r
:= struct{ io
.Reader
}{strings
.NewReader("1\n2\n")}
918 n
, err
:= Fscanf(r
, "%v\n", &i
)
919 if n
!= 1 || err
!= nil {
920 t
.Fatalf("first read: %d %q", n
, err
)
922 n
, err
= Fscanf(r
, "%v\n", &j
)
923 if n
!= 1 || err
!= nil {
924 t
.Fatalf("second read: %d %q", n
, err
)
926 if i
!= 1 || j
!= 2 {
927 t
.Errorf("wrong values; wanted 1 2 got %d %d", i
, j
)
931 // TestScanStateCount verifies the correct byte count is returned. Issue 8512.
933 // runeScanner implements the Scanner interface for TestScanStateCount.
934 type runeScanner
struct {
939 func (rs
*runeScanner
) Scan(state ScanState
, verb rune
) error
{
940 r
, size
, err
:= state
.ReadRune()
946 func TestScanStateCount(t
*testing
.T
) {
947 var a
, b
, c runeScanner
948 n
, err
:= Sscanf("12âž‚", "%c%c%c", &a
, &b
, &c
)
953 t
.Fatalf("expected 3 items consumed, got %d", n
)
955 if a
.rune
!= '1' || b
.rune
!= '2' || c
.rune
!= 'âž‚' {
956 t
.Errorf("bad scan rune: %q %q %q should be '1' '2' 'âž‚'", a
.rune
, b
.rune
, c
.rune
)
958 if a
.size
!= 1 || b
.size
!= 1 || c
.size
!= 3 {
959 t
.Errorf("bad scan size: %q %q %q should be 1 1 3", a
.size
, b
.size
, c
.size
)
963 // RecursiveInt accepts a string matching %d.%d.%d....
964 // and parses it into a linked list.
965 // It allows us to benchmark recursive descent style scanners.
966 type RecursiveInt
struct {
971 func (r
*RecursiveInt
) Scan(state ScanState
, verb rune
) (err error
) {
972 _
, err
= Fscan(state
, &r
.i
)
976 next
:= new(RecursiveInt
)
977 _
, err
= Fscanf(state
, ".%v", next
)
979 if err
== io
.ErrUnexpectedEOF
{
988 // scanInts performs the same scanning task as RecursiveInt.Scan
989 // but without recurring through scanner, so we can compare
990 // performance more directly.
991 func scanInts(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
993 _
, err
= Fscan(b
, &r
.i
)
997 c
, _
, err
:= b
.ReadRune()
1007 next
:= new(RecursiveInt
)
1008 err
= scanInts(next
, b
)
1015 func makeInts(n
int) []byte {
1016 var buf bytes
.Buffer
1018 for i
:= 1; i
< n
; i
++ {
1019 Fprintf(&buf
, ".%d", i
+1)
1024 func TestScanInts(t
*testing
.T
) {
1025 testScanInts(t
, scanInts
)
1026 testScanInts(t
, func(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
1027 _
, err
= Fscan(b
, r
)
1032 // 800 is small enough to not overflow the stack when using gccgo on a
1033 // platform that does not support split stack.
1034 const intCount
= 800
1036 func testScanInts(t
*testing
.T
, scan
func(*RecursiveInt
, *bytes
.Buffer
) error
) {
1037 r
:= new(RecursiveInt
)
1038 ints
:= makeInts(intCount
)
1039 buf
:= bytes
.NewBuffer(ints
)
1042 t
.Error("unexpected error", err
)
1045 for ; r
!= nil; r
= r
.next
{
1047 t
.Fatalf("bad scan: expected %d got %d", i
, r
.i
)
1051 if i
-1 != intCount
{
1052 t
.Fatalf("bad scan count: expected %d got %d", intCount
, i
-1)
1056 func BenchmarkScanInts(b
*testing
.B
) {
1058 ints
:= makeInts(intCount
)
1060 for i
:= b
.N
- 1; i
>= 0; i
-- {
1061 buf
:= bytes
.NewBuffer(ints
)
1068 func BenchmarkScanRecursiveInt(b
*testing
.B
) {
1070 ints
:= makeInts(intCount
)
1072 for i
:= b
.N
- 1; i
>= 0; i
-- {
1073 buf
:= bytes
.NewBuffer(ints
)
1080 func BenchmarkScanRecursiveIntReaderWrapper(b
*testing
.B
) {
1082 ints
:= makeInts(intCount
)
1084 for i
:= b
.N
- 1; i
>= 0; i
-- {
1085 buf
:= struct{ io
.Reader
}{strings
.NewReader(string(ints
))}
1093 // %x on bytes couldn't handle non-space bytes terminating the scan.
1094 func TestHexBytes(t
*testing
.T
) {
1096 n
, err
:= Sscanf("00010203", "%x", &a
)
1097 if n
!= 1 || err
!= nil {
1098 t
.Errorf("simple: got count, err = %d, %v; expected 1, nil", n
, err
)
1100 check
:= func(msg
string, x
[]byte) {
1102 t
.Errorf("%s: bad length %d", msg
, len(x
))
1104 for i
, b
:= range x
{
1106 t
.Errorf("%s: bad x[%d] = %x", msg
, i
, x
[i
])
1113 n
, err
= Sscanf("00010203 00010203", "%x %x", &a
, &b
)
1114 if n
!= 2 || err
!= nil {
1115 t
.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1117 check("simple pair a", a
)
1118 check("simple pair b", b
)
1122 n
, err
= Sscanf("00010203:", "%x", &a
)
1123 if n
!= 1 || err
!= nil {
1124 t
.Errorf("colon: got count, err = %d, %v; expected 1, nil", n
, err
)
1129 n
, err
= Sscanf("00010203:00010203", "%x:%x", &a
, &b
)
1130 if n
!= 2 || err
!= nil {
1131 t
.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1133 check("colon pair a", a
)
1134 check("colon pair b", b
)
1138 // This one fails because there is a hex byte after the data,
1139 // that is, an odd number of hex input bytes.
1140 n
, err
= Sscanf("000102034:", "%x", &a
)
1141 if n
!= 0 || err
== nil {
1142 t
.Errorf("odd count: got count, err = %d, %v; expected 0, error", n
, err
)
1146 func TestScanNewlinesAreSpaces(t
*testing
.T
) {
1148 var tests
= []struct {
1153 {"newlines", "1\n2\n", 2},
1154 {"no final newline", "1\n2", 2},
1155 {"newlines with spaces ", "1 \n 2 \n", 2},
1156 {"no final newline with spaces", "1 \n 2", 2},
1158 for _
, test
:= range tests
{
1159 n
, err
:= Sscan(test
.text
, &a
, &b
)
1160 if n
!= test
.count
{
1161 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1164 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1169 func TestScanlnNewlinesTerminate(t
*testing
.T
) {
1171 var tests
= []struct {
1177 {"one line one item", "1\n", 1, false},
1178 {"one line two items with spaces ", " 1 2 \n", 2, true},
1179 {"one line two items no newline", " 1 2", 2, true},
1180 {"two lines two items", "1\n2\n", 1, false},
1182 for _
, test
:= range tests
{
1183 n
, err
:= Sscanln(test
.text
, &a
, &b
)
1184 if n
!= test
.count
{
1185 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1187 if test
.ok
&& err
!= nil {
1188 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1190 if !test
.ok
&& err
== nil {
1191 t
.Errorf("%s: expected error; got none", test
.name
)
1196 func TestScanfNewlineMatchFormat(t
*testing
.T
) {
1198 var tests
= []struct {
1205 {"newline in both", "1\n2", "%d\n%d\n", 2, true},
1206 {"newline in input", "1\n2", "%d %d", 1, false},
1207 {"space-newline in input", "1 \n2", "%d %d", 1, false},
1208 {"newline in format", "1 2", "%d\n%d", 1, false},
1209 {"space-newline in format", "1 2", "%d \n%d", 1, false},
1210 {"space-newline in both", "1 \n2", "%d \n%d", 2, true},
1211 {"extra space in format", "1\n2", "%d\n %d", 2, true},
1212 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
1213 {"space vs newline 0000", "1\n2", "%d\n%d", 2, true},
1214 {"space vs newline 0001", "1\n2", "%d\n %d", 2, true},
1215 {"space vs newline 0010", "1\n2", "%d \n%d", 2, true},
1216 {"space vs newline 0011", "1\n2", "%d \n %d", 2, true},
1217 {"space vs newline 0100", "1\n 2", "%d\n%d", 2, true},
1218 {"space vs newline 0101", "1\n 2", "%d\n%d ", 2, true},
1219 {"space vs newline 0110", "1\n 2", "%d \n%d", 2, true},
1220 {"space vs newline 0111", "1\n 2", "%d \n %d", 2, true},
1221 {"space vs newline 1000", "1 \n2", "%d\n%d", 2, true},
1222 {"space vs newline 1001", "1 \n2", "%d\n %d", 2, true},
1223 {"space vs newline 1010", "1 \n2", "%d \n%d", 2, true},
1224 {"space vs newline 1011", "1 \n2", "%d \n %d", 2, true},
1225 {"space vs newline 1100", "1 \n 2", "%d\n%d", 2, true},
1226 {"space vs newline 1101", "1 \n 2", "%d\n %d", 2, true},
1227 {"space vs newline 1110", "1 \n 2", "%d \n%d", 2, true},
1228 {"space vs newline 1111", "1 \n 2", "%d \n %d", 2, true},
1229 {"space vs newline no-percent 0000", "1\n2", "1\n2", 0, true},
1230 {"space vs newline no-percent 0001", "1\n2", "1\n 2", 0, true},
1231 {"space vs newline no-percent 0010", "1\n2", "1 \n2", 0, true},
1232 {"space vs newline no-percent 0011", "1\n2", "1 \n 2", 0, true},
1233 {"space vs newline no-percent 0100", "1\n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1234 {"space vs newline no-percent 0101", "1\n 2", "1\n2 ", 0, false}, // fails: space after nl in input but not pattern
1235 {"space vs newline no-percent 0110", "1\n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1236 {"space vs newline no-percent 0111", "1\n 2", "1 \n 2", 0, true},
1237 {"space vs newline no-percent 1000", "1 \n2", "1\n2", 0, true},
1238 {"space vs newline no-percent 1001", "1 \n2", "1\n 2", 0, true},
1239 {"space vs newline no-percent 1010", "1 \n2", "1 \n2", 0, true},
1240 {"space vs newline no-percent 1011", "1 \n2", "1 \n 2", 0, true},
1241 {"space vs newline no-percent 1100", "1 \n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1242 {"space vs newline no-percent 1101", "1 \n 2", "1\n 2", 0, true},
1243 {"space vs newline no-percent 1110", "1 \n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1244 {"space vs newline no-percent 1111", "1 \n 2", "1 \n 2", 0, true},
1246 for _
, test
:= range tests
{
1249 if strings
.Contains(test
.format
, "%") {
1250 n
, err
= Sscanf(test
.text
, test
.format
, &a
, &b
)
1252 n
, err
= Sscanf(test
.text
, test
.format
)
1254 if n
!= test
.count
{
1255 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1257 if test
.ok
&& err
!= nil {
1258 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1260 if !test
.ok
&& err
== nil {
1261 t
.Errorf("%s: expected error; got none", test
.name
)
1266 // Test for issue 12090: Was unreading at EOF, double-scanning a byte.
1268 type hexBytes
[2]byte
1270 func (h
*hexBytes
) Scan(ss ScanState
, verb rune
) error
{
1272 _
, err
:= Fscanf(ss
, "%4x", &b
)
1274 panic(err
) // Really shouldn't happen.
1280 func TestHexByte(t
*testing
.T
) {
1282 n
, err
:= Sscanln("0123\n", &h
)
1287 t
.Fatalf("expected 1 item; scanned %d", n
)
1289 if h
[0] != 0x01 || h
[1] != 0x23 {
1290 t
.Fatalf("expected 0123 got %x", h
)