winipedia-utils 0.1.63__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
Potentially problematic release.
This version of winipedia-utils might be problematic. Click here for more details.
- winipedia_utils/concurrent/concurrent.py +245 -242
- winipedia_utils/concurrent/multiprocessing.py +130 -115
- winipedia_utils/concurrent/multithreading.py +93 -93
- winipedia_utils/consts.py +23 -23
- winipedia_utils/data/__init__.py +1 -1
- winipedia_utils/data/dataframe/__init__.py +1 -0
- winipedia_utils/data/dataframe/cleaning.py +378 -0
- winipedia_utils/data/structures/__init__.py +1 -0
- winipedia_utils/data/structures/dicts.py +16 -0
- winipedia_utils/django/__init__.py +24 -24
- winipedia_utils/django/bulk.py +538 -538
- winipedia_utils/django/command.py +334 -334
- winipedia_utils/django/database.py +289 -289
- winipedia_utils/git/__init__.py +1 -1
- winipedia_utils/git/gitignore/__init__.py +1 -1
- winipedia_utils/git/gitignore/gitignore.py +136 -136
- winipedia_utils/git/pre_commit/__init__.py +1 -1
- winipedia_utils/git/pre_commit/config.py +70 -70
- winipedia_utils/git/pre_commit/hooks.py +109 -109
- winipedia_utils/git/pre_commit/run_hooks.py +49 -49
- winipedia_utils/iterating/__init__.py +1 -1
- winipedia_utils/iterating/iterate.py +29 -29
- winipedia_utils/logging/ansi.py +6 -6
- winipedia_utils/logging/config.py +64 -64
- winipedia_utils/logging/logger.py +26 -26
- winipedia_utils/modules/class_.py +119 -119
- winipedia_utils/modules/function.py +101 -103
- winipedia_utils/modules/module.py +379 -379
- winipedia_utils/modules/package.py +390 -390
- winipedia_utils/oop/mixins/meta.py +333 -331
- winipedia_utils/oop/mixins/mixin.py +37 -37
- winipedia_utils/os/__init__.py +1 -1
- winipedia_utils/os/os.py +63 -63
- winipedia_utils/projects/__init__.py +1 -1
- winipedia_utils/projects/poetry/__init__.py +1 -1
- winipedia_utils/projects/poetry/config.py +91 -91
- winipedia_utils/projects/poetry/poetry.py +31 -31
- winipedia_utils/projects/project.py +48 -48
- winipedia_utils/pyside/__init__.py +1 -1
- winipedia_utils/pyside/core/__init__.py +1 -1
- winipedia_utils/pyside/core/py_qiodevice.py +476 -476
- winipedia_utils/pyside/ui/__init__.py +1 -1
- winipedia_utils/pyside/ui/base/__init__.py +1 -1
- winipedia_utils/pyside/ui/base/base.py +180 -180
- winipedia_utils/pyside/ui/pages/__init__.py +1 -1
- winipedia_utils/pyside/ui/pages/base/__init__.py +1 -1
- winipedia_utils/pyside/ui/pages/base/base.py +92 -92
- winipedia_utils/pyside/ui/pages/browser.py +26 -26
- winipedia_utils/pyside/ui/pages/player.py +85 -85
- winipedia_utils/pyside/ui/widgets/__init__.py +1 -1
- winipedia_utils/pyside/ui/widgets/browser.py +243 -243
- winipedia_utils/pyside/ui/widgets/clickable_widget.py +57 -57
- winipedia_utils/pyside/ui/widgets/media_player.py +430 -430
- winipedia_utils/pyside/ui/widgets/notification.py +78 -78
- winipedia_utils/pyside/ui/windows/__init__.py +1 -1
- winipedia_utils/pyside/ui/windows/base/__init__.py +1 -1
- winipedia_utils/pyside/ui/windows/base/base.py +49 -49
- winipedia_utils/resources/__init__.py +1 -1
- winipedia_utils/resources/svgs/__init__.py +1 -1
- winipedia_utils/resources/svgs/download_arrow.svg +2 -2
- winipedia_utils/resources/svgs/exit_fullscreen_icon.svg +5 -5
- winipedia_utils/resources/svgs/fullscreen_icon.svg +2 -2
- winipedia_utils/resources/svgs/menu_icon.svg +3 -3
- winipedia_utils/resources/svgs/pause_icon.svg +3 -3
- winipedia_utils/resources/svgs/play_icon.svg +16 -16
- winipedia_utils/resources/svgs/plus_icon.svg +23 -23
- winipedia_utils/resources/svgs/svg.py +15 -15
- winipedia_utils/security/__init__.py +1 -1
- winipedia_utils/security/cryptography.py +29 -29
- winipedia_utils/security/keyring.py +70 -70
- winipedia_utils/setup.py +47 -47
- winipedia_utils/testing/assertions.py +23 -23
- winipedia_utils/testing/convention.py +177 -177
- winipedia_utils/testing/create_tests.py +291 -291
- winipedia_utils/testing/fixtures.py +28 -28
- winipedia_utils/testing/tests/base/fixtures/__init__.py +1 -1
- winipedia_utils/testing/tests/base/fixtures/fixture.py +6 -6
- winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +33 -33
- winipedia_utils/testing/tests/base/fixtures/scopes/function.py +7 -7
- winipedia_utils/testing/tests/base/fixtures/scopes/module.py +31 -31
- winipedia_utils/testing/tests/base/fixtures/scopes/package.py +7 -7
- winipedia_utils/testing/tests/base/fixtures/scopes/session.py +312 -312
- winipedia_utils/testing/tests/base/utils/utils.py +82 -82
- winipedia_utils/testing/tests/conftest.py +32 -32
- winipedia_utils/text/string.py +126 -126
- {winipedia_utils-0.1.63.dist-info → winipedia_utils-0.2.0.dist-info}/METADATA +5 -4
- winipedia_utils-0.2.0.dist-info/RECORD +103 -0
- {winipedia_utils-0.1.63.dist-info → winipedia_utils-0.2.0.dist-info}/WHEEL +1 -1
- {winipedia_utils-0.1.63.dist-info → winipedia_utils-0.2.0.dist-info/licenses}/LICENSE +21 -21
- winipedia_utils/data/dataframe.py +0 -7
- winipedia_utils-0.1.63.dist-info/RECORD +0 -100
|
@@ -1,312 +1,312 @@
|
|
|
1
|
-
"""Session-level test fixtures and utilities.
|
|
2
|
-
|
|
3
|
-
This module provides fixtures and test functions that operate at the session scope,
|
|
4
|
-
ensuring that project-wide conventions are followed and that the overall project
|
|
5
|
-
structure is correct. These fixtures are automatically applied to the test session
|
|
6
|
-
through pytest's autouse mechanism.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from importlib import import_module
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
from winipedia_utils.consts import _DEV_DEPENDENCIES
|
|
13
|
-
from winipedia_utils.git.gitignore.gitignore import _gitignore_is_correct
|
|
14
|
-
from winipedia_utils.git.pre_commit.config import (
|
|
15
|
-
_pre_commit_config_is_correct,
|
|
16
|
-
)
|
|
17
|
-
from winipedia_utils.modules.module import to_path
|
|
18
|
-
from winipedia_utils.modules.package import (
|
|
19
|
-
find_packages,
|
|
20
|
-
get_src_package,
|
|
21
|
-
walk_package,
|
|
22
|
-
)
|
|
23
|
-
from winipedia_utils.projects.poetry.config import (
|
|
24
|
-
_pyproject_tool_configs_are_correct,
|
|
25
|
-
get_poetry_package_name,
|
|
26
|
-
laod_pyproject_toml,
|
|
27
|
-
)
|
|
28
|
-
from winipedia_utils.testing.assertions import assert_with_msg
|
|
29
|
-
from winipedia_utils.testing.convention import (
|
|
30
|
-
TESTS_PACKAGE_NAME,
|
|
31
|
-
make_test_obj_importpath_from_obj,
|
|
32
|
-
)
|
|
33
|
-
from winipedia_utils.testing.fixtures import autouse_session_fixture
|
|
34
|
-
from winipedia_utils.testing.tests.base.utils.utils import (
|
|
35
|
-
_conftest_content_is_correct,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@autouse_session_fixture
|
|
40
|
-
def _test_dev_dependencies_const_correct() -> None:
|
|
41
|
-
"""Verify that the dev dependencies in consts.py are correct.
|
|
42
|
-
|
|
43
|
-
This fixture runs once per test session and checks that the dev dependencies
|
|
44
|
-
in consts.py are correct by comparing them to the dev dependencies in
|
|
45
|
-
pyproject.toml.
|
|
46
|
-
|
|
47
|
-
Raises:
|
|
48
|
-
AssertionError: If the dev dependencies in consts.py are not correct
|
|
49
|
-
|
|
50
|
-
"""
|
|
51
|
-
if get_poetry_package_name() != "winipedia_utils":
|
|
52
|
-
# this const is only used in winipedia_utils
|
|
53
|
-
# to be able to install them with setup.py
|
|
54
|
-
return
|
|
55
|
-
toml_dict = laod_pyproject_toml()
|
|
56
|
-
actual_dev_dependencies = (
|
|
57
|
-
toml_dict.get("tool", {})
|
|
58
|
-
.get("poetry", {})
|
|
59
|
-
.get("group", {})
|
|
60
|
-
.get("dev", {})
|
|
61
|
-
.get("dependencies", {})
|
|
62
|
-
.keys()
|
|
63
|
-
)
|
|
64
|
-
assert_with_msg(
|
|
65
|
-
set(actual_dev_dependencies) == set(_DEV_DEPENDENCIES),
|
|
66
|
-
"Dev dependencies in consts.py are not correct",
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@autouse_session_fixture
|
|
71
|
-
def _test_dev_dependencies_are_in_pyproject_toml() -> None:
|
|
72
|
-
"""Verify that the dev dependencies are installed.
|
|
73
|
-
|
|
74
|
-
This fixture runs once per test session and checks that the dev dependencies
|
|
75
|
-
are installed by trying to import them.
|
|
76
|
-
|
|
77
|
-
Raises:
|
|
78
|
-
ImportError: If a dev dependency is not installed
|
|
79
|
-
|
|
80
|
-
"""
|
|
81
|
-
toml_dict = laod_pyproject_toml()
|
|
82
|
-
dev_dependencies = (
|
|
83
|
-
toml_dict.get("tool", {})
|
|
84
|
-
.get("poetry", {})
|
|
85
|
-
.get("group", {})
|
|
86
|
-
.get("dev", {})
|
|
87
|
-
.get("dependencies", {})
|
|
88
|
-
.keys()
|
|
89
|
-
)
|
|
90
|
-
assert_with_msg(
|
|
91
|
-
set(_DEV_DEPENDENCIES).issubset(set(dev_dependencies)),
|
|
92
|
-
"Dev dependencies in consts.py are not a subset of the ones in pyproject.toml",
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@autouse_session_fixture
|
|
97
|
-
def _test_conftest_exists_and_is_correct() -> None:
|
|
98
|
-
"""Verify that the conftest.py file exists and has the correct content.
|
|
99
|
-
|
|
100
|
-
This fixture runs once per test session and checks that the conftest.py file
|
|
101
|
-
exists in the tests directory and contains the correct pytest_plugins configuration.
|
|
102
|
-
|
|
103
|
-
Raises:
|
|
104
|
-
AssertionError: If the conftest.py file doesn't exist or has incorrect content
|
|
105
|
-
|
|
106
|
-
"""
|
|
107
|
-
conftest_path = Path(TESTS_PACKAGE_NAME, "conftest.py")
|
|
108
|
-
assert_with_msg(
|
|
109
|
-
conftest_path.is_file(),
|
|
110
|
-
f"Expected conftest.py file at {conftest_path} but it doesn't exist",
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
assert_with_msg(
|
|
114
|
-
_conftest_content_is_correct(conftest_path),
|
|
115
|
-
"conftest.py has incorrect content",
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
@autouse_session_fixture
|
|
120
|
-
def _test_pyproject_toml_is_correct() -> None:
|
|
121
|
-
"""Verify that the pyproject.toml file exists and has the correct content.
|
|
122
|
-
|
|
123
|
-
This fixture runs once per test session and checks that the pyproject.toml file
|
|
124
|
-
exists in the root directory and contains the correct content.
|
|
125
|
-
|
|
126
|
-
Raises:
|
|
127
|
-
AssertionError: If the pyproject.toml file doesn't exist
|
|
128
|
-
or has incorrect content
|
|
129
|
-
|
|
130
|
-
"""
|
|
131
|
-
pyproject_toml_path = Path("pyproject.toml")
|
|
132
|
-
assert_with_msg(
|
|
133
|
-
pyproject_toml_path.is_file(),
|
|
134
|
-
f"Expected pyproject.toml file at {pyproject_toml_path} but it doesn't exist",
|
|
135
|
-
)
|
|
136
|
-
assert_with_msg(
|
|
137
|
-
_pyproject_tool_configs_are_correct(),
|
|
138
|
-
"pyproject.toml has incorrect content.",
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
@autouse_session_fixture
|
|
143
|
-
def _test_pre_commit_config_yaml_is_correct() -> None:
|
|
144
|
-
"""Verify that the pre-commit yaml is correctly defining winipedia utils hook.
|
|
145
|
-
|
|
146
|
-
Checks that the yaml starts with the winipedia utils hook.
|
|
147
|
-
"""
|
|
148
|
-
pre_commit_config = Path(".pre-commit-config.yaml")
|
|
149
|
-
|
|
150
|
-
assert_with_msg(
|
|
151
|
-
pre_commit_config.is_file(),
|
|
152
|
-
f"Expected {pre_commit_config} to exist but it doesn't.",
|
|
153
|
-
)
|
|
154
|
-
assert_with_msg(
|
|
155
|
-
_pre_commit_config_is_correct(),
|
|
156
|
-
"Pre commit config is not correct.",
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
@autouse_session_fixture
|
|
161
|
-
def _test_gitignore_is_correct() -> None:
|
|
162
|
-
"""Verify that the .gitignore file exists and has the correct content.
|
|
163
|
-
|
|
164
|
-
This fixture runs once per test session and checks that the .gitignore file
|
|
165
|
-
exists in the root directory and contains the correct content.
|
|
166
|
-
|
|
167
|
-
Raises:
|
|
168
|
-
AssertionError: If the .gitignore file doesn't exist
|
|
169
|
-
or has incorrect content
|
|
170
|
-
|
|
171
|
-
"""
|
|
172
|
-
gitignore_path = Path(".gitignore")
|
|
173
|
-
assert_with_msg(
|
|
174
|
-
gitignore_path.is_file(),
|
|
175
|
-
f"Expected {gitignore_path} to exist but it doesn't.",
|
|
176
|
-
)
|
|
177
|
-
assert_with_msg(
|
|
178
|
-
_gitignore_is_correct(),
|
|
179
|
-
"Gitignore is not correct.",
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
@autouse_session_fixture
|
|
184
|
-
def _test_no_namespace_packages() -> None:
|
|
185
|
-
"""Verify that there are no namespace packages in the project.
|
|
186
|
-
|
|
187
|
-
This fixture runs once per test session and checks that all packages in the
|
|
188
|
-
project are regular packages with __init__.py files, not namespace packages.
|
|
189
|
-
|
|
190
|
-
Raises:
|
|
191
|
-
AssertionError: If any namespace packages are found
|
|
192
|
-
|
|
193
|
-
"""
|
|
194
|
-
packages = find_packages(depth=None)
|
|
195
|
-
namespace_packages = find_packages(depth=None, include_namespace_packages=True)
|
|
196
|
-
|
|
197
|
-
any_namespace_packages = set(namespace_packages) - set(packages)
|
|
198
|
-
assert_with_msg(
|
|
199
|
-
not any_namespace_packages,
|
|
200
|
-
f"Found namespace packages: {any_namespace_packages}. "
|
|
201
|
-
f"All packages should have __init__.py files.",
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
@autouse_session_fixture
|
|
206
|
-
def _test_all_src_code_in_one_package() -> None:
|
|
207
|
-
"""Verify that all source code is in a single package.
|
|
208
|
-
|
|
209
|
-
This fixture runs once per test session and checks that there is only one
|
|
210
|
-
source package besides the tests package.
|
|
211
|
-
|
|
212
|
-
Raises:
|
|
213
|
-
AssertionError: If there are multiple source packages
|
|
214
|
-
|
|
215
|
-
"""
|
|
216
|
-
packages = find_packages(depth=0)
|
|
217
|
-
src_package = get_src_package().__name__
|
|
218
|
-
expected_packages = {TESTS_PACKAGE_NAME, src_package}
|
|
219
|
-
assert_with_msg(
|
|
220
|
-
set(packages) == expected_packages,
|
|
221
|
-
f"Expected only packages {expected_packages}, but found {packages}",
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
@autouse_session_fixture
|
|
226
|
-
def _test_src_package_correctly_named() -> None:
|
|
227
|
-
"""Verify that the source package is correctly named.
|
|
228
|
-
|
|
229
|
-
This fixture runs once per test session and checks that the source package
|
|
230
|
-
is correctly named after the project.
|
|
231
|
-
|
|
232
|
-
Raises:
|
|
233
|
-
AssertionError: If the source package is not correctly named
|
|
234
|
-
|
|
235
|
-
"""
|
|
236
|
-
src_package = get_src_package().__name__
|
|
237
|
-
assert_with_msg(
|
|
238
|
-
src_package == get_poetry_package_name(),
|
|
239
|
-
f"Expected source package to be named {get_poetry_package_name()}, "
|
|
240
|
-
f"but it is named {src_package}",
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
@autouse_session_fixture
|
|
245
|
-
def _test_py_typed_exists() -> None:
|
|
246
|
-
"""Verify that the py.typed file exists in the source package.
|
|
247
|
-
|
|
248
|
-
This fixture runs once per test session and checks that the py.typed file
|
|
249
|
-
exists in the source package.
|
|
250
|
-
|
|
251
|
-
Raises:
|
|
252
|
-
AssertionError: If the py.typed file doesn't exist
|
|
253
|
-
|
|
254
|
-
"""
|
|
255
|
-
src_package = get_src_package()
|
|
256
|
-
py_typed_path = to_path(src_package.__name__, is_package=True) / "py.typed"
|
|
257
|
-
assert_with_msg(
|
|
258
|
-
py_typed_path.exists(),
|
|
259
|
-
f"Expected py.typed file to exist at {py_typed_path}",
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
@autouse_session_fixture
|
|
264
|
-
def _test_project_structure_mirrored() -> None:
|
|
265
|
-
"""Verify that the project structure is mirrored in tests.
|
|
266
|
-
|
|
267
|
-
This fixture runs once per test session and checks that for every package and
|
|
268
|
-
module in the source package, there is a corresponding test package and module.
|
|
269
|
-
|
|
270
|
-
Raises:
|
|
271
|
-
AssertionError: If any package or module doesn't have a corresponding test
|
|
272
|
-
|
|
273
|
-
"""
|
|
274
|
-
src_package = get_src_package()
|
|
275
|
-
|
|
276
|
-
# we will now go through all the modules in the src package and check
|
|
277
|
-
# that there is a corresponding test module
|
|
278
|
-
for package, modules in walk_package(src_package):
|
|
279
|
-
test_package_name = make_test_obj_importpath_from_obj(package)
|
|
280
|
-
test_package = import_module(test_package_name)
|
|
281
|
-
assert_with_msg(
|
|
282
|
-
bool(test_package),
|
|
283
|
-
f"Expected test package {test_package_name} to be a module",
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
for module in modules:
|
|
287
|
-
test_module_name = make_test_obj_importpath_from_obj(module)
|
|
288
|
-
test_module = import_module(test_module_name)
|
|
289
|
-
assert_with_msg(
|
|
290
|
-
bool(test_module),
|
|
291
|
-
f"Expected test module {test_module_name} to be a module",
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
@autouse_session_fixture
|
|
296
|
-
def _test_no_unitest_package_usage() -> None:
|
|
297
|
-
"""Verify that the unittest package is not used in the project.
|
|
298
|
-
|
|
299
|
-
This fixture runs once per test session and checks that the unittest package
|
|
300
|
-
is not used in the project.
|
|
301
|
-
|
|
302
|
-
Raises:
|
|
303
|
-
AssertionError: If the unittest package is used
|
|
304
|
-
|
|
305
|
-
"""
|
|
306
|
-
for path in Path().rglob("*.py"):
|
|
307
|
-
if path == to_path(__name__, is_package=False):
|
|
308
|
-
continue
|
|
309
|
-
assert_with_msg(
|
|
310
|
-
"unittest" not in path.read_text(encoding="utf-8"),
|
|
311
|
-
f"Found unittest usage in {path}. Use pytest instead.",
|
|
312
|
-
)
|
|
1
|
+
"""Session-level test fixtures and utilities.
|
|
2
|
+
|
|
3
|
+
This module provides fixtures and test functions that operate at the session scope,
|
|
4
|
+
ensuring that project-wide conventions are followed and that the overall project
|
|
5
|
+
structure is correct. These fixtures are automatically applied to the test session
|
|
6
|
+
through pytest's autouse mechanism.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from importlib import import_module
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from winipedia_utils.consts import _DEV_DEPENDENCIES
|
|
13
|
+
from winipedia_utils.git.gitignore.gitignore import _gitignore_is_correct
|
|
14
|
+
from winipedia_utils.git.pre_commit.config import (
|
|
15
|
+
_pre_commit_config_is_correct,
|
|
16
|
+
)
|
|
17
|
+
from winipedia_utils.modules.module import to_path
|
|
18
|
+
from winipedia_utils.modules.package import (
|
|
19
|
+
find_packages,
|
|
20
|
+
get_src_package,
|
|
21
|
+
walk_package,
|
|
22
|
+
)
|
|
23
|
+
from winipedia_utils.projects.poetry.config import (
|
|
24
|
+
_pyproject_tool_configs_are_correct,
|
|
25
|
+
get_poetry_package_name,
|
|
26
|
+
laod_pyproject_toml,
|
|
27
|
+
)
|
|
28
|
+
from winipedia_utils.testing.assertions import assert_with_msg
|
|
29
|
+
from winipedia_utils.testing.convention import (
|
|
30
|
+
TESTS_PACKAGE_NAME,
|
|
31
|
+
make_test_obj_importpath_from_obj,
|
|
32
|
+
)
|
|
33
|
+
from winipedia_utils.testing.fixtures import autouse_session_fixture
|
|
34
|
+
from winipedia_utils.testing.tests.base.utils.utils import (
|
|
35
|
+
_conftest_content_is_correct,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@autouse_session_fixture
|
|
40
|
+
def _test_dev_dependencies_const_correct() -> None:
|
|
41
|
+
"""Verify that the dev dependencies in consts.py are correct.
|
|
42
|
+
|
|
43
|
+
This fixture runs once per test session and checks that the dev dependencies
|
|
44
|
+
in consts.py are correct by comparing them to the dev dependencies in
|
|
45
|
+
pyproject.toml.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
AssertionError: If the dev dependencies in consts.py are not correct
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
if get_poetry_package_name() != "winipedia_utils":
|
|
52
|
+
# this const is only used in winipedia_utils
|
|
53
|
+
# to be able to install them with setup.py
|
|
54
|
+
return
|
|
55
|
+
toml_dict = laod_pyproject_toml()
|
|
56
|
+
actual_dev_dependencies = (
|
|
57
|
+
toml_dict.get("tool", {})
|
|
58
|
+
.get("poetry", {})
|
|
59
|
+
.get("group", {})
|
|
60
|
+
.get("dev", {})
|
|
61
|
+
.get("dependencies", {})
|
|
62
|
+
.keys()
|
|
63
|
+
)
|
|
64
|
+
assert_with_msg(
|
|
65
|
+
set(actual_dev_dependencies) == set(_DEV_DEPENDENCIES),
|
|
66
|
+
"Dev dependencies in consts.py are not correct",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@autouse_session_fixture
|
|
71
|
+
def _test_dev_dependencies_are_in_pyproject_toml() -> None:
|
|
72
|
+
"""Verify that the dev dependencies are installed.
|
|
73
|
+
|
|
74
|
+
This fixture runs once per test session and checks that the dev dependencies
|
|
75
|
+
are installed by trying to import them.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ImportError: If a dev dependency is not installed
|
|
79
|
+
|
|
80
|
+
"""
|
|
81
|
+
toml_dict = laod_pyproject_toml()
|
|
82
|
+
dev_dependencies = (
|
|
83
|
+
toml_dict.get("tool", {})
|
|
84
|
+
.get("poetry", {})
|
|
85
|
+
.get("group", {})
|
|
86
|
+
.get("dev", {})
|
|
87
|
+
.get("dependencies", {})
|
|
88
|
+
.keys()
|
|
89
|
+
)
|
|
90
|
+
assert_with_msg(
|
|
91
|
+
set(_DEV_DEPENDENCIES).issubset(set(dev_dependencies)),
|
|
92
|
+
"Dev dependencies in consts.py are not a subset of the ones in pyproject.toml",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@autouse_session_fixture
|
|
97
|
+
def _test_conftest_exists_and_is_correct() -> None:
|
|
98
|
+
"""Verify that the conftest.py file exists and has the correct content.
|
|
99
|
+
|
|
100
|
+
This fixture runs once per test session and checks that the conftest.py file
|
|
101
|
+
exists in the tests directory and contains the correct pytest_plugins configuration.
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
AssertionError: If the conftest.py file doesn't exist or has incorrect content
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
conftest_path = Path(TESTS_PACKAGE_NAME, "conftest.py")
|
|
108
|
+
assert_with_msg(
|
|
109
|
+
conftest_path.is_file(),
|
|
110
|
+
f"Expected conftest.py file at {conftest_path} but it doesn't exist",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
assert_with_msg(
|
|
114
|
+
_conftest_content_is_correct(conftest_path),
|
|
115
|
+
"conftest.py has incorrect content",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@autouse_session_fixture
|
|
120
|
+
def _test_pyproject_toml_is_correct() -> None:
|
|
121
|
+
"""Verify that the pyproject.toml file exists and has the correct content.
|
|
122
|
+
|
|
123
|
+
This fixture runs once per test session and checks that the pyproject.toml file
|
|
124
|
+
exists in the root directory and contains the correct content.
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
AssertionError: If the pyproject.toml file doesn't exist
|
|
128
|
+
or has incorrect content
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
pyproject_toml_path = Path("pyproject.toml")
|
|
132
|
+
assert_with_msg(
|
|
133
|
+
pyproject_toml_path.is_file(),
|
|
134
|
+
f"Expected pyproject.toml file at {pyproject_toml_path} but it doesn't exist",
|
|
135
|
+
)
|
|
136
|
+
assert_with_msg(
|
|
137
|
+
_pyproject_tool_configs_are_correct(),
|
|
138
|
+
"pyproject.toml has incorrect content.",
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@autouse_session_fixture
|
|
143
|
+
def _test_pre_commit_config_yaml_is_correct() -> None:
|
|
144
|
+
"""Verify that the pre-commit yaml is correctly defining winipedia utils hook.
|
|
145
|
+
|
|
146
|
+
Checks that the yaml starts with the winipedia utils hook.
|
|
147
|
+
"""
|
|
148
|
+
pre_commit_config = Path(".pre-commit-config.yaml")
|
|
149
|
+
|
|
150
|
+
assert_with_msg(
|
|
151
|
+
pre_commit_config.is_file(),
|
|
152
|
+
f"Expected {pre_commit_config} to exist but it doesn't.",
|
|
153
|
+
)
|
|
154
|
+
assert_with_msg(
|
|
155
|
+
_pre_commit_config_is_correct(),
|
|
156
|
+
"Pre commit config is not correct.",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@autouse_session_fixture
|
|
161
|
+
def _test_gitignore_is_correct() -> None:
|
|
162
|
+
"""Verify that the .gitignore file exists and has the correct content.
|
|
163
|
+
|
|
164
|
+
This fixture runs once per test session and checks that the .gitignore file
|
|
165
|
+
exists in the root directory and contains the correct content.
|
|
166
|
+
|
|
167
|
+
Raises:
|
|
168
|
+
AssertionError: If the .gitignore file doesn't exist
|
|
169
|
+
or has incorrect content
|
|
170
|
+
|
|
171
|
+
"""
|
|
172
|
+
gitignore_path = Path(".gitignore")
|
|
173
|
+
assert_with_msg(
|
|
174
|
+
gitignore_path.is_file(),
|
|
175
|
+
f"Expected {gitignore_path} to exist but it doesn't.",
|
|
176
|
+
)
|
|
177
|
+
assert_with_msg(
|
|
178
|
+
_gitignore_is_correct(),
|
|
179
|
+
"Gitignore is not correct.",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@autouse_session_fixture
|
|
184
|
+
def _test_no_namespace_packages() -> None:
|
|
185
|
+
"""Verify that there are no namespace packages in the project.
|
|
186
|
+
|
|
187
|
+
This fixture runs once per test session and checks that all packages in the
|
|
188
|
+
project are regular packages with __init__.py files, not namespace packages.
|
|
189
|
+
|
|
190
|
+
Raises:
|
|
191
|
+
AssertionError: If any namespace packages are found
|
|
192
|
+
|
|
193
|
+
"""
|
|
194
|
+
packages = find_packages(depth=None)
|
|
195
|
+
namespace_packages = find_packages(depth=None, include_namespace_packages=True)
|
|
196
|
+
|
|
197
|
+
any_namespace_packages = set(namespace_packages) - set(packages)
|
|
198
|
+
assert_with_msg(
|
|
199
|
+
not any_namespace_packages,
|
|
200
|
+
f"Found namespace packages: {any_namespace_packages}. "
|
|
201
|
+
f"All packages should have __init__.py files.",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@autouse_session_fixture
|
|
206
|
+
def _test_all_src_code_in_one_package() -> None:
|
|
207
|
+
"""Verify that all source code is in a single package.
|
|
208
|
+
|
|
209
|
+
This fixture runs once per test session and checks that there is only one
|
|
210
|
+
source package besides the tests package.
|
|
211
|
+
|
|
212
|
+
Raises:
|
|
213
|
+
AssertionError: If there are multiple source packages
|
|
214
|
+
|
|
215
|
+
"""
|
|
216
|
+
packages = find_packages(depth=0)
|
|
217
|
+
src_package = get_src_package().__name__
|
|
218
|
+
expected_packages = {TESTS_PACKAGE_NAME, src_package}
|
|
219
|
+
assert_with_msg(
|
|
220
|
+
set(packages) == expected_packages,
|
|
221
|
+
f"Expected only packages {expected_packages}, but found {packages}",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@autouse_session_fixture
|
|
226
|
+
def _test_src_package_correctly_named() -> None:
|
|
227
|
+
"""Verify that the source package is correctly named.
|
|
228
|
+
|
|
229
|
+
This fixture runs once per test session and checks that the source package
|
|
230
|
+
is correctly named after the project.
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
AssertionError: If the source package is not correctly named
|
|
234
|
+
|
|
235
|
+
"""
|
|
236
|
+
src_package = get_src_package().__name__
|
|
237
|
+
assert_with_msg(
|
|
238
|
+
src_package == get_poetry_package_name(),
|
|
239
|
+
f"Expected source package to be named {get_poetry_package_name()}, "
|
|
240
|
+
f"but it is named {src_package}",
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@autouse_session_fixture
|
|
245
|
+
def _test_py_typed_exists() -> None:
|
|
246
|
+
"""Verify that the py.typed file exists in the source package.
|
|
247
|
+
|
|
248
|
+
This fixture runs once per test session and checks that the py.typed file
|
|
249
|
+
exists in the source package.
|
|
250
|
+
|
|
251
|
+
Raises:
|
|
252
|
+
AssertionError: If the py.typed file doesn't exist
|
|
253
|
+
|
|
254
|
+
"""
|
|
255
|
+
src_package = get_src_package()
|
|
256
|
+
py_typed_path = to_path(src_package.__name__, is_package=True) / "py.typed"
|
|
257
|
+
assert_with_msg(
|
|
258
|
+
py_typed_path.exists(),
|
|
259
|
+
f"Expected py.typed file to exist at {py_typed_path}",
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@autouse_session_fixture
|
|
264
|
+
def _test_project_structure_mirrored() -> None:
|
|
265
|
+
"""Verify that the project structure is mirrored in tests.
|
|
266
|
+
|
|
267
|
+
This fixture runs once per test session and checks that for every package and
|
|
268
|
+
module in the source package, there is a corresponding test package and module.
|
|
269
|
+
|
|
270
|
+
Raises:
|
|
271
|
+
AssertionError: If any package or module doesn't have a corresponding test
|
|
272
|
+
|
|
273
|
+
"""
|
|
274
|
+
src_package = get_src_package()
|
|
275
|
+
|
|
276
|
+
# we will now go through all the modules in the src package and check
|
|
277
|
+
# that there is a corresponding test module
|
|
278
|
+
for package, modules in walk_package(src_package):
|
|
279
|
+
test_package_name = make_test_obj_importpath_from_obj(package)
|
|
280
|
+
test_package = import_module(test_package_name)
|
|
281
|
+
assert_with_msg(
|
|
282
|
+
bool(test_package),
|
|
283
|
+
f"Expected test package {test_package_name} to be a module",
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
for module in modules:
|
|
287
|
+
test_module_name = make_test_obj_importpath_from_obj(module)
|
|
288
|
+
test_module = import_module(test_module_name)
|
|
289
|
+
assert_with_msg(
|
|
290
|
+
bool(test_module),
|
|
291
|
+
f"Expected test module {test_module_name} to be a module",
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@autouse_session_fixture
|
|
296
|
+
def _test_no_unitest_package_usage() -> None:
|
|
297
|
+
"""Verify that the unittest package is not used in the project.
|
|
298
|
+
|
|
299
|
+
This fixture runs once per test session and checks that the unittest package
|
|
300
|
+
is not used in the project.
|
|
301
|
+
|
|
302
|
+
Raises:
|
|
303
|
+
AssertionError: If the unittest package is used
|
|
304
|
+
|
|
305
|
+
"""
|
|
306
|
+
for path in Path().rglob("*.py"):
|
|
307
|
+
if path == to_path(__name__, is_package=False):
|
|
308
|
+
continue
|
|
309
|
+
assert_with_msg(
|
|
310
|
+
"unittest" not in path.read_text(encoding="utf-8"),
|
|
311
|
+
f"Found unittest usage in {path}. Use pytest instead.",
|
|
312
|
+
)
|