aboutsummaryrefslogtreecommitdiff
path: root/test/shape/run-tests.py
blob: 03f03df6c39c02764dd6e65a4ae7b22d64cfd443 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python3

import sys, os, subprocess, hashlib

def shape_cmd(command):
	global hb_shape, process
	print (hb_shape + ' ' + " ".join(command))
	process.stdin.write ((';'.join (command) + '\n').encode ("utf-8"))
	process.stdin.flush ()
	return process.stdout.readline().decode ("utf-8").strip ()

args = sys.argv[1:]

have_freetype = int(os.getenv ('HAVE_FREETYPE', 1))
have_coretext = int(os.getenv ('HAVE_CORETEXT', 0))
have_directwrite = int(os.getenv ('HAVE_DIRECTWRITE', 0))
have_uniscribe = int(os.getenv ('HAVE_UNISCRIBE', 0))

if not args or args[0].find('hb-shape') == -1 or not os.path.exists (args[0]):
	sys.exit ("""First argument does not seem to point to usable hb-shape.""")
hb_shape, args = args[0], args[1:]

process = subprocess.Popen ([hb_shape, '--batch'],
			    stdin=subprocess.PIPE,
			    stdout=subprocess.PIPE,
			    stderr=sys.stdout)

passes = 0
fails = 0
skips = 0

if not len (args):
	args = ['-']

for filename in args:
	if filename == '-':
		print ("Running tests from standard input")
	else:
		print ("Running tests in " + filename)

	if filename == '-':
		f = sys.stdin
	else:
		f = open (filename, encoding='utf8')

	for line in f:
		comment = False
		if line.startswith ("#"):
			comment = True
			line = line[1:]

			if line.startswith (' '):
				print ("#%s" % line)
				continue

		line = line.strip ()
		if not line:
			continue

		fontfile, options, unicodes, glyphs_expected = line.split (';')
		options = options.split ()
		if fontfile.startswith ('/') or fontfile.startswith ('"/'):
			if os.name == 'nt': # Skip on Windows
				continue

			fontfile, expected_hash = (fontfile.split('@') + [''])[:2]

			try:
				with open (fontfile, 'rb') as ff:
					if expected_hash:
						actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip ()
						if actual_hash != expected_hash:
							print ('different version of %s found; Expected hash %s, got %s; skipping.' %
								   (fontfile, expected_hash, actual_hash))
							skips += 1
							continue
			except IOError:
				print ('%s not found, skip.' % fontfile)
				skips += 1
				continue
		else:
			cwd = os.path.dirname(filename)
			fontfile = os.path.normpath (os.path.join (cwd, fontfile))

		extra_options = ["--shaper=ot"]
		if glyphs_expected != '*':
			extra_options.append("--verify")
			extra_options.append("--unsafe-to-concat")

		if comment:
			print ('# %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes))
			continue

		if "--font-funcs=ft" in options and not have_freetype:
			skips += 1
			continue

		if "--shaper=coretext" in options and not have_coretext:
			skips += 1
			continue

		if "--shaper=directwrite" in options and not have_directwrite:
			skips += 1
			continue

		if "--shaper=uniscribe" in options and not have_uniscribe:
			skips += 1
			continue

		if "--font-funcs=ot" in options or not have_freetype:
			glyphs1 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options)
		else:
			glyphs1 = shape_cmd ([fontfile, "--font-funcs=ft"] + extra_options + ["--unicodes", unicodes] + options)
			glyphs2 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options)

			if glyphs1 != glyphs2 and glyphs_expected != '*':
				print ("FT funcs: " + glyphs1, file=sys.stderr)
				print ("OT funcs: " + glyphs2, file=sys.stderr)
				fails += 1
			else:
				passes += 1

		if glyphs1.strip() != glyphs_expected and glyphs_expected != '*':
			print ("hb-shape", fontfile, "--unicodes", unicodes, file=sys.stderr)
			print ("Actual:   " + glyphs1, file=sys.stderr)
			print ("Expected: " + glyphs_expected, file=sys.stderr)
			fails += 1
		else:
			passes += 1

print ("%d tests passed; %d failed; %d skipped." % (passes, fails, skips), file=sys.stderr)
if not (fails + passes):
	print ("No tests ran.")
elif not (fails + skips):
	print ("All tests passed.")

if fails:
	sys.exit (1)
elif passes:
	sys.exit (0)
else:
	sys.exit (77)