#!/usr/bin/python

import nose
import os
import sys
import glob
from collections import OrderedDict

# Change into parent dir
os.chdir(os.path.dirname(os.path.realpath(__file__)) + "/..")

class JimOrderPlugin(nose.plugins.Plugin):
    """When searching for tests and encountering a directory that
    contains a 'test.order' file, run tests listed in that file, in the
    order that they're listed.  Globs are OK in that file and duplicates
    are removed."""
    name = 'jimorder'
    score = 10000

    def prepareTestLoader(self, loader):
        def wrap(func):
            def wrapper(name, *args, **kwargs):
                addr = nose.selector.TestAddress(
                    name, workingDir=loader.workingDir)
                try:
                    order = os.path.join(addr.filename, "test.order")
                except Exception:
                    order = None
                if order and os.path.exists(order):
                    files = []
                    for line in open(order):
                        line = line.split('#')[0].strip()
                        if not line:
                            continue
                        fn = os.path.join(addr.filename, line.strip())
                        files.extend(sorted(glob.glob(fn)) or [fn])
                    files = list(OrderedDict.fromkeys(files))
                    tests = [ wrapper(fn, *args, **kwargs) for fn in files ]
                    return loader.suiteClass(tests)
                return func(name, *args, **kwargs)
            return wrapper
        loader.loadTestsFromName = wrap(loader.loadTestsFromName)
        return loader

# Use setup.cfg for most of the test configuration.  Adding
# --with-jimorder here means that a normal "nosetests" run will
# still work, it just won't support test.order.
if __name__ == "__main__":
    nose.main(addplugins = [ JimOrderPlugin() ],
              argv = sys.argv + ["--with-jimorder"])
