P08-03: 配置の通常操作受入
This commit is contained in:
@@ -267,6 +267,31 @@ def coordinates(p):
|
||||
expected = [matrix[0]*x+matrix[2]*y+matrix[4], matrix[1]*x+matrix[3]*y+matrix[5]]
|
||||
require(len(p[target]) == 2 and all(abs(a-b) < 0.001 for a,b in zip(expected,p[target])), 'transformed '+target+' mismatch')
|
||||
|
||||
def dispatch_gate(p, events):
|
||||
d = p['dispatch']
|
||||
presses = [e for e in events if e.get('button') == 1 and e.get('pressed') is True]
|
||||
require(len(presses) == 1 and presses[0].get('dispatch') == d
|
||||
and presses[0]['position'] == d['viewport'], 'OS dispatch event mismatch')
|
||||
for key in ('bounds', 'map_position', 'cell_dimensions', 'zoom', 'pan',
|
||||
'viewport_transform', 'screen_transform'):
|
||||
require(d[key] == p[key], 'OS dispatch transform drift')
|
||||
x, y = d['local']
|
||||
require(math.isfinite(x) and math.isfinite(y), 'OS nonfinite dispatch')
|
||||
origin, size, bounds = d['map_position'], d['cell_dimensions'], d['bounds']
|
||||
derived = [bounds['min_x'] + math.floor((x-origin[0])/size[0]),
|
||||
bounds['max_y'] - math.floor((y-origin[1])/size[1]), p['world_cell'][2]]
|
||||
require(d['world_cell'] == derived == p['world_cell'], 'OS actual input cell drift')
|
||||
for target in ('viewport', 'screen'):
|
||||
matrix = d[target+'_transform']
|
||||
expected = [matrix[0]*x+matrix[2]*y+matrix[4], matrix[1]*x+matrix[3]*y+matrix[5]]
|
||||
require(len(d[target]) == 2 and all(math.isfinite(v) for v in d[target])
|
||||
and all(abs(a-b) < 0.001 for a,b in zip(expected,d[target])), 'OS dispatch coordinate drift')
|
||||
selection = p['selection']
|
||||
require(isinstance(selection['required'], bool), 'OS selection requirement')
|
||||
if selection['required']:
|
||||
require(selection['occupant_id'] and selection['entity_id'] == selection['occupant_id'],
|
||||
'OS selected entity mismatch')
|
||||
|
||||
def preserve(a, b, results):
|
||||
differences = typed_differences(a, b)
|
||||
if not results:
|
||||
@@ -644,6 +669,13 @@ def check(project_root, evidence_dir):
|
||||
for key in ('screen_before', 'screen_after'):
|
||||
png(artifact(ack[key]).read_bytes())
|
||||
if request['action'] == 'cell' and 'position' in row:
|
||||
dispatch_gate(row['position'], observed['events'])
|
||||
if row['id'] == 'pan_zoom':
|
||||
selection = row['position']['selection']
|
||||
require(selection['required'], 'OS missing entity selection')
|
||||
occupants = decode(document('os-pair/'+row['after']+'.json'))['systems']['runtime']['world']['occupancies']
|
||||
matches = [o['entity_id'] for o in occupants if row['position']['world_cell'] in o['cells']]
|
||||
require(matches == [selection['occupant_id']], 'OS selected occupancy mismatch')
|
||||
require(request['world_cell'] == row['position']['world_cell']
|
||||
and request['viewport'] == row['position']['viewport']
|
||||
and request['screen'] == row['position']['screen'], 'OS transformed cell drift')
|
||||
|
||||
@@ -329,6 +329,41 @@ class EvidenceTests(unittest.TestCase):
|
||||
self.edit('os-pair/unsupported-1/observed.json', lambda d: d.update(events=[]))
|
||||
self.reject('missing OS events')
|
||||
|
||||
def test_os_dispatch_missing(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position'].pop('dispatch'))
|
||||
self.reject('dispatch')
|
||||
|
||||
def test_os_wrong_actual_input_cell(self):
|
||||
# Keep event and action mutually consistent; independent conversion must reject.
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position']['dispatch']['world_cell'].__setitem__(0, 99))
|
||||
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0]['dispatch']['world_cell'].__setitem__(0, 99))
|
||||
self.reject('OS actual input cell drift')
|
||||
|
||||
def test_os_event_position_disagrees(self):
|
||||
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0].update(position=[0,0]))
|
||||
self.reject('OS dispatch event mismatch')
|
||||
|
||||
def test_os_wrong_selected_entity(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(entity_id='wrong'))
|
||||
self.reject('OS selected entity mismatch')
|
||||
|
||||
def test_os_wrong_selected_occupancy(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(entity_id='wrong', occupant_id='wrong'))
|
||||
self.reject('OS selected occupancy mismatch')
|
||||
|
||||
def test_os_selection_requirement_cannot_be_removed(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(required=False))
|
||||
self.reject('OS missing entity selection')
|
||||
|
||||
def test_os_dispatch_transform_drift(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position']['dispatch'].update(pan=[100,0]))
|
||||
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0]['dispatch'].update(pan=[100,0]))
|
||||
self.reject('OS dispatch transform drift')
|
||||
|
||||
def test_os_later_getter_is_diagnostic(self):
|
||||
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['diagnostics'].update(getter_cell=[999,999,0]))
|
||||
self.assertEqual([], C.check(self.root, self.out))
|
||||
|
||||
def test_os_ack_for_another_request(self):
|
||||
self.edit('os-pair/unsupported-1/ack.json', lambda d: d.update(request_sha256='0'*64))
|
||||
self.reject('OS ack request mismatch')
|
||||
|
||||
Reference in New Issue
Block a user