run-tests.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/env python3
  2. import sys, os, subprocess, hashlib
  3. def shape_cmd(command):
  4. global hb_shape, process
  5. print (hb_shape + ' ' + " ".join(command))
  6. process.stdin.write ((';'.join (command) + '\n').encode ("utf-8"))
  7. process.stdin.flush ()
  8. return process.stdout.readline().decode ("utf-8").strip ()
  9. args = sys.argv[1:]
  10. have_freetype = int(os.getenv ('HAVE_FREETYPE', 1))
  11. have_coretext = int(os.getenv ('HAVE_CORETEXT', 0))
  12. have_directwrite = int(os.getenv ('HAVE_DIRECTWRITE', 0))
  13. have_uniscribe = int(os.getenv ('HAVE_UNISCRIBE', 0))
  14. if not args or args[0].find('hb-shape') == -1 or not os.path.exists (args[0]):
  15. sys.exit ("""First argument does not seem to point to usable hb-shape.""")
  16. hb_shape, args = args[0], args[1:]
  17. env = os.environ.copy()
  18. env['LC_ALL'] = 'C'
  19. process = subprocess.Popen ([hb_shape, '--batch'],
  20. stdin=subprocess.PIPE,
  21. stdout=subprocess.PIPE,
  22. stderr=sys.stdout,
  23. env=env)
  24. passes = 0
  25. fails = 0
  26. skips = 0
  27. if not len (args):
  28. args = ['-']
  29. for filename in args:
  30. if filename == '-':
  31. print ("Running tests from standard input")
  32. else:
  33. print ("Running tests in " + filename)
  34. if filename == '-':
  35. f = sys.stdin
  36. else:
  37. f = open (filename, encoding='utf8')
  38. for line in f:
  39. comment = False
  40. if line.startswith ("#"):
  41. comment = True
  42. line = line[1:]
  43. if line.startswith (' '):
  44. print ("#%s" % line)
  45. continue
  46. line = line.strip ()
  47. if not line:
  48. continue
  49. fontfile, options, unicodes, glyphs_expected = line.split (';')
  50. options = options.split ()
  51. if fontfile.startswith ('/') or fontfile.startswith ('"/'):
  52. if os.name == 'nt': # Skip on Windows
  53. continue
  54. fontfile, expected_hash = (fontfile.split('@') + [''])[:2]
  55. try:
  56. with open (fontfile, 'rb') as ff:
  57. if expected_hash:
  58. actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip ()
  59. if actual_hash != expected_hash:
  60. print ('different version of %s found; Expected hash %s, got %s; skipping.' %
  61. (fontfile, expected_hash, actual_hash))
  62. skips += 1
  63. continue
  64. except IOError:
  65. print ('%s not found, skip.' % fontfile)
  66. skips += 1
  67. continue
  68. else:
  69. cwd = os.path.dirname(filename)
  70. fontfile = os.path.normpath (os.path.join (cwd, fontfile))
  71. extra_options = ["--shaper=ot"]
  72. if glyphs_expected != '*':
  73. extra_options.append("--verify")
  74. extra_options.append("--unsafe-to-concat")
  75. if comment:
  76. print ('# %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes))
  77. continue
  78. if "--font-funcs=ft" in options and not have_freetype:
  79. skips += 1
  80. continue
  81. if "--shaper=coretext" in options and not have_coretext:
  82. skips += 1
  83. continue
  84. if "--shaper=directwrite" in options and not have_directwrite:
  85. skips += 1
  86. continue
  87. if "--shaper=uniscribe" in options and not have_uniscribe:
  88. skips += 1
  89. continue
  90. if "--font-funcs=ot" in options or not have_freetype:
  91. glyphs1 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options)
  92. else:
  93. glyphs1 = shape_cmd ([fontfile, "--font-funcs=ft"] + extra_options + ["--unicodes", unicodes] + options)
  94. glyphs2 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options)
  95. if glyphs1 != glyphs2 and glyphs_expected != '*':
  96. print ("FT funcs: " + glyphs1, file=sys.stderr)
  97. print ("OT funcs: " + glyphs2, file=sys.stderr)
  98. fails += 1
  99. else:
  100. passes += 1
  101. if glyphs1.strip() != glyphs_expected and glyphs_expected != '*':
  102. print ("hb-shape", fontfile, "--unicodes", unicodes, file=sys.stderr)
  103. print ("Actual: " + glyphs1, file=sys.stderr)
  104. print ("Expected: " + glyphs_expected, file=sys.stderr)
  105. fails += 1
  106. else:
  107. passes += 1
  108. print ("%d tests passed; %d failed; %d skipped." % (passes, fails, skips), file=sys.stderr)
  109. if not (fails + passes):
  110. print ("No tests ran.")
  111. elif not (fails + skips):
  112. print ("All tests passed.")
  113. if fails:
  114. sys.exit (1)
  115. elif passes:
  116. sys.exit (0)
  117. else:
  118. sys.exit (77)