1#!/usr/local/bin/python3.8
2
3import os
4
5# A single test in a subset test suite. Identifies a font
6# a subsetting profile, and a subset to be cut.
7class Test:
8	def __init__(self, font_path, profile_path, subset):
9		self.font_path = font_path
10		self.profile_path = profile_path
11		self.subset = subset
12
13	def unicodes(self):
14		import re
15		if self.subset == '*':
16			return self.subset[0]
17		elif re.match("^U\+", self.subset):
18			s = re.sub (r"U\+", "", self.subset)
19			return s
20		else:
21			return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
22
23	def get_profile_flags(self):
24		with open (self.profile_path, mode="r", encoding="utf-8") as f:
25		    return f.read().splitlines()
26
27	def get_font_name(self):
28		font_base_name = os.path.basename(self.font_path)
29		font_base_name_parts = os.path.splitext(font_base_name)
30		profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
31
32		if self.unicodes() == "*":
33			return "%s.%s.retain-all-codepoint%s" % (font_base_name_parts[0],
34				       profile_name,
35				       font_base_name_parts[1])
36		else:
37			return "%s.%s.%s%s" % (font_base_name_parts[0],
38				       profile_name,
39				       self.unicodes(),
40				       font_base_name_parts[1])
41
42	def get_font_extension(self):
43		font_base_name = os.path.basename(self.font_path)
44		font_base_name_parts = os.path.splitext(font_base_name)
45		return font_base_name_parts[1]
46
47# A group of tests to perform on the subsetter. Each test
48# Identifies a font a subsetting profile, and a subset to be cut.
49class SubsetTestSuite:
50
51	def __init__(self, test_path, definition):
52		self.test_path = test_path
53		self.fonts = []
54		self.profiles = []
55		self.subsets = []
56		self._parse(definition)
57
58	def get_output_directory(self):
59		test_name = os.path.splitext(os.path.basename(self.test_path))[0]
60		data_dir = os.path.join(os.path.dirname(self.test_path), "..")
61
62		output_dir = os.path.normpath(os.path.join(data_dir, "expected", test_name))
63		if not os.path.exists(output_dir):
64			os.mkdir(output_dir)
65		if not os.path.isdir(output_dir):
66			raise Exception("%s is not a directory." % output_dir)
67
68		return output_dir
69
70	def tests(self):
71		for font in self.fonts:
72			font = os.path.join(self._base_path(), "fonts", font)
73			for profile in self.profiles:
74				profile = os.path.join(self._base_path(), "profiles", profile)
75				for subset in self.subsets:
76					yield Test(font, profile, subset)
77
78	def _base_path(self):
79		return os.path.dirname(os.path.dirname(self.test_path))
80
81	def _parse(self, definition):
82		destinations = {
83				"FONTS:": self.fonts,
84				"PROFILES:": self.profiles,
85				"SUBSETS:": self.subsets
86		}
87
88		current_destination = None
89		for line in definition.splitlines():
90			line = line.strip()
91
92			if line.startswith("#"):
93				continue
94
95			if not line:
96				continue
97
98			if line in destinations:
99				current_destination = destinations[line]
100			elif current_destination is not None:
101				current_destination.append(line)
102			else:
103				raise Exception("Failed to parse test suite file.")
104