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