Repository: matplotlib/matplotlib
File: lib/matplotlib/testing/decorators.py (Python)

Code before:
    KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY

    def decorator(func):
        import pytest

        _, result_dir = _image_directories(func)
        old_sig = inspect.signature(func)

        if not {"fig_test", "fig_ref"}.issubset(old_sig.parameters):
            raise ValueError("The decorated function must have at least the "
                             "parameters 'fig_test' and 'fig_ref', but your "
                             f"function has the signature {old_sig}")

        @pytest.mark.parametrize("ext", extensions)
        def wrapper(*args, ext, request, **kwargs):
            if 'ext' in old_sig.parameters:
                kwargs['ext'] = ext
            if 'request' in old_sig.parameters:
                kwargs['request'] = request

            file_name = "".join(c for c in request.node.name
                                if c in ALLOWED_CHARS)
            fig_test = Figure()
            fig_ref = Figure()
            func(*args, fig_test=fig_test, fig_ref=fig_ref, **kwargs)
            if len(fig_test.get_children()) == 1 and len(fig_ref.get_children()) == 1:
                raise RuntimeError("Both figures are empty.  Make sure you are "
                                   "plotting to fig_test or fig_ref.")

            test_image_path = result_dir / (file_name + "." + ext)
            ref_image_path = result_dir / (file_name + "-expected." + ext)
            fig_test.savefig(test_image_path)
            fig_ref.savefig(ref_image_path)
            _raise_on_image_difference(
                ref_image_path, test_image_path, tol=tol
            )

        parameters = [
            param
            for param in old_sig.parameters.values()
            if param.name not in {"fig_test", "fig_ref"}
        ]
        if 'ext' not in old_sig.parameters:
            parameters += [inspect.Parameter("ext", KEYWORD_ONLY)]
        if 'request' not in old_sig.parameters:
            parameters += [inspect.Parameter("request", KEYWORD_ONLY)]
        new_sig = old_sig.replace(parameters=parameters)
        wrapper.__signature__ = new_sig

        # reach a bit into pytest internals to hoist the marks from
        # our wrapped function

Review comment (suggestion):
```suggestion
            if len(fig_test.get_children()) == 1 and len(fig_ref.get_children()) == 1:
                # no artists have been added. The only child is fig.patch.
```

Code after:
    KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY

    def decorator(func):
        import pytest

        _, result_dir = _image_directories(func)
        old_sig = inspect.signature(func)

        if not {"fig_test", "fig_ref"}.issubset(old_sig.parameters):
            raise ValueError("The decorated function must have at least the "
                             "parameters 'fig_test' and 'fig_ref', but your "
                             f"function has the signature {old_sig}")

        @pytest.mark.parametrize("ext", extensions)
        def wrapper(*args, ext, request, **kwargs):
            if 'ext' in old_sig.parameters:
                kwargs['ext'] = ext
            if 'request' in old_sig.parameters:
                kwargs['request'] = request

            file_name = "".join(c for c in request.node.name
                                if c in ALLOWED_CHARS)
            fig_test = Figure()
            fig_ref = Figure()
            func(*args, fig_test=fig_test, fig_ref=fig_ref, **kwargs)
            if len(fig_test.get_children()) == 1 and len(fig_ref.get_children()) == 1:
                # no artists have been added. The only child is fig.patch.
                raise RuntimeError("Both figures are empty.  Make sure you are "
                                   "plotting to fig_test or fig_ref.")

            test_image_path = result_dir / (file_name + "." + ext)
            ref_image_path = result_dir / (file_name + "-expected." + ext)
            fig_test.savefig(test_image_path)
            fig_ref.savefig(ref_image_path)
            _raise_on_image_difference(
                ref_image_path, test_image_path, tol=tol
            )

        parameters = [
            param
            for param in old_sig.parameters.values()
            if param.name not in {"fig_test", "fig_ref"}
        ]
        if 'ext' not in old_sig.parameters:
            parameters += [inspect.Parameter("ext", KEYWORD_ONLY)]
        if 'request' not in old_sig.parameters:
            parameters += [inspect.Parameter("request", KEYWORD_ONLY)]
        new_sig = old_sig.replace(parameters=parameters)
        wrapper.__signature__ = new_sig

        # reach a bit into pytest internals to hoist the marks from