5e3368ed9a5979467abbe3b1acd7b70024623af3
[platform/upstream/harfbuzz.git] / test / subset / subset_test_suite.py
1 #!/usr/bin/env python
2
3 import io
4 import os
5
6 # A single test in a subset test suite. Identifies a font
7 # a subsetting profile, and a subset to be cut.
8 class 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.
41 class 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 Exception("%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.")