subset_test_suite.py 4.1 KB

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