github.com/euank/go@v0.0.0-20160829210321-495514729181/src/fmt/scan_test.go (about) 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. 4 5 package fmt_test 6 7 import ( 8 "bufio" 9 "bytes" 10 "errors" 11 . "fmt" 12 "io" 13 "math" 14 "reflect" 15 "regexp" 16 "strings" 17 "testing" 18 "testing/iotest" 19 "unicode/utf8" 20 ) 21 22 type ScanTest struct { 23 text string 24 in interface{} 25 out interface{} 26 } 27 28 type ScanfTest struct { 29 format string 30 text string 31 in interface{} 32 out interface{} 33 } 34 35 type ScanfMultiTest struct { 36 format string 37 text string 38 in []interface{} 39 out []interface{} 40 err string 41 } 42 43 var ( 44 boolVal bool 45 intVal int 46 int8Val int8 47 int16Val int16 48 int32Val int32 49 int64Val int64 50 uintVal uint 51 uint8Val uint8 52 uint16Val uint16 53 uint32Val uint32 54 uint64Val uint64 55 float32Val float32 56 float64Val float64 57 stringVal string 58 bytesVal []byte 59 runeVal rune 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 80 ) 81 82 // Xs accepts any non-empty run of the verb character 83 type Xs string 84 85 func (x *Xs) Scan(state ScanState, verb rune) error { 86 tok, err := state.Token(true, func(r rune) bool { return r == verb }) 87 if err != nil { 88 return err 89 } 90 s := string(tok) 91 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) { 92 return errors.New("syntax error for xs") 93 } 94 *x = Xs(s) 95 return nil 96 } 97 98 var xVal Xs 99 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 { 103 i int 104 s string 105 } 106 107 func (s *IntString) Scan(state ScanState, verb rune) error { 108 if _, err := Fscan(state, &s.i); err != nil { 109 return err 110 } 111 112 tok, err := state.Token(true, nil) 113 if err != nil { 114 return err 115 } 116 s.s = string(tok) 117 return nil 118 } 119 120 var intStringVal IntString 121 122 var scanTests = []ScanTest{ 123 // Basic types 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 {"0\n", &intVal, 0}, 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"}, 174 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)}, 178 179 // Renamed types 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"))}, 197 198 // Custom scanners. 199 {" vvv ", &xVal, Xs("vvv")}, 200 {" 1234hello", &intStringVal, IntString{1234, "hello"}}, 201 202 // Fixed bugs 203 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow 204 } 205 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)}, 235 236 // Strings 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"}, 242 243 // Byte slices 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")}, 249 250 // Renamed types 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)}, 273 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. 278 279 // Corner cases 280 {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)}, 281 282 // Custom scanner. 283 {"%s", " sss ", &xVal, Xs("sss")}, 284 {"%2s", "sssss", &xVal, Xs("ss")}, 285 286 // Fixed bugs 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. 294 } 295 296 var overflowTests = []ScanTest{ 297 {"128", &int8Val, 0}, 298 {"32768", &int16Val, 0}, 299 {"-129", &int8Val, 0}, 300 {"-32769", &int16Val, 0}, 301 {"256", &uint8Val, 0}, 302 {"65536", &uint16Val, 0}, 303 {"1e100", &float32Val, 0}, 304 {"1e500", &float64Val, 0}, 305 {"(1e100+0i)", &complex64Val, 0}, 306 {"(1+1e100i)", &complex64Val, 0}, 307 {"(1-1e500i)", &complex128Val, 0}, 308 } 309 310 var truth bool 311 var i, j, k int 312 var f float64 313 var s, t string 314 var c complex128 315 var x, y Xs 316 var z IntString 317 var r1, r2, r3 rune 318 319 var multiTests = []ScanfMultiTest{ 320 {"", "", []interface{}{}, []interface{}{}, ""}, 321 {"%d", "23", args(&i), args(23), ""}, 322 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""}, 323 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""}, 324 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""}, 325 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""}, 326 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, 327 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, 328 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, 329 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""}, 330 {"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""}, 331 {"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""}, 332 333 // Custom scanners. 334 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, 335 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""}, 336 337 // Errors 338 {"%t", "23 18", args(&i), nil, "bad verb"}, 339 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"}, 340 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"}, 341 {"%c", "\u0100", args(&int8Val), nil, "overflow"}, 342 {"X%d", "10X", args(&intVal), nil, "input does not match format"}, 343 {"%d%", "42%", args(&intVal), args(42), "missing verb: % at end of format string"}, 344 {"%d% ", "42%", args(&intVal), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct. 345 346 // Bad UTF-8: should see every byte. 347 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""}, 348 349 // Fixed bugs 350 {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""}, 351 } 352 353 var readers = []struct { 354 name string 355 f func(string) io.Reader 356 }{ 357 {"StringReader", func(s string) io.Reader { 358 return strings.NewReader(s) 359 }}, 360 {"ReaderOnly", func(s string) io.Reader { 361 return struct{ io.Reader }{strings.NewReader(s)} 362 }}, 363 {"OneByteReader", func(s string) io.Reader { 364 return iotest.OneByteReader(strings.NewReader(s)) 365 }}, 366 {"DataErrReader", func(s string) io.Reader { 367 return iotest.DataErrReader(strings.NewReader(s)) 368 }}, 369 } 370 371 func testScan(t *testing.T, f func(string) io.Reader, scan func(r io.Reader, a ...interface{}) (int, error)) { 372 for _, test := range scanTests { 373 r := f(test.text) 374 n, err := scan(r, test.in) 375 if err != nil { 376 m := "" 377 if n > 0 { 378 m = Sprintf(" (%d fields ok)", n) 379 } 380 t.Errorf("got error scanning %q: %s%s", test.text, err, m) 381 continue 382 } 383 if n != 1 { 384 t.Errorf("count error on entry %q: got %d", test.text, n) 385 continue 386 } 387 // The incoming value may be a pointer 388 v := reflect.ValueOf(test.in) 389 if p := v; p.Kind() == reflect.Ptr { 390 v = p.Elem() 391 } 392 val := v.Interface() 393 if !reflect.DeepEqual(val, test.out) { 394 t.Errorf("scanning %q: expected %#v got %#v, type %T", test.text, test.out, val, val) 395 } 396 } 397 } 398 399 func TestScan(t *testing.T) { 400 for _, r := range readers { 401 t.Run(r.name, func(t *testing.T) { 402 testScan(t, r.f, Fscan) 403 }) 404 } 405 } 406 407 func TestScanln(t *testing.T) { 408 for _, r := range readers { 409 t.Run(r.name, func(t *testing.T) { 410 testScan(t, r.f, Fscanln) 411 }) 412 } 413 } 414 415 func TestScanf(t *testing.T) { 416 for _, test := range scanfTests { 417 n, err := Sscanf(test.text, test.format, test.in) 418 if err != nil { 419 t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err) 420 continue 421 } 422 if n != 1 { 423 t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n) 424 continue 425 } 426 // The incoming value may be a pointer 427 v := reflect.ValueOf(test.in) 428 if p := v; p.Kind() == reflect.Ptr { 429 v = p.Elem() 430 } 431 val := v.Interface() 432 if !reflect.DeepEqual(val, test.out) { 433 t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val) 434 } 435 } 436 } 437 438 func TestScanOverflow(t *testing.T) { 439 // different machines and different types report errors with different strings. 440 re := regexp.MustCompile("overflow|too large|out of range|not representable") 441 for _, test := range overflowTests { 442 _, err := Sscan(test.text, test.in) 443 if err == nil { 444 t.Errorf("expected overflow scanning %q", test.text) 445 continue 446 } 447 if !re.MatchString(err.Error()) { 448 t.Errorf("expected overflow error scanning %q: %s", test.text, err) 449 } 450 } 451 } 452 453 func verifyNaN(str string, t *testing.T) { 454 var f float64 455 var f32 float32 456 var f64 float64 457 text := str + " " + str + " " + str 458 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) 459 if err != nil { 460 t.Errorf("got error scanning %q: %s", text, err) 461 } 462 if n != 3 { 463 t.Errorf("count error scanning %q: got %d", text, n) 464 } 465 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) { 466 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64) 467 } 468 } 469 470 func TestNaN(t *testing.T) { 471 for _, s := range []string{"nan", "NAN", "NaN"} { 472 verifyNaN(s, t) 473 } 474 } 475 476 func verifyInf(str string, t *testing.T) { 477 var f float64 478 var f32 float32 479 var f64 float64 480 text := str + " " + str + " " + str 481 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) 482 if err != nil { 483 t.Errorf("got error scanning %q: %s", text, err) 484 } 485 if n != 3 { 486 t.Errorf("count error scanning %q: got %d", text, n) 487 } 488 sign := 1 489 if str[0] == '-' { 490 sign = -1 491 } 492 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) { 493 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64) 494 } 495 } 496 497 func TestInf(t *testing.T) { 498 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} { 499 verifyInf(s, t) 500 } 501 } 502 503 func testScanfMulti(t *testing.T, f func(string) io.Reader) { 504 sliceType := reflect.TypeOf(make([]interface{}, 1)) 505 for _, test := range multiTests { 506 r := f(test.text) 507 n, err := Fscanf(r, test.format, test.in...) 508 if err != nil { 509 if test.err == "" { 510 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err) 511 } else if !strings.Contains(err.Error(), test.err) { 512 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err) 513 } 514 continue 515 } 516 if test.err != "" { 517 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text) 518 } 519 if n != len(test.out) { 520 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n) 521 continue 522 } 523 // Convert the slice of pointers into a slice of values 524 resultVal := reflect.MakeSlice(sliceType, n, n) 525 for i := 0; i < n; i++ { 526 v := reflect.ValueOf(test.in[i]).Elem() 527 resultVal.Index(i).Set(v) 528 } 529 result := resultVal.Interface() 530 if !reflect.DeepEqual(result, test.out) { 531 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result) 532 } 533 } 534 } 535 536 func TestScanfMulti(t *testing.T) { 537 for _, r := range readers { 538 t.Run(r.name, func(t *testing.T) { 539 testScanfMulti(t, r.f) 540 }) 541 } 542 } 543 544 func TestScanMultiple(t *testing.T) { 545 var a int 546 var s string 547 n, err := Sscan("123abc", &a, &s) 548 if n != 2 { 549 t.Errorf("Sscan count error: expected 2: got %d", n) 550 } 551 if err != nil { 552 t.Errorf("Sscan expected no error; got %s", err) 553 } 554 if a != 123 || s != "abc" { 555 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s) 556 } 557 n, err = Sscan("asdf", &s, &a) 558 if n != 1 { 559 t.Errorf("Sscan count error: expected 1: got %d", n) 560 } 561 if err == nil { 562 t.Errorf("Sscan expected error; got none: %s", err) 563 } 564 if s != "asdf" { 565 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s) 566 } 567 } 568 569 // Empty strings are not valid input when scanning a string. 570 func TestScanEmpty(t *testing.T) { 571 var s1, s2 string 572 n, err := Sscan("abc", &s1, &s2) 573 if n != 1 { 574 t.Errorf("Sscan count error: expected 1: got %d", n) 575 } 576 if err == nil { 577 t.Error("Sscan <one item> expected error; got none") 578 } 579 if s1 != "abc" { 580 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1) 581 } 582 n, err = Sscan("", &s1, &s2) 583 if n != 0 { 584 t.Errorf("Sscan count error: expected 0: got %d", n) 585 } 586 if err == nil { 587 t.Error("Sscan <empty> expected error; got none") 588 } 589 // Quoted empty string is OK. 590 n, err = Sscanf(`""`, "%q", &s1) 591 if n != 1 { 592 t.Errorf("Sscanf count error: expected 1: got %d", n) 593 } 594 if err != nil { 595 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err) 596 } 597 } 598 599 func TestScanNotPointer(t *testing.T) { 600 r := strings.NewReader("1") 601 var a int 602 _, err := Fscan(r, a) 603 if err == nil { 604 t.Error("expected error scanning non-pointer") 605 } else if !strings.Contains(err.Error(), "pointer") { 606 t.Errorf("expected pointer error scanning non-pointer, got: %s", err) 607 } 608 } 609 610 func TestScanlnNoNewline(t *testing.T) { 611 var a int 612 _, err := Sscanln("1 x\n", &a) 613 if err == nil { 614 t.Error("expected error scanning string missing newline") 615 } else if !strings.Contains(err.Error(), "newline") { 616 t.Errorf("expected newline error scanning string missing newline, got: %s", err) 617 } 618 } 619 620 func TestScanlnWithMiddleNewline(t *testing.T) { 621 r := strings.NewReader("123\n456\n") 622 var a, b int 623 _, err := Fscanln(r, &a, &b) 624 if err == nil { 625 t.Error("expected error scanning string with extra newline") 626 } else if !strings.Contains(err.Error(), "newline") { 627 t.Errorf("expected newline error scanning string with extra newline, got: %s", err) 628 } 629 } 630 631 // eofCounter is a special Reader that counts reads at end of file. 632 type eofCounter struct { 633 reader *strings.Reader 634 eofCount int 635 } 636 637 func (ec *eofCounter) Read(b []byte) (n int, err error) { 638 n, err = ec.reader.Read(b) 639 if n == 0 { 640 ec.eofCount++ 641 } 642 return 643 } 644 645 // TestEOF verifies that when we scan, we see at most EOF once per call to a 646 // Scan function, and then only when it's really an EOF. 647 func TestEOF(t *testing.T) { 648 ec := &eofCounter{strings.NewReader("123\n"), 0} 649 var a int 650 n, err := Fscanln(ec, &a) 651 if err != nil { 652 t.Error("unexpected error", err) 653 } 654 if n != 1 { 655 t.Error("expected to scan one item, got", n) 656 } 657 if ec.eofCount != 0 { 658 t.Error("expected zero EOFs", ec.eofCount) 659 ec.eofCount = 0 // reset for next test 660 } 661 n, err = Fscanln(ec, &a) 662 if err == nil { 663 t.Error("expected error scanning empty string") 664 } 665 if n != 0 { 666 t.Error("expected to scan zero items, got", n) 667 } 668 if ec.eofCount != 1 { 669 t.Error("expected one EOF, got", ec.eofCount) 670 } 671 } 672 673 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input. 674 // This was a buglet: we used to get "expected integer". 675 func TestEOFAtEndOfInput(t *testing.T) { 676 var i, j int 677 n, err := Sscanf("23", "%d %d", &i, &j) 678 if n != 1 || i != 23 { 679 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i) 680 } 681 if err != io.EOF { 682 t.Errorf("Sscanf expected EOF; got %q", err) 683 } 684 n, err = Sscan("234", &i, &j) 685 if n != 1 || i != 234 { 686 t.Errorf("Sscan expected one value of 234; got %d %d", n, i) 687 } 688 if err != io.EOF { 689 t.Errorf("Sscan expected EOF; got %q", err) 690 } 691 // Trailing space is tougher. 692 n, err = Sscan("234 ", &i, &j) 693 if n != 1 || i != 234 { 694 t.Errorf("Sscan expected one value of 234; got %d %d", n, i) 695 } 696 if err != io.EOF { 697 t.Errorf("Sscan expected EOF; got %q", err) 698 } 699 } 700 701 var eofTests = []struct { 702 format string 703 v interface{} 704 }{ 705 {"%s", &stringVal}, 706 {"%q", &stringVal}, 707 {"%x", &stringVal}, 708 {"%v", &stringVal}, 709 {"%v", &bytesVal}, 710 {"%v", &intVal}, 711 {"%v", &uintVal}, 712 {"%v", &boolVal}, 713 {"%v", &float32Val}, 714 {"%v", &complex64Val}, 715 {"%v", &renamedStringVal}, 716 {"%v", &renamedBytesVal}, 717 {"%v", &renamedIntVal}, 718 {"%v", &renamedUintVal}, 719 {"%v", &renamedBoolVal}, 720 {"%v", &renamedFloat32Val}, 721 {"%v", &renamedComplex64Val}, 722 } 723 724 func TestEOFAllTypes(t *testing.T) { 725 for i, test := range eofTests { 726 if _, err := Sscanf("", test.format, test.v); err != io.EOF { 727 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err) 728 } 729 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF { 730 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err) 731 } 732 } 733 } 734 735 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive 736 // calls to Fscan do not lose runes. 737 func TestUnreadRuneWithBufio(t *testing.T) { 738 r := bufio.NewReader(strings.NewReader("123αb")) 739 var i int 740 var a string 741 n, err := Fscanf(r, "%d", &i) 742 if n != 1 || err != nil { 743 t.Errorf("reading int expected one item, no errors; got %d %q", n, err) 744 } 745 if i != 123 { 746 t.Errorf("expected 123; got %d", i) 747 } 748 n, err = Fscanf(r, "%s", &a) 749 if n != 1 || err != nil { 750 t.Errorf("reading string expected one item, no errors; got %d %q", n, err) 751 } 752 if a != "αb" { 753 t.Errorf("expected αb; got %q", a) 754 } 755 } 756 757 type TwoLines string 758 759 // Scan attempts to read two lines into the object. Scanln should prevent this 760 // because it stops at newline; Scan and Scanf should be fine. 761 func (t *TwoLines) Scan(state ScanState, verb rune) error { 762 chars := make([]rune, 0, 100) 763 for nlCount := 0; nlCount < 2; { 764 c, _, err := state.ReadRune() 765 if err != nil { 766 return err 767 } 768 chars = append(chars, c) 769 if c == '\n' { 770 nlCount++ 771 } 772 } 773 *t = TwoLines(string(chars)) 774 return nil 775 } 776 777 func TestMultiLine(t *testing.T) { 778 input := "abc\ndef\n" 779 // Sscan should work 780 var tscan TwoLines 781 n, err := Sscan(input, &tscan) 782 if n != 1 { 783 t.Errorf("Sscan: expected 1 item; got %d", n) 784 } 785 if err != nil { 786 t.Errorf("Sscan: expected no error; got %s", err) 787 } 788 if string(tscan) != input { 789 t.Errorf("Sscan: expected %q; got %q", input, tscan) 790 } 791 // Sscanf should work 792 var tscanf TwoLines 793 n, err = Sscanf(input, "%s", &tscanf) 794 if n != 1 { 795 t.Errorf("Sscanf: expected 1 item; got %d", n) 796 } 797 if err != nil { 798 t.Errorf("Sscanf: expected no error; got %s", err) 799 } 800 if string(tscanf) != input { 801 t.Errorf("Sscanf: expected %q; got %q", input, tscanf) 802 } 803 // Sscanln should not work 804 var tscanln TwoLines 805 n, err = Sscanln(input, &tscanln) 806 if n != 0 { 807 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln) 808 } 809 if err == nil { 810 t.Error("Sscanln: expected error; got none") 811 } else if err != io.ErrUnexpectedEOF { 812 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err) 813 } 814 } 815 816 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue 817 // 3481. 818 func TestLineByLineFscanf(t *testing.T) { 819 r := struct{ io.Reader }{strings.NewReader("1\n2\n")} 820 var i, j int 821 n, err := Fscanf(r, "%v\n", &i) 822 if n != 1 || err != nil { 823 t.Fatalf("first read: %d %q", n, err) 824 } 825 n, err = Fscanf(r, "%v\n", &j) 826 if n != 1 || err != nil { 827 t.Fatalf("second read: %d %q", n, err) 828 } 829 if i != 1 || j != 2 { 830 t.Errorf("wrong values; wanted 1 2 got %d %d", i, j) 831 } 832 } 833 834 // TestScanStateCount verifies the correct byte count is returned. Issue 8512. 835 836 // runeScanner implements the Scanner interface for TestScanStateCount. 837 type runeScanner struct { 838 rune rune 839 size int 840 } 841 842 func (rs *runeScanner) Scan(state ScanState, verb rune) error { 843 r, size, err := state.ReadRune() 844 rs.rune = r 845 rs.size = size 846 return err 847 } 848 849 func TestScanStateCount(t *testing.T) { 850 var a, b, c runeScanner 851 n, err := Sscanf("12➂", "%c%c%c", &a, &b, &c) 852 if err != nil { 853 t.Fatal(err) 854 } 855 if n != 3 { 856 t.Fatalf("expected 3 items consumed, got %d", n) 857 } 858 if a.rune != '1' || b.rune != '2' || c.rune != '➂' { 859 t.Errorf("bad scan rune: %q %q %q should be '1' '2' '➂'", a.rune, b.rune, c.rune) 860 } 861 if a.size != 1 || b.size != 1 || c.size != 3 { 862 t.Errorf("bad scan size: %q %q %q should be 1 1 3", a.size, b.size, c.size) 863 } 864 } 865 866 // RecursiveInt accepts a string matching %d.%d.%d.... 867 // and parses it into a linked list. 868 // It allows us to benchmark recursive descent style scanners. 869 type RecursiveInt struct { 870 i int 871 next *RecursiveInt 872 } 873 874 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) { 875 _, err = Fscan(state, &r.i) 876 if err != nil { 877 return 878 } 879 next := new(RecursiveInt) 880 _, err = Fscanf(state, ".%v", next) 881 if err != nil { 882 if err == io.ErrUnexpectedEOF { 883 err = nil 884 } 885 return 886 } 887 r.next = next 888 return 889 } 890 891 // scanInts performs the same scanning task as RecursiveInt.Scan 892 // but without recurring through scanner, so we can compare 893 // performance more directly. 894 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) { 895 r.next = nil 896 _, err = Fscan(b, &r.i) 897 if err != nil { 898 return 899 } 900 c, _, err := b.ReadRune() 901 if err != nil { 902 if err == io.EOF { 903 err = nil 904 } 905 return 906 } 907 if c != '.' { 908 return 909 } 910 next := new(RecursiveInt) 911 err = scanInts(next, b) 912 if err == nil { 913 r.next = next 914 } 915 return 916 } 917 918 func makeInts(n int) []byte { 919 var buf bytes.Buffer 920 Fprintf(&buf, "1") 921 for i := 1; i < n; i++ { 922 Fprintf(&buf, ".%d", i+1) 923 } 924 return buf.Bytes() 925 } 926 927 func TestScanInts(t *testing.T) { 928 testScanInts(t, scanInts) 929 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) { 930 _, err = Fscan(b, r) 931 return 932 }) 933 } 934 935 // 800 is small enough to not overflow the stack when using gccgo on a 936 // platform that does not support split stack. 937 const intCount = 800 938 939 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) { 940 r := new(RecursiveInt) 941 ints := makeInts(intCount) 942 buf := bytes.NewBuffer(ints) 943 err := scan(r, buf) 944 if err != nil { 945 t.Error("unexpected error", err) 946 } 947 i := 1 948 for ; r != nil; r = r.next { 949 if r.i != i { 950 t.Fatalf("bad scan: expected %d got %d", i, r.i) 951 } 952 i++ 953 } 954 if i-1 != intCount { 955 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1) 956 } 957 } 958 959 func BenchmarkScanInts(b *testing.B) { 960 b.ResetTimer() 961 ints := makeInts(intCount) 962 var r RecursiveInt 963 for i := b.N - 1; i >= 0; i-- { 964 buf := bytes.NewBuffer(ints) 965 b.StartTimer() 966 scanInts(&r, buf) 967 b.StopTimer() 968 } 969 } 970 971 func BenchmarkScanRecursiveInt(b *testing.B) { 972 b.ResetTimer() 973 ints := makeInts(intCount) 974 var r RecursiveInt 975 for i := b.N - 1; i >= 0; i-- { 976 buf := bytes.NewBuffer(ints) 977 b.StartTimer() 978 Fscan(buf, &r) 979 b.StopTimer() 980 } 981 } 982 983 func BenchmarkScanRecursiveIntReaderWrapper(b *testing.B) { 984 b.ResetTimer() 985 ints := makeInts(intCount) 986 var r RecursiveInt 987 for i := b.N - 1; i >= 0; i-- { 988 buf := struct{ io.Reader }{strings.NewReader(string(ints))} 989 b.StartTimer() 990 Fscan(buf, &r) 991 b.StopTimer() 992 } 993 } 994 995 // Issue 9124. 996 // %x on bytes couldn't handle non-space bytes terminating the scan. 997 func TestHexBytes(t *testing.T) { 998 var a, b []byte 999 n, err := Sscanf("00010203", "%x", &a) 1000 if n != 1 || err != nil { 1001 t.Errorf("simple: got count, err = %d, %v; expected 1, nil", n, err) 1002 } 1003 check := func(msg string, x []byte) { 1004 if len(x) != 4 { 1005 t.Errorf("%s: bad length %d", msg, len(x)) 1006 } 1007 for i, b := range x { 1008 if int(b) != i { 1009 t.Errorf("%s: bad x[%d] = %x", msg, i, x[i]) 1010 } 1011 } 1012 } 1013 check("simple", a) 1014 a = nil 1015 1016 n, err = Sscanf("00010203 00010203", "%x %x", &a, &b) 1017 if n != 2 || err != nil { 1018 t.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n, err) 1019 } 1020 check("simple pair a", a) 1021 check("simple pair b", b) 1022 a = nil 1023 b = nil 1024 1025 n, err = Sscanf("00010203:", "%x", &a) 1026 if n != 1 || err != nil { 1027 t.Errorf("colon: got count, err = %d, %v; expected 1, nil", n, err) 1028 } 1029 check("colon", a) 1030 a = nil 1031 1032 n, err = Sscanf("00010203:00010203", "%x:%x", &a, &b) 1033 if n != 2 || err != nil { 1034 t.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n, err) 1035 } 1036 check("colon pair a", a) 1037 check("colon pair b", b) 1038 a = nil 1039 b = nil 1040 1041 // This one fails because there is a hex byte after the data, 1042 // that is, an odd number of hex input bytes. 1043 n, err = Sscanf("000102034:", "%x", &a) 1044 if n != 0 || err == nil { 1045 t.Errorf("odd count: got count, err = %d, %v; expected 0, error", n, err) 1046 } 1047 } 1048 1049 func TestScanNewlinesAreSpaces(t *testing.T) { 1050 var a, b int 1051 var tests = []struct { 1052 name string 1053 text string 1054 count int 1055 }{ 1056 {"newlines", "1\n2\n", 2}, 1057 {"no final newline", "1\n2", 2}, 1058 {"newlines with spaces ", "1 \n 2 \n", 2}, 1059 {"no final newline with spaces", "1 \n 2", 2}, 1060 } 1061 for _, test := range tests { 1062 n, err := Sscan(test.text, &a, &b) 1063 if n != test.count { 1064 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1065 } 1066 if err != nil { 1067 t.Errorf("%s: unexpected error: %s", test.name, err) 1068 } 1069 } 1070 } 1071 1072 func TestScanlnNewlinesTerminate(t *testing.T) { 1073 var a, b int 1074 var tests = []struct { 1075 name string 1076 text string 1077 count int 1078 ok bool 1079 }{ 1080 {"one line one item", "1\n", 1, false}, 1081 {"one line two items with spaces ", " 1 2 \n", 2, true}, 1082 {"one line two items no newline", " 1 2", 2, true}, 1083 {"two lines two items", "1\n2\n", 1, false}, 1084 } 1085 for _, test := range tests { 1086 n, err := Sscanln(test.text, &a, &b) 1087 if n != test.count { 1088 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1089 } 1090 if test.ok && err != nil { 1091 t.Errorf("%s: unexpected error: %s", test.name, err) 1092 } 1093 if !test.ok && err == nil { 1094 t.Errorf("%s: expected error; got none", test.name) 1095 } 1096 } 1097 } 1098 1099 func TestScanfNewlineMatchFormat(t *testing.T) { 1100 var a, b int 1101 var tests = []struct { 1102 name string 1103 text string 1104 format string 1105 count int 1106 ok bool 1107 }{ 1108 {"newline in both", "1\n2", "%d\n%d\n", 2, true}, 1109 {"newline in input", "1\n2", "%d %d", 1, false}, 1110 {"space-newline in input", "1 \n2", "%d %d", 1, false}, 1111 {"newline in format", "1 2", "%d\n%d", 1, false}, 1112 {"space-newline in format", "1 2", "%d \n%d", 1, false}, 1113 {"space-newline in both", "1 \n2", "%d \n%d", 2, true}, 1114 {"extra space in format", "1\n2", "%d\n %d", 2, true}, 1115 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true}, 1116 } 1117 for _, test := range tests { 1118 n, err := Sscanf(test.text, test.format, &a, &b) 1119 if n != test.count { 1120 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1121 } 1122 if test.ok && err != nil { 1123 t.Errorf("%s: unexpected error: %s", test.name, err) 1124 } 1125 if !test.ok && err == nil { 1126 t.Errorf("%s: expected error; got none", test.name) 1127 } 1128 } 1129 } 1130 1131 // Test for issue 12090: Was unreading at EOF, double-scanning a byte. 1132 1133 type hexBytes [2]byte 1134 1135 func (h *hexBytes) Scan(ss ScanState, verb rune) error { 1136 var b []byte 1137 _, err := Fscanf(ss, "%4x", &b) 1138 if err != nil { 1139 panic(err) // Really shouldn't happen. 1140 } 1141 copy((*h)[:], b) 1142 return err 1143 } 1144 1145 func TestHexByte(t *testing.T) { 1146 var h hexBytes 1147 n, err := Sscanln("0123\n", &h) 1148 if err != nil { 1149 t.Fatal(err) 1150 } 1151 if n != 1 { 1152 t.Fatalf("expected 1 item; scanned %d", n) 1153 } 1154 if h[0] != 0x01 || h[1] != 0x23 { 1155 t.Fatalf("expected 0123 got %x", h) 1156 } 1157 }