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