|
1 | 1 | #!/usr/bin/env python3
|
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +# pwexplode.py - implementation of the PKWARE Data Compression Library |
| 5 | +# format (imploding) for byte streams |
| 6 | +# Copyright (C) 2021 by Sven Kochmann |
| 7 | + |
| 8 | +# This program is free software: you can redistribute it and/or modify |
| 9 | +# it under the terms of the GNU General Public License as published by |
| 10 | +# the Free Software Foundation, either version 3 of the License, or |
| 11 | +# (at your option) any later version. |
| 12 | + |
| 13 | +# This program is distributed in the hope that it will be useful, |
| 14 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | +# GNU General Public License for more details. |
| 17 | + |
| 18 | +# You should have received a copy of the GNU General Public License |
| 19 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | + |
| 21 | +# This script implements the test suite based on the testdata |
| 22 | +# collection prepared by KOLANICH, see: |
| 23 | +# https://github.com/implode-compression-impls/implode_test_files |
| 24 | + |
| 25 | +import json |
| 26 | +from pathlib import Path |
2 | 27 | import sys
|
3 | 28 | import unittest
|
4 |
| -from collections import OrderedDict |
5 |
| -from pathlib import Path |
6 | 29 |
|
7 |
| -from fileTestSuite.unittest import FileTestSuiteTestCaseMixin |
| 30 | +# Remove tracebacks unless "traceback" is given in script arguments. |
| 31 | +# Need to make sure that "traceback" gets removed from arguments since |
| 32 | +# unittest is parsing it. |
| 33 | +if not "traceback" in sys.argv: |
| 34 | + __unittest = True |
| 35 | +else: |
| 36 | + sys.argv.remove("traceback") |
| 37 | + |
| 38 | +# Small hack to make sure that the main module (pwexplode) can be |
| 39 | +# imported despite the fact that it is in the parent directory |
| 40 | +parentDir = Path(__file__).resolve().absolute().parent.parent |
| 41 | +sys.path.insert(0, str(parentDir)) |
| 42 | +import pwexplode |
| 43 | + |
| 44 | +# In the following we want to generate ONE test case per file |
| 45 | +# comparison. I found subtests not fully suitable (weird counting, |
| 46 | +# etc.). |
| 47 | + |
| 48 | +# Generate a list with the pairs of files (incl. relative path). This |
| 49 | +# is according to the fileTestSuite specs (since the data set uses it) |
| 50 | +# and can be found at: https://github.com/fileTestSuite/fileTestSuite |
| 51 | +subpath = "testDataset/" |
| 52 | +p = Path(subpath) |
| 53 | + |
| 54 | +list_files = [] |
| 55 | + |
| 56 | +def removeMetaFiles(filelist): |
| 57 | + return [file for file in filelist if not file.name in ["License.md", "meta.ftsmeta", "meta.json", "ReadMe.txt", "ReadMe.md"]] |
| 58 | + |
| 59 | +for file in p.rglob("*"): |
| 60 | + if file.is_dir(): |
| 61 | + meta = list(file.glob("meta.json")) |
| 62 | + |
| 63 | + if len(meta) == 1: |
| 64 | + metadata = json.load(meta[0].open()) |
| 65 | + print("Parsing", file.name + "/" + meta[0].name, "...") |
| 66 | + |
| 67 | + # Since sorted, same indices should point to the same |
| 68 | + # pair of files |
| 69 | + rawFiles = removeMetaFiles(sorted(list(file.glob("*" + metadata["rawExt"])))) |
| 70 | + decFiles = removeMetaFiles(sorted(list(file.glob("*" + metadata["processedExt"])))) |
| 71 | + |
| 72 | + # Hack: remove dec files from raw files (there is the case of no extension given |
| 73 | + # for rawExt of the unshield-dataset. Not optimal. (Also in this case the original |
| 74 | + # dataset has processedExt and rawExt exchanged; as of 2021-07-22) |
| 75 | + rawFiles = [file for file in rawFiles if not file in decFiles] |
8 | 76 |
|
9 |
| -dict = OrderedDict |
| 77 | + if len(rawFiles) == len(decFiles): |
| 78 | + for i in range(len(rawFiles)): |
| 79 | + basename = rawFiles[i].name[:len(rawFiles[i].name) - len(metadata["rawExt"])] |
| 80 | + list_files.append({"basename": basename, "imploded": str(decFiles[i]), "exploded": str(rawFiles[i])}) |
| 81 | + print("\tAdded %s[%s, %s]." |
| 82 | + % (basename, metadata["rawExt"], metadata["processedExt"])) |
| 83 | + else: |
| 84 | + print("There are %d raw files but %d decoded files. That does not fit." |
| 85 | + % (len(rawFiles), len(decFiles))) |
10 | 86 |
|
11 |
| -thisDir = Path(__file__).resolve().absolute().parent |
12 |
| -repoRootDir = thisDir.parent |
| 87 | +print("") |
13 | 88 |
|
14 |
| -sys.path.insert(0, str(repoRootDir)) |
| 89 | +# Define a basic test case class and comparison function (will act as "test..." method) |
| 90 | +class TestSuperCase(unittest.TestCase): |
| 91 | + pass |
15 | 92 |
|
16 |
| -from pwexplode import explode |
| 93 | +def test_generator(imploded, exploded): |
| 94 | + def test(self): |
| 95 | + imploded_data = b"" |
| 96 | + exploded_data = b"" |
17 | 97 |
|
| 98 | + with open(imploded, "rb") as f: |
| 99 | + imploded_data = f.read() |
18 | 100 |
|
19 |
| -class Tests(unittest.TestCase, FileTestSuiteTestCaseMixin): |
20 |
| - @property |
21 |
| - def fileTestSuiteDir(self) -> Path: |
22 |
| - return thisDir / "testDataset" |
| 101 | + with open(exploded, "rb") as f: |
| 102 | + exploded_data = f.read() |
23 | 103 |
|
24 |
| - def _testProcessorImpl(self, challFile: Path, respFile: Path, paramsDict=None) -> None: |
25 |
| - self.assertEqual(challFile.read_bytes(), explode(respFile.read_bytes())) |
| 104 | + self.assertEqual(pwexplode.explode(imploded_data), exploded_data) |
| 105 | + return test |
26 | 106 |
|
| 107 | +# Generate the Testcases and add a method each for each entry of the list |
| 108 | +for filepair in list_files: |
| 109 | + test_name = 'test_%s' % filepair["imploded"] |
| 110 | + test = test_generator(filepair["imploded"], filepair["exploded"]) |
| 111 | + setattr(TestSuperCase, test_name, test) |
27 | 112 |
|
28 | 113 | if __name__ == "__main__":
|
29 |
| - unittest.main() |
| 114 | + unittest.main(verbosity=2) |
0 commit comments