app
AI Flow
Public Made by Adomby adom
Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board.
main
John Lauer
Publish 0.2.49
4ec8e35
import importlib.util,json,struct,tempfile,unittest
from pathlib import Path
from unittest.mock import patch
s=importlib.util.spec_from_file_location('page_check',Path(__file__).resolve().parents[1]/'tools/project-page-check.py');m=importlib.util.module_from_spec(s);s.loader.exec_module(m)
class PageChecks(unittest.TestCase):
def setUp(self):
self.tmp=tempfile.TemporaryDirectory();self.r=Path(self.tmp.name)
g=json.dumps({'meshes':[{}],'nodes':[{}]}).encode();g+=b' '*((-len(g))%4)
(self.r/'board.glb').write_bytes(struct.pack('<4sIIII',b'glTF',2,20+len(g),len(g),0x4e4f534a)+g)
(self.r/'project.pdf').write_bytes(b'%PDF-test')
self.p={'component':{'parts':{'model_3d':'board.glb','datasheet':'project.pdf'}},'sections':['hero','readme','viewers']}
for i in range(6):(self.r/f'{i}.png').write_bytes(b'fixture')
(self.r/'README.md').write_text('\n'.join(f'' for i in range(6)))
self.mock=patch.object(m.subprocess,'run',return_value=type('Result',(),{'stdout':'Readable project specification '*100})());self.mock.start()
def tearDown(self):self.mock.stop();self.tmp.cleanup()
def run_check(self):
(self.r/'page.json').write_text(json.dumps(self.p));return m.check(self.r)
def test_complete_structure_still_requires_visual_review(self):
r=self.run_check();self.assertTrue(r['passed']);self.assertIn('pending',r['visualAcceptance'])
def test_implicit_component_asset_is_rejected(self):
self.p['component']['parts']={};self.assertFalse(self.run_check()['passed'])
def test_datasheet_before_readme_rejected(self):
self.p['sections']=['viewers','readme'];self.assertFalse(self.run_check()['passed'])
def test_blank_pdf_rejected(self):
m.subprocess.run.return_value.stdout='';self.assertFalse(self.run_check()['passed'])
def test_duplicate_images_not_six_screenshots(self):
(self.r/'README.md').write_text('\n'*6);self.assertFalse(self.run_check()['passed'])
def test_wrong_live_model_rejected(self):
self.run_check();live=self.r/'live.json';live.write_text(json.dumps({'metadata':{'model_3d_path':'chip.glb','datasheet_path':'project.pdf'}}));self.assertFalse(m.check(self.r,live)['passed'])
def test_molecule_page_needs_no_glb_and_suggests_dropping_one(self):
# issue #137: the registry builds a molecule page's model; a bound GLB is a suggestion, never an error
self.p['kind']='molecule';r=self.run_check();self.assertTrue(r['passed'],r);self.assertTrue(r['molecule'])
self.assertTrue(any('model_3d' in x for x in r['suggestions']),r)
self.p['component']['parts']={'datasheet':'project.pdf'};r=self.run_check();self.assertTrue(r['passed'],r);self.assertEqual(r['suggestions'],[])
live=self.r/'live.json';live.write_text(json.dumps({'metadata':{'model_3d_path':'registry.glb','datasheet_path':'project.pdf'}}));self.assertTrue(m.check(self.r,live)['passed'])
if __name__=='__main__':unittest.main()