pytest-respect 0.0.1__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.
- pytest_respect-0.0.1/.github/workflows/python-package.yml +42 -0
- pytest_respect-0.0.1/.gitignore +18 -0
- pytest_respect-0.0.1/.python-version +1 -0
- pytest_respect-0.0.1/LICENSE +21 -0
- pytest_respect-0.0.1/PKG-INFO +47 -0
- pytest_respect-0.0.1/README.md +17 -0
- pytest_respect-0.0.1/pyproject.toml +89 -0
- pytest_respect-0.0.1/src/pytest_respect/__init__.py +9 -0
- pytest_respect-0.0.1/src/pytest_respect/ext/__init__.py +1 -0
- pytest_respect-0.0.1/src/pytest_respect/ext/jsonyx.py +49 -0
- pytest_respect-0.0.1/src/pytest_respect/plugin.py +9 -0
- pytest_respect-0.0.1/src/pytest_respect/resources.py +588 -0
- pytest_respect-0.0.1/src/pytest_respect/utils.py +44 -0
- pytest_respect-0.0.1/tests/__init__.py +0 -0
- pytest_respect-0.0.1/tests/pytest_resources/__init__.py +0 -0
- pytest_respect-0.0.1/tests/pytest_resources/ext/__init__.py +0 -0
- pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx/test_expected_json__jsonyx.json +5 -0
- pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx/test_load_json__jsonyx_permissive.json +4 -0
- pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx.py +31 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expect_text.txt +2 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expect_text__mismatch.txt +1 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json.json +8 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__compact.json +1 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__default_digits.json +3 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__ndigits__test_load_json.json +3 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_pydantic.json +8 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_json.json +3 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic.json +1 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic_adapter.json +5 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic_adapter__failing.json +5 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_text.txt +1 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_resources.py +467 -0
- pytest_respect-0.0.1/tests/pytest_resources/test_utils.py +136 -0
- pytest_respect-0.0.1/uv.lock +619 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
|
3
|
+
|
|
4
|
+
name: Python package
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
- push
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: [ "3.10", "3.11", "3.12", "3.13" ]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
22
|
+
uses: actions/setup-python@v3
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: |
|
|
28
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
29
|
+
uv sync --dev --all-extras
|
|
30
|
+
# TODO run subset of tests with no extras
|
|
31
|
+
|
|
32
|
+
- name: Lint with ruff
|
|
33
|
+
run: uv run ruff check
|
|
34
|
+
|
|
35
|
+
- name: Type-check with pyright
|
|
36
|
+
run: uv run pyright
|
|
37
|
+
|
|
38
|
+
- name: Test with pytest
|
|
39
|
+
run: |
|
|
40
|
+
mkdir junit
|
|
41
|
+
uv run pytest tests/ --junitxml=junit/test-results.xml --cov-report=term-missing:skip-covered --cov=src |
|
|
42
|
+
tee junit/pytest-coverage.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ankeri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytest-respect
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Pytest plugin to load resource files relative to test code and to expect values to match them.
|
|
5
|
+
Project-URL: homepage, https://github.com/Ankeri/pytest-respect
|
|
6
|
+
Project-URL: issues, https://github.com/Ankeri/pytest-respect/issues
|
|
7
|
+
Author-email: Logi Ragnarsson <logi.ragnarsson@ankeri.is>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Framework :: Pytest
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: pytest>=8.0.0
|
|
23
|
+
Provides-Extra: jsonyx
|
|
24
|
+
Requires-Dist: jsonyx>=2.0.0; extra == 'jsonyx'
|
|
25
|
+
Provides-Extra: numpy
|
|
26
|
+
Requires-Dist: numpy>=2.0.0; extra == 'numpy'
|
|
27
|
+
Provides-Extra: pydantic
|
|
28
|
+
Requires-Dist: pydantic>=2.0.0; extra == 'pydantic'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# pytest-respect
|
|
32
|
+
|
|
33
|
+
Pytest plugin to load resource files relative to test code and to expect values to match them. The name is a contraction of `resources.expect`, which is frequently typed when using this plugin.
|
|
34
|
+
|
|
35
|
+
The primary use-case is running tests over moderately large datasets where adding them as constants in the test code would be cumbersome. This happens frequently with integration tests or when retrofitting tests onto an existing code-base.
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
|
|
39
|
+
The absolute simplest example is the following test. If it is found in a file called `foo/test_stuff.py`, then it will load the content of `foo/test_stuff/test_computation__input.json`, run the `compute` function on it, and assert that the output exactly matches the content of the file `foo/test_stuff/test_computation__output.json`.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
def test_computation(resources):
|
|
43
|
+
"""Running compute on input.json creates an output matching output.json"""
|
|
44
|
+
input = resources.load_json("input")
|
|
45
|
+
output = compute(input)
|
|
46
|
+
resources.expect_json(output, "output")
|
|
47
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# pytest-respect
|
|
2
|
+
|
|
3
|
+
Pytest plugin to load resource files relative to test code and to expect values to match them. The name is a contraction of `resources.expect`, which is frequently typed when using this plugin.
|
|
4
|
+
|
|
5
|
+
The primary use-case is running tests over moderately large datasets where adding them as constants in the test code would be cumbersome. This happens frequently with integration tests or when retrofitting tests onto an existing code-base.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
The absolute simplest example is the following test. If it is found in a file called `foo/test_stuff.py`, then it will load the content of `foo/test_stuff/test_computation__input.json`, run the `compute` function on it, and assert that the output exactly matches the content of the file `foo/test_stuff/test_computation__output.json`.
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
def test_computation(resources):
|
|
13
|
+
"""Running compute on input.json creates an output matching output.json"""
|
|
14
|
+
input = resources.load_json("input")
|
|
15
|
+
output = compute(input)
|
|
16
|
+
resources.expect_json(output, "output")
|
|
17
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# METADATA
|
|
2
|
+
|
|
3
|
+
[project]
|
|
4
|
+
name = "pytest-respect"
|
|
5
|
+
version = "0.0.1"
|
|
6
|
+
description = "Pytest plugin to load resource files relative to test code and to expect values to match them."
|
|
7
|
+
urls.homepage = "https://github.com/Ankeri/pytest-respect"
|
|
8
|
+
urls.issues = "https://github.com/Ankeri/pytest-respect/issues"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Logi Ragnarsson", email = "logi.ragnarsson@ankeri.is" }
|
|
12
|
+
]
|
|
13
|
+
license = "MIT"
|
|
14
|
+
license-files = ["LICENSE.md"]
|
|
15
|
+
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
28
|
+
"Framework :: Pytest"
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# DEPENDENCIES
|
|
33
|
+
|
|
34
|
+
requires-python = ">=3.10"
|
|
35
|
+
|
|
36
|
+
dependencies = [
|
|
37
|
+
"pytest>=8.0.0",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
pydantic = ["pydantic>=2.0.0"]
|
|
42
|
+
numpy = ["numpy>=2.0.0"]
|
|
43
|
+
jsonyx = ["jsonyx>=2.0.0"]
|
|
44
|
+
|
|
45
|
+
[dependency-groups]
|
|
46
|
+
dev = [
|
|
47
|
+
"pyright==1.1.*",
|
|
48
|
+
"pytest-cov==6.*",
|
|
49
|
+
"pytest-mock==3.*",
|
|
50
|
+
"ruff==0.*",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# PYTEST PLUGIN
|
|
55
|
+
|
|
56
|
+
[project.entry-points.pytest11]
|
|
57
|
+
respect = "pytest_respect.plugin"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# BUILD
|
|
61
|
+
|
|
62
|
+
[build-system]
|
|
63
|
+
requires = ["hatchling"]
|
|
64
|
+
build-backend = "hatchling.build"
|
|
65
|
+
|
|
66
|
+
[tool.hatch.build.targets.wheel]
|
|
67
|
+
packages = ["src/pytest_respect"]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# LINTING
|
|
71
|
+
|
|
72
|
+
[tool.ruff]
|
|
73
|
+
line-length = 140
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
select = [
|
|
77
|
+
"E", # pycodestyle
|
|
78
|
+
"F", # Pyflakes
|
|
79
|
+
"UP", # pyupgrade
|
|
80
|
+
"B", # flake8-bugbear
|
|
81
|
+
"I", # isort
|
|
82
|
+
"N", # pep8-naming
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
[tool.ruff.lint.per-file-ignores]
|
|
86
|
+
"test_*.py" = [
|
|
87
|
+
"D401", # imperative mode: tests are doc'd with statements and fixtures with nouns
|
|
88
|
+
"N802", # snake_case: Allow test_MyFancyClass_method
|
|
89
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Extensions to base pytest-respect functionality."""
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JSON encoders and loaders using the jsonyx library.
|
|
3
|
+
See https://github.com/nineteendo/jsonyx
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def jsonyx_encoder(obj: Any) -> str:
|
|
10
|
+
"""JSONYX encoder in very verbose mode."""
|
|
11
|
+
import jsonyx.allow
|
|
12
|
+
|
|
13
|
+
return jsonyx.dumps(
|
|
14
|
+
obj,
|
|
15
|
+
sort_keys=True,
|
|
16
|
+
indent=2,
|
|
17
|
+
allow=jsonyx.allow.NON_STR_KEYS,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def jsonyx_compactish_encoder(obj: Any) -> str:
|
|
22
|
+
"""JSONYX encoder which encodes lists and objects of primitives in compact mode."""
|
|
23
|
+
import jsonyx.allow
|
|
24
|
+
|
|
25
|
+
return jsonyx.dumps(
|
|
26
|
+
obj,
|
|
27
|
+
sort_keys=True,
|
|
28
|
+
indent=2,
|
|
29
|
+
indent_leaves=False,
|
|
30
|
+
allow=jsonyx.allow.NON_STR_KEYS,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def jsonyx_compact_encoder(obj: Any) -> str:
|
|
35
|
+
"""JSONYX encoder in very compact mode."""
|
|
36
|
+
import jsonyx.allow
|
|
37
|
+
|
|
38
|
+
return jsonyx.dumps(
|
|
39
|
+
obj,
|
|
40
|
+
sort_keys=True,
|
|
41
|
+
allow=jsonyx.allow.NON_STR_KEYS,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def jsonyx_permissive_loader(text: str) -> Any:
|
|
46
|
+
"""JSONYX loader in very permissive mode."""
|
|
47
|
+
import jsonyx.allow
|
|
48
|
+
|
|
49
|
+
return jsonyx.loads(text, allow=jsonyx.allow.EVERYTHING)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from pytest_respect.resources import TestResources
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.fixture
|
|
7
|
+
def resources(request: pytest.FixtureRequest) -> TestResources:
|
|
8
|
+
"""Load file resources relative to test functions and fixtures."""
|
|
9
|
+
return TestResources(request, ndigits=4)
|