From 58cb969aaab2e04ae680e45542da4a4b827d2f4e Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Tue, 8 Sep 2026 22:37:10 +0200 Subject: [PATCH] lib.TarIo: Add unit tests TarIo._match() and _filter_tar_file() are pure logic without test coverage. Add unit tests for the exact path matching, the unfiltered round trip, filtered extraction with a matched list, and a filter without hits. Signed-off-by: Jan Lindemann Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1 --- test/unit/python/jw/pkg/lib/TarIo/Makefile | 7 +++ test/unit/python/jw/pkg/lib/TarIo/test.py | 53 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/unit/python/jw/pkg/lib/TarIo/Makefile create mode 100644 test/unit/python/jw/pkg/lib/TarIo/test.py diff --git a/test/unit/python/jw/pkg/lib/TarIo/Makefile b/test/unit/python/jw/pkg/lib/TarIo/Makefile new file mode 100644 index 00000000..de693650 --- /dev/null +++ b/test/unit/python/jw/pkg/lib/TarIo/Makefile @@ -0,0 +1,7 @@ +TOPDIR = ../../../../../../.. + +include $(TOPDIR)/make/proj.mk +include $(JWBDIR)/make/py-run.mk + +all: +test: run diff --git a/test/unit/python/jw/pkg/lib/TarIo/test.py b/test/unit/python/jw/pkg/lib/TarIo/test.py new file mode 100644 index 00000000..56db44df --- /dev/null +++ b/test/unit/python/jw/pkg/lib/TarIo/test.py @@ -0,0 +1,53 @@ +import io +import tarfile + +from jw.pkg.lib.TarIo import TarIoTarFile + +def make_tar(files: dict[str, bytes]) -> bytes: + buf = io.BytesIO() + with tarfile.open(fileobj = buf, mode = 'w') as tf: + for name, content in files.items(): + info = tarfile.TarInfo(name) + info.size = len(content) + tf.addfile(info, io.BytesIO(content)) + return buf.getvalue() + +def members(blob: bytes) -> dict[str, bytes | None]: + ret = {} + with tarfile.open(fileobj = io.BytesIO(blob)) as tf: + for info in tf.getmembers(): + f = tf.extractfile(info) + ret[info.name] = f.read() if f is not None else None + return ret + +# -- Bypass the constructor: _filter_tar_file() and _match() do not use +# the copy contexts, so a bare instance is sufficient +tar = object.__new__(TarIoTarFile) + +files = { + 'a.txt': b'AAA', + 'dir/b.txt': b'BBB', + 'c.txt': b'CCC', +} +blob = make_tar(files) + +# -- _match is exact matching +assert tar._match('a.txt', ['a.txt', 'c.txt']) +assert not tar._match('a.txt', ['x.txt']) +assert not tar._match('a.txt', []) + +# -- _filter_tar_file without a filter is a round trip +ret = tar._filter_tar_file(blob) +assert members(ret) == files + +# -- With a filter, only the exact paths survive +matched: list[str] = [] +ret = tar._filter_tar_file(blob, ['a.txt', 'c.txt'], matched = matched) +assert members(ret) == {'a.txt': b'AAA', 'c.txt': b'CCC'} +assert sorted(matched) == ['a.txt', 'c.txt'] + +# -- A filter without hits yields an empty tar +ret = tar._filter_tar_file(blob, ['nope.txt']) +assert members(ret) == {} + +print('All TarIo tests passed')