3 # Runs a subsetting test suite. Compares the results of subsetting via harfbuz
4 # to subsetting via fonttools.
6 from __future__ import print_function, division, absolute_import
9 from difflib import unified_diff
16 from subset_test_suite import SubsetTestSuite
18 # https://stackoverflow.com/a/377028
21 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
23 fpath, _ = os.path.split(program)
28 for path in os.environ["PATH"].split(os.pathsep):
29 exe_file = os.path.join(path, program)
36 ots_sanitize = which ("ots-sanitize")
39 print("TTX is not present, skipping test.")
43 p = subprocess.Popen (
44 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
45 (stdoutdata, stderrdata) = p.communicate ()
46 print (stderrdata, end="") # file=sys.stderr
47 return stdoutdata, p.returncode
49 def read_binary (file_path):
50 with open (file_path, 'rb') as f:
53 def fail_test(test, cli_args, message):
54 print ('ERROR: %s' % message)
56 print (' test.font_path %s' % os.path.abspath (test.font_path))
57 print (' test.profile_path %s' % os.path.abspath (test.profile_path))
58 print (' test.unicodes %s' % test.unicodes ())
59 expected_file = os.path.join(test_suite.get_output_directory (),
60 test.get_font_name ())
61 print (' expected_file %s' % os.path.abspath (expected_file))
64 def run_test(test, should_check_ots):
65 out_file = os.path.join(tempfile.mkdtemp (), test.get_font_name () + '-subset' + test.get_font_extension ())
66 cli_args = [hb_subset,
67 "--font-file=" + test.font_path,
68 "--output-file=" + out_file,
69 "--unicodes=%s" % test.unicodes ()]
70 cli_args.extend (test.get_profile_flags ())
71 print (' '.join (cli_args))
72 _, return_code = cmd (cli_args)
75 return fail_test (test, cli_args, "%s returned %d" % (' '.join (cli_args), return_code))
77 expected_ttx, return_code = run_ttx (os.path.join (test_suite.get_output_directory (),
78 test.get_font_name ()))
80 return fail_test (test, cli_args, "ttx (expected) returned %d" % (return_code))
82 actual_ttx, return_code = run_ttx(out_file)
84 return fail_test (test, cli_args, "ttx (actual) returned %d" % (return_code))
86 print ("stripping checksums.")
87 expected_ttx = strip_check_sum (expected_ttx)
88 actual_ttx = strip_check_sum (actual_ttx)
90 if not actual_ttx == expected_ttx:
91 for line in unified_diff (expected_ttx.splitlines (1), actual_ttx.splitlines (1)):
92 sys.stdout.write (line)
94 return fail_test(test, cli_args, 'ttx for expected and actual does not match.')
97 print ("Checking output with ots-sanitize.")
98 if not check_ots (out_file):
99 return fail_test (test, cli_args, 'ots for subsetted file fails.')
104 print ("ttx %s" % file)
105 return cmd([ttx, "-q", "-o-", file])
107 def strip_check_sum (ttx_string):
108 return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
109 'checkSumAdjustment value="0x00000000"',
110 ttx_string.decode ("utf-8"), count=1)
114 print("OTS is not present, skipping all ots checks.")
118 def check_ots (path):
119 ots_report, returncode = cmd ([ots_sanitize, path])
121 print("OTS Failure: %s" % ots_report);
126 if not args or sys.argv[1].find('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
127 print ("First argument does not seem to point to usable hb-subset.")
129 hb_subset, args = args[0], args[1:]
132 print ("No tests supplied.")
139 with io.open (path, mode="r", encoding="utf-8") as f:
140 print ("Running tests in " + path)
141 test_suite = SubsetTestSuite (path, f.read())
142 for test in test_suite.tests ():
143 fails += run_test (test, has_ots)
146 print (str (fails) + " test(s) failed.")
149 print ("All tests passed.")