Files
EscapistsReintroduced/tests/test_ordinary_gate_choices.py

57 lines
3.9 KiB
Python

import copy
from pathlib import Path
import sys
import unittest
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'tools'))
from ordinary_gate_choices import parse_choice_record,parse_choice_records,join_choice_snapshots,exact_prison_choices
from test_ordinary_gate_evidence import fixture,NONCE
def line(index=1,real=2100,selected='ERR_PrisonDoorAction:7',context=1,ordered='0=ERR_PrisonDoorAction:7:0,1=ERR_UnlockPrisonAction:8:1'):
return f'ERR GATE CHOICE: run={NONCE} sample={index} real={real} selected={selected} context={context} actions=2 permissions=2 shown=2 truncated=0 ordered=[{ordered}]'
class Choices(unittest.TestCase):
def test_exact_pair_and_selected_identity(self):
c=parse_choice_record(line(),NONCE);self.assertEqual(c['selected_id'],7)
self.assertEqual(exact_prison_choices({'choices':c}),c)
c['selected_class']='ERR_UnlockPrisonAction';c['selected_id']=8
self.assertEqual(exact_prison_choices({'choices':c})['selected_id'],8)
def test_empty_and_truncated_are_diagnostic_only(self):
empty=line(selected='none:-1',context=0,ordered='').replace('actions=2 permissions=2 shown=2','actions=0 permissions=0 shown=0')
self.assertEqual(parse_choice_record(empty,NONCE)['actions'],[])
with self.assertRaises(ValueError):exact_prison_choices({'choices':parse_choice_record(empty,NONCE)})
entries=','.join(f'{i}=Action:{i}:1' for i in range(8))
truncated=line(ordered=entries).replace('actions=2 permissions=2 shown=2 truncated=0','actions=9 permissions=9 shown=8 truncated=1')
self.assertTrue(parse_choice_record(truncated,NONCE)['truncated'])
def test_missing_permissions_do_not_become_false_permission(self):
text=line(ordered='0=ERR_PrisonDoorAction:7:0,1=ERR_UnlockPrisonAction:8:-1').replace('permissions=2','permissions=1')
c=parse_choice_record(text,NONCE);self.assertIsNone(c['actions'][1]['permitted'])
with self.assertRaises(ValueError):exact_prison_choices({'choices':c})
def test_malformed_ids_counts_nonce_and_sequence_refuse(self):
for text in [line().replace(NONCE,'foreign'),line().replace('shown=2','shown=1'),line().replace('truncated=0','truncated=1'),line().replace('Action:7','Action:-1'),line().replace('0=ERR','1=ERR'),line().replace(':8:1',':8:-1'),line().replace('context=1','context=3')]:
with self.subTest(text=text),self.assertRaises(ValueError):parse_choice_record(text,NONCE)
for text in [line()+'\n'+line(),line(2),line()+'\n'+line(2,2000)]:
with self.assertRaises(ValueError):parse_choice_records(text,NONCE)
def test_exact_pair_refuses_other_order_identity_or_permission(self):
c=parse_choice_record(line(),NONCE)
for fault in ('order','duplicate','permission','selected','class'):
d=copy.deepcopy(c)
if fault=='order':d['actions'].reverse()
elif fault=='duplicate':d['actions'][1]['id']=7
elif fault=='permission':d['actions'][0]['permitted']=True
elif fault=='selected':d['selected_id']=9
else:d['actions'][1]['class']='ForeignAction'
with self.subTest(fault=fault),self.assertRaises(ValueError):exact_prison_choices({'choices':d})
def test_real_native_schema_join_requires_exact_clock_and_selection(self):
from ordinary_gate_evidence import join_gate_snapshots
content=fixture();snapshots=join_gate_snapshots(content,NONCE)['snapshots']
choices=[]
for i,s in snapshots.items():
choices.append(line(i,s['real_ms'],selected='none:-1',context=0,ordered='').replace('actions=2 permissions=2 shown=2','actions=0 permissions=0 shown=0'))
raw=content+'\n'+'\n'.join(choices)
self.assertEqual(len(join_choice_snapshots(raw,NONCE)['snapshots']),len(snapshots))
for bad in [raw.replace('selected=none:-1','selected=ERR_UnlockPrisonAction:8',1),raw.replace('context=0 actions=0','context=1 actions=0',1),raw.replace(f'sample=1 real={snapshots[1]["real_ms"]} selected',f'sample=1 real={snapshots[1]["real_ms"]+1} selected',1)]:
with self.assertRaises(ValueError):join_choice_snapshots(bad,NONCE)
if __name__=='__main__':unittest.main()