Skip to content

Commit 370ed28

Browse files
committed
test: add unit tests for the file selection utility functions
1 parent 98f584a commit 370ed28

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

tests/unit/client/test_utils.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# This Software (Dioptra) is being made available as a public service by the
2+
# National Institute of Standards and Technology (NIST), an Agency of the United
3+
# States Department of Commerce. This software was developed in part by employees of
4+
# NIST and in part by NIST contractors. Copyright in portions of this software that
5+
# were developed by NIST contractors has been licensed or assigned to NIST. Pursuant
6+
# to Title 17 United States Code Section 105, works of NIST employees are not
7+
# subject to copyright protection in the United States. However, NIST may hold
8+
# international copyright in software created by its employees and domestic
9+
# copyright (or licensing rights) in portions of software that were assigned or
10+
# licensed to NIST. To the extent that NIST holds copyright in this software, it is
11+
# being made available under the Creative Commons Attribution 4.0 International
12+
# license (CC BY 4.0). The disclaimers of the CC BY 4.0 license apply to all parts
13+
# of the software developed or licensed by NIST.
14+
#
15+
# ACCESS THE FULL CC BY 4.0 LICENSE HERE:
16+
# https://creativecommons.org/licenses/by/4.0/legalcode
17+
import re
18+
from pathlib import Path
19+
20+
import pytest
21+
22+
from dioptra.client import select_files_in_directory, select_one_or_more_files
23+
from dioptra.client.base import DioptraFile
24+
25+
26+
@pytest.fixture
27+
def fake_directory(tmp_path: Path) -> Path:
28+
(tmp_path / "subdir").mkdir()
29+
(tmp_path / "subdir" / "subdir2").mkdir()
30+
(tmp_path / "subdir" / "file1.txt").write_text("Content of file1")
31+
(tmp_path / "subdir" / "file2.txt").write_text("Content of file2")
32+
(tmp_path / "subdir" / "subdir2" / "file1.txt").write_text("Content of file1")
33+
(tmp_path / "subdir" / "subdir2" / "file3.md").write_text("# Content of file3")
34+
(tmp_path / "file4.txt").write_text("Content of file4")
35+
return tmp_path
36+
37+
38+
@pytest.mark.parametrize(
39+
"recursive, include_pattern, expected_filenames",
40+
[
41+
(False, None, {"file4.txt"}),
42+
(
43+
True,
44+
None,
45+
{
46+
"file4.txt",
47+
"subdir/file1.txt",
48+
"subdir/file2.txt",
49+
"subdir/subdir2/file1.txt",
50+
"subdir/subdir2/file3.md",
51+
},
52+
),
53+
(True, r".*\.md", {"subdir/subdir2/file3.md"}),
54+
(True, re.compile(r".*\.md"), {"subdir/subdir2/file3.md"}),
55+
(
56+
True,
57+
r".*\.txt",
58+
{
59+
"file4.txt",
60+
"subdir/file1.txt",
61+
"subdir/file2.txt",
62+
"subdir/subdir2/file1.txt",
63+
},
64+
),
65+
],
66+
)
67+
def test_select_files_in_directory(
68+
fake_directory: Path,
69+
recursive: bool,
70+
include_pattern: str | re.Pattern | None,
71+
expected_filenames: set[str],
72+
) -> None:
73+
# Select the files from the temporary directory
74+
selected_files = select_files_in_directory(
75+
fake_directory, recursive=recursive, include_pattern=include_pattern
76+
)
77+
78+
# Extract filenames to validate their paths
79+
filenames = [dioptra_file.filename for dioptra_file in selected_files]
80+
81+
# Validate that all filenames match the expected relative POSIX paths
82+
assert set(filenames) == expected_filenames
83+
84+
# Verify DioptraFile structure
85+
for dioptra_file in selected_files:
86+
assert isinstance(dioptra_file, DioptraFile)
87+
assert dioptra_file.stream.readable()
88+
89+
90+
@pytest.mark.parametrize(
91+
"relative_file_paths, renames, expected_filenames",
92+
[
93+
(["file4.txt"], None, {"file4.txt"}),
94+
(
95+
[
96+
"file4.txt",
97+
"subdir/file1.txt",
98+
"subdir/file2.txt",
99+
"subdir/subdir2/file3.md",
100+
],
101+
None,
102+
{"file4.txt", "file1.txt", "file2.txt", "file3.md"},
103+
),
104+
(["subdir/subdir2/file3.md"], None, {"file3.md"}),
105+
(["subdir/subdir2/file3.md", "file4.txt"], None, {"file3.md", "file4.txt"}),
106+
(
107+
["file4.txt", "subdir/file1.txt", "subdir/subdir2/file1.txt"],
108+
{"subdir/subdir2/file1.txt": "file1_copy.txt"},
109+
{"file1.txt", "file4.txt", "file1_copy.txt"},
110+
),
111+
],
112+
)
113+
def test_select_one_or_more_files(
114+
fake_directory: Path,
115+
relative_file_paths: list[str],
116+
renames: dict[str | Path, str] | None,
117+
expected_filenames: set[str],
118+
) -> None:
119+
file_paths: list[str | Path] = [
120+
fake_directory / file_path for file_path in relative_file_paths
121+
]
122+
if renames is not None:
123+
renames = {
124+
str(fake_directory / relative_path): new_filename
125+
for relative_path, new_filename in renames.items()
126+
}
127+
128+
# Select the files from the temporary directory
129+
selected_files = select_one_or_more_files(file_paths, renames=renames)
130+
131+
# Extract filenames for validation
132+
filenames = [dioptra_file.filename for dioptra_file in selected_files]
133+
134+
# Validate that list of selected filenames match the expected ones after renaming
135+
assert set(filenames) == set(expected_filenames)
136+
137+
# Verify DioptraFile structure
138+
for dioptra_file in selected_files:
139+
assert isinstance(dioptra_file, DioptraFile)
140+
assert dioptra_file.stream.readable()
141+
142+
143+
def test_select_one_or_more_with_duplicate_filename_fails(
144+
fake_directory: Path,
145+
) -> None:
146+
relative_file_paths = ["file4.txt", "subdir/file1.txt", "subdir/subdir2/file1.txt"]
147+
file_paths: list[str | Path] = [
148+
fake_directory / file_path for file_path in relative_file_paths
149+
]
150+
151+
with pytest.raises(ValueError):
152+
select_one_or_more_files(file_paths)

0 commit comments

Comments
 (0)