diffpdf 0.3.2__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {diffpdf-0.3.2 → diffpdf-1.1.0}/.github/dependabot.yml +1 -1
- diffpdf-1.1.0/.github/workflows/build.yml +62 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/.github/workflows/pypi-publish.yml +1 -1
- diffpdf-1.1.0/.pre-commit-config.yaml +36 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/.vscode/extensions.json +1 -2
- {diffpdf-0.3.2 → diffpdf-1.1.0}/.vscode/settings.json +2 -8
- {diffpdf-0.3.2 → diffpdf-1.1.0}/MANIFEST.in +1 -1
- {diffpdf-0.3.2 → diffpdf-1.1.0}/PKG-INFO +44 -19
- {diffpdf-0.3.2 → diffpdf-1.1.0}/README.md +38 -9
- diffpdf-1.1.0/pyproject.toml +76 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/__init__.py +1 -1
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/text_check.py +7 -1
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/test_api.py +13 -2
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/test_cli.py +0 -1
- diffpdf-1.1.0/uv.lock +845 -0
- diffpdf-0.3.2/.github/workflows/build.yml +0 -45
- diffpdf-0.3.2/hooks/pre-commit +0 -59
- diffpdf-0.3.2/mypy.ini +0 -4
- diffpdf-0.3.2/pyproject.toml +0 -56
- {diffpdf-0.3.2 → diffpdf-1.1.0}/.gitignore +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/LICENSE +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/cli.py +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/hash_check.py +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/logger.py +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/page_check.py +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/py.typed +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/src/diffpdf/visual_check.py +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/1-letter-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/1-letter-diff-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/major-color-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/major-color-diff-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/page-count-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/fail/page-count-diff-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/hash-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/hash-diff-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/identical-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/identical-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/minor-color-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/minor-color-diff-B.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/multiplatform-diff-A.pdf +0 -0
- {diffpdf-0.3.2 → diffpdf-1.1.0}/tests/assets/pass/multiplatform-diff-B.pdf +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
# Tests compatibility across Ubuntu/Windows and Python/package version extremes
|
|
14
|
+
os: [ubuntu-latest, windows-latest]
|
|
15
|
+
dependencies: [locked, oldest]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
|
+
|
|
20
|
+
# When searching for a system Python version, uv will use the first compatible version - not the newest version.
|
|
21
|
+
# Therefore, make sure the newest version is available on the runner.
|
|
22
|
+
- name: Install Python
|
|
23
|
+
uses: actions/setup-python@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: 3.x
|
|
26
|
+
|
|
27
|
+
# At the time of writing there is no way to force uv select the lowest version of Python.
|
|
28
|
+
# Therefore, extract this from pyproject.toml
|
|
29
|
+
# More info: https://github.com/astral-sh/uv/issues/16333
|
|
30
|
+
- name: Extract minimum Python version from pyproject.toml
|
|
31
|
+
if: matrix.dependencies == 'oldest'
|
|
32
|
+
id: python-version
|
|
33
|
+
shell: bash
|
|
34
|
+
run: |
|
|
35
|
+
MIN_PY=$(grep 'requires-python' pyproject.toml | sed -E 's/[^0-9.]//g')
|
|
36
|
+
echo "min=$MIN_PY" >> $GITHUB_OUTPUT
|
|
37
|
+
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@v7
|
|
40
|
+
with:
|
|
41
|
+
version: "latest"
|
|
42
|
+
|
|
43
|
+
- name: Install locked dependencies
|
|
44
|
+
if: matrix.dependencies == 'locked'
|
|
45
|
+
run: uv sync --locked
|
|
46
|
+
|
|
47
|
+
- name: Install oldest dependencies
|
|
48
|
+
if: matrix.dependencies == 'oldest'
|
|
49
|
+
run: uv sync --resolution lowest --python ${{ steps.python-version.outputs.min }}
|
|
50
|
+
|
|
51
|
+
- name: Run pre-commit hooks
|
|
52
|
+
if: matrix.dependencies == 'locked'
|
|
53
|
+
run: uv run pre-commit run --all-files
|
|
54
|
+
|
|
55
|
+
- name: Run pytest
|
|
56
|
+
run: uv run pytest
|
|
57
|
+
|
|
58
|
+
- name: Upload coverage reports to Codecov
|
|
59
|
+
if: matrix.os == 'ubuntu-latest' && matrix.dependencies == 'locked'
|
|
60
|
+
uses: codecov/codecov-action@v5
|
|
61
|
+
with:
|
|
62
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-added-large-files
|
|
6
|
+
- id: check-case-conflict
|
|
7
|
+
- id: check-illegal-windows-names
|
|
8
|
+
- id: check-merge-conflict
|
|
9
|
+
- id: detect-private-key
|
|
10
|
+
- id: end-of-file-fixer
|
|
11
|
+
|
|
12
|
+
- repo: local
|
|
13
|
+
hooks:
|
|
14
|
+
- id: uv-sync-check
|
|
15
|
+
name: check uv is synced
|
|
16
|
+
entry: uv lock --check -q
|
|
17
|
+
language: system
|
|
18
|
+
pass_filenames: false
|
|
19
|
+
|
|
20
|
+
- id: ruff-lint
|
|
21
|
+
name: lint
|
|
22
|
+
entry: uv run ruff check --fix -q
|
|
23
|
+
language: system
|
|
24
|
+
pass_filenames: false
|
|
25
|
+
|
|
26
|
+
- id: ruff-format
|
|
27
|
+
name: format
|
|
28
|
+
entry: uv run ruff format -q
|
|
29
|
+
language: system
|
|
30
|
+
pass_filenames: false
|
|
31
|
+
|
|
32
|
+
- id: ty
|
|
33
|
+
name: type check
|
|
34
|
+
entry: uv run ty check -q
|
|
35
|
+
language: system
|
|
36
|
+
pass_filenames: false
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// List of extensions which should be recommended for users of this workspace.
|
|
6
6
|
"recommendations": [
|
|
7
7
|
"ms-python.python",
|
|
8
|
-
"matangover.mypy",
|
|
9
8
|
"charliermarsh.ruff",
|
|
10
9
|
"ryanluker.vscode-coverage-gutters",
|
|
11
10
|
"astral-sh.ty"
|
|
@@ -14,4 +13,4 @@
|
|
|
14
13
|
"unwantedRecommendations": [
|
|
15
14
|
"ms-python.vscode-pylance"
|
|
16
15
|
]
|
|
17
|
-
}
|
|
16
|
+
}
|
|
@@ -6,13 +6,7 @@
|
|
|
6
6
|
"source.organizeImports.ruff": "explicit"
|
|
7
7
|
},
|
|
8
8
|
|
|
9
|
-
// Enable MyPy type checker
|
|
10
|
-
"mypy.runUsingActiveInterpreter": true,
|
|
11
|
-
|
|
12
9
|
// Configure Pytest
|
|
13
|
-
"python.testing.pytestArgs": [
|
|
14
|
-
"tests"
|
|
15
|
-
],
|
|
16
10
|
"python.testing.unittestEnabled": false,
|
|
17
|
-
"python.testing.pytestEnabled": true
|
|
18
|
-
}
|
|
11
|
+
"python.testing.pytestEnabled": true,
|
|
12
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
include README.md
|
|
2
|
-
include LICENSE
|
|
2
|
+
include LICENSE
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffpdf
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A tool for comparing PDF files
|
|
5
5
|
Project-URL: Homepage, https://github.com/JustusRijke/DiffPDF
|
|
6
6
|
Project-URL: Issues, https://github.com/JustusRijke/DiffPDF/issues
|
|
7
7
|
Author-email: Justus Rijke <justusrijke@gmail.com>
|
|
8
8
|
License-Expression: MIT
|
|
9
9
|
License-File: LICENSE
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Operating System :: Microsoft :: Windows
|
|
12
12
|
Classifier: Operating System :: POSIX :: Linux
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Typing :: Typed
|
|
15
|
-
Requires-Python: >=3.10
|
|
16
|
-
Requires-Dist: click
|
|
15
|
+
Requires-Python: >=3.10.0
|
|
16
|
+
Requires-Dist: click>=8
|
|
17
17
|
Requires-Dist: pillow>=10.0.0
|
|
18
|
-
Requires-Dist: pixelmatch-fast>=1.3.
|
|
18
|
+
Requires-Dist: pixelmatch-fast>=1.3.1
|
|
19
|
+
Requires-Dist: pre-commit>=4.5.1
|
|
19
20
|
Requires-Dist: pymupdf>=1.23.0
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: mypy; extra == 'dev'
|
|
22
|
-
Requires-Dist: pytest; extra == 'dev'
|
|
23
|
-
Requires-Dist: pytest-cov; extra == 'dev'
|
|
24
|
-
Requires-Dist: ruff; extra == 'dev'
|
|
25
21
|
Description-Content-Type: text/markdown
|
|
26
22
|
|
|
27
23
|
# DiffPDF
|
|
@@ -30,6 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
30
26
|
[](https://codecov.io/gh/JustusRijke/DiffPDF)
|
|
31
27
|
[](https://www.python.org/downloads/)
|
|
32
28
|
[](LICENSE)
|
|
29
|
+
[](https://pypi.org/project/DiffPDF/)
|
|
33
30
|
[](https://pypi.org/project/DiffPDF/)
|
|
34
31
|
|
|
35
32
|
CLI tool for detecting structural, textual, and visual differences between PDF files, for use in automatic regression tests.
|
|
@@ -47,12 +44,15 @@ Each stage only runs if all previous stages pass.
|
|
|
47
44
|
|
|
48
45
|
## Installation
|
|
49
46
|
|
|
47
|
+
Install Python (v3.10 or higher) and install the package:
|
|
48
|
+
|
|
50
49
|
```bash
|
|
51
50
|
pip install diffpdf
|
|
52
51
|
```
|
|
53
52
|
|
|
54
53
|
## CLI Usage
|
|
55
|
-
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
56
|
Usage: diffpdf [OPTIONS] REFERENCE ACTUAL
|
|
57
57
|
|
|
58
58
|
Compare two PDF files for structural, textual, and visual differences.
|
|
@@ -60,13 +60,13 @@ Usage: diffpdf [OPTIONS] REFERENCE ACTUAL
|
|
|
60
60
|
Options:
|
|
61
61
|
--threshold FLOAT Pixelmatch threshold (0.0-1.0)
|
|
62
62
|
--dpi INTEGER Render resolution
|
|
63
|
-
--output-dir DIRECTORY Diff
|
|
63
|
+
--output-dir DIRECTORY Diff output directory (saves text diffs and visual diff images on failure)
|
|
64
64
|
-v, --verbose Increase verbosity
|
|
65
65
|
--version Show the version and exit.
|
|
66
66
|
--help Show this message and exit.
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
### Exit Codes
|
|
70
70
|
|
|
71
71
|
- `0` — Pass (PDFs are equivalent)
|
|
72
72
|
- `1` — Fail (differences detected)
|
|
@@ -77,19 +77,44 @@ Options:
|
|
|
77
77
|
```python
|
|
78
78
|
from diffpdf import diffpdf
|
|
79
79
|
|
|
80
|
-
# Basic usage (no diff
|
|
80
|
+
# Basic usage (no diff output saved)
|
|
81
81
|
diffpdf("reference.pdf", "actual.pdf")
|
|
82
82
|
|
|
83
|
-
# With options (save diff images to ./output directory)
|
|
84
|
-
diffpdf("reference.pdf", "actual.pdf", output_dir="./output",
|
|
83
|
+
# With options (save text diffs and visual diff images to ./output directory)
|
|
84
|
+
diffpdf("reference.pdf", "actual.pdf", output_dir="./output", dpi=300)
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
## Development
|
|
88
88
|
|
|
89
|
+
Install [uv](https://github.com/astral-sh/uv?tab=readme-ov-file#installation). Then, install dependencies & activate the automatically generated virtual environment:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv sync --locked
|
|
93
|
+
source .venv/bin/activate
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Skip `--locked` to use the newest dependencies (this might modify `uv.lock`)
|
|
97
|
+
|
|
98
|
+
### Testing
|
|
99
|
+
|
|
100
|
+
Run tests:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pytest
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Quality Assurance (QA)
|
|
107
|
+
|
|
108
|
+
Automatically run code quality checks before every commit using [pre-commit](https://pre-commit.com/):
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pre-commit install
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This installs git hooks that run ruff, type checks, and other checks before each commit. You can run manually at any time with:
|
|
115
|
+
|
|
89
116
|
```bash
|
|
90
|
-
|
|
91
|
-
pytest tests/ -v
|
|
92
|
-
ruff check .
|
|
117
|
+
pre-commit run --all-files
|
|
93
118
|
```
|
|
94
119
|
|
|
95
120
|
## Acknowledgements
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://codecov.io/gh/JustusRijke/DiffPDF)
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
6
|
[](LICENSE)
|
|
7
|
+
[](https://pypi.org/project/DiffPDF/)
|
|
7
8
|
[](https://pypi.org/project/DiffPDF/)
|
|
8
9
|
|
|
9
10
|
CLI tool for detecting structural, textual, and visual differences between PDF files, for use in automatic regression tests.
|
|
@@ -21,12 +22,15 @@ Each stage only runs if all previous stages pass.
|
|
|
21
22
|
|
|
22
23
|
## Installation
|
|
23
24
|
|
|
25
|
+
Install Python (v3.10 or higher) and install the package:
|
|
26
|
+
|
|
24
27
|
```bash
|
|
25
28
|
pip install diffpdf
|
|
26
29
|
```
|
|
27
30
|
|
|
28
31
|
## CLI Usage
|
|
29
|
-
|
|
32
|
+
|
|
33
|
+
```bash
|
|
30
34
|
Usage: diffpdf [OPTIONS] REFERENCE ACTUAL
|
|
31
35
|
|
|
32
36
|
Compare two PDF files for structural, textual, and visual differences.
|
|
@@ -34,13 +38,13 @@ Usage: diffpdf [OPTIONS] REFERENCE ACTUAL
|
|
|
34
38
|
Options:
|
|
35
39
|
--threshold FLOAT Pixelmatch threshold (0.0-1.0)
|
|
36
40
|
--dpi INTEGER Render resolution
|
|
37
|
-
--output-dir DIRECTORY Diff
|
|
41
|
+
--output-dir DIRECTORY Diff output directory (saves text diffs and visual diff images on failure)
|
|
38
42
|
-v, --verbose Increase verbosity
|
|
39
43
|
--version Show the version and exit.
|
|
40
44
|
--help Show this message and exit.
|
|
41
45
|
```
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
### Exit Codes
|
|
44
48
|
|
|
45
49
|
- `0` — Pass (PDFs are equivalent)
|
|
46
50
|
- `1` — Fail (differences detected)
|
|
@@ -51,19 +55,44 @@ Options:
|
|
|
51
55
|
```python
|
|
52
56
|
from diffpdf import diffpdf
|
|
53
57
|
|
|
54
|
-
# Basic usage (no diff
|
|
58
|
+
# Basic usage (no diff output saved)
|
|
55
59
|
diffpdf("reference.pdf", "actual.pdf")
|
|
56
60
|
|
|
57
|
-
# With options (save diff images to ./output directory)
|
|
58
|
-
diffpdf("reference.pdf", "actual.pdf", output_dir="./output",
|
|
61
|
+
# With options (save text diffs and visual diff images to ./output directory)
|
|
62
|
+
diffpdf("reference.pdf", "actual.pdf", output_dir="./output", dpi=300)
|
|
59
63
|
```
|
|
60
64
|
|
|
61
65
|
## Development
|
|
62
66
|
|
|
67
|
+
Install [uv](https://github.com/astral-sh/uv?tab=readme-ov-file#installation). Then, install dependencies & activate the automatically generated virtual environment:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv sync --locked
|
|
71
|
+
source .venv/bin/activate
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Skip `--locked` to use the newest dependencies (this might modify `uv.lock`)
|
|
75
|
+
|
|
76
|
+
### Testing
|
|
77
|
+
|
|
78
|
+
Run tests:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pytest
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Quality Assurance (QA)
|
|
85
|
+
|
|
86
|
+
Automatically run code quality checks before every commit using [pre-commit](https://pre-commit.com/):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pre-commit install
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This installs git hooks that run ruff, type checks, and other checks before each commit. You can run manually at any time with:
|
|
93
|
+
|
|
63
94
|
```bash
|
|
64
|
-
|
|
65
|
-
pytest tests/ -v
|
|
66
|
-
ruff check .
|
|
95
|
+
pre-commit run --all-files
|
|
67
96
|
```
|
|
68
97
|
|
|
69
98
|
## Acknowledgements
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"hatchling",
|
|
4
|
+
"hatch-vcs",
|
|
5
|
+
]
|
|
6
|
+
build-backend = "hatchling.build"
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "diffpdf"
|
|
10
|
+
dynamic = ["version"]
|
|
11
|
+
description = "A tool for comparing PDF files"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
license = "MIT"
|
|
14
|
+
license-files = ["LICENSE"]
|
|
15
|
+
authors = [{name = "Justus Rijke", email="justusrijke@gmail.com"}]
|
|
16
|
+
requires-python = ">=3.10.0"
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Development Status :: 5 - Production/Stable",
|
|
20
|
+
"Operating System :: Microsoft :: Windows",
|
|
21
|
+
"Operating System :: POSIX :: Linux",
|
|
22
|
+
"Typing :: Typed",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"click>=8",
|
|
26
|
+
"pymupdf>=1.23.0",
|
|
27
|
+
"pixelmatch-fast>=1.3.1",
|
|
28
|
+
"Pillow>=10.0.0",
|
|
29
|
+
"pre-commit>=4.5.1",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/JustusRijke/DiffPDF"
|
|
34
|
+
Issues = "https://github.com/JustusRijke/DiffPDF/issues"
|
|
35
|
+
|
|
36
|
+
[dependency-groups]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=9",
|
|
39
|
+
"pytest-cov>=6",
|
|
40
|
+
"ruff>=0.10",
|
|
41
|
+
"ty>=0.0.8",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
diffpdf = "diffpdf.cli:cli"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.version]
|
|
48
|
+
source = "vcs"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.version.raw-options]
|
|
51
|
+
local_scheme = "no-local-version"
|
|
52
|
+
|
|
53
|
+
[tool.pytest]
|
|
54
|
+
strict = true
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
filterwarnings = ["error"] # Treat all warnings as errors (e.g., deprecation warnings)
|
|
57
|
+
addopts = [
|
|
58
|
+
"-v", # Verbose output
|
|
59
|
+
"--cov", # Enable coverage
|
|
60
|
+
"--cov-branch", # Make sure to cover every decision branch
|
|
61
|
+
"--cov-report=term-missing", # Report which lines aren't covered
|
|
62
|
+
"--cov-report=xml", # Dump to XML for Codecov
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
extend-select = [
|
|
67
|
+
"I", # Sort imports
|
|
68
|
+
"ANN", # Enforce type annotations
|
|
69
|
+
"PT", # Common style issues or inconsistencies with pytest-based tests
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.ruff.lint.isort]
|
|
73
|
+
combine-as-imports = true # Combines "as" imports on the same line
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint.per-file-ignores]
|
|
76
|
+
"tests/**" = ["ANN"] # Do not enforce type annotations for tests
|
|
@@ -35,7 +35,7 @@ def diffpdf(
|
|
|
35
35
|
return False
|
|
36
36
|
|
|
37
37
|
logger.info("[3/4] Checking text content...")
|
|
38
|
-
if not check_text_content(ref_path, actual_path):
|
|
38
|
+
if not check_text_content(ref_path, actual_path, out_path):
|
|
39
39
|
return False
|
|
40
40
|
|
|
41
41
|
logger.info("[4/4] Checking visual content...")
|
|
@@ -33,7 +33,7 @@ def generate_diff(
|
|
|
33
33
|
return diff
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def check_text_content(ref: Path, actual: Path) -> bool:
|
|
36
|
+
def check_text_content(ref: Path, actual: Path, output_dir: Path | None) -> bool:
|
|
37
37
|
logger = logging.getLogger()
|
|
38
38
|
# Extract text and remove whitespace
|
|
39
39
|
ref_text = re.sub(r"\s+", " ", extract_text(ref)).strip()
|
|
@@ -42,6 +42,12 @@ def check_text_content(ref: Path, actual: Path) -> bool:
|
|
|
42
42
|
if ref_text != actual_text:
|
|
43
43
|
diff = generate_diff(ref_text, ref, actual_text, actual)
|
|
44
44
|
diff_text = "\n".join(diff)
|
|
45
|
+
|
|
46
|
+
if output_dir is not None:
|
|
47
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
diff_file = output_dir / f"{ref.stem}_vs_{actual.stem}_text_diff.txt"
|
|
49
|
+
diff_file.write_text(diff_text)
|
|
50
|
+
|
|
45
51
|
logger.error(f"Text content mismatch:\n {diff_text}")
|
|
46
52
|
return False
|
|
47
53
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# type: ignore
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
|
|
4
3
|
import pytest
|
|
@@ -9,7 +8,7 @@ TEST_ASSETS_DIR = Path(__file__).parent / "assets"
|
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
@pytest.mark.parametrize(
|
|
12
|
-
"ref_pdf_rel,actual_pdf_rel,should_pass",
|
|
11
|
+
("ref_pdf_rel", "actual_pdf_rel", "should_pass"),
|
|
13
12
|
[
|
|
14
13
|
# Pass cases
|
|
15
14
|
("pass/identical-A.pdf", "pass/identical-B.pdf", True),
|
|
@@ -29,3 +28,15 @@ def test_api(ref_pdf_rel, actual_pdf_rel, should_pass):
|
|
|
29
28
|
result = diffpdf(ref_pdf, actual_pdf)
|
|
30
29
|
|
|
31
30
|
assert result == should_pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_text_diff_output(tmp_path):
|
|
34
|
+
ref_pdf = TEST_ASSETS_DIR / "fail/1-letter-diff-A.pdf"
|
|
35
|
+
actual_pdf = TEST_ASSETS_DIR / "fail/1-letter-diff-B.pdf"
|
|
36
|
+
|
|
37
|
+
result = diffpdf(ref_pdf, actual_pdf, output_dir=tmp_path)
|
|
38
|
+
|
|
39
|
+
assert result is False
|
|
40
|
+
diff_file = tmp_path / "1-letter-diff-A_vs_1-letter-diff-B_text_diff.txt"
|
|
41
|
+
assert diff_file.exists()
|
|
42
|
+
assert diff_file.read_text()
|