"""压缩算法分发层的直接单测。 `compression.py` 是"用哪种算法"的唯一分发点(core 只按 `compress_algo` 值分发, 不关心具体算法)。这里锁住它的契约,这样以后往 `ALGORITHMS` 里加算法 (包括自定义算法、或未来的加密层)时,有东西能兜住回归。 分层关系:`huffman.py` 只管纯算法(有自己的 test_huffman.py), `compression.py` 管分发与算法名到数据的映射,`core.py` 管存取。 """ import unittest import zlib import helpers # noqa: F401 -- 把 src 加入 sys.path from sqlite_vfs import compression from sqlite_vfs.huffman import FREQ_SIZE class AlgorithmRegistryTest(unittest.TestCase): def test_default_algorithm_is_zlib(self): self.assertEqual("zlib", compression.DEFAULT_ALGORITHM) def test_registry_contains_the_three_builtins(self): self.assertEqual(("none", "zlib", "huffman"), compression.ALGORITHMS) def test_every_registered_algorithm_roundtrips(self): data = b"the quick brown fox jumps over the lazy dog. " * 60 for algorithm in compression.ALGORITHMS: with self.subTest(algorithm=algorithm): algo, freq, blob = compression.compress_with(data, algorithm) self.assertEqual(algorithm, algo) self.assertEqual(data, compression.decompress_with(algo, freq, blob)) def test_unknown_algorithm_is_rejected_on_both_sides(self): with self.assertRaises(ValueError) as ctx: compression.compress_with(b"x", "lzma") self.assertIn("lzma", str(ctx.exception)) self.assertIn("none", str(ctx.exception), "报错要列出可用算法") with self.assertRaises(ValueError): compression.decompress_with("lzma", None, b"x") class CompressContractTest(unittest.TestCase): DATA = b"payload " * 100 def test_none_returns_the_input_unchanged(self): algo, freq, blob = compression.compress_with(self.DATA, "none") self.assertEqual("none", algo) self.assertIsNone(freq) self.assertIs(self.DATA, blob, "none 应当零拷贝直接返回原对象") def test_zlib_produces_a_real_zlib_stream(self): algo, freq, blob = compression.compress_with(self.DATA, "zlib") self.assertIsNone(freq, "zlib 不需要附加数据") self.assertEqual(self.DATA, zlib.decompress(blob)) self.assertLess(len(blob), len(self.DATA)) def test_huffman_carries_a_fixed_size_frequency_table(self): algo, freq, blob = compression.compress_with(self.DATA, "huffman") self.assertEqual("huffman", algo) self.assertEqual(FREQ_SIZE, len(freq), "频率表固定 1024 字节") self.assertEqual(self.DATA, compression.decompress_with(algo, freq, blob)) def test_huffman_without_frequency_table_is_rejected(self): algo, _freq, blob = compression.compress_with(self.DATA, "huffman") with self.assertRaises(ValueError) as ctx: compression.decompress_with(algo, None, blob) self.assertIn("频率表", str(ctx.exception)) def test_stored_size_counts_the_frequency_table(self): _algo, freq, blob = compression.compress_with(self.DATA, "huffman") self.assertEqual( len(blob) + len(freq), compression.stored_size(blob, freq) ) self.assertEqual(len(blob), compression.stored_size(blob, None)) def test_stored_size_ignores_an_empty_frequency_table(self): self.assertEqual(3, compression.stored_size(b"abc", b"")) class AlgorithmTradeoffTest(unittest.TestCase): """把实测出来的取舍钉在测试里:默认算法不能悄悄退化成更差的那个。""" #: 高度重复的文本——LZ77 的强项,纯熵编码的弱项 REPETITIVE = b"function render(el){return el.innerHTML}\n" * 800 def test_zlib_beats_huffman_by_a_lot_on_repetitive_text(self): _a1, f1, z = compression.compress_with(self.REPETITIVE, "zlib") _a2, f2, h = compression.compress_with(self.REPETITIVE, "huffman") zlib_total = compression.stored_size(z, f1) huffman_total = compression.stored_size(h, f2) self.assertLess( zlib_total * 10, huffman_total, f"zlib={zlib_total} huffman={huffman_total}——差距应当在一个数量级上", ) def test_huffman_is_not_used_for_small_files(self): """huffman 每个文件要带 1024 字节频率表,小文件必然负收益。""" small = b"tiny content" _algo, freq, blob = compression.compress_with(small, "huffman") self.assertGreater( compression.stored_size(blob, freq), len(small), "小文件压完更大——这正是 core 用 COMPRESS_MIN_SIZE 挡住它的原因", ) if __name__ == "__main__": unittest.main()