<commit_before>"""Integration test for the CLI."""
import pathlib

import pytest
import typer
import typer.testing

from rstcheck import _extras
from tests.conftest import EXAMPLES_DIR, TESTING_DIR
from tests.integration_tests.conftest import ERROR_CODE_REGEX


def test_cli_help_message(cli_app: typer.Typer, cli_runner: typer.testing.CliRunner) -> None:
    """Test help message."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "Enabled features:" in result.stdout


@pytest.mark.skipif(not _extras.SPHINX_INSTALLED, reason="Depends on sphinx extra.")
def test_cli_help_message_with_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test help message when sphinx is installed."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "Enabled features:" in result.stdout
    assert "Sphinx" in result.stdout


@pytest.mark.skipif(not _extras.TOMLI_INSTALLED, reason="Depends on toml extra.")
def test_cli_help_message_with_tomli(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test help message when toml is installed."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "pyproject.toml" in result.stdout
    assert "Enabled features:" in result.stdout
    assert "Toml" in result.stdout


@pytest.mark.parametrize("test_file", list(TESTING_DIR.glob("examples/good/*.rst")))
def test_all_good_examples(
    test_file: pathlib.Path,
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/good`` are errorless."""
    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


def test_all_good_examples_recurively(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/good`` recursively."""
    test_dir = EXAMPLES_DIR / "good"

    result = cli_runner.invoke(cli_app, [str(test_dir), "--recursive"])

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


@pytest.mark.parametrize("test_file", list(TESTING_DIR.glob("examples/bad/*.rst")))
def test_all_bad_examples(
    test_file: pathlib.Path,
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/bad`` have errors."""
    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code != 0
    assert ERROR_CODE_REGEX.search(result.stdout) is not None


def test_all_bad_examples_recurively(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/bad`` recursively."""
    test_dir = EXAMPLES_DIR / "bad"

    result = cli_runner.invoke(cli_app, [str(test_dir), "--recursive"])

    assert result.exit_code != 0
    assert ERROR_CODE_REGEX.search(result.stdout) is not None


def test_mix_of_good_and_bad_examples(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test mix of good and bad examples."""
    test_file_good = EXAMPLES_DIR / "good" / "code_blocks.rst"
    test_file_bad = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file_good), str(test_file_bad)])

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 1


def test_good_example_with_piping(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test good example file piped into rstcheck."""
    test_file = EXAMPLES_DIR / "good" / "code_blocks.rst"
    test_file_content = test_file.read_text("utf-8")

    result = cli_runner.invoke(cli_app, "-", input=test_file_content)

    assert result.exit_code == 0


def test_bad_example_with_piping(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test bad example file piped into rstcheck."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"
    test_file_content = test_file.read_text("utf-8")

    result = cli_runner.invoke(cli_app, "-", input=test_file_content)

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 1


def test_piping_is_not_allowed_with_additional_files(cli_app: typer.Typer) -> None:
    """Test piping into rstcheck is not allowed with additional files.

    Test cli prints error to stderr.
    """
    cli_runner_divided_output = typer.testing.CliRunner(mix_stderr=False)

    result = cli_runner_divided_output.invoke(cli_app, ["-", "foo"])

    assert result.exit_code == 1
    assert "'-' is only allowed without additional files." in result.stderr
    assert "Aborted!" in result.stderr


def test_without_report_exits_zero(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test bad example without report is ok."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file), "--report-level", "none"])

    assert result.exit_code == 0


def test_matching_ignore_msg_exits_zero(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test matching ignore message."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(
        cli_app, [str(test_file), "--ignore-messages", r"(Title .verline & underline mismatch\.$)"]
    )

    assert result.exit_code == 0


def test_non_matching_ignore_msg_errors(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test non matching ignore message."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file), "--ignore-messages", r"(No match\.$)"])

    assert result.exit_code != 0


def test_custom_directive_and_role(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 4


def test_custom_directive_and_role_with_ignore(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role and CLI ignores."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"

    result = cli_runner.invoke(
        cli_app,
        [
            "--ignore-directives",
            "my-directive",
            "--ignore-roles",
            "some-custom-thing",
            str(test_file),
        ],
    )

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


def test_custom_directive_and_role_with_config_file(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role and config file."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"
    config_file = EXAMPLES_DIR / "custom" / "rstcheck.custom.ini"

    result = cli_runner.invoke(cli_app, ["--config", str(config_file), str(test_file)])

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


@pytest.mark.skipif(_extras.SPHINX_INSTALLED, reason="Test without sphinx extra.")
def test_sphinx_role_erros_without_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test sphinx example errors without sphinx."""
    test_file = EXAMPLES_DIR / "sphinx" / "good.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code == 0


@pytest.mark.skipif(not _extras.SPHINX_INSTALLED, reason="Depends on sphinx extra.")
def test_sphinx_role_exits_zero_with_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test sphinx example does not error with sphinx."""
    test_file = EXAMPLES_DIR / "sphinx" / "good.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code == 0<commit_msg>fix sphinx test<commit_after>"""Integration test for the CLI."""
import pathlib

import pytest
import typer
import typer.testing

from rstcheck import _extras
from tests.conftest import EXAMPLES_DIR, TESTING_DIR
from tests.integration_tests.conftest import ERROR_CODE_REGEX


def test_cli_help_message(cli_app: typer.Typer, cli_runner: typer.testing.CliRunner) -> None:
    """Test help message."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "Enabled features:" in result.stdout


@pytest.mark.skipif(not _extras.SPHINX_INSTALLED, reason="Depends on sphinx extra.")
def test_cli_help_message_with_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test help message when sphinx is installed."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "Enabled features:" in result.stdout
    assert "Sphinx" in result.stdout


@pytest.mark.skipif(not _extras.TOMLI_INSTALLED, reason="Depends on toml extra.")
def test_cli_help_message_with_tomli(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test help message when toml is installed."""
    result = cli_runner.invoke(cli_app, "--help")

    assert result.exit_code == 0
    assert "pyproject.toml" in result.stdout
    assert "Enabled features:" in result.stdout
    assert "Toml" in result.stdout


@pytest.mark.parametrize("test_file", list(TESTING_DIR.glob("examples/good/*.rst")))
def test_all_good_examples(
    test_file: pathlib.Path,
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/good`` are errorless."""
    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


def test_all_good_examples_recurively(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/good`` recursively."""
    test_dir = EXAMPLES_DIR / "good"

    result = cli_runner.invoke(cli_app, [str(test_dir), "--recursive"])

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


@pytest.mark.parametrize("test_file", list(TESTING_DIR.glob("examples/bad/*.rst")))
def test_all_bad_examples(
    test_file: pathlib.Path,
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/bad`` have errors."""
    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code != 0
    assert ERROR_CODE_REGEX.search(result.stdout) is not None


def test_all_bad_examples_recurively(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test all files in ``testing/examples/bad`` recursively."""
    test_dir = EXAMPLES_DIR / "bad"

    result = cli_runner.invoke(cli_app, [str(test_dir), "--recursive"])

    assert result.exit_code != 0
    assert ERROR_CODE_REGEX.search(result.stdout) is not None


def test_mix_of_good_and_bad_examples(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test mix of good and bad examples."""
    test_file_good = EXAMPLES_DIR / "good" / "code_blocks.rst"
    test_file_bad = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file_good), str(test_file_bad)])

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 1


def test_good_example_with_piping(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test good example file piped into rstcheck."""
    test_file = EXAMPLES_DIR / "good" / "code_blocks.rst"
    test_file_content = test_file.read_text("utf-8")

    result = cli_runner.invoke(cli_app, "-", input=test_file_content)

    assert result.exit_code == 0


def test_bad_example_with_piping(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test bad example file piped into rstcheck."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"
    test_file_content = test_file.read_text("utf-8")

    result = cli_runner.invoke(cli_app, "-", input=test_file_content)

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 1


def test_piping_is_not_allowed_with_additional_files(cli_app: typer.Typer) -> None:
    """Test piping into rstcheck is not allowed with additional files.

    Test cli prints error to stderr.
    """
    cli_runner_divided_output = typer.testing.CliRunner(mix_stderr=False)

    result = cli_runner_divided_output.invoke(cli_app, ["-", "foo"])

    assert result.exit_code == 1
    assert "'-' is only allowed without additional files." in result.stderr
    assert "Aborted!" in result.stderr


def test_without_report_exits_zero(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test bad example without report is ok."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file), "--report-level", "none"])

    assert result.exit_code == 0


def test_matching_ignore_msg_exits_zero(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test matching ignore message."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(
        cli_app, [str(test_file), "--ignore-messages", r"(Title .verline & underline mismatch\.$)"]
    )

    assert result.exit_code == 0


def test_non_matching_ignore_msg_errors(
    cli_app: typer.Typer,
    cli_runner: typer.testing.CliRunner,
) -> None:
    """Test non matching ignore message."""
    test_file = EXAMPLES_DIR / "bad" / "rst.rst"

    result = cli_runner.invoke(cli_app, [str(test_file), "--ignore-messages", r"(No match\.$)"])

    assert result.exit_code != 0


def test_custom_directive_and_role(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code != 0
    assert len(ERROR_CODE_REGEX.findall(result.stdout)) == 4


def test_custom_directive_and_role_with_ignore(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role and CLI ignores."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"

    result = cli_runner.invoke(
        cli_app,
        [
            "--ignore-directives",
            "my-directive",
            "--ignore-roles",
            "some-custom-thing",
            str(test_file),
        ],
    )

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


def test_custom_directive_and_role_with_config_file(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test file with custom directive and role and config file."""
    test_file = EXAMPLES_DIR / "custom" / "custom_directive_and_role.rst"
    config_file = EXAMPLES_DIR / "custom" / "rstcheck.custom.ini"

    result = cli_runner.invoke(cli_app, ["--config", str(config_file), str(test_file)])

    assert result.exit_code == 0
    assert "Success! No issues detected." in result.stdout


@pytest.mark.skipif(_extras.SPHINX_INSTALLED, reason="Test without sphinx extra.")
def test_sphinx_role_erros_without_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test sphinx example errors without sphinx."""
    test_file = EXAMPLES_DIR / "sphinx" / "good.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code != 0


@pytest.mark.skipif(not _extras.SPHINX_INSTALLED, reason="Depends on sphinx extra.")
def test_sphinx_role_exits_zero_with_sphinx(
    cli_app: typer.Typer, cli_runner: typer.testing.CliRunner
) -> None:
    """Test sphinx example does not error with sphinx."""
    test_file = EXAMPLES_DIR / "sphinx" / "good.rst"

    result = cli_runner.invoke(cli_app, str(test_file))

    assert result.exit_code == 0
{'fraction_non_alphanumeric': 0.1220136518771331, 'fraction_numerical': 0.0029254022428083864, 'mean_word_length': 3.8304386223138063, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '652960', 'n_tokens_mistral': 5949, 'n_tokens_neox': 5623, 'n_words': 1219}