#!/usr/bin/python from collections import defaultdict from os import listdir from os.path import abspath, dirname, isdir, isfile, join, realpath, relpath, splitext import re from subprocess import Popen, PIPE import sys # Runs the tests. WREN_DIR = dirname(realpath(__file__)) TEST_DIR = join(WREN_DIR, 'test') if sys.platform == 'win32': WREN_APP = join(WREN_DIR, 'Debug', 'wren.exe') if not isfile(WREN_DIR): WREN_APP = join(WREN_DIR, 'Release', 'wren.exe') if not isfile(WREN_APP): sys.exit('Cannot find wren.exe!') elif sys.platform.startswith('linux'): WREN_APP = join(WREN_DIR, '1', 'out', 'Debug', 'wren') if not isfile(WREN_APP): WREN_APP = join(WREN_DIR, '1', 'out', 'Release', 'wren') if not isfile(WREN_APP): sys.exit('Cannot find wren!') elif sys.platform.startswith('darwin'): WREN_APP = join(WREN_DIR, 'build', 'Debug', 'wren') if not isfile(WREN_APP): WREN_APP = join(WREN_DIR, 'build', 'Release', 'wren') if not isfile(WREN_APP): sys.exit('Cannot find wren!') else: sys.exit('System not supported!') EXPECT_PATTERN = re.compile(r'// expect: (.*)') SKIP_PATTERN = re.compile(r'// skip: (.*)') NONTEST_PATTERN = re.compile(r'// nontest') if sys.platform == 'win32': class color: GREEN = '' RED = '' DEFAULT = '' PINK = '' YELLOW = '' else: class color: GREEN = '\033[32m' RED = '\033[31m' DEFAULT = '\033[0m' PINK = '\033[91m' YELLOW = '\033[33m' passed = 0 failed = 0 skipped = defaultdict(int) num_skipped = 0; def walk(dir, callback): """ Walks [dir], and executes [callback] on each file. """ dir = abspath(dir) for file in [file for file in listdir(dir) if not file in [".",".."]]: nfile = join(dir, file) if isdir(nfile): walk(nfile, callback) else: callback(nfile) def print_line(line=None): # Erase the line. print '\033[2K', # Move the cursor to the beginning. print '\r', if line: print line, sys.stdout.flush() def run_test(path): global passed global failed global skipped global num_skipped if (splitext(path)[1] != '.wren'): return # Check if we are just running a subset of the tests. if len(sys.argv) == 2: this_test = relpath(path, join(WREN_DIR, 'test')) if not this_test.startswith(sys.argv[1]): return # Make a nice short path relative to the working directory. path = relpath(path) # Read the test and parse out the expectations. expect_output = [] expect_error = [] expect_return = 0 print_line('Passed: ' + color.GREEN + str(passed) + color.DEFAULT + ' Failed: ' + color.RED + str(failed) + color.DEFAULT + ' Skipped: ' + color.YELLOW + str(num_skipped) + color.DEFAULT) line_num = 1 with open(path, 'r') as file: for line in file: match = EXPECT_PATTERN.search(line) if match: expect_output.append((match.group(1), line_num)) match = SKIP_PATTERN.search(line) if match: num_skipped += 1 skipped[match.group(1)] += 1 return match = NONTEST_PATTERN.search(line) if match: # Not a test file at all, so ignore it. return line_num += 1 # Invoke wren and run the test. proc = Popen([WREN_APP, path], stdout=PIPE, stderr=PIPE) (out, err) = proc.communicate() (out, err) = out.replace('\r\n', '\n'), err.replace('\r\n', '\n') fails = [] # Validate the exit code. if proc.returncode != 0: fails.append('Expected return code 0 and got {0}.'. format(proc.returncode)) else: # Validate the output. expect_index = 0 # Remove the trailing last empty line. out_lines = out.split('\n') if out_lines[-1] == '': del out_lines[-1] for line in out_lines: if expect_index >= len(expect_output): fails.append('Got output "{0}" when none was expected.'. format(line)) elif expect_output[expect_index][0] != line: fails.append('Expected output "{0}" on line {1} and got "{2}".'. format(expect_output[expect_index][0], expect_output[expect_index][1], line)) expect_index += 1 while expect_index < len(expect_output): fails.append('Missing expected output "{0}" on line {1}.'. format(expect_output[expect_index][0], expect_output[expect_index][1])) expect_index += 1 # Display the results. if len(fails) == 0: passed += 1 #print color.GREEN + 'PASS' + color.DEFAULT + ': ' + path else: failed += 1 print_line(color.RED + 'FAIL' + color.DEFAULT + ': ' + path) print for fail in fails: print ' ', color.PINK + fail + color.DEFAULT print walk(TEST_DIR, run_test) print_line() if failed == 0: print 'All ' + color.GREEN + str(passed) + color.DEFAULT + ' tests passed.' else: print (color.GREEN + str(passed) + color.DEFAULT + ' tests passed. ' + color.RED + str(failed) + color.DEFAULT + ' tests failed.') for key in sorted(skipped.keys()): print ('Skipped ' + color.YELLOW + str(skipped[key]) + color.DEFAULT + ' tests: ' + key)