Skip to content

Commit bc49f85

Browse files
author
Zhe Yu
committed
tests(cli): refactor tests and coverage for files rm
1 parent 63bdb23 commit bc49f85

2 files changed

Lines changed: 49 additions & 83 deletions

File tree

src/vectorcode/subcommands/files/rm.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,27 @@
22

33
from vectorcode.cli_utils import Config
44
from vectorcode.database import get_database_connector
5+
from vectorcode.database.errors import CollectionNotFoundError
56
from vectorcode.database.types import ResultType
67

78
logger = logging.getLogger(name=__name__)
89

910

1011
async def rm(configs: Config) -> int:
11-
database = get_database_connector(configs)
12-
remove_count = await database.delete()
12+
try:
13+
database = get_database_connector(configs)
14+
remove_count = await database.delete()
1315

14-
if not configs.pipe:
15-
print(f"Removed {remove_count} file(s).")
16-
if await database.count(ResultType.chunk) == 0:
17-
logger.warning(
18-
f"The collection at {configs.project_root} is now empty, and will be removed."
19-
)
20-
await database.drop()
21-
return 0
16+
if not configs.pipe:
17+
print(f"Removed {remove_count} file(s).")
18+
if await database.count(ResultType.chunk) == 0:
19+
logger.warning(
20+
f"The collection at {configs.project_root} is now empty, and will be removed."
21+
)
22+
await database.drop()
23+
return 0
24+
except CollectionNotFoundError:
25+
logger.error(f"There's no existing collection for `{configs.project_root}`.")
26+
return 1
27+
except Exception: # pragma: nocover
28+
raise

tests/subcommands/files/test_files_rm.py

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,60 @@
1+
from pathlib import Path
12
from unittest.mock import AsyncMock, patch
23

34
import pytest
4-
from chromadb.api.models.AsyncCollection import AsyncCollection
55

6-
from vectorcode.cli_utils import CliAction, Config, FilesAction
6+
from vectorcode.cli_utils import Config
7+
from vectorcode.database.errors import CollectionNotFoundError
78
from vectorcode.subcommands.files.rm import rm
89

910

1011
@pytest.fixture
11-
def client():
12-
return AsyncMock()
12+
def mock_db():
13+
db = AsyncMock()
1314

15+
def mock_delete():
16+
count = 0
17+
for f in db._configs.rm_paths:
18+
if Path(f).name in {"file1.py", "file2.py", "file3.py"}:
19+
count += 1
20+
return count
1421

15-
@pytest.fixture
16-
def collection():
17-
col = AsyncMock(spec=AsyncCollection)
18-
col.get.return_value = {
19-
"ids": ["id1", "id2", "id3"],
20-
"distances": [0.1, 0.2, 0.3],
21-
"metadatas": [
22-
{"path": "file1.py", "start": 1, "end": 1},
23-
{"path": "file2.py", "start": 1, "end": 1},
24-
{"path": "file3.py", "start": 1, "end": 1},
25-
],
26-
"documents": [
27-
"content1",
28-
"content2",
29-
"content3",
30-
],
31-
}
32-
col.name = "test_collection"
33-
return col
22+
db.delete = AsyncMock(side_effect=mock_delete)
23+
return db
3424

3525

3626
@pytest.mark.asyncio
37-
async def test_rm(client, collection, capsys):
38-
with (
39-
patch("vectorcode.subcommands.files.rm.ClientManager") as MockClientManager,
40-
patch(
41-
"vectorcode.subcommands.files.rm.get_collection", return_value=collection
42-
),
43-
patch("vectorcode.common.try_server", return_value=True),
44-
patch("os.path.isfile", return_value=True),
45-
patch(
46-
"vectorcode.subcommands.files.rm.expand_path", side_effect=lambda x, y: x
47-
),
27+
async def test_rm(mock_db, capsys):
28+
configs = Config(rm_paths=["file1.py", "file2.py"])
29+
mock_db._configs = configs
30+
with patch(
31+
"vectorcode.subcommands.files.rm.get_database_connector", return_value=mock_db
4832
):
49-
MockClientManager.return_value._create_client.return_value = client
50-
config = Config(
51-
action=CliAction.files,
52-
files_action=FilesAction.rm,
53-
rm_paths=["file1.py"],
54-
)
55-
await rm(config)
56-
collection.delete.assert_called_with(where={"path": {"$in": ["file1.py"]}})
33+
assert await rm(configs) == 0
34+
assert capsys.readouterr().out.strip() == "Removed 2 file(s)."
5735

5836

5937
@pytest.mark.asyncio
60-
async def test_rm_empty_collection(client, collection, capsys):
61-
with (
62-
patch(
63-
"vectorcode.subcommands.files.rm.get_collection", return_value=collection
64-
),
65-
patch("vectorcode.common.try_server", return_value=True),
66-
patch("os.path.isfile", return_value=True),
67-
patch(
68-
"vectorcode.subcommands.files.rm.expand_path", side_effect=lambda x, y: x
69-
),
70-
patch(
71-
"vectorcode.subcommands.files.rm.ClientManager._create_client",
72-
return_value=client,
73-
),
38+
async def test_rm_clean_after_rm(mock_db, capsys):
39+
configs = Config(rm_paths=["file1.py", "file2.py"])
40+
mock_db._configs = configs
41+
mock_db.count = AsyncMock(return_value=0)
42+
with patch(
43+
"vectorcode.subcommands.files.rm.get_database_connector", return_value=mock_db
7444
):
75-
config = Config(
76-
action=CliAction.files,
77-
files_action=FilesAction.rm,
78-
rm_paths=["file1.py"],
79-
)
80-
collection.count = AsyncMock(return_value=0)
81-
client.delete_collection = AsyncMock()
82-
await rm(config)
83-
client.delete_collection.assert_called_once_with(collection.name)
45+
assert await rm(configs) == 0
46+
mock_db.drop.assert_called_once()
8447

8548

8649
@pytest.mark.asyncio
87-
async def test_rm_no_collection(client, collection, capsys):
88-
with (
89-
patch("vectorcode.subcommands.files.rm.ClientManager") as MockClientManager,
90-
patch("vectorcode.subcommands.files.rm.get_collection", side_effect=ValueError),
50+
async def test_rm_no_collection(mock_db, capsys):
51+
with patch(
52+
"vectorcode.subcommands.files.rm.get_database_connector", return_value=mock_db
9153
):
92-
MockClientManager.return_value._create_client.return_value = client
54+
mock_db.delete.side_effect = CollectionNotFoundError
9355
assert (
9456
await rm(
9557
Config(
96-
action=CliAction.files,
97-
files_action=FilesAction.rm,
98-
pipe=True,
9958
rm_paths=["file1.py"],
10059
)
10160
)

0 commit comments

Comments
 (0)