Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions tests/unit/__snapshots__/test_lockfile_message_snapshots.ambr
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# serializer version: 1
# name: TestBumpLockfileMessages.test_message[nested]
'''
Updated version to 1.2.3 in 1 manifest(s) and 2 lockfile(s):
- Cargo.toml
- Cargo.lock (lockfile)
- tests/ui_lints/Cargo.lock (lockfile)
'''
# ---
# name: TestBumpLockfileMessages.test_message[root]
'''
Updated version to 1.2.3 in 1 manifest(s) and 1 lockfile(s):
- Cargo.toml
- Cargo.lock (lockfile)
'''
# ---
# name: TestStaleLockfileMessages.test_message[multiple]
'''
Tracked Cargo.lock files are stale after manifest version changes.
This can happen after manifest changes made without `lading bump`, or after running `lading bump --no-rebuild-lockfiles`; repair each stale lockfile directly:
- /ws/Cargo.lock
cargo generate-lockfile --manifest-path /ws/Cargo.toml
- /ws/tests/ui_lints/Cargo.lock
cargo generate-lockfile --manifest-path /ws/tests/ui_lints/Cargo.toml
'''
# ---
# name: TestStaleLockfileMessages.test_message[single]
'''
Tracked Cargo.lock files are stale after manifest version changes.
This can happen after manifest changes made without `lading bump`, or after running `lading bump --no-rebuild-lockfiles`; repair each stale lockfile directly:
- /ws/Cargo.lock
cargo generate-lockfile --manifest-path /ws/Cargo.toml
'''
# ---
12 changes: 12 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from lading.commands import bump, publish, publish_preflight
from lading.workspace import WorkspaceCrate, WorkspaceDependency, WorkspaceGraph

_ORIGINAL_PREFLIGHT = publish_preflight._run_preflight_checks

# These modules drive ``bump.run`` to exercise manifest updates, documentation
# rewriting, and the rebuild_lockfiles resolution logic -- none of which need
# Cargo to actually build or regenerate lockfiles. The stub is scoped to them by
Expand Down Expand Up @@ -73,6 +75,16 @@ def disable_publish_preflight(monkeypatch: pytest.MonkeyPatch) -> None:
)


@pytest.fixture
def enable_publish_preflight(monkeypatch: pytest.MonkeyPatch) -> None:
"""Restore publish pre-flight checks for public command integration tests."""
monkeypatch.setattr(
publish_preflight,
"_run_preflight_checks",
_ORIGINAL_PREFLIGHT,
)


@pytest.fixture(autouse=True)
def stub_lockfile_regeneration(
request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch
Expand Down
150 changes: 150 additions & 0 deletions tests/unit/test_lockfile_message_snapshots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"""Snapshot tests for lockfile-related CLI output (issue #81).

PR #75 introduced two text outputs that were previously verified only by
substring matching: the ``(lockfile)`` suffix in ``lading bump`` result
messages and the multi-line stale-lockfile error raised by
``lading publish``. These snapshots exercise the public command entry points
and lock in the exact formats.
"""

from __future__ import annotations

import collections.abc as cabc
import typing as typ
from pathlib import Path

import pytest

from lading import config
from lading.commands import bump, lockfile, publish
from lading.workspace import WorkspaceGraph

if typ.TYPE_CHECKING:
from syrupy.assertion import SnapshotAssertion

_SNAPSHOT_WORKSPACE_ROOT = Path("/ws")


class TestBumpLockfileMessages:
"""Snapshot bump messages for root and nested lockfiles."""

@pytest.mark.parametrize(
"lockfile_paths",
[
pytest.param(
(Path("Cargo.lock"),),
id="root",
),
pytest.param(
(
Path("Cargo.lock"),
Path("tests/ui_lints/Cargo.lock"),
),
id="nested",
),
],
)
def test_message(
self,
monkeypatch: pytest.MonkeyPatch,
snapshot: SnapshotAssertion,
tmp_path: Path,
lockfile_paths: tuple[Path, ...],
) -> None:
"""The public bump command renders lockfiles relative to the workspace."""
(tmp_path / "Cargo.toml").write_text(
'[workspace]\nmembers = []\n\n[workspace.package]\nversion = "0.1.0"\n',
encoding="utf-8",
)
workspace = WorkspaceGraph(workspace_root=tmp_path, crates=())

def fake_regenerate_lockfiles(
workspace_root: Path,
lockfile_manifests: tuple[str, ...],
*,
runner: object | None = None,
) -> tuple[Path, ...]:
del lockfile_manifests, runner
return tuple(workspace_root / path for path in lockfile_paths)

monkeypatch.setattr(
bump.bump_lockfiles,
"regenerate_lockfiles",
fake_regenerate_lockfiles,
)

message = bump.run(
tmp_path,
"1.2.3",
options=bump.BumpOptions(
rebuild_lockfiles=True,
configuration=config.LadingConfig(),
workspace=workspace,
),
)

assert snapshot == message


@pytest.mark.usefixtures("enable_publish_preflight")
class TestStaleLockfileMessages:
"""Snapshot stale-lockfile errors for one and multiple lockfiles."""

@pytest.mark.parametrize(
"lockfiles",
[
pytest.param(
[_SNAPSHOT_WORKSPACE_ROOT / "Cargo.lock"],
id="single",
),
pytest.param(
[
_SNAPSHOT_WORKSPACE_ROOT / "Cargo.lock",
_SNAPSHOT_WORKSPACE_ROOT / "tests" / "ui_lints" / "Cargo.lock",
],
id="multiple",
),
],
)
def test_message(
self,
monkeypatch: pytest.MonkeyPatch,
snapshot: SnapshotAssertion,
tmp_path: Path,
lockfiles: list[Path],
) -> None:
"""The public publish command reports every stale lockfile repair."""
monkeypatch.setattr(
lockfile.CargoLockfileInspectionRepository,
"discover_tracked_lockfiles",
lambda _repository, _root: tuple(lockfiles),
)
monkeypatch.setattr(
lockfile.CargoLockfileInspectionRepository,
"validate_lockfile_freshness",
lambda _repository, _manifest: lockfile.LockfileFreshness(
is_fresh=False,
is_stale=True,
detail="the lock file needs to be updated",
),
)

def runner(
command: cabc.Sequence[str],
*,
cwd: Path | None = None,
env: cabc.Mapping[str, str] | None = None,
) -> tuple[int, str, str]:
del command, cwd, env
return 0, "", ""

workspace = WorkspaceGraph(workspace_root=tmp_path, crates=())
with pytest.raises(publish.PublishPreflightError) as excinfo:
publish.run(
tmp_path,
config.LadingConfig(),
workspace,
options=publish.PublishOptions(command_runner=runner),
)

assert snapshot == str(excinfo.value)
Loading