1import logging 2import shutil 3 4from fontTools.misc import plistlib 5from fontTools.ufoLib import UFOReader, UFOWriter, UFOFormatVersion 6from fontTools.ufoLib.errors import UFOLibError, UnsupportedUFOFormat 7import pytest 8 9 10@pytest.fixture 11def ufo_path(tmp_path): 12 ufodir = tmp_path / "TestFont.ufo" 13 ufodir.mkdir() 14 with (ufodir / "metainfo.plist").open("wb") as f: 15 plistlib.dump({"creator": "pytest", "formatVersion": 3}, f) 16 (ufodir / "glyphs").mkdir() 17 with (ufodir / "layercontents.plist").open("wb") as f: 18 plistlib.dump([("public.default", "glyphs")], f) 19 return ufodir 20 21 22def test_formatVersion_deprecated(ufo_path): 23 reader = UFOReader(ufo_path) 24 25 with pytest.warns(DeprecationWarning) as warnings: 26 assert reader.formatVersion == 3 27 28 assert len(warnings) == 1 29 assert "is deprecated; use the 'formatVersionTuple'" in warnings[0].message.args[0] 30 31 32def test_formatVersionTuple(ufo_path): 33 reader = UFOReader(ufo_path) 34 35 assert reader.formatVersionTuple == (3, 0) 36 assert reader.formatVersionTuple.major == 3 37 assert reader.formatVersionTuple.minor == 0 38 assert str(reader.formatVersionTuple) == "3.0" 39 40 41def test_readMetaInfo_errors(ufo_path): 42 (ufo_path / "metainfo.plist").unlink() 43 with pytest.raises(UFOLibError, match="'metainfo.plist' is missing"): 44 UFOReader(ufo_path) 45 46 (ufo_path / "metainfo.plist").write_bytes(plistlib.dumps({})) 47 with pytest.raises(UFOLibError, match="Missing required formatVersion"): 48 UFOReader(ufo_path) 49 50 (ufo_path / "metainfo.plist").write_bytes(plistlib.dumps([])) 51 with pytest.raises(UFOLibError, match="metainfo.plist is not properly formatted"): 52 UFOReader(ufo_path) 53 54 55def test_readMetaInfo_unsupported_format_version(ufo_path, caplog): 56 metainfo = {"formatVersion": 10, "formatVersionMinor": 15} 57 (ufo_path / "metainfo.plist").write_bytes(plistlib.dumps(metainfo)) 58 59 with pytest.raises(UnsupportedUFOFormat): 60 UFOReader(ufo_path) # validate=True by default 61 62 with pytest.raises(UnsupportedUFOFormat): 63 UFOReader(ufo_path, validate=True) 64 65 caplog.clear() 66 with caplog.at_level(logging.WARNING, logger="fontTools.ufoLib"): 67 UFOReader(ufo_path, validate=False) 68 69 assert len(caplog.records) == 1 70 assert "Unsupported UFO format" in caplog.text 71 assert "Assuming the latest supported version" in caplog.text 72 73 74def test_UFOWriter_formatVersion(tmp_path): 75 ufo_path = tmp_path / "TestFont.ufo" 76 with UFOWriter(ufo_path, formatVersion=3) as writer: 77 assert writer.formatVersionTuple == (3, 0) 78 79 shutil.rmtree(str(ufo_path)) 80 with UFOWriter(ufo_path, formatVersion=(2, 0)) as writer: 81 assert writer.formatVersionTuple == (2, 0) 82 83 84def test_UFOWriter_formatVersion_default_latest(tmp_path): 85 writer = UFOWriter(tmp_path / "TestFont.ufo") 86 assert writer.formatVersionTuple == UFOFormatVersion.default() 87 88 89def test_UFOWriter_unsupported_format_version(tmp_path): 90 with pytest.raises(UnsupportedUFOFormat): 91 UFOWriter(tmp_path, formatVersion=(123, 456)) 92 93 94def test_UFOWriter_previous_higher_format_version(ufo_path): 95 with pytest.raises( 96 UnsupportedUFOFormat, match="UFO located at this path is a higher version" 97 ): 98 UFOWriter(ufo_path, formatVersion=(2, 0)) 99