1 #!/usr/bin/python3
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright © 2018 Endless Mobile, Inc.
5 #
6 # SPDX-License-Identifier: LGPL-2.1-or-later
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 # MA 02110-1301 USA
22
23 """Integration tests for glib-mkenums utility."""
24
25 import collections
26 import os
27 import shutil
28 import subprocess
29 import sys
30 import tempfile
31 import textwrap
32 import unittest
33
34 import taptestrunner
35
36
37 Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
38
39
40 class ESC[4;38;5;81mTestMkenums(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
41 """Integration test for running glib-mkenums.
42
43 This can be run when installed or uninstalled. When uninstalled, it
44 requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set.
45
46 The idea with this test harness is to test the glib-mkenums utility, its
47 handling of command line arguments, its exit statuses, and its handling of
48 various C source codes. In future we could split the core glib-mkenums
49 parsing and generation code out into a library and unit test that, and
50 convert this test to just check command line behaviour.
51 """
52
53 # Track the cwd, we want to back out to that to clean up our tempdir
54 cwd = ""
55 rspfile = False
56
57 def setUp(self):
58 self.timeout_seconds = 10 # seconds per test
59 self.tmpdir = tempfile.TemporaryDirectory()
60 self.cwd = os.getcwd()
61 os.chdir(self.tmpdir.name)
62 print("tmpdir:", self.tmpdir.name)
63 if "G_TEST_BUILDDIR" in os.environ:
64 self.__mkenums = os.path.join(
65 os.environ["G_TEST_BUILDDIR"], "..", "glib-mkenums"
66 )
67 else:
68 self.__mkenums = shutil.which("glib-mkenums")
69 print("rspfile: {}, mkenums:".format(self.rspfile), self.__mkenums)
70
71 def tearDown(self):
72 os.chdir(self.cwd)
73 self.tmpdir.cleanup()
74
75 def _write_rspfile(self, argv):
76 import shlex
77
78 with tempfile.NamedTemporaryFile(
79 dir=self.tmpdir.name, mode="w", delete=False
80 ) as f:
81 contents = " ".join([shlex.quote(arg) for arg in argv])
82 print("Response file contains:", contents)
83 f.write(contents)
84 f.flush()
85 return f.name
86
87 def runMkenums(self, *args):
88 if self.rspfile:
89 rspfile = self._write_rspfile(args)
90 args = ["@" + rspfile]
91 argv = [self.__mkenums]
92
93 # shebang lines are not supported on native
94 # Windows consoles
95 if os.name == "nt":
96 argv.insert(0, sys.executable)
97
98 argv.extend(args)
99 print("Running:", argv)
100
101 env = os.environ.copy()
102 env["LC_ALL"] = "C.UTF-8"
103 env["G_DEBUG"] = "fatal-warnings"
104 print("Environment:", env)
105
106 # We want to ensure consistent line endings...
107 info = subprocess.run(
108 argv,
109 timeout=self.timeout_seconds,
110 stdout=subprocess.PIPE,
111 stderr=subprocess.PIPE,
112 env=env,
113 universal_newlines=True,
114 )
115 info.check_returncode()
116 out = info.stdout.strip()
117 err = info.stderr.strip()
118
119 # Known substitutions for standard boilerplate
120 subs = {
121 "standard_top_comment": "This file is generated by glib-mkenums, do not modify "
122 "it. This code is licensed under the same license as the "
123 "containing project. Note that it links to GLib, so must "
124 "comply with the LGPL linking clauses.",
125 "standard_bottom_comment": "Generated data ends here",
126 }
127
128 result = Result(info, out, err, subs)
129
130 print("Output:", result.out)
131 return result
132
133 def runMkenumsWithTemplate(self, template_contents, *args):
134 with tempfile.NamedTemporaryFile(
135 dir=self.tmpdir.name, suffix=".template", delete=False
136 ) as template_file:
137 # Write out the template.
138 template_file.write(template_contents.encode("utf-8"))
139 print(template_file.name + ":", template_contents)
140 template_file.flush()
141
142 return self.runMkenums("--template", template_file.name, *args)
143
144 def runMkenumsWithAllSubstitutions(self, *args):
145 """Run glib-mkenums with a template which outputs all substitutions."""
146 template_contents = """
147 /*** BEGIN file-header ***/
148 file-header
149 /*** END file-header ***/
150
151 /*** BEGIN file-production ***/
152 file-production
153 filename: @filename@
154 basename: @basename@
155 /*** END file-production ***/
156
157 /*** BEGIN enumeration-production ***/
158 enumeration-production
159 EnumName: @EnumName@
160 enum_name: @enum_name@
161 ENUMNAME: @ENUMNAME@
162 ENUMSHORT: @ENUMSHORT@
163 ENUMPREFIX: @ENUMPREFIX@
164 enumsince: @enumsince@
165 type: @type@
166 Type: @Type@
167 TYPE: @TYPE@
168 /*** END enumeration-production ***/
169
170 /*** BEGIN value-header ***/
171 value-header
172 EnumName: @EnumName@
173 enum_name: @enum_name@
174 ENUMNAME: @ENUMNAME@
175 ENUMSHORT: @ENUMSHORT@
176 ENUMPREFIX: @ENUMPREFIX@
177 enumsince: @enumsince@
178 type: @type@
179 Type: @Type@
180 TYPE: @TYPE@
181 /*** END value-header ***/
182
183 /*** BEGIN value-production ***/
184 value-production
185 VALUENAME: @VALUENAME@
186 valuenick: @valuenick@
187 valuenum: @valuenum@
188 type: @type@
189 Type: @Type@
190 TYPE: @TYPE@
191 /*** END value-production ***/
192
193 /*** BEGIN value-tail ***/
194 value-tail
195 EnumName: @EnumName@
196 enum_name: @enum_name@
197 ENUMNAME: @ENUMNAME@
198 ENUMSHORT: @ENUMSHORT@
199 ENUMPREFIX: @ENUMPREFIX@
200 enumsince: @enumsince@
201 type: @type@
202 Type: @Type@
203 TYPE: @TYPE@
204 /*** END value-tail ***/
205
206 /*** BEGIN comment ***/
207 comment
208 comment: @comment@
209 /*** END comment ***/
210
211 /*** BEGIN file-tail ***/
212 file-tail
213 /*** END file-tail ***/
214 """
215 return self.runMkenumsWithTemplate(template_contents, *args)
216
217 def runMkenumsWithHeader(self, h_contents, encoding="utf-8"):
218 with tempfile.NamedTemporaryFile(
219 dir=self.tmpdir.name, suffix=".h", delete=False
220 ) as h_file:
221 # Write out the header to be scanned.
222 h_file.write(h_contents.encode(encoding))
223 print(h_file.name + ":", h_contents)
224 h_file.flush()
225
226 # Run glib-mkenums with a template which outputs all substitutions.
227 result = self.runMkenumsWithAllSubstitutions(h_file.name)
228
229 # Known substitutions for generated filenames.
230 result.subs.update(
231 {"filename": h_file.name, "basename": os.path.basename(h_file.name)}
232 )
233
234 return result
235
236 def assertSingleEnum(
237 self,
238 result,
239 enum_name_camel,
240 enum_name_lower,
241 enum_name_upper,
242 enum_name_short,
243 enum_prefix,
244 enum_since,
245 type_lower,
246 type_camel,
247 type_upper,
248 value_name,
249 value_nick,
250 value_num,
251 ):
252 """Assert that out (from runMkenumsWithHeader()) contains a single
253 enum and value matching the given arguments."""
254 subs = dict(
255 {
256 "enum_name_camel": enum_name_camel,
257 "enum_name_lower": enum_name_lower,
258 "enum_name_upper": enum_name_upper,
259 "enum_name_short": enum_name_short,
260 "enum_prefix": enum_prefix,
261 "enum_since": enum_since,
262 "type_lower": type_lower,
263 "type_camel": type_camel,
264 "type_upper": type_upper,
265 "value_name": value_name,
266 "value_nick": value_nick,
267 "value_num": value_num,
268 },
269 **result.subs
270 )
271
272 self.assertEqual(
273 """
274 comment
275 comment: {standard_top_comment}
276
277
278 file-header
279 file-production
280 filename: {filename}
281 basename: {basename}
282 enumeration-production
283 EnumName: {enum_name_camel}
284 enum_name: {enum_name_lower}
285 ENUMNAME: {enum_name_upper}
286 ENUMSHORT: {enum_name_short}
287 ENUMPREFIX: {enum_prefix}
288 enumsince: {enum_since}
289 type: {type_lower}
290 Type: {type_camel}
291 TYPE: {type_upper}
292 value-header
293 EnumName: {enum_name_camel}
294 enum_name: {enum_name_lower}
295 ENUMNAME: {enum_name_upper}
296 ENUMSHORT: {enum_name_short}
297 ENUMPREFIX: {enum_prefix}
298 enumsince: {enum_since}
299 type: {type_lower}
300 Type: {type_camel}
301 TYPE: {type_upper}
302 value-production
303 VALUENAME: {value_name}
304 valuenick: {value_nick}
305 valuenum: {value_num}
306 type: {type_lower}
307 Type: {type_camel}
308 TYPE: {type_upper}
309 value-tail
310 EnumName: {enum_name_camel}
311 enum_name: {enum_name_lower}
312 ENUMNAME: {enum_name_upper}
313 ENUMSHORT: {enum_name_short}
314 ENUMPREFIX: {enum_prefix}
315 enumsince: {enum_since}
316 type: {type_lower}
317 Type: {type_camel}
318 TYPE: {type_upper}
319 file-tail
320
321 comment
322 comment: {standard_bottom_comment}
323 """.format(
324 **subs
325 ).strip(),
326 result.out,
327 )
328
329 def test_help(self):
330 """Test the --help argument."""
331 result = self.runMkenums("--help")
332 self.assertIn("usage: glib-mkenums", result.out)
333
334 def test_no_args(self):
335 """Test running with no arguments at all."""
336 result = self.runMkenums()
337 self.assertEqual("", result.err)
338 self.assertEqual(
339 """/* {standard_top_comment} */
340
341
342 /* {standard_bottom_comment} */""".format(
343 **result.subs
344 ),
345 result.out.strip(),
346 )
347
348 def test_empty_template(self):
349 """Test running with an empty template and no header files."""
350 result = self.runMkenumsWithTemplate("")
351 self.assertEqual("", result.err)
352 self.assertEqual(
353 """/* {standard_top_comment} */
354
355
356 /* {standard_bottom_comment} */""".format(
357 **result.subs
358 ),
359 result.out.strip(),
360 )
361
362 def test_no_headers(self):
363 """Test running with a complete template, but no header files."""
364 result = self.runMkenumsWithAllSubstitutions()
365 self.assertEqual("", result.err)
366 self.assertEqual(
367 """
368 comment
369 comment: {standard_top_comment}
370
371
372 file-header
373 file-tail
374
375 comment
376 comment: {standard_bottom_comment}
377 """.format(
378 **result.subs
379 ).strip(),
380 result.out,
381 )
382
383 def test_empty_header(self):
384 """Test an empty header."""
385 result = self.runMkenumsWithHeader("")
386 self.assertEqual("", result.err)
387 self.assertEqual(
388 """
389 comment
390 comment: {standard_top_comment}
391
392
393 file-header
394 file-tail
395
396 comment
397 comment: {standard_bottom_comment}
398 """.format(
399 **result.subs
400 ).strip(),
401 result.out,
402 )
403
404 def test_enum_name(self):
405 """Test typedefs with an enum and a typedef name. Bug #794506."""
406 h_contents = """
407 typedef enum _SomeEnumIdentifier {
408 ENUM_VALUE
409 } SomeEnumIdentifier;
410 """
411 result = self.runMkenumsWithHeader(h_contents)
412 self.assertEqual("", result.err)
413 self.assertSingleEnum(
414 result,
415 "SomeEnumIdentifier",
416 "some_enum_identifier",
417 "SOME_ENUM_IDENTIFIER",
418 "ENUM_IDENTIFIER",
419 "SOME",
420 "",
421 "enum",
422 "Enum",
423 "ENUM",
424 "ENUM_VALUE",
425 "value",
426 "0",
427 )
428
429 def test_non_utf8_encoding(self):
430 """Test source files with non-UTF-8 encoding. Bug #785113."""
431 h_contents = """
432 /* Copyright © La Peña */
433 typedef enum {
434 ENUM_VALUE
435 } SomeEnumIdentifier;
436 """
437 result = self.runMkenumsWithHeader(h_contents, encoding="iso-8859-1")
438 self.assertIn("WARNING: UnicodeWarning: ", result.err)
439 self.assertSingleEnum(
440 result,
441 "SomeEnumIdentifier",
442 "some_enum_identifier",
443 "SOME_ENUM_IDENTIFIER",
444 "ENUM_IDENTIFIER",
445 "SOME",
446 "",
447 "enum",
448 "Enum",
449 "ENUM",
450 "ENUM_VALUE",
451 "value",
452 "0",
453 )
454
455 def test_reproducible(self):
456 """Test builds are reproducible regardless of file ordering.
457 Bug #691436."""
458 template_contents = "template"
459
460 h_contents1 = """
461 typedef enum {
462 FIRST,
463 } Header1;
464 """
465
466 h_contents2 = """
467 typedef enum {
468 SECOND,
469 } Header2;
470 """
471
472 with tempfile.NamedTemporaryFile(
473 dir=self.tmpdir.name, suffix="1.h", delete=False
474 ) as h_file1, tempfile.NamedTemporaryFile(
475 dir=self.tmpdir.name, suffix="2.h", delete=False
476 ) as h_file2:
477 # Write out the headers.
478 h_file1.write(h_contents1.encode("utf-8"))
479 h_file2.write(h_contents2.encode("utf-8"))
480
481 h_file1.flush()
482 h_file2.flush()
483
484 # Run glib-mkenums with the headers in one order, and then again
485 # in another order.
486 result1 = self.runMkenumsWithTemplate(
487 template_contents, h_file1.name, h_file2.name
488 )
489 self.assertEqual("", result1.err)
490
491 result2 = self.runMkenumsWithTemplate(
492 template_contents, h_file2.name, h_file1.name
493 )
494 self.assertEqual("", result2.err)
495
496 # The output should be the same.
497 self.assertEqual(result1.out, result2.out)
498
499 def test_no_nick(self):
500 """Test trigraphs with a desc but no nick. Issue #1360."""
501 h_contents = """
502 typedef enum {
503 GEGL_SAMPLER_NEAREST = 0, /*< desc="nearest" >*/
504 } GeglSamplerType;
505 """
506 result = self.runMkenumsWithHeader(h_contents)
507 self.assertEqual("", result.err)
508 self.assertSingleEnum(
509 result,
510 "GeglSamplerType",
511 "gegl_sampler_type",
512 "GEGL_SAMPLER_TYPE",
513 "SAMPLER_TYPE",
514 "GEGL",
515 "",
516 "enum",
517 "Enum",
518 "ENUM",
519 "GEGL_SAMPLER_NEAREST",
520 "nearest",
521 "0",
522 )
523
524 def test_with_double_quotes(self):
525 """Test trigraphs with double-quoted expressions. Issue #65."""
526 h_contents = """
527 typedef enum {
528 FOO_VALUE /*< nick="eek, a comma" >*/
529 } Foo;
530 """
531 result = self.runMkenumsWithHeader(h_contents)
532 self.assertEqual("", result.err)
533 self.assertSingleEnum(
534 result,
535 "Foo",
536 "foo_",
537 "FOO_",
538 "",
539 "FOO",
540 "",
541 "enum",
542 "Enum",
543 "ENUM",
544 "FOO_VALUE",
545 "eek, a comma",
546 "0",
547 )
548
549 def test_filename_basename_in_fhead_ftail(self):
550 template_contents = """
551 /*** BEGIN file-header ***/
552 file-header
553 filename: @filename@
554 basename: @basename@
555 /*** END file-header ***/
556
557 /*** BEGIN comment ***/
558 comment
559 comment: @comment@
560 /*** END comment ***/
561
562 /*** BEGIN file-tail ***/
563 file-tail
564 filename: @filename@
565 basename: @basename@
566 /*** END file-tail ***/"""
567 result = self.runMkenumsWithTemplate(template_contents)
568 self.assertEqual(
569 textwrap.dedent(
570 """
571 WARNING: @filename@ used in file-header section.
572 WARNING: @basename@ used in file-header section.
573 WARNING: @filename@ used in file-tail section.
574 WARNING: @basename@ used in file-tail section.
575 """
576 ).strip(),
577 result.err,
578 )
579 self.assertEqual(
580 """
581 comment
582 comment: {standard_top_comment}
583
584
585 file-header
586 filename: @filename@
587 basename: @basename@
588 file-tail
589 filename: @filename@
590 basename: @basename@
591
592 comment
593 comment: {standard_bottom_comment}
594 """.format(
595 **result.subs
596 ).strip(),
597 result.out,
598 )
599
600 def test_since(self):
601 """Test user-provided 'since' version handling
602 https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1492"""
603 h_contents = """
604 typedef enum { /*< since=1.0 >*/
605 QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0,
606 } QmiWmsMessageProtocol;
607 """
608 result = self.runMkenumsWithHeader(h_contents)
609 self.assertEqual("", result.err)
610 self.assertSingleEnum(
611 result,
612 "QmiWmsMessageProtocol",
613 "qmi_wms_message_protocol",
614 "QMI_WMS_MESSAGE_PROTOCOL",
615 "WMS_MESSAGE_PROTOCOL",
616 "QMI",
617 "1.0",
618 "enum",
619 "Enum",
620 "ENUM",
621 "QMI_WMS_MESSAGE_PROTOCOL_CDMA",
622 "cdma",
623 "0",
624 )
625
626 def test_enum_private_public(self):
627 """Test private/public enums. Bug #782162."""
628 h_contents1 = """
629 typedef enum {
630 ENUM_VALUE_PUBLIC1,
631 /*< private >*/
632 ENUM_VALUE_PRIVATE,
633 } SomeEnumA
634 """
635
636 h_contents2 = """
637 typedef enum {
638 /*< private >*/
639 ENUM_VALUE_PRIVATE,
640 /*< public >*/
641 ENUM_VALUE_PUBLIC2,
642 } SomeEnumB;
643 """
644
645 result = self.runMkenumsWithHeader(h_contents1)
646 self.maxDiff = None
647 self.assertEqual("", result.err)
648 self.assertSingleEnum(
649 result,
650 "SomeEnumA",
651 "some_enum_a",
652 "SOME_ENUM_A",
653 "ENUM_A",
654 "SOME",
655 "",
656 "enum",
657 "Enum",
658 "ENUM",
659 "ENUM_VALUE_PUBLIC1",
660 "public1",
661 "0",
662 )
663 result = self.runMkenumsWithHeader(h_contents2)
664 self.assertEqual("", result.err)
665 self.assertSingleEnum(
666 result,
667 "SomeEnumB",
668 "some_enum_b",
669 "SOME_ENUM_B",
670 "ENUM_B",
671 "SOME",
672 "",
673 "enum",
674 "Enum",
675 "ENUM",
676 "ENUM_VALUE_PUBLIC2",
677 "public2",
678 "1",
679 )
680
681 def test_available_in(self):
682 """Test GLIB_AVAILABLE_ENUMERATOR_IN_2_68 handling
683 https://gitlab.gnome.org/GNOME/glib/-/issues/2327"""
684 h_contents = """
685 typedef enum {
686 G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = (1<<2)
687 } GDBusServerFlags;
688 """
689 result = self.runMkenumsWithHeader(h_contents)
690 self.assertEqual("", result.err)
691 self.assertSingleEnum(
692 result,
693 "GDBusServerFlags",
694 "g_dbus_server_flags",
695 "G_DBUS_SERVER_FLAGS",
696 "DBUS_SERVER_FLAGS",
697 "G",
698 "",
699 "flags",
700 "Flags",
701 "FLAGS",
702 "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER",
703 "user",
704 "4",
705 )
706
707 def test_deprecated_in(self):
708 """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68 handling
709 https://gitlab.gnome.org/GNOME/glib/-/issues/2327"""
710 h_contents = """
711 typedef enum {
712 G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_DEPRECATED_ENUMERATOR_IN_2_68 = (1<<2)
713 } GDBusServerFlags;
714 """
715 result = self.runMkenumsWithHeader(h_contents)
716 self.assertEqual("", result.err)
717 self.assertSingleEnum(
718 result,
719 "GDBusServerFlags",
720 "g_dbus_server_flags",
721 "G_DBUS_SERVER_FLAGS",
722 "DBUS_SERVER_FLAGS",
723 "G",
724 "",
725 "flags",
726 "Flags",
727 "FLAGS",
728 "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER",
729 "user",
730 "4",
731 )
732
733 def test_deprecated_in_for(self):
734 """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR() handling
735 https://gitlab.gnome.org/GNOME/glib/-/issues/2327"""
736 h_contents = """
737 typedef enum {
738 G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR(G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER2) = (1<<2)
739 } GDBusServerFlags;
740 """
741 result = self.runMkenumsWithHeader(h_contents)
742 self.assertEqual("", result.err)
743 self.assertSingleEnum(
744 result,
745 "GDBusServerFlags",
746 "g_dbus_server_flags",
747 "G_DBUS_SERVER_FLAGS",
748 "DBUS_SERVER_FLAGS",
749 "G",
750 "",
751 "flags",
752 "Flags",
753 "FLAGS",
754 "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER",
755 "user",
756 "4",
757 )
758
759 def test_enum_symbolic_expression(self):
760 """Test use of symbol in value expression."""
761 h_contents = """
762 typedef enum {
763 /*< private >*/
764 ENUM_VALUE_PRIVATE = 5,
765 /*< public >*/
766 ENUM_VALUE_PUBLIC = ENUM_VALUE_PRIVATE + 2,
767 } TestSymbolicEnum;
768 """
769
770 result = self.runMkenumsWithHeader(h_contents)
771 self.assertEqual("", result.err)
772 self.assertSingleEnum(
773 result,
774 "TestSymbolicEnum",
775 "test_symbolic_enum",
776 "TEST_SYMBOLIC_ENUM",
777 "SYMBOLIC_ENUM",
778 "TEST",
779 "",
780 "enum",
781 "Enum",
782 "ENUM",
783 "ENUM_VALUE_PUBLIC",
784 "public",
785 "7",
786 )
787
788 def test_comma_in_enum_value(self):
789 """Test use of comma in enum value."""
790 h_contents = """
791 typedef enum {
792 ENUM_VALUE_WITH_COMMA = ',',
793 } TestCommaEnum;
794 """
795
796 result = self.runMkenumsWithHeader(h_contents)
797 self.assertEqual("", result.err)
798 self.assertSingleEnum(
799 result,
800 "TestCommaEnum",
801 "test_comma_enum",
802 "TEST_COMMA_ENUM",
803 "COMMA_ENUM",
804 "TEST",
805 "",
806 "enum",
807 "Enum",
808 "ENUM",
809 "ENUM_VALUE_WITH_COMMA",
810 "comma",
811 44,
812 )
813
814
815 class ESC[4;38;5;81mTestRspMkenums(ESC[4;38;5;149mTestMkenums):
816 """Run all tests again in @rspfile mode"""
817
818 rspfile = True
819
820
821 if __name__ == "__main__":
822 unittest.main(testRunner=taptestrunner.TAPTestRunner())