test: add test coverage for tests/helpers.py#10844
test: add test coverage for tests/helpers.py#10844yosofbadr wants to merge 5 commits intopython-poetry:mainfrom
Conversation
Add comprehensive tests for all helper functions and classes in tests/helpers.py as requested in issue python-poetry#9161. The existing tests covered only flatten_dict, isolated_environment, and switch_working_directory. This adds coverage for: - get_package: package creation with version and yanked status - get_dependency: dependency creation with constraints, groups, options - copy_path: file and directory copying with overwrite behavior - MockDulwichRepo: path storage and mock git revision - mock_clone: fixture-based git clone simulation - TestLocker: lock state management and data persistence - TestRepository: package lookup and link generation - make_entry_point_from_plugin: entry point creation from plugin classes - mock_metadata_entry_points: metadata patching for plugin tests - with_working_directory: working directory with optional copy - set_keyring_backend: keyring backend switching with cache clearing - pbs_installer_supported_arch: architecture support detection
- Add type annotation for 'data' variable to fix var-annotated error - Use tmp_path fixture for MockDulwichRepo tests to fix Windows path separator assertion failures - Match conftest DummyBackend pattern with classproperty and typed __init__ to fix unused-ignore and no-untyped-call mypy errors
- Replace `eps == []` with `len(eps) == 0` to fix mypy comparison-overlap error on Python 3.12+ (EntryPoints cannot be compared with list[Never]) - Remove unused imports (Path from pathlib, FIXTURE_PATH) - Move Path import into TYPE_CHECKING block - Apply ruff formatting fixes
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="tests/test_helpers.py" line_range="478-487" />
<code_context>
+class TestSetKeyringBackend:
</code_context>
<issue_to_address>
**issue (testing):** Test does not actually verify the cache-clearing behavior and leaves global keyring state mutated after the test.
This only checks that the global backend is set, not that `PoetryKeyring`’s availability cache is actually cleared and recomputed. Please also assert that `PoetryKeyring.is_available()` is recalculated (e.g., set a known value before `set_keyring_backend` and verify it changes afterward). In addition, the test mutates the process-wide keyring backend without restoring it; capture `keyring.get_keyring()` beforehand and restore it in a `try/finally` or fixture teardown to avoid cross-test interference.
</issue_to_address>
### Comment 2
<location path="tests/test_helpers.py" line_range="260-269" />
<code_context>
+class TestTestRepository:
</code_context>
<issue_to_address>
**suggestion (testing):** Repository tests don't cover version/constraint resolution behavior when multiple packages are present.
Since `TestRepository` is used to simulate real resolution behavior, please add a test with multiple versions of the same package and a constrained dependency. For example, add `foo-1.0.0` and `foo-2.0.0` and assert that `find_packages(get_dependency("foo", "<2.0"))` returns only the expected version(s).
</issue_to_address>
### Comment 3
<location path="tests/test_helpers.py" line_range="65-74" />
<code_context>
+# --- get_dependency ---
+
+
+class TestGetDependency:
+ def test_returns_dependency_with_wildcard_constraint(self) -> None:
+ dep = get_dependency("foo")
+ assert dep.name == "foo"
+ assert str(dep.constraint) == "*"
+
+ def test_returns_dependency_with_version_constraint(self) -> None:
+ dep = get_dependency("foo", ">=1.0")
+ assert dep.name == "foo"
+
+ def test_returns_dependency_with_dict_constraint(self) -> None:
+ dep = get_dependency("foo", {"version": ">=1.0", "python": "^3.10"})
+ assert dep.name == "foo"
+
+ def test_returns_optional_dependency(self) -> None:
+ dep = get_dependency("foo", ">=1.0", optional=True)
+ assert dep.is_optional()
+
+ def test_returns_dependency_with_groups(self) -> None:
+ dep = get_dependency("foo", ">=1.0", groups=["dev"])
+ assert dep.in_extras == []
+
+ def test_returns_dependency_allowing_prereleases(self) -> None:
</code_context>
<issue_to_address>
**issue (testing):** The `test_returns_dependency_with_groups` case doesn't assert anything about the `groups` argument behavior.
Here the test passes `groups=["dev"]` but only asserts `dep.in_extras == []`, which doesn’t exercise or document the `groups` behavior. Please add an assertion on whatever attribute actually represents `groups` (e.g. `dep.groups` or the equivalent) so this test will fail if group handling regresses, rather than giving a false sense of coverage.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| class TestSetKeyringBackend: | ||
| def test_sets_keyring_backend_and_clears_cache(self) -> None: | ||
| from jaraco.classes import properties | ||
| from keyring.backend import KeyringBackend | ||
|
|
||
| class DummyBackend(KeyringBackend): | ||
| def __init__(self) -> None: | ||
| pass | ||
|
|
||
| @properties.classproperty |
There was a problem hiding this comment.
issue (testing): Test does not actually verify the cache-clearing behavior and leaves global keyring state mutated after the test.
This only checks that the global backend is set, not that PoetryKeyring’s availability cache is actually cleared and recomputed. Please also assert that PoetryKeyring.is_available() is recalculated (e.g., set a known value before set_keyring_backend and verify it changes afterward). In addition, the test mutates the process-wide keyring backend without restoring it; capture keyring.get_keyring() beforehand and restore it in a try/finally or fixture teardown to avoid cross-test interference.
| class TestTestRepository: | ||
| def test_find_packages_returns_matching_packages(self) -> None: | ||
| repo = TestRepository("test") | ||
| package = get_package("foo", "1.0.0") | ||
| repo.add_package(package) | ||
|
|
||
| dep = get_dependency("foo", ">=1.0") | ||
| result = repo.find_packages(dep) | ||
| assert len(result) == 1 | ||
| assert result[0].name == "foo" |
There was a problem hiding this comment.
suggestion (testing): Repository tests don't cover version/constraint resolution behavior when multiple packages are present.
Since TestRepository is used to simulate real resolution behavior, please add a test with multiple versions of the same package and a constrained dependency. For example, add foo-1.0.0 and foo-2.0.0 and assert that find_packages(get_dependency("foo", "<2.0")) returns only the expected version(s).
| class TestGetDependency: | ||
| def test_returns_dependency_with_wildcard_constraint(self) -> None: | ||
| dep = get_dependency("foo") | ||
| assert dep.name == "foo" | ||
| assert str(dep.constraint) == "*" | ||
|
|
||
| def test_returns_dependency_with_version_constraint(self) -> None: | ||
| dep = get_dependency("foo", ">=1.0") | ||
| assert dep.name == "foo" | ||
|
|
There was a problem hiding this comment.
issue (testing): The test_returns_dependency_with_groups case doesn't assert anything about the groups argument behavior.
Here the test passes groups=["dev"] but only asserts dep.in_extras == [], which doesn’t exercise or document the groups behavior. Please add an assertion on whatever attribute actually represents groups (e.g. dep.groups or the equivalent) so this test will fail if group handling regresses, rather than giving a false sense of coverage.
Summary
Closes #9161
Adds comprehensive test coverage for
tests/helpers.pyas requested by @Secrus in #9149 (comment).The existing
tests/test_helpers.pyhad tests for only 3 of the 15+ helper functions/classes. This PR adds tests covering all remaining helpers:get_package- package creation with version and yanked statusget_dependency- dependency creation with constraints, groups, optional, prereleasescopy_path- file and directory copying with overwrite behaviorMockDulwichRepo- path storage and mock git revisionmock_clone- fixture-based git clone simulationTestLocker- lock state management, mock data, and write persistenceTestRepository- package lookup (success and not-found) and link generationmake_entry_point_from_plugin- entry point creation with and without dist/groupmock_metadata_entry_points- metadata patching and group filteringwith_working_directory- working directory context manager with optional copyset_keyring_backend- keyring backend switching with cache clearingpbs_installer_supported_arch- architecture support detection (supported, unsupported, case-insensitive)Also adds additional edge-case tests for the previously covered helpers (
flatten_dict,isolated_environment,switch_working_directory).Total: 66 tests, all passing.
Test plan
pytest tests/test_helpers.py -v