github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/pkg/dbc/parser_test.go (about) 1 package dbc 2 3 import ( 4 "io/ioutil" 5 "os" 6 "strings" 7 "testing" 8 "text/scanner" 9 10 "github.com/davecgh/go-spew/spew" 11 "gotest.tools/v3/assert" 12 ) 13 14 func shouldUpdateGoldenFiles() bool { 15 return os.Getenv("GOLDEN") == "true" 16 } 17 18 func TestParse_ExampleDBC(t *testing.T) { 19 const inputFile = "../../testdata/dbc/example/example.dbc" 20 const goldenFile = "../../testdata/dbc/example/example.dbc.golden" 21 data, err := ioutil.ReadFile(inputFile) 22 assert.NilError(t, err) 23 p := NewParser(inputFile, data) 24 assert.NilError(t, p.Parse()) 25 if shouldUpdateGoldenFiles() { 26 assert.NilError(t, ioutil.WriteFile(goldenFile, []byte(dump(p.Defs())), 0600)) 27 } 28 goldenFileData, err := ioutil.ReadFile(goldenFile) 29 assert.NilError(t, err) 30 assert.Equal(t, string(goldenFileData), dump(p.Defs())) 31 } 32 33 func TestParser_Parse(t *testing.T) { 34 for _, tt := range []struct { 35 name string 36 text string 37 defs []Def 38 }{ 39 { 40 name: "version.dbc", 41 text: `VERSION "foo"`, 42 defs: []Def{ 43 &VersionDef{ 44 Pos: scanner.Position{ 45 Filename: "version.dbc", 46 Line: 1, 47 Column: 1, 48 }, 49 Version: "foo", 50 }, 51 }, 52 }, 53 54 { 55 name: "multiple_version.dbc", 56 text: strings.Join([]string{ 57 `VERSION "foo"`, 58 `VERSION "bar"`, 59 }, "\n"), 60 defs: []Def{ 61 &VersionDef{ 62 Pos: scanner.Position{ 63 Filename: "multiple_version.dbc", 64 Line: 1, 65 Column: 1, 66 }, 67 Version: "foo", 68 }, 69 &VersionDef{ 70 Pos: scanner.Position{ 71 Filename: "multiple_version.dbc", 72 Line: 2, 73 Column: 1, 74 Offset: 14, 75 }, 76 Version: "bar", 77 }, 78 }, 79 }, 80 81 { 82 name: "no_bus_speed.dbc", 83 text: `BS_:`, 84 defs: []Def{ 85 &BitTimingDef{ 86 Pos: scanner.Position{ 87 Filename: "no_bus_speed.dbc", 88 Line: 1, 89 Column: 1, 90 }, 91 }, 92 }, 93 }, 94 95 { 96 name: "bus_speed.dbc", 97 text: `BS_: 250000`, 98 defs: []Def{ 99 &BitTimingDef{ 100 Pos: scanner.Position{ 101 Filename: "bus_speed.dbc", 102 Line: 1, 103 Column: 1, 104 }, 105 BaudRate: 250000, 106 }, 107 }, 108 }, 109 110 { 111 name: "symbols.dbc", 112 text: strings.Join([]string{ 113 "NS_ :", 114 "NS_DESC_", 115 "CM_", 116 "BA_DEF_", 117 "BA_", 118 "VAL_", 119 }, "\n\t"), 120 defs: []Def{ 121 &NewSymbolsDef{ 122 Pos: scanner.Position{ 123 Filename: "symbols.dbc", 124 Line: 1, 125 Column: 1, 126 }, 127 Symbols: []Keyword{ 128 "NS_DESC_", 129 "CM_", 130 "BA_DEF_", 131 "BA_", 132 "VAL_", 133 }, 134 }, 135 }, 136 }, 137 138 { 139 name: "standard_message.dbc", 140 text: "BO_ 804 CRUISE: 8 PCM", 141 defs: []Def{ 142 &MessageDef{ 143 Pos: scanner.Position{ 144 Filename: "standard_message.dbc", 145 Line: 1, 146 Column: 1, 147 }, 148 Name: "CRUISE", 149 MessageID: 804, 150 Size: 8, 151 Transmitter: "PCM", 152 }, 153 }, 154 }, 155 156 { 157 name: "extended_message.dbc", 158 text: "BO_ 2566857412 BMS2_4: 8 Vector__XXX", 159 defs: []Def{ 160 &MessageDef{ 161 Pos: scanner.Position{ 162 Filename: "extended_message.dbc", 163 Line: 1, 164 Column: 1, 165 }, 166 Name: "BMS2_4", 167 MessageID: 2566857412, 168 Size: 8, 169 Transmitter: "Vector__XXX", 170 }, 171 }, 172 }, 173 174 { 175 name: "signal.dbc", 176 text: `SG_ CellTempLowest : 32|8@0+ (1,-40) [-40|215] "C" Vector__XXX`, 177 defs: []Def{ 178 &SignalDef{ 179 Pos: scanner.Position{ 180 Filename: "signal.dbc", 181 Line: 1, 182 Column: 1, 183 }, 184 Name: "CellTempLowest", 185 StartBit: 32, 186 Size: 8, 187 IsBigEndian: true, 188 Factor: 1, 189 Offset: -40, 190 Minimum: -40, 191 Maximum: 215, 192 Unit: "C", 193 Receivers: []Identifier{"Vector__XXX"}, 194 }, 195 }, 196 }, 197 198 { 199 name: "multiplexer_signal.dbc", 200 text: `SG_ TestSignal M : 56|8@1+ (0.001,0) [0|0.255] "l/mm" XXX`, 201 defs: []Def{ 202 &SignalDef{ 203 Pos: scanner.Position{ 204 Filename: "multiplexer_signal.dbc", 205 Line: 1, 206 Column: 1, 207 }, 208 Name: "TestSignal", 209 StartBit: 56, 210 Size: 8, 211 Factor: 0.001, 212 Offset: 0, 213 Minimum: 0, 214 Maximum: 0.255, 215 Unit: "l/mm", 216 Receivers: []Identifier{"XXX"}, 217 IsMultiplexerSwitch: true, 218 }, 219 }, 220 }, 221 222 { 223 name: "multiplexed_signal.dbc", 224 text: `SG_ TestSignal m2 : 56|8@1+ (0.001,0) [0|0.255] "l/mm" XXX`, 225 defs: []Def{ 226 &SignalDef{ 227 Pos: scanner.Position{ 228 Filename: "multiplexed_signal.dbc", 229 Line: 1, 230 Column: 1, 231 }, 232 Name: "TestSignal", 233 StartBit: 56, 234 Size: 8, 235 Factor: 0.001, 236 Offset: 0, 237 Minimum: 0, 238 Maximum: 0.255, 239 Unit: "l/mm", 240 Receivers: []Identifier{"XXX"}, 241 IsMultiplexed: true, 242 MultiplexerSwitch: 2, 243 }, 244 }, 245 }, 246 247 { 248 name: "comment.dbc", 249 text: `CM_ "comment";`, 250 defs: []Def{ 251 &CommentDef{ 252 Pos: scanner.Position{ 253 Filename: "comment.dbc", 254 Line: 1, 255 Column: 1, 256 }, 257 Comment: "comment", 258 }, 259 }, 260 }, 261 262 { 263 name: "node_comment.dbc", 264 text: `CM_ BU_ NodeName "node comment";`, 265 defs: []Def{ 266 &CommentDef{ 267 Pos: scanner.Position{ 268 Filename: "node_comment.dbc", 269 Line: 1, 270 Column: 1, 271 }, 272 ObjectType: ObjectTypeNetworkNode, 273 NodeName: "NodeName", 274 Comment: "node comment", 275 }, 276 }, 277 }, 278 279 { 280 name: "message_comment.dbc", 281 text: `CM_ BO_ 1234 "message comment";`, 282 defs: []Def{ 283 &CommentDef{ 284 Pos: scanner.Position{ 285 Filename: "message_comment.dbc", 286 Line: 1, 287 Column: 1, 288 }, 289 ObjectType: ObjectTypeMessage, 290 MessageID: 1234, 291 Comment: "message comment", 292 }, 293 }, 294 }, 295 296 { 297 name: "signal_comment.dbc", 298 text: `CM_ SG_ 1234 SignalName "signal comment";`, 299 defs: []Def{ 300 &CommentDef{ 301 Pos: scanner.Position{ 302 Filename: "signal_comment.dbc", 303 Line: 1, 304 Column: 1, 305 }, 306 ObjectType: ObjectTypeSignal, 307 MessageID: 1234, 308 SignalName: "SignalName", 309 Comment: "signal comment", 310 }, 311 }, 312 }, 313 314 { 315 name: "int_attribute_definition.dbc", 316 text: `BA_DEF_ "AttributeName" INT 5 10;`, 317 defs: []Def{ 318 &AttributeDef{ 319 Pos: scanner.Position{ 320 Filename: "int_attribute_definition.dbc", 321 Line: 1, 322 Column: 1, 323 }, 324 Name: "AttributeName", 325 Type: AttributeValueTypeInt, 326 MinimumInt: 5, 327 MaximumInt: 10, 328 }, 329 }, 330 }, 331 332 { 333 name: "int_attribute_definition_no_min_or_max.dbc", 334 text: `BA_DEF_ "AttributeName" INT;`, 335 defs: []Def{ 336 &AttributeDef{ 337 Pos: scanner.Position{ 338 Filename: "int_attribute_definition_no_min_or_max.dbc", 339 Line: 1, 340 Column: 1, 341 }, 342 Name: "AttributeName", 343 Type: AttributeValueTypeInt, 344 }, 345 }, 346 }, 347 348 { 349 name: "float_attribute_definition.dbc", 350 text: `BA_DEF_ "AttributeName" FLOAT 0.5 1.5;`, 351 defs: []Def{ 352 &AttributeDef{ 353 Pos: scanner.Position{ 354 Filename: "float_attribute_definition.dbc", 355 Line: 1, 356 Column: 1, 357 }, 358 Name: "AttributeName", 359 Type: AttributeValueTypeFloat, 360 MinimumFloat: 0.5, 361 MaximumFloat: 1.5, 362 }, 363 }, 364 }, 365 366 { 367 name: "float_attribute_definition_no_min_or_max.dbc", 368 text: `BA_DEF_ "AttributeName" FLOAT;`, 369 defs: []Def{ 370 &AttributeDef{ 371 Pos: scanner.Position{ 372 Filename: "float_attribute_definition_no_min_or_max.dbc", 373 Line: 1, 374 Column: 1, 375 }, 376 Name: "AttributeName", 377 Type: AttributeValueTypeFloat, 378 }, 379 }, 380 }, 381 382 { 383 name: "string_attribute.dbc", 384 text: `BA_DEF_ "AttributeName" STRING;`, 385 defs: []Def{ 386 &AttributeDef{ 387 Pos: scanner.Position{ 388 Filename: "string_attribute.dbc", 389 Line: 1, 390 Column: 1, 391 }, 392 Name: "AttributeName", 393 Type: AttributeValueTypeString, 394 }, 395 }, 396 }, 397 398 { 399 name: "enum_attribute.dbc", 400 text: `BA_DEF_ "AttributeName" ENUM "value1","value2";`, 401 defs: []Def{ 402 &AttributeDef{ 403 Pos: scanner.Position{ 404 Filename: "enum_attribute.dbc", 405 Line: 1, 406 Column: 1, 407 }, 408 Name: "AttributeName", 409 Type: AttributeValueTypeEnum, 410 EnumValues: []string{"value1", "value2"}, 411 }, 412 }, 413 }, 414 415 { 416 name: "enum_attribute_for_messages.dbc", 417 text: `BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";`, 418 defs: []Def{ 419 &AttributeDef{ 420 Pos: scanner.Position{ 421 Filename: "enum_attribute_for_messages.dbc", 422 Line: 1, 423 Column: 1, 424 }, 425 Name: "VFrameFormat", 426 ObjectType: ObjectTypeMessage, 427 Type: AttributeValueTypeEnum, 428 EnumValues: []string{"StandardCAN", "ExtendedCAN", "reserved", "J1939PG"}, 429 }, 430 }, 431 }, 432 433 { 434 name: "attribute_default_string.dbc", 435 text: strings.Join([]string{ 436 `BA_DEF_ "Foo" STRING;`, 437 `BA_DEF_DEF_ "Foo" "string value";`, 438 }, "\n"), 439 defs: []Def{ 440 &AttributeDef{ 441 Pos: scanner.Position{ 442 Filename: "attribute_default_string.dbc", 443 Line: 1, 444 Column: 1, 445 }, 446 Name: "Foo", 447 Type: AttributeValueTypeString, 448 }, 449 &AttributeDefaultValueDef{ 450 Pos: scanner.Position{ 451 Filename: "attribute_default_string.dbc", 452 Line: 2, 453 Column: 1, 454 Offset: 22, 455 }, 456 AttributeName: "Foo", 457 DefaultStringValue: "string value", 458 }, 459 }, 460 }, 461 462 { 463 name: "attribute_default_int.dbc", 464 text: strings.Join([]string{ 465 `BA_DEF_ "Foo" INT 0 200;`, 466 `BA_DEF_DEF_ "Foo" 100;`, 467 }, "\n"), 468 defs: []Def{ 469 &AttributeDef{ 470 Pos: scanner.Position{ 471 Filename: "attribute_default_int.dbc", 472 Line: 1, 473 Column: 1, 474 }, 475 Name: "Foo", 476 Type: AttributeValueTypeInt, 477 MinimumInt: 0, 478 MaximumInt: 200, 479 }, 480 &AttributeDefaultValueDef{ 481 Pos: scanner.Position{ 482 Filename: "attribute_default_int.dbc", 483 Line: 2, 484 Column: 1, 485 Offset: 25, 486 }, 487 AttributeName: "Foo", 488 DefaultIntValue: 100, 489 }, 490 }, 491 }, 492 493 { 494 name: "attribute_default_float.dbc", 495 text: strings.Join([]string{ 496 `BA_DEF_ "Foo" FLOAT 0.5 200.5;`, 497 `BA_DEF_DEF_ "Foo" 100.5;`, 498 }, "\n"), 499 defs: []Def{ 500 &AttributeDef{ 501 Pos: scanner.Position{ 502 Filename: "attribute_default_float.dbc", 503 Line: 1, 504 Column: 1, 505 }, 506 Name: "Foo", 507 Type: AttributeValueTypeFloat, 508 MinimumFloat: 0.5, 509 MaximumFloat: 200.5, 510 }, 511 &AttributeDefaultValueDef{ 512 Pos: scanner.Position{ 513 Filename: "attribute_default_float.dbc", 514 Line: 2, 515 Column: 1, 516 Offset: 31, 517 }, 518 AttributeName: "Foo", 519 DefaultFloatValue: 100.5, 520 }, 521 }, 522 }, 523 524 { 525 name: "attribute_value.dbc", 526 text: strings.Join([]string{ 527 `BA_DEF_ "Foo" FLOAT;`, 528 `BA_ "Foo" 100.5;`, 529 }, "\n"), 530 defs: []Def{ 531 &AttributeDef{ 532 Pos: scanner.Position{ 533 Filename: "attribute_value.dbc", 534 Line: 1, 535 Column: 1, 536 }, 537 Name: "Foo", 538 Type: AttributeValueTypeFloat, 539 }, 540 &AttributeValueForObjectDef{ 541 Pos: scanner.Position{ 542 Filename: "attribute_value.dbc", 543 Line: 2, 544 Column: 1, 545 Offset: 21, 546 }, 547 AttributeName: "Foo", 548 FloatValue: 100.5, 549 }, 550 }, 551 }, 552 553 { 554 name: "negative_attribute_value.dbc", 555 text: strings.Join([]string{ 556 `BA_DEF_ "Foo" INT;`, 557 `BA_ "Foo" -100;`, 558 }, "\n"), 559 defs: []Def{ 560 &AttributeDef{ 561 Pos: scanner.Position{ 562 Filename: "negative_attribute_value.dbc", 563 Line: 1, 564 Column: 1, 565 }, 566 Name: "Foo", 567 Type: AttributeValueTypeInt, 568 }, 569 &AttributeValueForObjectDef{ 570 Pos: scanner.Position{ 571 Filename: "negative_attribute_value.dbc", 572 Line: 2, 573 Column: 1, 574 Offset: 19, 575 }, 576 AttributeName: "Foo", 577 IntValue: -100, 578 }, 579 }, 580 }, 581 582 { 583 name: "node_attribute_value.dbc", 584 text: strings.Join([]string{ 585 `BA_DEF_ "Foo" INT;`, 586 `BA_ "Foo" BU_ TestNode 100;`, 587 }, "\n"), 588 defs: []Def{ 589 &AttributeDef{ 590 Pos: scanner.Position{ 591 Filename: "node_attribute_value.dbc", 592 Line: 1, 593 Column: 1, 594 }, 595 Name: "Foo", 596 Type: AttributeValueTypeInt, 597 }, 598 &AttributeValueForObjectDef{ 599 Pos: scanner.Position{ 600 Filename: "node_attribute_value.dbc", 601 Line: 2, 602 Column: 1, 603 Offset: 19, 604 }, 605 AttributeName: "Foo", 606 ObjectType: ObjectTypeNetworkNode, 607 NodeName: "TestNode", 608 IntValue: 100, 609 }, 610 }, 611 }, 612 613 { 614 name: "message_attribute_value.dbc", 615 text: strings.Join([]string{ 616 `BA_DEF_ "Foo" STRING;`, 617 `BA_ "Foo" BO_ 1234 "string value";`, 618 }, "\n"), 619 defs: []Def{ 620 &AttributeDef{ 621 Pos: scanner.Position{ 622 Filename: "message_attribute_value.dbc", 623 Line: 1, 624 Column: 1, 625 }, 626 Name: "Foo", 627 Type: AttributeValueTypeString, 628 }, 629 &AttributeValueForObjectDef{ 630 Pos: scanner.Position{ 631 Filename: "message_attribute_value.dbc", 632 Line: 2, 633 Column: 1, 634 Offset: 22, 635 }, 636 AttributeName: "Foo", 637 ObjectType: ObjectTypeMessage, 638 MessageID: 1234, 639 StringValue: "string value", 640 }, 641 }, 642 }, 643 644 { 645 name: "signal_attribute_value.dbc", 646 text: strings.Join([]string{ 647 `BA_DEF_ "Foo" STRING;`, 648 `BA_ "Foo" SG_ 1234 SignalName "string value";`, 649 }, "\n"), 650 defs: []Def{ 651 &AttributeDef{ 652 Pos: scanner.Position{ 653 Filename: "signal_attribute_value.dbc", 654 Line: 1, 655 Column: 1, 656 }, 657 Name: "Foo", 658 Type: AttributeValueTypeString, 659 }, 660 &AttributeValueForObjectDef{ 661 Pos: scanner.Position{ 662 Filename: "signal_attribute_value.dbc", 663 Line: 2, 664 Column: 1, 665 Offset: 22, 666 }, 667 AttributeName: "Foo", 668 ObjectType: ObjectTypeSignal, 669 MessageID: 1234, 670 SignalName: "SignalName", 671 StringValue: "string value", 672 }, 673 }, 674 }, 675 676 { 677 name: "enum_attribute_value_by_index.dbc", 678 text: strings.Join([]string{ 679 `BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";`, 680 `BA_ "VFrameFormat" BO_ 1234 3;`, 681 }, "\n"), 682 defs: []Def{ 683 &AttributeDef{ 684 Pos: scanner.Position{ 685 Filename: "enum_attribute_value_by_index.dbc", 686 Line: 1, 687 Column: 1, 688 }, 689 Name: "VFrameFormat", 690 ObjectType: ObjectTypeMessage, 691 Type: AttributeValueTypeEnum, 692 EnumValues: []string{"StandardCAN", "ExtendedCAN", "reserved", "J1939PG"}, 693 }, 694 &AttributeValueForObjectDef{ 695 Pos: scanner.Position{ 696 Filename: "enum_attribute_value_by_index.dbc", 697 Line: 2, 698 Column: 1, 699 Offset: 84, 700 }, 701 AttributeName: "VFrameFormat", 702 ObjectType: ObjectTypeMessage, 703 MessageID: 1234, 704 StringValue: "J1939PG", 705 }, 706 }, 707 }, 708 709 { 710 name: "value_descriptions_for_signal.dbc", 711 text: `VAL_ 3 StW_AnglSens_Id 2 "MUST" 0 "PSBL" 1 "SELF";`, 712 defs: []Def{ 713 &ValueDescriptionsDef{ 714 Pos: scanner.Position{ 715 Filename: "value_descriptions_for_signal.dbc", 716 Line: 1, 717 Column: 1, 718 }, 719 ObjectType: ObjectTypeSignal, 720 MessageID: 3, 721 SignalName: "StW_AnglSens_Id", 722 ValueDescriptions: []ValueDescriptionDef{ 723 { 724 Pos: scanner.Position{ 725 Filename: "value_descriptions_for_signal.dbc", 726 Line: 1, 727 Column: 24, 728 Offset: 23, 729 }, 730 Value: 2, 731 Description: "MUST", 732 }, 733 { 734 Pos: scanner.Position{ 735 Filename: "value_descriptions_for_signal.dbc", 736 Line: 1, 737 Column: 33, 738 Offset: 32, 739 }, 740 Value: 0, 741 Description: "PSBL", 742 }, 743 { 744 Pos: scanner.Position{ 745 Filename: "value_descriptions_for_signal.dbc", 746 Line: 1, 747 Column: 42, 748 Offset: 41, 749 }, 750 Value: 1, 751 Description: "SELF", 752 }, 753 }, 754 }, 755 }, 756 }, 757 758 { 759 name: "value_table.dbc", 760 text: `VAL_TABLE_ DI_gear 7 "DI_GEAR_SNA" 4 "DI_GEAR_D";`, 761 defs: []Def{ 762 &ValueTableDef{ 763 Pos: scanner.Position{ 764 Filename: "value_table.dbc", 765 Line: 1, 766 Column: 1, 767 }, 768 TableName: "DI_gear", 769 ValueDescriptions: []ValueDescriptionDef{ 770 { 771 Pos: scanner.Position{ 772 Filename: "value_table.dbc", 773 Line: 1, 774 Column: 20, 775 Offset: 19, 776 }, 777 Value: 7, 778 Description: "DI_GEAR_SNA", 779 }, 780 { 781 Pos: scanner.Position{ 782 Filename: "value_table.dbc", 783 Line: 1, 784 Column: 36, 785 Offset: 35, 786 }, 787 Value: 4, 788 Description: "DI_GEAR_D", 789 }, 790 }, 791 }, 792 }, 793 }, 794 795 { 796 name: "node_list.dbc", 797 text: `BU_: RSDS`, 798 defs: []Def{ 799 &NodesDef{ 800 Pos: scanner.Position{ 801 Filename: "node_list.dbc", 802 Line: 1, 803 Column: 1, 804 }, 805 NodeNames: []Identifier{"RSDS"}, 806 }, 807 }, 808 }, 809 810 { 811 name: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 812 text: strings.Join([]string{ 813 `BU_: RSDS`, 814 `VAL_TABLE_ TableName 3 "Value3" 2 "Value2" 1 "Value1" 0 "Value0";`, 815 }, "\n"), 816 defs: []Def{ 817 &NodesDef{ 818 Pos: scanner.Position{ 819 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 820 Line: 1, 821 Column: 1, 822 }, 823 NodeNames: []Identifier{"RSDS"}, 824 }, 825 &ValueTableDef{ 826 Pos: scanner.Position{ 827 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 828 Line: 2, 829 Column: 1, 830 Offset: 10, 831 }, 832 TableName: "TableName", 833 ValueDescriptions: []ValueDescriptionDef{ 834 { 835 Pos: scanner.Position{ 836 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 837 Line: 2, 838 Column: 22, 839 Offset: 31, 840 }, 841 Value: 3, 842 Description: "Value3", 843 }, 844 { 845 Pos: scanner.Position{ 846 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 847 Line: 2, 848 Column: 33, 849 Offset: 42, 850 }, 851 Value: 2, 852 Description: "Value2", 853 }, 854 { 855 Pos: scanner.Position{ 856 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 857 Line: 2, 858 Column: 44, 859 Offset: 53, 860 }, 861 Value: 1, 862 Description: "Value1", 863 }, 864 { 865 Pos: scanner.Position{ 866 Filename: "node_list_followed_by_single_newline_followed_by_value_table.dbc", 867 Line: 2, 868 Column: 55, 869 Offset: 64, 870 }, 871 Value: 0, 872 Description: "Value0", 873 }, 874 }, 875 }, 876 }, 877 }, 878 879 { 880 name: "signal_value_type.dbc", 881 text: `SIG_VALTYPE_ 42 TestSignal 2;`, 882 defs: []Def{ 883 &SignalValueTypeDef{ 884 Pos: scanner.Position{ 885 Filename: "signal_value_type.dbc", 886 Line: 1, 887 Column: 1, 888 }, 889 MessageID: 42, 890 SignalName: "TestSignal", 891 SignalValueType: SignalValueTypeFloat64, 892 }, 893 }, 894 }, 895 896 { 897 name: "signal_value_type_with_colon.dbc", 898 text: `SIG_VALTYPE_ 42 TestSignal : 2;`, 899 defs: []Def{ 900 &SignalValueTypeDef{ 901 Pos: scanner.Position{ 902 Filename: "signal_value_type_with_colon.dbc", 903 Line: 1, 904 Column: 1, 905 }, 906 MessageID: 42, 907 SignalName: "TestSignal", 908 SignalValueType: SignalValueTypeFloat64, 909 }, 910 }, 911 }, 912 913 { 914 name: "message_transmitters.dbc", 915 text: `BO_TX_BU_ 42: Node1 Node2;`, 916 defs: []Def{ 917 &MessageTransmittersDef{ 918 Pos: scanner.Position{ 919 Filename: "message_transmitters.dbc", 920 Line: 1, 921 Column: 1, 922 }, 923 MessageID: 42, 924 Transmitters: []Identifier{"Node1", "Node2"}, 925 }, 926 }, 927 }, 928 929 { 930 name: "message_transmitters_comma_separated.dbc", 931 text: `BO_TX_BU_ 42: Node1,Node2;`, 932 defs: []Def{ 933 &MessageTransmittersDef{ 934 Pos: scanner.Position{ 935 Filename: "message_transmitters_comma_separated.dbc", 936 Line: 1, 937 Column: 1, 938 }, 939 MessageID: 42, 940 Transmitters: []Identifier{"Node1", "Node2"}, 941 }, 942 }, 943 }, 944 945 { 946 name: "environment_variable_data.dbc", 947 text: `ENVVAR_DATA_ VariableName: 42;`, 948 defs: []Def{ 949 &EnvironmentVariableDataDef{ 950 Pos: scanner.Position{ 951 Filename: "environment_variable_data.dbc", 952 Line: 1, 953 Column: 1, 954 }, 955 EnvironmentVariableName: "VariableName", 956 DataSize: 42, 957 }, 958 }, 959 }, 960 961 { 962 name: "environment_variable_value_descriptions.dbc", 963 text: `VAL_ VariableName 2 "Value2" 1 "Value1" 0 "Value0";`, 964 defs: []Def{ 965 &ValueDescriptionsDef{ 966 Pos: scanner.Position{ 967 Filename: "environment_variable_value_descriptions.dbc", 968 Line: 1, 969 Column: 1, 970 }, 971 ObjectType: ObjectTypeEnvironmentVariable, 972 EnvironmentVariableName: "VariableName", 973 ValueDescriptions: []ValueDescriptionDef{ 974 { 975 Pos: scanner.Position{ 976 Filename: "environment_variable_value_descriptions.dbc", 977 Line: 1, 978 Column: 19, 979 Offset: 18, 980 }, 981 Value: 2, 982 Description: "Value2", 983 }, 984 { 985 Pos: scanner.Position{ 986 Filename: "environment_variable_value_descriptions.dbc", 987 Line: 1, 988 Column: 30, 989 Offset: 29, 990 }, 991 Value: 1, 992 Description: "Value1", 993 }, 994 { 995 Pos: scanner.Position{ 996 Filename: "environment_variable_value_descriptions.dbc", 997 Line: 1, 998 Column: 41, 999 Offset: 40, 1000 }, 1001 Value: 0, 1002 Description: "Value0", 1003 }, 1004 }, 1005 }, 1006 }, 1007 }, 1008 1009 { 1010 name: "unknown_def.dbc", 1011 text: `FOO_ Bar 2 Baz;`, 1012 defs: []Def{ 1013 &UnknownDef{ 1014 Pos: scanner.Position{ 1015 Filename: "unknown_def.dbc", 1016 Line: 1, 1017 Column: 1, 1018 }, 1019 Keyword: "FOO_", 1020 }, 1021 }, 1022 }, 1023 } { 1024 tt := tt 1025 t.Run(tt.name, func(t *testing.T) { 1026 p := NewParser(tt.name, []byte(tt.text)) 1027 assert.NilError(t, p.Parse()) 1028 assert.DeepEqual(t, tt.defs, p.Defs()) 1029 }) 1030 } 1031 } 1032 1033 func TestParser_Parse_Error(t *testing.T) { 1034 for _, tt := range []struct { 1035 name string 1036 text string 1037 err *parseError 1038 }{ 1039 { 1040 name: "non_string_version.dbc", 1041 text: "VERSION foo", 1042 err: &parseError{ 1043 pos: scanner.Position{ 1044 Filename: "non_string_version.dbc", 1045 Line: 1, 1046 Column: 9, 1047 Offset: 8, 1048 }, 1049 reason: "expected token \"", 1050 }, 1051 }, 1052 { 1053 name: "invalid_utf8.dbc", 1054 text: `VERSION "foo` + string([]byte{0xc3, 0x28}) + `"`, 1055 err: &parseError{ 1056 pos: scanner.Position{ 1057 Filename: "invalid_utf8.dbc", 1058 Line: 1, 1059 Column: 13, 1060 Offset: 12, 1061 }, 1062 reason: "invalid UTF-8 encoding", 1063 }, 1064 }, 1065 } { 1066 tt := tt 1067 t.Run(tt.name, func(t *testing.T) { 1068 p := NewParser(tt.name, []byte(tt.text)) 1069 assert.Error(t, p.Parse(), tt.err.Error()) 1070 }) 1071 } 1072 } 1073 1074 func dump(data interface{}) string { 1075 spewConfig := spew.ConfigState{ 1076 Indent: " ", 1077 DisablePointerAddresses: true, 1078 DisableCapacities: true, 1079 SortKeys: true, 1080 } 1081 return spewConfig.Sdump(data) 1082 }