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