Skip to content

Commit 5060613

Browse files
committed
tests(async_svn): Add AsyncSvn command tests
why: Verify async SVN command operations what: - Add TestAsyncSvn for init, repr, run tests - Add TestAsyncSvnCheckout for checkout operations - Add TestAsyncSvnUpdate and TestAsyncSvnInfo tests
1 parent 330e62b commit 5060613

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

tests/cmd/_async/test_svn.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"""Tests for libvcs.cmd._async.svn."""
2+
3+
from __future__ import annotations
4+
5+
import shutil
6+
import typing as t
7+
from pathlib import Path
8+
9+
import pytest
10+
11+
from libvcs.cmd._async.svn import AsyncSvn
12+
from libvcs.pytest_plugin import CreateRepoPytestFixtureFn
13+
14+
if not shutil.which("svn"):
15+
pytestmark = pytest.mark.skip(reason="svn is not available")
16+
17+
18+
class RunFixture(t.NamedTuple):
19+
"""Test fixture for AsyncSvn.run()."""
20+
21+
test_id: str
22+
args: list[str]
23+
kwargs: dict[str, t.Any]
24+
expected_in_output: str | None
25+
26+
27+
RUN_FIXTURES = [
28+
RunFixture(
29+
test_id="version",
30+
args=["--version"],
31+
kwargs={},
32+
expected_in_output="svn",
33+
),
34+
RunFixture(
35+
test_id="help_short",
36+
args=["help"],
37+
kwargs={},
38+
expected_in_output="usage",
39+
),
40+
]
41+
42+
43+
class TestAsyncSvn:
44+
"""Tests for AsyncSvn class."""
45+
46+
def test_init(self, tmp_path: Path) -> None:
47+
"""Test AsyncSvn initialization."""
48+
svn = AsyncSvn(path=tmp_path)
49+
assert svn.path == tmp_path
50+
assert svn.progress_callback is None
51+
52+
def test_repr(self, tmp_path: Path) -> None:
53+
"""Test AsyncSvn repr."""
54+
svn = AsyncSvn(path=tmp_path)
55+
assert "AsyncSvn" in repr(svn)
56+
assert str(tmp_path) in repr(svn)
57+
58+
@pytest.mark.parametrize(
59+
list(RunFixture._fields),
60+
RUN_FIXTURES,
61+
ids=[f.test_id for f in RUN_FIXTURES],
62+
)
63+
@pytest.mark.asyncio
64+
async def test_run(
65+
self,
66+
test_id: str,
67+
args: list[str],
68+
kwargs: dict[str, t.Any],
69+
expected_in_output: str | None,
70+
tmp_path: Path,
71+
) -> None:
72+
"""Test AsyncSvn.run() with various commands."""
73+
svn = AsyncSvn(path=tmp_path)
74+
output = await svn.run(args, **kwargs)
75+
if expected_in_output is not None:
76+
assert expected_in_output in output.lower()
77+
78+
79+
class TestAsyncSvnCheckout:
80+
"""Tests for AsyncSvn.checkout()."""
81+
82+
@pytest.mark.asyncio
83+
async def test_checkout_basic(
84+
self,
85+
tmp_path: Path,
86+
create_svn_remote_repo: CreateRepoPytestFixtureFn,
87+
) -> None:
88+
"""Test basic checkout operation."""
89+
remote_repo = create_svn_remote_repo()
90+
repo_path = tmp_path / "checked_out_repo"
91+
92+
svn = AsyncSvn(path=repo_path)
93+
await svn.checkout(url=f"file://{remote_repo}")
94+
95+
assert repo_path.exists()
96+
assert (repo_path / ".svn").exists()
97+
98+
@pytest.mark.asyncio
99+
async def test_checkout_quiet(
100+
self,
101+
tmp_path: Path,
102+
create_svn_remote_repo: CreateRepoPytestFixtureFn,
103+
) -> None:
104+
"""Test checkout with quiet flag."""
105+
remote_repo = create_svn_remote_repo()
106+
repo_path = tmp_path / "quiet_repo"
107+
108+
svn = AsyncSvn(path=repo_path)
109+
await svn.checkout(url=f"file://{remote_repo}", quiet=True)
110+
111+
assert repo_path.exists()
112+
113+
114+
class TestAsyncSvnUpdate:
115+
"""Tests for AsyncSvn.update()."""
116+
117+
@pytest.mark.asyncio
118+
async def test_update_basic(
119+
self,
120+
tmp_path: Path,
121+
create_svn_remote_repo: CreateRepoPytestFixtureFn,
122+
) -> None:
123+
"""Test basic update operation."""
124+
remote_repo = create_svn_remote_repo()
125+
repo_path = tmp_path / "update_repo"
126+
127+
svn = AsyncSvn(path=repo_path)
128+
await svn.checkout(url=f"file://{remote_repo}")
129+
output = await svn.update()
130+
131+
assert "revision" in output.lower() or "at revision" in output.lower()
132+
133+
134+
class TestAsyncSvnInfo:
135+
"""Tests for AsyncSvn.info()."""
136+
137+
@pytest.mark.asyncio
138+
async def test_info_basic(
139+
self,
140+
tmp_path: Path,
141+
create_svn_remote_repo: CreateRepoPytestFixtureFn,
142+
) -> None:
143+
"""Test basic info operation."""
144+
remote_repo = create_svn_remote_repo()
145+
repo_path = tmp_path / "info_repo"
146+
147+
svn = AsyncSvn(path=repo_path)
148+
await svn.checkout(url=f"file://{remote_repo}")
149+
output = await svn.info()
150+
151+
assert "URL:" in output or "url" in output.lower()
152+
153+
@pytest.mark.asyncio
154+
async def test_info_xml(
155+
self,
156+
tmp_path: Path,
157+
create_svn_remote_repo: CreateRepoPytestFixtureFn,
158+
) -> None:
159+
"""Test info with XML output."""
160+
remote_repo = create_svn_remote_repo()
161+
repo_path = tmp_path / "info_xml_repo"
162+
163+
svn = AsyncSvn(path=repo_path)
164+
await svn.checkout(url=f"file://{remote_repo}")
165+
output = await svn.info(xml=True)
166+
167+
assert "<?xml" in output
168+
assert "<info>" in output

0 commit comments

Comments
 (0)