runtests.py (3955B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 6 import argparse 7 import glob 8 import os 9 import sys 10 import traceback 11 12 import WebIDL 13 14 15 class TestHarness: 16 def __init__(self, test, verbose): 17 self.test = test 18 self.verbose = verbose 19 self.printed_intro = False 20 self.passed = 0 21 self.failures = [] 22 23 def start(self): 24 if self.verbose: 25 self.maybe_print_intro() 26 27 def finish(self): 28 if self.verbose or self.printed_intro: 29 print("Finished test %s" % self.test) 30 31 def maybe_print_intro(self): 32 if not self.printed_intro: 33 print("Starting test %s" % self.test) 34 self.printed_intro = True 35 36 def test_pass(self, msg): 37 self.passed += 1 38 if self.verbose: 39 print("TEST-PASS | %s" % msg) 40 41 def test_fail(self, msg): 42 self.maybe_print_intro() 43 self.failures.append(msg) 44 print("TEST-UNEXPECTED-FAIL | %s" % msg) 45 46 def ok(self, condition, msg): 47 if condition: 48 self.test_pass(msg) 49 else: 50 self.test_fail(msg) 51 52 def check(self, a, b, msg): 53 if a == b: 54 self.test_pass(msg) 55 else: 56 self.test_fail(msg + " | Got %s expected %s" % (a, b)) 57 58 def should_throw(self, parser, code, msg): 59 parser = parser.reset() 60 threw = False 61 try: 62 parser.parse(code) 63 parser.finish() 64 except Exception: 65 threw = True 66 67 self.ok(threw, "Should have thrown: %s" % msg) 68 69 70 def run_tests(tests, verbose): 71 testdir = os.path.join(os.path.dirname(__file__), "tests") 72 if not tests: 73 tests = glob.iglob(os.path.join(testdir, "*.py")) 74 sys.path.append(testdir) 75 76 all_passed = 0 77 failed_tests = [] 78 79 for test in tests: 80 (testpath, ext) = os.path.splitext(os.path.basename(test)) 81 _test = __import__(testpath, globals(), locals(), ["WebIDLTest"]) 82 83 harness = TestHarness(test, verbose) 84 harness.start() 85 try: 86 _test.WebIDLTest.__call__(WebIDL.Parser(), harness) 87 except Exception as ex: 88 harness.test_fail("Unhandled exception in test %s: %s" % (testpath, ex)) 89 traceback.print_exc() 90 finally: 91 harness.finish() 92 all_passed += harness.passed 93 if harness.failures: 94 failed_tests.append((test, harness.failures)) 95 96 if verbose or failed_tests: 97 print() 98 print("Result summary:") 99 print("Successful: %d" % all_passed) 100 print("Unexpected: %d" % sum(len(failures) for _, failures in failed_tests)) 101 for test, failures in failed_tests: 102 print("%s:" % test) 103 for failure in failures: 104 print("TEST-UNEXPECTED-FAIL | %s" % failure) 105 return 1 if failed_tests else 0 106 107 108 def get_parser(): 109 usage = """%(prog)s [OPTIONS] [TESTS] 110 Where TESTS are relative to the tests directory.""" 111 parser = argparse.ArgumentParser(usage=usage) 112 parser.add_argument( 113 "-q", 114 "--quiet", 115 action="store_false", 116 dest="verbose", 117 help="Don't print passing tests.", 118 default=None, 119 ) 120 parser.add_argument( 121 "-v", 122 "--verbose", 123 action="store_true", 124 dest="verbose", 125 help="Run tests in verbose mode.", 126 ) 127 parser.add_argument("tests", nargs="*", help="Tests to run") 128 return parser 129 130 131 if __name__ == "__main__": 132 parser = get_parser() 133 args = parser.parse_args() 134 if args.verbose is None: 135 args.verbose = True 136 137 # Make sure the current directory is in the python path so we can cache the 138 # result of the webidlyacc.py generation. 139 sys.path.append(".") 140 141 sys.exit(run_tests(args.tests, verbose=args.verbose))