#!/usr/bin/env python
# We assume that tests are in ./src relative to executor
# (*not* relative to this file)
# TODO: replace with a standard library e.g. schooltest, nose ...
import os
import sys
import re
import unittest
from optparse import OptionParser

# Hack to get path to this directory
srcpath = os.path.abspath('./src')

def makeTestSuite(testCaseRegex = ""):
    """
    Walk all directories in package searching for tests.
    Tests are identified by name which must be of form:
        <something>test.py (ignoring case)
    @param testCaseRegex: regex to select names of test cases. Optional
        parameter, defaulting to empty string.
    """
    allFiles = []
    for root, dirs, files in os.walk(srcpath):
        # get the path offset from srcpath
        # could use os.path.commonprefix
        pathOffset = root[len(srcpath) + 1:]
        test = re.compile(testCaseRegex + '.*test\.py$', re.IGNORECASE)
        files = filter(test.search, files)
        files = [pathOffset + '/' +  ff for ff in files]
        allFiles += files
    filenameToModuleName = lambda f: os.path.splitext(f)[0].replace('/','.')
    moduleNames = map(filenameToModuleName, allFiles)
    modules =[__import__(tmp1,'','','*') for tmp1 in moduleNames]
    load = unittest.defaultTestLoader.loadTestsFromModule
    return unittest.TestSuite(map(load, modules))
    
    if len(sys.argv) > 1 and sys.argv[1] == 'test':
        testCaseRegex = ''
        if len(sys.argv) > 2:
            testCaseRegex = sys.argv[2]
    else:
        usage()

if __name__ == "__main__":
    usage  = \
'''usage: %prog [options] [test-case-regex]

Run tests. If regex supplied run only those tests which match (otherwise run
all)
'''
    parser = OptionParser(usage)
    parser.add_option('-v', '--verbose',
        action='store_true', dest='verbose', default=False,
        help='Be verbose in printing status messages')
    parser.add_option('-l', '--level',
        action='store', type='int', dest='level', default=1,
        help='Verbosity level of test runner')
    
    (options, args) = parser.parse_args()
    # by default always 1 argument (name of file itself)
    testCaseRegex = ''
    if len(args) == 0:
        testCaseRegex = ''
    elif len(args) == 1:
        testCaseRegex = args[0]
    else:
        print 'ERROR: you have supplied too many arguments\n'
        parser.print_help()
        sys.exit(0)
    testSuite = makeTestSuite(testCaseRegex) 
    testRunner = unittest.TextTestRunner(verbosity=options.level)
    testRunner.run(testSuite)
