Coverage for tests/test_sphinxlint.py: 100%

1 from pathlib import Path

2

3 import pytest

4

5 from sphinxlint.cli import main

6 from sphinxlint.utils import paragraphs

7

8 FIXTURE_DIR = Path(__file__).resolve().parent / "fixtures"

9

10

11@pytest.mark.parametrize("file", [str(f) for f in (FIXTURE_DIR / "xpass").iterdir()])

12 def test_sphinxlint_shall_pass(file, capsys):

13 has_errors = main(["sphinxlint.py", "--enable", "all", str(file)])

14 out, err = capsys.readouterr()

15 assert err == ""

16 assert out == "No problems found.\n"

17 assert not has_errors

18

19

20@pytest.mark.parametrize(

21 "file", [str(f) for f in (FIXTURE_DIR / "triggers-false-positive").iterdir()]

22)

23 def test_sphinxlint_shall_trigger_false_positive(file, capsys):

24 has_errors = main(["sphinxlint.py", str(file)])

25 out, err = capsys.readouterr()

26 assert out == "No problems found.\n"

27 assert err == ""

28 assert not has_errors

29 has_errors = main(["sphinxlint.py", "--enable", "all", str(file)])

30 out, err = capsys.readouterr()

31 assert out != "No problems found.\n"

32 assert err != ""

33 assert has_errors

34

35

36 def gather_xfail():

37 """Find all rst files in the fixtures/xfail directory.

38

39 Each file is searched for lines containing expcted errors, they

40 are starting with `.. expect: `.

41 """

42 marker = ".. expect: "

43 for file in (FIXTURE_DIR / "xfail").iterdir():

44 expected_errors = []

45 for line in Path(file).read_text(encoding="UTF-8").splitlines():

46 if line.startswith(marker):

47 expected_errors.append(line[len(marker) :])

48 yield str(file), expected_errors

49

50

51@pytest.mark.parametrize("file,expected_errors", gather_xfail())

52 def test_sphinxlint_shall_not_pass(file, expected_errors, capsys):

53 has_errors = main(["sphinxlint.py", "--enable", "all", file])

54 out, err = capsys.readouterr()

55 assert out != "No problems found.\n"

56 assert err != ""

57 assert has_errors

58 assert expected_errors, (

59 "That's not OK not to tell which errors are expected, "

60 """add one using a ".. expect: " line."""

61 )

62 for expected_error in expected_errors:

63 assert expected_error in err

64 number_of_expected_errors = len(expected_errors)

65 number_of_reported_errors = len(err.splitlines())

66 assert (

67 number_of_expected_errors == number_of_reported_errors

68 ), f"{number_of_reported_errors=}, {err=}"

69

70

71@pytest.mark.parametrize("file", [str(FIXTURE_DIR / "paragraphs.rst")])

72 def test_paragraphs(file):

73 with open(file, encoding="UTF-8") as ifile:

74 lines = tuple(ifile.readlines())

75 actual = paragraphs(lines)

76 for lno, para in actual:

77 firstpline = para.splitlines(keepends=True)[0]

78 # check that the first line of the paragraph matches the

79 # corresponding line in the original file -- note that

80 # `lines` is 0-indexed but paragraphs return 1-indexed values

81 assert firstpline == lines[lno - 1]

82

83

84@pytest.mark.parametrize("file", [str(FIXTURE_DIR / "paragraphs.rst")])

85 def test_line_no_in_error_msg(file, capsys):

86 has_errors = main(["sphinxlint.py", file])

87 out, err = capsys.readouterr()

88 assert out == ""

89 assert "paragraphs.rst:76: role missing colon before" in err

90 assert "paragraphs.rst:70: role use a single backtick" in err

91 assert "paragraphs.rst:65: inline literal missing (escaped) space" in err

92 assert has_errors