Ebrahim Byagowi | 8d19907 | 2020-02-19 14:56:55 +0330 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Ebrahim Byagowi | cab2c2c | 2018-03-29 12:48:47 +0430 | [diff] [blame] | 2 | |
Ebrahim Byagowi | ba810ce | 2020-04-05 22:51:58 +0430 | [diff] [blame] | 3 | import sys, os, subprocess, hashlib |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 4 | |
Behdad Esfahbod | f3acb97 | 2021-08-10 11:05:40 -0600 | [diff] [blame] | 5 | def shape_cmd(command): |
| 6 | global hb_shape, process |
| 7 | print (hb_shape + ' ' + " ".join(command)) |
| 8 | process.stdin.write ((';'.join (command) + '\n').encode ("utf-8")) |
Ebrahim Byagowi | c4b6bad | 2020-07-02 18:07:01 +0430 | [diff] [blame] | 9 | process.stdin.flush () |
| 10 | return process.stdout.readline().decode ("utf-8").strip () |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 11 | |
Behdad Esfahbod | 504f913 | 2018-01-09 23:15:54 +0100 | [diff] [blame] | 12 | args = sys.argv[1:] |
Behdad Esfahbod | f928931 | 2018-10-31 18:25:05 -0700 | [diff] [blame] | 13 | |
Khaled Hosny | f76ffa8 | 2022-03-24 06:23:22 +0200 | [diff] [blame] | 14 | have_freetype = int(os.getenv ('HAVE_FREETYPE', 1)) |
| 15 | have_coretext = int(os.getenv ('HAVE_CORETEXT', 0)) |
| 16 | have_directwrite = int(os.getenv ('HAVE_DIRECTWRITE', 0)) |
| 17 | have_uniscribe = int(os.getenv ('HAVE_UNISCRIBE', 0)) |
Ebrahim Byagowi | 43e3ab0 | 2020-07-02 17:34:24 +0430 | [diff] [blame] | 18 | |
Behdad Esfahbod | f928931 | 2018-10-31 18:25:05 -0700 | [diff] [blame] | 19 | if not args or args[0].find('hb-shape') == -1 or not os.path.exists (args[0]): |
Ebrahim Byagowi | 7554f61 | 2020-05-28 22:51:29 +0430 | [diff] [blame] | 20 | sys.exit ("""First argument does not seem to point to usable hb-shape.""") |
Behdad Esfahbod | 504f913 | 2018-01-09 23:15:54 +0100 | [diff] [blame] | 21 | hb_shape, args = args[0], args[1:] |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 22 | |
Ebrahim Byagowi | c4b6bad | 2020-07-02 18:07:01 +0430 | [diff] [blame] | 23 | process = subprocess.Popen ([hb_shape, '--batch'], |
Behdad Esfahbod | 422debb | 2018-10-30 00:51:43 -0700 | [diff] [blame] | 24 | stdin=subprocess.PIPE, |
| 25 | stdout=subprocess.PIPE, |
Ebrahim Byagowi | c4b6bad | 2020-07-02 18:07:01 +0430 | [diff] [blame] | 26 | stderr=sys.stdout) |
Behdad Esfahbod | 422debb | 2018-10-30 00:51:43 -0700 | [diff] [blame] | 27 | |
Behdad Esfahbod | ea9512e | 2018-11-24 15:49:33 -0500 | [diff] [blame] | 28 | passes = 0 |
Ebrahim Byagowi | 4e3cf91 | 2018-01-01 11:17:51 +0330 | [diff] [blame] | 29 | fails = 0 |
Ebrahim Byagowi | 341851e | 2018-11-23 15:40:05 +0330 | [diff] [blame] | 30 | skips = 0 |
Ebrahim Byagowi | 4e3cf91 | 2018-01-01 11:17:51 +0330 | [diff] [blame] | 31 | |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 32 | if not len (args): |
Behdad Esfahbod | 44c65ee | 2018-01-09 21:58:57 +0100 | [diff] [blame] | 33 | args = ['-'] |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 34 | |
Behdad Esfahbod | 44c65ee | 2018-01-09 21:58:57 +0100 | [diff] [blame] | 35 | for filename in args: |
Khaled Hosny | 1fd3a26 | 2021-08-01 19:38:39 +0200 | [diff] [blame] | 36 | if filename == '-': |
| 37 | print ("Running tests from standard input") |
| 38 | else: |
| 39 | print ("Running tests in " + filename) |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 40 | |
Behdad Esfahbod | 44c65ee | 2018-01-09 21:58:57 +0100 | [diff] [blame] | 41 | if filename == '-': |
| 42 | f = sys.stdin |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 43 | else: |
Ebrahim Byagowi | 74fdd34 | 2020-03-14 20:03:14 +0330 | [diff] [blame] | 44 | f = open (filename, encoding='utf8') |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 45 | |
| 46 | for line in f: |
Behdad Esfahbod | ee3a3e1 | 2018-11-24 15:37:01 -0500 | [diff] [blame] | 47 | comment = False |
| 48 | if line.startswith ("#"): |
| 49 | comment = True |
| 50 | line = line[1:] |
| 51 | |
| 52 | if line.startswith (' '): |
Khaled Hosny | 1fd3a26 | 2021-08-01 19:38:39 +0200 | [diff] [blame] | 53 | print ("#%s" % line) |
Behdad Esfahbod | ee3a3e1 | 2018-11-24 15:37:01 -0500 | [diff] [blame] | 54 | continue |
| 55 | |
| 56 | line = line.strip () |
| 57 | if not line: |
| 58 | continue |
| 59 | |
Behdad Esfahbod | f3acb97 | 2021-08-10 11:05:40 -0600 | [diff] [blame] | 60 | fontfile, options, unicodes, glyphs_expected = line.split (';') |
Ebrahim Byagowi | 43e3ab0 | 2020-07-02 17:34:24 +0430 | [diff] [blame] | 61 | options = options.split () |
Ebrahim Byagowi | 341851e | 2018-11-23 15:40:05 +0330 | [diff] [blame] | 62 | if fontfile.startswith ('/') or fontfile.startswith ('"/'): |
Ebrahim Byagowi | 03564fd | 2020-03-14 20:09:00 +0330 | [diff] [blame] | 63 | if os.name == 'nt': # Skip on Windows |
Ebrahim Byagowi | 74fdd34 | 2020-03-14 20:03:14 +0330 | [diff] [blame] | 64 | continue |
| 65 | |
Behdad Esfahbod | d8ea552 | 2021-02-18 12:07:46 -0700 | [diff] [blame] | 66 | fontfile, expected_hash = (fontfile.split('@') + [''])[:2] |
Ebrahim Byagowi | 341851e | 2018-11-23 15:40:05 +0330 | [diff] [blame] | 67 | |
| 68 | try: |
| 69 | with open (fontfile, 'rb') as ff: |
Behdad Esfahbod | d8ea552 | 2021-02-18 12:07:46 -0700 | [diff] [blame] | 70 | if expected_hash: |
| 71 | actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip () |
| 72 | if actual_hash != expected_hash: |
| 73 | print ('different version of %s found; Expected hash %s, got %s; skipping.' % |
| 74 | (fontfile, expected_hash, actual_hash)) |
| 75 | skips += 1 |
| 76 | continue |
| 77 | except IOError: |
Behdad Esfahbod | ea9512e | 2018-11-24 15:49:33 -0500 | [diff] [blame] | 78 | print ('%s not found, skip.' % fontfile) |
| 79 | skips += 1 |
Ebrahim Byagowi | 341851e | 2018-11-23 15:40:05 +0330 | [diff] [blame] | 80 | continue |
| 81 | else: |
| 82 | cwd = os.path.dirname(filename) |
| 83 | fontfile = os.path.normpath (os.path.join (cwd, fontfile)) |
ebraminio | 20e69c9 | 2017-12-07 12:24:12 +0330 | [diff] [blame] | 84 | |
Behdad Esfahbod | 0abce58 | 2018-10-04 16:23:42 +0200 | [diff] [blame] | 85 | extra_options = ["--shaper=ot"] |
Behdad Esfahbod | 55468ca | 2018-10-04 12:13:55 +0200 | [diff] [blame] | 86 | if glyphs_expected != '*': |
| 87 | extra_options.append("--verify") |
Behdad Esfahbod | 33145a4 | 2022-05-31 04:59:07 -0600 | [diff] [blame] | 88 | extra_options.append("--unsafe-to-concat") |
Behdad Esfahbod | 55468ca | 2018-10-04 12:13:55 +0200 | [diff] [blame] | 89 | |
Behdad Esfahbod | ee3a3e1 | 2018-11-24 15:37:01 -0500 | [diff] [blame] | 90 | if comment: |
Khaled Hosny | 1fd3a26 | 2021-08-01 19:38:39 +0200 | [diff] [blame] | 91 | print ('# %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes)) |
ebraminio | 20e69c9 | 2017-12-07 12:24:12 +0330 | [diff] [blame] | 92 | continue |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 93 | |
Ebrahim Byagowi | 2013bab | 2020-07-06 11:57:45 +0430 | [diff] [blame] | 94 | if "--font-funcs=ft" in options and not have_freetype: |
Ebrahim Byagowi | 43e3ab0 | 2020-07-02 17:34:24 +0430 | [diff] [blame] | 95 | skips += 1 |
| 96 | continue |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 97 | |
Khaled Hosny | f76ffa8 | 2022-03-24 06:23:22 +0200 | [diff] [blame] | 98 | if "--shaper=coretext" in options and not have_coretext: |
| 99 | skips += 1 |
| 100 | continue |
| 101 | |
| 102 | if "--shaper=directwrite" in options and not have_directwrite: |
| 103 | skips += 1 |
| 104 | continue |
| 105 | |
| 106 | if "--shaper=uniscribe" in options and not have_uniscribe: |
| 107 | skips += 1 |
| 108 | continue |
| 109 | |
Ebrahim Byagowi | 2013bab | 2020-07-06 11:57:45 +0430 | [diff] [blame] | 110 | if "--font-funcs=ot" in options or not have_freetype: |
Behdad Esfahbod | f3acb97 | 2021-08-10 11:05:40 -0600 | [diff] [blame] | 111 | glyphs1 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options) |
Behdad Esfahbod | ea9512e | 2018-11-24 15:49:33 -0500 | [diff] [blame] | 112 | else: |
Behdad Esfahbod | f3acb97 | 2021-08-10 11:05:40 -0600 | [diff] [blame] | 113 | glyphs1 = shape_cmd ([fontfile, "--font-funcs=ft"] + extra_options + ["--unicodes", unicodes] + options) |
| 114 | glyphs2 = shape_cmd ([fontfile, "--font-funcs=ot"] + extra_options + ["--unicodes", unicodes] + options) |
Ebrahim Byagowi | 43e3ab0 | 2020-07-02 17:34:24 +0430 | [diff] [blame] | 115 | |
| 116 | if glyphs1 != glyphs2 and glyphs_expected != '*': |
| 117 | print ("FT funcs: " + glyphs1, file=sys.stderr) |
| 118 | print ("OT funcs: " + glyphs2, file=sys.stderr) |
| 119 | fails += 1 |
| 120 | else: |
| 121 | passes += 1 |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 122 | |
Ebrahim Byagowi | c4b6bad | 2020-07-02 18:07:01 +0430 | [diff] [blame] | 123 | if glyphs1.strip() != glyphs_expected and glyphs_expected != '*': |
Behdad Esfahbod | fc9e6ae | 2022-07-30 12:02:36 -0600 | [diff] [blame] | 124 | print ("hb-shape", fontfile, "--unicodes", unicodes, file=sys.stderr) |
Ebrahim Byagowi | c4b6bad | 2020-07-02 18:07:01 +0430 | [diff] [blame] | 125 | print ("Actual: " + glyphs1, file=sys.stderr) |
Ebrahim Byagowi | cd5580e | 2020-05-28 23:43:55 +0430 | [diff] [blame] | 126 | print ("Expected: " + glyphs_expected, file=sys.stderr) |
Behdad Esfahbod | ea9512e | 2018-11-24 15:49:33 -0500 | [diff] [blame] | 127 | fails += 1 |
| 128 | else: |
| 129 | passes += 1 |
ebraminio | 5f061d2 | 2017-12-07 11:22:55 +0330 | [diff] [blame] | 130 | |
Khaled Hosny | 1fd3a26 | 2021-08-01 19:38:39 +0200 | [diff] [blame] | 131 | print ("%d tests passed; %d failed; %d skipped." % (passes, fails, skips), file=sys.stderr) |
| 132 | if not (fails + passes): |
| 133 | print ("No tests ran.") |
| 134 | elif not (fails + skips): |
| 135 | print ("All tests passed.") |
Behdad Esfahbod | ea9512e | 2018-11-24 15:49:33 -0500 | [diff] [blame] | 136 | |
| 137 | if fails: |
| 138 | sys.exit (1) |
| 139 | elif passes: |
| 140 | sys.exit (0) |
| 141 | else: |
| 142 | sys.exit (77) |