From 27a701c37142118bff0ecb8aec5b2717f9d34e0e Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 16 Feb 2020 12:55:50 -0500 Subject: [PATCH] Rewrote testlist.py to allow producing an auxiliary file (or auxiliary files) to allow not having to compute the test lookup table in testparent (though we're not doing that yet). It mostly works. --- test/meson.build | 4 +- test/testlist.py | 114 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 6 deletions(-) diff --git a/test/meson.build b/test/meson.build index 1f781651..bf41bbb1 100644 --- a/test/meson.build +++ b/test/meson.build @@ -49,7 +49,9 @@ libui_testparent = executable('testparent', libui_test_sources + libui_test_sour pymod = import('python') python = pymod.find_installation() # Using files() is the cleanest way to ensure the python script gets the right filenames regardless of how meson sandboxes the command it's running. -runresult = run_command(python, files(['testlist.py'] + libui_test_sources)) +libui_testlist_py = files(['testlist.py']) +libui_test_sources_files = files(libui_test_sources) +runresult = run_command(python, libui_testlist_py + ['list'] + libui_test_sources_files) if runresult.returncode() != 0 error('testlist.py failed; cannot compute list of test cases. Exit code @0@; stderr:\n@1@'.format(runresult.returncode(), runresult.stderr())) endif diff --git a/test/testlist.py b/test/testlist.py index 29b1fa0e..dd37695b 100644 --- a/test/testlist.py +++ b/test/testlist.py @@ -1,11 +1,115 @@ # 20 january 2020 # note: python 3 +import abc import fileinput import re +import sys -r = re.compile('^(?:Test|TestNoInit)\(([A-Za-z0-9_]+)\)$') -for line in fileinput.input(): - match = r.match(line) - if match is not None: - print('Test' + match.group(1)) +def errf(fmt, *args): + print(fmt.format(*args), file = sys.stderr) + +class command(metaclass = abc.ABCMeta): + @classmethod + @abc.abstractmethod + def name(cls): + raise NotImplementedError + + @classmethod + @abc.abstractmethod + def usageString(cls): + raise NotImplementedError + + # returns the list of filenames to iterate through + # returns None if there was an error parsing arguments + @abc.abstractmethod + def processArgs(self, args): + raise NotImplementedError + + @abc.abstractmethod + def run(self, casenames): + raise NotImplementedError + +class listCommand: + @classmethod + def name(cls): + return 'list' + + @classmethod + def usageString(cls): + return 'list [source-files...]' + + def processArgs(self, args): + return args + + def run(self, casenames): + for x in casenames: + print('Test' + x) +command.register(listCommand) + +class headerCommand: + filename = None + + @classmethod + def name(cls): + return 'header' + + @classmethod + def usageString(cls): + return 'header header-file [source-files...]' + + def processArgs(self, args): + if len(args) < 1: + errf('error: output filename missing') + return None + self.filename = args[0] + return args[1:] + + def run(self, casenames): + # TODO + raise NotImplementedError +command.register(headerCommand) + +commands = [ + listCommand, + headerCommand, +] + +def usage(): + errf('usage:') + errf('{} help', sys.argv[0]) + for cmd in commands: + errf('{} {}', sys.argv[0], cmd.usageString()) + sys.exit(1) + +def main(): + r = re.compile('^(?:Test|TestNoInit)\(([A-Za-z0-9_]+)\)$') + + if len(sys.argv) < 2: + usage() + cmdname = sys.argv[1] + if cmdname == 'help': + usage() + cmdtype = None + for cmd in commands: + if cmd.name() == cmdname: + cmdtype = cmd + break + if cmdtype is None: + errf('error: unknown command {}', cmdname) + usage() + + cmd = cmdtype() + files = cmd.processArgs(sys.argv[2:]) + if files is None: + usage() + + casenames = [] + for line in fileinput.input(files = files): + match = r.match(line) + if match is not None: + casenames.append(match.group(1)) + print('*', casenames) + cmd.run(casenames) + +main()