| #!/usr/bin/python3 | |
| # -*- coding: utf-8 -*- | |
| # | |
| # Copyright © 2018 Endless Mobile, Inc. | |
| # | |
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # | |
| # This library is free software; you can redistribute it and/or | |
| # modify it under the terms of the GNU Lesser General Public | |
| # License as published by the Free Software Foundation; either | |
| # version 2.1 of the License, or (at your option) any later version. | |
| # | |
| # This library is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| # Lesser General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU Lesser General Public | |
| # License along with this library; if not, write to the Free Software | |
| # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| # MA 02110-1301 USA | |
| """Integration tests for glib-mkenums utility.""" | |
| import collections | |
| import os | |
| import shutil | |
| import subprocess | |
| import sys | |
| import tempfile | |
| import textwrap | |
| import unittest | |
| import taptestrunner | |
| Result = collections.namedtuple("Result", ("info", "out", "err", "subs")) | |
| class TestMkenums(unittest.TestCase): | |
| """Integration test for running glib-mkenums. | |
| This can be run when installed or uninstalled. When uninstalled, it | |
| requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set. | |
| The idea with this test harness is to test the glib-mkenums utility, its | |
| handling of command line arguments, its exit statuses, and its handling of | |
| various C source codes. In future we could split the core glib-mkenums | |
| parsing and generation code out into a library and unit test that, and | |
| convert this test to just check command line behaviour. | |
| """ | |
| # Track the cwd, we want to back out to that to clean up our tempdir | |
| cwd = "" | |
| rspfile = False | |
| def setUp(self): | |
| self.timeout_seconds = 10 # seconds per test | |
| self.tmpdir = tempfile.TemporaryDirectory() | |
| self.cwd = os.getcwd() | |
| os.chdir(self.tmpdir.name) | |
| print("tmpdir:", self.tmpdir.name) | |
| if "G_TEST_BUILDDIR" in os.environ: | |
| self.__mkenums = os.path.join( | |
| os.environ["G_TEST_BUILDDIR"], "..", "glib-mkenums" | |
| ) | |
| else: | |
| self.__mkenums = shutil.which("glib-mkenums") | |
| print("rspfile: {}, mkenums:".format(self.rspfile), self.__mkenums) | |
| def tearDown(self): | |
| os.chdir(self.cwd) | |
| self.tmpdir.cleanup() | |
| def _write_rspfile(self, argv): | |
| import shlex | |
| with tempfile.NamedTemporaryFile( | |
| dir=self.tmpdir.name, mode="w", delete=False | |
| ) as f: | |
| contents = " ".join([shlex.quote(arg) for arg in argv]) | |
| print("Response file contains:", contents) | |
| f.write(contents) | |
| f.flush() | |
| return f.name | |
| def runMkenums(self, *args): | |
| if self.rspfile: | |
| rspfile = self._write_rspfile(args) | |
| args = ["@" + rspfile] | |
| argv = [self.__mkenums] | |
| # shebang lines are not supported on native | |
| # Windows consoles | |
| if os.name == "nt": | |
| argv.insert(0, sys.executable) | |
| argv.extend(args) | |
| print("Running:", argv) | |
| env = os.environ.copy() | |
| env["LC_ALL"] = "C.UTF-8" | |
| env["G_DEBUG"] = "fatal-warnings" | |
| print("Environment:", env) | |
| # We want to ensure consistent line endings... | |
| info = subprocess.run( | |
| argv, | |
| timeout=self.timeout_seconds, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE, | |
| env=env, | |
| universal_newlines=True, | |
| ) | |
| info.check_returncode() | |
| out = info.stdout.strip() | |
| err = info.stderr.strip() | |
| # Known substitutions for standard boilerplate | |
| subs = { | |
| "standard_top_comment": "This file is generated by glib-mkenums, do not modify " | |
| "it. This code is licensed under the same license as the " | |
| "containing project. Note that it links to GLib, so must " | |
| "comply with the LGPL linking clauses.", | |
| "standard_bottom_comment": "Generated data ends here", | |
| } | |
| result = Result(info, out, err, subs) | |
| print("Output:", result.out) | |
| return result | |
| def runMkenumsWithTemplate(self, template_contents, *args): | |
| with tempfile.NamedTemporaryFile( | |
| dir=self.tmpdir.name, suffix=".template", delete=False | |
| ) as template_file: | |
| # Write out the template. | |
| template_file.write(template_contents.encode("utf-8")) | |
| print(template_file.name + ":", template_contents) | |
| template_file.flush() | |
| return self.runMkenums("--template", template_file.name, *args) | |
| def runMkenumsWithAllSubstitutions(self, *args): | |
| """Run glib-mkenums with a template which outputs all substitutions.""" | |
| template_contents = """ | |
| /*** BEGIN file-header ***/ | |
| file-header | |
| /*** END file-header ***/ | |
| /*** BEGIN file-production ***/ | |
| file-production | |
| filename: @filename@ | |
| basename: @basename@ | |
| /*** END file-production ***/ | |
| /*** BEGIN enumeration-production ***/ | |
| enumeration-production | |
| EnumName: @EnumName@ | |
| enum_name: @enum_name@ | |
| ENUMNAME: @ENUMNAME@ | |
| ENUMSHORT: @ENUMSHORT@ | |
| ENUMPREFIX: @ENUMPREFIX@ | |
| enumsince: @enumsince@ | |
| type: @type@ | |
| Type: @Type@ | |
| TYPE: @TYPE@ | |
| /*** END enumeration-production ***/ | |
| /*** BEGIN value-header ***/ | |
| value-header | |
| EnumName: @EnumName@ | |
| enum_name: @enum_name@ | |
| ENUMNAME: @ENUMNAME@ | |
| ENUMSHORT: @ENUMSHORT@ | |
| ENUMPREFIX: @ENUMPREFIX@ | |
| enumsince: @enumsince@ | |
| type: @type@ | |
| Type: @Type@ | |
| TYPE: @TYPE@ | |
| /*** END value-header ***/ | |
| /*** BEGIN value-production ***/ | |
| value-production | |
| VALUENAME: @VALUENAME@ | |
| valuenick: @valuenick@ | |
| valuenum: @valuenum@ | |
| type: @type@ | |
| Type: @Type@ | |
| TYPE: @TYPE@ | |
| /*** END value-production ***/ | |
| /*** BEGIN value-tail ***/ | |
| value-tail | |
| EnumName: @EnumName@ | |
| enum_name: @enum_name@ | |
| ENUMNAME: @ENUMNAME@ | |
| ENUMSHORT: @ENUMSHORT@ | |
| ENUMPREFIX: @ENUMPREFIX@ | |
| enumsince: @enumsince@ | |
| type: @type@ | |
| Type: @Type@ | |
| TYPE: @TYPE@ | |
| /*** END value-tail ***/ | |
| /*** BEGIN comment ***/ | |
| comment | |
| comment: @comment@ | |
| /*** END comment ***/ | |
| /*** BEGIN file-tail ***/ | |
| file-tail | |
| /*** END file-tail ***/ | |
| """ | |
| return self.runMkenumsWithTemplate(template_contents, *args) | |
| def runMkenumsWithHeader(self, h_contents, encoding="utf-8"): | |
| with tempfile.NamedTemporaryFile( | |
| dir=self.tmpdir.name, suffix=".h", delete=False | |
| ) as h_file: | |
| # Write out the header to be scanned. | |
| h_file.write(h_contents.encode(encoding)) | |
| print(h_file.name + ":", h_contents) | |
| h_file.flush() | |
| # Run glib-mkenums with a template which outputs all substitutions. | |
| result = self.runMkenumsWithAllSubstitutions(h_file.name) | |
| # Known substitutions for generated filenames. | |
| result.subs.update( | |
| {"filename": h_file.name, "basename": os.path.basename(h_file.name)} | |
| ) | |
| return result | |
| def assertSingleEnum( | |
| self, | |
| result, | |
| enum_name_camel, | |
| enum_name_lower, | |
| enum_name_upper, | |
| enum_name_short, | |
| enum_prefix, | |
| enum_since, | |
| type_lower, | |
| type_camel, | |
| type_upper, | |
| value_name, | |
| value_nick, | |
| value_num, | |
| ): | |
| """Assert that out (from runMkenumsWithHeader()) contains a single | |
| enum and value matching the given arguments.""" | |
| subs = dict( | |
| { | |
| "enum_name_camel": enum_name_camel, | |
| "enum_name_lower": enum_name_lower, | |
| "enum_name_upper": enum_name_upper, | |
| "enum_name_short": enum_name_short, | |
| "enum_prefix": enum_prefix, | |
| "enum_since": enum_since, | |
| "type_lower": type_lower, | |
| "type_camel": type_camel, | |
| "type_upper": type_upper, | |
| "value_name": value_name, | |
| "value_nick": value_nick, | |
| "value_num": value_num, | |
| }, | |
| **result.subs | |
| ) | |
| self.assertEqual( | |
| """ | |
| comment | |
| comment: {standard_top_comment} | |
| file-header | |
| file-production | |
| filename: {filename} | |
| basename: {basename} | |
| enumeration-production | |
| EnumName: {enum_name_camel} | |
| enum_name: {enum_name_lower} | |
| ENUMNAME: {enum_name_upper} | |
| ENUMSHORT: {enum_name_short} | |
| ENUMPREFIX: {enum_prefix} | |
| enumsince: {enum_since} | |
| type: {type_lower} | |
| Type: {type_camel} | |
| TYPE: {type_upper} | |
| value-header | |
| EnumName: {enum_name_camel} | |
| enum_name: {enum_name_lower} | |
| ENUMNAME: {enum_name_upper} | |
| ENUMSHORT: {enum_name_short} | |
| ENUMPREFIX: {enum_prefix} | |
| enumsince: {enum_since} | |
| type: {type_lower} | |
| Type: {type_camel} | |
| TYPE: {type_upper} | |
| value-production | |
| VALUENAME: {value_name} | |
| valuenick: {value_nick} | |
| valuenum: {value_num} | |
| type: {type_lower} | |
| Type: {type_camel} | |
| TYPE: {type_upper} | |
| value-tail | |
| EnumName: {enum_name_camel} | |
| enum_name: {enum_name_lower} | |
| ENUMNAME: {enum_name_upper} | |
| ENUMSHORT: {enum_name_short} | |
| ENUMPREFIX: {enum_prefix} | |
| enumsince: {enum_since} | |
| type: {type_lower} | |
| Type: {type_camel} | |
| TYPE: {type_upper} | |
| file-tail | |
| comment | |
| comment: {standard_bottom_comment} | |
| """.format( | |
| **subs | |
| ).strip(), | |
| result.out, | |
| ) | |
| def test_help(self): | |
| """Test the --help argument.""" | |
| result = self.runMkenums("--help") | |
| self.assertIn("usage: glib-mkenums", result.out) | |
| def test_no_args(self): | |
| """Test running with no arguments at all.""" | |
| result = self.runMkenums() | |
| self.assertEqual("", result.err) | |
| self.assertEqual( | |
| """/* {standard_top_comment} */ | |
| /* {standard_bottom_comment} */""".format( | |
| **result.subs | |
| ), | |
| result.out.strip(), | |
| ) | |
| def test_empty_template(self): | |
| """Test running with an empty template and no header files.""" | |
| result = self.runMkenumsWithTemplate("") | |
| self.assertEqual("", result.err) | |
| self.assertEqual( | |
| """/* {standard_top_comment} */ | |
| /* {standard_bottom_comment} */""".format( | |
| **result.subs | |
| ), | |
| result.out.strip(), | |
| ) | |
| def test_no_headers(self): | |
| """Test running with a complete template, but no header files.""" | |
| result = self.runMkenumsWithAllSubstitutions() | |
| self.assertEqual("", result.err) | |
| self.assertEqual( | |
| """ | |
| comment | |
| comment: {standard_top_comment} | |
| file-header | |
| file-tail | |
| comment | |
| comment: {standard_bottom_comment} | |
| """.format( | |
| **result.subs | |
| ).strip(), | |
| result.out, | |
| ) | |
| def test_empty_header(self): | |
| """Test an empty header.""" | |
| result = self.runMkenumsWithHeader("") | |
| self.assertEqual("", result.err) | |
| self.assertEqual( | |
| """ | |
| comment | |
| comment: {standard_top_comment} | |
| file-header | |
| file-tail | |
| comment | |
| comment: {standard_bottom_comment} | |
| """.format( | |
| **result.subs | |
| ).strip(), | |
| result.out, | |
| ) | |
| def test_enum_name(self): | |
| """Test typedefs with an enum and a typedef name. Bug #794506.""" | |
| h_contents = """ | |
| typedef enum _SomeEnumIdentifier { | |
| ENUM_VALUE | |
| } SomeEnumIdentifier; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "SomeEnumIdentifier", | |
| "some_enum_identifier", | |
| "SOME_ENUM_IDENTIFIER", | |
| "ENUM_IDENTIFIER", | |
| "SOME", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE", | |
| "value", | |
| "0", | |
| ) | |
| def test_non_utf8_encoding(self): | |
| """Test source files with non-UTF-8 encoding. Bug #785113.""" | |
| h_contents = """ | |
| /* Copyright © La Peña */ | |
| typedef enum { | |
| ENUM_VALUE | |
| } SomeEnumIdentifier; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents, encoding="iso-8859-1") | |
| self.assertIn("WARNING: UnicodeWarning: ", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "SomeEnumIdentifier", | |
| "some_enum_identifier", | |
| "SOME_ENUM_IDENTIFIER", | |
| "ENUM_IDENTIFIER", | |
| "SOME", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE", | |
| "value", | |
| "0", | |
| ) | |
| def test_reproducible(self): | |
| """Test builds are reproducible regardless of file ordering. | |
| Bug #691436.""" | |
| template_contents = "template" | |
| h_contents1 = """ | |
| typedef enum { | |
| FIRST, | |
| } Header1; | |
| """ | |
| h_contents2 = """ | |
| typedef enum { | |
| SECOND, | |
| } Header2; | |
| """ | |
| with tempfile.NamedTemporaryFile( | |
| dir=self.tmpdir.name, suffix="1.h", delete=False | |
| ) as h_file1, tempfile.NamedTemporaryFile( | |
| dir=self.tmpdir.name, suffix="2.h", delete=False | |
| ) as h_file2: | |
| # Write out the headers. | |
| h_file1.write(h_contents1.encode("utf-8")) | |
| h_file2.write(h_contents2.encode("utf-8")) | |
| h_file1.flush() | |
| h_file2.flush() | |
| # Run glib-mkenums with the headers in one order, and then again | |
| # in another order. | |
| result1 = self.runMkenumsWithTemplate( | |
| template_contents, h_file1.name, h_file2.name | |
| ) | |
| self.assertEqual("", result1.err) | |
| result2 = self.runMkenumsWithTemplate( | |
| template_contents, h_file2.name, h_file1.name | |
| ) | |
| self.assertEqual("", result2.err) | |
| # The output should be the same. | |
| self.assertEqual(result1.out, result2.out) | |
| def test_no_nick(self): | |
| """Test trigraphs with a desc but no nick. Issue #1360.""" | |
| h_contents = """ | |
| typedef enum { | |
| GEGL_SAMPLER_NEAREST = 0, /*< desc="nearest" >*/ | |
| } GeglSamplerType; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "GeglSamplerType", | |
| "gegl_sampler_type", | |
| "GEGL_SAMPLER_TYPE", | |
| "SAMPLER_TYPE", | |
| "GEGL", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "GEGL_SAMPLER_NEAREST", | |
| "nearest", | |
| "0", | |
| ) | |
| def test_with_double_quotes(self): | |
| """Test trigraphs with double-quoted expressions. Issue #65.""" | |
| h_contents = """ | |
| typedef enum { | |
| FOO_VALUE /*< nick="eek, a comma" >*/ | |
| } Foo; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "Foo", | |
| "foo_", | |
| "FOO_", | |
| "", | |
| "FOO", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "FOO_VALUE", | |
| "eek, a comma", | |
| "0", | |
| ) | |
| def test_filename_basename_in_fhead_ftail(self): | |
| template_contents = """ | |
| /*** BEGIN file-header ***/ | |
| file-header | |
| filename: @filename@ | |
| basename: @basename@ | |
| /*** END file-header ***/ | |
| /*** BEGIN comment ***/ | |
| comment | |
| comment: @comment@ | |
| /*** END comment ***/ | |
| /*** BEGIN file-tail ***/ | |
| file-tail | |
| filename: @filename@ | |
| basename: @basename@ | |
| /*** END file-tail ***/""" | |
| result = self.runMkenumsWithTemplate(template_contents) | |
| self.assertEqual( | |
| textwrap.dedent( | |
| """ | |
| WARNING: @filename@ used in file-header section. | |
| WARNING: @basename@ used in file-header section. | |
| WARNING: @filename@ used in file-tail section. | |
| WARNING: @basename@ used in file-tail section. | |
| """ | |
| ).strip(), | |
| result.err, | |
| ) | |
| self.assertEqual( | |
| """ | |
| comment | |
| comment: {standard_top_comment} | |
| file-header | |
| filename: @filename@ | |
| basename: @basename@ | |
| file-tail | |
| filename: @filename@ | |
| basename: @basename@ | |
| comment | |
| comment: {standard_bottom_comment} | |
| """.format( | |
| **result.subs | |
| ).strip(), | |
| result.out, | |
| ) | |
| def test_since(self): | |
| """Test user-provided 'since' version handling | |
| https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1492""" | |
| h_contents = """ | |
| typedef enum { /*< since=1.0 >*/ | |
| QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0, | |
| } QmiWmsMessageProtocol; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "QmiWmsMessageProtocol", | |
| "qmi_wms_message_protocol", | |
| "QMI_WMS_MESSAGE_PROTOCOL", | |
| "WMS_MESSAGE_PROTOCOL", | |
| "QMI", | |
| "1.0", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "QMI_WMS_MESSAGE_PROTOCOL_CDMA", | |
| "cdma", | |
| "0", | |
| ) | |
| def test_enum_private_public(self): | |
| """Test private/public enums. Bug #782162.""" | |
| h_contents1 = """ | |
| typedef enum { | |
| ENUM_VALUE_PUBLIC1, | |
| /*< private >*/ | |
| ENUM_VALUE_PRIVATE, | |
| } SomeEnumA | |
| """ | |
| h_contents2 = """ | |
| typedef enum { | |
| /*< private >*/ | |
| ENUM_VALUE_PRIVATE, | |
| /*< public >*/ | |
| ENUM_VALUE_PUBLIC2, | |
| } SomeEnumB; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents1) | |
| self.maxDiff = None | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "SomeEnumA", | |
| "some_enum_a", | |
| "SOME_ENUM_A", | |
| "ENUM_A", | |
| "SOME", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE_PUBLIC1", | |
| "public1", | |
| "0", | |
| ) | |
| result = self.runMkenumsWithHeader(h_contents2) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "SomeEnumB", | |
| "some_enum_b", | |
| "SOME_ENUM_B", | |
| "ENUM_B", | |
| "SOME", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE_PUBLIC2", | |
| "public2", | |
| "1", | |
| ) | |
| def test_available_in(self): | |
| """Test GLIB_AVAILABLE_ENUMERATOR_IN_2_68 handling | |
| https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" | |
| h_contents = """ | |
| typedef enum { | |
| G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = (1<<2) | |
| } GDBusServerFlags; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "GDBusServerFlags", | |
| "g_dbus_server_flags", | |
| "G_DBUS_SERVER_FLAGS", | |
| "DBUS_SERVER_FLAGS", | |
| "G", | |
| "", | |
| "flags", | |
| "Flags", | |
| "FLAGS", | |
| "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", | |
| "user", | |
| "4", | |
| ) | |
| def test_deprecated_in(self): | |
| """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68 handling | |
| https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" | |
| h_contents = """ | |
| typedef enum { | |
| G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_DEPRECATED_ENUMERATOR_IN_2_68 = (1<<2) | |
| } GDBusServerFlags; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "GDBusServerFlags", | |
| "g_dbus_server_flags", | |
| "G_DBUS_SERVER_FLAGS", | |
| "DBUS_SERVER_FLAGS", | |
| "G", | |
| "", | |
| "flags", | |
| "Flags", | |
| "FLAGS", | |
| "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", | |
| "user", | |
| "4", | |
| ) | |
| def test_deprecated_in_for(self): | |
| """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR() handling | |
| https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" | |
| h_contents = """ | |
| typedef enum { | |
| 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) | |
| } GDBusServerFlags; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "GDBusServerFlags", | |
| "g_dbus_server_flags", | |
| "G_DBUS_SERVER_FLAGS", | |
| "DBUS_SERVER_FLAGS", | |
| "G", | |
| "", | |
| "flags", | |
| "Flags", | |
| "FLAGS", | |
| "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", | |
| "user", | |
| "4", | |
| ) | |
| def test_enum_symbolic_expression(self): | |
| """Test use of symbol in value expression.""" | |
| h_contents = """ | |
| typedef enum { | |
| /*< private >*/ | |
| ENUM_VALUE_PRIVATE = 5, | |
| /*< public >*/ | |
| ENUM_VALUE_PUBLIC = ENUM_VALUE_PRIVATE + 2, | |
| } TestSymbolicEnum; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "TestSymbolicEnum", | |
| "test_symbolic_enum", | |
| "TEST_SYMBOLIC_ENUM", | |
| "SYMBOLIC_ENUM", | |
| "TEST", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE_PUBLIC", | |
| "public", | |
| "7", | |
| ) | |
| def test_comma_in_enum_value(self): | |
| """Test use of comma in enum value.""" | |
| h_contents = """ | |
| typedef enum { | |
| ENUM_VALUE_WITH_COMMA = ',', | |
| } TestCommaEnum; | |
| """ | |
| result = self.runMkenumsWithHeader(h_contents) | |
| self.assertEqual("", result.err) | |
| self.assertSingleEnum( | |
| result, | |
| "TestCommaEnum", | |
| "test_comma_enum", | |
| "TEST_COMMA_ENUM", | |
| "COMMA_ENUM", | |
| "TEST", | |
| "", | |
| "enum", | |
| "Enum", | |
| "ENUM", | |
| "ENUM_VALUE_WITH_COMMA", | |
| "comma", | |
| 44, | |
| ) | |
| class TestRspMkenums(TestMkenums): | |
| """Run all tests again in @rspfile mode""" | |
| rspfile = True | |
| if __name__ == "__main__": | |
| unittest.main(testRunner=taptestrunner.TAPTestRunner()) |