# -*- coding: utf-8 -*-

# test/scaffold.py
# Part of python-daemon, an implementation of PEP 3143.
#
# Copyright © 2007–2010 Ben Finney <ben+python@benfinney.id.au>
# This is free software; you may copy, modify and/or distribute this work
# under the terms of the GNU General Public License, version 2 or later.
# No warranty expressed or implied. See the file LICENSE.GPL-2 for details.

""" Scaffolding for unit test modules.
    """

import unittest
import doctest
import logging
import os
import sys
import operator
import textwrap
from minimock import (
    Mock,
    TraceTracker as MockTracker,
    mock,
    restore as mock_restore,
    )

test_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(test_dir)
if not test_dir in sys.path:
    sys.path.insert(1, test_dir)
if not parent_dir in sys.path:
    sys.path.insert(1, parent_dir)

# Disable all but the most critical logging messages
logging.disable(logging.CRITICAL)


def get_python_module_names(file_list, file_suffix='.py'):
    """ Return a list of module names from a filename list. """
    module_names = [m[:m.rfind(file_suffix)] for m in file_list
        if m.endswith(file_suffix)]
    return module_names


def get_test_module_names(module_list, module_prefix='test_'):
    """ Return the list of module names that qualify as test modules. """
    module_names = [m for m in module_list
        if m.startswith(module_prefix)]
    return module_names


def make_suite(path=test_dir):
    """ Create the test suite for the given path. """
    loader = unittest.TestLoader()
    python_module_names = get_python_module_names(os.listdir(path))
    test_module_names = get_test_module_names(python_module_names)
    suite = loader.loadTestsFromNames(test_module_names)

    return suite


def get_function_signature(func):
    """ Get the function signature as a mapping of attributes. """
    arg_count = func.func_code.co_argcount
    arg_names = func.func_code.co_varnames[:arg_count]

    arg_defaults = {}
    func_defaults = ()
    if func.func_defaults is not None:
        func_defaults = func.func_defaults
    for (name, value) in zip(arg_names[::-1], func_defaults[::-1]):
        arg_defaults[name] = value

    signature = {
        'name': func.__name__,
        'arg_count': arg_count,
        'arg_names': arg_names,
        'arg_defaults': arg_defaults,
        }

    non_pos_names = list(func.func_code.co_varnames[arg_count:])
    COLLECTS_ARBITRARY_POSITIONAL_ARGS = 0x04
    if func.func_code.co_flags & COLLECTS_ARBITRARY_POSITIONAL_ARGS:
        signature['var_args'] = non_pos_names.pop(0)
    COLLECTS_ARBITRARY_KEYWORD_ARGS = 0x08
    if func.func_code.co_flags & COLLECTS_ARBITRARY_KEYWORD_ARGS:
        signature['var_kw_args'] = non_pos_names.pop(0)

    return signature


def format_function_signature(func):
    """ Format the function signature as printable text. """
    signature = get_function_signature(func)

    args_text = []
    for arg_name in signature['arg_names']:
        if arg_name in signature['arg_defaults']:
            arg_default = signature['arg_defaults'][arg_name]
            arg_text_template = "%(arg_name)s=%(arg_default)r"
        else:
            arg_text_template = "%(arg_name)s"
        args_text.append(arg_text_template % vars())
    if 'var_args' in signature:
        args_text.append("*%(var_args)s" % signature)
    if 'var_kw_args' in signature:
        args_text.append("**%(var_kw_args)s" % signature)
    signature_args_text = ", ".join(args_text)

    func_name = signature['name']
    signature_text = (
        "%(func_name)s(%(signature_args_text)s)" % vars())

    return signature_text


class TestCase(unittest.TestCase):
    """ Test case behaviour. """

    def failUnlessRaises(self, exc_class, func, *args, **kwargs):
        """ Fail unless the function call raises the expected exception.

            Fail the test if an instance of the exception class
            ``exc_class`` is not raised when calling ``func`` with the
            arguments ``*args`` and ``**kwargs``.

            """
        try:
            super(TestCase, self).failUnlessRaises(
                exc_class, func, *args, **kwargs)
        except self.failureException:
            exc_class_name = exc_class.__name__
            msg = (
                "Exception %(exc_class_name)s not raised"
                " for function call:"
                " func=%(func)r args=%(args)r kwargs=%(kwargs)r"
                ) % vars()
            raise self.failureException(msg)

    def failIfIs(self, first, second, msg=None):
        """ Fail if the two objects are identical.

            Fail the test if ``first`` and ``second`` are identical,
            as determined by the ``is`` operator.

            """
        if first is second:
            if msg is None:
                msg = "%(first)r is %(second)r" % vars()
            raise self.failureException(msg)

    def failUnlessIs(self, first, second, msg=None):
        """ Fail unless the two objects are identical.

            Fail the test unless ``first`` and ``second`` are
            identical, as determined by the ``is`` operator.

            """
        if first is not second:
            if msg is None:
                msg = "%(first)r is not %(second)r" % vars()
            raise self.failureException(msg)

    assertIs = failUnlessIs
    assertNotIs = failIfIs

    def failIfIn(self, first, second, msg=None):
        """ Fail if the second object is in the first.

            Fail the test if ``first`` contains ``second``, as
            determined by the ``in`` operator.

            """
        if second in first:
            if msg is None:
                msg = "%(second)r is in %(first)r" % vars()
            raise self.failureException(msg)

    def failUnlessIn(self, first, second, msg=None):
        """ Fail unless the second object is in the first.

            Fail the test unless ``first`` contains ``second``, as
            determined by the ``in`` operator.

            """
        if second not in first:
            if msg is None:
                msg = "%(second)r is not in %(first)r" % vars()
            raise self.failureException(msg)

    assertIn = failUnlessIn
    assertNotIn = failIfIn

    def failUnlessOutputCheckerMatch(self, want, got, msg=None):
        """ Fail unless the specified string matches the expected.

            Fail the test unless ``want`` matches ``got``, as
            determined by a ``doctest.OutputChecker`` instance. This
            is not an equality check, but a pattern match according to
            the ``OutputChecker`` rules.

            """
        checker = doctest.OutputChecker()
        want = textwrap.dedent(want)
        source = ""
        example = doctest.Example(source, want)
        got = textwrap.dedent(got)
        checker_optionflags = reduce(operator.or_, [
            doctest.ELLIPSIS,
            ])
        if not checker.check_output(want, got, checker_optionflags):
            if msg is None:
                diff = checker.output_difference(
                    example, got, checker_optionflags)
                msg = "\n".join([
                    "Output received did not match expected output",
                    "%(diff)s",
                    ]) % vars()
            raise self.failureException(msg)

    assertOutputCheckerMatch = failUnlessOutputCheckerMatch

    def failUnlessMockCheckerMatch(self, want, tracker=None, msg=None):
        """ Fail unless the mock tracker matches the wanted output.

            Fail the test unless `want` matches the output tracked by
            `tracker` (defaults to ``self.mock_tracker``. This is not
            an equality check, but a pattern match according to the
            ``minimock.MinimockOutputChecker`` rules.

            """
        if tracker is None:
            tracker = self.mock_tracker
        if not tracker.check(want):
            if msg is None:
                diff = tracker.diff(want)
                msg = "\n".join([
                    "Output received did not match expected output",
                    "%(diff)s",
                    ]) % vars()
            raise self.failureException(msg)

    def failIfMockCheckerMatch(self, want, tracker=None, msg=None):
        """ Fail if the mock tracker matches the specified output.

            Fail the test if `want` matches the output tracked by
            `tracker` (defaults to ``self.mock_tracker``. This is not
            an equality check, but a pattern match according to the
            ``minimock.MinimockOutputChecker`` rules.

            """
        if tracker is None:
            tracker = self.mock_tracker
        if tracker.check(want):
            if msg is None:
                diff = tracker.diff(want)
                msg = "\n".join([
                    "Output received matched specified undesired output",
                    "%(diff)s",
                    ]) % vars()
            raise self.failureException(msg)

    assertMockCheckerMatch = failUnlessMockCheckerMatch
    assertNotMockCheckerMatch = failIfMockCheckerMatch

    def failIfIsInstance(self, obj, classes, msg=None):
        """ Fail if the object is an instance of the specified classes.

            Fail the test if the object ``obj`` is an instance of any
            of ``classes``.

            """
        if isinstance(obj, classes):
            if msg is None:
                msg = (
                    "%(obj)r is an instance of one of %(classes)r"
                    ) % vars()
            raise self.failureException(msg)

    def failUnlessIsInstance(self, obj, classes, msg=None):
        """ Fail unless the object is an instance of the specified classes.

            Fail the test unless the object ``obj`` is an instance of
            any of ``classes``.

            """
        if not isinstance(obj, classes):
            if msg is None:
                msg = (
                    "%(obj)r is not an instance of any of %(classes)r"
                    ) % vars()
            raise self.failureException(msg)

    assertIsInstance = failUnlessIsInstance
    assertNotIsInstance = failIfIsInstance

    def failUnlessFunctionInTraceback(self, traceback, function, msg=None):
        """ Fail if the function is not in the traceback.

            Fail the test if the function ``function`` is not at any
            of the levels in the traceback object ``traceback``.

            """
        func_in_traceback = False
        expect_code = function.func_code
        current_traceback = traceback
        while current_traceback is not None:
            if expect_code is current_traceback.tb_frame.f_code:
                func_in_traceback = True
                break
            current_traceback = current_traceback.tb_next

        if not func_in_traceback:
            if msg is None:
                msg = (
                    "Traceback did not lead to original function"
                    " %(function)s"
                    ) % vars()
            raise self.failureException(msg)

    assertFunctionInTraceback = failUnlessFunctionInTraceback

    def failUnlessFunctionSignatureMatch(self, first, second, msg=None):
        """ Fail if the function signatures do not match.

            Fail the test if the function signature does not match
            between the ``first`` function and the ``second``
            function.

            The function signature includes:

            * function name,

            * count of named parameters,

            * sequence of named parameters,

            * default values of named parameters,

            * collector for arbitrary positional arguments,

            * collector for arbitrary keyword arguments.

            """
        first_signature = get_function_signature(first)
        second_signature = get_function_signature(second)

        if first_signature != second_signature:
            if msg is None:
                first_signature_text = format_function_signature(first)
                second_signature_text = format_function_signature(second)
                msg = (textwrap.dedent("""\
                    Function signatures do not match:
                        %(first_signature)r != %(second_signature)r
                    Expected:
                        %(first_signature_text)s
                    Got:
                        %(second_signature_text)s""")
                    ) % vars()
            raise self.failureException(msg)

    assertFunctionSignatureMatch = failUnlessFunctionSignatureMatch


class Exception_TestCase(TestCase):
    """ Test cases for exception classes. """

    def __init__(self, *args, **kwargs):
        """ Set up a new instance """
        self.valid_exceptions = NotImplemented
        super(Exception_TestCase, self).__init__(*args, **kwargs)

    def setUp(self):
        """ Set up test fixtures. """
        for exc_type, params in self.valid_exceptions.items():
            args = (None, ) * params['min_args']
            params['args'] = args
            instance = exc_type(*args)
            params['instance'] = instance

        super(Exception_TestCase, self).setUp()

    def test_exception_instance(self):
        """ Exception instance should be created. """
        for params in self.valid_exceptions.values():
            instance = params['instance']
            self.failIfIs(None, instance)

    def test_exception_types(self):
        """ Exception instances should match expected types. """
        for params in self.valid_exceptions.values():
            instance = params['instance']
            for match_type in params['types']:
                match_type_name = match_type.__name__
                fail_msg = (
                    "%(instance)r is not an instance of"
                    " %(match_type_name)s"
                    ) % vars()
                self.failUnless(
                    isinstance(instance, match_type),
                    msg=fail_msg)
