get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/conf/lex_test.go (about) 1 package conf 2 3 import "testing" 4 5 // Test to make sure we get what we expect. 6 func expect(t *testing.T, lx *lexer, items []item) { 7 t.Helper() 8 for i := 0; i < len(items); i++ { 9 item := lx.nextItem() 10 _ = item.String() 11 if item.typ == itemEOF { 12 break 13 } 14 if item != items[i] { 15 t.Fatalf("Testing: '%s'\nExpected %q, received %q\n", 16 lx.input, items[i], item) 17 } 18 if item.typ == itemError { 19 break 20 } 21 } 22 } 23 24 func TestPlainValue(t *testing.T) { 25 expectedItems := []item{ 26 {itemKey, "foo", 1, 0}, 27 {itemEOF, "", 1, 0}, 28 } 29 lx := lex("foo") 30 expect(t, lx, expectedItems) 31 } 32 33 func TestSimpleKeyStringValues(t *testing.T) { 34 // Double quotes 35 expectedItems := []item{ 36 {itemKey, "foo", 1, 0}, 37 {itemString, "bar", 1, 7}, 38 {itemEOF, "", 1, 0}, 39 } 40 lx := lex("foo = \"bar\"") 41 expect(t, lx, expectedItems) 42 43 // Single quotes 44 expectedItems = []item{ 45 {itemKey, "foo", 1, 0}, 46 {itemString, "bar", 1, 7}, 47 {itemEOF, "", 1, 0}, 48 } 49 lx = lex("foo = 'bar'") 50 expect(t, lx, expectedItems) 51 52 // No spaces 53 expectedItems = []item{ 54 {itemKey, "foo", 1, 0}, 55 {itemString, "bar", 1, 5}, 56 {itemEOF, "", 1, 0}, 57 } 58 lx = lex("foo='bar'") 59 expect(t, lx, expectedItems) 60 61 // NL 62 expectedItems = []item{ 63 {itemKey, "foo", 1, 0}, 64 {itemString, "bar", 1, 5}, 65 {itemEOF, "", 1, 0}, 66 } 67 lx = lex("foo='bar'\r\n") 68 expect(t, lx, expectedItems) 69 70 expectedItems = []item{ 71 {itemKey, "foo", 1, 0}, 72 {itemString, "bar", 1, 6}, 73 {itemEOF, "", 1, 0}, 74 } 75 lx = lex("foo=\t'bar'\t") 76 expect(t, lx, expectedItems) 77 } 78 79 func TestComplexStringValues(t *testing.T) { 80 expectedItems := []item{ 81 {itemKey, "foo", 1, 0}, 82 {itemString, "bar\\r\\n \\t", 1, 7}, 83 {itemEOF, "", 2, 0}, 84 } 85 86 lx := lex("foo = 'bar\\r\\n \\t'") 87 expect(t, lx, expectedItems) 88 } 89 90 func TestStringStartingWithNumber(t *testing.T) { 91 expectedItems := []item{ 92 {itemKey, "foo", 1, 0}, 93 {itemString, "3xyz", 1, 6}, 94 {itemEOF, "", 2, 0}, 95 } 96 97 lx := lex(`foo = 3xyz`) 98 expect(t, lx, expectedItems) 99 100 lx = lex(`foo = 3xyz,`) 101 expect(t, lx, expectedItems) 102 103 lx = lex(`foo = 3xyz;`) 104 expect(t, lx, expectedItems) 105 106 expectedItems = []item{ 107 {itemKey, "foo", 2, 9}, 108 {itemString, "3xyz", 2, 15}, 109 {itemEOF, "", 2, 0}, 110 } 111 content := ` 112 foo = 3xyz 113 ` 114 lx = lex(content) 115 expect(t, lx, expectedItems) 116 117 expectedItems = []item{ 118 {itemKey, "map", 2, 9}, 119 {itemMapStart, "", 2, 14}, 120 {itemKey, "foo", 3, 11}, 121 {itemString, "3xyz", 3, 17}, 122 {itemMapEnd, "", 3, 22}, 123 {itemEOF, "", 2, 0}, 124 } 125 content = ` 126 map { 127 foo = 3xyz} 128 ` 129 lx = lex(content) 130 expect(t, lx, expectedItems) 131 132 expectedItems = []item{ 133 {itemKey, "map", 2, 9}, 134 {itemMapStart, "", 2, 14}, 135 {itemKey, "foo", 3, 11}, 136 {itemString, "3xyz", 3, 17}, 137 {itemMapEnd, "", 4, 10}, 138 {itemEOF, "", 2, 0}, 139 } 140 content = ` 141 map { 142 foo = 3xyz; 143 } 144 ` 145 lx = lex(content) 146 expect(t, lx, expectedItems) 147 148 expectedItems = []item{ 149 {itemKey, "map", 2, 9}, 150 {itemMapStart, "", 2, 14}, 151 {itemKey, "foo", 3, 11}, 152 {itemString, "3xyz", 3, 17}, 153 {itemKey, "bar", 4, 11}, 154 {itemString, "4wqs", 4, 17}, 155 {itemMapEnd, "", 5, 10}, 156 {itemEOF, "", 2, 0}, 157 } 158 content = ` 159 map { 160 foo = 3xyz, 161 bar = 4wqs 162 } 163 ` 164 lx = lex(content) 165 expect(t, lx, expectedItems) 166 } 167 168 func TestBinaryString(t *testing.T) { 169 expectedItems := []item{ 170 {itemKey, "foo", 1, 0}, 171 {itemString, "e", 1, 9}, 172 {itemEOF, "", 1, 0}, 173 } 174 lx := lex("foo = \\x65") 175 expect(t, lx, expectedItems) 176 } 177 178 func TestBinaryStringLatin1(t *testing.T) { 179 expectedItems := []item{ 180 {itemKey, "foo", 1, 0}, 181 {itemString, "\xe9", 1, 9}, 182 {itemEOF, "", 1, 0}, 183 } 184 lx := lex("foo = \\xe9") 185 expect(t, lx, expectedItems) 186 } 187 188 func TestSimpleKeyIntegerValues(t *testing.T) { 189 expectedItems := []item{ 190 {itemKey, "foo", 1, 0}, 191 {itemInteger, "123", 1, 6}, 192 {itemEOF, "", 1, 0}, 193 } 194 lx := lex("foo = 123") 195 expect(t, lx, expectedItems) 196 197 expectedItems = []item{ 198 {itemKey, "foo", 1, 0}, 199 {itemInteger, "123", 1, 4}, 200 {itemEOF, "", 1, 0}, 201 } 202 lx = lex("foo=123") 203 expect(t, lx, expectedItems) 204 lx = lex("foo=123\r\n") 205 expect(t, lx, expectedItems) 206 } 207 208 func TestSimpleKeyNegativeIntegerValues(t *testing.T) { 209 expectedItems := []item{ 210 {itemKey, "foo", 1, 0}, 211 {itemInteger, "-123", 1, 6}, 212 {itemEOF, "", 1, 0}, 213 } 214 lx := lex("foo = -123") 215 expect(t, lx, expectedItems) 216 217 expectedItems = []item{ 218 {itemKey, "foo", 1, 0}, 219 {itemInteger, "-123", 1, 4}, 220 {itemEOF, "", 1, 0}, 221 } 222 lx = lex("foo=-123") 223 expect(t, lx, expectedItems) 224 lx = lex("foo=-123\r\n") 225 expect(t, lx, expectedItems) 226 } 227 228 func TestConvenientIntegerValues(t *testing.T) { 229 expectedItems := []item{ 230 {itemKey, "foo", 1, 0}, 231 {itemInteger, "1k", 1, 6}, 232 {itemEOF, "", 1, 0}, 233 } 234 lx := lex("foo = 1k") 235 expect(t, lx, expectedItems) 236 237 expectedItems = []item{ 238 {itemKey, "foo", 1, 0}, 239 {itemInteger, "1K", 1, 6}, 240 {itemEOF, "", 1, 0}, 241 } 242 lx = lex("foo = 1K") 243 expect(t, lx, expectedItems) 244 245 expectedItems = []item{ 246 {itemKey, "foo", 1, 0}, 247 {itemInteger, "1m", 1, 6}, 248 {itemEOF, "", 1, 0}, 249 } 250 lx = lex("foo = 1m") 251 expect(t, lx, expectedItems) 252 253 expectedItems = []item{ 254 {itemKey, "foo", 1, 0}, 255 {itemInteger, "1M", 1, 6}, 256 {itemEOF, "", 1, 0}, 257 } 258 lx = lex("foo = 1M") 259 expect(t, lx, expectedItems) 260 261 expectedItems = []item{ 262 {itemKey, "foo", 1, 0}, 263 {itemInteger, "1g", 1, 6}, 264 {itemEOF, "", 1, 0}, 265 } 266 lx = lex("foo = 1g") 267 expect(t, lx, expectedItems) 268 269 expectedItems = []item{ 270 {itemKey, "foo", 1, 0}, 271 {itemInteger, "1G", 1, 6}, 272 {itemEOF, "", 1, 0}, 273 } 274 lx = lex("foo = 1G") 275 expect(t, lx, expectedItems) 276 277 expectedItems = []item{ 278 {itemKey, "foo", 1, 0}, 279 {itemInteger, "1MB", 1, 6}, 280 {itemEOF, "", 1, 0}, 281 } 282 lx = lex("foo = 1MB") 283 expect(t, lx, expectedItems) 284 285 expectedItems = []item{ 286 {itemKey, "foo", 1, 0}, 287 {itemInteger, "1Gb", 1, 6}, 288 {itemEOF, "", 1, 0}, 289 } 290 lx = lex("foo = 1Gb") 291 expect(t, lx, expectedItems) 292 293 // Negative versions 294 expectedItems = []item{ 295 {itemKey, "foo", 1, 0}, 296 {itemInteger, "-1m", 1, 6}, 297 {itemEOF, "", 1, 0}, 298 } 299 lx = lex("foo = -1m") 300 expect(t, lx, expectedItems) 301 302 expectedItems = []item{ 303 {itemKey, "foo", 1, 0}, 304 {itemInteger, "-1GB", 1, 6}, 305 {itemEOF, "", 1, 0}, 306 } 307 lx = lex("foo = -1GB ") 308 expect(t, lx, expectedItems) 309 310 expectedItems = []item{ 311 {itemKey, "foo", 1, 0}, 312 {itemString, "1Ghz", 1, 6}, 313 {itemEOF, "", 1, 0}, 314 } 315 lx = lex("foo = 1Ghz") 316 expect(t, lx, expectedItems) 317 318 expectedItems = []item{ 319 {itemKey, "foo", 1, 0}, 320 {itemString, "2Pie", 1, 6}, 321 {itemEOF, "", 1, 0}, 322 } 323 lx = lex("foo = 2Pie") 324 expect(t, lx, expectedItems) 325 326 expectedItems = []item{ 327 {itemKey, "foo", 1, 0}, 328 {itemString, "3Mbs", 1, 6}, 329 {itemEOF, "", 1, 0}, 330 } 331 lx = lex("foo = 3Mbs,") 332 expect(t, lx, expectedItems) 333 334 expectedItems = []item{ 335 {itemKey, "foo", 1, 0}, 336 {itemInteger, "4Gb", 1, 6}, 337 {itemKey, "bar", 1, 11}, 338 {itemString, "5Gø", 1, 17}, 339 {itemEOF, "", 1, 0}, 340 } 341 lx = lex("foo = 4Gb, bar = 5Gø") 342 expect(t, lx, expectedItems) 343 } 344 345 func TestSimpleKeyFloatValues(t *testing.T) { 346 expectedItems := []item{ 347 {itemKey, "foo", 1, 0}, 348 {itemFloat, "22.2", 1, 6}, 349 {itemEOF, "", 1, 0}, 350 } 351 lx := lex("foo = 22.2") 352 expect(t, lx, expectedItems) 353 354 expectedItems = []item{ 355 {itemKey, "foo", 1, 0}, 356 {itemFloat, "22.2", 1, 4}, 357 {itemEOF, "", 1, 0}, 358 } 359 lx = lex("foo=22.2") 360 expect(t, lx, expectedItems) 361 lx = lex("foo=22.2\r\n") 362 expect(t, lx, expectedItems) 363 } 364 365 func TestBadBinaryStringEndingAfterZeroHexChars(t *testing.T) { 366 expectedItems := []item{ 367 {itemKey, "foo", 1, 0}, 368 {itemError, "Expected two hexadecimal digits after '\\x', but hit end of line", 2, 1}, 369 {itemEOF, "", 1, 0}, 370 } 371 lx := lex("foo = xyz\\x\n") 372 expect(t, lx, expectedItems) 373 } 374 375 func TestBadBinaryStringEndingAfterOneHexChar(t *testing.T) { 376 expectedItems := []item{ 377 {itemKey, "foo", 1, 0}, 378 {itemError, "Expected two hexadecimal digits after '\\x', but hit end of line", 2, 1}, 379 {itemEOF, "", 1, 0}, 380 } 381 lx := lex("foo = xyz\\xF\n") 382 expect(t, lx, expectedItems) 383 } 384 385 func TestBadBinaryStringWithZeroHexChars(t *testing.T) { 386 expectedItems := []item{ 387 {itemKey, "foo", 1, 0}, 388 {itemError, "Expected two hexadecimal digits after '\\x', but got ']\"'", 1, 12}, 389 {itemEOF, "", 1, 0}, 390 } 391 lx := lex(`foo = "[\x]"`) 392 expect(t, lx, expectedItems) 393 } 394 395 func TestBadBinaryStringWithOneHexChar(t *testing.T) { 396 expectedItems := []item{ 397 {itemKey, "foo", 1, 0}, 398 {itemError, "Expected two hexadecimal digits after '\\x', but got 'e]'", 1, 12}, 399 {itemEOF, "", 1, 0}, 400 } 401 lx := lex(`foo = "[\xe]"`) 402 expect(t, lx, expectedItems) 403 } 404 405 func TestBadFloatValues(t *testing.T) { 406 expectedItems := []item{ 407 {itemKey, "foo", 1, 0}, 408 {itemError, "Floats must start with a digit", 1, 7}, 409 {itemEOF, "", 1, 0}, 410 } 411 lx := lex("foo = .2") 412 expect(t, lx, expectedItems) 413 } 414 415 func TestBadKey(t *testing.T) { 416 expectedItems := []item{ 417 {itemError, "Unexpected key separator ':'", 1, 1}, 418 {itemEOF, "", 1, 0}, 419 } 420 lx := lex(" :foo = 22") 421 expect(t, lx, expectedItems) 422 } 423 424 func TestSimpleKeyBoolValues(t *testing.T) { 425 expectedItems := []item{ 426 {itemKey, "foo", 1, 0}, 427 {itemBool, "true", 1, 6}, 428 {itemEOF, "", 1, 0}, 429 } 430 lx := lex("foo = true") 431 expect(t, lx, expectedItems) 432 433 expectedItems = []item{ 434 {itemKey, "foo", 1, 0}, 435 {itemBool, "true", 1, 4}, 436 {itemEOF, "", 1, 0}, 437 } 438 lx = lex("foo=true") 439 expect(t, lx, expectedItems) 440 lx = lex("foo=true\r\n") 441 expect(t, lx, expectedItems) 442 } 443 444 func TestComments(t *testing.T) { 445 expectedItems := []item{ 446 {itemCommentStart, "", 1, 1}, 447 {itemText, " This is a comment", 1, 1}, 448 {itemEOF, "", 1, 0}, 449 } 450 lx := lex("# This is a comment") 451 expect(t, lx, expectedItems) 452 lx = lex("# This is a comment\r\n") 453 expect(t, lx, expectedItems) 454 455 expectedItems = []item{ 456 {itemCommentStart, "", 1, 2}, 457 {itemText, " This is a comment", 1, 2}, 458 {itemEOF, "", 1, 0}, 459 } 460 lx = lex("// This is a comment\r\n") 461 expect(t, lx, expectedItems) 462 } 463 464 func TestTopValuesWithComments(t *testing.T) { 465 expectedItems := []item{ 466 {itemKey, "foo", 1, 0}, 467 {itemInteger, "123", 1, 6}, 468 {itemCommentStart, "", 1, 12}, 469 {itemText, " This is a comment", 1, 12}, 470 {itemEOF, "", 1, 0}, 471 } 472 473 lx := lex("foo = 123 // This is a comment") 474 expect(t, lx, expectedItems) 475 476 expectedItems = []item{ 477 {itemKey, "foo", 1, 0}, 478 {itemInteger, "123", 1, 4}, 479 {itemCommentStart, "", 1, 12}, 480 {itemText, " This is a comment", 1, 12}, 481 {itemEOF, "", 1, 0}, 482 } 483 lx = lex("foo=123 # This is a comment") 484 expect(t, lx, expectedItems) 485 } 486 487 func TestRawString(t *testing.T) { 488 expectedItems := []item{ 489 {itemKey, "foo", 1, 0}, 490 {itemString, "bar", 1, 6}, 491 {itemEOF, "", 1, 0}, 492 } 493 lx := lex("foo = bar") 494 expect(t, lx, expectedItems) 495 lx = lex(`foo = bar' `) 496 expect(t, lx, expectedItems) 497 } 498 499 func TestDateValues(t *testing.T) { 500 expectedItems := []item{ 501 {itemKey, "foo", 1, 0}, 502 {itemDatetime, "2016-05-04T18:53:41Z", 1, 6}, 503 {itemEOF, "", 1, 0}, 504 } 505 506 lx := lex("foo = 2016-05-04T18:53:41Z") 507 expect(t, lx, expectedItems) 508 } 509 510 func TestVariableValues(t *testing.T) { 511 expectedItems := []item{ 512 {itemKey, "foo", 1, 0}, 513 {itemVariable, "bar", 1, 7}, 514 {itemEOF, "", 1, 0}, 515 } 516 lx := lex("foo = $bar") 517 expect(t, lx, expectedItems) 518 519 expectedItems = []item{ 520 {itemKey, "foo", 1, 0}, 521 {itemVariable, "bar", 1, 6}, 522 {itemEOF, "", 1, 0}, 523 } 524 lx = lex("foo =$bar") 525 expect(t, lx, expectedItems) 526 527 expectedItems = []item{ 528 {itemKey, "foo", 1, 0}, 529 {itemVariable, "bar", 1, 5}, 530 {itemEOF, "", 1, 0}, 531 } 532 lx = lex("foo $bar") 533 expect(t, lx, expectedItems) 534 } 535 536 func TestArrays(t *testing.T) { 537 expectedItems := []item{ 538 {itemKey, "foo", 1, 0}, 539 {itemArrayStart, "", 1, 7}, 540 {itemInteger, "1", 1, 7}, 541 {itemInteger, "2", 1, 10}, 542 {itemInteger, "3", 1, 13}, 543 {itemString, "bar", 1, 17}, 544 {itemArrayEnd, "", 1, 22}, 545 {itemEOF, "", 1, 0}, 546 } 547 lx := lex("foo = [1, 2, 3, 'bar']") 548 expect(t, lx, expectedItems) 549 550 expectedItems = []item{ 551 {itemKey, "foo", 1, 0}, 552 {itemArrayStart, "", 1, 7}, 553 {itemInteger, "1", 1, 7}, 554 {itemInteger, "2", 1, 9}, 555 {itemInteger, "3", 1, 11}, 556 {itemString, "bar", 1, 14}, 557 {itemArrayEnd, "", 1, 19}, 558 {itemEOF, "", 1, 0}, 559 } 560 lx = lex("foo = [1,2,3,'bar']") 561 expect(t, lx, expectedItems) 562 563 expectedItems = []item{ 564 {itemKey, "foo", 1, 0}, 565 {itemArrayStart, "", 1, 7}, 566 {itemInteger, "1", 1, 7}, 567 {itemInteger, "2", 1, 10}, 568 {itemInteger, "3", 1, 12}, 569 {itemString, "bar", 1, 15}, 570 {itemArrayEnd, "", 1, 20}, 571 {itemEOF, "", 1, 0}, 572 } 573 lx = lex("foo = [1, 2,3,'bar']") 574 expect(t, lx, expectedItems) 575 } 576 577 var mlArray = ` 578 # top level comment 579 foo = [ 580 1, # One 581 2, // Two 582 3 # Three 583 'bar' , 584 "bar" 585 ] 586 ` 587 588 func TestMultilineArrays(t *testing.T) { 589 expectedItems := []item{ 590 {itemCommentStart, "", 2, 2}, 591 {itemText, " top level comment", 2, 2}, 592 {itemKey, "foo", 3, 1}, 593 {itemArrayStart, "", 3, 8}, 594 {itemInteger, "1", 4, 2}, 595 {itemCommentStart, "", 4, 6}, 596 {itemText, " One", 4, 6}, 597 {itemInteger, "2", 5, 2}, 598 {itemCommentStart, "", 5, 7}, 599 {itemText, " Two", 5, 7}, 600 {itemInteger, "3", 6, 2}, 601 {itemCommentStart, "", 6, 5}, 602 {itemText, " Three", 6, 5}, 603 {itemString, "bar", 7, 3}, 604 {itemString, "bar", 8, 3}, 605 {itemArrayEnd, "", 9, 2}, 606 {itemEOF, "", 9, 0}, 607 } 608 lx := lex(mlArray) 609 expect(t, lx, expectedItems) 610 } 611 612 var mlArrayNoSep = ` 613 # top level comment 614 foo = [ 615 1 // foo 616 2 617 3 618 'bar' 619 "bar" 620 ] 621 ` 622 623 func TestMultilineArraysNoSep(t *testing.T) { 624 expectedItems := []item{ 625 {itemCommentStart, "", 2, 2}, 626 {itemText, " top level comment", 2, 2}, 627 {itemKey, "foo", 3, 1}, 628 {itemArrayStart, "", 3, 8}, 629 {itemInteger, "1", 4, 2}, 630 {itemCommentStart, "", 4, 6}, 631 {itemText, " foo", 4, 6}, 632 {itemInteger, "2", 5, 2}, 633 {itemInteger, "3", 6, 2}, 634 {itemString, "bar", 7, 3}, 635 {itemString, "bar", 8, 3}, 636 {itemArrayEnd, "", 9, 2}, 637 {itemEOF, "", 9, 0}, 638 } 639 lx := lex(mlArrayNoSep) 640 expect(t, lx, expectedItems) 641 } 642 643 func TestSimpleMap(t *testing.T) { 644 expectedItems := []item{ 645 {itemKey, "foo", 1, 0}, 646 {itemMapStart, "", 1, 7}, 647 {itemKey, "ip", 1, 7}, 648 {itemString, "127.0.0.1", 1, 11}, 649 {itemKey, "port", 1, 23}, 650 {itemInteger, "4242", 1, 30}, 651 {itemMapEnd, "", 1, 35}, 652 {itemEOF, "", 1, 0}, 653 } 654 655 lx := lex("foo = {ip='127.0.0.1', port = 4242}") 656 expect(t, lx, expectedItems) 657 } 658 659 var mlMap = ` 660 foo = { 661 ip = '127.0.0.1' # the IP 662 port= 4242 // the port 663 } 664 ` 665 666 func TestMultilineMap(t *testing.T) { 667 expectedItems := []item{ 668 {itemKey, "foo", 2, 1}, 669 {itemMapStart, "", 2, 8}, 670 {itemKey, "ip", 3, 3}, 671 {itemString, "127.0.0.1", 3, 9}, 672 {itemCommentStart, "", 3, 21}, 673 {itemText, " the IP", 3, 21}, 674 {itemKey, "port", 4, 3}, 675 {itemInteger, "4242", 4, 9}, 676 {itemCommentStart, "", 4, 16}, 677 {itemText, " the port", 4, 16}, 678 {itemMapEnd, "", 5, 2}, 679 {itemEOF, "", 5, 0}, 680 } 681 682 lx := lex(mlMap) 683 expect(t, lx, expectedItems) 684 } 685 686 var nestedMap = ` 687 foo = { 688 host = { 689 ip = '127.0.0.1' 690 port= 4242 691 } 692 } 693 ` 694 695 func TestNestedMaps(t *testing.T) { 696 expectedItems := []item{ 697 {itemKey, "foo", 2, 1}, 698 {itemMapStart, "", 2, 8}, 699 {itemKey, "host", 3, 3}, 700 {itemMapStart, "", 3, 11}, 701 {itemKey, "ip", 4, 5}, 702 {itemString, "127.0.0.1", 4, 11}, 703 {itemKey, "port", 5, 5}, 704 {itemInteger, "4242", 5, 11}, 705 {itemMapEnd, "", 6, 4}, 706 {itemMapEnd, "", 7, 2}, 707 {itemEOF, "", 7, 0}, 708 } 709 710 lx := lex(nestedMap) 711 expect(t, lx, expectedItems) 712 } 713 714 func TestQuotedKeys(t *testing.T) { 715 expectedItems := []item{ 716 {itemKey, "foo", 1, 0}, 717 {itemInteger, "123", 1, 6}, 718 {itemEOF, "", 1, 0}, 719 } 720 lx := lex("foo : 123") 721 expect(t, lx, expectedItems) 722 723 expectedItems = []item{ 724 {itemKey, "foo", 1, 1}, 725 {itemInteger, "123", 1, 8}, 726 {itemEOF, "", 1, 0}, 727 } 728 lx = lex("'foo' : 123") 729 expect(t, lx, expectedItems) 730 lx = lex("\"foo\" : 123") 731 expect(t, lx, expectedItems) 732 } 733 734 func TestQuotedKeysWithSpace(t *testing.T) { 735 expectedItems := []item{ 736 {itemKey, " foo", 1, 1}, 737 {itemInteger, "123", 1, 9}, 738 {itemEOF, "", 1, 0}, 739 } 740 lx := lex("' foo' : 123") 741 expect(t, lx, expectedItems) 742 743 expectedItems = []item{ 744 {itemKey, " foo", 1, 1}, 745 {itemInteger, "123", 1, 9}, 746 {itemEOF, "", 1, 0}, 747 } 748 lx = lex("\" foo\" : 123") 749 expect(t, lx, expectedItems) 750 } 751 752 func TestColonKeySep(t *testing.T) { 753 expectedItems := []item{ 754 {itemKey, "foo", 1, 0}, 755 {itemInteger, "123", 1, 6}, 756 {itemEOF, "", 1, 0}, 757 } 758 lx := lex("foo : 123") 759 expect(t, lx, expectedItems) 760 761 expectedItems = []item{ 762 {itemKey, "foo", 1, 0}, 763 {itemInteger, "123", 1, 4}, 764 {itemEOF, "", 1, 0}, 765 } 766 lx = lex("foo:123") 767 expect(t, lx, expectedItems) 768 769 expectedItems = []item{ 770 {itemKey, "foo", 1, 0}, 771 {itemInteger, "123", 1, 5}, 772 {itemEOF, "", 1, 0}, 773 } 774 lx = lex("foo: 123") 775 expect(t, lx, expectedItems) 776 777 expectedItems = []item{ 778 {itemKey, "foo", 1, 0}, 779 {itemInteger, "123", 1, 6}, 780 {itemEOF, "", 1, 0}, 781 } 782 lx = lex("foo: 123\r\n") 783 expect(t, lx, expectedItems) 784 } 785 786 func TestWhitespaceKeySep(t *testing.T) { 787 expectedItems := []item{ 788 {itemKey, "foo", 1, 0}, 789 {itemInteger, "123", 1, 4}, 790 {itemEOF, "", 1, 0}, 791 } 792 lx := lex("foo 123") 793 expect(t, lx, expectedItems) 794 lx = lex("foo 123") 795 expect(t, lx, expectedItems) 796 lx = lex("foo\t123") 797 expect(t, lx, expectedItems) 798 expectedItems = []item{ 799 {itemKey, "foo", 1, 0}, 800 {itemInteger, "123", 1, 5}, 801 {itemEOF, "", 1, 0}, 802 } 803 lx = lex("foo\t\t123\r\n") 804 expect(t, lx, expectedItems) 805 } 806 807 var escString = ` 808 foo = \t 809 bar = \r 810 baz = \n 811 q = \" 812 bs = \\ 813 ` 814 815 func TestEscapedString(t *testing.T) { 816 expectedItems := []item{ 817 {itemKey, "foo", 2, 1}, 818 {itemString, "\t", 2, 9}, 819 {itemKey, "bar", 3, 1}, 820 {itemString, "\r", 3, 9}, 821 {itemKey, "baz", 4, 1}, 822 {itemString, "\n", 4, 9}, 823 {itemKey, "q", 5, 1}, 824 {itemString, "\"", 5, 9}, 825 {itemKey, "bs", 6, 1}, 826 {itemString, "\\", 6, 9}, 827 {itemEOF, "", 6, 0}, 828 } 829 lx := lex(escString) 830 expect(t, lx, expectedItems) 831 } 832 833 func TestCompoundStringES(t *testing.T) { 834 expectedItems := []item{ 835 {itemKey, "foo", 1, 0}, 836 {itemString, "\\end", 1, 8}, 837 {itemEOF, "", 2, 0}, 838 } 839 lx := lex(`foo = "\\end"`) 840 expect(t, lx, expectedItems) 841 } 842 843 func TestCompoundStringSE(t *testing.T) { 844 expectedItems := []item{ 845 {itemKey, "foo", 1, 0}, 846 {itemString, "start\\", 1, 8}, 847 {itemEOF, "", 2, 0}, 848 } 849 lx := lex(`foo = "start\\"`) 850 expect(t, lx, expectedItems) 851 } 852 853 func TestCompoundStringEE(t *testing.T) { 854 expectedItems := []item{ 855 {itemKey, "foo", 1, 0}, 856 {itemString, "Eq", 1, 12}, 857 {itemEOF, "", 2, 0}, 858 } 859 lx := lex(`foo = \x45\x71`) 860 expect(t, lx, expectedItems) 861 } 862 863 func TestCompoundStringSEE(t *testing.T) { 864 expectedItems := []item{ 865 {itemKey, "foo", 1, 0}, 866 {itemString, "startEq", 1, 12}, 867 {itemEOF, "", 2, 0}, 868 } 869 lx := lex(`foo = start\x45\x71`) 870 expect(t, lx, expectedItems) 871 } 872 873 func TestCompoundStringSES(t *testing.T) { 874 expectedItems := []item{ 875 {itemKey, "foo", 1, 0}, 876 {itemString, "start|end", 1, 9}, 877 {itemEOF, "", 2, 0}, 878 } 879 lx := lex(`foo = start\x7Cend`) 880 expect(t, lx, expectedItems) 881 } 882 883 func TestCompoundStringEES(t *testing.T) { 884 expectedItems := []item{ 885 {itemKey, "foo", 1, 0}, 886 {itemString, "<>end", 1, 12}, 887 {itemEOF, "", 2, 0}, 888 } 889 lx := lex(`foo = \x3c\x3eend`) 890 expect(t, lx, expectedItems) 891 } 892 893 func TestCompoundStringESE(t *testing.T) { 894 expectedItems := []item{ 895 {itemKey, "foo", 1, 0}, 896 {itemString, "<middle>", 1, 12}, 897 {itemEOF, "", 2, 0}, 898 } 899 lx := lex(`foo = \x3cmiddle\x3E`) 900 expect(t, lx, expectedItems) 901 } 902 903 func TestBadStringEscape(t *testing.T) { 904 expectedItems := []item{ 905 {itemKey, "foo", 1, 0}, 906 {itemError, "Invalid escape character 'y'. Only the following escape characters are allowed: \\xXX, \\t, \\n, \\r, \\\", \\\\.", 1, 8}, 907 {itemEOF, "", 2, 0}, 908 } 909 lx := lex(`foo = \y`) 910 expect(t, lx, expectedItems) 911 } 912 913 func TestNonBool(t *testing.T) { 914 expectedItems := []item{ 915 {itemKey, "foo", 1, 0}, 916 {itemString, "\\true", 1, 7}, 917 {itemEOF, "", 2, 0}, 918 } 919 lx := lex(`foo = \\true`) 920 expect(t, lx, expectedItems) 921 } 922 923 func TestNonVariable(t *testing.T) { 924 expectedItems := []item{ 925 {itemKey, "foo", 1, 0}, 926 {itemString, "\\$var", 1, 7}, 927 {itemEOF, "", 2, 0}, 928 } 929 lx := lex(`foo = \\$var`) 930 expect(t, lx, expectedItems) 931 } 932 933 func TestEmptyStringDQ(t *testing.T) { 934 expectedItems := []item{ 935 {itemKey, "foo", 1, 0}, 936 {itemString, "", 1, 7}, 937 {itemEOF, "", 2, 0}, 938 } 939 lx := lex(`foo = ""`) 940 expect(t, lx, expectedItems) 941 } 942 943 func TestEmptyStringSQ(t *testing.T) { 944 expectedItems := []item{ 945 {itemKey, "foo", 1, 0}, 946 {itemString, "", 1, 7}, 947 {itemEOF, "", 2, 0}, 948 } 949 lx := lex(`foo = ''`) 950 expect(t, lx, expectedItems) 951 } 952 953 var nestedWhitespaceMap = ` 954 foo { 955 host { 956 ip = '127.0.0.1' 957 port= 4242 958 } 959 } 960 ` 961 962 func TestNestedWhitespaceMaps(t *testing.T) { 963 expectedItems := []item{ 964 {itemKey, "foo", 2, 1}, 965 {itemMapStart, "", 2, 7}, 966 {itemKey, "host", 3, 3}, 967 {itemMapStart, "", 3, 10}, 968 {itemKey, "ip", 4, 5}, 969 {itemString, "127.0.0.1", 4, 11}, 970 {itemKey, "port", 5, 5}, 971 {itemInteger, "4242", 5, 11}, 972 {itemMapEnd, "", 6, 4}, 973 {itemMapEnd, "", 7, 2}, 974 {itemEOF, "", 7, 0}, 975 } 976 977 lx := lex(nestedWhitespaceMap) 978 expect(t, lx, expectedItems) 979 } 980 981 var semicolons = ` 982 foo = 123; 983 bar = 'baz'; 984 baz = 'boo' 985 map { 986 id = 1; 987 } 988 ` 989 990 func TestOptionalSemicolons(t *testing.T) { 991 expectedItems := []item{ 992 {itemKey, "foo", 2, 1}, 993 {itemInteger, "123", 2, 7}, 994 {itemKey, "bar", 3, 1}, 995 {itemString, "baz", 3, 8}, 996 {itemKey, "baz", 4, 1}, 997 {itemString, "boo", 4, 8}, 998 {itemKey, "map", 5, 1}, 999 {itemMapStart, "", 5, 6}, 1000 {itemKey, "id", 6, 2}, 1001 {itemInteger, "1", 6, 7}, 1002 {itemMapEnd, "", 7, 2}, 1003 {itemEOF, "", 8, 0}, 1004 } 1005 1006 lx := lex(semicolons) 1007 expect(t, lx, expectedItems) 1008 } 1009 1010 func TestSemicolonChaining(t *testing.T) { 1011 expectedItems := []item{ 1012 {itemKey, "foo", 1, 0}, 1013 {itemString, "1", 1, 5}, 1014 {itemKey, "bar", 1, 9}, 1015 {itemFloat, "2.2", 1, 13}, 1016 {itemKey, "baz", 1, 18}, 1017 {itemBool, "true", 1, 22}, 1018 {itemEOF, "", 1, 0}, 1019 } 1020 1021 lx := lex("foo='1'; bar=2.2; baz=true;") 1022 expect(t, lx, expectedItems) 1023 } 1024 1025 var noquotes = ` 1026 foo = 123 1027 bar = baz 1028 baz=boo 1029 map { 1030 id:one 1031 id2 : onetwo 1032 } 1033 t true 1034 f false 1035 tstr "true" 1036 tkey = two 1037 fkey = five # This should be a string 1038 ` 1039 1040 func TestNonQuotedStrings(t *testing.T) { 1041 expectedItems := []item{ 1042 {itemKey, "foo", 2, 1}, 1043 {itemInteger, "123", 2, 7}, 1044 {itemKey, "bar", 3, 1}, 1045 {itemString, "baz", 3, 7}, 1046 {itemKey, "baz", 4, 1}, 1047 {itemString, "boo", 4, 5}, 1048 {itemKey, "map", 5, 1}, 1049 {itemMapStart, "", 5, 6}, 1050 {itemKey, "id", 6, 2}, 1051 {itemString, "one", 6, 5}, 1052 {itemKey, "id2", 7, 2}, 1053 {itemString, "onetwo", 7, 8}, 1054 {itemMapEnd, "", 8, 2}, 1055 {itemKey, "t", 9, 1}, 1056 {itemBool, "true", 9, 3}, 1057 {itemKey, "f", 10, 1}, 1058 {itemBool, "false", 10, 3}, 1059 {itemKey, "tstr", 11, 1}, 1060 {itemString, "true", 11, 7}, 1061 {itemKey, "tkey", 12, 1}, 1062 {itemString, "two", 12, 8}, 1063 {itemKey, "fkey", 13, 1}, 1064 {itemString, "five", 13, 8}, 1065 {itemCommentStart, "", 13, 14}, 1066 {itemText, " This should be a string", 13, 14}, 1067 {itemEOF, "", 14, 0}, 1068 } 1069 lx := lex(noquotes) 1070 expect(t, lx, expectedItems) 1071 } 1072 1073 var danglingquote = ` 1074 listen: "localhost:4242 1075 1076 http: localhost:8222 1077 ` 1078 1079 func TestDanglingQuotedString(t *testing.T) { 1080 expectedItems := []item{ 1081 {itemKey, "listen", 2, 1}, 1082 {itemError, "Unexpected EOF.", 5, 1}, 1083 } 1084 lx := lex(danglingquote) 1085 expect(t, lx, expectedItems) 1086 } 1087 1088 var keydanglingquote = ` 1089 foo = " 1090 listen: " 1091 1092 http: localhost:8222 1093 1094 " 1095 ` 1096 1097 func TestKeyDanglingQuotedString(t *testing.T) { 1098 expectedItems := []item{ 1099 {itemKey, "foo", 2, 1}, 1100 {itemString, "\nlisten: ", 3, 8}, 1101 {itemKey, "http", 5, 1}, 1102 {itemString, "localhost:8222", 5, 7}, 1103 {itemError, "Unexpected EOF.", 8, 1}, 1104 } 1105 lx := lex(keydanglingquote) 1106 expect(t, lx, expectedItems) 1107 } 1108 1109 var danglingsquote = ` 1110 listen: 'localhost:4242 1111 1112 http: localhost:8222 1113 ` 1114 1115 func TestDanglingSingleQuotedString(t *testing.T) { 1116 expectedItems := []item{ 1117 {itemKey, "listen", 2, 1}, 1118 {itemError, "Unexpected EOF.", 5, 1}, 1119 } 1120 lx := lex(danglingsquote) 1121 expect(t, lx, expectedItems) 1122 } 1123 1124 var keydanglingsquote = ` 1125 foo = ' 1126 listen: ' 1127 1128 http: localhost:8222 1129 1130 ' 1131 ` 1132 1133 func TestKeyDanglingSingleQuotedString(t *testing.T) { 1134 expectedItems := []item{ 1135 {itemKey, "foo", 2, 1}, 1136 {itemString, "\nlisten: ", 3, 8}, 1137 {itemKey, "http", 5, 1}, 1138 {itemString, "localhost:8222", 5, 7}, 1139 {itemError, "Unexpected EOF.", 8, 1}, 1140 } 1141 lx := lex(keydanglingsquote) 1142 expect(t, lx, expectedItems) 1143 } 1144 1145 var mapdanglingbracket = ` 1146 listen = 4222 1147 1148 cluster = { 1149 1150 foo = bar 1151 1152 ` 1153 1154 func TestMapDanglingBracket(t *testing.T) { 1155 expectedItems := []item{ 1156 {itemKey, "listen", 2, 1}, 1157 {itemInteger, "4222", 2, 10}, 1158 {itemKey, "cluster", 4, 1}, 1159 {itemMapStart, "", 4, 12}, 1160 {itemKey, "foo", 6, 3}, 1161 {itemString, "bar", 6, 9}, 1162 {itemError, "Unexpected EOF processing map.", 8, 1}, 1163 } 1164 lx := lex(mapdanglingbracket) 1165 expect(t, lx, expectedItems) 1166 } 1167 1168 var blockdanglingparens = ` 1169 listen = 4222 1170 1171 quote = ( 1172 1173 foo = bar 1174 1175 ` 1176 1177 func TestBlockDanglingParens(t *testing.T) { 1178 expectedItems := []item{ 1179 {itemKey, "listen", 2, 1}, 1180 {itemInteger, "4222", 2, 10}, 1181 {itemKey, "quote", 4, 1}, 1182 {itemError, "Unexpected EOF processing block.", 8, 1}, 1183 } 1184 lx := lex(blockdanglingparens) 1185 expect(t, lx, expectedItems) 1186 } 1187 1188 func TestMapQuotedKeys(t *testing.T) { 1189 expectedItems := []item{ 1190 {itemKey, "foo", 1, 0}, 1191 {itemMapStart, "", 1, 7}, 1192 {itemKey, "bar", 1, 8}, 1193 {itemInteger, "4242", 1, 15}, 1194 {itemMapEnd, "", 1, 20}, 1195 {itemEOF, "", 1, 0}, 1196 } 1197 lx := lex("foo = {'bar' = 4242}") 1198 expect(t, lx, expectedItems) 1199 lx = lex("foo = {\"bar\" = 4242}") 1200 expect(t, lx, expectedItems) 1201 } 1202 1203 func TestSpecialCharsMapQuotedKeys(t *testing.T) { 1204 expectedItems := []item{ 1205 {itemKey, "foo", 1, 0}, 1206 {itemMapStart, "", 1, 7}, 1207 {itemKey, "bar-1.2.3", 1, 8}, 1208 {itemMapStart, "", 1, 22}, 1209 {itemKey, "port", 1, 23}, 1210 {itemInteger, "4242", 1, 28}, 1211 {itemMapEnd, "", 1, 34}, 1212 {itemMapEnd, "", 1, 35}, 1213 {itemEOF, "", 1, 0}, 1214 } 1215 lx := lex("foo = {'bar-1.2.3' = { port:4242 }}") 1216 expect(t, lx, expectedItems) 1217 lx = lex("foo = {\"bar-1.2.3\" = { port:4242 }}") 1218 expect(t, lx, expectedItems) 1219 } 1220 1221 var mlnestedmap = ` 1222 systems { 1223 allinone { 1224 description: "This is a description." 1225 } 1226 } 1227 ` 1228 1229 func TestDoubleNestedMapsNewLines(t *testing.T) { 1230 expectedItems := []item{ 1231 {itemKey, "systems", 2, 1}, 1232 {itemMapStart, "", 2, 10}, 1233 {itemKey, "allinone", 3, 3}, 1234 {itemMapStart, "", 3, 13}, 1235 {itemKey, "description", 4, 5}, 1236 {itemString, "This is a description.", 4, 19}, 1237 {itemMapEnd, "", 5, 4}, 1238 {itemMapEnd, "", 6, 2}, 1239 {itemEOF, "", 7, 0}, 1240 } 1241 lx := lex(mlnestedmap) 1242 expect(t, lx, expectedItems) 1243 } 1244 1245 var blockexample = ` 1246 numbers ( 1247 1234567890 1248 ) 1249 ` 1250 1251 func TestBlockString(t *testing.T) { 1252 expectedItems := []item{ 1253 {itemKey, "numbers", 2, 1}, 1254 {itemString, "\n1234567890\n", 4, 10}, 1255 } 1256 lx := lex(blockexample) 1257 expect(t, lx, expectedItems) 1258 } 1259 1260 func TestBlockStringEOF(t *testing.T) { 1261 expectedItems := []item{ 1262 {itemKey, "numbers", 2, 1}, 1263 {itemString, "\n1234567890\n", 4, 10}, 1264 } 1265 blockbytes := []byte(blockexample[0 : len(blockexample)-1]) 1266 blockbytes = append(blockbytes, 0) 1267 lx := lex(string(blockbytes)) 1268 expect(t, lx, expectedItems) 1269 } 1270 1271 var mlblockexample = ` 1272 numbers ( 1273 12(34)56 1274 ( 1275 7890 1276 ) 1277 ) 1278 ` 1279 1280 func TestBlockStringMultiLine(t *testing.T) { 1281 expectedItems := []item{ 1282 {itemKey, "numbers", 2, 1}, 1283 {itemString, "\n 12(34)56\n (\n 7890\n )\n", 7, 10}, 1284 } 1285 lx := lex(mlblockexample) 1286 expect(t, lx, expectedItems) 1287 } 1288 1289 func TestUnquotedIPAddr(t *testing.T) { 1290 expectedItems := []item{ 1291 {itemKey, "listen", 1, 0}, 1292 {itemString, "127.0.0.1:4222", 1, 8}, 1293 {itemEOF, "", 1, 0}, 1294 } 1295 lx := lex("listen: 127.0.0.1:4222") 1296 expect(t, lx, expectedItems) 1297 1298 expectedItems = []item{ 1299 {itemKey, "listen", 1, 0}, 1300 {itemString, "127.0.0.1", 1, 8}, 1301 {itemEOF, "", 1, 0}, 1302 } 1303 lx = lex("listen: 127.0.0.1") 1304 expect(t, lx, expectedItems) 1305 1306 expectedItems = []item{ 1307 {itemKey, "listen", 1, 0}, 1308 {itemString, "apcera.me:80", 1, 8}, 1309 {itemEOF, "", 1, 0}, 1310 } 1311 lx = lex("listen: apcera.me:80") 1312 expect(t, lx, expectedItems) 1313 1314 expectedItems = []item{ 1315 {itemKey, "listen", 1, 0}, 1316 {itemString, "nats.io:-1", 1, 8}, 1317 {itemEOF, "", 1, 0}, 1318 } 1319 lx = lex("listen: nats.io:-1") 1320 expect(t, lx, expectedItems) 1321 1322 expectedItems = []item{ 1323 {itemKey, "listen", 1, 0}, 1324 {itemInteger, "-1", 1, 8}, 1325 {itemEOF, "", 1, 0}, 1326 } 1327 lx = lex("listen: -1") 1328 expect(t, lx, expectedItems) 1329 1330 expectedItems = []item{ 1331 {itemKey, "listen", 1, 0}, 1332 {itemString, ":-1", 1, 8}, 1333 {itemEOF, "", 1, 0}, 1334 } 1335 lx = lex("listen: :-1") 1336 expect(t, lx, expectedItems) 1337 1338 expectedItems = []item{ 1339 {itemKey, "listen", 1, 0}, 1340 {itemString, ":80", 1, 9}, 1341 {itemEOF, "", 1, 0}, 1342 } 1343 lx = lex("listen = :80") 1344 expect(t, lx, expectedItems) 1345 1346 expectedItems = []item{ 1347 {itemKey, "listen", 1, 0}, 1348 {itemArrayStart, "", 1, 10}, 1349 {itemString, "localhost:4222", 1, 10}, 1350 {itemString, "localhost:4333", 1, 26}, 1351 {itemArrayEnd, "", 1, 41}, 1352 {itemEOF, "", 1, 0}, 1353 } 1354 lx = lex("listen = [localhost:4222, localhost:4333]") 1355 expect(t, lx, expectedItems) 1356 } 1357 1358 var arrayOfMaps = ` 1359 authorization { 1360 users = [ 1361 {user: alice, password: foo} 1362 {user: bob, password: bar} 1363 ] 1364 timeout: 0.5 1365 } 1366 ` 1367 1368 func TestArrayOfMaps(t *testing.T) { 1369 expectedItems := []item{ 1370 {itemKey, "authorization", 2, 1}, 1371 {itemMapStart, "", 2, 16}, 1372 {itemKey, "users", 3, 5}, 1373 {itemArrayStart, "", 3, 14}, 1374 {itemMapStart, "", 4, 8}, 1375 {itemKey, "user", 4, 8}, 1376 {itemString, "alice", 4, 14}, 1377 {itemKey, "password", 4, 21}, 1378 {itemString, "foo", 4, 31}, 1379 {itemMapEnd, "", 4, 35}, 1380 {itemMapStart, "", 5, 8}, 1381 {itemKey, "user", 5, 8}, 1382 {itemString, "bob", 5, 14}, 1383 {itemKey, "password", 5, 21}, 1384 {itemString, "bar", 5, 31}, 1385 {itemMapEnd, "", 5, 35}, 1386 {itemArrayEnd, "", 6, 6}, 1387 {itemKey, "timeout", 7, 5}, 1388 {itemFloat, "0.5", 7, 14}, 1389 {itemMapEnd, "", 8, 2}, 1390 {itemEOF, "", 9, 0}, 1391 } 1392 lx := lex(arrayOfMaps) 1393 expect(t, lx, expectedItems) 1394 } 1395 1396 func TestInclude(t *testing.T) { 1397 expectedItems := []item{ 1398 {itemInclude, "users.conf", 1, 9}, 1399 {itemEOF, "", 1, 0}, 1400 } 1401 lx := lex("include \"users.conf\"") 1402 expect(t, lx, expectedItems) 1403 1404 lx = lex("include 'users.conf'") 1405 expect(t, lx, expectedItems) 1406 1407 expectedItems = []item{ 1408 {itemInclude, "users.conf", 1, 8}, 1409 {itemEOF, "", 1, 0}, 1410 } 1411 lx = lex("include users.conf") 1412 expect(t, lx, expectedItems) 1413 } 1414 1415 func TestMapInclude(t *testing.T) { 1416 expectedItems := []item{ 1417 {itemKey, "foo", 1, 0}, 1418 {itemMapStart, "", 1, 5}, 1419 {itemInclude, "users.conf", 1, 14}, 1420 {itemMapEnd, "", 1, 26}, 1421 {itemEOF, "", 1, 0}, 1422 } 1423 1424 lx := lex("foo { include users.conf }") 1425 expect(t, lx, expectedItems) 1426 1427 expectedItems = []item{ 1428 {itemKey, "foo", 1, 0}, 1429 {itemMapStart, "", 1, 5}, 1430 {itemInclude, "users.conf", 1, 13}, 1431 {itemMapEnd, "", 1, 24}, 1432 {itemEOF, "", 1, 0}, 1433 } 1434 lx = lex("foo {include users.conf}") 1435 expect(t, lx, expectedItems) 1436 1437 expectedItems = []item{ 1438 {itemKey, "foo", 1, 0}, 1439 {itemMapStart, "", 1, 5}, 1440 {itemInclude, "users.conf", 1, 15}, 1441 {itemMapEnd, "", 1, 28}, 1442 {itemEOF, "", 1, 0}, 1443 } 1444 lx = lex("foo { include 'users.conf' }") 1445 expect(t, lx, expectedItems) 1446 1447 expectedItems = []item{ 1448 {itemKey, "foo", 1, 0}, 1449 {itemMapStart, "", 1, 5}, 1450 {itemInclude, "users.conf", 1, 15}, 1451 {itemMapEnd, "", 1, 27}, 1452 {itemEOF, "", 1, 0}, 1453 } 1454 lx = lex("foo { include \"users.conf\"}") 1455 expect(t, lx, expectedItems) 1456 } 1457 1458 func TestJSONCompat(t *testing.T) { 1459 for _, test := range []struct { 1460 name string 1461 input string 1462 expected []item 1463 }{ 1464 { 1465 name: "should omit initial and final brackets at top level with a single item", 1466 input: ` 1467 { 1468 "http_port": 8223 1469 } 1470 `, 1471 expected: []item{ 1472 {itemKey, "http_port", 3, 28}, 1473 {itemInteger, "8223", 3, 40}, 1474 {itemKey, "}", 4, 25}, 1475 {itemEOF, "", 0, 0}, 1476 }, 1477 }, 1478 { 1479 name: "should omit trailing commas at top level with two items", 1480 input: ` 1481 { 1482 "http_port": 8223, 1483 "port": 4223 1484 } 1485 `, 1486 expected: []item{ 1487 {itemKey, "http_port", 3, 28}, 1488 {itemInteger, "8223", 3, 40}, 1489 {itemKey, "port", 4, 28}, 1490 {itemInteger, "4223", 4, 35}, 1491 {itemKey, "}", 5, 25}, 1492 {itemEOF, "", 0, 0}, 1493 }, 1494 }, 1495 { 1496 name: "should omit trailing commas at top level with multiple items", 1497 input: ` 1498 { 1499 "http_port": 8223, 1500 "port": 4223, 1501 "max_payload": "5MB", 1502 "debug": true, 1503 "max_control_line": 1024 1504 } 1505 `, 1506 expected: []item{ 1507 {itemKey, "http_port", 3, 28}, 1508 {itemInteger, "8223", 3, 40}, 1509 {itemKey, "port", 4, 28}, 1510 {itemInteger, "4223", 4, 35}, 1511 {itemKey, "max_payload", 5, 28}, 1512 {itemString, "5MB", 5, 43}, 1513 {itemKey, "debug", 6, 28}, 1514 {itemBool, "true", 6, 36}, 1515 {itemKey, "max_control_line", 7, 28}, 1516 {itemInteger, "1024", 7, 47}, 1517 {itemKey, "}", 8, 25}, 1518 {itemEOF, "", 0, 0}, 1519 }, 1520 }, 1521 { 1522 name: "should support JSON not prettified", 1523 input: `{"http_port": 8224,"port": 4224} 1524 `, 1525 expected: []item{ 1526 {itemKey, "http_port", 1, 2}, 1527 {itemInteger, "8224", 1, 14}, 1528 {itemKey, "port", 1, 20}, 1529 {itemInteger, "4224", 1, 27}, 1530 {itemEOF, "", 0, 0}, 1531 }, 1532 }, 1533 { 1534 name: "should support JSON not prettified with final bracket after newline", 1535 input: `{"http_port": 8225,"port": 4225 1536 } 1537 `, 1538 expected: []item{ 1539 {itemKey, "http_port", 1, 2}, 1540 {itemInteger, "8225", 1, 14}, 1541 {itemKey, "port", 1, 20}, 1542 {itemInteger, "4225", 1, 27}, 1543 {itemKey, "}", 2, 25}, 1544 {itemEOF, "", 0, 0}, 1545 }, 1546 }, 1547 { 1548 name: "should support uglified JSON with inner blocks", 1549 input: `{"http_port": 8227,"port": 4227,"write_deadline": "1h","cluster": {"port": 6222,"routes": ["nats://127.0.0.1:4222","nats://127.0.0.1:4223","nats://127.0.0.1:4224"]}} 1550 `, 1551 expected: []item{ 1552 {itemKey, "http_port", 1, 2}, 1553 {itemInteger, "8227", 1, 14}, 1554 {itemKey, "port", 1, 20}, 1555 {itemInteger, "4227", 1, 27}, 1556 {itemKey, "write_deadline", 1, 33}, 1557 {itemString, "1h", 1, 51}, 1558 {itemKey, "cluster", 1, 56}, 1559 {itemMapStart, "", 1, 67}, 1560 {itemKey, "port", 1, 68}, 1561 {itemInteger, "6222", 1, 75}, 1562 {itemKey, "routes", 1, 81}, 1563 {itemArrayStart, "", 1, 91}, 1564 {itemString, "nats://127.0.0.1:4222", 1, 92}, 1565 {itemString, "nats://127.0.0.1:4223", 1, 116}, 1566 {itemString, "nats://127.0.0.1:4224", 1, 140}, 1567 {itemArrayEnd, "", 1, 163}, 1568 {itemMapEnd, "", 1, 164}, 1569 {itemKey, "}", 14, 25}, 1570 {itemEOF, "", 0, 0}, 1571 }, 1572 }, 1573 { 1574 name: "should support prettified JSON with inner blocks", 1575 input: ` 1576 { 1577 "http_port": 8227, 1578 "port": 4227, 1579 "write_deadline": "1h", 1580 "cluster": { 1581 "port": 6222, 1582 "routes": [ 1583 "nats://127.0.0.1:4222", 1584 "nats://127.0.0.1:4223", 1585 "nats://127.0.0.1:4224" 1586 ] 1587 } 1588 } 1589 `, 1590 expected: []item{ 1591 {itemKey, "http_port", 3, 28}, 1592 {itemInteger, "8227", 3, 40}, 1593 {itemKey, "port", 4, 28}, 1594 {itemInteger, "4227", 4, 35}, 1595 {itemKey, "write_deadline", 5, 28}, 1596 {itemString, "1h", 5, 46}, 1597 {itemKey, "cluster", 6, 28}, 1598 {itemMapStart, "", 6, 39}, 1599 {itemKey, "port", 7, 30}, 1600 {itemInteger, "6222", 7, 37}, 1601 {itemKey, "routes", 8, 30}, 1602 {itemArrayStart, "", 8, 40}, 1603 {itemString, "nats://127.0.0.1:4222", 9, 32}, 1604 {itemString, "nats://127.0.0.1:4223", 10, 32}, 1605 {itemString, "nats://127.0.0.1:4224", 11, 32}, 1606 {itemArrayEnd, "", 12, 30}, 1607 {itemMapEnd, "", 13, 28}, 1608 {itemKey, "}", 14, 25}, 1609 {itemEOF, "", 0, 0}, 1610 }, 1611 }, 1612 { 1613 name: "should support JSON with blocks", 1614 input: `{ 1615 "jetstream": { 1616 "store_dir": "/tmp/nats" 1617 "max_mem": 1000000, 1618 }, 1619 "port": 4222, 1620 "server_name": "nats1" 1621 } 1622 `, 1623 expected: []item{ 1624 {itemKey, "jetstream", 2, 28}, 1625 {itemMapStart, "", 2, 41}, 1626 {itemKey, "store_dir", 3, 30}, 1627 {itemString, "/tmp/nats", 3, 43}, 1628 {itemKey, "max_mem", 4, 30}, 1629 {itemInteger, "1000000", 4, 40}, 1630 {itemMapEnd, "", 5, 28}, 1631 {itemKey, "port", 6, 28}, 1632 {itemInteger, "4222", 6, 35}, 1633 {itemKey, "server_name", 7, 28}, 1634 {itemString, "nats1", 7, 43}, 1635 {itemKey, "}", 8, 25}, 1636 {itemEOF, "", 0, 0}, 1637 }, 1638 }, 1639 } { 1640 t.Run(test.name, func(t *testing.T) { 1641 lx := lex(test.input) 1642 expect(t, lx, test.expected) 1643 }) 1644 } 1645 }