1# Copyright (C) 2014 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15from common.immutables import ImmutableDict 16from common.testing import ToUnicode 17from file_format.c1visualizer.parser import ParseC1visualizerStream 18from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass 19from file_format.checker.parser import ParseCheckerStream, ParseCheckerStatement 20from file_format.checker.struct import CheckerFile, TestCase, TestStatement 21from match.file import MatchTestCase, MatchFailedException, \ 22 BadStructureException 23from match.line import MatchLines 24 25import io 26import unittest 27 28CheckerException = SystemExit 29 30class MatchLines_Test(unittest.TestCase): 31 32 def createTestStatement(self, checkerString): 33 checkerFile = CheckerFile("<checker-file>") 34 testCase = TestCase(checkerFile, "TestMethod TestPass", 0) 35 return ParseCheckerStatement(testCase, checkerString, TestStatement.Variant.InOrder, 0) 36 37 def tryMatch(self, checkerString, c1String, varState={}): 38 return MatchLines(self.createTestStatement(checkerString), 39 ToUnicode(c1String), 40 ImmutableDict(varState)) 41 42 def assertMatches(self, checkerString, c1String, varState={}): 43 self.assertIsNotNone(self.tryMatch(checkerString, c1String, varState)) 44 45 def assertDoesNotMatch(self, checkerString, c1String, varState={}): 46 self.assertIsNone(self.tryMatch(checkerString, c1String, varState)) 47 48 def test_TextAndWhitespace(self): 49 self.assertMatches("foo", "foo") 50 self.assertMatches("foo", " foo ") 51 self.assertMatches("foo", "foo bar") 52 self.assertDoesNotMatch("foo", "XfooX") 53 self.assertDoesNotMatch("foo", "zoo") 54 55 self.assertMatches("foo bar", "foo bar") 56 self.assertMatches("foo bar", "abc foo bar def") 57 self.assertMatches("foo bar", "foo foo bar bar") 58 59 self.assertMatches("foo bar", "foo X bar") 60 self.assertDoesNotMatch("foo bar", "foo Xbar") 61 62 def test_Pattern(self): 63 self.assertMatches("foo{{A|B}}bar", "fooAbar") 64 self.assertMatches("foo{{A|B}}bar", "fooBbar") 65 self.assertDoesNotMatch("foo{{A|B}}bar", "fooCbar") 66 67 def test_VariableReference(self): 68 self.assertMatches("foo<<X>>bar", "foobar", {"X": ""}) 69 self.assertMatches("foo<<X>>bar", "fooAbar", {"X": "A"}) 70 self.assertMatches("foo<<X>>bar", "fooBbar", {"X": "B"}) 71 self.assertDoesNotMatch("foo<<X>>bar", "foobar", {"X": "A"}) 72 self.assertDoesNotMatch("foo<<X>>bar", "foo bar", {"X": "A"}) 73 with self.assertRaises(CheckerException): 74 self.tryMatch("foo<<X>>bar", "foobar", {}) 75 76 def test_VariableDefinition(self): 77 self.assertMatches("foo<<X:A|B>>bar", "fooAbar") 78 self.assertMatches("foo<<X:A|B>>bar", "fooBbar") 79 self.assertDoesNotMatch("foo<<X:A|B>>bar", "fooCbar") 80 81 env = self.tryMatch("foo<<X:A.*B>>bar", "fooABbar", {}) 82 self.assertEqual(env, {"X": "AB"}) 83 env = self.tryMatch("foo<<X:A.*B>>bar", "fooAxxBbar", {}) 84 self.assertEqual(env, {"X": "AxxB"}) 85 86 self.assertMatches("foo<<X:A|B>>bar<<X>>baz", "fooAbarAbaz") 87 self.assertMatches("foo<<X:A|B>>bar<<X>>baz", "fooBbarBbaz") 88 self.assertDoesNotMatch("foo<<X:A|B>>bar<<X>>baz", "fooAbarBbaz") 89 90 def test_NoVariableRedefinition(self): 91 with self.assertRaises(CheckerException): 92 self.tryMatch("<<X:...>><<X>><<X:...>><<X>>", "foofoobarbar") 93 94 def test_EnvNotChangedOnPartialMatch(self): 95 env = {"Y": "foo"} 96 self.assertDoesNotMatch("<<X:A>>bar", "Abaz", env) 97 self.assertFalse("X" in env.keys()) 98 99 def test_VariableContentEscaped(self): 100 self.assertMatches("<<X:..>>foo<<X>>", ".*foo.*") 101 self.assertDoesNotMatch("<<X:..>>foo<<X>>", ".*fooAAAA") 102 103 104class MatchFiles_Test(unittest.TestCase): 105 106 def assertMatches(self, checkerString, c1String, isa=None, instructionSetFeatures=None): 107 checkerString = \ 108 """ 109 /// CHECK-START: MyMethod MyPass 110 """ + checkerString 111 metaData = "" 112 if isa: 113 metaData += "isa:" + isa 114 115 if instructionSetFeatures: 116 if metaData: 117 metaData += " " 118 119 joinedFeatures = ",".join(map(lambda feature: feature 120 if instructionSetFeatures[feature] 121 else "-" + feature, 122 instructionSetFeatures)) 123 metaData += "isa_features:" + joinedFeatures 124 125 metaDataString = "" 126 if metaData: 127 metaDataString = \ 128 """ 129 begin_compilation 130 name "%s" 131 method "%s" 132 date 1234 133 end_compilation 134 """ % (metaData, metaData) 135 c1String = metaDataString + \ 136 """ 137 begin_compilation 138 name "MyMethod" 139 method "MyMethod" 140 date 1234 141 end_compilation 142 begin_cfg 143 name "MyPass" 144 """ + c1String + \ 145 """ 146 end_cfg 147 """ 148 checkerFile = ParseCheckerStream("<test-file>", "CHECK", io.StringIO(ToUnicode(checkerString))) 149 c1File = ParseC1visualizerStream("<c1-file>", io.StringIO(ToUnicode(c1String))) 150 assert len(checkerFile.testCases) == 1 151 assert len(c1File.passes) == 1 152 MatchTestCase(checkerFile.testCases[0], c1File.passes[0], c1File.instructionSetFeatures) 153 154 def assertDoesNotMatch(self, checkerString, c1String, isa=None, instructionSetFeatures=None): 155 with self.assertRaises(MatchFailedException): 156 self.assertMatches(checkerString, c1String, isa, instructionSetFeatures) 157 158 def assertBadStructure(self, checkerString, c1String): 159 with self.assertRaises(BadStructureException): 160 self.assertMatches(checkerString, c1String) 161 162 def test_Text(self): 163 self.assertMatches("/// CHECK: foo bar", "foo bar") 164 self.assertDoesNotMatch("/// CHECK: foo bar", "abc def") 165 166 def test_Pattern(self): 167 self.assertMatches("/// CHECK: abc {{de.}}", "abc de#") 168 self.assertDoesNotMatch("/// CHECK: abc {{de.}}", "abc d#f") 169 170 def test_Variables(self): 171 self.assertMatches( 172 """ 173 /// CHECK: foo<<X:.>>bar 174 /// CHECK: abc<<X>>def 175 """, 176 """ 177 foo0bar 178 abc0def 179 """) 180 self.assertMatches( 181 """ 182 /// CHECK: foo<<X:([0-9]+)>>bar 183 /// CHECK: abc<<X>>def 184 /// CHECK: ### <<X>> ### 185 """, 186 """ 187 foo1234bar 188 abc1234def 189 ### 1234 ### 190 """) 191 self.assertDoesNotMatch( 192 """ 193 /// CHECK: foo<<X:([0-9]+)>>bar 194 /// CHECK: abc<<X>>def 195 """, 196 """ 197 foo1234bar 198 abc1235def 199 """) 200 201 def test_WholeWordMustMatch(self): 202 self.assertMatches("/// CHECK: b{{.}}r", "abc bar def") 203 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc Xbar def") 204 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc barX def") 205 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc b r def") 206 207 def test_InOrderStatements(self): 208 self.assertMatches( 209 """ 210 /// CHECK: foo 211 /// CHECK: bar 212 """, 213 """ 214 foo 215 bar 216 """) 217 self.assertDoesNotMatch( 218 """ 219 /// CHECK: foo 220 /// CHECK: bar 221 """, 222 """ 223 bar 224 foo 225 """) 226 227 def test_NextLineStatements(self): 228 self.assertMatches( 229 """ 230 /// CHECK: foo 231 /// CHECK-NEXT: bar 232 /// CHECK-NEXT: abc 233 /// CHECK: def 234 """, 235 """ 236 foo 237 bar 238 abc 239 def 240 """) 241 self.assertMatches( 242 """ 243 /// CHECK: foo 244 /// CHECK-NEXT: bar 245 /// CHECK: def 246 """, 247 """ 248 foo 249 bar 250 abc 251 def 252 """) 253 self.assertDoesNotMatch( 254 """ 255 /// CHECK: foo 256 /// CHECK-NEXT: bar 257 """, 258 """ 259 foo 260 abc 261 bar 262 """) 263 264 self.assertDoesNotMatch( 265 """ 266 /// CHECK: foo 267 /// CHECK-NEXT: bar 268 """, 269 """ 270 bar 271 foo 272 abc 273 """) 274 275 def test_DagStatements(self): 276 self.assertMatches( 277 """ 278 /// CHECK-DAG: foo 279 /// CHECK-DAG: bar 280 """, 281 """ 282 foo 283 bar 284 """) 285 self.assertMatches( 286 """ 287 /// CHECK-DAG: foo 288 /// CHECK-DAG: bar 289 """, 290 """ 291 bar 292 foo 293 """) 294 295 def test_DagStatementsScope(self): 296 self.assertMatches( 297 """ 298 /// CHECK: foo 299 /// CHECK-DAG: abc 300 /// CHECK-DAG: def 301 /// CHECK: bar 302 """, 303 """ 304 foo 305 def 306 abc 307 bar 308 """) 309 self.assertDoesNotMatch( 310 """ 311 /// CHECK: foo 312 /// CHECK-DAG: abc 313 /// CHECK-DAG: def 314 /// CHECK: bar 315 """, 316 """ 317 foo 318 abc 319 bar 320 def 321 """) 322 self.assertDoesNotMatch( 323 """ 324 /// CHECK: foo 325 /// CHECK-DAG: abc 326 /// CHECK-DAG: def 327 /// CHECK: bar 328 """, 329 """ 330 foo 331 def 332 bar 333 abc 334 """) 335 336 def test_NotStatements(self): 337 self.assertMatches( 338 """ 339 /// CHECK-NOT: foo 340 """, 341 """ 342 abc 343 def 344 """) 345 self.assertDoesNotMatch( 346 """ 347 /// CHECK-NOT: foo 348 """, 349 """ 350 abc foo 351 def 352 """) 353 self.assertDoesNotMatch( 354 """ 355 /// CHECK-NOT: foo 356 /// CHECK-NOT: bar 357 """, 358 """ 359 abc 360 def bar 361 """) 362 363 def test_NotStatementsScope(self): 364 self.assertMatches( 365 """ 366 /// CHECK: abc 367 /// CHECK-NOT: foo 368 /// CHECK: def 369 """, 370 """ 371 abc 372 def 373 """) 374 self.assertMatches( 375 """ 376 /// CHECK: abc 377 /// CHECK-NOT: foo 378 /// CHECK: def 379 """, 380 """ 381 abc 382 def 383 foo 384 """) 385 self.assertDoesNotMatch( 386 """ 387 /// CHECK: abc 388 /// CHECK-NOT: foo 389 /// CHECK: def 390 """, 391 """ 392 abc 393 foo 394 def 395 """) 396 self.assertDoesNotMatch( 397 """ 398 /// CHECK-NOT: foo 399 /// CHECK-EVAL: 1 + 1 == 2 400 /// CHECK: bar 401 """, 402 """ 403 foo 404 abc 405 bar 406 """); 407 self.assertMatches( 408 """ 409 /// CHECK-DAG: bar 410 /// CHECK-DAG: abc 411 /// CHECK-NOT: foo 412 """, 413 """ 414 foo 415 abc 416 bar 417 """); 418 self.assertDoesNotMatch( 419 """ 420 /// CHECK-DAG: abc 421 /// CHECK-DAG: foo 422 /// CHECK-NOT: bar 423 """, 424 """ 425 foo 426 abc 427 bar 428 """); 429 430 def test_LineOnlyMatchesOnce(self): 431 self.assertMatches( 432 """ 433 /// CHECK-DAG: foo 434 /// CHECK-DAG: foo 435 """, 436 """ 437 foo 438 abc 439 foo 440 """) 441 self.assertDoesNotMatch( 442 """ 443 /// CHECK-DAG: foo 444 /// CHECK-DAG: foo 445 """, 446 """ 447 foo 448 abc 449 bar 450 """) 451 452 def test_EvalStatements(self): 453 self.assertMatches("/// CHECK-EVAL: True", "foo") 454 self.assertDoesNotMatch("/// CHECK-EVAL: False", "foo") 455 456 self.assertMatches("/// CHECK-EVAL: 1 + 2 == 3", "foo") 457 self.assertDoesNotMatch("/// CHECK-EVAL: 1 + 2 == 4", "foo") 458 459 twoVarTestCase = """ 460 /// CHECK-DAG: <<X:\d+>> <<Y:\d+>> 461 /// CHECK-EVAL: <<X>> > <<Y>> 462 """ 463 self.assertMatches(twoVarTestCase, "42 41"); 464 self.assertDoesNotMatch(twoVarTestCase, "42 43") 465 466 def test_MisplacedNext(self): 467 self.assertBadStructure( 468 """ 469 /// CHECK-DAG: foo 470 /// CHECK-NEXT: bar 471 """, 472 """ 473 foo 474 bar 475 """) 476 self.assertBadStructure( 477 """ 478 /// CHECK-NOT: foo 479 /// CHECK-NEXT: bar 480 """, 481 """ 482 foo 483 bar 484 """) 485 self.assertBadStructure( 486 """ 487 /// CHECK-EVAL: True 488 /// CHECK-NEXT: bar 489 """, 490 """ 491 foo 492 bar 493 """) 494 self.assertBadStructure( 495 """ 496 /// CHECK-NEXT: bar 497 """, 498 """ 499 foo 500 bar 501 """) 502 503 def test_EnvVariableEval(self): 504 self.assertMatches( 505 """ 506 /// CHECK-IF: os.environ.get('MARTY_MCFLY') != '89mph!' 507 /// CHECK-FI: 508 """, 509 """ 510 foo 511 """ 512 ) 513 self.assertMatches( 514 """ 515 /// CHECK-EVAL: os.environ.get('MARTY_MCFLY') != '89mph!' 516 """, 517 """ 518 foo 519 """ 520 ) 521 522 def test_IfStatements(self): 523 self.assertMatches( 524 """ 525 /// CHECK: foo1 526 /// CHECK-IF: True 527 /// CHECK-NEXT: foo2 528 /// CHECK-FI: 529 /// CHECK-NEXT: foo3 530 /// CHECK-NEXT: bar 531 """, 532 """ 533 foo1 534 foo2 535 foo3 536 bar 537 """) 538 self.assertMatches( 539 """ 540 /// CHECK: foo1 541 /// CHECK-IF: False 542 /// CHECK-NEXT: foo2 543 /// CHECK-FI: 544 /// CHECK-NEXT: bar 545 """, 546 """ 547 foo1 548 bar 549 """) 550 self.assertMatches( 551 """ 552 /// CHECK: foo1 553 /// CHECK-IF: True 554 /// CHECK-DAG: foo2 555 /// CHECK-FI: 556 /// CHECK-DAG: bar 557 /// CHECK: foo3 558 """, 559 """ 560 foo1 561 bar 562 foo2 563 foo3 564 """) 565 self.assertDoesNotMatch( 566 """ 567 /// CHECK: foo1 568 /// CHECK-IF: False 569 /// CHECK-NEXT: foo2 570 /// CHECK-FI: 571 /// CHECK-NEXT: foo3 572 """, 573 """ 574 foo1 575 foo2 576 foo3 577 """) 578 579 def test_IfElseStatements(self): 580 self.assertMatches( 581 """ 582 /// CHECK: foo1 583 /// CHECK-IF: True 584 /// CHECK-NEXT: foo2 585 /// CHECK-ELSE: 586 /// CHECK-NEXT: foo3 587 /// CHECK-FI: 588 /// CHECK-NEXT: bar 589 """, 590 """ 591 foo1 592 foo2 593 bar 594 """) 595 self.assertMatches( 596 """ 597 /// CHECK: foo1 598 /// CHECK-IF: False 599 /// CHECK-NEXT: foo2 600 /// CHECK-ELSE: 601 /// CHECK-NEXT: foo3 602 /// CHECK-FI: 603 /// CHECK-NEXT: bar 604 """, 605 """ 606 foo1 607 foo3 608 bar 609 """) 610 self.assertMatches( 611 """ 612 /// CHECK: foo1 613 /// CHECK-IF: False 614 /// CHECK-NEXT: foo2 615 /// CHECK-ELSE: 616 /// CHECK-DAG: bar 617 /// CHECK-FI: 618 /// CHECK-DAG: foo3 619 /// CHECK: foo4 620 """, 621 """ 622 foo1 623 foo3 624 bar 625 foo4 626 """) 627 self.assertDoesNotMatch( 628 """ 629 /// CHECK: foo1 630 /// CHECK-IF: False 631 /// CHECK-NEXT: foo2 632 /// CHECK-ELSE: 633 /// CHECK-NEXT: foo3 634 /// CHECK-FI: 635 /// CHECK-NEXT: bar 636 """, 637 """ 638 foo1 639 foo2 640 bar 641 """) 642 643 def test_IfElifElseStatements(self): 644 self.assertMatches( 645 """ 646 /// CHECK: foo1 647 /// CHECK-IF: True 648 /// CHECK-NEXT: foo2 649 /// CHECK-ELIF: True 650 /// CHECK-NEXT: foo3 651 /// CHECK-ELIF: True 652 /// CHECK-NEXT: foo4 653 /// CHECK-FI: 654 /// CHECK-NEXT: bar 655 """, 656 """ 657 foo1 658 foo2 659 bar 660 """) 661 self.assertMatches( 662 """ 663 /// CHECK: foo1 664 /// CHECK-IF: False 665 /// CHECK-NEXT: foo2 666 /// CHECK-ELIF: False 667 /// CHECK-NEXT: foo3 668 /// CHECK-ELIF: True 669 /// CHECK-NEXT: foo4 670 /// CHECK-FI: 671 /// CHECK-NEXT: bar 672 """, 673 """ 674 foo1 675 foo4 676 bar 677 """) 678 self.assertMatches( 679 """ 680 /// CHECK: foo1 681 /// CHECK-IF: False 682 /// CHECK-NEXT: foo2 683 /// CHECK-ELIF: True 684 /// CHECK-NEXT: foo3 685 /// CHECK-ELIF: True 686 /// CHECK-NEXT: foo4 687 /// CHECK-FI: 688 /// CHECK-NEXT: bar 689 """, 690 """ 691 foo1 692 foo3 693 bar 694 """) 695 self.assertMatches( 696 """ 697 /// CHECK: foo1 698 /// CHECK-IF: False 699 /// CHECK-NEXT: foo2 700 /// CHECK-ELIF: False 701 /// CHECK-NEXT: foo3 702 /// CHECK-ELIF: False 703 /// CHECK-NEXT: foo4 704 /// CHECK-FI: 705 /// CHECK-NEXT: bar 706 """, 707 """ 708 foo1 709 bar 710 """) 711 self.assertDoesNotMatch( 712 """ 713 /// CHECK: foo1 714 /// CHECK-IF: False 715 /// CHECK-NEXT: foo2 716 /// CHECK-ELIF: True 717 /// CHECK-NEXT: foo3 718 /// CHECK-ELSE: 719 /// CHECK-NEXT: foo4 720 /// CHECK-FI: 721 /// CHECK-NEXT: bar 722 """, 723 """ 724 foo1 725 foo2 726 bar 727 """) 728 729 def test_NestedBranching(self): 730 self.assertMatches( 731 """ 732 /// CHECK: foo1 733 /// CHECK-IF: True 734 /// CHECK-IF: True 735 /// CHECK-NEXT: foo2 736 /// CHECK-ELSE: 737 /// CHECK-NEXT: foo3 738 /// CHECK-FI: 739 /// CHECK-ELSE: 740 /// CHECK-IF: True 741 /// CHECK-NEXT: foo4 742 /// CHECK-ELSE: 743 /// CHECK-NEXT: foo5 744 /// CHECK-FI: 745 /// CHECK-FI: 746 /// CHECK-NEXT: foo6 747 """, 748 """ 749 foo1 750 foo2 751 foo6 752 """) 753 self.assertMatches( 754 """ 755 /// CHECK-IF: True 756 /// CHECK-IF: False 757 /// CHECK: foo1 758 /// CHECK-ELSE: 759 /// CHECK: foo2 760 /// CHECK-FI: 761 /// CHECK-ELSE: 762 /// CHECK-IF: True 763 /// CHECK: foo3 764 /// CHECK-ELSE: 765 /// CHECK: foo4 766 /// CHECK-FI: 767 /// CHECK-FI: 768 """, 769 """ 770 foo2 771 """) 772 self.assertMatches( 773 """ 774 /// CHECK-IF: False 775 /// CHECK-IF: True 776 /// CHECK: foo1 777 /// CHECK-ELSE: 778 /// CHECK: foo2 779 /// CHECK-FI: 780 /// CHECK-ELSE: 781 /// CHECK-IF: False 782 /// CHECK: foo3 783 /// CHECK-ELSE: 784 /// CHECK-IF: False 785 /// CHECK: foo4 786 /// CHECK-ELSE: 787 /// CHECK: foo5 788 /// CHECK-FI: 789 /// CHECK-FI: 790 /// CHECK-FI: 791 """, 792 """ 793 foo5 794 """) 795 self.assertDoesNotMatch( 796 """ 797 /// CHECK: foo1 798 /// CHECK-IF: True 799 /// CHECK-IF: False 800 /// CHECK-NEXT: foo2 801 /// CHECK-ELSE: 802 /// CHECK-NEXT: foo3 803 /// CHECK-FI: 804 /// CHECK-NEXT: foo6 805 """, 806 """ 807 foo1 808 foo2 809 foo6 810 """) 811 812 def test_VariablesInBranches(self): 813 self.assertMatches( 814 """ 815 /// CHECK-IF: True 816 /// CHECK: foo<<VarA:\d+>> 817 /// CHECK-FI: 818 /// CHECK-EVAL: <<VarA>> == 12 819 """, 820 """ 821 foo12 822 """) 823 self.assertDoesNotMatch( 824 """ 825 /// CHECK-IF: True 826 /// CHECK: foo<<VarA:\d+>> 827 /// CHECK-FI: 828 /// CHECK-EVAL: <<VarA>> == 99 829 """, 830 """ 831 foo12 832 """) 833 self.assertMatches( 834 """ 835 /// CHECK-IF: True 836 /// CHECK: foo<<VarA:\d+>> 837 /// CHECK-IF: <<VarA>> == 12 838 /// CHECK: bar<<VarB:M|N>> 839 /// CHECK-FI: 840 /// CHECK-FI: 841 /// CHECK-EVAL: "<<VarB>>" == "M" 842 """, 843 """ 844 foo12 845 barM 846 """) 847 self.assertMatches( 848 """ 849 /// CHECK-IF: False 850 /// CHECK: foo<<VarA:\d+>> 851 /// CHECK-ELIF: True 852 /// CHECK: foo<<VarA:M|N>> 853 /// CHECK-FI: 854 /// CHECK-EVAL: "<<VarA>>" == "M" 855 """, 856 """ 857 fooM 858 """) 859 self.assertMatches( 860 """ 861 /// CHECK-IF: False 862 /// CHECK: foo<<VarA:A|B>> 863 /// CHECK-ELIF: False 864 /// CHECK: foo<<VarA:A|B>> 865 /// CHECK-ELSE: 866 /// CHECK-IF: False 867 /// CHECK: foo<<VarA:A|B>> 868 /// CHECK-ELSE: 869 /// CHECK: foo<<VarA:M|N>> 870 /// CHECK-FI: 871 /// CHECK-FI: 872 /// CHECK-EVAL: "<<VarA>>" == "N" 873 """, 874 """ 875 fooN 876 """) 877 878 def test_MalformedBranching(self): 879 self.assertBadStructure( 880 """ 881 /// CHECK-IF: True 882 /// CHECK: foo 883 """, 884 """ 885 foo 886 """) 887 self.assertBadStructure( 888 """ 889 /// CHECK-ELSE: 890 /// CHECK: foo 891 """, 892 """ 893 foo 894 """) 895 self.assertBadStructure( 896 """ 897 /// CHECK-IF: True 898 /// CHECK: foo 899 /// CHECK-ELSE: 900 """, 901 """ 902 foo 903 """) 904 self.assertBadStructure( 905 """ 906 /// CHECK-IF: True 907 /// CHECK: foo 908 /// CHECK-ELIF: 909 /// CHECK: foo 910 /// CHECK-IF: True 911 /// CHECK: foo 912 /// CHECK-FI: 913 """, 914 """ 915 foo 916 """) 917 self.assertBadStructure( 918 """ 919 /// CHECK-IF: True 920 /// CHECK: foo 921 /// CHECK-ELSE: 922 /// CHECK: foo 923 /// CHECK-ELIF: 924 /// CHECK: foo 925 /// CHECK-FI: 926 """, 927 """ 928 foo 929 """) 930 self.assertBadStructure( 931 """ 932 /// CHECK-IF: True 933 /// CHECK: foo 934 /// CHECK-ELSE: 935 /// CHECK: foo 936 /// CHECK-ELSE: 937 /// CHECK: foo 938 /// CHECK-FI: 939 """, 940 """ 941 foo 942 """) 943 944 def test_hasIsaFeature(self): 945 no_isa = None 946 self.assertMatches( 947 """ 948 /// CHECK-EVAL: hasIsaFeature('feature1') and not hasIsaFeature('feature2') 949 """, 950 """ 951 foo 952 """, 953 no_isa, 954 ImmutableDict({"feature1": True}) 955 ) 956 self.assertDoesNotMatch( 957 """ 958 /// CHECK-EVAL: not hasIsaFeature('feature1') 959 """, 960 """ 961 foo 962 """, 963 no_isa, 964 ImmutableDict({"feature1": True}) 965 ) 966 self.assertMatches( 967 """ 968 /// CHECK-IF: hasIsaFeature('feature2') 969 /// CHECK: bar1 970 /// CHECK-ELSE: 971 /// CHECK: bar2 972 /// CHECK-FI: 973 """, 974 """ 975 foo 976 bar1 977 """, 978 no_isa, 979 ImmutableDict({"feature1": False, "feature2": True}) 980 ) 981 self.assertMatches( 982 """ 983 /// CHECK-EVAL: hasIsaFeature('feature1') and not hasIsaFeature('feature2') 984 """, 985 """ 986 foo 987 """, 988 "some_isa", 989 ImmutableDict({"feature1": True}) 990 ) 991 self.assertDoesNotMatch( 992 """ 993 /// CHECK-EVAL: not hasIsaFeature('feature1') 994 """, 995 """ 996 foo 997 """, 998 "some_isa", 999 ImmutableDict({"feature1": True}) 1000 ) 1001 self.assertMatches( 1002 """ 1003 /// CHECK-IF: hasIsaFeature('feature2') 1004 /// CHECK: bar1 1005 /// CHECK-ELSE: 1006 /// CHECK: bar2 1007 /// CHECK-FI: 1008 """, 1009 """ 1010 foo 1011 bar1 1012 """, 1013 "some_isa", 1014 ImmutableDict({"feature1": False, "feature2": True}) 1015 ) 1016