diff --git a/Tests/ttx/ttx_test.py b/Tests/ttx/ttx_test.py index fcc0cc113..b0ad3d9bb 100644 --- a/Tests/ttx/ttx_test.py +++ b/Tests/ttx/ttx_test.py @@ -14,7 +14,9 @@ import unittest import pytest + class TTXTest(unittest.TestCase): + def __init__(self, methodName): unittest.TestCase.__init__(self, methodName) # Python 3 renamed assertRaisesRegexp to assertRaisesRegex, @@ -50,94 +52,129 @@ class TTXTest(unittest.TestCase): with open(file_path, "r", encoding="utf-8") as f: return f.readlines() -# ----- -# Tests -# ----- + # ----- + # Tests + # ----- def test_parseOptions_no_args(self): with self.assertRaises(getopt.GetoptError) as cm: ttx.parseOptions([]) - self.assertTrue('Must specify at least one input file' in str(cm.exception)) + self.assertTrue( + "Must specify at least one input file" in str(cm.exception) + ) def test_parseOptions_invalid_path(self): - file_path = 'invalid_font_path' + file_path = "invalid_font_path" with self.assertRaises(getopt.GetoptError) as cm: ttx.parseOptions([file_path]) self.assertTrue('File not found: "%s"' % file_path in str(cm.exception)) def test_parseOptions_font2ttx_1st_time(self): - file_name = 'TestOTF.otf' + file_name = "TestOTF.otf" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) jobs, _ = ttx.parseOptions([temp_path]) - self.assertEqual(jobs[0][0].__name__, 'ttDump') - self.assertEqual(jobs[0][1:], - (os.path.join(self.tempdir, file_name), - os.path.join(self.tempdir, file_name.split('.')[0] + '.ttx'))) + self.assertEqual(jobs[0][0].__name__, "ttDump") + self.assertEqual( + jobs[0][1:], + ( + os.path.join(self.tempdir, file_name), + os.path.join(self.tempdir, file_name.split(".")[0] + ".ttx"), + ), + ) def test_parseOptions_font2ttx_2nd_time(self): - file_name = 'TestTTF.ttf' + file_name = "TestTTF.ttf" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) - _, _ = ttx.parseOptions([temp_path]) # this is NOT a mistake + _, _ = ttx.parseOptions([temp_path]) # this is NOT a mistake jobs, _ = ttx.parseOptions([temp_path]) - self.assertEqual(jobs[0][0].__name__, 'ttDump') - self.assertEqual(jobs[0][1:], - (os.path.join(self.tempdir, file_name), - os.path.join(self.tempdir, file_name.split('.')[0] + '#1.ttx'))) + self.assertEqual(jobs[0][0].__name__, "ttDump") + self.assertEqual( + jobs[0][1:], + ( + os.path.join(self.tempdir, file_name), + os.path.join(self.tempdir, file_name.split(".")[0] + "#1.ttx"), + ), + ) def test_parseOptions_ttx2font_1st_time(self): - file_name = 'TestTTF.ttx' + file_name = "TestTTF.ttx" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) jobs, _ = ttx.parseOptions([temp_path]) - self.assertEqual(jobs[0][0].__name__, 'ttCompile') - self.assertEqual(jobs[0][1:], - (os.path.join(self.tempdir, file_name), - os.path.join(self.tempdir, file_name.split('.')[0] + '.ttf'))) + self.assertEqual(jobs[0][0].__name__, "ttCompile") + self.assertEqual( + jobs[0][1:], + ( + os.path.join(self.tempdir, file_name), + os.path.join(self.tempdir, file_name.split(".")[0] + ".ttf"), + ), + ) def test_parseOptions_ttx2font_2nd_time(self): - file_name = 'TestOTF.ttx' + file_name = "TestOTF.ttx" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) - _, _ = ttx.parseOptions([temp_path]) # this is NOT a mistake + _, _ = ttx.parseOptions([temp_path]) # this is NOT a mistake jobs, _ = ttx.parseOptions([temp_path]) - self.assertEqual(jobs[0][0].__name__, 'ttCompile') - self.assertEqual(jobs[0][1:], - (os.path.join(self.tempdir, file_name), - os.path.join(self.tempdir, file_name.split('.')[0] + '#1.otf'))) + self.assertEqual(jobs[0][0].__name__, "ttCompile") + self.assertEqual( + jobs[0][1:], + ( + os.path.join(self.tempdir, file_name), + os.path.join(self.tempdir, file_name.split(".")[0] + "#1.otf"), + ), + ) def test_parseOptions_multiple_fonts(self): - file_names = ['TestOTF.otf', 'TestTTF.ttf'] + file_names = ["TestOTF.otf", "TestTTF.ttf"] font_paths = [self.getpath(file_name) for file_name in file_names] - temp_paths = [self.temp_font(font_path, file_name) \ - for font_path, file_name in zip(font_paths, file_names)] + temp_paths = [ + self.temp_font(font_path, file_name) + for font_path, file_name in zip(font_paths, file_names) + ] jobs, _ = ttx.parseOptions(temp_paths) for i in range(len(jobs)): - self.assertEqual(jobs[i][0].__name__, 'ttDump') - self.assertEqual(jobs[i][1:], - (os.path.join(self.tempdir, file_names[i]), - os.path.join(self.tempdir, file_names[i].split('.')[0] + '.ttx'))) + self.assertEqual(jobs[i][0].__name__, "ttDump") + self.assertEqual( + jobs[i][1:], + ( + os.path.join(self.tempdir, file_names[i]), + os.path.join( + self.tempdir, file_names[i].split(".")[0] + ".ttx" + ), + ), + ) def test_parseOptions_mixed_files(self): - operations = ['ttDump', 'ttCompile'] - extensions = ['.ttx', '.ttf'] - file_names = ['TestOTF.otf', 'TestTTF.ttx'] + operations = ["ttDump", "ttCompile"] + extensions = [".ttx", ".ttf"] + file_names = ["TestOTF.otf", "TestTTF.ttx"] font_paths = [self.getpath(file_name) for file_name in file_names] - temp_paths = [self.temp_font(font_path, file_name) \ - for font_path, file_name in zip(font_paths, file_names)] + temp_paths = [ + self.temp_font(font_path, file_name) + for font_path, file_name in zip(font_paths, file_names) + ] jobs, _ = ttx.parseOptions(temp_paths) for i in range(len(jobs)): self.assertEqual(jobs[i][0].__name__, operations[i]) - self.assertEqual(jobs[i][1:], - (os.path.join(self.tempdir, file_names[i]), - os.path.join(self.tempdir, file_names[i].split('.')[0] + extensions[i]))) + self.assertEqual( + jobs[i][1:], + ( + os.path.join(self.tempdir, file_names[i]), + os.path.join( + self.tempdir, + file_names[i].split(".")[0] + extensions[i], + ), + ), + ) def test_parseOptions_splitTables(self): - file_name = 'TestTTF.ttf' + file_name = "TestTTF.ttf" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) - args = ['-s', temp_path] + args = ["-s", temp_path] jobs, options = ttx.parseOptions(args) @@ -159,15 +196,15 @@ class TTXTest(unittest.TestCase): continue # the tuple looks like this: # (u'head', {u'src': u'TestTTF._h_e_a_d.ttx'}, []) - table_file_name = item[1].get('src') + table_file_name = item[1].get("src") table_file_path = os.path.join(temp_folder, table_file_name) self.assertTrue(os.path.exists(table_file_path)) def test_parseOptions_splitGlyphs(self): - file_name = 'TestTTF.ttf' + file_name = "TestTTF.ttf" font_path = self.getpath(file_name) temp_path = self.temp_font(font_path, file_name) - args = ['-g', temp_path] + args = ["-g", temp_path] jobs, options = ttx.parseOptions(args) @@ -191,7 +228,7 @@ class TTXTest(unittest.TestCase): # the tuple looks like this: # (u'head', {u'src': u'TestTTF._h_e_a_d.ttx'}, []) table_tag = item[0] - table_file_name = item[1].get('src') + table_file_name = item[1].get("src") table_file_path = os.path.join(temp_folder, table_file_name) self.assertTrue(os.path.exists(table_file_path)) if table_tag != "glyf": @@ -201,69 +238,68 @@ class TTXTest(unittest.TestCase): if not isinstance(item, tuple): continue # glyphs without outline data only have 'name' attribute - glyph_file_name = item[1].get('src') + glyph_file_name = item[1].get("src") if glyph_file_name is not None: - glyph_file_path = os.path.join(temp_folder, - glyph_file_name) + glyph_file_path = os.path.join(temp_folder, glyph_file_name) self.assertTrue(os.path.exists(glyph_file_path)) def test_guessFileType_ttf(self): - file_name = 'TestTTF.ttf' + file_name = "TestTTF.ttf" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTF') + self.assertEqual(ttx.guessFileType(font_path), "TTF") def test_guessFileType_otf(self): - file_name = 'TestOTF.otf' + file_name = "TestOTF.otf" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'OTF') + self.assertEqual(ttx.guessFileType(font_path), "OTF") def test_guessFileType_woff(self): - file_name = 'TestWOFF.woff' + file_name = "TestWOFF.woff" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'WOFF') + self.assertEqual(ttx.guessFileType(font_path), "WOFF") def test_guessFileType_woff2(self): - file_name = 'TestWOFF2.woff2' + file_name = "TestWOFF2.woff2" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'WOFF2') + self.assertEqual(ttx.guessFileType(font_path), "WOFF2") def test_guessFileType_ttc(self): - file_name = 'TestTTC.ttc' + file_name = "TestTTC.ttc" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTC') + self.assertEqual(ttx.guessFileType(font_path), "TTC") def test_guessFileType_dfont(self): - file_name = 'TestDFONT.dfont' + file_name = "TestDFONT.dfont" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTF') + self.assertEqual(ttx.guessFileType(font_path), "TTF") def test_guessFileType_ttx_ttf(self): - file_name = 'TestTTF.ttx' + file_name = "TestTTF.ttx" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTX') + self.assertEqual(ttx.guessFileType(font_path), "TTX") def test_guessFileType_ttx_otf(self): - file_name = 'TestOTF.ttx' + file_name = "TestOTF.ttx" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'OTX') + self.assertEqual(ttx.guessFileType(font_path), "OTX") def test_guessFileType_ttx_bom(self): - file_name = 'TestBOM.ttx' + file_name = "TestBOM.ttx" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTX') + self.assertEqual(ttx.guessFileType(font_path), "TTX") def test_guessFileType_ttx_no_sfntVersion(self): - file_name = 'TestNoSFNT.ttx' + file_name = "TestNoSFNT.ttx" font_path = self.getpath(file_name) - self.assertEqual(ttx.guessFileType(font_path), 'TTX') + self.assertEqual(ttx.guessFileType(font_path), "TTX") def test_guessFileType_ttx_no_xml(self): - file_name = 'TestNoXML.ttx' + file_name = "TestNoXML.ttx" font_path = self.getpath(file_name) self.assertIsNone(ttx.guessFileType(font_path)) def test_guessFileType_invalid_path(self): - font_path = 'invalid_font_path' + font_path = "invalid_font_path" self.assertIsNone(ttx.guessFileType(font_path)) @@ -272,34 +308,7 @@ class TTXTest(unittest.TestCase): # ----------------------- -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): +def test_options_flag_h(capsys): with pytest.raises(SystemExit): ttx.Options([("-h", None)], 1) @@ -307,7 +316,7 @@ def test_ttx_options_class_flag_h(capsys): assert "TTX -- From OpenType To XML And Back" in out -def test_ttx_options_class_flag_version(capsys): +def test_options_flag_version(capsys): with pytest.raises(SystemExit): ttx.Options([("--version", None)], 1) @@ -319,328 +328,435 @@ def test_ttx_options_class_flag_version(capsys): assert version_list[2].isdigit() -def test_ttx_options_class_flag_d_goodpath(tmpdir): +def test_options_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(): +def test_options_d_badpath(): with pytest.raises(getopt.GetoptError): ttx.Options([("-d", "bogusdir")], 1) -def test_ttx_options_class_flag_o(): +def test_options_o(): tto = ttx.Options([("-o", "testfile.ttx")], 1) assert tto.outputFile == "testfile.ttx" -def test_ttx_options_class_flag_f(): +def test_options_f(): tto = ttx.Options([("-f", "")], 1) assert tto.overWrite is True -def test_ttx_options_class_flag_v(): +def test_options_v(): tto = ttx.Options([("-v", "")], 1) assert tto.verbose is True assert tto.logLevel == logging.DEBUG -def test_ttx_options_class_flag_q(): +def test_options_q(): tto = ttx.Options([("-q", "")], 1) assert tto.quiet is True assert tto.logLevel == logging.WARNING -def test_ttx_options_class_flag_l(): +def test_options_l(): tto = ttx.Options([("-l", "")], 1) assert tto.listTables is True -def test_ttx_options_class_flag_t_nopadding(): +def test_options_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(): +def test_options_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(): +def test_options_s(): tto = ttx.Options([("-s", "")], 1) assert tto.splitTables is True assert tto.splitGlyphs is False -def test_ttx_options_class_flag_g(): +def test_options_g(): tto = ttx.Options([("-g", "")], 1) assert tto.splitGlyphs is True assert tto.splitTables is True -def test_ttx_options_class_flag_i(): +def test_options_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') +def test_options_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(): +def test_options_z_invalidoption(): with pytest.raises(getopt.GetoptError): ttx.Options([("-z", "bogus")], 1) -def test_ttx_options_class_flag_y_validvalue(): +def test_options_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(): +def test_options_y_invalidvalue(): with pytest.raises(ValueError): ttx.Options([("-y", "A")], 1) -def test_ttx_options_class_flag_m(): +def test_options_m(): tto = ttx.Options([("-m", "testfont.ttf")], 1) assert tto.mergeFile == "testfont.ttf" -def test_ttx_options_class_flag_b(): +def test_options_b(): tto = ttx.Options([("-b", "")], 1) assert tto.recalcBBoxes is False -def test_ttx_options_class_flag_a(): +def test_options_a(): tto = ttx.Options([("-a", "")], 1) assert tto.allowVID is True -def test_ttx_options_class_flag_e(): +def test_options_e(): tto = ttx.Options([("-e", "")], 1) assert tto.ignoreDecompileErrors is False -def test_ttx_options_class_flag_unicodedata(): +def test_options_unicodedata(): tto = ttx.Options([("--unicodedata", "UnicodeData.txt")], 1) assert tto.unicodedata == "UnicodeData.txt" -def test_ttx_options_class_flag_newline_lf(): +def test_options_newline_lf(): tto = ttx.Options([("--newline", "LF")], 1) assert tto.newlinestr == "\n" -def test_ttx_options_class_flag_newline_cr(): +def test_options_newline_cr(): tto = ttx.Options([("--newline", "CR")], 1) assert tto.newlinestr == "\r" -def test_ttx_options_class_flag_newline_crlf(): +def test_options_newline_crlf(): tto = ttx.Options([("--newline", "CRLF")], 1) assert tto.newlinestr == "\r\n" -def test_ttx_options_class_flag_newline_invalid(): +def test_options_newline_invalid(): with pytest.raises(getopt.GetoptError): ttx.Options([("--newline", "BOGUS")], 1) -def test_ttx_options_class_flag_recalc_timestamp(): +def test_options_recalc_timestamp(): tto = ttx.Options([("--recalc-timestamp", "")], 1) assert tto.recalcTimestamp is True -def test_ttx_options_class_flag_flavor(): +def test_options_flavor(): tto = ttx.Options([("--flavor", "woff")], 1) assert tto.flavor == "woff" -def test_ttx_options_class_flag_with_zopfli(): +def test_options_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(): +def test_options_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(): +def test_options_quiet_and_verbose_shouldfail(): with pytest.raises(getopt.GetoptError): ttx.Options([("-q", ""), ("-v", "")], 1) -def test_ttx_options_class_flag_mergefile_and_flavor_shouldfail(): +def test_options_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(): +def test_options_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(): +def test_options_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(): +def test_options_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): +def test_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) + default_options = ttx.Options([], 1) ttx.ttCompile(inttx, outotf, default_options) # confirm that font was built - assert os.path.isfile(outotf) is True + assert os.path.isfile(outotf) # 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") + 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): +def test_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 = ttx.Options([], 1) options.flavor = "woff" ttx.ttCompile(inttx, outwoff, options) # confirm that font was built - assert os.path.isfile(outwoff) is True + assert os.path.isfile(outwoff) # 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") + 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): +def test_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 = 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 + assert os.path.isfile(outwoff) # 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") + 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): +def test_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 = ttx.Options([], 1) options.flavor = "woff2" ttx.ttCompile(inttx, outwoff2, options) # confirm that font was built - assert os.path.isfile(outwoff2) is True + assert os.path.isfile(outwoff2) # 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") + 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): +def test_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) + default_options = ttx.Options([], 1) ttx.ttCompile(inttx, outttf, default_options) # confirm that font was built - assert os.path.isfile(outttf) is True + assert os.path.isfile(outttf) # 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") + 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): +def test_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 = ttx.Options([], 1) options.flavor = "woff" ttx.ttCompile(inttx, outwoff, options) # confirm that font was built - assert os.path.isfile(outwoff) is True + assert os.path.isfile(outwoff) # 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") + 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): +def test_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 = 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 + assert os.path.isfile(outwoff) # 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") + 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): +def test_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 = ttx.Options([], 1) options.flavor = "woff2" ttx.ttCompile(inttx, outwoff2, options) # confirm that font was built - assert os.path.isfile(outwoff2) is True + assert os.path.isfile(outwoff2) # 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") + 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): +# TODO: convert to pytest parametrize for this and the next test +def test_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) + 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 + assert os.path.isfile(outttf1) # 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 + assert ttf["head"].modified == epochtime # reset options to recalculate the timestamp and compile new font options.recalcTimestamp = True @@ -651,23 +767,23 @@ def test_ttx_ttcompile_ttf_timestamp_calcs(tmpdir): mtime = os.path.getmtime(inttx) epochtime = timestampSinceEpoch(mtime) ttf = TTFont(outttf2) - assert ttf['head'].modified > epochtime + assert ttf["head"].modified > epochtime -def test_ttx_ttcompile_otf_timestamp_calcs(tmpdir): +def test_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) + 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 + assert os.path.isfile(outotf1) # 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 + assert ttf["head"].modified == epochtime # reset options to recalculate the timestamp and compile new font options.recalcTimestamp = True @@ -678,21 +794,38 @@ def test_ttx_ttcompile_otf_timestamp_calcs(tmpdir): mtime = os.path.getmtime(inttx) epochtime = timestampSinceEpoch(mtime) ttf = TTFont(outotf2) - assert ttf['head'].modified > epochtime + assert ttf["head"].modified > epochtime # ------------------------- # ttx.ttList function tests # ------------------------- -def test_ttx_ttlist_ttf(capsys, tmpdir): + +def test_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 = 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") + 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 @@ -700,14 +833,25 @@ def test_ttx_ttlist_ttf(capsys, tmpdir): assert "OS/2 0x67230FF8 96 376" in out -def test_ttx_ttlist_otf(capsys, tmpdir): +def test_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 = 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") + 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 @@ -715,15 +859,26 @@ def test_ttx_ttlist_otf(capsys, tmpdir): assert "OS/2 0x67230FF8 96 272" in out -def test_ttx_ttlist_woff(capsys, tmpdir): +def test_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 = 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") + 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 @@ -731,27 +886,43 @@ def test_ttx_ttlist_woff(capsys, tmpdir): assert "OS/2 0x67230FF8 84 340" in out -def test_ttx_ttlist_woff2(capsys, tmpdir): +def test_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 = 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") + 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): +def test_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] @@ -759,7 +930,7 @@ def test_ttx_main_default_ttf_dump_to_ttx(tmpdir): assert os.path.isfile(outpath) -def test_ttx_main_default_ttx_compile_to_ttf(tmpdir): +def test_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] @@ -767,7 +938,7 @@ def test_ttx_main_default_ttx_compile_to_ttf(tmpdir): assert os.path.isfile(outpath) -def test_ttx_main_getopterror_missing_directory(): +def test_main_getopterror_missing_directory(): with pytest.raises(SystemExit): with pytest.raises(getopt.GetoptError): inpath = os.path.join("Tests", "ttx", "data", "TestTTF.ttf") @@ -775,54 +946,71 @@ def test_ttx_main_getopterror_missing_directory(): ttx.main(args) -def test_ttx_main_keyboard_interrupt(tmpdir, monkeypatch, capsys): +def test_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))) + monkeypatch.setattr( + ttx, "process", (lambda x, y: raise_exception(KeyboardInterrupt)) + ) ttx.main(args) out, err = capsys.readouterr() assert "(Cancelled.)" in err -@pytest.mark.skipif(sys.platform == "win32", - reason="waitForKeyPress function causes test to hang on Windows platform") -def test_ttx_main_system_exit(tmpdir, monkeypatch): +@pytest.mark.skipif( + sys.platform == "win32", + reason="waitForKeyPress function causes test to hang on Windows platform", +) +def test_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))) + monkeypatch.setattr( + ttx, "process", (lambda x, y: raise_exception(SystemExit)) + ) ttx.main(args) -def test_ttx_main_ttlib_error(tmpdir, monkeypatch, capsys): +def test_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")))) + monkeypatch.setattr( + ttx, + "process", + (lambda x, y: raise_exception(TTLibError("Test error"))), + ) ttx.main(args) out, err = capsys.readouterr() assert "Test error" in err -@pytest.mark.skipif(sys.platform == "win32", - reason="waitForKeyPress function causes test to hang on Windows platform") -def test_ttx_main_base_exception(tmpdir, monkeypatch, capsys): +@pytest.mark.skipif( + sys.platform == "win32", + reason="waitForKeyPress function causes test to hang on Windows platform", +) +def test_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")))) + 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 # --------------------------- @@ -830,6 +1018,3 @@ def test_ttx_main_base_exception(tmpdir, monkeypatch, capsys): def raise_exception(exception): raise exception - - -