import contextlib import io import tempfile import unittest from pathlib import Path import npc_parts class CliTests(unittest.TestCase): def test_part_names_are_known(self): self.assertEqual( set(npc_parts.PART_NAMES), {"head", "face", "hand_l", "hand_r", "head_proto"}, ) def test_blender_commands_fail_cleanly_without_bpy(self): # Outside Blender, build/extract/assemble/inspect must explain the # flatpak invocation instead of raising. for cmd in ("build", "extract", "assemble", "inspect"): with self.subTest(cmd=cmd): code = npc_parts._needs_blender(cmd) self.assertEqual(code, 2) def test_sheet_rejects_missing_directory(self): with self.assertRaises(SystemExit) as ctx: npc_parts.make_sheet("/nonexistent/does-not-exist", "/tmp/x.jpg") self.assertIn("not a directory", str(ctx.exception)) def test_compare_rejects_missing_directory(self): with self.assertRaises(SystemExit) as ctx: npc_parts.compare("/nonexistent", "/nonexistent2", "/tmp/x.jpg") self.assertIn("not a directory", str(ctx.exception)) class SheetTests(unittest.TestCase): def test_sheet_builds_from_real_pngs(self): with tempfile.TemporaryDirectory() as td: td = Path(td) Image, _ = npc_parts._pillow() for i in range(3): im = Image.new("RGB", (64, 64), (i * 60, 0, 0)) im.save(td / f"f{i}.png") out = td / "sheet.jpg" result = npc_parts.make_sheet(str(td), str(out)) self.assertEqual(Path(result).suffix, ".jpg") self.assertTrue(out.is_file()) if __name__ == "__main__": unittest.main()