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},
127 {"2_1\n", &intVal
, 21},
129 {"000\n", &intVal
, 0},
130 {"0x10\n", &intVal
, 0x10},
131 {"0x_1_0\n", &intVal
, 0x10},
132 {"-0x10\n", &intVal
, -0x10},
133 {"0377\n", &intVal
, 0377},
134 {"0_3_7_7\n", &intVal
, 0377},
135 {"0o377\n", &intVal
, 0377},
136 {"0o_3_7_7\n", &intVal
, 0377},
137 {"-0377\n", &intVal
, -0377},
138 {"-0o377\n", &intVal
, -0377},
139 {"0\n", &uintVal
, uint(0)},
140 {"000\n", &uintVal
, uint(0)},
141 {"0x10\n", &uintVal
, uint(0x10)},
142 {"0377\n", &uintVal
, uint(0377)},
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 {"127\n", &int8Val
, int8(127)},
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 {"-128\n", &int8Val
, int8(-128)},
154 {"+21\n", &intVal
, +21},
155 {"+22\n", &int8Val
, int8(+22)},
156 {"+23\n", &int16Val
, int16(+23)},
157 {"+24\n", &int32Val
, int32(+24)},
158 {"+25\n", &int64Val
, int64(+25)},
159 {"+127\n", &int8Val
, int8(+127)},
160 {"26\n", &uintVal
, uint(26)},
161 {"27\n", &uint8Val
, uint8(27)},
162 {"28\n", &uint16Val
, uint16(28)},
163 {"29\n", &uint32Val
, uint32(29)},
164 {"30\n", &uint64Val
, uint64(30)},
165 {"255\n", &uint8Val
, uint8(255)},
166 {"32767\n", &int16Val
, int16(32767)},
167 {"2.3\n", &float64Val
, 2.3},
168 {"2.3e1\n", &float32Val
, float32(2.3e1
)},
169 {"2.3e2\n", &float64Val
, 2.3e2
},
170 {"2.3p2\n", &float64Val
, 2.3 * 4},
171 {"2.3p+2\n", &float64Val
, 2.3 * 4},
172 {"2.3p+66\n", &float64Val
, 2.3 * (1 << 66)},
173 {"2.3p-66\n", &float64Val
, 2.3 / (1 << 66)},
174 {"0x2.3p-66\n", &float64Val
, float64(0x23) / (1 << 70)},
175 {"2_3.4_5\n", &float64Val
, 23.45},
176 {"2.35\n", &stringVal
, "2.35"},
177 {"2345678\n", &bytesVal
, []byte("2345678")},
178 {"(3.4e1-2i)\n", &complex128Val
, 3.4e1
- 2i
},
179 {"-3.45e1-3i\n", &complex64Val
, complex64(-3.45e1
- 3i
)},
180 {"-.45e1-1e2i\n", &complex128Val
, complex128(-.45e1
- 100i
)},
181 {"-.4_5e1-1E2i\n", &complex128Val
, complex128(-.45e1
- 100i
)},
182 {"0x1.0p1+0x1.0P2i\n", &complex128Val
, complex128(2 + 4i
)},
183 {"-0x1p1-0x1p2i\n", &complex128Val
, complex128(-2 - 4i
)},
184 {"-0x1ep-1-0x1p2i\n", &complex128Val
, complex128(-15 - 4i
)},
185 {"-0x1_Ep-1-0x1p0_2i\n", &complex128Val
, complex128(-15 - 4i
)},
186 {"hello\n", &stringVal
, "hello"},
188 // Carriage-return followed by newline. (We treat \r\n as \n always.)
189 {"hello\r\n", &stringVal
, "hello"},
190 {"27\r\n", &uint8Val
, uint8(27)},
193 {"true\n", &renamedBoolVal
, renamedBool(true)},
194 {"F\n", &renamedBoolVal
, renamedBool(false)},
195 {"101\n", &renamedIntVal
, renamedInt(101)},
196 {"102\n", &renamedIntVal
, renamedInt(102)},
197 {"103\n", &renamedUintVal
, renamedUint(103)},
198 {"104\n", &renamedUintVal
, renamedUint(104)},
199 {"105\n", &renamedInt8Val
, renamedInt8(105)},
200 {"106\n", &renamedInt16Val
, renamedInt16(106)},
201 {"107\n", &renamedInt32Val
, renamedInt32(107)},
202 {"108\n", &renamedInt64Val
, renamedInt64(108)},
203 {"109\n", &renamedUint8Val
, renamedUint8(109)},
204 {"110\n", &renamedUint16Val
, renamedUint16(110)},
205 {"111\n", &renamedUint32Val
, renamedUint32(111)},
206 {"112\n", &renamedUint64Val
, renamedUint64(112)},
207 {"113\n", &renamedUintptrVal
, renamedUintptr(113)},
208 {"114\n", &renamedStringVal
, renamedString("114")},
209 {"115\n", &renamedBytesVal
, renamedBytes([]byte("115"))},
212 {" vvv ", &xVal
, Xs("vvv")},
213 {" 1234hello", &intStringVal
, IntString
{1234, "hello"}},
216 {"2147483648\n", &int64Val
, int64(2147483648)}, // was: integer overflow
219 var scanfTests
= []ScanfTest
{
220 {"%v", "TRUE\n", &boolVal
, true},
221 {"%t", "false\n", &boolVal
, false},
222 {"%v", "-71\n", &intVal
, -71},
223 {"%v", "-7_1\n", &intVal
, -71},
224 {"%v", "0b111\n", &intVal
, 7},
225 {"%v", "0b_1_1_1\n", &intVal
, 7},
226 {"%v", "0377\n", &intVal
, 0377},
227 {"%v", "0_3_7_7\n", &intVal
, 0377},
228 {"%v", "0o377\n", &intVal
, 0377},
229 {"%v", "0o_3_7_7\n", &intVal
, 0377},
230 {"%v", "0x44\n", &intVal
, 0x44},
231 {"%v", "0x_4_4\n", &intVal
, 0x44},
232 {"%d", "72\n", &intVal
, 72},
233 {"%c", "a\n", &runeVal
, 'a'},
234 {"%c", "\u5072\n", &runeVal
, '\u5072'},
235 {"%c", "\u1234\n", &runeVal
, '\u1234'},
236 {"%d", "73\n", &int8Val
, int8(73)},
237 {"%d", "+74\n", &int16Val
, int16(74)},
238 {"%d", "75\n", &int32Val
, int32(75)},
239 {"%d", "76\n", &int64Val
, int64(76)},
240 {"%b", "1001001\n", &intVal
, 73},
241 {"%o", "075\n", &intVal
, 075},
242 {"%x", "a75\n", &intVal
, 0xa75},
243 {"%v", "71\n", &uintVal
, uint(71)},
244 {"%d", "72\n", &uintVal
, uint(72)},
245 {"%d", "7_2\n", &uintVal
, uint(7)}, // only %v takes underscores
246 {"%d", "73\n", &uint8Val
, uint8(73)},
247 {"%d", "74\n", &uint16Val
, uint16(74)},
248 {"%d", "75\n", &uint32Val
, uint32(75)},
249 {"%d", "76\n", &uint64Val
, uint64(76)},
250 {"%b", "1001001\n", &uintVal
, uint(73)},
251 {"%b", "100_1001\n", &uintVal
, uint(4)},
252 {"%o", "075\n", &uintVal
, uint(075)},
253 {"%o", "07_5\n", &uintVal
, uint(07)}, // only %v takes underscores
254 {"%x", "a75\n", &uintVal
, uint(0xa75)},
255 {"%x", "A75\n", &uintVal
, uint(0xa75)},
256 {"%x", "A7_5\n", &uintVal
, uint(0xa7)}, // only %v takes underscores
257 {"%U", "U+1234\n", &intVal
, int(0x1234)},
258 {"%U", "U+4567\n", &uintVal
, uint(0x4567)},
260 {"%e", "2.3\n", &float64Val
, 2.3},
261 {"%E", "2.3e1\n", &float32Val
, float32(2.3e1
)},
262 {"%f", "2.3e2\n", &float64Val
, 2.3e2
},
263 {"%g", "2.3p2\n", &float64Val
, 2.3 * 4},
264 {"%G", "2.3p+2\n", &float64Val
, 2.3 * 4},
265 {"%v", "2.3p+66\n", &float64Val
, 2.3 * (1 << 66)},
266 {"%f", "2.3p-66\n", &float64Val
, 2.3 / (1 << 66)},
267 {"%G", "0x2.3p-66\n", &float64Val
, float64(0x23) / (1 << 70)},
268 {"%E", "2_3.4_5\n", &float64Val
, 23.45},
271 {"%s", "using-%s\n", &stringVal
, "using-%s"},
272 {"%x", "7573696e672d2578\n", &stringVal
, "using-%x"},
273 {"%X", "7573696E672D2558\n", &stringVal
, "using-%X"},
274 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal
, "quoted\twith\\doubles"},
275 {"%q", "`quoted with backs`\n", &stringVal
, "quoted with backs"},
278 {"%s", "bytes-%s\n", &bytesVal
, []byte("bytes-%s")},
279 {"%x", "62797465732d2578\n", &bytesVal
, []byte("bytes-%x")},
280 {"%X", "62797465732D2558\n", &bytesVal
, []byte("bytes-%X")},
281 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal
, []byte("bytes\rwith\vdoubles")},
282 {"%q", "`bytes with backs`\n", &bytesVal
, []byte("bytes with backs")},
285 {"%v\n", "true\n", &renamedBoolVal
, renamedBool(true)},
286 {"%t\n", "F\n", &renamedBoolVal
, renamedBool(false)},
287 {"%v", "101\n", &renamedIntVal
, renamedInt(101)},
288 {"%c", "\u0101\n", &renamedIntVal
, renamedInt('\u0101')},
289 {"%o", "0146\n", &renamedIntVal
, renamedInt(102)},
290 {"%v", "103\n", &renamedUintVal
, renamedUint(103)},
291 {"%d", "104\n", &renamedUintVal
, renamedUint(104)},
292 {"%d", "105\n", &renamedInt8Val
, renamedInt8(105)},
293 {"%d", "106\n", &renamedInt16Val
, renamedInt16(106)},
294 {"%d", "107\n", &renamedInt32Val
, renamedInt32(107)},
295 {"%d", "108\n", &renamedInt64Val
, renamedInt64(108)},
296 {"%x", "6D\n", &renamedUint8Val
, renamedUint8(109)},
297 {"%o", "0156\n", &renamedUint16Val
, renamedUint16(110)},
298 {"%d", "111\n", &renamedUint32Val
, renamedUint32(111)},
299 {"%d", "112\n", &renamedUint64Val
, renamedUint64(112)},
300 {"%d", "113\n", &renamedUintptrVal
, renamedUintptr(113)},
301 {"%s", "114\n", &renamedStringVal
, renamedString("114")},
302 {"%q", "\"1155\"\n", &renamedBytesVal
, renamedBytes([]byte("1155"))},
303 {"%g", "116e1\n", &renamedFloat32Val
, renamedFloat32(116e1
)},
304 {"%g", "-11.7e+1", &renamedFloat64Val
, renamedFloat64(-11.7e+1)},
305 {"%g", "11+6e1i\n", &renamedComplex64Val
, renamedComplex64(11 + 6e1i
)},
306 {"%g", "-11.+7e+1i", &renamedComplex128Val
, renamedComplex128(-11. + 7e+1i
)},
308 // Interesting formats
309 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal
, 118},
310 {"%% %%:%d", "% %:119\n", &intVal
, 119},
311 {"%d%%", "42%", &intVal
, 42}, // %% at end of string.
314 {"%x", "FFFFFFFF\n", &uint32Val
, uint32(0xFFFFFFFF)},
317 {"%s", " sss ", &xVal
, Xs("sss")},
318 {"%2s", "sssss", &xVal
, Xs("ss")},
321 {"%d\n", "27\n", &intVal
, 27}, // ok
322 {"%d\n", "28 \n", &intVal
, 28}, // was: "unexpected newline"
323 {"%v", "0", &intVal
, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
324 {"%v", "0", &uintVal
, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
325 {"%c", " ", &uintVal
, uint(' ')}, // %c must accept a blank.
326 {"%c", "\t", &uintVal
, uint('\t')}, // %c must accept any space.
327 {"%c", "\n", &uintVal
, uint('\n')}, // %c must accept any space.
328 {"%d%%", "23%\n", &uintVal
, uint(23)}, // %% matches literal %.
329 {"%%%d", "%23\n", &uintVal
, uint(23)}, // %% matches literal %.
332 {"%d", "27", &intVal
, 27},
333 {"%d", "27 ", &intVal
, 27},
334 {"%d", " 27", &intVal
, 27},
335 {"%d", " 27 ", &intVal
, 27},
337 {"X%d", "X27", &intVal
, 27},
338 {"X%d", "X27 ", &intVal
, 27},
339 {"X%d", "X 27", &intVal
, 27},
340 {"X%d", "X 27 ", &intVal
, 27},
342 {"X %d", "X27", &intVal
, nil}, // expected space in input to match format
343 {"X %d", "X27 ", &intVal
, nil}, // expected space in input to match format
344 {"X %d", "X 27", &intVal
, 27},
345 {"X %d", "X 27 ", &intVal
, 27},
347 {"%dX", "27X", &intVal
, 27},
348 {"%dX", "27 X", &intVal
, nil}, // input does not match format
349 {"%dX", " 27X", &intVal
, 27},
350 {"%dX", " 27 X", &intVal
, nil}, // input does not match format
352 {"%d X", "27X", &intVal
, nil}, // expected space in input to match format
353 {"%d X", "27 X", &intVal
, 27},
354 {"%d X", " 27X", &intVal
, nil}, // expected space in input to match format
355 {"%d X", " 27 X", &intVal
, 27},
357 {"X %d X", "X27X", &intVal
, nil}, // expected space in input to match format
358 {"X %d X", "X27 X", &intVal
, nil}, // expected space in input to match format
359 {"X %d X", "X 27X", &intVal
, nil}, // expected space in input to match format
360 {"X %d X", "X 27 X", &intVal
, 27},
362 {"X %s X", "X27X", &stringVal
, nil}, // expected space in input to match format
363 {"X %s X", "X27 X", &stringVal
, nil}, // expected space in input to match format
364 {"X %s X", "X 27X", &stringVal
, nil}, // unexpected EOF
365 {"X %s X", "X 27 X", &stringVal
, "27"},
367 {"X%sX", "X27X", &stringVal
, nil}, // unexpected EOF
368 {"X%sX", "X27 X", &stringVal
, nil}, // input does not match format
369 {"X%sX", "X 27X", &stringVal
, nil}, // unexpected EOF
370 {"X%sX", "X 27 X", &stringVal
, nil}, // input does not match format
372 {"X%s", "X27", &stringVal
, "27"},
373 {"X%s", "X27 ", &stringVal
, "27"},
374 {"X%s", "X 27", &stringVal
, "27"},
375 {"X%s", "X 27 ", &stringVal
, "27"},
377 {"X%dX", "X27X", &intVal
, 27},
378 {"X%dX", "X27 X", &intVal
, nil}, // input does not match format
379 {"X%dX", "X 27X", &intVal
, 27},
380 {"X%dX", "X 27 X", &intVal
, nil}, // input does not match format
382 {"X%dX", "X27X", &intVal
, 27},
383 {"X%dX", "X27X ", &intVal
, 27},
384 {"X%dX", " X27X", &intVal
, nil}, // input does not match format
385 {"X%dX", " X27X ", &intVal
, nil}, // input does not match format
387 {"X%dX\n", "X27X", &intVal
, 27},
388 {"X%dX \n", "X27X ", &intVal
, 27},
389 {"X%dX\n", "X27X\n", &intVal
, 27},
390 {"X%dX\n", "X27X \n", &intVal
, 27},
392 {"X%dX \n", "X27X", &intVal
, 27},
393 {"X%dX \n", "X27X ", &intVal
, 27},
394 {"X%dX \n", "X27X\n", &intVal
, 27},
395 {"X%dX \n", "X27X \n", &intVal
, 27},
397 {"X%c", "X\n", &runeVal
, '\n'},
398 {"X%c", "X \n", &runeVal
, ' '},
399 {"X %c", "X!", &runeVal
, nil}, // expected space in input to match format
400 {"X %c", "X\n", &runeVal
, nil}, // newline in input does not match format
401 {"X %c", "X !", &runeVal
, '!'},
402 {"X %c", "X \n", &runeVal
, '\n'},
404 {" X%dX", "X27X", &intVal
, nil}, // expected space in input to match format
405 {" X%dX", "X27X ", &intVal
, nil}, // expected space in input to match format
406 {" X%dX", " X27X", &intVal
, 27},
407 {" X%dX", " X27X ", &intVal
, 27},
409 {"X%dX ", "X27X", &intVal
, 27},
410 {"X%dX ", "X27X ", &intVal
, 27},
411 {"X%dX ", " X27X", &intVal
, nil}, // input does not match format
412 {"X%dX ", " X27X ", &intVal
, nil}, // input does not match format
414 {" X%dX ", "X27X", &intVal
, nil}, // expected space in input to match format
415 {" X%dX ", "X27X ", &intVal
, nil}, // expected space in input to match format
416 {" X%dX ", " X27X", &intVal
, 27},
417 {" X%dX ", " X27X ", &intVal
, 27},
419 {"%d\nX", "27\nX", &intVal
, 27},
420 {"%dX\n X", "27X\n X", &intVal
, 27},
423 var overflowTests
= []ScanTest
{
424 {"128", &int8Val
, 0},
425 {"32768", &int16Val
, 0},
426 {"-129", &int8Val
, 0},
427 {"-32769", &int16Val
, 0},
428 {"256", &uint8Val
, 0},
429 {"65536", &uint16Val
, 0},
430 {"1e100", &float32Val
, 0},
431 {"1e500", &float64Val
, 0},
432 {"(1e100+0i)", &complex64Val
, 0},
433 {"(1+1e100i)", &complex64Val
, 0},
434 {"(1-1e500i)", &complex128Val
, 0},
446 var multiTests
= []ScanfMultiTest
{
447 {"", "", []any
{}, []any
{}, ""},
448 {"%d", "23", args(&i
), args(23), ""},
449 {"%2s%3s", "22333", args(&s
, &t
), args("22", "333"), ""},
450 {"%2d%3d", "44555", args(&i
, &j
), args(44, 555), ""},
451 {"%2d.%3d", "66.777", args(&i
, &j
), args(66, 777), ""},
452 {"%d, %d", "23, 18", args(&i
, &j
), args(23, 18), ""},
453 {"%3d22%3d", "33322333", args(&i
, &j
), args(333, 333), ""},
454 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c
, &f
), args((3 + 2i
), 2.5), ""},
455 {"%d%s", "123abc", args(&i
, &s
), args(123, "abc"), ""},
456 {"%c%c%c", "2\u50c2X", args(&r1
, &r2
, &r3
), args('2', '\u50c2', 'X'), ""},
457 {"%5s%d", " 1234567 ", args(&s
, &i
), args("12345", 67), ""},
458 {"%5s%d", " 12 34 567 ", args(&s
, &i
), args("12", 34), ""},
461 {"%e%f", "eefffff", args(&x
, &y
), args(Xs("ee"), Xs("fffff")), ""},
462 {"%4v%s", "12abcd", args(&z
, &s
), args(IntString
{12, "ab"}, "cd"), ""},
465 {"%t", "23 18", args(&i
), nil, "bad verb"},
466 {"%d %d %d", "23 18", args(&i
, &j
), args(23, 18), "too few operands"},
467 {"%d %d", "23 18 27", args(&i
, &j
, &k
), args(23, 18), "too many operands"},
468 {"%c", "\u0100", args(&int8Val
), nil, "overflow"},
469 {"X%d", "10X", args(&intVal
), nil, "input does not match format"},
470 {"%d%", "42%", args(&intVal
), args(42), "missing verb: % at end of format string"},
471 {"%d% ", "42%", args(&intVal
), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct.
472 {"%%%d", "xxx 42", args(&intVal
), args(42), "missing literal %"},
473 {"%%%d", "x42", args(&intVal
), args(42), "missing literal %"},
474 {"%%%d", "42", args(&intVal
), args(42), "missing literal %"},
476 // Bad UTF-8: should see every byte.
477 {"%c%c%c", "\xc2X\xc2", args(&r1
, &r2
, &r3
), args(utf8
.RuneError
, 'X', utf8
.RuneError
), ""},
480 {"%v%v", "FALSE23", args(&truth
, &i
), args(false, 23), ""},
483 var readers
= []struct {
485 f
func(string) io
.Reader
487 {"StringReader", func(s
string) io
.Reader
{
488 return strings
.NewReader(s
)
490 {"ReaderOnly", func(s
string) io
.Reader
{
491 return struct{ io
.Reader
}{strings
.NewReader(s
)}
493 {"OneByteReader", func(s
string) io
.Reader
{
494 return iotest
.OneByteReader(strings
.NewReader(s
))
496 {"DataErrReader", func(s
string) io
.Reader
{
497 return iotest
.DataErrReader(strings
.NewReader(s
))
501 func testScan(t
*testing
.T
, f
func(string) io
.Reader
, scan
func(r io
.Reader
, a
...any
) (int, error
)) {
502 for _
, test
:= range scanTests
{
504 n
, err
:= scan(r
, test
.in
)
508 m
= Sprintf(" (%d fields ok)", n
)
510 t
.Errorf("got error scanning %q: %s%s", test
.text
, err
, m
)
514 t
.Errorf("count error on entry %q: got %d", test
.text
, n
)
517 // The incoming value may be a pointer
518 v
:= reflect
.ValueOf(test
.in
)
519 if p
:= v
; p
.Kind() == reflect
.Pointer
{
523 if !reflect
.DeepEqual(val
, test
.out
) {
524 t
.Errorf("scanning %q: expected %#v got %#v, type %T", test
.text
, test
.out
, val
, val
)
529 func TestScan(t
*testing
.T
) {
530 for _
, r
:= range readers
{
531 t
.Run(r
.name
, func(t
*testing
.T
) {
532 testScan(t
, r
.f
, Fscan
)
537 func TestScanln(t
*testing
.T
) {
538 for _
, r
:= range readers
{
539 t
.Run(r
.name
, func(t
*testing
.T
) {
540 testScan(t
, r
.f
, Fscanln
)
545 func TestScanf(t
*testing
.T
) {
546 for _
, test
:= range scanfTests
{
547 n
, err
:= Sscanf(test
.text
, test
.format
, test
.in
)
550 t
.Errorf("Sscanf(%q, %q): unexpected error: %v", test
.text
, test
.format
, err
)
555 t
.Errorf("Sscanf(%q, %q): unexpected success", test
.text
, test
.format
)
559 t
.Errorf("Sscanf(%q, %q): parsed %d field, want 1", test
.text
, test
.format
, n
)
562 // The incoming value may be a pointer
563 v
:= reflect
.ValueOf(test
.in
)
564 if p
:= v
; p
.Kind() == reflect
.Pointer
{
568 if !reflect
.DeepEqual(val
, test
.out
) {
569 t
.Errorf("Sscanf(%q, %q): parsed value %T(%#v), want %T(%#v)", test
.text
, test
.format
, val
, val
, test
.out
, test
.out
)
574 func TestScanOverflow(t
*testing
.T
) {
575 // different machines and different types report errors with different strings.
576 re
:= regexp
.MustCompile("overflow|too large|out of range|not representable")
577 for _
, test
:= range overflowTests
{
578 _
, err
:= Sscan(test
.text
, test
.in
)
580 t
.Errorf("expected overflow scanning %q", test
.text
)
583 if !re
.MatchString(err
.Error()) {
584 t
.Errorf("expected overflow error scanning %q: %s", test
.text
, err
)
589 func verifyNaN(str
string, t
*testing
.T
) {
593 text
:= str
+ " " + str
+ " " + str
594 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
596 t
.Errorf("got error scanning %q: %s", text
, err
)
599 t
.Errorf("count error scanning %q: got %d", text
, n
)
601 if !math
.IsNaN(float64(f
)) ||
!math
.IsNaN(float64(f32
)) ||
!math
.IsNaN(f64
) {
602 t
.Errorf("didn't get NaNs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
606 func TestNaN(t
*testing
.T
) {
607 for _
, s
:= range []string{"nan", "NAN", "NaN"} {
612 func verifyInf(str
string, t
*testing
.T
) {
616 text
:= str
+ " " + str
+ " " + str
617 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
619 t
.Errorf("got error scanning %q: %s", text
, err
)
622 t
.Errorf("count error scanning %q: got %d", text
, n
)
628 if !math
.IsInf(float64(f
), sign
) ||
!math
.IsInf(float64(f32
), sign
) ||
!math
.IsInf(f64
, sign
) {
629 t
.Errorf("didn't get right Infs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
633 func TestInf(t
*testing
.T
) {
634 for _
, s
:= range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
639 func testScanfMulti(t
*testing
.T
, f
func(string) io
.Reader
) {
640 sliceType
:= reflect
.TypeOf(make([]any
, 1))
641 for _
, test
:= range multiTests
{
643 n
, err
:= Fscanf(r
, test
.format
, test
.in
...)
646 t
.Errorf("got error scanning (%q, %q): %q", test
.format
, test
.text
, err
)
647 } else if !strings
.Contains(err
.Error(), test
.err
) {
648 t
.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test
.format
, test
.text
, err
, test
.err
)
653 t
.Errorf("expected error %q error scanning (%q, %q)", test
.err
, test
.format
, test
.text
)
655 if n
!= len(test
.out
) {
656 t
.Errorf("count error on entry (%q, %q): expected %d got %d", test
.format
, test
.text
, len(test
.out
), n
)
659 // Convert the slice of pointers into a slice of values
660 resultVal
:= reflect
.MakeSlice(sliceType
, n
, n
)
661 for i
:= 0; i
< n
; i
++ {
662 v
:= reflect
.ValueOf(test
.in
[i
]).Elem()
663 resultVal
.Index(i
).Set(v
)
665 result
:= resultVal
.Interface()
666 if !reflect
.DeepEqual(result
, test
.out
) {
667 t
.Errorf("scanning (%q, %q): expected %#v got %#v", test
.format
, test
.text
, test
.out
, result
)
672 func TestScanfMulti(t
*testing
.T
) {
673 for _
, r
:= range readers
{
674 t
.Run(r
.name
, func(t
*testing
.T
) {
675 testScanfMulti(t
, r
.f
)
680 func TestScanMultiple(t
*testing
.T
) {
683 n
, err
:= Sscan("123abc", &a
, &s
)
685 t
.Errorf("Sscan count error: expected 2: got %d", n
)
688 t
.Errorf("Sscan expected no error; got %s", err
)
690 if a
!= 123 || s
!= "abc" {
691 t
.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a
, s
)
693 n
, err
= Sscan("asdf", &s
, &a
)
695 t
.Errorf("Sscan count error: expected 1: got %d", n
)
698 t
.Errorf("Sscan expected error; got none: %s", err
)
701 t
.Errorf("Sscan wrong values: got %q expected \"asdf\"", s
)
705 // Empty strings are not valid input when scanning a string.
706 func TestScanEmpty(t
*testing
.T
) {
708 n
, err
:= Sscan("abc", &s1
, &s2
)
710 t
.Errorf("Sscan count error: expected 1: got %d", n
)
713 t
.Error("Sscan <one item> expected error; got none")
716 t
.Errorf("Sscan wrong values: got %q expected \"abc\"", s1
)
718 n
, err
= Sscan("", &s1
, &s2
)
720 t
.Errorf("Sscan count error: expected 0: got %d", n
)
723 t
.Error("Sscan <empty> expected error; got none")
725 // Quoted empty string is OK.
726 n
, err
= Sscanf(`""`, "%q", &s1
)
728 t
.Errorf("Sscanf count error: expected 1: got %d", n
)
731 t
.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err
)
735 func TestScanNotPointer(t
*testing
.T
) {
736 r
:= strings
.NewReader("1")
738 _
, err
:= Fscan(r
, a
)
740 t
.Error("expected error scanning non-pointer")
741 } else if !strings
.Contains(err
.Error(), "pointer") {
742 t
.Errorf("expected pointer error scanning non-pointer, got: %s", err
)
746 func TestScanlnNoNewline(t
*testing
.T
) {
748 _
, err
:= Sscanln("1 x\n", &a
)
750 t
.Error("expected error scanning string missing newline")
751 } else if !strings
.Contains(err
.Error(), "newline") {
752 t
.Errorf("expected newline error scanning string missing newline, got: %s", err
)
756 func TestScanlnWithMiddleNewline(t
*testing
.T
) {
757 r
:= strings
.NewReader("123\n456\n")
759 _
, err
:= Fscanln(r
, &a
, &b
)
761 t
.Error("expected error scanning string with extra newline")
762 } else if !strings
.Contains(err
.Error(), "newline") {
763 t
.Errorf("expected newline error scanning string with extra newline, got: %s", err
)
767 // eofCounter is a special Reader that counts reads at end of file.
768 type eofCounter
struct {
769 reader
*strings
.Reader
773 func (ec
*eofCounter
) Read(b
[]byte) (n
int, err error
) {
774 n
, err
= ec
.reader
.Read(b
)
781 // TestEOF verifies that when we scan, we see at most EOF once per call to a
782 // Scan function, and then only when it's really an EOF.
783 func TestEOF(t
*testing
.T
) {
784 ec
:= &eofCounter
{strings
.NewReader("123\n"), 0}
786 n
, err
:= Fscanln(ec
, &a
)
788 t
.Error("unexpected error", err
)
791 t
.Error("expected to scan one item, got", n
)
793 if ec
.eofCount
!= 0 {
794 t
.Error("expected zero EOFs", ec
.eofCount
)
795 ec
.eofCount
= 0 // reset for next test
797 n
, err
= Fscanln(ec
, &a
)
799 t
.Error("expected error scanning empty string")
802 t
.Error("expected to scan zero items, got", n
)
804 if ec
.eofCount
!= 1 {
805 t
.Error("expected one EOF, got", ec
.eofCount
)
809 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
810 // This was a buglet: we used to get "expected integer".
811 func TestEOFAtEndOfInput(t
*testing
.T
) {
813 n
, err
:= Sscanf("23", "%d %d", &i
, &j
)
814 if n
!= 1 || i
!= 23 {
815 t
.Errorf("Sscanf expected one value of 23; got %d %d", n
, i
)
818 t
.Errorf("Sscanf expected EOF; got %q", err
)
820 n
, err
= Sscan("234", &i
, &j
)
821 if n
!= 1 || i
!= 234 {
822 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
825 t
.Errorf("Sscan expected EOF; got %q", err
)
827 // Trailing space is tougher.
828 n
, err
= Sscan("234 ", &i
, &j
)
829 if n
!= 1 || i
!= 234 {
830 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
833 t
.Errorf("Sscan expected EOF; got %q", err
)
837 var eofTests
= []struct {
850 {"%v", &complex64Val
},
851 {"%v", &renamedStringVal
},
852 {"%v", &renamedBytesVal
},
853 {"%v", &renamedIntVal
},
854 {"%v", &renamedUintVal
},
855 {"%v", &renamedBoolVal
},
856 {"%v", &renamedFloat32Val
},
857 {"%v", &renamedComplex64Val
},
860 func TestEOFAllTypes(t
*testing
.T
) {
861 for i
, test
:= range eofTests
{
862 if _
, err
:= Sscanf("", test
.format
, test
.v
); err
!= io
.EOF
{
863 t
.Errorf("#%d: %s %T not eof on empty string: %s", i
, test
.format
, test
.v
, err
)
865 if _
, err
:= Sscanf(" ", test
.format
, test
.v
); err
!= io
.EOF
{
866 t
.Errorf("#%d: %s %T not eof on trailing blanks: %s", i
, test
.format
, test
.v
, err
)
871 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
872 // calls to Fscan do not lose runes.
873 func TestUnreadRuneWithBufio(t
*testing
.T
) {
874 r
:= bufio
.NewReader(strings
.NewReader("123αb"))
877 n
, err
:= Fscanf(r
, "%d", &i
)
878 if n
!= 1 || err
!= nil {
879 t
.Errorf("reading int expected one item, no errors; got %d %q", n
, err
)
882 t
.Errorf("expected 123; got %d", i
)
884 n
, err
= Fscanf(r
, "%s", &a
)
885 if n
!= 1 || err
!= nil {
886 t
.Errorf("reading string expected one item, no errors; got %d %q", n
, err
)
889 t
.Errorf("expected αb; got %q", a
)
895 // Scan attempts to read two lines into the object. Scanln should prevent this
896 // because it stops at newline; Scan and Scanf should be fine.
897 func (t
*TwoLines
) Scan(state ScanState
, verb rune
) error
{
898 chars
:= make([]rune
, 0, 100)
899 for nlCount
:= 0; nlCount
< 2; {
900 c
, _
, err
:= state
.ReadRune()
904 chars
= append(chars
, c
)
909 *t
= TwoLines(string(chars
))
913 func TestMultiLine(t
*testing
.T
) {
914 input
:= "abc\ndef\n"
917 n
, err
:= Sscan(input
, &tscan
)
919 t
.Errorf("Sscan: expected 1 item; got %d", n
)
922 t
.Errorf("Sscan: expected no error; got %s", err
)
924 if string(tscan
) != input
{
925 t
.Errorf("Sscan: expected %q; got %q", input
, tscan
)
927 // Sscanf should work
929 n
, err
= Sscanf(input
, "%s", &tscanf
)
931 t
.Errorf("Sscanf: expected 1 item; got %d", n
)
934 t
.Errorf("Sscanf: expected no error; got %s", err
)
936 if string(tscanf
) != input
{
937 t
.Errorf("Sscanf: expected %q; got %q", input
, tscanf
)
939 // Sscanln should not work
941 n
, err
= Sscanln(input
, &tscanln
)
943 t
.Errorf("Sscanln: expected 0 items; got %d: %q", n
, tscanln
)
946 t
.Error("Sscanln: expected error; got none")
947 } else if err
!= io
.ErrUnexpectedEOF
{
948 t
.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err
)
952 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
954 func TestLineByLineFscanf(t
*testing
.T
) {
955 r
:= struct{ io
.Reader
}{strings
.NewReader("1\n2\n")}
957 n
, err
:= Fscanf(r
, "%v\n", &i
)
958 if n
!= 1 || err
!= nil {
959 t
.Fatalf("first read: %d %q", n
, err
)
961 n
, err
= Fscanf(r
, "%v\n", &j
)
962 if n
!= 1 || err
!= nil {
963 t
.Fatalf("second read: %d %q", n
, err
)
965 if i
!= 1 || j
!= 2 {
966 t
.Errorf("wrong values; wanted 1 2 got %d %d", i
, j
)
970 // TestScanStateCount verifies the correct byte count is returned. Issue 8512.
972 // runeScanner implements the Scanner interface for TestScanStateCount.
973 type runeScanner
struct {
978 func (rs
*runeScanner
) Scan(state ScanState
, verb rune
) error
{
979 r
, size
, err
:= state
.ReadRune()
985 func TestScanStateCount(t
*testing
.T
) {
986 var a
, b
, c runeScanner
987 n
, err
:= Sscanf("12âž‚", "%c%c%c", &a
, &b
, &c
)
992 t
.Fatalf("expected 3 items consumed, got %d", n
)
994 if a
.rune
!= '1' || b
.rune
!= '2' || c
.rune
!= 'âž‚' {
995 t
.Errorf("bad scan rune: %q %q %q should be '1' '2' 'âž‚'", a
.rune
, b
.rune
, c
.rune
)
997 if a
.size
!= 1 || b
.size
!= 1 || c
.size
!= 3 {
998 t
.Errorf("bad scan size: %q %q %q should be 1 1 3", a
.size
, b
.size
, c
.size
)
1002 // RecursiveInt accepts a string matching %d.%d.%d....
1003 // and parses it into a linked list.
1004 // It allows us to benchmark recursive descent style scanners.
1005 type RecursiveInt
struct {
1010 func (r
*RecursiveInt
) Scan(state ScanState
, verb rune
) (err error
) {
1011 _
, err
= Fscan(state
, &r
.i
)
1015 next
:= new(RecursiveInt
)
1016 _
, err
= Fscanf(state
, ".%v", next
)
1018 if err
== io
.ErrUnexpectedEOF
{
1027 // scanInts performs the same scanning task as RecursiveInt.Scan
1028 // but without recurring through scanner, so we can compare
1029 // performance more directly.
1030 func scanInts(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
1032 _
, err
= Fscan(b
, &r
.i
)
1036 c
, _
, err
:= b
.ReadRune()
1046 next
:= new(RecursiveInt
)
1047 err
= scanInts(next
, b
)
1054 func makeInts(n
int) []byte {
1055 var buf bytes
.Buffer
1057 for i
:= 1; i
< n
; i
++ {
1058 Fprintf(&buf
, ".%d", i
+1)
1063 func TestScanInts(t
*testing
.T
) {
1064 testScanInts(t
, scanInts
)
1065 testScanInts(t
, func(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
1066 _
, err
= Fscan(b
, r
)
1071 // 800 is small enough to not overflow the stack when using gccgo on a
1072 // platform that does not support split stack.
1073 const intCount
= 800
1075 func testScanInts(t
*testing
.T
, scan
func(*RecursiveInt
, *bytes
.Buffer
) error
) {
1076 r
:= new(RecursiveInt
)
1077 ints
:= makeInts(intCount
)
1078 buf
:= bytes
.NewBuffer(ints
)
1081 t
.Error("unexpected error", err
)
1084 for ; r
!= nil; r
= r
.next
{
1086 t
.Fatalf("bad scan: expected %d got %d", i
, r
.i
)
1090 if i
-1 != intCount
{
1091 t
.Fatalf("bad scan count: expected %d got %d", intCount
, i
-1)
1095 func BenchmarkScanInts(b
*testing
.B
) {
1097 ints
:= makeInts(intCount
)
1099 for i
:= b
.N
- 1; i
>= 0; i
-- {
1100 buf
:= bytes
.NewBuffer(ints
)
1107 func BenchmarkScanRecursiveInt(b
*testing
.B
) {
1109 ints
:= makeInts(intCount
)
1111 for i
:= b
.N
- 1; i
>= 0; i
-- {
1112 buf
:= bytes
.NewBuffer(ints
)
1119 func BenchmarkScanRecursiveIntReaderWrapper(b
*testing
.B
) {
1121 ints
:= makeInts(intCount
)
1123 for i
:= b
.N
- 1; i
>= 0; i
-- {
1124 buf
:= struct{ io
.Reader
}{strings
.NewReader(string(ints
))}
1132 // %x on bytes couldn't handle non-space bytes terminating the scan.
1133 func TestHexBytes(t
*testing
.T
) {
1135 n
, err
:= Sscanf("00010203", "%x", &a
)
1136 if n
!= 1 || err
!= nil {
1137 t
.Errorf("simple: got count, err = %d, %v; expected 1, nil", n
, err
)
1139 check
:= func(msg
string, x
[]byte) {
1141 t
.Errorf("%s: bad length %d", msg
, len(x
))
1143 for i
, b
:= range x
{
1145 t
.Errorf("%s: bad x[%d] = %x", msg
, i
, x
[i
])
1152 n
, err
= Sscanf("00010203 00010203", "%x %x", &a
, &b
)
1153 if n
!= 2 || err
!= nil {
1154 t
.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1156 check("simple pair a", a
)
1157 check("simple pair b", b
)
1161 n
, err
= Sscanf("00010203:", "%x", &a
)
1162 if n
!= 1 || err
!= nil {
1163 t
.Errorf("colon: got count, err = %d, %v; expected 1, nil", n
, err
)
1168 n
, err
= Sscanf("00010203:00010203", "%x:%x", &a
, &b
)
1169 if n
!= 2 || err
!= nil {
1170 t
.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1172 check("colon pair a", a
)
1173 check("colon pair b", b
)
1177 // This one fails because there is a hex byte after the data,
1178 // that is, an odd number of hex input bytes.
1179 n
, err
= Sscanf("000102034:", "%x", &a
)
1180 if n
!= 0 || err
== nil {
1181 t
.Errorf("odd count: got count, err = %d, %v; expected 0, error", n
, err
)
1185 func TestScanNewlinesAreSpaces(t
*testing
.T
) {
1187 var tests
= []struct {
1192 {"newlines", "1\n2\n", 2},
1193 {"no final newline", "1\n2", 2},
1194 {"newlines with spaces ", "1 \n 2 \n", 2},
1195 {"no final newline with spaces", "1 \n 2", 2},
1197 for _
, test
:= range tests
{
1198 n
, err
:= Sscan(test
.text
, &a
, &b
)
1199 if n
!= test
.count
{
1200 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1203 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1208 func TestScanlnNewlinesTerminate(t
*testing
.T
) {
1210 var tests
= []struct {
1216 {"one line one item", "1\n", 1, false},
1217 {"one line two items with spaces ", " 1 2 \n", 2, true},
1218 {"one line two items no newline", " 1 2", 2, true},
1219 {"two lines two items", "1\n2\n", 1, false},
1221 for _
, test
:= range tests
{
1222 n
, err
:= Sscanln(test
.text
, &a
, &b
)
1223 if n
!= test
.count
{
1224 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1226 if test
.ok
&& err
!= nil {
1227 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1229 if !test
.ok
&& err
== nil {
1230 t
.Errorf("%s: expected error; got none", test
.name
)
1235 func TestScanfNewlineMatchFormat(t
*testing
.T
) {
1237 var tests
= []struct {
1244 {"newline in both", "1\n2", "%d\n%d\n", 2, true},
1245 {"newline in input", "1\n2", "%d %d", 1, false},
1246 {"space-newline in input", "1 \n2", "%d %d", 1, false},
1247 {"newline in format", "1 2", "%d\n%d", 1, false},
1248 {"space-newline in format", "1 2", "%d \n%d", 1, false},
1249 {"space-newline in both", "1 \n2", "%d \n%d", 2, true},
1250 {"extra space in format", "1\n2", "%d\n %d", 2, true},
1251 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
1252 {"space vs newline 0000", "1\n2", "%d\n%d", 2, true},
1253 {"space vs newline 0001", "1\n2", "%d\n %d", 2, true},
1254 {"space vs newline 0010", "1\n2", "%d \n%d", 2, true},
1255 {"space vs newline 0011", "1\n2", "%d \n %d", 2, true},
1256 {"space vs newline 0100", "1\n 2", "%d\n%d", 2, true},
1257 {"space vs newline 0101", "1\n 2", "%d\n%d ", 2, true},
1258 {"space vs newline 0110", "1\n 2", "%d \n%d", 2, true},
1259 {"space vs newline 0111", "1\n 2", "%d \n %d", 2, true},
1260 {"space vs newline 1000", "1 \n2", "%d\n%d", 2, true},
1261 {"space vs newline 1001", "1 \n2", "%d\n %d", 2, true},
1262 {"space vs newline 1010", "1 \n2", "%d \n%d", 2, true},
1263 {"space vs newline 1011", "1 \n2", "%d \n %d", 2, true},
1264 {"space vs newline 1100", "1 \n 2", "%d\n%d", 2, true},
1265 {"space vs newline 1101", "1 \n 2", "%d\n %d", 2, true},
1266 {"space vs newline 1110", "1 \n 2", "%d \n%d", 2, true},
1267 {"space vs newline 1111", "1 \n 2", "%d \n %d", 2, true},
1268 {"space vs newline no-percent 0000", "1\n2", "1\n2", 0, true},
1269 {"space vs newline no-percent 0001", "1\n2", "1\n 2", 0, true},
1270 {"space vs newline no-percent 0010", "1\n2", "1 \n2", 0, true},
1271 {"space vs newline no-percent 0011", "1\n2", "1 \n 2", 0, true},
1272 {"space vs newline no-percent 0100", "1\n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1273 {"space vs newline no-percent 0101", "1\n 2", "1\n2 ", 0, false}, // fails: space after nl in input but not pattern
1274 {"space vs newline no-percent 0110", "1\n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1275 {"space vs newline no-percent 0111", "1\n 2", "1 \n 2", 0, true},
1276 {"space vs newline no-percent 1000", "1 \n2", "1\n2", 0, true},
1277 {"space vs newline no-percent 1001", "1 \n2", "1\n 2", 0, true},
1278 {"space vs newline no-percent 1010", "1 \n2", "1 \n2", 0, true},
1279 {"space vs newline no-percent 1011", "1 \n2", "1 \n 2", 0, true},
1280 {"space vs newline no-percent 1100", "1 \n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1281 {"space vs newline no-percent 1101", "1 \n 2", "1\n 2", 0, true},
1282 {"space vs newline no-percent 1110", "1 \n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1283 {"space vs newline no-percent 1111", "1 \n 2", "1 \n 2", 0, true},
1285 for _
, test
:= range tests
{
1288 if strings
.Contains(test
.format
, "%") {
1289 n
, err
= Sscanf(test
.text
, test
.format
, &a
, &b
)
1291 n
, err
= Sscanf(test
.text
, test
.format
)
1293 if n
!= test
.count
{
1294 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1296 if test
.ok
&& err
!= nil {
1297 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1299 if !test
.ok
&& err
== nil {
1300 t
.Errorf("%s: expected error; got none", test
.name
)
1305 // Test for issue 12090: Was unreading at EOF, double-scanning a byte.
1307 type hexBytes
[2]byte
1309 func (h
*hexBytes
) Scan(ss ScanState
, verb rune
) error
{
1311 _
, err
:= Fscanf(ss
, "%4x", &b
)
1313 panic(err
) // Really shouldn't happen.
1319 func TestHexByte(t
*testing
.T
) {
1321 n
, err
:= Sscanln("0123\n", &h
)
1326 t
.Fatalf("expected 1 item; scanned %d", n
)
1328 if h
[0] != 0x01 || h
[1] != 0x23 {
1329 t
.Fatalf("expected 0123 got %x", h
)