harfbuzz/test/subset/subset_test_suite.py

136 lines
3.8 KiB
Python

#!/usr/bin/env python3
import os
# A single test in a subset test suite. Identifies a font
# a subsetting profile, and a subset to be cut.
class Test:
def __init__(self, font_path, profile_path, subset, instance, options):
self.font_path = font_path
self.profile_path = profile_path
self.subset = subset
self.instance = instance
self.options = options
def unicodes(self):
import re
if self.subset == '*':
return self.subset[0]
elif self.subset == "no-unicodes":
return ""
elif re.match("^U\+", self.subset):
s = re.sub (r"U\+", "", self.subset)
return s
else:
return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
def instance_name(self):
if not self.instance:
return self.instance
else:
s = "." + self.instance.replace(':', '-')
return s
def get_profile_flags(self):
with open (self.profile_path, mode="r", encoding="utf-8") as f:
return f.read().splitlines()
def get_instance_flags(self):
if not self.instance:
return []
else:
return self.instance.split(',')
def get_font_name(self):
font_base_name = os.path.basename(self.font_path)
font_base_name_parts = os.path.splitext(font_base_name)
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
if self.unicodes() == "*":
return "%s.%s.retain-all-codepoint%s%s" % (font_base_name_parts[0],
profile_name,
self.instance_name(),
font_base_name_parts[1])
elif self.unicodes() == "":
return "%s.%s.no-unicodes%s%s" % (font_base_name_parts[0],
profile_name,
self.instance_name(),
font_base_name_parts[1])
else:
return "%s.%s.%s%s%s" % (font_base_name_parts[0],
profile_name,
self.unicodes(),
self.instance_name(),
font_base_name_parts[1])
def get_font_extension(self):
font_base_name = os.path.basename(self.font_path)
font_base_name_parts = os.path.splitext(font_base_name)
return font_base_name_parts[1]
# A group of tests to perform on the subsetter. Each test
# Identifies a font a subsetting profile, and a subset to be cut.
class SubsetTestSuite:
def __init__(self, test_path, definition):
self.test_path = test_path
self.fonts = []
self.profiles = []
self.subsets = []
self.instances = []
self.options = []
self._parse(definition)
def get_output_directory(self):
test_name = os.path.splitext(os.path.basename(self.test_path))[0]
data_dir = os.path.join(os.path.dirname(self.test_path), "..")
output_dir = os.path.normpath(os.path.join(data_dir, "expected", test_name))
if not os.path.exists(output_dir):
os.mkdir(output_dir)
if not os.path.isdir(output_dir):
raise Exception("%s is not a directory." % output_dir)
return output_dir
def tests(self):
for font in self.fonts:
font = os.path.join(self._base_path(), "fonts", font)
for profile in self.profiles:
profile = os.path.join(self._base_path(), "profiles", profile)
for subset in self.subsets:
if self.instances:
for instance in self.instances:
yield Test(font, profile, subset, instance, options=self.options)
else:
yield Test(font, profile, subset, "", options=self.options)
def _base_path(self):
return os.path.dirname(os.path.dirname(self.test_path))
def _parse(self, definition):
destinations = {
"FONTS:": self.fonts,
"PROFILES:": self.profiles,
"SUBSETS:": self.subsets,
"INSTANCES:": self.instances,
"OPTIONS:": self.options,
}
current_destination = None
for line in definition.splitlines():
line = line.strip()
if line.startswith("#"):
continue
if not line:
continue
if line in destinations:
current_destination = destinations[line]
elif current_destination is not None:
current_destination.append(line)
else:
raise Exception("Failed to parse test suite file.")