Skip to content

Commit 54953b5

Browse files
committed
chore: add CI and modernize test deps
1 parent cf9ac6e commit 54953b5

File tree

8 files changed

+96
-17
lines changed

8 files changed

+96
-17
lines changed

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
13+
- name: Set up Python
14+
uses: actions/setup-python@v5
15+
with:
16+
python-version-file: .python-version
17+
18+
- name: Configure git for private deps
19+
run: |
20+
git config --global url."https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/"
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install -U pip
25+
python -m pip install -r requirements-dev.txt
26+
27+
- name: Lint
28+
run: |
29+
flake8 validator tests
30+
31+
- name: Test
32+
run: |
33+
pytest -q

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.11
1+
3.12.12

.travis.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

requirements-dev.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-r requirements.txt
2-
flake8==3.6.0
3-
nose
4-
coverage
2+
flake8==7.1.1
3+
pytest>=8
4+
coverage==7.6.1

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
beautifulsoup4==4.4.1
1+
beautifulsoup4==4.14.3
2+
sdiff @ git+https://github.com/KeepSafe/[email protected]#egg=sdiff
23
Markdown
34
html2text==2014.12.29
45
lxml==6.0.2

tests/test_parser.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from unittest import TestCase
22

3+
import pytest
4+
35
from validator import parsers
46

57
from tests.utils import read
@@ -10,3 +12,18 @@ def test_xml_parsing(self):
1012
content = read('tests/fixtures/bugs/parser_bug.xml')
1113
parser = parsers.XmlParser()
1214
parser.parse(content)
15+
16+
17+
def test_xml_parser_empty_returns_empty():
18+
parser = parsers.XmlParser()
19+
20+
assert parser.parse(' ') == ''
21+
22+
23+
def test_chain_parser_wraps_errors():
24+
parser = parsers.ChainParser([parsers.XmlParser()])
25+
26+
with pytest.raises(parsers.ParserError) as exc:
27+
parser.parse('<root><broken></root>')
28+
29+
assert 'error in content' in str(exc.value)

tests/test_reports.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from validator.errors import ContentData, MdDiff, UrlDiff
2+
from validator.reports import HtmlReporter
3+
4+
5+
def test_html_reporter_handles_url_diff(tmp_path):
6+
reporter = HtmlReporter(output_directory=str(tmp_path))
7+
error = UrlDiff('http://example.com', files=['errors/source.md'], status_code=404)
8+
9+
reporter.report([error])
10+
11+
report_path = tmp_path / 'errors' / 'source.html'
12+
assert report_path.exists()
13+
assert 'http://example.com returned with code 404' in report_path.read_text()
14+
15+
16+
def test_html_reporter_writes_markdown_diff(tmp_path):
17+
reporter = HtmlReporter(output_directory=str(tmp_path))
18+
base = ContentData('base.md', 'Base', '<del>Base</del>', '<p>Base</p>')
19+
other = ContentData('other.md', 'Other', '<ins>Other</ins>', '<p>Other</p>')
20+
error = MdDiff(base, other, ['Missing content'])
21+
22+
reporter.report([error])
23+
24+
report_path = tmp_path / 'other.html'
25+
assert report_path.exists()
26+
content = report_path.read_text()
27+
assert 'Missing content' in content
28+
assert '<del>' in content
29+
assert '<ins>' in content
30+
assert 'Base' in content
31+
assert 'Other' in content

validator/reports.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from pathlib import Path
2+
13
from bs4 import BeautifulSoup
24
import shutil
35
import markdown
@@ -94,13 +96,17 @@ def _add_content(self, soup, tag_id, content):
9496
# TODO remove isinstance
9597
def report(self, errors):
9698
shutil.rmtree(self.output_directory, ignore_errors=True)
99+
if self.output_directory:
100+
Path(self.output_directory).mkdir(parents=True, exist_ok=True)
97101
for error in errors:
98102
# TODO save to different files for links and diff
99103
# TODO use mustache for templates
100104
report_soup = BeautifulSoup(self.report_template, 'lxml')
105+
source_path = None
101106
if isinstance(error, UrlDiff):
102107
messages = [f'<span>{error.url} returned with code {error.status_code}</span>']
103108
self._add_content(report_soup, 'urls', '\n'.join(messages))
109+
source_path = error.files[0] if error.files else 'url_errors'
104110
if isinstance(error, MdDiff):
105111
error_msgs = '<br />'.join(map(lambda i: str(i), error.error_msgs))
106112
base = markdown.markdown(error.base.parsed)
@@ -110,7 +116,9 @@ def report(self, errors):
110116
report_soup = self._add_content(report_soup, 'left_diff', BeautifulSoup(error.base.diff, 'lxml').body)
111117
report_soup = self._add_content(report_soup, 'right_diff', BeautifulSoup(error.other.diff, 'lxml').body)
112118
report_soup = self._add_content(report_soup, 'error_msgs', BeautifulSoup(error_msgs, 'lxml').body)
113-
save_report(self.output_directory, error.other.original, report_soup.prettify())
119+
source_path = error.other.original
120+
if source_path is not None:
121+
save_report(self.output_directory, source_path, report_soup.prettify())
114122

115123

116124
class ConsoleReporter:

0 commit comments

Comments
 (0)