|
| 1 | +from pathlib import Path |
1 | 2 | from unittest.mock import AsyncMock, patch |
2 | 3 |
|
3 | 4 | import pytest |
4 | | -from chromadb.api.models.AsyncCollection import AsyncCollection |
5 | 5 |
|
6 | | -from vectorcode.cli_utils import CliAction, Config, FilesAction |
| 6 | +from vectorcode.cli_utils import Config |
| 7 | +from vectorcode.database.errors import CollectionNotFoundError |
7 | 8 | from vectorcode.subcommands.files.rm import rm |
8 | 9 |
|
9 | 10 |
|
10 | 11 | @pytest.fixture |
11 | | -def client(): |
12 | | - return AsyncMock() |
| 12 | +def mock_db(): |
| 13 | + db = AsyncMock() |
13 | 14 |
|
| 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 |
14 | 21 |
|
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 |
34 | 24 |
|
35 | 25 |
|
36 | 26 | @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 |
48 | 32 | ): |
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)." |
57 | 35 |
|
58 | 36 |
|
59 | 37 | @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 |
74 | 44 | ): |
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() |
84 | 47 |
|
85 | 48 |
|
86 | 49 | @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 |
91 | 53 | ): |
92 | | - MockClientManager.return_value._create_client.return_value = client |
| 54 | + mock_db.delete.side_effect = CollectionNotFoundError |
93 | 55 | assert ( |
94 | 56 | await rm( |
95 | 57 | Config( |
96 | | - action=CliAction.files, |
97 | | - files_action=FilesAction.rm, |
98 | | - pipe=True, |
99 | 58 | rm_paths=["file1.py"], |
100 | 59 | ) |
101 | 60 | ) |
|
0 commit comments