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