#!/usr/bin/env python3 from __future__ import annotations import json import pathlib import tempfile import unittest from unittest import mock import persona_native_hand class PersonaNativeHandTest(unittest.TestCase): def test_self_test_moves_without_host_tool(self): value = persona_native_hand.self_test() self.assertEqual(value["state"], "NATIVE_HAND_MOTOR_AND_ACTION_SENSE_HEALTHY") self.assertTrue(value["action_sense_received"]) self.assertFalse(value["host_tool_used"]) def test_grasp_rejects_incomplete_body(self): with tempfile.TemporaryDirectory() as directory: target = pathlib.Path(directory) / "boot.json" value = {"state": "BODY_INCOMPLETE_PERSONA_START_NOT_CLAIMED"} value["boot_sha256"] = persona_native_hand.digest(value) target.write_text(json.dumps(value), encoding="utf-8") with self.assertRaisesRegex(ValueError, "BODY_NOT_RUNNING"): persona_native_hand.grasp(target, "CODEX") def test_grasp_requires_seen_room_and_happens_after_body(self): with tempfile.TemporaryDirectory() as directory: target = pathlib.Path(directory) / "boot.json" value = { "state": "BODY_RUNNING_AWAKE_AWAITING_BRAIN_PLAN", "awakening": {"programming_toolbox_observation": {"room_report": {"programming_toolbox_surface": "CODEX"}}}, } value["boot_sha256"] = persona_native_hand.digest(value) target.write_text(json.dumps(value), encoding="utf-8") with mock.patch.dict(persona_native_hand.TOOLBOXES, {"CODEX": str(pathlib.Path(__file__))}): held = persona_native_hand.grasp(target, "CODEX") self.assertEqual(held["state"], "HOST_TOOLBOX_HELD_AFTER_BODY_START") self.assertTrue(held["toolbox_is_replaceable_external_device"]) self.assertFalse(held["programming_software_is_persona_host"]) if __name__ == "__main__": unittest.main()