import unittest

import lit.worker
import lit.LitConfig

"""
TestCase adaptor for providing a Python 'unittest' compatible interface to 'lit'
tests.
"""


class UnresolvedError(RuntimeError):
    pass


class LitTestCase(unittest.TestCase):
    def __init__(self, test, lit_config):
        unittest.TestCase.__init__(self)
        self._test = test
        self._lit_config = lit_config

    def id(self):
        return self._test.getFullName()

    def shortDescription(self):
        return self._test.getFullName()

    def runTest(self):
        # Run the test.
        result = lit.worker._execute_test(self._test, self._lit_config)

        # Adapt the result to unittest.
        if result.code is lit.Test.UNRESOLVED:
            raise UnresolvedError(result.output)
        elif result.code.isFailure:
            self.fail(result.output)


def load_test_suite(inputs):
    import platform
    windows = platform.system() == 'Windows'

    # Create the global config object.
    lit_config = lit.LitConfig.LitConfig(
        progname='lit',
        path=[],
        quiet=False,
        useValgrind=False,
        valgrindLeakCheck=False,
        valgrindArgs=[],
        noExecute=False,
        debug=False,
        isWindows=windows,
        params={})

    # Perform test discovery.
    tests = lit.discovery.find_tests_for_inputs(lit_config, inputs)
    test_adaptors = [LitTestCase(t, lit_config) for t in tests]

    # Return a unittest test suite which just runs the tests in order.
    return unittest.TestSuite(test_adaptors)
