ttx tests: add tests for Options, ttCompile, ttList, main
This commit is contained in:
parent
cf5b31e9c6
commit
1404624f3c
@ -1,14 +1,17 @@
|
|||||||
from __future__ import print_function, division, absolute_import
|
from __future__ import print_function, division, absolute_import
|
||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.misc.testTools import parseXML
|
from fontTools.misc.testTools import parseXML
|
||||||
|
from fontTools.misc.timeTools import timestampSinceEpoch
|
||||||
|
from fontTools.ttLib import TTFont, TTLibError
|
||||||
from fontTools import ttx
|
from fontTools import ttx
|
||||||
import getopt
|
import getopt
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
class TTXTest(unittest.TestCase):
|
class TTXTest(unittest.TestCase):
|
||||||
def __init__(self, methodName):
|
def __init__(self, methodName):
|
||||||
@ -263,5 +266,565 @@ class TTXTest(unittest.TestCase):
|
|||||||
self.assertIsNone(ttx.guessFileType(font_path))
|
self.assertIsNone(ttx.guessFileType(font_path))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
# -----------------------
|
||||||
sys.exit(unittest.main())
|
# ttx.Options class tests
|
||||||
|
# -----------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_defaults():
|
||||||
|
tto = ttx.Options([(None, None)], 1)
|
||||||
|
assert tto.listTables is False
|
||||||
|
assert tto.outputDir is None
|
||||||
|
assert tto.outputFile is None
|
||||||
|
assert tto.overWrite is False
|
||||||
|
assert tto.verbose is False
|
||||||
|
assert tto.quiet is False
|
||||||
|
assert tto.splitTables is False
|
||||||
|
assert tto.splitGlyphs is False
|
||||||
|
assert tto.disassembleInstructions is True
|
||||||
|
assert tto.mergeFile is None
|
||||||
|
assert tto.recalcBBoxes is True
|
||||||
|
assert tto.allowVID is False
|
||||||
|
assert tto.ignoreDecompileErrors is True
|
||||||
|
assert tto.bitmapGlyphDataFormat == "raw"
|
||||||
|
assert tto.unicodedata is None
|
||||||
|
assert tto.newlinestr is None
|
||||||
|
assert tto.recalcTimestamp is False
|
||||||
|
assert tto.flavor is None
|
||||||
|
assert tto.useZopfli is False
|
||||||
|
assert tto.onlyTables == []
|
||||||
|
assert tto.skipTables == []
|
||||||
|
assert tto.fontNumber == -1
|
||||||
|
assert tto.logLevel == logging.INFO
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_h(capsys):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
ttx.Options([("-h", None)], 1)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert "TTX -- From OpenType To XML And Back" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_version(capsys):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
ttx.Options([("--version", None)], 1)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
version_list = out.split(".")
|
||||||
|
assert len(version_list) >= 3
|
||||||
|
assert version_list[0].isdigit()
|
||||||
|
assert version_list[1].isdigit()
|
||||||
|
assert version_list[2].isdigit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_d_goodpath(tmpdir):
|
||||||
|
temp_dir_path = str(tmpdir)
|
||||||
|
tto = ttx.Options([("-d", temp_dir_path)], 1)
|
||||||
|
assert tto.outputDir == temp_dir_path
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_d_badpath():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-d", "bogusdir")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_o():
|
||||||
|
tto = ttx.Options([("-o", "testfile.ttx")], 1)
|
||||||
|
assert tto.outputFile == "testfile.ttx"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_f():
|
||||||
|
tto = ttx.Options([("-f", "")], 1)
|
||||||
|
assert tto.overWrite is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_v():
|
||||||
|
tto = ttx.Options([("-v", "")], 1)
|
||||||
|
assert tto.verbose is True
|
||||||
|
assert tto.logLevel == logging.DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_q():
|
||||||
|
tto = ttx.Options([("-q", "")], 1)
|
||||||
|
assert tto.quiet is True
|
||||||
|
assert tto.logLevel == logging.WARNING
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_l():
|
||||||
|
tto = ttx.Options([("-l", "")], 1)
|
||||||
|
assert tto.listTables is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_t_nopadding():
|
||||||
|
tto = ttx.Options([("-t", "CFF2")], 1)
|
||||||
|
assert len(tto.onlyTables) == 1
|
||||||
|
assert tto.onlyTables[0] == "CFF2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_t_withpadding():
|
||||||
|
tto = ttx.Options([("-t", "CFF")], 1)
|
||||||
|
assert len(tto.onlyTables) == 1
|
||||||
|
assert tto.onlyTables[0] == "CFF "
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_s():
|
||||||
|
tto = ttx.Options([("-s", "")], 1)
|
||||||
|
assert tto.splitTables is True
|
||||||
|
assert tto.splitGlyphs is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_g():
|
||||||
|
tto = ttx.Options([("-g", "")], 1)
|
||||||
|
assert tto.splitGlyphs is True
|
||||||
|
assert tto.splitTables is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_i():
|
||||||
|
tto = ttx.Options([("-i", "")], 1)
|
||||||
|
assert tto.disassembleInstructions is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_z_validoptions():
|
||||||
|
valid_options = ('raw', 'row', 'bitwise', 'extfile')
|
||||||
|
for option in valid_options:
|
||||||
|
tto = ttx.Options([("-z", option)], 1)
|
||||||
|
assert tto.bitmapGlyphDataFormat == option
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_z_invalidoption():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-z", "bogus")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_y_validvalue():
|
||||||
|
tto = ttx.Options([("-y", "1")], 1)
|
||||||
|
assert tto.fontNumber == 1
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: fix this with a check in the ttx module: str.isdigit()
|
||||||
|
def test_ttx_options_class_flag_y_invalidvalue():
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
ttx.Options([("-y", "A")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_m():
|
||||||
|
tto = ttx.Options([("-m", "testfont.ttf")], 1)
|
||||||
|
assert tto.mergeFile == "testfont.ttf"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_b():
|
||||||
|
tto = ttx.Options([("-b", "")], 1)
|
||||||
|
assert tto.recalcBBoxes is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_a():
|
||||||
|
tto = ttx.Options([("-a", "")], 1)
|
||||||
|
assert tto.allowVID is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_e():
|
||||||
|
tto = ttx.Options([("-e", "")], 1)
|
||||||
|
assert tto.ignoreDecompileErrors is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_unicodedata():
|
||||||
|
tto = ttx.Options([("--unicodedata", "UnicodeData.txt")], 1)
|
||||||
|
assert tto.unicodedata == "UnicodeData.txt"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_newline_lf():
|
||||||
|
tto = ttx.Options([("--newline", "LF")], 1)
|
||||||
|
assert tto.newlinestr == "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_newline_cr():
|
||||||
|
tto = ttx.Options([("--newline", "CR")], 1)
|
||||||
|
assert tto.newlinestr == "\r"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_newline_crlf():
|
||||||
|
tto = ttx.Options([("--newline", "CRLF")], 1)
|
||||||
|
assert tto.newlinestr == "\r\n"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_newline_invalid():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("--newline", "BOGUS")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_recalc_timestamp():
|
||||||
|
tto = ttx.Options([("--recalc-timestamp", "")], 1)
|
||||||
|
assert tto.recalcTimestamp is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_flavor():
|
||||||
|
tto = ttx.Options([("--flavor", "woff")], 1)
|
||||||
|
assert tto.flavor == "woff"
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_with_zopfli():
|
||||||
|
tto = ttx.Options([("--with-zopfli", ""), ("--flavor", "woff")], 1)
|
||||||
|
assert tto.useZopfli is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_with_zopfli_fails_without_woff_flavor():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("--with-zopfli", "")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_quiet_and_verbose_shouldfail():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-q", ""), ("-v", "")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_mergefile_and_flavor_shouldfail():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-m", "testfont.ttf"), ("--flavor", "woff")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_onlytables_and_skiptables_shouldfail():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-t", "CFF"), ("-x", "CFF2")], 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_mergefile_and_multiplefiles_shouldfail():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("-m", "testfont.ttf")], 2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_options_class_flag_woff2_and_zopfli_shouldfail():
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
ttx.Options([("--with-zopfli", ""), ("--flavor", "woff2")], 1)
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# ttx.ttCompile function tests
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_otf_compile_default(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestOTF.ttx")
|
||||||
|
outotf = os.path.join(str(tmpdir), "TestOTF.otf")
|
||||||
|
default_options = ttx.Options([("", "")], 1)
|
||||||
|
ttx.ttCompile(inttx, outotf, default_options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outotf) is True
|
||||||
|
# confirm that it is valid OTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outotf)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_otf_to_woff_without_zopfli(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestOTF.ttx")
|
||||||
|
outwoff = os.path.join(str(tmpdir), "TestOTF.woff")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff"
|
||||||
|
ttx.ttCompile(inttx, outwoff, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_otf_to_woff_with_zopfli(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestOTF.ttx")
|
||||||
|
outwoff = os.path.join(str(tmpdir), "TestOTF.woff")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff"
|
||||||
|
options.useZopfli = True
|
||||||
|
ttx.ttCompile(inttx, outwoff, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_otf_to_woff2(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestOTF.ttx")
|
||||||
|
outwoff2 = os.path.join(str(tmpdir), "TestTTF.woff2")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff2"
|
||||||
|
ttx.ttCompile(inttx, outwoff2, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff2) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff2)
|
||||||
|
# DSIG should not be included from original ttx as per woff2 spec (https://dev.w3.org/webfonts/WOFF2/spec/)
|
||||||
|
assert "DSIG" not in ttf
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_ttf_compile_default(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outttf = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
default_options = ttx.Options([("", "")], 1)
|
||||||
|
ttx.ttCompile(inttx, outttf, default_options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outttf) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outttf)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_ttf_to_woff_without_zopfli(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outwoff = os.path.join(str(tmpdir), "TestTTF.woff")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff"
|
||||||
|
ttx.ttCompile(inttx, outwoff, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_ttf_to_woff_with_zopfli(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outwoff = os.path.join(str(tmpdir), "TestTTF.woff")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff"
|
||||||
|
options.useZopfli = True
|
||||||
|
ttx.ttCompile(inttx, outwoff, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff)
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp", "DSIG")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_ttf_to_woff2(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outwoff2 = os.path.join(str(tmpdir), "TestTTF.woff2")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.flavor = "woff2"
|
||||||
|
ttx.ttCompile(inttx, outwoff2, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outwoff2) is True
|
||||||
|
# confirm that it is valid TTF file, can instantiate a TTFont, has expected OpenType tables
|
||||||
|
ttf = TTFont(outwoff2)
|
||||||
|
# DSIG should not be included from original ttx as per woff2 spec (https://dev.w3.org/webfonts/WOFF2/spec/)
|
||||||
|
assert "DSIG" not in ttf
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp")
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in ttf
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_ttf_timestamp_calcs(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outttf1 = os.path.join(str(tmpdir), "TestTTF1.ttf")
|
||||||
|
outttf2 = os.path.join(str(tmpdir), "TestTTF2.ttf")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
# build with default options = do not recalculate timestamp
|
||||||
|
ttx.ttCompile(inttx, outttf1, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outttf1) is True
|
||||||
|
# confirm that timestamp is same as modified time on ttx file
|
||||||
|
mtime = os.path.getmtime(inttx)
|
||||||
|
epochtime = timestampSinceEpoch(mtime)
|
||||||
|
ttf = TTFont(outttf1)
|
||||||
|
assert ttf['head'].modified == epochtime
|
||||||
|
|
||||||
|
# reset options to recalculate the timestamp and compile new font
|
||||||
|
options.recalcTimestamp = True
|
||||||
|
ttx.ttCompile(inttx, outttf2, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outttf2) is True
|
||||||
|
# confirm that timestamp is more recent than modified time on ttx file
|
||||||
|
mtime = os.path.getmtime(inttx)
|
||||||
|
epochtime = timestampSinceEpoch(mtime)
|
||||||
|
ttf = TTFont(outttf2)
|
||||||
|
assert ttf['head'].modified > epochtime
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttcompile_otf_timestamp_calcs(tmpdir):
|
||||||
|
inttx = os.path.join("Tests", "ttx", "data", "TestOTF.ttx")
|
||||||
|
outotf1 = os.path.join(str(tmpdir), "TestOTF1.ttf")
|
||||||
|
outotf2 = os.path.join(str(tmpdir), "TestOTF2.ttf")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
# build with default options = do not recalculate timestamp
|
||||||
|
ttx.ttCompile(inttx, outotf1, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outotf1) is True
|
||||||
|
# confirm that timestamp is same as modified time on ttx file
|
||||||
|
mtime = os.path.getmtime(inttx)
|
||||||
|
epochtime = timestampSinceEpoch(mtime)
|
||||||
|
ttf = TTFont(outotf1)
|
||||||
|
assert ttf['head'].modified == epochtime
|
||||||
|
|
||||||
|
# reset options to recalculate the timestamp and compile new font
|
||||||
|
options.recalcTimestamp = True
|
||||||
|
ttx.ttCompile(inttx, outotf2, options)
|
||||||
|
# confirm that font was built
|
||||||
|
assert os.path.isfile(outotf2) is True
|
||||||
|
# confirm that timestamp is more recent than modified time on ttx file
|
||||||
|
mtime = os.path.getmtime(inttx)
|
||||||
|
epochtime = timestampSinceEpoch(mtime)
|
||||||
|
ttf = TTFont(outotf2)
|
||||||
|
assert ttf['head'].modified > epochtime
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# ttx.ttList function tests
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
def test_ttx_ttlist_ttf(capsys, tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttf")
|
||||||
|
fakeoutpath = os.path.join(str(tmpdir), "TestTTF.ttx")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.listTables = True
|
||||||
|
ttx.ttList(inpath, fakeoutpath, options)
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp", "DSIG")
|
||||||
|
# confirm that expected tables are printed to stdout
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in out
|
||||||
|
# test for one of the expected tag/checksum/length/offset strings
|
||||||
|
assert "OS/2 0x67230FF8 96 376" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttlist_otf(capsys, tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestOTF.Otf")
|
||||||
|
fakeoutpath = os.path.join(str(tmpdir), "TestOTF.ttx")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.listTables = True
|
||||||
|
ttx.ttList(inpath, fakeoutpath, options)
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx", "DSIG")
|
||||||
|
# confirm that expected tables are printed to stdout
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in out
|
||||||
|
# test for one of the expected tag/checksum/length/offset strings
|
||||||
|
assert "OS/2 0x67230FF8 96 272" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttlist_woff(capsys, tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestWOFF.woff")
|
||||||
|
fakeoutpath = os.path.join(str(tmpdir), "TestWOFF.ttx")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.listTables = True
|
||||||
|
options.flavor = "woff"
|
||||||
|
ttx.ttList(inpath, fakeoutpath, options)
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF ", "hmtx", "DSIG")
|
||||||
|
# confirm that expected tables are printed to stdout
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in out
|
||||||
|
# test for one of the expected tag/checksum/length/offset strings
|
||||||
|
assert "OS/2 0x67230FF8 84 340" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_ttlist_woff2(capsys, tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestWOFF2.woff2")
|
||||||
|
fakeoutpath = os.path.join(str(tmpdir), "TestWOFF2.ttx")
|
||||||
|
options = ttx.Options([("", "")], 1)
|
||||||
|
options.listTables = True
|
||||||
|
options.flavor = "woff2"
|
||||||
|
ttx.ttList(inpath, fakeoutpath, options)
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
expected_tables = ("head", "hhea", "maxp", "OS/2", "name", "cmap", "hmtx", "fpgm", "prep", "cvt ", "loca", "glyf", "post", "gasp")
|
||||||
|
# confirm that expected tables are printed to stdout
|
||||||
|
for table in expected_tables:
|
||||||
|
assert table in out
|
||||||
|
# test for one of the expected tag/checksum/length/offset strings
|
||||||
|
assert "OS/2 0x67230FF8 96 0" in out
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
# main function tests
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_default_ttf_dump_to_ttx(tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttf")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttx")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
ttx.main(args)
|
||||||
|
assert os.path.isfile(outpath)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_default_ttx_compile_to_ttf(tmpdir):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
ttx.main(args)
|
||||||
|
assert os.path.isfile(outpath)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_getopterror_missing_directory():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
with pytest.raises(getopt.GetoptError):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttf")
|
||||||
|
args = ["-d", "bogusdir", inpath]
|
||||||
|
ttx.main(args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_keyboard_interrupt(tmpdir, monkeypatch, capsys):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
monkeypatch.setattr(ttx, 'process', (lambda x, y: raise_exception(KeyboardInterrupt)))
|
||||||
|
ttx.main(args)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert "(Cancelled.)" in err
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_system_exit(tmpdir, monkeypatch):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
monkeypatch.setattr(ttx, 'process', (lambda x, y: raise_exception(SystemExit)))
|
||||||
|
ttx.main(args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_ttlib_error(tmpdir, monkeypatch, capsys):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
monkeypatch.setattr(ttx, 'process', (lambda x, y: raise_exception(TTLibError("Test error"))))
|
||||||
|
ttx.main(args)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert "Test error" in err
|
||||||
|
|
||||||
|
|
||||||
|
def test_ttx_main_base_exception(tmpdir, monkeypatch, capsys):
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttx")
|
||||||
|
outpath = os.path.join(str(tmpdir), "TestTTF.ttf")
|
||||||
|
args = ["-o", outpath, inpath]
|
||||||
|
monkeypatch.setattr(ttx, 'process', (lambda x, y: raise_exception(Exception("Test error"))))
|
||||||
|
ttx.main(args)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert "Unhandled exception has occurred" in err
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# support functions for tests
|
||||||
|
# ---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def raise_exception(exception):
|
||||||
|
raise exception
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user