Skip to content

test: add test coverage for tests/helpers.py#10844

Open
yosofbadr wants to merge 5 commits intopython-poetry:mainfrom
yosofbadr:test/helpers-coverage
Open

test: add test coverage for tests/helpers.py#10844
yosofbadr wants to merge 5 commits intopython-poetry:mainfrom
yosofbadr:test/helpers-coverage

Conversation

@yosofbadr
Copy link
Copy Markdown

@yosofbadr yosofbadr commented Apr 15, 2026

Summary

Closes #9161

Adds comprehensive test coverage for tests/helpers.py as requested by @Secrus in #9149 (comment).

The existing tests/test_helpers.py had 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 status
  • get_dependency - dependency creation with constraints, groups, optional, prereleases
  • 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, mock data, and write persistence
  • TestRepository - package lookup (success and not-found) and link generation
  • make_entry_point_from_plugin - entry point creation with and without dist/group
  • mock_metadata_entry_points - metadata patching and group filtering
  • with_working_directory - working directory context manager with optional copy
  • set_keyring_backend - keyring backend switching with cache clearing
  • pbs_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

  • All 66 tests pass locally with pytest tests/test_helpers.py -v
  • CI passes on all supported platforms

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
@yosofbadr yosofbadr marked this pull request as ready for review April 15, 2026 20:21
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tests/test_helpers.py
Comment on lines +478 to +487
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread tests/test_helpers.py
Comment on lines +260 to +269
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"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Comment thread tests/test_helpers.py
Comment on lines +65 to +74
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"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add test coverage for tests/helpers.py

1 participant