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.
Files changed (34) hide show
  1. pytest_respect-0.0.1/.github/workflows/python-package.yml +42 -0
  2. pytest_respect-0.0.1/.gitignore +18 -0
  3. pytest_respect-0.0.1/.python-version +1 -0
  4. pytest_respect-0.0.1/LICENSE +21 -0
  5. pytest_respect-0.0.1/PKG-INFO +47 -0
  6. pytest_respect-0.0.1/README.md +17 -0
  7. pytest_respect-0.0.1/pyproject.toml +89 -0
  8. pytest_respect-0.0.1/src/pytest_respect/__init__.py +9 -0
  9. pytest_respect-0.0.1/src/pytest_respect/ext/__init__.py +1 -0
  10. pytest_respect-0.0.1/src/pytest_respect/ext/jsonyx.py +49 -0
  11. pytest_respect-0.0.1/src/pytest_respect/plugin.py +9 -0
  12. pytest_respect-0.0.1/src/pytest_respect/resources.py +588 -0
  13. pytest_respect-0.0.1/src/pytest_respect/utils.py +44 -0
  14. pytest_respect-0.0.1/tests/__init__.py +0 -0
  15. pytest_respect-0.0.1/tests/pytest_resources/__init__.py +0 -0
  16. pytest_respect-0.0.1/tests/pytest_resources/ext/__init__.py +0 -0
  17. pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx/test_expected_json__jsonyx.json +5 -0
  18. pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx/test_load_json__jsonyx_permissive.json +4 -0
  19. pytest_respect-0.0.1/tests/pytest_resources/ext/test_jsonyx.py +31 -0
  20. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expect_text.txt +2 -0
  21. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expect_text__mismatch.txt +1 -0
  22. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json.json +8 -0
  23. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__compact.json +1 -0
  24. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__default_digits.json +3 -0
  25. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_json__ndigits__test_load_json.json +3 -0
  26. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_expected_pydantic.json +8 -0
  27. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_json.json +3 -0
  28. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic.json +1 -0
  29. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic_adapter.json +5 -0
  30. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_pydantic_adapter__failing.json +5 -0
  31. pytest_respect-0.0.1/tests/pytest_resources/test_resources/test_load_text.txt +1 -0
  32. pytest_respect-0.0.1/tests/pytest_resources/test_resources.py +467 -0
  33. pytest_respect-0.0.1/tests/pytest_resources/test_utils.py +136 -0
  34. 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,18 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ junit/
9
+ .coverage
10
+
11
+ # IDEs
12
+ /.idea
13
+
14
+ # Virtual environments
15
+ .venv
16
+
17
+ # Local secrets for e.g. direnv
18
+ /.envrc
@@ -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,9 @@
1
+ from pytest_respect.resources import PathMaker, TestResources, list_resources
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ __all__ = [
6
+ "TestResources",
7
+ "PathMaker",
8
+ "list_resources",
9
+ ]
@@ -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)