import copy import gzip import hashlib import json from pathlib import Path import sys import tempfile import unittest ROOT=Path(__file__).resolve().parents[1] sys.path.insert(0,str(ROOT/'scripts')) from oglib.catalog import Catalog from oglib.template_program import compile_program from openglyph import compile_project,inspect class BuilderTests(unittest.TestCase): @classmethod def setUpClass(cls):cls.catalog=Catalog(ROOT/'data/glyphwiki-ebag.kage.jsonl.gz') def test_pinned_edit_replay_and_source_isolation(self): source=self.catalog.resolve('ebag:s030-067') project=json.loads((ROOT/'examples/newforms.json').read_text()) original=copy.deepcopy(source) for row in project['glyphs']: program=dict(schema='guwenzi.template-program.v1',base=row['base'],edits=row['edits']) recipe,info=compile_program(self.catalog,program) self.assertEqual((recipe,info),compile_program(self.catalog,json.loads(json.dumps(info['program'])))) self.assertNotEqual(recipe['root'],source['name']) self.assertEqual(self.catalog.resolve('ebag:s030-067'),original) def test_all_source_dependencies_exist_and_versions_do_not_fallback(self): from oglib.catalog import refs for name,data in self.catalog.table.items(): for child in refs(data):self.assertIn(child,self.catalog.table,name) with self.assertRaises(ValueError):self.catalog.resolve('u81e3@999999') def test_build_is_deterministic_and_never_overwrites(self): with tempfile.TemporaryDirectory() as tmp: root=Path(tmp);first=compile_project(ROOT/'examples/newforms.json',root/'first') second=compile_project(ROOT/'examples/newforms.json',root/'second') self.assertEqual(first['font_sha256'],second['font_sha256']) self.assertEqual(first['glyphs'],second['glyphs']) original=(root/'first'/first['font_file']).read_bytes() with self.assertRaises(ValueError):compile_project(ROOT/'examples/newforms.json',root/'first') self.assertEqual((root/'first'/first['font_file']).read_bytes(),original) def test_each_exported_char_has_a_real_outline(self): from fontTools.ttLib import TTFont from fontTools.pens.boundsPen import BoundsPen with tempfile.TemporaryDirectory() as tmp: folder=Path(tmp)/'output';result=compile_project(ROOT/'examples/newforms.json',folder) with TTFont(folder/result['font_file']) as font: cmap=font.getBestCmap();gs=font.getGlyphSet() for row in result['glyphs']: name=cmap[row['codepoint']];pen=BoundsPen(gs);gs[name].draw(pen) self.assertIsNotNone(pen.bounds) self.assertNotIn('SVG ',font);self.assertNotIn('sbix',font) def test_removed_ids_keep_slots_on_revision(self): project=json.loads((ROOT/'examples/newforms.json').read_text()) with tempfile.TemporaryDirectory() as tmp: root=Path(tmp);first=compile_project(ROOT/'examples/newforms.json',root/'first') project['glyphs']=project['glyphs'][1:];project['glyphs'].append(dict(id='new',base='ebag:s030-067',edits=[])) manifest=root/'project.json';manifest.write_text(json.dumps(project)) second=compile_project(manifest,root/'second',root/'first/allocation.json') before={r['id']:r['codepoint'] for r in first['glyphs']};after={r['id']:r['codepoint'] for r in second['glyphs']} for key in ('n2','n3','n4'):self.assertEqual(before[key],after[key]) self.assertNotIn(after['new'],before.values()) def test_inspection_produces_numbered_actual_vector_previews(self): with tempfile.TemporaryDirectory() as tmp: folder=Path(tmp)/'preview';result=inspect('ebag:s030-067','r4',folder) self.assertEqual(len(result['nodes']),4) page=(folder/'index.html').read_text() for row in result['nodes']:self.assertIn(row['node'],page) self.assertEqual(len(list(folder.glob('*.svg'))),6) with self.assertRaises(ValueError):inspect('ebag:s030-067','r4',folder) def test_remote_module_project_compiles_to_real_offline_font(self): value=dict(schema='openglyph.project.v1',namespace='remote',glyphs=[dict(id='new',base='ebag:s030-067', modules={'mark':dict(schema='guwenzi.template-program.v1',base='primitive:dot',edits=[])}, edits=[dict(op='insert',parent='root',id='mark',glyph='module:mark',box=[77,129,119,167])])]) with tempfile.TemporaryDirectory() as tmp: root=Path(tmp);project=root/'project.json';project.write_text(json.dumps(value)) report=compile_project(project,root/'built') self.assertEqual(report['glyphs'][0]['alias'],'remote:new') self.assertTrue((root/'built'/report['font_file']).is_file()) if __name__=='__main__':unittest.main()