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

Tests each example file. The examples directory must be in the same place that this test_examples.py file lives.