Files
LihonT/tests/test_settings_model.py
cheb0chik e63ca75eac LihonT 2 Luna pre-release
Avatar shapes (circle, flower, rounded square, hexagon, heart, triangle): the own shape everywhere and, through
the members service, the shapes other members published after proving the account with the code in the bio.
Own accent colour and AMOLED, compact bottom bar, Material 3 profile and plus button, save menu (quality, audio
only, photo posts without the watermark), fixed comment cards, "Luna (pre-release)" in the mod screen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 19:03:48 +03:00

116 lines
3.9 KiB
Python

"""Run the platform-independent settings contract on a real JVM.
The Android file adapter is compiled against android.jar, not executed under
desktop stubs. Device/storage integration belongs to the later APK stage.
"""
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
PACKAGE = ROOT / "src" / "lihont" / "two" / "settings"
HARNESS = ROOT / "tests" / "java" / "lihont" / "two" / "settings" / "SettingsModelTest.java"
class SettingsModelTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.javac = shutil.which("javac")
cls.java = shutil.which("java")
if not cls.javac or not cls.java:
raise RuntimeError("Settings model tests require a JDK with java and javac")
cls.temporary = tempfile.TemporaryDirectory(prefix="lihont-settings-tests-")
cls.addClassCleanup(cls.temporary.cleanup)
cls.classes = Path(cls.temporary.name) / "classes"
cls.classes.mkdir()
cls.environment = dict(os.environ)
cls.environment.pop("JAVA_TOOL_OPTIONS", None)
cls.run_command([
cls.javac, "--release", "17", "-encoding", "UTF-8", "-d", str(cls.classes),
str(PACKAGE / "ModSettings.java"),
str(PACKAGE / "SettingsCodec.java"),
str(PACKAGE / "SettingsRepository.java"),
str(PACKAGE / "TonalPalette.java"),
str(HARNESS),
])
@classmethod
def run_command(cls, command):
result = subprocess.run(
command, capture_output=True, text=True, encoding="utf-8",
env=cls.environment, timeout=60,
)
if result.returncode:
raise AssertionError(
f"Command failed with exit {result.returncode}: {command[0]}\n"
+ result.stdout + result.stderr
)
return result
def run_scenario(self, name):
result = self.run_command([
self.java, "-cp", str(self.classes),
"lihont.two.settings.SettingsModelTest", name,
])
self.assertEqual(result.stdout.strip(), "PASS " + name)
def test_defaults_and_region_warning(self):
self.run_scenario("defaults")
def test_all_iso_countries_roundtrip(self):
self.run_scenario("countries")
def test_typed_inputs_reject_invalid_values(self):
self.run_scenario("validation")
def test_restart_policy(self):
self.run_scenario("restart")
def test_valid_json_and_portable_roundtrip(self):
self.run_scenario("codec")
def test_invalid_documents_are_rejected(self):
self.run_scenario("invalid")
def test_settings_persist_across_repository_instances(self):
self.run_scenario("persistence")
def test_active_snapshot_and_noop_write(self):
self.run_scenario("snapshot")
def test_reset_restores_defaults_and_persists_them(self):
self.run_scenario("reset")
def test_invalid_imports_preserve_memory_and_disk(self):
self.run_scenario("atomicImport")
def test_io_failures_are_visible_and_preserve_previous_settings(self):
self.run_scenario("ioFailures")
def test_corrupt_or_future_stored_data_is_not_overwritten(self):
self.run_scenario("corruptStorage")
def test_look_choices_roundtrip_and_old_files_keep_the_old_look(self):
self.run_scenario("look")
def test_fixed_accents_keep_their_contrast(self):
self.run_scenario("tonal")
def test_android_adapter_compiles_against_android_api(self):
android_jar = ROOT / "tools" / "android.jar"
self.assertTrue(android_jar.is_file(), "tools/android.jar must be available")
self.run_command([
self.javac, "--release", "17", "-encoding", "UTF-8",
"-cp", str(android_jar) + os.pathsep + str(self.classes),
"-d", str(self.classes), str(PACKAGE / "AndroidSettingsStorage.java"),
])
if __name__ == "__main__":
unittest.main()