Files
govoplan-campaign/tests/test_filename_allocator.py
2026-09-08 12:19:37 +02:00

76 lines
2.4 KiB
Python
Executable File

from pathlib import Path
import random
import unittest
from govoplan_campaign.backend.services.filenames import FilenameAllocator
from govoplan_campaign.backend.services.zip_service import _normalized_members
def legacy_names(names):
used = set()
result = []
for name in names:
path = Path(name)
candidate = name
counter = 2
while candidate.casefold() in used:
candidate = f"{path.stem} ({counter}){path.suffix}"
counter += 1
used.add(candidate.casefold())
result.append(candidate)
return result
class FilenameAllocatorTests(unittest.TestCase):
def test_exact_equivalence_with_colliding_suffixes_case_unicode_and_multiple_dots(
self,
):
choices = [
"report.pdf",
"REPORT.PDF",
"report (2).pdf",
"report (3).pdf",
"report (2) (2).pdf",
".hidden",
"a.tar.gz",
"A.TAR.GZ",
"Straße.txt",
"STRASSE.txt",
"readme",
]
rng = random.Random(42)
for _ in range(30):
names = [rng.choice(choices) for _ in range(200)]
allocator = FilenameAllocator()
self.assertEqual(
legacy_names(names), [allocator.allocate(name) for name in names]
)
def test_zip_and_message_names_preserve_every_input_and_sequence(self):
names = ["a.pdf", "A.pdf", "a (2).pdf", "a.pdf"]
paths = [Path(f"/synthetic/{index}/source") for index in range(len(names))]
members = _normalized_members(list(zip(paths, names)))
self.assertEqual(paths, [path for path, _ in members])
self.assertEqual(legacy_names(names), [name for _, name in members])
self.assertEqual("a.pdf", FilenameAllocator().allocate("a.pdf"))
def test_many_collisions_have_linear_membership_work(self):
class CountingSet(set):
probes = 0
def __contains__(self, item):
self.probes += 1
return super().__contains__(item)
allocator = FilenameAllocator()
allocator.used = CountingSet()
for _ in range(10000):
last = allocator.allocate("report.pdf")
self.assertEqual("report (10000).pdf", last)
self.assertEqual(10000, len(allocator.used))
self.assertEqual(19999, allocator.used.probes)
if __name__ == "__main__":
unittest.main()