Fix inventory layout integration and qualify ordinary UI and radio guidance
This commit is contained in:
@@ -19,11 +19,14 @@ def records(nonce=NONCE, menus=False):
|
||||
return f'SCRIPT : ERR INPUT OBSERVE: run={nonce} sample={index} real={1000+real} world={5000+real} {event}\n'
|
||||
result=line(0,0,'QUEUED')
|
||||
for i in range(1,450):
|
||||
opened=menus and 22<=i<=24
|
||||
opened=menus and 22<=i<=25
|
||||
result+=line(i,i*100,f'SAMPLE origin=<1, 2, 3> forward=0 input=<0, 0, 0> velocity=<0, 0, 0> inventory={int(opened)}')
|
||||
if i==21:result+=line(i,i*100,'READY')+line(i,i*100,'CAPTURE_REQUEST baseline')
|
||||
if menus and i==22:result+=line(i,i*100,'INVENTORY_OPEN')+line(i,i*100,'CAPTURE_REQUEST open')
|
||||
if menus and i==25:result+=line(i,i*100,'INVENTORY_CLOSED')+line(i,i*100,'CAPTURE_REQUEST closed')
|
||||
if i==21:result+=line(i,i*100,'READY')
|
||||
if not menus and i==24:result+=line(i,i*100,'CAPTURE_REQUEST baseline')
|
||||
if menus and i==22:result+=line(i,i*100,'INVENTORY_OPEN')
|
||||
if menus and i==25:result+=line(i,i*100,'CAPTURE_REQUEST open')
|
||||
if menus and i==26:result+=line(i,i*100,'INVENTORY_CLOSED')
|
||||
if menus and i==29:result+=line(i,i*100,'CAPTURE_REQUEST closed')
|
||||
return result+line(449,45000,'FINISHED observation-bound')
|
||||
|
||||
class InputRunnerTests(unittest.TestCase):
|
||||
@@ -59,7 +62,7 @@ class InputRunnerTests(unittest.TestCase):
|
||||
menu=runner.input_observer_evidence(records(menus=True),NONCE)
|
||||
self.assertTrue(menu['sampler_complete'],menu)
|
||||
self.assertTrue(menu['inventory_open_observed'] and menu['inventory_close_observed'])
|
||||
self.assertEqual(menu['capture_requests'],['baseline','open','closed'])
|
||||
self.assertEqual(menu['capture_requests'],['open','closed'])
|
||||
|
||||
def test_malformed_missing_reordered_unbounded_and_foreign_records_refused(self):
|
||||
good=records()
|
||||
@@ -79,6 +82,39 @@ class InputRunnerTests(unittest.TestCase):
|
||||
for bad in (good.replace('INVENTORY_OPEN','INVENTORY_CLOSED'),good.replace('inventory=1','inventory=0'),good.replace('CAPTURE_REQUEST open','CAPTURE_REQUEST baseline')):
|
||||
self.assertFalse(runner.input_observer_evidence(bad,NONCE)['sampler_complete'])
|
||||
|
||||
def test_delayed_capture_requires_delay_current_sample_and_transition_interval(self):
|
||||
def add_after(text, anchor, suffix):
|
||||
lines=text.splitlines()
|
||||
index=next(i for i,line in enumerate(lines) if anchor in line)
|
||||
prefix=lines[index].split(' SAMPLE ',1)[0] if ' SAMPLE ' in lines[index] else lines[index].rsplit(' ',1)[0]
|
||||
lines.insert(index+1,prefix+' CAPTURE_REQUEST '+suffix)
|
||||
return '\n'.join(lines)+'\n'
|
||||
baseline=records()
|
||||
without='\n'.join(line for line in baseline.splitlines() if 'CAPTURE_REQUEST' not in line)+'\n'
|
||||
# A skipped capture is valid; a same-tick or 200ms request is not.
|
||||
self.assertTrue(runner.input_observer_evidence(without,NONCE)['sampler_complete'])
|
||||
for anchor in (' READY','sample=23 real=3300 world=7300 SAMPLE'):
|
||||
self.assertFalse(runner.input_observer_evidence(add_after(without,anchor,'baseline'),NONCE)['sampler_complete'])
|
||||
duplicate=baseline.replace('CAPTURE_REQUEST baseline','CAPTURE_REQUEST baseline\n'+next(line for line in baseline.splitlines() if 'CAPTURE_REQUEST baseline' in line))
|
||||
stale=baseline.replace('sample=24 real=3400 world=7400 CAPTURE','sample=23 real=3400 world=7400 CAPTURE')
|
||||
self.assertFalse(runner.input_observer_evidence(duplicate,NONCE)['sampler_complete'])
|
||||
self.assertFalse(runner.input_observer_evidence(stale,NONCE)['sampler_complete'])
|
||||
menus=records(menus=True)
|
||||
no_caps='\n'.join(line for line in menus.splitlines() if 'CAPTURE_REQUEST' not in line)+'\n'
|
||||
for anchor,suffix in (('sample=25 real=3500 world=7500 SAMPLE','baseline'),(' INVENTORY_CLOSED','open')):
|
||||
self.assertFalse(runner.input_observer_evidence(add_after(no_caps,anchor,suffix),NONCE)['sampler_complete'])
|
||||
wrong_state=menus.replace('sample=25 real=3500 world=7500 SAMPLE origin=<1, 2, 3> forward=0 input=<0, 0, 0> velocity=<0, 0, 0> inventory=1',
|
||||
'sample=25 real=3500 world=7500 SAMPLE origin=<1, 2, 3> forward=0 input=<0, 0, 0> velocity=<0, 0, 0> inventory=0')
|
||||
self.assertFalse(runner.input_observer_evidence(wrong_state,NONCE)['sampler_complete'])
|
||||
|
||||
def test_delayed_baseline_rejects_intervening_motion_even_if_returned(self):
|
||||
good=records()
|
||||
original='sample=22 real=3200 world=7200 SAMPLE origin=<1, 2, 3> forward=0 input=<0, 0, 0> velocity=<0, 0, 0>'
|
||||
for changed in (original.replace('origin=<1, 2, 3>','origin=<1.2, 2, 3>'),original.replace('forward=0','forward=1'),
|
||||
original.replace('input=<0, 0, 0>','input=<0, 0, 1>'),original.replace('velocity=<0, 0, 0>','velocity=<0, 0, 1>')):
|
||||
with self.subTest(changed=changed):
|
||||
self.assertFalse(runner.input_observer_evidence(good.replace(original,changed),NONCE)['sampler_complete'])
|
||||
|
||||
def test_prior_failure_results_are_never_replaced(self):
|
||||
for previous in ('game-failed','cleanup-failed','source-changed','display-probe-incomplete','timeout','process-exited'):
|
||||
for content in ('',records()):self.assertEqual(runner.input_observer_result(previous,content,NONCE)[0],previous)
|
||||
|
||||
Reference in New Issue
Block a user