optimism.test_examples
1import os 2import sys 3import io 4import importlib 5import re 6 7from . import optimism 8 9optimism.skipChecksAfterFail(None) 10optimism.suppressErrorDetailsAfterFail(None) 11 12# Detect whether we've got better or worse line numbers so we can create 13# correct tests... 14better_line_numbers = sys.version_info >= (3, 8) 15 16EXAMPLES = [ 17 ("basic", []), 18 ("bits", []), 19 ("multi", []), 20 ("block", []), 21 ("runfile", ["Tester"]), 22 ("tracing", ["Tester"]), 23 ("catch_and_release", ["one", "two"]), 24 ("skip", []), 25 ("fragments", []), 26 ("errors", []), 27 ("files", []), 28 ("code", []), 29 ("suites", []), 30 ("literals", []), 31 ("structure", []), 32 ("doctests", []), 33 ("memoryReports", []) 34 #("reverse_tracing", []), 35 # TODO: Include this once the machinery for it is there 36] 37 38 39EXPECTATIONS = { 40 "basic": [ 41 "✓ {file}:16", 42 "✓ {file}:27", 43 "✓ {file}:42", 44 "✓ {file}:43" if better_line_numbers else "✓ {file}:45", 45 """\ 46-- Summary for suite 'default' -- 47All 4 expectation(s) were met. 48---- 49""", 50 """\ 51✗ {file}:54 52 Result: 53 11 54 was NOT equivalent to the expected value: 55 10 56 Called function 'f' with arguments: 57 x = 6 58 y = 4""", 59 """\ 60✗ {file}:55 61 Result: 62 11 63 was NOT equivalent to the expected value: 64 10 65 Test expression was: 66 f(x + x, y) 67 Values were: 68 x = 3 69 y = 4""", 70 """\ 71✗ expectation from {file}:61 NOT met for test case at {file}:60 72 Result: 73 None 74 was NOT equivalent to the expected value: 75 False 76 Called function 'display' with arguments: 77 message = 'nope'""", 78 """\ 79✓ expectation from {file}:62 met for test case at {file}:60 80 Printed lines: 81 \"\"\"\\ 82 The message is: 83 -nope- 84 \"\"\" 85 were exactly the same as the expected printed lines: 86 \"\"\"\\ 87 The message is: 88 -nope- 89 \"\"\" 90 Called function 'display' with arguments: 91 message = 'nope'""", 92 """\ 93✗ {file}:65 94 Printed lines: 95 \"\"\"\\ 96 The message is: 97 -nope- 98 \"\"\" 99 were NOT the same as the expected printed lines: 100 \"\"\"\\ 101 The message is: 102 -yep- 103 \"\"\" 104 First difference was: 105 strings differ on line 2 where we got: 106 '-nope-' 107 but we expected: 108 '-yep-' 109 Called function 'display' with arguments: 110 message = 'nope'""", 111 """\ 112✗ {file}:69 113 Result: 114 1 115 was NOT equivalent to the expected value: 116 5 117 Called function 'f' with arguments: 118 x = 0 119 y = 0""", 120 """\ 121✗ {file}:69 122 Result: 123 3 124 was NOT equivalent to the expected value: 125 5 126 Called function 'f' with arguments: 127 x = 1 128 y = 1""", 129 "✓ {file}:69", 130 """\ 131-- Summary for suite 'default' -- 1326 of the 12 expectation(s) were NOT met: 133 ✗ {file}:54 134 ✗ {file}:55 135 ✗ {file}:61 136 ✗ {file}:65 137 ✗ {file}:69 138 ✗ {file}:69 139----""" 140 ], 141 142 "bits": [ 143 """\ 144✓ {file}:9 145 Result: 146 [1, 2, 3, [4, 5, 6]] 147 was equivalent to the expected value: 148 [1, 2, 3, [4, 5, 6]] 149 Test expression was: 150 x 151 Values were: 152 x = [1, 2, 3, [4, 5, 6]]""", 153 """\ 154✓ {file}:12 155 Result: 156 [1, 2, 3, [4, 5]] 157 was equivalent to the expected value: 158 [1, 2, 3, [4, 5]] 159 Test expression was: 160 x 161 Values were: 162 x = [1, 2, 3, [4, 5]]""", 163 """\ 164✓ {file}:13 165 Result: 166 [4, 5] 167 was equivalent to the expected value: 168 [4, 5] 169 Test expression was: 170 x[3] 171 Values were: 172 x = [1, 2, 3, [4, 5]] 173 x[3] = [4, 5]""", 174 """\ 175✓ {file}:14 176 Result: 177 5 178 was equivalent to the expected value: 179 5 180 Test expression was: 181 x[3][-1] 182 Values were: 183 x = [1, 2, 3, [4, 5]] 184 x[3] = [4, 5] 185 x[3][-1] = 5""", 186 """\ 187✓ {file}:17 188 Result: 189 [1, 2, 3] 190 was equivalent to the expected value: 191 [1, 2, 3] 192 Test expression was: 193 x 194 Values were: 195 x = [1, 2, 3]""", 196 """\ 197✓ {file}:18 198 Result: 199 2 200 was equivalent to the expected value: 201 2 202 Test expression was: 203 x[1] 204 Values were: 205 x = [1, 2, 3] 206 x[1] = 2""", 207 """\ 208✓ {file}:20 209 Result: 210 [1, 2, 3] 211 was equivalent to the expected value: 212 [1, 2, 3] 213 Test expression was: 214 x 215 Values were: 216 x = [1, 2, 3]""", 217 """\ 218✓ {file}:22 219 Result: 220 [1, 2] 221 was equivalent to the expected value: 222 [1, 2] 223 Test expression was: 224 x 225 Values were: 226 x = [1, 2]""", 227 """\ 228✓ {file}:25 229 Result: 230 2 231 was equivalent to the expected value: 232 2 233 Test expression was: 234 x[-1] 235 Values were: 236 x = [1] 237 x[-1] = 1""", 238 """\ 239✓ {file}:27 240 The result type (<class 'list'>) was the expected type. 241 Test expression was: 242 x 243 Values were: 244 x = [1]""", 245 """\ 246✓ {file}:28 247 The result type (<class 'int'>) was the expected type. 248 Test expression was: 249 x[0] 250 Values were: 251 x = [1] 252 x[0] = 1""", 253 ], 254 255 "block": [ 256 """\ 257✗ {file}:12 258 Failed due to an error: 259 Traceback omitted 260 NameError: name 'x' is not defined 261 Ran code: 262 print(x) 263 x += 1 264 print(x)""", 265 """\ 266✗ {file}:13 267 Failed due to an error: 268 Traceback omitted 269 NameError: name 'x' is not defined 270 Ran code: 271 print(x) 272 x += 1 273 print(x)""", 274 "✓ {file}:15", 275 "✓ {file}:16", 276 "✓ {file}:28", 277 "✓ {file}:29", 278 """\ 279✗ {file}:30 280 Variable 'x' with value: 281 5 282 was NOT equivalent to the expected value: 283 6 284 Ran code: 285 x = 3 286 print(x) 287 x += 1 288 print(x) 289 x += 1""", 290 ], 291 292 "multi": [ 293 f"""\ 294✓ {{file}}:7 295 Result: 296 {eval(expr)} 297 was equivalent to the expected value: 298 {eval(expr)} 299 Test expression was: 300 {expr} 301 Values were: 302 i = {i}""" 303 for i in range(3) 304 for expr in ["i", "i + 1", "i * i"] 305 ] + [ 306 """\ 307✓ {file}:9 308 Result: 309 (1, 2, 3) 310 was equivalent to the expected value: 311 (1, 2, 3) 312 Test expression was: 313 ( 314 1, 315 2, 316 3 317 )""" if better_line_numbers else """\ 318✓ {file}:15 319 Result: 320 (1, 2, 3) 321 was equivalent to the expected value: 322 (1, 2, 3) 323 Test expression was: 324 ( 325 1, 326 2, 327 3 328 )""", 329 ], 330 331 "runfile": [ 332 "✓ {file}:9" if better_line_numbers else "✓ {file}:12", 333 "✓ {file}:35", 334 """\ 335✗ {file}:42 336 Custom check failed: 337 failure message 338 Ran file 'io_example.py'""", 339 "✓ {file}:57", 340 """\ 341✗ {file}:58 342 Custom check failed: 343 'Hi Tester!' did not match 'Hi Tester?' 344 Ran file 'io_example.py'""", 345 ], 346 347 "tracing": [ 348 "3 input(\"What is your name? \") ⇒ 'Tester'", 349 "4 name ⇒ 'Tester'", 350 "4 \"Hello \" + opt.trace(name) ⇒ 'Hello Tester'", 351 "5 '=' * len(greeting) ⇒ '============'", 352 "6 print(greeting) ⇒ None", 353 "7 underline ⇒ '============'", 354 "9 \"ha\" * 50 ⇒ 'hahahahahahahahahahahahahahahahahaha...", 355 """\ 356{file}:12 "ha" * 50 ⇒ 'hahahahahahahahahahahahahahahahahaha... 357 Full result is: 358 'hahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaha'""", # noqa 359 ], 360 361 "catch_and_release": [ 362 "✓ {file}:19", 363 "✓ {file}:20", 364 "✓ {file}:24", 365 "✓ {file}:25", 366 "✓ {file}:30", 367 "✓ {file}:31", 368 ], 369 370 "skip": [ 371 "✓ {file}:4", # appears twice 372 "Did not find 'indetn' in module 'optimism'...", 373 "~ {file}:7 (skipped)", 374 "~ {file}:8 (skipped)", 375 """\ 376✗ {file}:19 377 Result: 378 3 379 was NOT equivalent to the expected value: 380 4 381 Called function 'f'""", 382 "~ {file}:20 (skipped)", 383 "~ {file}:21 (skipped)", 384 "✓ {file}:24", 385 """\ 386✗ {file}:29 387 Result: 388 3 389 was NOT equivalent to the expected value: 390 4 391 Called function 'f'""", 392 "~ {file}:30 (skipped)", 393 "~ {file}:31 (skipped)", 394 """\ 395✗ {file}:36 396 Result: 397 3 398 was NOT equivalent to the expected value: 399 4 400 Called function 'f'""", 401 """\ 402✗ {file}:37 403 Result: 404 3 405 was NOT equivalent to the expected value: 406 5 407 Called function 'f'""", 408 "✓ {file}:38", 409 ], 410 411 "fragments": [ 412 "✓ {file}:19", 413 "✓ {file}:20", 414 "✓ {file}:21", 415 "✓ {file}:22", 416 "✓ {file}:23", 417 ], 418 419 "errors": [ 420 """\ 421✗ {file}:6 422 Failed due to an error: 423 Traceback omitted 424 ZeroDivisionError: division by zero 425 Called function 'f'""" 426 ], 427 428 "files": [ 429 "✓ {file}:10", 430 "✓ {file}:11", 431 '''\ 432✗ {file}:12 433 File contents: 434 """\\ 435 1 436 2 437 3 438 """ 439 were NOT the same as the expected file contents: 440 """\\ 441 1 442 2 443 """ 444 First difference was: 445 strings differ on line 3 where we got: 446 '3' 447 but we expected: 448 '' 449 Called function 'write123' with arguments: 450 filename = 'b.txt' 451''', 452 '''\ 453✗ {file}:13 454 File contents: 455 """\\ 456 1 457 2 458 3 459 """ 460 were NOT the same as the expected file contents: 461 """\\ 462 1 463 2 464 hello 465 """ 466 First difference was: 467 strings differ on line 3 where we got: 468 '3' 469 but we expected: 470 'hello' 471 Called function 'write123' with arguments: 472 filename = 'b.txt' 473''', 474 "✓ {file}:23", 475 '''\ 476✗ {file}:25 477 File contents: 478 """\\ 479 abc\\r 480 def\\r 481 """ 482 were NOT the same as the expected file contents: 483 """\\ 484 abc 485 def 486 """ 487 First difference was: 488 strings differ on line 1 where we got: 489 'abc\\r' 490 but we expected: 491 'abc' 492 Called function 'writeReturny' with arguments: 493 filename = 'a.txt' 494''', 495 "✓ {file}:37", 496 "✓ {file}:39", 497 "✓ {file}:46", 498 '''\ 499✗ {file}:48 500 Result: 501 'abc\\ndef' 502 was NOT equivalent to the expected value: 503 'abc\\ndef\\n' 504 Test expression was: 505 'abc\\ndef' 506''', 507 ], 508 509 "code": [ 510 "✓ {file}:21", 511 "✓ {file}:24", 512 "✓ {file}:25", 513 "✓ {file}:26", 514 "✓ {file}:40", 515 "✓ {file}:41", 516 """\ 517✗ {file}:42 518 Code does not contain the expected structure: 519 at least 1 definition(s) of functionName 520 Although it does partially satisfy the requirement: 521 Requirement partially satisfied via 0 full and 2 partial match(es): 522 Partial match: FunctionDef on line 10 523 Partial match: FunctionDef on line 99 524 checked code in file '{full_file}'""", 525 "✓ {file}:44", 526 """\ 527✗ {file}:45 528 Code does not contain the expected structure: 529 at least 1 function definition(s) that also contain(s): 530 at least 1 loop(s) or generator expression(s) 531 Although it does partially satisfy the requirement: 532 Requirement partially satisfied via 0 full and 2 partial match(es): 533 Partial match: FunctionDef on line 10 534 Partial match: FunctionDef on line 99 535 checked code in file '{full_file}'""", 536 """\ 537✗ {file}:46 538 Code does not contain the expected structure: 539 at least 1 loop(s) or generator expression(s) that also contain(s): 540 at least 1 function definition(s) 541 Although it does partially satisfy the requirement: 542 Requirement partially satisfied via 0 full and 1 partial match(es): 543 Partial match: For on line 29 544 checked code in file '{full_file}'""", 545 """\ 546✗ {file}:47 547 Code does not contain the expected structure: 548 at least 1 while loop(s) 549 Although it does partially satisfy the requirement: 550 Requirement partially satisfied via 0 full and 1 partial match(es): 551 Partial match: For on line 29 552 checked code in file '{full_file}'""", 553 "✓ {file}:48", 554 "✓ {file}:50" if better_line_numbers else "✓ {file}:51", 555 "✓ {file}:53" if better_line_numbers else "✓ {file}:54", 556 "✓ {file}:56" if better_line_numbers else "✓ {file}:57", 557 """\ 558✗ {file}:""" + ('59' if better_line_numbers else '60') + """ 559 Code does not contain the expected structure: 560 at least 1 loop(s) or generator expression(s) that also contain(s): 561 4 call(s) to print 562 Although it does partially satisfy the requirement: 563 Requirement partially satisfied via 0 full and 1 partial match(es): 564 Partial match: For on line 29 565 checked code in file '{full_file}'""", 566 """\ 567✗ {file}:""" + ('62' if better_line_numbers else '63') + """ 568 Code does not contain the expected structure: 569 at least 1 loop(s) or generator expression(s) that also contain(s): 570 at least 4 call(s) to print 571 Although it does partially satisfy the requirement: 572 Requirement partially satisfied via 0 full and 1 partial match(es): 573 Partial match: For on line 29 574 checked code in file '{full_file}'""", 575 "✓ {file}:65" if better_line_numbers else "✓ {file}:66", 576 """\ 577✗ {file}:""" + ('68' if better_line_numbers else '69') + """ 578 Code does not contain the expected structure: 579 at least 1 loop(s) or generator expression(s) that also contain(s): 580 no call(s) to print 581 Although it does partially satisfy the requirement: 582 Requirement partially satisfied via 0 full and 1 partial match(es): 583 Partial match: For on line 29 584 checked code in file '{full_file}'""", 585 "✓ {file}:71" if better_line_numbers else "✓ {file}:72", 586 "✓ {file}:75" if better_line_numbers else "✓ {file}:76", 587 """\ 588✗ {file}:""" + ('78' if better_line_numbers else '79') + """ 589 Code does not contain the expected structure: 590 at least 1 if/else statement(s) or expression(s) that also contain(s): 591 at least 1 operator '>' 592 Although it does partially satisfy the requirement: 593 Requirement partially satisfied via 0 full and 1 partial match(es): 594 Partial match: If on line 33 595 checked code in file '{full_file}'""", 596 "✓ {file}:81" if better_line_numbers else "✓ {file}:82", 597 "✓ {file}:84" if better_line_numbers else "✓ {file}:85", 598 "✓ {file}:90", 599 "✓ {file}:91", 600 "✓ {file}:92", 601 """\ 602✗ {file}:93 603 Code does not contain the expected structure: 604 at least 1 constant 2.0 605 Although it does partially satisfy the requirement: 606 Requirement partially satisfied via 0 full and 60 partial match(es): 607""" + ("""\ 608 Partial match: Constant on line 1 609 Partial match: Constant on line 7""" if better_line_numbers else """\ 610 Partial match: Str on line 3 611 Partial match: NameConstant on line 7"""), # not listing all 60... 612 "✓ {file}:94", 613 """\ 614✗ {file}:95 615 Code does not contain the expected structure: 616 at least 1 constant 5.0 617 Although it does partially satisfy the requirement: 618 Requirement partially satisfied via 0 full and 60 partial match(es): 619""" + ("""\ 620 Partial match: Constant on line 1 621 Partial match: Constant on line 7""" if better_line_numbers else """\ 622 Partial match: Str on line 3 623 Partial match: NameConstant on line 7"""), # not listing all 60... 624 "✓ {file}:104", 625 "✓ {file}:107", 626 """\ 627✗ {file}:110 628 Code does not contain the expected structure: 629 at least 1 definition(s) of aug that also contain(s): 630 no operator '/' 631 Although it does partially satisfy the requirement: 632 Requirement partially satisfied via 0 full and 2 partial match(es): 633 Partial match: FunctionDef on line 99 634 Partial match: FunctionDef on line 10 635""" 636 ], 637 638 "reverse_tracing": [ 639 # TODO 640 ], 641 642 "suites": [ 643 "✓ {file}:14", 644 "✓ {file}:16", 645 "✓ {file}:17", 646 "✓ {file}:20", 647 "✓ {file}:24", 648 '''\ 649✗ {file}:26 650 Printed lines: 651 """\\ 652 4 653 """ 654 were NOT the same as the expected printed lines: 655 """\\ 656 5 657 """ 658 First difference was: 659 strings differ on line 1 where we got: 660 '4' 661 but we expected: 662 '5' 663 Called function 'f' with arguments: 664 x = 4 665 y = 5''', 666 "✓ {file}:27", 667 "✓ {file}:29", 668 """\ 669-- Summary for suite 'B' -- 6701 of the 4 expectation(s) were NOT met: 671 ✗ {file}:26 672----""", 673 """\ 674-- Summary for suite 'A' -- 675All 4 expectation(s) were met. 676----""", 677 ], 678 679 "literals": [ 680 "✓ {file}:17", 681 "✓ {file}:18", 682 "✓ {file}:19", 683 "✓ {file}:20", 684 "✓ {file}:21", 685 "✓ {file}:22", 686 "✓ {file}:23" if better_line_numbers else "✓ {file}:24", 687 "✓ {file}:27", 688 "✓ {file}:28", 689 "✓ {file}:29", 690 "✓ {file}:30", 691 "✓ {file}:31", 692 "✓ {file}:32", 693 "✓ {file}:33", 694 "✓ {file}:34", 695 """\ 696✗ {file}:36 697 Code does not contain the expected structure: 698 at least 1 literal [4, 5, 6] 699 Although it does partially satisfy the requirement: 700 Requirement partially satisfied via 0 full and 6 partial match(es): 701 Partial match: List on line 2 702 Partial match: Tuple on line 3 703 Partial match: List on line 6 704 Partial match: List on line 7 705 Partial match: Tuple on line 7 706 Partial match: List on line 7 707 checked code from block at {file}:16""", 708 """\ 709✗ {file}:37 710 Code does not contain the expected structure: 711 at least 1 literal (1, 2, 3) 712 Although it does partially satisfy the requirement: 713 Requirement partially satisfied via 0 full and 6 partial match(es): 714 Partial match: List on line 2 715 Partial match: Tuple on line 3 716 Partial match: List on line 6 717 Partial match: List on line 7 718 Partial match: Tuple on line 7 719 Partial match: List on line 7 720 checked code from block at {file}:16""", 721 """\ 722✗ {file}:40 723 Code does not contain the expected structure: 724 at least 1 literal(s) 725 checked code from block at {file}:39""", 726 """\ 727✗ {file}:41 728 Code does not contain the expected structure: 729 at least 1 list literal(s) 730 checked code from block at {file}:39""", 731 """\ 732✗ {file}:42 733 Code does not contain the expected structure: 734 at least 1 tuple literal(s) 735 checked code from block at {file}:39""", 736 """\ 737✗ {file}:43 738 Code does not contain the expected structure: 739 at least 1 set literal(s) 740 checked code from block at {file}:39""", 741 """\ 742✗ {file}:44 743 Code does not contain the expected structure: 744 at least 1 dict literal(s) 745 checked code from block at {file}:39""", 746 "✓ {file}:47", 747 "✓ {file}:48", 748 "✓ {file}:49", 749 "✓ {file}:50", 750 "✓ {file}:51", 751 "✓ {file}:54", 752 ], 753 754 "structure": [ 755 "✓ {file}:18", 756 """\ 757✗ {file}:22 758 Structure of the result: 759 @0: [1, 2, @1, @0] 760 @1: [3, 4] 761 was NOT equivalent to the expected structure: 762 @0: [1, 2, @1, @0] 763 @1: [3, 4] 764 @2: ['extra'] 765 Differences: 766 did not find a match for list @2 767 Called function 'f' 768""", 769 "✓ {file}:27", 770 "✓ {file}:33", 771 "✓ {file}:34", 772 "✓ {file}:35", 773 "✓ {file}:52", 774 "✓ {file}:61", 775 "✓ {file}:67", 776 "✓ {file}:74", 777 """\ 778✗ {file}:75 779 Variable 'x' had structure: 780 x: @0 781 @0: [@1] 782 @1: [1, 2] 783 which was NOT structurally equivalent to to the expected structure: 784 x: @0 785 @0: [@1] 786 @1: [1] 787 Differences: 788 list @1: list has 1 extra item(s) 789 Ran code: 790 x = [[1, 2]] 791""", 792 """\ 793✗ {file}:76 794 Variable 'x' had structure: 795 x: @0 796 @0: [@1] 797 @1: [1, 2] 798 which was NOT structurally equivalent to to the expected structure: 799 x: @0 800 @0: [@1] 801 @1: [1, 2, 3] 802 Differences: 803 list @1: list has 1 missing item(s) 804 Ran code: 805 x = [[1, 2]] 806""", 807 """\ 808✗ {file}:77 809 Variable 'x' had structure: 810 x: @0 811 @0: [@1] 812 @1: [1, 2] 813 which was NOT structurally equivalent to to the expected structure: 814 x: @0 815 @0: [@1] 816 @1: [3, 4] 817 Differences: 818 list @1 slot 0: value 1 differs from expected value 3 819 list @1 slot 1: value 2 differs from expected value 4 820 Ran code: 821 x = [[1, 2]] 822""", 823 "✓ {file}:80", 824 """\ 825✗ {file}:81 826 Variable 'x' had structure: 827 x: @0 828 @0: (@1,) 829 @1: (1, 2) 830 which was NOT structurally equivalent to to the expected structure: 831 x: @0 832 @0: (@1,) 833 @1: (1,) 834 Differences: 835 tuple @1: tuple has 1 extra item(s) 836 Ran code: 837 x = ((1, 2),) 838""", 839 """\ 840✗ {file}:82 841 Variable 'x' had structure: 842 x: @0 843 @0: (@1,) 844 @1: (1, 2) 845 which was NOT structurally equivalent to to the expected structure: 846 x: @0 847 @0: (@1,) 848 @1: (1, 2, 3) 849 Differences: 850 tuple @1: tuple has 1 missing item(s) 851 Ran code: 852 x = ((1, 2),) 853""", 854 """\ 855✗ {file}:83 856 Variable 'x' had structure: 857 x: @0 858 @0: (@1,) 859 @1: (1, 2) 860 which was NOT structurally equivalent to to the expected structure: 861 x: @0 862 @0: (@1,) 863 @1: (3, 4) 864 Differences: 865 tuple @1 slot 0: value 1 differs from expected value 3 866 tuple @1 slot 1: value 2 differs from expected value 4 867 Ran code: 868 x = ((1, 2),) 869""", 870 "✓ {file}:91", 871 "✓ {file}:96", 872 "✓ {file}:101", 873 """\ 874✗ {file}:105 875 Variable 'x' had structure: 876 x: @0 877 @0: (@1, @1) 878 @1: (1, 2) 879 which was NOT structurally equivalent to to the expected structure: 880 x: @0 881 @0: (@1, @1) 882 @1: (1, 2, 3) 883 Differences: 884 tuple @1: tuple has 1 missing item(s) 885 Ran code: 886 x = ((1, 2),) 887 x = x + (x[0],) 888 y = x[0] 889 y = y + (3,) 890""", 891 """\ 892✗ {file}:110 893 Variable 'x' had structure: 894 x: @0 895 @0: (@1, @1) 896 @1: (1, 2) 897 which was NOT structurally equivalent to to the expected structure: 898 x: @0 899 @0: (@3, @3) 900 @3: (1, 2, 3) 901 Differences: 902 tuple @1: tuple has 1 missing item(s) 903 Ran code: 904 x = ((1, 2),) 905 x = x + (x[0],) 906 y = x[0] 907 y = y + (3,) 908""" 909 ], 910 911 "doctests": [ 912 """\ 913✗ {file}:22 914 Docstring was absent or empty. 915 checked code of function 'a' 916""", 917 """\ 918✗ {file}:23 919 Found only 0 distinct doctest example(s) (required 1). 920 checked code of function 'a' 921""", 922 """\ 923✗ {file}:24 924 No doctests were found. 925 checked code of function 'a' 926""", 927 """\ 928✗ {file}:33 929 Docstring was absent or empty. 930 checked code of function 'b' 931""", 932 """\ 933✗ {file}:34 934 Found only 0 distinct doctest example(s) (required 1). 935 checked code of function 'b' 936""", 937 """\ 938✗ {file}:35 939 No doctests were found. 940 checked code of function 'b' 941✓ {file}:44 942""", 943 """\ 944✗ {file}:45 945 Found only 0 distinct doctest example(s) (required 1). 946 checked code of function 'c' 947""", 948 """\ 949✗ {file}:46 950 No doctests were found. 951 checked code of function 'c' 952""", 953 "✓ {file}:61", 954 "✓ {file}:62", 955 "✓ {file}:63", 956 "✓ {file}:64", 957 """\ 958✗ {file}:65 959 Found only 1 distinct doctest example(s) (required 2). 960 checked code of function 'd' 961""", 962 "✓ {file}:76", 963 """\ 964✗ {file}:77 965 At {file}:72, output didn't match what the test expected. Expected: 966 4 967 Got: 968 3 969 checked code of function 'e' 970""", 971 "✓ {file}:92", 972 "✓ {file}:93", 973 "✓ {file}:94", 974 """\ 975✗ {file}:95 976 Found only 3 distinct doctest example(s) (required 4). 977 checked code of function 'f' 978""", 979 "✓ {file}:96", 980 "✓ {file}:96", 981 "✓ {file}:96", 982 "✓ {file}:114", 983 "✓ {file}:115", 984 """\ 985✗ {file}:116 986 Found only 3 distinct doctest example(s) (required 4). 987 checked code of function 'g' 988""", 989 "✓ {file}:117", 990 "✓ {file}:117", 991 "✓ {file}:117", 992 "✓ {file}:119", 993 "✓ {file}:120", 994 """\ 995✗ {file}:122 996 At {file}:104, output didn't match what the test expected. Expected: 997 2 998 Got: 999 Unexpected exception: 1000 Traceback omitted 1001 NameError: name 'g' is not defined 1002 checked code of function 'g' 1003""", 1004 """\ 1005✗ {file}:122 1006 At {file}:106, output didn't match what the test expected. Expected: 1007 3 1008 Got: 1009 Unexpected exception: 1010 Traceback omitted 1011 NameError: name 'g' is not defined 1012 checked code of function 'g' 1013""", 1014 """\ 1015✗ {file}:122 1016 At {file}:108, output didn't match what the test expected. Expected: 1017 4 1018 Got: 1019 Unexpected exception: 1020 Traceback omitted 1021 NameError: name 'g' is not defined 1022 checked code of function 'g' 1023""", 1024 """\ 1025✗ {file}:124 1026 At {file}:104, output didn't match what the test expected. Expected: 1027 2 1028 Got: 1029 Unexpected exception: 1030 Traceback omitted 1031 NameError: name 'g' is not defined 1032 checked code of function 'g' 1033""", 1034 """\ 1035✗ {file}:124 1036 At {file}:106, output didn't match what the test expected. Expected: 1037 3 1038 Got: 1039 Unexpected exception: 1040 Traceback omitted 1041 NameError: name 'g' is not defined 1042 checked code of function 'g' 1043""", 1044 """\ 1045✗ {file}:124 1046 At {file}:108, output didn't match what the test expected. Expected: 1047 4 1048 Got: 1049 Unexpected exception: 1050 Traceback omitted 1051 NameError: name 'g' is not defined 1052 checked code of function 'g' 1053""", 1054 "✓ {file}:139", 1055 "✓ {file}:140", 1056 """\ 1057✗ {file}:141 1058 Found only 3 distinct doctest example(s) (required 4). 1059 checked code of function 'h' 1060""", 1061 "✓ {file}:142", 1062 "✓ {file}:142", 1063 """\ 1064✗ {file}:142 1065 At {file}:135, output didn't match what the test expected. Expected: 1066 4 1067 Got: 1068 3 1069 checked code of function 'h' 1070""", 1071 "✓ {file}:157", 1072 """\ 1073✗ {file}:158 1074 Found only 1 distinct doctest example(s) (required 2; ignored 2 duplicates). 1075 checked code of function 'i' 1076""", 1077 "✓ {file}:159", 1078 "✓ {file}:159", 1079 "✓ {file}:159", 1080 "✓ {file}:175", 1081 """\ 1082✗ {file}:176 1083 At {file}:166, output didn't match what the test expected. Expected: 1084 3 1085 Got: 1086 2 1087 checked code of function 'j' 1088""", 1089 "✓ {file}:176", 1090 "✓ {file}:176", 1091 "✓ {file}:201", 1092 """\ 1093✗ {file}:202 1094 Found only 2 distinct doctest example(s) (required 3). 1095 checked code of function 'k' 1096""", 1097 "✓ {file}:203", 1098 "✓ {file}:203", 1099 "✓ {file}:221", 1100 """\ 1101✗ {file}:222 1102 Found only 3 distinct doctest example(s) (required 4). 1103 checked code of function 'l' 1104""", 1105 "✓ {file}:223", 1106 "✓ {file}:223", 1107 "✓ {file}:223", 1108 "✓ {file}:239", 1109 """\ 1110✗ {file}:240 1111 Found only 3 distinct doctest example(s) (required 4). 1112 checked code of function 'm' 1113""", 1114 "✓ {file}:241", 1115 "✓ {file}:241", 1116 """\ 1117✗ {file}:241 1118 At {file}:235, output didn't match what the test expected. Expected: 1119 '11' 1120 Got: 1121 Unexpected exception: 1122 Traceback omitted 1123 TypeError: can only concatenate str (not "int") to str 1124 checked code of function 'm' 1125""", 1126 "✓ {file}:264", 1127 """\ 1128✗ {file}:265 1129 Found only 1 distinct doctest example(s) (required 2; ignored 4 duplicates). 1130 checked code of function 'n' 1131""", 1132 "✓ {file}:266", 1133 "✓ {file}:266", 1134 "✓ {file}:266", 1135 "✓ {file}:266", 1136 "✓ {file}:266", 1137 "✓ {file}:281", 1138 """\ 1139✗ {file}:282 1140 Found only 1 distinct doctest example(s) (required 2). 1141 checked code of function 'o' 1142""", 1143 "✓ {file}:283", 1144 "✓ {file}:300", 1145 "✓ {file}:300", 1146 "✓ {file}:300", 1147 "✓ {file}:300", 1148 "✓ {file}:303", 1149 """\ 1150✗ {file}:304 1151 Found only 4 distinct doctest example(s) (required 5). 1152 checked code of function 'p' 1153""", 1154 "✓ {file}:306", 1155 """\ 1156✗ {file}:307 1157 Found only 3 matching distinct doctest example(s) (required 4). 1158 checked code of function 'p' 1159""", 1160 "✓ {file}:309", 1161 """\ 1162✗ {file}:310 1163 Found only 1 matching distinct doctest example(s) (required 2). 1164 checked code of function 'p' 1165""", 1166 "✓ {file}:312", 1167 """\ 1168✗ {file}:313 1169 Found only 1 matching distinct doctest example(s) (required 2). 1170 checked code of function 'p' 1171""", 1172 "✓ {file}:315", 1173 """\ 1174✗ {file}:316 1175 Found only 2 matching distinct doctest example(s) (required 3). 1176 checked code of function 'p' 1177""", 1178 "✓ {file}:319", 1179 """\ 1180✗ {file}:320 1181 Found only 1 matching distinct doctest example(s) (required 2). 1182 checked code of function 'p' 1183""", 1184 "✓ {file}:322", 1185 """\ 1186✗ {file}:323 1187 Found only 2 matching distinct doctest example(s) (required 3). 1188 checked code of function 'p' 1189""", 1190 "✗ {file}:325", 1191 """\ 1192 Found only 0 matching distinct doctest example(s) (required 1). 1193 checked code of function 'p' 1194""", 1195 "✓ {file}:327", 1196 """\ 1197✗ {file}:328 1198 Found only 1 matching distinct doctest example(s) (required 2). 1199 checked code of function 'p' 1200""", 1201 "✓ {file}:362", 1202 "✓ {file}:363", 1203 """\ 1204✗ {file}:364 1205 Found only 3 distinct doctest example(s) (required 4; ignored 1 duplicates). 1206 checked code from block at {file}:332 1207""", 1208 "✓ {file}:365", 1209 "✓ {file}:365", 1210 "✓ {file}:365", 1211 "✓ {file}:365", 1212 """\ 1213✗ {file}:370 1214 Docstring was absent or empty. 1215 checked code from block at {file}:368 1216""", 1217 """\ 1218✗ {file}:371 1219 Found only 0 distinct doctest example(s) (required 1). 1220 checked code from block at {file}:368 1221""", 1222 """\ 1223✗ {file}:372 1224 No doctests were found. 1225 checked code from block at {file}:368 1226""", 1227 """\ 1228✗ {file}:377 1229 Docstring was absent or empty. 1230 checked code from block at {file}:375 1231""", 1232 "✓ {file}:378", 1233 """\ 1234✗ {file}:379 1235 Found only 1 distinct doctest example(s) (required 2). 1236 checked code from block at {file}:375 1237""", 1238 "✓ {file}:380", 1239 """\ 1240✗ {file}:384 1241 At code block from {file}:383:4, output didn't match what the test expected. Expected: 1242 4 1243 Got: 1244 5 1245 checked code from block at {file}:383 1246""", 1247 "✓ {file}:390", 1248 "✓ {file}:391", 1249 "✓ {file}:391", 1250 "✓ {file}:391", 1251 "✓ {file}:391", 1252 "✓ {file}:391", 1253 "✓ {file}:392", 1254 """\ 1255✗ {file}:393 1256 Found only 5 distinct doctest example(s) (required 6). 1257 checked code in file 'doc_example.py' 1258""", 1259 "✓ {file}:394", 1260 """\ 1261✗ {file}:395 1262 Found only 2 matching distinct doctest example(s) (required 3). 1263 checked code in file 'doc_example.py' 1264""" 1265 ], 1266 "memoryReports": [ 1267 "✓ {file}:22", 1268 "✓ {file}:23", 1269 ] 1270} 1271 1272STDOUT_EXPECT = { 1273 "catch_and_release": [ 1274 "one Z!", 1275 "Re-providing input was blocked.", 1276 "Hello", 1277 "two Z!" 1278 ], 1279 1280 "code": [ 1281 "0", 1282 "1", 1283 "2", 1284 "3" 1285 ], 1286 1287 "suites": [ 1288 '3', 1289 'a', 1290 """\ 1291Outcomes in suite A: 1292(True, '{file}:14', '✓ {file}:14') 1293(True, '{file}:16', '✓ {file}:16') 1294(True, '{file}:17', '✓ {file}:17') 1295(True, '{file}:20', '✓ {file}:20')""", 1296 '''\ 1297Outcomes in suite B: 1298(True, '{file}:24', '✓ {file}:24') 1299(False, '{file}:26', '✗ {file}:26\\n Printed lines:\\n """\\\\\\n 4\\n """\\n were NOT the same as the expected printed lines:\\n """\\\\\\n 5\\n """\\n First difference was:\\n strings differ on line 1 where we got:\\n \\\'4\\\'\\n but we expected:\\n \\\'5\\\'\\n Called function \\\'f\\\' with arguments:\\n x = 4\\n y = 5') 1300(True, '{file}:27', '✓ {file}:27') 1301(True, '{file}:29', '✓ {file}:29')''', # noqa E501 1302 """\ 1303Outcomes in suite A (again): 1304(True, '{file}:14', '✓ {file}:14') 1305(True, '{file}:16', '✓ {file}:16') 1306(True, '{file}:17', '✓ {file}:17') 1307(True, '{file}:20', '✓ {file}:20') 1308(True, '{file}:46', '✓ {file}:46')""", 1309 "No more outcomes in suite A: []", 1310 "No more outcomes in suite B: []", 1311 "No more suite B.", 1312 ], 1313 1314 "memoryReports": [ 1315 """\ 1316words: @0 1317pair: @3 1318@0: [@1, @2] 1319@3: [@0, @0] 1320@1: 'hi' 1321@2: 'bye' 1322""", 1323 """\ 1324pair: @0 1325words: @1 1326knot: @4 1327@0: [@1, @1] 1328@1: [@2, @3] 1329@4: [@0, @1, @4] 1330@2: 'hi' 1331@3: 'bye' 1332""", 1333 ] 1334} 1335 1336 1337def run_example(mname, inputs=[]): 1338 """ 1339 Runs a module and captures stderr and stdout, returning a tuple 1340 containing the imported module, the captured stderr string, and the 1341 captured stdout string. The given input strings are provided as stdin 1342 during the run. 1343 """ 1344 old_stderr = sys.stderr 1345 old_stdout = sys.stdout 1346 old_stdin = sys.stdin 1347 old_print_to = optimism.PRINT_TO 1348 sys.stderr = io.StringIO() 1349 sys.stdout = io.StringIO() 1350 sys.stdin = io.StringIO('\n'.join(inputs) + '\n') 1351 optimism.PRINT_TO = sys.stderr 1352 1353 filePath = os.path.abspath(mname + '.py') 1354 1355 try: 1356 spec = importlib.util.spec_from_file_location(mname, filePath) 1357 module = importlib.util.module_from_spec(spec) 1358 # Note we skip adding it to sys.modules 1359 spec.loader.exec_module(module) 1360 errOut = sys.stderr.getvalue() 1361 stdOut = sys.stdout.getvalue() 1362 1363 finally: 1364 sys.stderr = old_stderr 1365 sys.stdout = old_stdout 1366 sys.stdin = old_stdin 1367 optimism.PRINT_TO = old_print_to 1368 1369 return (module, errOut, stdOut) 1370 1371 1372def test_all(): 1373 """ 1374 Tests each example file. The `examples` directory must be in the 1375 same place that this `test_examples.py` file lives. 1376 """ 1377 olddir = os.getcwd() 1378 try: 1379 os.chdir(os.path.join(os.path.dirname(__file__), "examples")) 1380 sys.path.insert(0, '.') 1381 for (mname, inputs) in EXAMPLES: 1382 optimism.detailLevel(0) 1383 optimism.deleteAllTestSuites() 1384 optimism.colors(False) 1385 module, output, stdout = run_example(mname, inputs) 1386 # Replace tracebacks with generic forms so we can match on 1387 # specific errors being reported while ignoring the files & lines 1388 # where they are reported. 1389 stdout = re.sub( 1390 r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)", 1391 "Traceback omitted\n\\1", 1392 stdout, 1393 flags=re.MULTILINE | re.DOTALL 1394 ) 1395 output = re.sub( 1396 r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)", 1397 "Traceback omitted\n\\1", 1398 output, 1399 flags=re.MULTILINE | re.DOTALL 1400 ) 1401 #output = re.sub(r"Traceback \(most recent call last\).*?NameError:", "HAHAHA", output, flags=re.MULTILINE | re.DOTALL) 1402 # Scrub line numbers from tracebacks so our expectations don't 1403 # become hopelessly fragile 1404 stdout = re.sub(r", line \d+,", ", line X,", stdout) 1405 output = re.sub(r", line \d+,", ", line X,", output) 1406 for ex in EXPECTATIONS[mname]: 1407 exp = ex.format( 1408 file=os.path.basename(module.__file__), 1409 dir=( 1410 os.path.split(module.__file__)[0] + '/' 1411 if better_line_numbers 1412 else '' 1413 ), 1414 full_file=module.__file__, 1415 opt_file=optimism.__file__, 1416 ) 1417 # Redundant, but makes issues easier to diagnose 1418 for line in exp.splitlines(): 1419 if line not in output: 1420 print("\n\nLINE:\n" + line) 1421 print("\n\nOUTPUT:\n" + output) 1422 assert (line in output), (line, output) 1423 if exp not in output: 1424 print("\n\nEXP:\n" + exp) 1425 print("\n\nOUTPUT:\n" + output) 1426 assert (exp in output), (exp, output) 1427 if mname in STDOUT_EXPECT: 1428 for ex in STDOUT_EXPECT[mname]: 1429 exp = ex.format( 1430 file=os.path.basename(module.__file__), 1431 dir=os.path.split(module.__file__)[0], 1432 full_file=module.__file__, 1433 opt_file=optimism.__file__, 1434 ) 1435 for line in exp.splitlines(): 1436 assert (line in stdout), stdout 1437 assert (exp in stdout), stdout 1438 finally: 1439 os.chdir(olddir) 1440 1441 1442if __name__ == "__main__": 1443 print('Testing example files...') 1444 test_all() 1445 print('...all tests passed.')
better_line_numbers =
True
EXAMPLES =
[('basic', []), ('bits', []), ('multi', []), ('block', []), ('runfile', ['Tester']), ('tracing', ['Tester']), ('catch_and_release', ['one', 'two']), ('skip', []), ('fragments', []), ('errors', []), ('files', []), ('code', []), ('suites', []), ('literals', []), ('structure', []), ('doctests', []), ('memoryReports', [])]
EXPECTATIONS =
{'basic': ['✓ {file}:16', '✓ {file}:27', '✓ {file}:42', '✓ {file}:43', "-- Summary for suite 'default' --\nAll 4 expectation(s) were met.\n----\n", "✗ {file}:54\n Result:\n 11\n was NOT equivalent to the expected value:\n 10\n Called function 'f' with arguments:\n x = 6\n y = 4", '✗ {file}:55\n Result:\n 11\n was NOT equivalent to the expected value:\n 10\n Test expression was:\n f(x + x, y)\n Values were:\n x = 3\n y = 4', "✗ expectation from {file}:61 NOT met for test case at {file}:60\n Result:\n None\n was NOT equivalent to the expected value:\n False\n Called function 'display' with arguments:\n message = 'nope'", '✓ expectation from {file}:62 met for test case at {file}:60\n Printed lines:\n """\\\n The message is:\n -nope-\n """\n were exactly the same as the expected printed lines:\n """\\\n The message is:\n -nope-\n """\n Called function \'display\' with arguments:\n message = \'nope\'', '✗ {file}:65\n Printed lines:\n """\\\n The message is:\n -nope-\n """\n were NOT the same as the expected printed lines:\n """\\\n The message is:\n -yep-\n """\n First difference was:\n strings differ on line 2 where we got:\n \'-nope-\'\n but we expected:\n \'-yep-\'\n Called function \'display\' with arguments:\n message = \'nope\'', "✗ {file}:69\n Result:\n 1\n was NOT equivalent to the expected value:\n 5\n Called function 'f' with arguments:\n x = 0\n y = 0", "✗ {file}:69\n Result:\n 3\n was NOT equivalent to the expected value:\n 5\n Called function 'f' with arguments:\n x = 1\n y = 1", '✓ {file}:69', "-- Summary for suite 'default' --\n6 of the 12 expectation(s) were NOT met:\n ✗ {file}:54\n ✗ {file}:55\n ✗ {file}:61\n ✗ {file}:65\n ✗ {file}:69\n ✗ {file}:69\n----"], 'bits': ['✓ {file}:9\n Result:\n [1, 2, 3, [4, 5, 6]]\n was equivalent to the expected value:\n [1, 2, 3, [4, 5, 6]]\n Test expression was:\n x\n Values were:\n x = [1, 2, 3, [4, 5, 6]]', '✓ {file}:12\n Result:\n [1, 2, 3, [4, 5]]\n was equivalent to the expected value:\n [1, 2, 3, [4, 5]]\n Test expression was:\n x\n Values were:\n x = [1, 2, 3, [4, 5]]', '✓ {file}:13\n Result:\n [4, 5]\n was equivalent to the expected value:\n [4, 5]\n Test expression was:\n x[3]\n Values were:\n x = [1, 2, 3, [4, 5]]\n x[3] = [4, 5]', '✓ {file}:14\n Result:\n 5\n was equivalent to the expected value:\n 5\n Test expression was:\n x[3][-1]\n Values were:\n x = [1, 2, 3, [4, 5]]\n x[3] = [4, 5]\n x[3][-1] = 5', '✓ {file}:17\n Result:\n [1, 2, 3]\n was equivalent to the expected value:\n [1, 2, 3]\n Test expression was:\n x\n Values were:\n x = [1, 2, 3]', '✓ {file}:18\n Result:\n 2\n was equivalent to the expected value:\n 2\n Test expression was:\n x[1]\n Values were:\n x = [1, 2, 3]\n x[1] = 2', '✓ {file}:20\n Result:\n [1, 2, 3]\n was equivalent to the expected value:\n [1, 2, 3]\n Test expression was:\n x\n Values were:\n x = [1, 2, 3]', '✓ {file}:22\n Result:\n [1, 2]\n was equivalent to the expected value:\n [1, 2]\n Test expression was:\n x\n Values were:\n x = [1, 2]', '✓ {file}:25\n Result:\n 2\n was equivalent to the expected value:\n 2\n Test expression was:\n x[-1]\n Values were:\n x = [1]\n x[-1] = 1', "✓ {file}:27\n The result type (<class 'list'>) was the expected type.\n Test expression was:\n x\n Values were:\n x = [1]", "✓ {file}:28\n The result type (<class 'int'>) was the expected type.\n Test expression was:\n x[0]\n Values were:\n x = [1]\n x[0] = 1"], 'block': ["✗ {file}:12\n Failed due to an error:\n Traceback omitted\n NameError: name 'x' is not defined\n Ran code:\n print(x)\n x += 1\n print(x)", "✗ {file}:13\n Failed due to an error:\n Traceback omitted\n NameError: name 'x' is not defined\n Ran code:\n print(x)\n x += 1\n print(x)", '✓ {file}:15', '✓ {file}:16', '✓ {file}:28', '✓ {file}:29', "✗ {file}:30\n Variable 'x' with value:\n 5\n was NOT equivalent to the expected value:\n 6\n Ran code:\n x = 3\n print(x)\n x += 1\n print(x)\n x += 1"], 'multi': ['✓ {file}:7\n Result:\n 0\n was equivalent to the expected value:\n 0\n Test expression was:\n i\n Values were:\n i = 0', '✓ {file}:7\n Result:\n 1\n was equivalent to the expected value:\n 1\n Test expression was:\n i + 1\n Values were:\n i = 0', '✓ {file}:7\n Result:\n 0\n was equivalent to the expected value:\n 0\n Test expression was:\n i * i\n Values were:\n i = 0', '✓ {file}:7\n Result:\n 1\n was equivalent to the expected value:\n 1\n Test expression was:\n i\n Values were:\n i = 1', '✓ {file}:7\n Result:\n 2\n was equivalent to the expected value:\n 2\n Test expression was:\n i + 1\n Values were:\n i = 1', '✓ {file}:7\n Result:\n 1\n was equivalent to the expected value:\n 1\n Test expression was:\n i * i\n Values were:\n i = 1', '✓ {file}:7\n Result:\n 2\n was equivalent to the expected value:\n 2\n Test expression was:\n i\n Values were:\n i = 2', '✓ {file}:7\n Result:\n 3\n was equivalent to the expected value:\n 3\n Test expression was:\n i + 1\n Values were:\n i = 2', '✓ {file}:7\n Result:\n 4\n was equivalent to the expected value:\n 4\n Test expression was:\n i * i\n Values were:\n i = 2', '✓ {file}:9\n Result:\n (1, 2, 3)\n was equivalent to the expected value:\n (1, 2, 3)\n Test expression was:\n (\n 1,\n 2,\n 3\n )'], 'runfile': ['✓ {file}:9', '✓ {file}:35', "✗ {file}:42\n Custom check failed:\n failure message\n Ran file 'io_example.py'", '✓ {file}:57', "✗ {file}:58\n Custom check failed:\n 'Hi Tester!' did not match 'Hi Tester?'\n Ran file 'io_example.py'"], 'tracing': ['3 input("What is your name? ") ⇒ \'Tester\'', "4 name ⇒ 'Tester'", '4 "Hello " + opt.trace(name) ⇒ \'Hello Tester\'', "5 '=' * len(greeting) ⇒ '============'", '6 print(greeting) ⇒ None', "7 underline ⇒ '============'", '9 "ha" * 50 ⇒ \'hahahahahahahahahahahahahahahahahaha...', '{file}:12 "ha" * 50 ⇒ \'hahahahahahahahahahahahahahahahahaha...\n Full result is:\n \'hahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaha\''], 'catch_and_release': ['✓ {file}:19', '✓ {file}:20', '✓ {file}:24', '✓ {file}:25', '✓ {file}:30', '✓ {file}:31'], 'skip': ['✓ {file}:4', "Did not find 'indetn' in module 'optimism'...", '~ {file}:7 (skipped)', '~ {file}:8 (skipped)', "✗ {file}:19\n Result:\n 3\n was NOT equivalent to the expected value:\n 4\n Called function 'f'", '~ {file}:20 (skipped)', '~ {file}:21 (skipped)', '✓ {file}:24', "✗ {file}:29\n Result:\n 3\n was NOT equivalent to the expected value:\n 4\n Called function 'f'", '~ {file}:30 (skipped)', '~ {file}:31 (skipped)', "✗ {file}:36\n Result:\n 3\n was NOT equivalent to the expected value:\n 4\n Called function 'f'", "✗ {file}:37\n Result:\n 3\n was NOT equivalent to the expected value:\n 5\n Called function 'f'", '✓ {file}:38'], 'fragments': ['✓ {file}:19', '✓ {file}:20', '✓ {file}:21', '✓ {file}:22', '✓ {file}:23'], 'errors': ["✗ {file}:6\n Failed due to an error:\n Traceback omitted\n ZeroDivisionError: division by zero\n Called function 'f'"], 'files': ['✓ {file}:10', '✓ {file}:11', '✗ {file}:12\n File contents:\n """\\\n 1\n 2\n 3\n """\n were NOT the same as the expected file contents:\n """\\\n 1\n 2\n """\n First difference was:\n strings differ on line 3 where we got:\n \'3\'\n but we expected:\n \'\'\n Called function \'write123\' with arguments:\n filename = \'b.txt\'\n', '✗ {file}:13\n File contents:\n """\\\n 1\n 2\n 3\n """\n were NOT the same as the expected file contents:\n """\\\n 1\n 2\n hello\n """\n First difference was:\n strings differ on line 3 where we got:\n \'3\'\n but we expected:\n \'hello\'\n Called function \'write123\' with arguments:\n filename = \'b.txt\'\n', '✓ {file}:23', '✗ {file}:25\n File contents:\n """\\\n abc\\r\n def\\r\n """\n were NOT the same as the expected file contents:\n """\\\n abc\n def\n """\n First difference was:\n strings differ on line 1 where we got:\n \'abc\\r\'\n but we expected:\n \'abc\'\n Called function \'writeReturny\' with arguments:\n filename = \'a.txt\'\n', '✓ {file}:37', '✓ {file}:39', '✓ {file}:46', "✗ {file}:48\n Result:\n 'abc\\ndef'\n was NOT equivalent to the expected value:\n 'abc\\ndef\\n'\n Test expression was:\n 'abc\\ndef'\n"], 'code': ['✓ {file}:21', '✓ {file}:24', '✓ {file}:25', '✓ {file}:26', '✓ {file}:40', '✓ {file}:41', "✗ {file}:42\n Code does not contain the expected structure:\n at least 1 definition(s) of functionName\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 2 partial match(es):\n Partial match: FunctionDef on line 10\n Partial match: FunctionDef on line 99\n checked code in file '{full_file}'", '✓ {file}:44', "✗ {file}:45\n Code does not contain the expected structure:\n at least 1 function definition(s) that also contain(s):\n at least 1 loop(s) or generator expression(s)\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 2 partial match(es):\n Partial match: FunctionDef on line 10\n Partial match: FunctionDef on line 99\n checked code in file '{full_file}'", "✗ {file}:46\n Code does not contain the expected structure:\n at least 1 loop(s) or generator expression(s) that also contain(s):\n at least 1 function definition(s)\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: For on line 29\n checked code in file '{full_file}'", "✗ {file}:47\n Code does not contain the expected structure:\n at least 1 while loop(s)\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: For on line 29\n checked code in file '{full_file}'", '✓ {file}:48', '✓ {file}:50', '✓ {file}:53', '✓ {file}:56', "✗ {file}:59\n Code does not contain the expected structure:\n at least 1 loop(s) or generator expression(s) that also contain(s):\n 4 call(s) to print\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: For on line 29\n checked code in file '{full_file}'", "✗ {file}:62\n Code does not contain the expected structure:\n at least 1 loop(s) or generator expression(s) that also contain(s):\n at least 4 call(s) to print\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: For on line 29\n checked code in file '{full_file}'", '✓ {file}:65', "✗ {file}:68\n Code does not contain the expected structure:\n at least 1 loop(s) or generator expression(s) that also contain(s):\n no call(s) to print\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: For on line 29\n checked code in file '{full_file}'", '✓ {file}:71', '✓ {file}:75', "✗ {file}:78\n Code does not contain the expected structure:\n at least 1 if/else statement(s) or expression(s) that also contain(s):\n at least 1 operator '>'\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 1 partial match(es):\n Partial match: If on line 33\n checked code in file '{full_file}'", '✓ {file}:81', '✓ {file}:84', '✓ {file}:90', '✓ {file}:91', '✓ {file}:92', '✗ {file}:93\n Code does not contain the expected structure:\n at least 1 constant 2.0\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 60 partial match(es):\n Partial match: Constant on line 1\n Partial match: Constant on line 7', '✓ {file}:94', '✗ {file}:95\n Code does not contain the expected structure:\n at least 1 constant 5.0\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 60 partial match(es):\n Partial match: Constant on line 1\n Partial match: Constant on line 7', '✓ {file}:104', '✓ {file}:107', "✗ {file}:110\n Code does not contain the expected structure:\n at least 1 definition(s) of aug that also contain(s):\n no operator '/'\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 2 partial match(es):\n Partial match: FunctionDef on line 99\n Partial match: FunctionDef on line 10\n"], 'reverse_tracing': [], 'suites': ['✓ {file}:14', '✓ {file}:16', '✓ {file}:17', '✓ {file}:20', '✓ {file}:24', '✗ {file}:26\n Printed lines:\n """\\\n 4\n """\n were NOT the same as the expected printed lines:\n """\\\n 5\n """\n First difference was:\n strings differ on line 1 where we got:\n \'4\'\n but we expected:\n \'5\'\n Called function \'f\' with arguments:\n x = 4\n y = 5', '✓ {file}:27', '✓ {file}:29', "-- Summary for suite 'B' --\n1 of the 4 expectation(s) were NOT met:\n ✗ {file}:26\n----", "-- Summary for suite 'A' --\nAll 4 expectation(s) were met.\n----"], 'literals': ['✓ {file}:17', '✓ {file}:18', '✓ {file}:19', '✓ {file}:20', '✓ {file}:21', '✓ {file}:22', '✓ {file}:23', '✓ {file}:27', '✓ {file}:28', '✓ {file}:29', '✓ {file}:30', '✓ {file}:31', '✓ {file}:32', '✓ {file}:33', '✓ {file}:34', '✗ {file}:36\n Code does not contain the expected structure:\n at least 1 literal [4, 5, 6]\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 6 partial match(es):\n Partial match: List on line 2\n Partial match: Tuple on line 3\n Partial match: List on line 6\n Partial match: List on line 7\n Partial match: Tuple on line 7\n Partial match: List on line 7\n checked code from block at {file}:16', '✗ {file}:37\n Code does not contain the expected structure:\n at least 1 literal (1, 2, 3)\n Although it does partially satisfy the requirement:\n Requirement partially satisfied via 0 full and 6 partial match(es):\n Partial match: List on line 2\n Partial match: Tuple on line 3\n Partial match: List on line 6\n Partial match: List on line 7\n Partial match: Tuple on line 7\n Partial match: List on line 7\n checked code from block at {file}:16', '✗ {file}:40\n Code does not contain the expected structure:\n at least 1 literal(s)\n checked code from block at {file}:39', '✗ {file}:41\n Code does not contain the expected structure:\n at least 1 list literal(s)\n checked code from block at {file}:39', '✗ {file}:42\n Code does not contain the expected structure:\n at least 1 tuple literal(s)\n checked code from block at {file}:39', '✗ {file}:43\n Code does not contain the expected structure:\n at least 1 set literal(s)\n checked code from block at {file}:39', '✗ {file}:44\n Code does not contain the expected structure:\n at least 1 dict literal(s)\n checked code from block at {file}:39', '✓ {file}:47', '✓ {file}:48', '✓ {file}:49', '✓ {file}:50', '✓ {file}:51', '✓ {file}:54'], 'structure': ['✓ {file}:18', "✗ {file}:22\n Structure of the result:\n @0: [1, 2, @1, @0]\n @1: [3, 4]\n was NOT equivalent to the expected structure:\n @0: [1, 2, @1, @0]\n @1: [3, 4]\n @2: ['extra']\n Differences:\n did not find a match for list @2\n Called function 'f'\n", '✓ {file}:27', '✓ {file}:33', '✓ {file}:34', '✓ {file}:35', '✓ {file}:52', '✓ {file}:61', '✓ {file}:67', '✓ {file}:74', "✗ {file}:75\n Variable 'x' had structure:\n x: @0\n @0: [@1]\n @1: [1, 2]\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: [@1]\n @1: [1]\n Differences:\n list @1: list has 1 extra item(s)\n Ran code:\n x = [[1, 2]]\n", "✗ {file}:76\n Variable 'x' had structure:\n x: @0\n @0: [@1]\n @1: [1, 2]\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: [@1]\n @1: [1, 2, 3]\n Differences:\n list @1: list has 1 missing item(s)\n Ran code:\n x = [[1, 2]]\n", "✗ {file}:77\n Variable 'x' had structure:\n x: @0\n @0: [@1]\n @1: [1, 2]\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: [@1]\n @1: [3, 4]\n Differences:\n list @1 slot 0: value 1 differs from expected value 3\n list @1 slot 1: value 2 differs from expected value 4\n Ran code:\n x = [[1, 2]]\n", '✓ {file}:80', "✗ {file}:81\n Variable 'x' had structure:\n x: @0\n @0: (@1,)\n @1: (1, 2)\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: (@1,)\n @1: (1,)\n Differences:\n tuple @1: tuple has 1 extra item(s)\n Ran code:\n x = ((1, 2),)\n", "✗ {file}:82\n Variable 'x' had structure:\n x: @0\n @0: (@1,)\n @1: (1, 2)\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: (@1,)\n @1: (1, 2, 3)\n Differences:\n tuple @1: tuple has 1 missing item(s)\n Ran code:\n x = ((1, 2),)\n", "✗ {file}:83\n Variable 'x' had structure:\n x: @0\n @0: (@1,)\n @1: (1, 2)\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: (@1,)\n @1: (3, 4)\n Differences:\n tuple @1 slot 0: value 1 differs from expected value 3\n tuple @1 slot 1: value 2 differs from expected value 4\n Ran code:\n x = ((1, 2),)\n", '✓ {file}:91', '✓ {file}:96', '✓ {file}:101', "✗ {file}:105\n Variable 'x' had structure:\n x: @0\n @0: (@1, @1)\n @1: (1, 2)\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: (@1, @1)\n @1: (1, 2, 3)\n Differences:\n tuple @1: tuple has 1 missing item(s)\n Ran code:\n x = ((1, 2),)\n x = x + (x[0],)\n y = x[0]\n y = y + (3,)\n", "✗ {file}:110\n Variable 'x' had structure:\n x: @0\n @0: (@1, @1)\n @1: (1, 2)\n which was NOT structurally equivalent to to the expected structure:\n x: @0\n @0: (@3, @3)\n @3: (1, 2, 3)\n Differences:\n tuple @1: tuple has 1 missing item(s)\n Ran code:\n x = ((1, 2),)\n x = x + (x[0],)\n y = x[0]\n y = y + (3,)\n"], 'doctests': ["✗ {file}:22\n Docstring was absent or empty.\n checked code of function 'a'\n", "✗ {file}:23\n Found only 0 distinct doctest example(s) (required 1).\n checked code of function 'a'\n", "✗ {file}:24\n No doctests were found.\n checked code of function 'a'\n", "✗ {file}:33\n Docstring was absent or empty.\n checked code of function 'b'\n", "✗ {file}:34\n Found only 0 distinct doctest example(s) (required 1).\n checked code of function 'b'\n", "✗ {file}:35\n No doctests were found.\n checked code of function 'b'\n✓ {file}:44\n", "✗ {file}:45\n Found only 0 distinct doctest example(s) (required 1).\n checked code of function 'c'\n", "✗ {file}:46\n No doctests were found.\n checked code of function 'c'\n", '✓ {file}:61', '✓ {file}:62', '✓ {file}:63', '✓ {file}:64', "✗ {file}:65\n Found only 1 distinct doctest example(s) (required 2).\n checked code of function 'd'\n", '✓ {file}:76', "✗ {file}:77\n At {file}:72, output didn't match what the test expected. Expected:\n 4\n Got:\n 3\n checked code of function 'e'\n", '✓ {file}:92', '✓ {file}:93', '✓ {file}:94', "✗ {file}:95\n Found only 3 distinct doctest example(s) (required 4).\n checked code of function 'f'\n", '✓ {file}:96', '✓ {file}:96', '✓ {file}:96', '✓ {file}:114', '✓ {file}:115', "✗ {file}:116\n Found only 3 distinct doctest example(s) (required 4).\n checked code of function 'g'\n", '✓ {file}:117', '✓ {file}:117', '✓ {file}:117', '✓ {file}:119', '✓ {file}:120', "✗ {file}:122\n At {file}:104, output didn't match what the test expected. Expected:\n 2\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", "✗ {file}:122\n At {file}:106, output didn't match what the test expected. Expected:\n 3\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", "✗ {file}:122\n At {file}:108, output didn't match what the test expected. Expected:\n 4\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", "✗ {file}:124\n At {file}:104, output didn't match what the test expected. Expected:\n 2\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", "✗ {file}:124\n At {file}:106, output didn't match what the test expected. Expected:\n 3\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", "✗ {file}:124\n At {file}:108, output didn't match what the test expected. Expected:\n 4\n Got:\n Unexpected exception:\n Traceback omitted\n NameError: name 'g' is not defined\n checked code of function 'g'\n", '✓ {file}:139', '✓ {file}:140', "✗ {file}:141\n Found only 3 distinct doctest example(s) (required 4).\n checked code of function 'h'\n", '✓ {file}:142', '✓ {file}:142', "✗ {file}:142\n At {file}:135, output didn't match what the test expected. Expected:\n 4\n Got:\n 3\n checked code of function 'h'\n", '✓ {file}:157', "✗ {file}:158\n Found only 1 distinct doctest example(s) (required 2; ignored 2 duplicates).\n checked code of function 'i'\n", '✓ {file}:159', '✓ {file}:159', '✓ {file}:159', '✓ {file}:175', "✗ {file}:176\n At {file}:166, output didn't match what the test expected. Expected:\n 3\n Got:\n 2\n checked code of function 'j'\n", '✓ {file}:176', '✓ {file}:176', '✓ {file}:201', "✗ {file}:202\n Found only 2 distinct doctest example(s) (required 3).\n checked code of function 'k'\n", '✓ {file}:203', '✓ {file}:203', '✓ {file}:221', "✗ {file}:222\n Found only 3 distinct doctest example(s) (required 4).\n checked code of function 'l'\n", '✓ {file}:223', '✓ {file}:223', '✓ {file}:223', '✓ {file}:239', "✗ {file}:240\n Found only 3 distinct doctest example(s) (required 4).\n checked code of function 'm'\n", '✓ {file}:241', '✓ {file}:241', '✗ {file}:241\n At {file}:235, output didn\'t match what the test expected. Expected:\n \'11\'\n Got:\n Unexpected exception:\n Traceback omitted\n TypeError: can only concatenate str (not "int") to str\n checked code of function \'m\'\n', '✓ {file}:264', "✗ {file}:265\n Found only 1 distinct doctest example(s) (required 2; ignored 4 duplicates).\n checked code of function 'n'\n", '✓ {file}:266', '✓ {file}:266', '✓ {file}:266', '✓ {file}:266', '✓ {file}:266', '✓ {file}:281', "✗ {file}:282\n Found only 1 distinct doctest example(s) (required 2).\n checked code of function 'o'\n", '✓ {file}:283', '✓ {file}:300', '✓ {file}:300', '✓ {file}:300', '✓ {file}:300', '✓ {file}:303', "✗ {file}:304\n Found only 4 distinct doctest example(s) (required 5).\n checked code of function 'p'\n", '✓ {file}:306', "✗ {file}:307\n Found only 3 matching distinct doctest example(s) (required 4).\n checked code of function 'p'\n", '✓ {file}:309', "✗ {file}:310\n Found only 1 matching distinct doctest example(s) (required 2).\n checked code of function 'p'\n", '✓ {file}:312', "✗ {file}:313\n Found only 1 matching distinct doctest example(s) (required 2).\n checked code of function 'p'\n", '✓ {file}:315', "✗ {file}:316\n Found only 2 matching distinct doctest example(s) (required 3).\n checked code of function 'p'\n", '✓ {file}:319', "✗ {file}:320\n Found only 1 matching distinct doctest example(s) (required 2).\n checked code of function 'p'\n", '✓ {file}:322', "✗ {file}:323\n Found only 2 matching distinct doctest example(s) (required 3).\n checked code of function 'p'\n", '✗ {file}:325', " Found only 0 matching distinct doctest example(s) (required 1).\n checked code of function 'p'\n", '✓ {file}:327', "✗ {file}:328\n Found only 1 matching distinct doctest example(s) (required 2).\n checked code of function 'p'\n", '✓ {file}:362', '✓ {file}:363', '✗ {file}:364\n Found only 3 distinct doctest example(s) (required 4; ignored 1 duplicates).\n checked code from block at {file}:332\n', '✓ {file}:365', '✓ {file}:365', '✓ {file}:365', '✓ {file}:365', '✗ {file}:370\n Docstring was absent or empty.\n checked code from block at {file}:368\n', '✗ {file}:371\n Found only 0 distinct doctest example(s) (required 1).\n checked code from block at {file}:368\n', '✗ {file}:372\n No doctests were found.\n checked code from block at {file}:368\n', '✗ {file}:377\n Docstring was absent or empty.\n checked code from block at {file}:375\n', '✓ {file}:378', '✗ {file}:379\n Found only 1 distinct doctest example(s) (required 2).\n checked code from block at {file}:375\n', '✓ {file}:380', "✗ {file}:384\n At code block from {file}:383:4, output didn't match what the test expected. Expected:\n 4\n Got:\n 5\n checked code from block at {file}:383\n", '✓ {file}:390', '✓ {file}:391', '✓ {file}:391', '✓ {file}:391', '✓ {file}:391', '✓ {file}:391', '✓ {file}:392', "✗ {file}:393\n Found only 5 distinct doctest example(s) (required 6).\n checked code in file 'doc_example.py'\n", '✓ {file}:394', "✗ {file}:395\n Found only 2 matching distinct doctest example(s) (required 3).\n checked code in file 'doc_example.py'\n"], 'memoryReports': ['✓ {file}:22', '✓ {file}:23']}
STDOUT_EXPECT =
{'catch_and_release': ['one Z!', 'Re-providing input was blocked.', 'Hello', 'two Z!'], 'code': ['0', '1', '2', '3'], 'suites': ['3', 'a', "Outcomes in suite A:\n(True, '{file}:14', '✓ {file}:14')\n(True, '{file}:16', '✓ {file}:16')\n(True, '{file}:17', '✓ {file}:17')\n(True, '{file}:20', '✓ {file}:20')", 'Outcomes in suite B:\n(True, \'{file}:24\', \'✓ {file}:24\')\n(False, \'{file}:26\', \'✗ {file}:26\\n Printed lines:\\n """\\\\\\n 4\\n """\\n were NOT the same as the expected printed lines:\\n """\\\\\\n 5\\n """\\n First difference was:\\n strings differ on line 1 where we got:\\n \\\'4\\\'\\n but we expected:\\n \\\'5\\\'\\n Called function \\\'f\\\' with arguments:\\n x = 4\\n y = 5\')\n(True, \'{file}:27\', \'✓ {file}:27\')\n(True, \'{file}:29\', \'✓ {file}:29\')', "Outcomes in suite A (again):\n(True, '{file}:14', '✓ {file}:14')\n(True, '{file}:16', '✓ {file}:16')\n(True, '{file}:17', '✓ {file}:17')\n(True, '{file}:20', '✓ {file}:20')\n(True, '{file}:46', '✓ {file}:46')", 'No more outcomes in suite A: []', 'No more outcomes in suite B: []', 'No more suite B.'], 'memoryReports': ["words: @0\npair: @3\n@0: [@1, @2]\n@3: [@0, @0]\n@1: 'hi'\n@2: 'bye'\n", "pair: @0\nwords: @1\nknot: @4\n@0: [@1, @1]\n@1: [@2, @3]\n@4: [@0, @1, @4]\n@2: 'hi'\n@3: 'bye'\n"]}
def
run_example(mname, inputs=[]):
1338def run_example(mname, inputs=[]): 1339 """ 1340 Runs a module and captures stderr and stdout, returning a tuple 1341 containing the imported module, the captured stderr string, and the 1342 captured stdout string. The given input strings are provided as stdin 1343 during the run. 1344 """ 1345 old_stderr = sys.stderr 1346 old_stdout = sys.stdout 1347 old_stdin = sys.stdin 1348 old_print_to = optimism.PRINT_TO 1349 sys.stderr = io.StringIO() 1350 sys.stdout = io.StringIO() 1351 sys.stdin = io.StringIO('\n'.join(inputs) + '\n') 1352 optimism.PRINT_TO = sys.stderr 1353 1354 filePath = os.path.abspath(mname + '.py') 1355 1356 try: 1357 spec = importlib.util.spec_from_file_location(mname, filePath) 1358 module = importlib.util.module_from_spec(spec) 1359 # Note we skip adding it to sys.modules 1360 spec.loader.exec_module(module) 1361 errOut = sys.stderr.getvalue() 1362 stdOut = sys.stdout.getvalue() 1363 1364 finally: 1365 sys.stderr = old_stderr 1366 sys.stdout = old_stdout 1367 sys.stdin = old_stdin 1368 optimism.PRINT_TO = old_print_to 1369 1370 return (module, errOut, stdOut)
Runs a module and captures stderr and stdout, returning a tuple containing the imported module, the captured stderr string, and the captured stdout string. The given input strings are provided as stdin during the run.
def
test_all():
1373def test_all(): 1374 """ 1375 Tests each example file. The `examples` directory must be in the 1376 same place that this `test_examples.py` file lives. 1377 """ 1378 olddir = os.getcwd() 1379 try: 1380 os.chdir(os.path.join(os.path.dirname(__file__), "examples")) 1381 sys.path.insert(0, '.') 1382 for (mname, inputs) in EXAMPLES: 1383 optimism.detailLevel(0) 1384 optimism.deleteAllTestSuites() 1385 optimism.colors(False) 1386 module, output, stdout = run_example(mname, inputs) 1387 # Replace tracebacks with generic forms so we can match on 1388 # specific errors being reported while ignoring the files & lines 1389 # where they are reported. 1390 stdout = re.sub( 1391 r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)", 1392 "Traceback omitted\n\\1", 1393 stdout, 1394 flags=re.MULTILINE | re.DOTALL 1395 ) 1396 output = re.sub( 1397 r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)", 1398 "Traceback omitted\n\\1", 1399 output, 1400 flags=re.MULTILINE | re.DOTALL 1401 ) 1402 #output = re.sub(r"Traceback \(most recent call last\).*?NameError:", "HAHAHA", output, flags=re.MULTILINE | re.DOTALL) 1403 # Scrub line numbers from tracebacks so our expectations don't 1404 # become hopelessly fragile 1405 stdout = re.sub(r", line \d+,", ", line X,", stdout) 1406 output = re.sub(r", line \d+,", ", line X,", output) 1407 for ex in EXPECTATIONS[mname]: 1408 exp = ex.format( 1409 file=os.path.basename(module.__file__), 1410 dir=( 1411 os.path.split(module.__file__)[0] + '/' 1412 if better_line_numbers 1413 else '' 1414 ), 1415 full_file=module.__file__, 1416 opt_file=optimism.__file__, 1417 ) 1418 # Redundant, but makes issues easier to diagnose 1419 for line in exp.splitlines(): 1420 if line not in output: 1421 print("\n\nLINE:\n" + line) 1422 print("\n\nOUTPUT:\n" + output) 1423 assert (line in output), (line, output) 1424 if exp not in output: 1425 print("\n\nEXP:\n" + exp) 1426 print("\n\nOUTPUT:\n" + output) 1427 assert (exp in output), (exp, output) 1428 if mname in STDOUT_EXPECT: 1429 for ex in STDOUT_EXPECT[mname]: 1430 exp = ex.format( 1431 file=os.path.basename(module.__file__), 1432 dir=os.path.split(module.__file__)[0], 1433 full_file=module.__file__, 1434 opt_file=optimism.__file__, 1435 ) 1436 for line in exp.splitlines(): 1437 assert (line in stdout), stdout 1438 assert (exp in stdout), stdout 1439 finally: 1440 os.chdir(olddir)
Tests each example file. The examples directory must be in the
same place that this test_examples.py file lives.