* [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