"""CPU-only regression checks for LoRA families and pre-GPU preparation.""" import ast import os import sys import threading import unittest from pathlib import Path from types import SimpleNamespace sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from jujo_loras import CATALOGS, JUJO_ENTRIES, NONE_LORA, lora_selected, sample_card, jujo_label, pony_selection_notice class TestAuthorLoras(unittest.TestCase): def test_no_selection_is_never_active(self): for enabled in (False, True): for name in (NONE_LORA, "", None): self.assertFalse(lora_selected(enabled, name)) self.assertTrue(lora_selected(True, "a.safetensors")) def test_family_catalogs_and_samples(self): anima, ill = JUJO_ENTRIES["anima"], JUJO_ENTRIES["illustrious"] self.assertTrue(anima and ill) self.assertFalse(set(anima) & set(ill)) self.assertIn("hotarueye_xl_tareme1_v20.safetensors", ill) self.assertNotIn("hotarueye_xl_tareme1_v10.safetensors", ill) self.assertTrue(ill["hotarueye_xl_comic02_v10.safetensors"]["pony_only"]) self.assertEqual(len(ill), 188) self.assertEqual(sum(bool(e.get("pony_only")) for e in ill.values()), 17) self.assertEqual([bool(e.get("pony_only")) for e in ill.values()], [False]*171+[True]*17) for family, entries in JUJO_ENTRIES.items(): for name, entry in entries.items(): self.assertIsNotNone(entry["image"]) if family == "illustrious": self.assertTrue(entry["path"].startswith("sdxl/")) if "_pony" in name: self.assertTrue(entry.get("pony_only")) self.assertIn(CATALOGS[family]["revision"], sample_card(family, name)) def test_pony_notices(self): for name, entry in JUJO_ENTRIES["illustrious"].items(): if entry.get("pony_only"): self.assertIn("Pony用・ILL未検証", jujo_label("illustrious", name)) self.assertIn(name, pony_selection_notice("illustrious", [name])) self.assertIn("未検証", sample_card("illustrious", name)) else: self.assertEqual(pony_selection_notice("illustrious", [name]), "") self.assertEqual(pony_selection_notice("anima", ["unknown", NONE_LORA]), "") def test_download_before_gpu_and_reject_other_family(self): source = ast.parse((Path(__file__).resolve().parents[1] / "app.py").read_text(encoding="utf-8")) function = next(n for n in source.body if isinstance(n, ast.FunctionDef) and n.name == "serialized_generate") actions = [] env = dict( generation_lock=threading.Lock(), MODEL_FAMILY={"anima": "anima", "ill": "illustrious"}, MODEL_ALIASES={}, FAMILY_LORA_NAMES={key: set(value) for key, value in JUJO_ENTRIES.items()}, JUJO_ENTRIES=JUJO_ENTRIES, JUJO_CATALOGS=CATALOGS, lora_selected=lora_selected, gr=SimpleNamespace(Error=ValueError), ensure_model_file=lambda *a, **kw: actions.append(("download", a, kw)), MODELS_ROOT="models", os=os, _generate_image_core=lambda *a, **kw: actions.append(("gpu",)), ) exec(compile(ast.Module(body=[function], type_ignores=[]), "app.py", "exec"), env) args = ["anima", "", "", 1024, 1024, 1, 8, 1, "euler", "normal"] args += [True, NONE_LORA, 0.8] * 4 args += [None, None, lambda *a, **kw: None] env["serialized_generate"](*args) self.assertEqual(actions, [("gpu",)]) actions.clear() name = next(iter(JUJO_ENTRIES["anima"])) args[11] = name env["serialized_generate"](*args) self.assertEqual([x[0] for x in actions], ["download", "gpu"]) self.assertEqual(actions[0][2]["revision"], CATALOGS["anima"]["revision"]) self.assertEqual(actions[0][1][1], "") actions.clear() args[11] = next(iter(JUJO_ENTRIES["illustrious"])) with self.assertRaises(ValueError): env["serialized_generate"](*args) self.assertEqual(actions, []) if __name__ == "__main__": unittest.main()