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