public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/javatoolkit:master commit in: /, src/test/
@ 2025-03-08 11:32 Arthur Zamarin
  0 siblings, 0 replies; only message in thread
From: Arthur Zamarin @ 2025-03-08 11:32 UTC (permalink / raw
  To: gentoo-commits

commit:     a1de19b1ec5097d260ec6dbaef1cc11380a7f95f
Author:     Andrei Horodniceanu <a.horodniceanu <AT> proton <DOT> me>
AuthorDate: Wed Feb 19 16:45:26 2025 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Sat Mar  8 11:31:58 2025 +0000
URL:        https://gitweb.gentoo.org/proj/javatoolkit.git/commit/?id=a1de19b1

cvv.py: Add tests

Signed-off-by: Andrei Horodniceanu <a.horodniceanu <AT> proton.me>
Approved-by: Volkmar W. Pogatzki <gentoo <AT> pogatzki.net>
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 NEWS                 |   1 +
 README.md            |   7 ++
 src/test/__init__.py |   0
 src/test/test_cvv.py | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 224 insertions(+)

diff --git a/NEWS b/NEWS
index 1c21ec8..80aeaaf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,5 @@
 0.6.8 (???)
+- Add tests
 - Support Multi-Release jars, bug #900767
 - Migrate build-system to flit with pyproject.toml
 

diff --git a/README.md b/README.md
index 6c0a40d..ae2119b 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,10 @@ MOTIVATION
 
 This is Javatoolkit, Gentoolkit's Indonesian cousin. It contains a collection of
 handy scripts for ebuild writers and advanced Java users on Gentoo.
+
+# Tests
+
+To run the tests, in the top-level directory of this repository run:
+```sh
+python -m unittest discover -t src -s test
+```

diff --git a/src/test/__init__.py b/src/test/__init__.py
new file mode 100644
index 0000000..e69de29

diff --git a/src/test/test_cvv.py b/src/test/test_cvv.py
new file mode 100644
index 0000000..616cb8c
--- /dev/null
+++ b/src/test/test_cvv.py
@@ -0,0 +1,216 @@
+from unittest import TestCase
+import io
+import javatoolkit.cvv as cvv
+from zipfile import ZipFile
+import struct
+import typing as T
+
+
+def create_class_header(version: int) -> bytes:
+    magic = b'\xca\xfe\xba\xbe'
+    minor = 0
+    major = version + 44
+    return magic + struct.pack('>2H', minor, major)
+
+
+def create_class_file(version: int) -> io.BytesIO:
+    return io.BytesIO(create_class_header(version))
+
+
+def create_jar(files: list[tuple[str, int]], multi_release: bool = False) -> ZipFile:
+    result = ZipFile(io.BytesIO(), 'w')
+    for (path, version) in files:
+        result.writestr(path, create_class_header(version))
+    manifest = f'''Manifest-Version: 1.0
+Created-By: 21.0.6 (javatoolkit mock)
+Multi-Release: {'true' if multi_release else 'false'}
+'''
+    result.writestr('META-INF/MANIFEST.MF', manifest)
+    return result
+
+
+AnyFileInfo = T.TypeVar('AnyFileInfo',
+                        bound=cvv.BadFile | cvv.GoodFile | cvv.SkippedFile)
+
+
+def my_sort(lst: list[AnyFileInfo]) -> list[AnyFileInfo]:
+    if len(lst) == 0:
+        return lst
+
+    def key_extractor(v: AnyFileInfo) -> tuple[str, str]:
+        match v.loc:
+            case cvv.JarLoc(cvv.FileLoc(path), member):
+                return (path, member)
+            case cvv.FileLoc(path):
+                return (path, '')
+
+    return sorted(lst, key=key_extractor)
+
+
+class SimpleTest(TestCase):
+    def test_class(self) -> None:
+        m = cvv.CVVMagic('8')
+        m.do_class(create_class_file(7), cvv.FileLoc('7.class'))
+        m.do_class(create_class_file(8), cvv.FileLoc('8.class'))
+        m.do_class(create_class_file(9), cvv.FileLoc('9.class'))
+
+        def make_class(path: str, encoded_version: str) -> cvv.ClassFile:
+            return cvv.ClassFile(
+                encoded_version=encoded_version,
+                expected_version='1.8',
+                loc=cvv.FileLoc(path)
+            )
+
+        self.assertListEqual(my_sort(m.good), [
+            make_class('7.class', '1.7'),
+            make_class('8.class', '1.8'),
+        ])
+        self.assertListEqual(my_sort(m.bad), [
+            make_class('9.class', '9')
+        ])
+        self.assertListEqual(m.skipped, [])
+
+    def test_jar(self) -> None:
+        m = cvv.CVVMagic('1.8')
+        m.do_jar(jar_path=cvv.FileLoc('a.jar'), jar=create_jar([
+            ('Main.class', 8),
+            ('module-info.class', 9),
+            ('my/deep/module/Foo.class', 10),
+        ]))
+
+        def jar_loc(path: str) -> cvv.JarLoc:
+            return cvv.JarLoc(cvv.FileLoc('a.jar'), path)
+
+        def make_class(path: str, encoded_version: str) -> cvv.ClassFile:
+            return cvv.ClassFile(
+                encoded_version=encoded_version,
+                expected_version='1.8',
+                loc=jar_loc(path)
+            )
+
+        def make_skip(path: str, ver: str) -> cvv.SkippedModuleInfo:
+            return cvv.SkippedModuleInfo(jar_loc(path), ver, '1.8')
+
+        self.assertListEqual(my_sort(m.good), [
+            make_class('Main.class', '1.8'),
+        ])
+        self.assertListEqual(my_sort(m.bad), [
+            make_class('my/deep/module/Foo.class', '10'),
+        ])
+        self.assertListEqual(my_sort(m.skipped), [
+            make_skip('module-info.class', '9'),
+        ])
+
+    def test_multirelease_jar(self) -> None:
+        m = cvv.CVVMagic('9')
+        m.do_jar(jar_path=cvv.FileLoc('a.jar'), jar=create_jar(multi_release=True, files=[
+            ('module-info.class', 9),
+            ('File1.class', 9),
+            ('File2.class', 8),
+            ('META-INF/versions/10/module-info.class', 10),
+            ('META-INF/versions/10/File1.class', 11),
+            ('META-INF/versions/10/File2.class', 10),
+            ('META-INF/versions/14/module-info.class', 15),
+            ('META-INF/versions/14/File1.class', 13),
+        ]))
+
+        def make_class(path: str, encoded_version: str, expected_version: T.Optional[str] = None) -> cvv.ClassFile:
+            return cvv.ClassFile(
+                encoded_version=encoded_version,
+                expected_version=expected_version or '9',
+                loc=cvv.JarLoc(cvv.FileLoc('a.jar'), path),
+            )
+
+        self.assertListEqual(my_sort(m.good), [
+            make_class('File1.class', '9'),
+            make_class('File2.class', '1.8'),
+            make_class('META-INF/versions/10/File2.class', '10', '10'),
+            make_class('META-INF/versions/10/module-info.class', '10', '10'),
+            make_class('META-INF/versions/14/File1.class', '13', '14'),
+            make_class('module-info.class', '9'),
+        ])
+        self.assertListEqual(my_sort(m.bad), [
+            make_class('META-INF/versions/10/File1.class', '11', '10'),
+            make_class('META-INF/versions/14/module-info.class', '15', '14'),
+        ])
+        self.assertListEqual(m.skipped, [])
+
+    def test_multirelease_invalid_ver(self) -> None:
+        m = cvv.CVVMagic('10')
+        m.do_jar(jar_path=cvv.FileLoc('b.jar'), jar=create_jar(multi_release=True, files=[
+            ('Class.class', 10),
+            ('META-INF/versions/8/Class.class', 8),
+            ('META-INF/versions/hamburger/Class.class', 9874),
+        ]))
+
+        def jar_member(path: str) -> cvv.JarLoc:
+            return cvv.JarLoc(cvv.FileLoc('b.jar'), path)
+
+        def make_class(path: str, ver: str, expected: str) -> cvv.ClassFile:
+            return cvv.ClassFile(jar_member(path), encoded_version=ver, expected_version=expected)
+
+        self.assertListEqual(my_sort(m.good), [
+            make_class('Class.class', '10', '10'),
+        ])
+        self.assertListEqual(my_sort(m.bad), [])
+        self.assertListEqual(my_sort(m.skipped), [
+            cvv.SkippedVersionDir(
+                jar_member('META-INF/versions/8'),
+                'The version directory "8" is less than 9'),
+            cvv.SkippedVersionDir(
+                jar_member('META-INF/versions/hamburger'),
+                'The version directory "hamburger" is not a number'),
+        ])
+
+    def test_multirelease_no_manifest(self) -> None:
+        m = cvv.CVVMagic('8')
+        jar = cvv.FileLoc('a.jar')
+        m.do_jar(create_jar(multi_release=False, files=[
+            ('module/App.class', 8),
+            ('module/Class.class', 8),
+            ('META-INF/versions/9/module/App.class', 9),
+            ('META-INF/versions/9/module/Class.class', 9),
+            ('META-INF/versions/10/module/App.class', 10),
+            ('META-INF/versions/10/module/Class.class', 10),
+            # These 2 should be skipped, not reported as errors
+            ('META-INF/versions/7/module/App.class', 7),
+            ('META-INF/versions/7/module/Class.class', 8),
+        ]), jar)
+
+        def jar_member(path: str) -> cvv.JarLoc:
+            return cvv.JarLoc(jar, path)
+
+        def make_class(path: str) -> cvv.ClassFile:
+            return cvv.ClassFile(
+                encoded_version='1.8',
+                expected_version='1.8',
+                loc=jar_member(path))
+
+        self.assertListEqual(my_sort(m.good), [
+            make_class('module/App.class'),
+            make_class('module/Class.class'),
+        ])
+        self.assertListEqual(my_sort(m.bad), [
+            cvv.BadMultireleaseManifest(jar_member('META-INF/MANIFEST.MF'), [
+                jar_member('META-INF/versions/10'),
+                jar_member('META-INF/versions/9'),
+            ]),
+        ])
+        self.assertListEqual(my_sort(m.skipped), [
+            cvv.SkippedVersionDir(jar_member('META-INF/versions/7'),
+                                  'The version directory "7" is less than 9'),
+        ])
+
+    def test_no_manifest(self):
+        m = cvv.CVVMagic('10')
+        jar_path = cvv.FileLoc('/path/to/a.jar')
+
+        jar = ZipFile(io.BytesIO(), 'w')
+        jar.writestr('module-info.class', create_class_header(10))
+
+        m.do_jar(jar, jar_path)
+        self.assertListEqual(m.good, [
+            cvv.ClassFile(cvv.JarLoc(jar_path, 'module-info.class'), '10', '10'),
+        ])
+        self.assertListEqual(m.bad, [])
+        self.assertListEqual(m.skipped, [])


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2025-03-08 11:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-08 11:32 [gentoo-commits] proj/javatoolkit:master commit in: /, src/test/ Arthur Zamarin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox