Files
verstack/tests/test_godot_scripts.py

55 lines
3.4 KiB
Python

import hashlib
import json
from pathlib import Path
import sys
import tempfile
import unittest
from unittest.mock import patch
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'plugins'))
import godot_scripts
class GodotRecovery(unittest.TestCase):
def setUp(self):
self.temp=tempfile.TemporaryDirectory();self.addCleanup(self.temp.cleanup)
self.root=Path(self.temp.name);self.source=self.root/'input';self.output=self.root/'output'
self.source.mkdir();self.output.mkdir();tool=self.root/'gdre';tool.write_bytes(b'pinned test tool')
self.request={'protocol':1,'input_dir':str(self.source),'output_dir':str(self.output),'workspace_bytes':1024**2,
'settings':{'tool':str(tool),'expected_files':{'gdre':hashlib.sha256(tool.read_bytes()).hexdigest()}}}
def test_original_source_keeps_paths_and_resource_references(self):
p=self.source/'scripts'/'scene.gd';p.parent.mkdir();p.write_text('extends Node\nconst TEX = preload("res://images/title.png")\n')
result=godot_scripts.run(self.request);self.assertEqual(result['coverage'],'complete')
evidence=json.loads((self.output/'godot-scripts-evidence.json').read_text());row=evidence['scripts'][0]
self.assertEqual(row['resource_references'],['res://images/title.png'])
self.assertEqual((self.output/row['output']).read_bytes(),p.read_bytes())
self.assertEqual(row['validation'],'original-source')
def test_loose_bytecode_without_version_is_a_visible_failure(self):
(self.source/'game.gdc').write_bytes(b'GDSCfixture')
result=godot_scripts.run(self.request);self.assertEqual(result['coverage'],'partial')
evidence=json.loads((self.output/'godot-scripts-evidence.json').read_text())
self.assertEqual(evidence['summary']['failed'],1)
self.assertIn('bytecode_version',evidence['scripts'][0]['error'])
self.assertFalse(list(self.output.rglob('*.gd')))
def test_tool_pin_rejects_changed_executable(self):
(self.root/'gdre').write_bytes(b'changed')
with self.assertRaisesRegex(ValueError,'pin'):godot_scripts.run(self.request)
def test_binary_source_is_not_published_as_decompiled_text(self):
(self.source/'bad.gd').write_bytes(b'extends Node\x00')
result=godot_scripts.run(self.request);self.assertEqual(result['coverage'],'partial')
self.assertFalse(list(self.output.rglob('*.gd')))
def test_validation_rejects_changed_roundtrip_source(self):
original=self.root/'original.gd';original.write_text('extends Node\nconst ANSWER = 42\n')
worker=godot_scripts.Recovery(self.request)
def invoke(args,work):
if any(a.startswith('--decompile=') for a in args):
target=work/'validation-returned';target.mkdir();(target/'script-00000.gd').write_text('extends Node\nconst ANSWER = 41\n')
with patch.object(worker,'invoke',side_effect=invoke),self.assertRaisesRegex(ValueError,'changed'):
worker.validate([({},original)],'4.4.1',self.root)
def test_output_budget_prevents_publication(self):
(self.source/'large.gd').write_text('extends Node\n'+'# comment\n'*100)
self.request['workspace_bytes']=16
result=godot_scripts.run(self.request);self.assertEqual(result['coverage'],'partial')
self.assertFalse(list(self.output.rglob('*.gd')))
if __name__=='__main__':unittest.main()