from typing import Callable


def create_skip_test_if_base_class_decorator(child_attr: str) -> Callable:
    """A function that creates a custom decorator for use on a Base Test class, to allow the base
    test class not show failed or skipped tests, when they aren't real tests but templates for
    child test classes

    Example usage:

    skip_test_if_base_class = create_skip_test_if_base_class_decorator('card_class')

    class SomeBaseTest(unittest.TestCase):
        card_class = None  # required on child classes

        @skip_test_if_base_class
        def test_success(self):
            pass

    :param child_attr: an attribute that will be None on the parent, but will be set on children
    :type: str
    :return: a decorator to be used on any test method
    :rtype: Callable
    """

    def decorator(f: Callable) -> Callable:
        """
        Handy decorator that when added to a test, will check if the test is on the base class
        or on the child class. Child classes are expected to have set their child_attr and should
        be able to run all tests
        """

        def wrapper(self, *args, **kwargs):
            # check here is primitive.
            # We assume all children are setting this child_attr
            if getattr(self, child_attr) is not None:
                f(self, *args, **kwargs)
            else:
                # self.skipTest("Skipping on base parent class")
                # silently skip these tests, since they SHOULD pass
                # and be happy on any bases classes
                pass

        return wrapper

    return decorator