P23-03: 生活の観察
This commit is contained in:
@@ -288,27 +288,6 @@ class InfrastructureTests(unittest.TestCase):
|
||||
if change == 'id': q[0]['ack']['sequence'] = 2
|
||||
with self.assertRaises(ValueError): check.inspect_resume(writer, r, saved, q, members)
|
||||
|
||||
def test_rectangle_pixel_and_transform_negatives(self):
|
||||
source = 'scripts/ui/pixel_people.gd'
|
||||
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"', (check.ROOT/source).read_text())))
|
||||
report = dict(rooms={}, landing_badges=[], cabins=[], resting_staff={}, badges=[],
|
||||
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1)])
|
||||
row = dict(category='staff', id='staff/s', rect=[1, 1, 16, 18], viewport_rect=[1, 1, 16, 18],
|
||||
screen_rect=[1, 1, 16, 18], style_source=source, style_colors=colors)
|
||||
audit = dict(rows=[row])
|
||||
matrix = [1, 0, 0, 1, 0, 0]
|
||||
image = (24, 24, [[(113, 157, 148)]*24 for _ in range(24)])
|
||||
self.assertEqual(check.compare_rectangles(report, audit, matrix, matrix, matrix, image), ['staff/staff/s'])
|
||||
for change in ('rectangle', 'pixels', 'transform', 'coverage', 'palette'):
|
||||
with self.subTest(change=change):
|
||||
a, m, img = copy.deepcopy(audit), matrix[:], image
|
||||
if change == 'rectangle': a['rows'][0]['rect'][0] += 1
|
||||
if change == 'pixels': img = (24, 24, [[(0, 0, 0)]*24 for _ in range(24)])
|
||||
if change == 'transform': m[4] = 10
|
||||
if change == 'coverage': a['rows'].clear()
|
||||
if change == 'palette': a['rows'][0]['style_colors'] = ['000000']
|
||||
with self.assertRaises(ValueError): check.compare_rectangles(report, a, matrix, m, matrix, img)
|
||||
|
||||
def test_interpolation_history_tampering(self):
|
||||
state = dict(systems=dict(runtime=dict(guests=dict(guests=[]), staff=dict(staff=[]),
|
||||
elevators=dict(shafts=[], trips=[], current_minute=0))))
|
||||
@@ -568,5 +547,215 @@ class ComparisonTests(unittest.TestCase):
|
||||
check.compare_layouts(a, b)
|
||||
|
||||
|
||||
class OfflineGeometryTests(unittest.TestCase):
|
||||
"""Synthetic calibration examples; no OS or acceptance credit."""
|
||||
|
||||
def setUp(self):
|
||||
self.calibration = dict(window_size=[100, 80], window_position=[240, 150],
|
||||
screenshot_pixels=[200, 190], backing_scale=2,
|
||||
canvas_stretch=1, titlebar_pixels=30)
|
||||
self.request = dict(window_size=[100, 80], window_position=[240, 150],
|
||||
screen_scale=2, content_scale_factor=1, target_pid=123)
|
||||
self.clicks = [dict(target_pid=123, events=[dict(action='click',
|
||||
coordinates=[20, 70], calibration=copy.deepcopy(self.calibration),
|
||||
point=dict(screen=[10, 20], viewport=[10, 20],
|
||||
viewport_to_screen=[1, 0, 0, 1, 0, 0]))])]
|
||||
|
||||
def transform(self):
|
||||
return check.screenshot_transform(self.calibration, self.request, [200, 190], self.clicks)
|
||||
|
||||
def test_uses_measured_scale_origin_not_desktop_position(self):
|
||||
self.assertEqual(check.affine_rect(self.transform(), [10, 20, 5, 7]), [20, 70, 10, 14])
|
||||
|
||||
def test_shifted_titlebar_fails_independent_click(self):
|
||||
self.calibration['titlebar_pixels'] += 1
|
||||
self.calibration['screenshot_pixels'][1] += 1
|
||||
self.clicks[0]['events'][0]['calibration'] = copy.deepcopy(self.calibration)
|
||||
with self.assertRaises(ValueError):
|
||||
check.screenshot_transform(self.calibration, self.request, [200, 191], self.clicks)
|
||||
|
||||
def test_wrong_click_offset_fails(self):
|
||||
self.clicks[0]['events'][0]['coordinates'][1] -= 30
|
||||
with self.assertRaisesRegex(ValueError, 'click screenshot offset'):
|
||||
self.transform()
|
||||
|
||||
def test_wrong_pid_cannot_calibrate(self):
|
||||
self.clicks[0]['target_pid'] += 1
|
||||
with self.assertRaisesRegex(ValueError, 'missing independent click'):
|
||||
self.transform()
|
||||
|
||||
def test_nonfinite_and_false_scale_rejected(self):
|
||||
for scale in (False, float('nan'), 0, -1):
|
||||
self.calibration['backing_scale'] = scale
|
||||
with self.assertRaisesRegex(ValueError, 'invalid screenshot calibration'):
|
||||
self.transform()
|
||||
|
||||
def test_all_visibility_cases_are_accounted_for(self):
|
||||
self.assertEqual(check.rectangle_eligibility([2, 3, 4, 5], [10, 10]),
|
||||
('visible', [2, 3, 4, 5]))
|
||||
self.assertEqual(check.rectangle_eligibility([-2, 3, 4, 5], [10, 10]),
|
||||
('clipped', [0, 3, 2, 5]))
|
||||
self.assertEqual(check.rectangle_eligibility([10, 3, 4, 5], [10, 10])[0], 'outside')
|
||||
self.assertEqual(check.rectangle_eligibility([2, 3, 0, 5], [10, 10])[0], 'outside')
|
||||
|
||||
def test_invalid_rectangles_rejected(self):
|
||||
for rect in ([0, 0, -1, 4], [float('nan'), 0, 1, 4]):
|
||||
with self.assertRaisesRegex(ValueError, 'invalid clipping rectangle'):
|
||||
check.rectangle_eligibility(rect, [10, 10])
|
||||
|
||||
def test_noise_is_measured_and_does_not_assert_class(self):
|
||||
before = (2, 2, [[(10, 20, 30)]*2 for _ in range(2)])
|
||||
after = copy.deepcopy(before)
|
||||
after[2][1][1] = (10, 27, 30)
|
||||
noise = check.paired_crop_noise(before, after, [0, 0, 2, 2])
|
||||
self.assertEqual(noise, dict(samples=4, max_channel_delta=7,
|
||||
mean_channel_delta=1.75, unchanged=3))
|
||||
self.assertNotIn('pass', noise)
|
||||
self.assertNotIn('state', noise)
|
||||
|
||||
def test_wrong_dimensions_and_empty_crop_rejected(self):
|
||||
image = (1, 1, [[(0, 0, 0)]])
|
||||
with self.assertRaisesRegex(ValueError, 'paired image dimensions'):
|
||||
check.paired_crop_noise(image, (2, 1, []), [0, 0, 1, 1])
|
||||
with self.assertRaisesRegex(ValueError, 'empty noise crop'):
|
||||
check.paired_crop_noise(image, image, [1, 0, 1, 1])
|
||||
|
||||
def test_report_positions_and_source_provenance_are_recomputed(self):
|
||||
source = 'scripts/ui/pixel_people.gd'
|
||||
report = dict(rooms={}, landing_badges=[], cabins=[], resting_staff={}, badges=[],
|
||||
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1)])
|
||||
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
|
||||
(check.ROOT/source).read_text())))
|
||||
audit = dict(rows=[dict(category='staff', id='staff/s', rect=[1, 1, 16, 18],
|
||||
style_source=source, style_colors=colors)])
|
||||
check.validate_drawing_rows(report, audit)
|
||||
for change in ('shift', 'identity', 'missing', 'palette'):
|
||||
tampered = copy.deepcopy(audit)
|
||||
if change == 'shift': tampered['rows'][0]['rect'][0] += 1
|
||||
if change == 'identity': tampered['rows'][0]['category'] = 'guest'
|
||||
if change == 'missing': tampered['rows'] = []
|
||||
if change == 'palette': tampered['rows'][0]['style_colors'] = ['000000']
|
||||
with self.subTest(change=change), self.assertRaises(ValueError):
|
||||
check.validate_drawing_rows(report, tampered)
|
||||
|
||||
|
||||
class FrameReviewTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
OfflineGeometryTests.setUp(self)
|
||||
self.request.update(local_to_viewport=[1, 0, 0, 1, 0, 0],
|
||||
viewport_to_screen=[1, 0, 0, 1, 0, 0],
|
||||
local_to_screen=[1, 0, 0, 1, 0, 0])
|
||||
self.report = dict(layer=0, viewport=[100, 80], rooms={}, cabins=[],
|
||||
landing_badges=[], badges=[], resting_staff={}, traffic=[],
|
||||
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1, state=0)])
|
||||
source = 'scripts/ui/pixel_people.gd'
|
||||
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
|
||||
(check.ROOT/source).read_text())))
|
||||
self.audit = dict(rows=[dict(category='staff', id='staff/s', rect=[1, 1, 16, 18],
|
||||
viewport_rect=[1, 1, 16, 18], screen_rect=[1, 1, 16, 18],
|
||||
style_source=source, style_colors=colors)])
|
||||
self.image = (200, 190, [[(x % 256, y % 256, 0) for x in range(200)] for y in range(190)])
|
||||
|
||||
def frame(self):
|
||||
return check.frame_rows(self.report, self.audit, self.request,
|
||||
dict(calibration=self.calibration), [self.image], self.clicks)
|
||||
|
||||
def test_blank_crop_fails_without_threshold(self):
|
||||
self.image = (200, 190, [[(0, 0, 0)] * 200 for _ in range(190)])
|
||||
result = self.frame()
|
||||
self.assertFalse(result['mechanical_pass'])
|
||||
self.assertIn('blank crop', result['rows'][0]['failures'])
|
||||
|
||||
def test_missing_extra_and_unaudited_traffic_fail(self):
|
||||
for change in ('missing', 'extra', 'traffic'):
|
||||
with self.subTest(change=change):
|
||||
original = copy.deepcopy(self.audit)
|
||||
if change == 'missing': self.audit['rows'].clear()
|
||||
if change == 'extra': self.audit['rows'] *= 2
|
||||
if change == 'traffic':
|
||||
self.report['traffic'] = [dict(cell=[-6, 2, 0], rect=[1, 1, 5, 5],
|
||||
traffic=dict(current_density=1, temporary_block=False))]
|
||||
result = self.frame()
|
||||
self.assertFalse(result['mechanical_pass'])
|
||||
self.assertEqual(len(result['rows']), len(self.audit['rows']))
|
||||
self.assertIn('offline rectangle coverage', result['errors'])
|
||||
self.audit = original
|
||||
|
||||
def test_dense_or_blocked_traffic_row_closes_audit_gap(self):
|
||||
source = 'scenes/main/world_preview.gd'
|
||||
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
|
||||
(check.ROOT/source).read_text())))
|
||||
for density, blocked in ((1, False), (0, True), (0, False)):
|
||||
with self.subTest(density=density, blocked=blocked):
|
||||
self.report['traffic'] = [dict(cell=[-6, 2, 0], rect=[1, 1, 5, 5],
|
||||
traffic=dict(current_density=density, temporary_block=blocked))]
|
||||
active = density > 0 or blocked
|
||||
missing = self.frame()
|
||||
self.assertEqual(missing['mechanical_pass'], not active)
|
||||
if active:
|
||||
self.assertIn('offline rectangle coverage', missing['errors'])
|
||||
self.audit['rows'].append(dict(category='traffic', id='-6,2,0',
|
||||
rect=[1, 1, 5, 5], viewport_rect=[1, 1, 5, 5],
|
||||
screen_rect=[1, 1, 5, 5], style_source=source, style_colors=colors))
|
||||
complete = self.frame()
|
||||
self.assertTrue(complete['mechanical_pass'], complete['errors'])
|
||||
self.audit['rows'].pop()
|
||||
|
||||
def test_wrong_state_enum_and_name_fail(self):
|
||||
source = 'scripts/ui/pixel_tower_art.gd'
|
||||
self.report['actor_drawings'] = []
|
||||
room = dict(rect=[1, 1, 16, 18], state=3, state_name='NO_STAFF', operation=0)
|
||||
self.report['rooms'] = {'r': room}
|
||||
self.audit['rows'][0].update(category='room', id='r', style_source=source,
|
||||
style_colors=list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
|
||||
(check.ROOT/source).read_text()))))
|
||||
self.assertEqual(self.frame()['rows'][0]['operation'], 'INACTIVE')
|
||||
for state, name in ((99, 'NO_STAFF'), (3, 'OPEN'), (True, 'NO_ACCESS')):
|
||||
room.update(state=state, state_name=name)
|
||||
with self.assertRaises(ValueError): self.frame()
|
||||
|
||||
def test_frame_rejects_affine_and_calibration_shift(self):
|
||||
self.request['local_to_screen'][4] += 1
|
||||
with self.assertRaisesRegex(ValueError, 'affine composition'): self.frame()
|
||||
self.request['local_to_screen'][4] -= 1
|
||||
self.clicks[0]['events'][0]['coordinates'][1] += 1
|
||||
with self.assertRaisesRegex(ValueError, 'click screenshot offset'): self.frame()
|
||||
|
||||
def test_eligible_crop_fully_outside_image_fails(self):
|
||||
for key in ('viewport_to_screen', 'local_to_screen'):
|
||||
self.request[key][4] = 300
|
||||
self.audit['rows'][0]['screen_rect'][0] += 300
|
||||
result = self.frame()
|
||||
self.assertFalse(result['mechanical_pass'])
|
||||
self.assertIn('eligible crop outside image', result['rows'][0]['failures'])
|
||||
|
||||
def test_manifest_crop_and_independent_review_binding(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
directory = Path(temporary)
|
||||
manifest, digest = check.write_frame_review(directory, self.frame(),
|
||||
[dict(whole_image_sha256='a'*64, raw_sha256='b'*64, conversion_sha256='c'*64)])
|
||||
self.assertEqual(check.sha(directory/'manifest.json'), digest)
|
||||
crop = manifest['rows'][0]['crops'][0]
|
||||
self.assertEqual(check.sha(directory/crop['path']), crop['sha256'])
|
||||
self.assertEqual(check.png_pixels((directory/crop['path']).read_bytes())[:2], (32, 36))
|
||||
verdict_path = directory/'independent-verdict.json'
|
||||
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), set())
|
||||
verdict = dict(manifest_sha256=digest, reviewer='independent-opus-direct-image',
|
||||
rows=[dict(row_index=0, category=True, state=True, position=True)])
|
||||
for change in ('wrong_sha', 'missing_row', 'extra_row', 'rejected_state'):
|
||||
bad = copy.deepcopy(verdict)
|
||||
if change == 'wrong_sha': bad['manifest_sha256'] = '0'*64
|
||||
if change == 'missing_row': bad['rows'] = []
|
||||
if change == 'extra_row': bad['rows'] *= 2
|
||||
if change == 'rejected_state': bad['rows'][0]['state'] = False
|
||||
verdict_path.write_text(json.dumps(bad))
|
||||
with self.subTest(change=change), self.assertRaises(ValueError):
|
||||
check.reviewed_pixel_categories(manifest, digest, verdict_path)
|
||||
verdict_path.write_text(json.dumps(verdict))
|
||||
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), {'staff'})
|
||||
manifest['mechanical_pass'] = False
|
||||
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), set())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user