From 853e51f097020a8ddf531484ce6baf34fef5ddaa Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Mon, 6 May 2024 22:12:50 +0200 Subject: [PATCH] Tests: move test_utils This will now be tested with pytests Provide some bootstrap files (autoconfig and parser test case) to get the test to run This will need to be refactored later --- tests/__init__.py | 0 tests/autoconfig.py | 55 +++++++++++++++ tests/parser_test_case.py | 103 +++++++++++++++++++++++++++++ {unittests => tests}/test_utils.py | 2 +- unittests/autoconfig.py | 13 ++-- unittests/test_all.py | 2 - 6 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/autoconfig.py create mode 100644 tests/parser_test_case.py rename {unittests => tests}/test_utils.py (97%) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/autoconfig.py b/tests/autoconfig.py new file mode 100644 index 00000000..29c784f9 --- /dev/null +++ b/tests/autoconfig.py @@ -0,0 +1,55 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import sys +import logging +import warnings +import platform + +# Prevents copy.deepcopy RecursionError in some tests (Travis build) +sys.setrecursionlimit(10000) + +this_module_dir_path = os.path.abspath( + os.path.dirname(sys.modules[__name__].__file__)) + +data_directory = os.path.join(this_module_dir_path, 'data') +build_directory = os.path.join(this_module_dir_path, 'temp') + +sys.path.insert(1, os.path.join(os.curdir, '..')) +# The tests are run on the parent pygccxml directory, not the one +# in site-packages. Insert the directory's path. +sys.path.insert(1, "../src/pygccxml") + +from pygccxml import parser # nopep8 +from pygccxml import utils # nopep8 + +# We want to make sure we throw an error for ALL the warnings during the +# tests. This will allow us to be notified by the build bots, so that the +# warnings can be fixed. +warnings.simplefilter("error", Warning) + +# Set logging level +utils.loggers.set_level(logging.CRITICAL) + +# Find out the c++ parser (gccxml or castxml) +generator_path, generator_name = utils.find_xml_generator() + + +class cxx_parsers_cfg(object): + config = parser.load_xml_generator_configuration( + os.path.normpath(this_module_dir_path + '/xml_generator.cfg'), + xml_generator_path=generator_path, + working_directory=data_directory, + xml_generator=generator_name) + + if platform.system() == 'Windows': + config.define_symbols.append('_HAS_EXCEPTIONS=0') + + +if cxx_parsers_cfg.config.xml_generator: + generator_name = cxx_parsers_cfg.config.xml_generator +if cxx_parsers_cfg.config.xml_generator_path: + generator_path = cxx_parsers_cfg.config.xml_generator_path diff --git a/tests/parser_test_case.py b/tests/parser_test_case.py new file mode 100644 index 00000000..b0584774 --- /dev/null +++ b/tests/parser_test_case.py @@ -0,0 +1,103 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import pprint +import time +import unittest + +from . import autoconfig + + +class parser_test_case_t(unittest.TestCase): + + CXX_PARSER_CFG = None + xml_generator_from_xml_file = None + + def __init__(self, *args): + unittest.TestCase.__init__(self, *args) + self.xml_generator_from_xml_file = None + if self.CXX_PARSER_CFG: + self.config = self.CXX_PARSER_CFG.clone() + elif autoconfig.cxx_parsers_cfg.config: + self.config = autoconfig.cxx_parsers_cfg.config.clone() + else: + pass + + def run(self, result=None): + """ + Override the run method. + + Allows to measure the time each test needs. The result is written + in the test_cost.log file. + + """ + with open("test_cost.log", "a") as cost_file: + start_time = time.time() + super(parser_test_case_t, self).run(result) + name = super(parser_test_case_t, self).id() + cost_file.write( + name + " " + + str(time.time() - start_time) + "\n") + + def _test_type_composition(self, type_, expected_compound, expected_base): + self.assertTrue( + isinstance(type_, expected_compound), + "the compound type('%s') should be '%s'" % + (type_.decl_string, expected_compound.__name__)) + self.assertTrue( + isinstance(type_.base, expected_base), + "base type('%s') should be '%s'" % + (type_.decl_string, expected_base.__name__)) + + def _test_calldef_return_type(self, calldef, expected_type): + self.assertTrue( + isinstance(calldef.return_type, expected_type), + ("the function's '%s' expected return type is '%s' and in " + + "reality it is different('%s')") % + (calldef.name, expected_type.__name__, + calldef.return_type.__class__.__name__)) + + def _test_calldef_args(self, calldef, expected_args): + self.assertTrue( + len(calldef.arguments) == len(expected_args), + ("the function's '%s' expected number of arguments is '%d' and " + + "in reality it is different('%d')") % + (calldef.name, len(expected_args), len(calldef.arguments))) + + for i, expected_arg in enumerate(expected_args): + arg = calldef.arguments[i] + self.assertTrue( + arg == expected_arg, + ("the function's '%s' expected %d's argument is '%s' and in " + + "reality it is different('%s')") % + (calldef.name, i, pprint.pformat(expected_arg.__dict__), + pprint.pformat(arg.__dict__))) + + def _test_calldef_exceptions(self, calldef, exceptions): + # exceptions is list of classes names + exception_decls = [] + for name in exceptions: + exception_decl = self.global_ns.class_(name) + self.assertTrue( + exception_decl, + "unable to find exception class '%s'" % + name) + exception_decls.append(exception_decl) + exception_decls.sort() + self.assertTrue( + len(calldef.exceptions) == len(exception_decls), + ("the function's '%s' expected number of exceptions is '%d' and " + + "in reality it is different('%d')") % + (calldef.name, + len(exception_decls), + len(calldef.exceptions))) + exceptions_indeed = sorted(calldef.exceptions[:]) + self.assertTrue( + exception_decls == exceptions_indeed, + ("the function's '%s' expected exceptions are '%s' and in " + + "reality it is different('%s')") % + (calldef.name, + pprint.pformat([delc.name for delc in exception_decls]), + pprint.pformat([delc.name for delc in exceptions_indeed]))) diff --git a/unittests/test_utils.py b/tests/test_utils.py similarity index 97% rename from unittests/test_utils.py rename to tests/test_utils.py index 9fa76c15..5f989dd6 100644 --- a/unittests/test_utils.py +++ b/tests/test_utils.py @@ -14,7 +14,7 @@ class Test(parser_test_case.parser_test_case_t): - def test(self): + def test_contains_parent_dir(self): path = os.path.normpath("/mypath/folder1/folder2/folder3") dirs = [ os.path.normpath("/mypath/folder1/folder2/"), diff --git a/unittests/autoconfig.py b/unittests/autoconfig.py index 29c784f9..4c97c8ac 100644 --- a/unittests/autoconfig.py +++ b/unittests/autoconfig.py @@ -9,6 +9,9 @@ import warnings import platform +from pygccxml import parser +from pygccxml import utils + # Prevents copy.deepcopy RecursionError in some tests (Travis build) sys.setrecursionlimit(10000) @@ -18,14 +21,6 @@ data_directory = os.path.join(this_module_dir_path, 'data') build_directory = os.path.join(this_module_dir_path, 'temp') -sys.path.insert(1, os.path.join(os.curdir, '..')) -# The tests are run on the parent pygccxml directory, not the one -# in site-packages. Insert the directory's path. -sys.path.insert(1, "../src/pygccxml") - -from pygccxml import parser # nopep8 -from pygccxml import utils # nopep8 - # We want to make sure we throw an error for ALL the warnings during the # tests. This will allow us to be notified by the build bots, so that the # warnings can be fixed. @@ -34,7 +29,7 @@ # Set logging level utils.loggers.set_level(logging.CRITICAL) -# Find out the c++ parser (gccxml or castxml) +# Find out the c++ parser (castxml) generator_path, generator_name = utils.find_xml_generator() diff --git a/unittests/test_all.py b/unittests/test_all.py index 4ae4c66c..92585f16 100644 --- a/unittests/test_all.py +++ b/unittests/test_all.py @@ -61,7 +61,6 @@ from . import inline_specifier_tester from . import test_create_decl_string from . import example_tester -from . import test_utils from . import test_va_list_tag_removal from . import test_copy_constructor from . import test_cpp_standards @@ -140,7 +139,6 @@ test_pattern_parser, test_function_pointer, test_directory_cache, - test_utils, test_cpp_standards, test_va_list_tag_removal, decl_printer_tester,