Something went wrong. Try again.
Native control, inspection, UI automation and evidence capture for a running Witcher 3 process.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127import hashlibimport jsonfrom pathlib import Pathimport tempfileimport unittestfrom unittest.mock import patch
from witcher_devkit import evaluation, experiments as lab, native
def snap(position=(0, 0, 0), generation=10): return dict(ok=True, generation=generation, data=dict(ready=True, world=dict(devkit_paused=True, player=dict(position=position))))
def actor(level, hp=918): return dict(data=dict(actor=dict(id=3, level=level, max_hp=hp, alive=True), health_type='essence', armor=0, ability_counts={'bonus': level-1}))
class SetupTests(unittest.TestCase): def test_spawn_observes_initialization_and_never_repeats_mutation(self): with patch.object(lab, 'require_paused', return_value=snap()), \ patch.object(lab, 'data', return_value=dict(ok=True, generation=10, data=[dict(id=3)])) as call, \ patch.object(lab, 'profile', side_effect=[actor(1,108), actor(6), actor(6), actor(6)]), \ patch.object(native, 'bounded_action') as advance: result = lab.spawn('nekker', 6) self.assertTrue(result['experimental_validity']) self.assertEqual(result['history'][0]['profiles'][0]['actor']['level'], 1) self.assertEqual(result['elapsed_ticks'], 45) call.assert_called_once() self.assertEqual(advance.call_count, 3)
def test_wolf_level_offset_fails_without_changing_the_request(self): with patch.object(lab, 'require_paused', return_value=snap()), \ patch.object(lab, 'data', return_value=dict(ok=True, generation=10, data=[dict(id=3)])), \ patch.object(lab, 'profile', return_value=actor(10)), patch.object(native, 'bounded_action'): result = lab.spawn('wolf', 6) self.assertFalse(result['ok']) self.assertEqual(result['reason'], 'actual_level_mismatch') self.assertEqual(result['requested']['level'], 6) self.assertEqual(result['observed'][0]['actor']['level'], 10)
def test_teleport_checks_navigation_target_and_reports_elapsed_ticks(self): with patch.object(lab, 'require_paused', return_value=snap()), \ patch.object(lab, 'data', return_value=dict(ok=True, data=[1, 2, 3])) as call, \ patch.object(lab, 'snapshot', side_effect=[snap(), snap([1,2,3])]), patch.object(native, 'bounded_action'): result = lab.teleport('1|2|4') self.assertTrue(result['ok']) self.assertEqual(result['requested'], [1,2,4]) self.assertEqual(result['navigation_target'], [1,2,3]) self.assertEqual(result['elapsed_ticks'], 5) call.assert_called_once()
def test_uninitialized_combat_attributes_are_not_normalized_to_zero(self): value=dict(ability_initialized=False,armor=-1,armor_terms={'base':-1},attack_power={'base':-1},spell_power={'base':-1},level_attribute={'additive':-1},defenses={},abilities=[],abilities_including_inventory=[]) with patch.object(lab,'data',return_value={'data':value}): result=lab.profile('10|3')['data'] self.assertIsNone(result['armor']) self.assertEqual(result['native_armor'],-1) self.assertFalse(result['combat_attributes_available'])
def test_rejected_setup_advance_does_not_claim_elapsed_ticks(self): with patch.object(lab,'require_paused',return_value=snap()),patch.object(lab,'data',return_value=dict(ok=True,data=[1,2,3])),patch.object(lab,'snapshot',return_value=snap()),patch.object(native,'bounded_action',return_value={'ok':False,'data':'blocked'}) as advance: with self.assertRaisesRegex(RuntimeError,'elapsed ticks not assumed'): lab.teleport('1|2|3') self.assertEqual(advance.call_count,1)
def test_event_overflow_is_explicit(self): with patch.object(lab, 'snapshot', return_value=snap()), \ patch.object(lab, 'data', return_value={'data':dict(latest=132, oldest=5, events=[{'sequence':i} for i in range(5,9)])}): result = lab.events(after=1, generation=10, limit=4) self.assertFalse(result['complete']) self.assertEqual(result['gaps'], [dict(first=2,last=4)]) self.assertTrue(result['more'])
def test_stale_cursor_never_requests_event_page(self): with patch.object(lab, 'snapshot', return_value=snap()), patch.object(lab, 'data') as call: with self.assertRaisesRegex(RuntimeError, 'different world'): lab.events(1, 9) call.assert_not_called()
class ScopedEvaluationTests(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory(); self.addCleanup(self.tmp.cleanup) self.root = Path(self.tmp.name); (self.root/'artifacts').mkdir() self.target = self.root/'installed.ws'; self.target.write_bytes(b'original\r\nbytes\r\n') self.previous = self.target.read_bytes() self.probe = self.root/'probe.ws'; self.probe.write_text('return "null";') self.receipt = dict(evaluation=dict(path=str(self.target), sha256=hashlib.sha256(self.previous).hexdigest())) (self.root/'deployment.json').write_text(json.dumps(self.receipt)) for patcher in [patch.object(native,'ROOT',self.root), patch.object(native,'STATE_ROOT',self.root), patch.object(native.legacy,'ARTIFACTS',self.root/'artifacts'), patch.object(native,'state',return_value={'session':'test'}), patch.object(native,'recompile',return_value={'ok':True})]: patcher.start();self.addCleanup(patcher.stop)
def temporary_evaluation(self, path): self.target.write_text('function PDEvaluateBody() : string\n{\n'+Path(path).read_text()+'\n}\n') receipt = dict(evaluation=dict(path=str(self.target),sha256=hashlib.sha256(self.target.read_bytes()).hexdigest())) (self.root/'deployment.json').write_text(json.dumps(receipt)) return {'ok':True,'compile':{'ok':True},'executed':True}
def test_success_restores_exact_bytes_and_receipt(self): with patch.object(native,'evaluate',side_effect=self.temporary_evaluation): result = evaluation.scoped(self.probe) self.assertTrue(result['restoration']['ok']) self.assertEqual(self.target.read_bytes(), self.previous) self.assertEqual(json.loads((self.root/'deployment.json').read_text()),self.receipt)
def test_lost_evaluation_ack_still_restores_source(self): def fail(path): self.temporary_evaluation(path) raise TimeoutError('lost acknowledgement') with patch.object(native,'evaluate',side_effect=fail): with self.assertRaises(TimeoutError):evaluation.scoped(self.probe) self.assertEqual(self.target.read_bytes(), self.previous) journals=list((self.root/'artifacts').glob('scoped-*/recovery.json')) self.assertEqual(json.loads(journals[0].read_text())['status'],'restored')
def test_unrelated_edit_is_never_overwritten(self): def altered(path): r=self.temporary_evaluation(path);self.target.write_text('someone else changed this');return r with patch.object(native,'evaluate',side_effect=altered): with self.assertRaisesRegex(RuntimeError,'changed outside'):evaluation.scoped(self.probe) self.assertEqual(self.target.read_text(),'someone else changed this')
if __name__ == '__main__':unittest.main()