From 2ff9ee73d45e40c1faf4bbc867eba9998a777a0f Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Wed, 13 Nov 2024 23:05:28 +0100 Subject: [PATCH] tests: refactor / simplify Note: I removed some tests from test_elaborated_types I checked and these were already broken It's unclear to me why this has been the case, I think they were added by mistake but never tested because the castxml = 1 flag was never set ... --- tests/parser_test_case.py | 103 ---------------- tests/test_algorithms_cache.py | 89 ++++++-------- tests/test_argument_without_name.py | 63 ++++------ tests/test_array_argument.py | 111 +++++++---------- tests/test_array_bug.py | 182 ++++++++++++---------------- tests/test_config.py | 3 - tests/test_elaborated_types.py | 93 ++++++-------- tests/test_example.py | 68 +++-------- tests/test_file_cache.py | 142 +++++++++------------- tests/test_filters_tester.py | 163 +++++++++++-------------- tests/test_find_noncopyable_vars.py | 56 ++++----- tests/test_free_operators.py | 54 +++------ tests/test_function_pointer.py | 147 ++++++++++------------ tests/test_function_traits.py | 53 +++----- tests/test_order.py | 167 ++++++++++++------------- 15 files changed, 569 insertions(+), 925 deletions(-) delete mode 100644 tests/parser_test_case.py diff --git a/tests/parser_test_case.py b/tests/parser_test_case.py deleted file mode 100644 index b0584774..00000000 --- a/tests/parser_test_case.py +++ /dev/null @@ -1,103 +0,0 @@ -# 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/tests/test_algorithms_cache.py b/tests/test_algorithms_cache.py index 3c7146c0..1e30185b 100644 --- a/tests/test_algorithms_cache.py +++ b/tests/test_algorithms_cache.py @@ -3,75 +3,58 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): - # tester source reader - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'core_membership.hpp' - self.global_ns = None - - def setUp(self): - decls = parser.parse([self.header], self.config) - self.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.global_ns = declarations.get_global_namespace(decls) - - def test_name_based(self): - cls = self.global_ns.class_(name='class_for_nested_enums_t') +TEST_FILES = ['core_membership.hpp'] - cls_full_name = declarations.full_name(cls) - self.assertTrue(cls.cache.full_name == cls_full_name) - cls_declaration_path = declarations.declaration_path(cls) - self.assertTrue(cls.cache.declaration_path == cls_declaration_path) - - enum = cls.enumeration('ENestedPublic') - - enum_full_name = declarations.full_name(enum) - self.assertTrue(enum.cache.full_name == enum_full_name) +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - enum_declaration_path = declarations.declaration_path(enum) - self.assertTrue(enum.cache.declaration_path == enum_declaration_path) - # now we change class name, all internal decls cache should be cleared - cls.name = "new_name" - self.assertTrue(not cls.cache.full_name) - self.assertTrue(not cls.cache.declaration_path) +def test_name_based(global_ns): + cls = global_ns.class_(name='class_for_nested_enums_t') - self.assertTrue(not enum.cache.full_name) - self.assertTrue(not enum.cache.declaration_path) + cls_full_name = declarations.full_name(cls) + assert cls.cache.full_name == cls_full_name - def test_access_type(self): - cls = self.global_ns.class_(name='class_for_nested_enums_t') - enum = cls.enumeration('ENestedPublic') - self.assertTrue(enum.cache.access_type == 'public') - enum.cache.reset_access_type() - self.assertTrue(not enum.cache.access_type) - self.assertTrue('public' == cls.find_out_member_access_type(enum)) - self.assertTrue(enum.cache.access_type == 'public') + cls_declaration_path = declarations.declaration_path(cls) + assert cls.cache.declaration_path == cls_declaration_path + enum = cls.enumeration('ENestedPublic') -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) + enum_full_name = declarations.full_name(enum) + assert enum.cache.full_name == enum_full_name - return suite + enum_declaration_path = declarations.declaration_path(enum) + assert enum.cache.declaration_path == enum_declaration_path + # now we change class name, all internal decls cache should be cleared + cls.name = "new_name" + assert not cls.cache.full_name + assert not cls.cache.declaration_path -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) + assert not enum.cache.full_name + assert not enum.cache.declaration_path -if __name__ == "__main__": - run_suite() +def test_access_type(global_ns): + cls = global_ns.class_(name='class_for_nested_enums_t') + enum = cls.enumeration('ENestedPublic') + assert enum.cache.access_type == 'public' + enum.cache.reset_access_type() + assert not enum.cache.access_type + assert 'public' == cls.find_out_member_access_type(enum) + assert enum.cache.access_type == 'public' diff --git a/tests/test_argument_without_name.py b/tests/test_argument_without_name.py index be161a7f..93a457c9 100644 --- a/tests/test_argument_without_name.py +++ b/tests/test_argument_without_name.py @@ -3,54 +3,41 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations +TEST_FILES = ['test_argument_without_name.hpp'] -class Test(parser_test_case.parser_test_case_t): - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_argument_without_name.hpp" - self.config.cflags = "-std=c++11" +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + config.cflags = "-std=c++11" + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - def test_argument_without_name(self): - """ - Test passing an object without name to a templated function. +def test_argument_without_name(global_ns): + """ + Test passing an object without name to a templated function. - The test was failing when building the declaration string. - The declaration string will be 'void (*)( & )'. If the passed - object had a name the result would then be 'void (*)(Name & )'. + The test was failing when building the declaration string. + The declaration string will be 'void (*)( & )'. If the passed + object had a name the result would then be 'void (*)(Name & )'. - See bug #55 + See bug #55 - """ + """ - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - criteria = declarations.calldef_matcher(name="function") - free_funcs = declarations.matcher.find(criteria, global_ns) - for free_func in free_funcs: - decl_string = free_func.create_decl_string(with_defaults=False) - self.assertEqual(decl_string, "void (*)( & )") - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + criteria = declarations.calldef_matcher(name="function") + free_funcs = declarations.matcher.find(criteria, global_ns) + for free_func in free_funcs: + decl_string = free_func.create_decl_string(with_defaults=False) + assert decl_string == "void (*)( & )" diff --git a/tests/test_array_argument.py b/tests/test_array_argument.py index 9d832854..9b25d61c 100644 --- a/tests/test_array_argument.py +++ b/tests/test_array_argument.py @@ -3,74 +3,53 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_array_argument.hpp" - self.config.cflags = "-std=c++11" - - def test_array_argument(self): - - """ - Test to ensure that function arguments' array size are kept intact - rather than presented as pointers. - - """ - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - criteria = declarations.calldef_matcher(name="function") - free_funcs = declarations.matcher.find(criteria, global_ns) - for free_func in free_funcs: - decl_string = free_func.create_decl_string(with_defaults=False) - self.assertEqual( - decl_string, - "void ( ::test::* )( int [1024],int [512] )" - ) - arg1 = free_func.arguments[0] - arg2 = free_func.arguments[1] - self.assertEqual(arg1.decl_type.decl_string, "int [1024]") - self.assertEqual(arg1.name, "arg1") - self.assertEqual( - declarations.type_traits.array_size(arg1.decl_type), - 1024 - ) - self.assertIsInstance( - declarations.type_traits.array_item_type(arg1.decl_type), - declarations.cpptypes.int_t - ) - self.assertEqual(arg2.decl_type.decl_string, "int [512]") - self.assertEqual(arg2.name, "arg2") - self.assertEqual( - declarations.type_traits.array_size(arg2.decl_type), - 512 - ) - self.assertIsInstance( - declarations.type_traits.array_item_type(arg2.decl_type), - declarations.cpptypes.int_t - ) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +TEST_FILES = ['test_array_argument.hpp'] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + config.cflags = "-std=c++11" + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns + + +def test_array_argument(global_ns): + + """ + Test to ensure that function arguments' array size are kept intact + rather than presented as pointers. + + """ + + criteria = declarations.calldef_matcher(name="function") + free_funcs = declarations.matcher.find(criteria, global_ns) + for free_func in free_funcs: + decl_string = free_func.create_decl_string(with_defaults=False) + assert decl_string == "void ( ::test::* )( int [1024],int [512] )" + arg1 = free_func.arguments[0] + arg2 = free_func.arguments[1] + assert arg1.decl_type.decl_string == "int [1024]" + assert arg1.name == "arg1" + assert declarations.type_traits.array_size(arg1.decl_type) == 1024 + assert isinstance( + declarations.type_traits.array_item_type(arg1.decl_type), + declarations.cpptypes.int_t + ) is True + assert arg2.decl_type.decl_string == "int [512]" + assert arg2.name == "arg2" + assert declarations.type_traits.array_size(arg2.decl_type) == 512 + assert isinstance( + declarations.type_traits.array_item_type(arg2.decl_type), + declarations.cpptypes.int_t + ) is True diff --git a/tests/test_array_bug.py b/tests/test_array_bug.py index bb748f77..3236a849 100644 --- a/tests/test_array_bug.py +++ b/tests/test_array_bug.py @@ -3,114 +3,84 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest - -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - - def test1(self): - code = 'int aaaa[2][3][4][5];' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - aaaa_type = global_ns.variable('aaaa').decl_type - self.assertTrue( - 'int [2][3][4][5]' == aaaa_type.decl_string, - aaaa_type.decl_string) - - def test2(self): - code = 'int* aaaa[2][3][4][5];' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - aaaa_type = global_ns.variable('aaaa').decl_type - self.assertTrue( - 'int * [2][3][4][5]' == aaaa_type.decl_string, - aaaa_type.decl_string) - - def test3(self): - code = 'int aaaa[2];' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - aaaa_type = global_ns.variable('aaaa').decl_type - self.assertTrue( - 'int [2]' == aaaa_type.decl_string, - aaaa_type.decl_string) - - def test4(self): - code = 'struct xyz{}; xyz aaaa[2][3];' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - aaaa_type = global_ns.variable('aaaa').decl_type - self.assertTrue( - '::xyz [2][3]' == aaaa_type.decl_string, - aaaa_type.decl_string) - - def test5(self): - code = 'char const arr[4] = {};' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - arr_type = global_ns.variable('arr').decl_type - self.assertTrue( - 'char const [4]' == arr_type.decl_string, - arr_type.decl_string) - self.assertTrue( - declarations.is_array(arr_type)) - self.assertTrue( - declarations.is_const(arr_type)) - - def test6(self): - code = 'char volatile arr[4] = {};' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - arr_type = global_ns.variable('arr').decl_type - self.assertTrue( - 'char volatile [4]' == arr_type.decl_string, - arr_type.decl_string) - self.assertTrue( - declarations.is_array(arr_type)) - self.assertTrue( - declarations.is_volatile(arr_type)) - - def test7(self): - code = 'char const volatile arr[4] = {};' - src_reader = parser.source_reader_t(self.config) - global_ns = declarations.get_global_namespace( - src_reader.read_string(code)) - arr_type = global_ns.variable('arr').decl_type - self.assertTrue( - 'char const volatile [4]' == arr_type.decl_string, - arr_type.decl_string) - self.assertTrue( - declarations.is_array(arr_type)) - self.assertTrue( - declarations.is_const(arr_type)) - self.assertTrue( - declarations.is_volatile(arr_type)) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +def test_array_bug_1(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'int aaaa[2][3][4][5];' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + aaaa_type = global_ns.variable('aaaa').decl_type + assert 'int [2][3][4][5]' == aaaa_type.decl_string + + +def test_array_bug_2(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'int* aaaa[2][3][4][5];' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + aaaa_type = global_ns.variable('aaaa').decl_type + assert 'int * [2][3][4][5]' == aaaa_type.decl_string + + +def test_array_bug_3(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'int aaaa[2];' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + aaaa_type = global_ns.variable('aaaa').decl_type + assert 'int [2]' == aaaa_type.decl_string + + +def test_array_bug_4(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'struct xyz{}; xyz aaaa[2][3];' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + aaaa_type = global_ns.variable('aaaa').decl_type + assert '::xyz [2][3]' == aaaa_type.decl_string + + +def test_array_bug_5(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'char const arr[4] = {};' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + arr_type = global_ns.variable('arr').decl_type + assert 'char const [4]' == arr_type.decl_string + assert declarations.is_array(arr_type) is True + assert declarations.is_const(arr_type) is True + + +def test_array_bug_6(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'char volatile arr[4] = {};' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + arr_type = global_ns.variable('arr').decl_type + assert 'char volatile [4]' == arr_type.decl_string + assert declarations.is_array(arr_type) is True + assert declarations.is_volatile(arr_type) is True + + +def test_array_bug_7(): + config = autoconfig.cxx_parsers_cfg.config.clone() + code = 'char const volatile arr[4] = {};' + src_reader = parser.source_reader_t(config) + global_ns = declarations.get_global_namespace( + src_reader.read_string(code)) + arr_type = global_ns.variable('arr').decl_type + assert 'char const volatile [4]' == arr_type.decl_string + assert declarations.is_array(arr_type) is True + assert declarations.is_const(arr_type) is True + assert declarations.is_volatile(arr_type) is True diff --git a/tests/test_config.py b/tests/test_config.py index 8ee8dc41..06f0ddb0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -3,9 +3,6 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import sys -import os -import unittest import pytest from pygccxml import parser diff --git a/tests/test_elaborated_types.py b/tests/test_elaborated_types.py index b56aae3f..36f82691 100644 --- a/tests/test_elaborated_types.py +++ b/tests/test_elaborated_types.py @@ -3,75 +3,58 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): +TEST_FILES = ['test_elaborated_types.hpp'] - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_elaborated_types.hpp" - def test_is_elaborated_type(self): - """ - Test for the is_elaborated function - """ +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - if self.config.castxml_epic_version != 1: - return - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) +def test_is_elaborated_type(global_ns): + """ + Test for the is_elaborated function + """ - if self.config.xml_generator_from_xml_file.is_castxml1: - for specifier in ["class", "struct", "enum", "union"]: - self._test_impl_yes(global_ns, specifier) - self._test_impl_no(global_ns, specifier) - self._test_arg_impl(global_ns, specifier) + for specifier in ["class", "struct", "enum", "union"]: + _test_impl_yes(specifier=specifier, global_ns=global_ns) + _test_impl_no(specifier=specifier, global_ns=global_ns) + _test_arg_impl(specifier=specifier, global_ns=global_ns) - def _test_impl_yes(self, global_ns, specifier): - yes = global_ns.namespace(name="::elaborated_t::yes_" + specifier) - for decl in yes.declarations: - self.assertTrue( - declarations.is_elaborated(decl.decl_type)) - self.assertIn(specifier, str(decl.decl_type)) - def _test_impl_no(self, global_ns, specifier): - no = global_ns.namespace(name="::elaborated_t::no_" + specifier) - for decl in no.declarations: - self.assertFalse( - declarations.is_elaborated(decl.decl_type)) - self.assertNotIn(specifier, str(decl.decl_type)) +def _test_impl_yes(specifier, global_ns): + yes = global_ns.namespace(name="::elaborated_t::yes_" + specifier) + for decl in yes.declarations: + assert declarations.is_elaborated(decl.decl_type) is True - def _test_arg_impl(self, global_ns, specifier): - decls = global_ns.namespace( - name="::elaborated_t::arguments_" + specifier) - for decl in decls.declarations: - # The first argument is not elaborated - no = decl.arguments[0].decl_type - # The second argument is always elaborated - yes = decl.arguments[1].decl_type - self.assertTrue(declarations.is_elaborated(yes)) - self.assertFalse(declarations.is_elaborated(no)) - self.assertIn(specifier, str(yes)) - self.assertNotIn(specifier, str(no)) +def _test_impl_no(specifier, global_ns): + no = global_ns.namespace(name="::elaborated_t::no_" + specifier) + for decl in no.declarations: + assert declarations.is_elaborated(decl.decl_type) is False -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +def _test_arg_impl(specifier, global_ns): + decls = global_ns.namespace( + name="::elaborated_t::arguments_" + specifier) + for decl in decls.declarations: + # The first argument is not elaborated + no = decl.arguments[0].decl_type + # The second argument is always elaborated + yes = decl.arguments[1].decl_type + assert declarations.is_elaborated(yes) is True + assert declarations.is_elaborated(no) is False diff --git a/tests/test_example.py b/tests/test_example.py index 7347d684..12ff9136 100644 --- a/tests/test_example.py +++ b/tests/test_example.py @@ -5,59 +5,29 @@ import os import fnmatch -import unittest import subprocess -from . import parser_test_case +def test_example(): + """Runs the example in the docs directory""" -class Test(parser_test_case.parser_test_case_t): + env = os.environ.copy() - def test_example(self): - """Runs the example in the docs directory""" + # Get the path to current directory + path = os.path.dirname(os.path.realpath(__file__)) + # Set the COVERAGE_PROCESS_START env. variable. + # Allows to cover files run in a subprocess + # http://nedbatchelder.com/code/coverage/subprocess.html + env["COVERAGE_PROCESS_START"] = path + "/../.coveragerc" - env = os.environ.copy() + # Find all the examples files + file_paths = [] + for root, _, filenames in os.walk(path + "/../docs/examples"): + for file_path in fnmatch.filter(filenames, '*.py'): + file_paths.append(os.path.join(root, file_path)) - # Get the path to current directory - path = os.path.dirname(os.path.realpath(__file__)) - # Set the COVERAGE_PROCESS_START env. variable. - # Allows to cover files run in a subprocess - # http://nedbatchelder.com/code/coverage/subprocess.html - env["COVERAGE_PROCESS_START"] = path + "/../.coveragerc" - - # Find all the examples files - file_paths = [] - for root, dirnames, filenames in os.walk(path + "/../docs/examples"): - for file_path in fnmatch.filter(filenames, '*.py'): - file_paths.append(os.path.join(root, file_path)) - - for file_path in file_paths: - - if "elaborated" in file_path and\ - self.config.castxml_epic_version != 1: - # Don't run this test if the castxml_epic_version was not - # set to 1, because the test needs to be able to run with - # that version - continue - - return_code = subprocess.call( - ["python", path + "/example_tester_wrap.py", file_path], - env=env) - self.assertFalse( - return_code, - msg="The example %s did not run correctly" % file_path) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + for file_path in file_paths: + return_code = subprocess.call( + ["python", path + "/example_tester_wrap.py", file_path], + env=env) + assert return_code == 0 diff --git a/tests/test_file_cache.py b/tests/test_file_cache.py index e03b0072..4fcb4723 100644 --- a/tests/test_file_cache.py +++ b/tests/test_file_cache.py @@ -4,95 +4,71 @@ # See http://www.boost.org/LICENSE_1_0.txt import os -import sys -import unittest -import subprocess from . import autoconfig -from . import parser_test_case from pygccxml import parser - -class Test(parser_test_case.parser_test_case_t): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = os.path.join(autoconfig.data_directory, 'core_cache.hpp') - self.cache_file = os.path.join( +TEST_FILE = os.path.join(autoconfig.data_directory, 'core_cache.hpp') +cache_file = os.path.join( autoconfig.data_directory, 'pygccxml.cache') - if os.path.exists(self.cache_file) and os.path.isfile(self.cache_file): - os.remove(self.cache_file) - - def touch(self): - # Need to change file. - with open(self.header, "a+") as header: - header.write("//touch") - - def test_update(self): - - # Save the content of the header file for later - with open(self.header, "r") as old_header: - content = old_header.read() - - declarations = parser.parse([self.header], self.config) - cache = parser.file_cache_t(self.cache_file) - cache.update( - source_file=self.header, - configuration=self.config, - declarations=declarations, - included_files=[]) - self.assertTrue( - declarations == cache.cached_value( - self.header, - self.config), - "cached declarations and source declarations are different") - self.touch() - self.assertTrue( - cache.cached_value(self.header, self.config) is None, - "cache didn't recognize that some files on disk has been changed") - - # We wrote a //touch in the header file. Just replace the file with the - # original content. The touched file would be sometimes commited by - # error as it was modified. - with open(self.header, "w") as new_header: - new_header.write(content) - - def test_from_file(self): - declarations = parser.parse([self.header], self.config) - cache = parser.file_cache_t(self.cache_file) - cache.update( - source_file=self.header, - configuration=self.config, - declarations=declarations, - included_files=[]) - self.assertTrue( - declarations == cache.cached_value( - self.header, - self.config), - "cached declarations and source declarations are different") - cache.flush() - cache = parser.file_cache_t(self.cache_file) - self.assertTrue( - declarations == cache.cached_value( - self.header, - self.config), - ("cached declarations and source declarations are different, " + - "after pickling")) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) -if __name__ == "__main__": - run_suite() +def reset_cache(): + if os.path.exists(cache_file) and os.path.isfile(cache_file): + os.remove(cache_file) + + +def touch(): + # Need to change file. + with open(TEST_FILE, "a+") as header: + header.write("//touch") + + +def test_update_cache(): + reset_cache() + config = autoconfig.cxx_parsers_cfg.config.clone() + + # Save the content of the header file for later + with open(TEST_FILE, "r") as old_header: + content = old_header.read() + + declarations = parser.parse([TEST_FILE], config) + cache = parser.file_cache_t(cache_file) + cache.update( + source_file=TEST_FILE, + configuration=config, + declarations=declarations, + included_files=[]) + assert declarations == cache.cached_value( + TEST_FILE, + config) + touch() + assert cache.cached_value(TEST_FILE, config) is None + + # We wrote a //touch in the header file. Just replace the file with the + # original content. The touched file would be sometimes commited by + # error as it was modified. + with open(TEST_FILE, "w") as new_header: + new_header.write(content) + + +def test_cache_from_file(): + reset_cache() + config = autoconfig.cxx_parsers_cfg.config.clone() + declarations = parser.parse([TEST_FILE], config) + cache = parser.file_cache_t(cache_file) + cache.update( + source_file=TEST_FILE, + configuration=config, + declarations=declarations, + included_files=[]) + assert declarations == cache.cached_value( + TEST_FILE, + config) + cache.flush() + cache = parser.file_cache_t(cache_file) + assert declarations == cache.cached_value( + TEST_FILE, + config) diff --git a/tests/test_filters_tester.py b/tests/test_filters_tester.py index e3d4d747..699c0e74 100644 --- a/tests/test_filters_tester.py +++ b/tests/test_filters_tester.py @@ -3,102 +3,81 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations +TEST_FILES = ['declarations_calldef.hpp'] -class Test(parser_test_case.parser_test_case_t): - global_ns = None - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'declarations_calldef.hpp' - self.global_ns = None - - def setUp(self): - if not Test.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.global_ns.init_optimizer() - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.global_ns = Test.global_ns - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - def test_regex(self): - criteria = declarations.regex_matcher_t( - 'oper.*', - lambda decl: decl.name) - operators = declarations.matcher.find(criteria, self.global_ns) - operators = [d for d in operators if not d.is_artificial] - self.assertTrue(6 == len(operators)) - - def test_access_type(self): - criteria = declarations.access_type_matcher_t( - declarations.ACCESS_TYPES.PUBLIC) - public_members = declarations.matcher.find(criteria, self.global_ns) - public_members = [d for d in public_members if not d.is_artificial] - if self.xml_generator_from_xml_file.is_castxml: - nbr = len(public_members) - self.assertTrue(nbr in [17, 21]) - if nbr == 21: - # We are using llvm 3.9, see bug #32. Make sure the 4 names - # are still there - names = ["isa", "flags", "str", "length"] - for name in names: - self.assertTrue( - names in [mbr.name for mbr in public_members]) - else: - self.assertTrue(17 == len(public_members)) - - def test_or_matcher(self): - criteria1 = declarations.regex_matcher_t( - "oper.*", - lambda decl: decl.name) - criteria2 = declarations.access_type_matcher_t( - declarations.ACCESS_TYPES.PUBLIC) - found = declarations.matcher.find( - criteria1 | criteria2, - self.global_ns) - found = [d for d in found if not d.is_artificial] - self.assertTrue(len(found) != 35) - - def test_and_matcher(self): - criteria1 = declarations.regex_matcher_t( - 'oper.*', - lambda decl: decl.name) - criteria2 = declarations.access_type_matcher_t( - declarations.ACCESS_TYPES.PUBLIC) - found = declarations.matcher.find( - criteria1 & criteria2, - self.global_ns) - found = [d for d in found if not d.is_artificial] - self.assertTrue(len(found) <= 6) - - def test_not_matcher(self): - criteria1 = declarations.regex_matcher_t( - 'oper.*', - lambda decl: decl.name) - found = declarations.matcher.find(~(~criteria1), self.global_ns) - found = [d for d in found if not d.is_artificial] - self.assertTrue(len(found) == 6) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns + + +def test_regex(global_ns): + criteria = declarations.regex_matcher_t( + 'oper.*', + lambda decl: decl.name) + operators = declarations.matcher.find(criteria, global_ns) + operators = [d for d in operators if not d.is_artificial] + assert len(operators) == 6 + + +def test_access_type(global_ns): + criteria = declarations.access_type_matcher_t( + declarations.ACCESS_TYPES.PUBLIC) + public_members = declarations.matcher.find(criteria, global_ns) + public_members = [d for d in public_members if not d.is_artificial] + + nbr = len(public_members) + assert nbr in [17, 21] + if nbr == 21: + # We are using llvm 3.9, see bug #32. Make sure the 4 names + # are still there + names = ["isa", "flags", "str", "length"] + for name in names: + assert names in [mbr.name for mbr in public_members] + + +def test_or_matcher(global_ns): + criteria1 = declarations.regex_matcher_t( + "oper.*", + lambda decl: decl.name) + criteria2 = declarations.access_type_matcher_t( + declarations.ACCESS_TYPES.PUBLIC) + found = declarations.matcher.find( + criteria1 | criteria2, + global_ns) + found = [d for d in found if not d.is_artificial] + assert len(found) != 35 + + +def test_and_matcher(global_ns): + criteria1 = declarations.regex_matcher_t( + 'oper.*', + lambda decl: decl.name) + criteria2 = declarations.access_type_matcher_t( + declarations.ACCESS_TYPES.PUBLIC) + found = declarations.matcher.find( + criteria1 & criteria2, + global_ns) + found = [d for d in found if not d.is_artificial] + assert len(found) <= 6 + + +def test_not_matcher(global_ns): + criteria1 = declarations.regex_matcher_t( + 'oper.*', + lambda decl: decl.name) + found = declarations.matcher.find(~(~criteria1), global_ns) + found = [d for d in found if not d.is_artificial] + assert len(found) == 6 diff --git a/tests/test_find_noncopyable_vars.py b/tests/test_find_noncopyable_vars.py index 78622e3f..8b31d9d2 100644 --- a/tests/test_find_noncopyable_vars.py +++ b/tests/test_find_noncopyable_vars.py @@ -3,48 +3,38 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): +TEST_FILES = ['find_noncopyable_vars.hpp'] - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "find_noncopyable_vars.hpp" - decls = parser.parse([self.header], self.config) - self.global_ns = declarations.get_global_namespace(decls) - def test(self): - """ - Test the find_noncopyable_vars function +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - """ - # The ptr1 variable in the holder struct can be copied, - # but not the ptr2 variable - holder = self.global_ns.class_("holder") - nc_vars = declarations.find_noncopyable_vars(holder) - self.assertEqual(len(nc_vars), 1) - self.assertEqual(nc_vars[0].name, "ptr2") - self.assertTrue(declarations.is_pointer(nc_vars[0].decl_type)) - self.assertTrue(declarations.is_const(nc_vars[0].decl_type)) +def test_find_noncopyable_vars(global_ns): + """ + Test the find_noncopyable_vars function + """ -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + # The ptr1 variable in the holder struct can be copied, + # but not the ptr2 variable + holder = global_ns.class_("holder") + nc_vars = declarations.find_noncopyable_vars(holder) + assert len(nc_vars) == 1 + assert nc_vars[0].name == "ptr2" + assert declarations.is_pointer(nc_vars[0].decl_type) is True + assert declarations.is_const(nc_vars[0].decl_type) is True diff --git a/tests/test_free_operators.py b/tests/test_free_operators.py index 936b63f1..c3e2d193 100644 --- a/tests/test_free_operators.py +++ b/tests/test_free_operators.py @@ -3,47 +3,33 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): +TEST_FILES = ['free_operators.hpp'] - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'free_operators.hpp' - self.global_ns = None - def setUp(self): - reader = parser.source_reader_t(self.config) - decls = reader.read_file(self.header) - self.global_ns = declarations.get_global_namespace(decls) +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - def test(self): - fo = self.global_ns.namespace('free_operators') - number = fo.class_('number') - rational = fo.class_('rational') - for oper in fo.free_operators(): - if number.name in str(oper): - self.assertTrue(number in oper.class_types) - if rational.name in str(oper): - self.assertTrue(rational in oper.class_types) - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +def test_free_operators(global_ns): + fo = global_ns.namespace('free_operators') + number = fo.class_('number') + rational = fo.class_('rational') + for oper in fo.free_operators(): + if number.name in str(oper): + assert number in oper.class_types + if rational.name in str(oper): + assert rational in oper.class_types diff --git a/tests/test_function_pointer.py b/tests/test_function_pointer.py index 2c32393a..95e80186 100644 --- a/tests/test_function_pointer.py +++ b/tests/test_function_pointer.py @@ -3,91 +3,72 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_function_pointer.hpp" - - def test_function_pointer(self): - """ - Test working with pointers and function pointers. - - """ - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - # Test on a function pointer - criteria = declarations.variable_matcher(name="func1") - variables = declarations.matcher.find(criteria, global_ns) - - self.assertTrue(variables[0].name == "func1") - self.assertTrue( - isinstance(variables[0].decl_type, declarations.pointer_t)) - self.assertTrue( - str(variables[0].decl_type) == "void (*)( int,double )") - self.assertTrue( - declarations.is_calldef_pointer(variables[0].decl_type)) - self.assertTrue( - isinstance(declarations.remove_pointer(variables[0].decl_type), - declarations.free_function_type_t)) - - # Get the function (free_function_type_t) and test the return and - # argument types - function = variables[0].decl_type.base - self.assertTrue(isinstance(function.return_type, declarations.void_t)) - self.assertTrue( - isinstance(function.arguments_types[0], declarations.int_t)) - self.assertTrue( - isinstance(function.arguments_types[1], declarations.double_t)) - - # Test on a normal pointer - criteria = declarations.variable_matcher(name="myPointer") - variables = declarations.matcher.find(criteria, global_ns) - - self.assertTrue(variables[0].name == "myPointer") - self.assertTrue( - isinstance(variables[0].decl_type, declarations.pointer_t)) - self.assertFalse( - declarations.is_calldef_pointer(variables[0].decl_type)) - self.assertTrue( - isinstance(declarations.remove_pointer(variables[0].decl_type), - declarations.volatile_t)) - - # Test on function pointer in struct (x8) - for d in global_ns.declarations: - if d.name == "x8": - self.assertTrue( - isinstance(d.decl_type, declarations.pointer_t)) - self.assertTrue(declarations.is_calldef_pointer(d.decl_type)) - self.assertTrue( - isinstance( - declarations.remove_pointer(d.decl_type), - declarations.member_function_type_t)) - self.assertTrue( - str(declarations.remove_pointer(d.decl_type)) == - "void ( ::some_struct_t::* )( )") - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +TEST_FILES = ['test_function_pointer.hpp'] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns + + +def test_function_pointer(global_ns): + """ + Test working with pointers and function pointers. + + """ + + # Test on a function pointer + criteria = declarations.variable_matcher(name="func1") + variables = declarations.matcher.find(criteria, global_ns) + + assert variables[0].name == "func1" + assert isinstance(variables[0].decl_type, declarations.pointer_t) is True + assert str(variables[0].decl_type) == "void (*)( int,double )" + assert declarations.is_calldef_pointer(variables[0].decl_type) is True + assert isinstance( + declarations.remove_pointer(variables[0].decl_type), + declarations.free_function_type_t + ) is True + + # Get the function (free_function_type_t) and test the return and + # argument types + function = variables[0].decl_type.base + assert isinstance(function.return_type, declarations.void_t) + assert isinstance(function.arguments_types[0], declarations.int_t) + assert isinstance(function.arguments_types[1], declarations.double_t) + + # Test on a normal pointer + criteria = declarations.variable_matcher(name="myPointer") + variables = declarations.matcher.find(criteria, global_ns) + + assert variables[0].name == "myPointer" + assert isinstance(variables[0].decl_type, declarations.pointer_t) + assert declarations.is_calldef_pointer(variables[0].decl_type) is False + assert isinstance( + declarations.remove_pointer(variables[0].decl_type), + declarations.volatile_t + ) is True + + # Test on function pointer in struct (x8) + for d in global_ns.declarations: + if d.name == "x8": + assert isinstance(d.decl_type, declarations.pointer_t) is True + assert declarations.is_calldef_pointer(d.decl_type) + assert isinstance( + declarations.remove_pointer(d.decl_type), + declarations.member_function_type_t + ) is True + assert str(declarations.remove_pointer(d.decl_type)) == \ + "void ( ::some_struct_t::* )( )" diff --git a/tests/test_function_traits.py b/tests/test_function_traits.py index 63135210..96280bfd 100644 --- a/tests/test_function_traits.py +++ b/tests/test_function_traits.py @@ -3,49 +3,32 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations +TEST_FILES = ['covariant_returns.hpp'] -class Test(parser_test_case.parser_test_case_t): - global_ns = None +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'covariant_returns.hpp' - def setUp(self): - if not Test.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.global_ns.init_optimizer() +def test_is_same_function(global_ns): + d = global_ns.class_('better_algorithm_t') + b = global_ns.class_('algorithm_t') - def test_is_same_function(self): - d = self.global_ns.class_('better_algorithm_t') - b = self.global_ns.class_('algorithm_t') + df = d.member_function('f') + bf = b.member_function('f') - df = d.member_function('f') - bf = b.member_function('f') - - self.assertTrue( - id(df) != id(bf) and declarations.is_same_function(df, bf)) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + assert id(df) != id(bf) + assert declarations.is_same_function(df, bf) is True diff --git a/tests/test_order.py b/tests/test_order.py index 97b50d5a..bcb4832d 100644 --- a/tests/test_order.py +++ b/tests/test_order.py @@ -3,100 +3,83 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_order.hpp" - - def test_order(self): - """ - Test order of const, volatile, etc... in decl_string. - - The convention in pygccxml is that const and volatile qualifiers - are placed on the right of their `base` type. - - """ - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - c1 = global_ns.variable("c1") - c2 = global_ns.variable("c2") - self.assertEqual(c1.decl_type.decl_string, "int const") - self.assertEqual(c2.decl_type.decl_string, "int const") - - cptr1 = global_ns.variable("cptr1") - cptr2 = global_ns.variable("cptr2") - self.assertEqual(cptr1.decl_type.decl_string, "int const * const") - self.assertEqual(cptr2.decl_type.decl_string, "int const * const") - - v1 = global_ns.variable("v1") - v2 = global_ns.variable("v2") - self.assertEqual(v1.decl_type.decl_string, "int volatile") - self.assertEqual(v2.decl_type.decl_string, "int volatile") - - vptr1 = global_ns.variable("vptr1") - vptr2 = global_ns.variable("vptr2") - decl_string = "int volatile * volatile" - self.assertEqual(vptr1.decl_type.decl_string, decl_string) - self.assertEqual(vptr2.decl_type.decl_string, decl_string) - - cv1 = global_ns.variable("cv1") - cv2 = global_ns.variable("cv2") - cv3 = global_ns.variable("cv3") - cv4 = global_ns.variable("cv4") - self.assertEqual(cv1.decl_type.decl_string, "int const volatile") - self.assertEqual(cv2.decl_type.decl_string, "int const volatile") - self.assertEqual(cv3.decl_type.decl_string, "int const volatile") - self.assertEqual(cv4.decl_type.decl_string, "int const volatile") - - cvptr1 = global_ns.variable("cvptr1") - cvptr2 = global_ns.variable("cvptr2") - cvptr3 = global_ns.variable("cvptr3") - cvptr4 = global_ns.variable("cvptr4") - decl_string = "int const volatile * const volatile" - self.assertEqual(cvptr1.decl_type.decl_string, decl_string) - self.assertEqual(cvptr2.decl_type.decl_string, decl_string) - self.assertEqual(cvptr3.decl_type.decl_string, decl_string) - self.assertEqual(cvptr4.decl_type.decl_string, decl_string) - - ac1 = global_ns.variable("ac1") - ac2 = global_ns.variable("ac2") - self.assertEqual(ac1.decl_type.decl_string, "int const [2]") - self.assertEqual(ac2.decl_type.decl_string, "int const [2]") - - acptr1 = global_ns.variable("acptr1") - acptr2 = global_ns.variable("acptr2") - self.assertEqual(acptr1.decl_type.decl_string, "int const * const [2]") - self.assertEqual(acptr2.decl_type.decl_string, "int const * const [2]") - - class_a = global_ns.variable("classA") - if self.config.xml_generator_from_xml_file.is_castxml1: - # The elaborated type specifier (class) is on the left - self.assertEqual(class_a.decl_type.decl_string, "class ::A const") - else: - self.assertEqual(class_a.decl_type.decl_string, "::A const") - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() +TEST_FILES = ['test_order.hpp'] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + return global_ns + + +def test_order(global_ns): + """ + Test order of const, volatile, etc... in decl_string. + + The convention in pygccxml is that const and volatile qualifiers + are placed on the right of their `base` type. + + """ + c1 = global_ns.variable("c1") + c2 = global_ns.variable("c2") + assert c1.decl_type.decl_string == "int const" + assert c2.decl_type.decl_string == "int const" + + cptr1 = global_ns.variable("cptr1") + cptr2 = global_ns.variable("cptr2") + assert cptr1.decl_type.decl_string == "int const * const" + assert cptr2.decl_type.decl_string == "int const * const" + + v1 = global_ns.variable("v1") + v2 = global_ns.variable("v2") + assert v1.decl_type.decl_string == "int volatile" + assert v2.decl_type.decl_string == "int volatile" + + vptr1 = global_ns.variable("vptr1") + vptr2 = global_ns.variable("vptr2") + decl_string = "int volatile * volatile" + assert vptr1.decl_type.decl_string == decl_string + assert vptr2.decl_type.decl_string == decl_string + + cv1 = global_ns.variable("cv1") + cv2 = global_ns.variable("cv2") + cv3 = global_ns.variable("cv3") + cv4 = global_ns.variable("cv4") + assert cv1.decl_type.decl_string == "int const volatile" + assert cv2.decl_type.decl_string == "int const volatile" + assert cv3.decl_type.decl_string == "int const volatile" + assert cv4.decl_type.decl_string == "int const volatile" + + cvptr1 = global_ns.variable("cvptr1") + cvptr2 = global_ns.variable("cvptr2") + cvptr3 = global_ns.variable("cvptr3") + cvptr4 = global_ns.variable("cvptr4") + decl_string = "int const volatile * const volatile" + assert cvptr1.decl_type.decl_string == decl_string + assert cvptr2.decl_type.decl_string == decl_string + assert cvptr3.decl_type.decl_string == decl_string + assert cvptr4.decl_type.decl_string == decl_string + + ac1 = global_ns.variable("ac1") + ac2 = global_ns.variable("ac2") + assert ac1.decl_type.decl_string, "int const [2]" + assert ac2.decl_type.decl_string, "int const [2]" + + acptr1 = global_ns.variable("acptr1") + acptr2 = global_ns.variable("acptr2") + assert acptr1.decl_type.decl_string == "int const * const [2]" + assert acptr2.decl_type.decl_string == "int const * const [2]" + + class_a = global_ns.variable("classA") + assert class_a.decl_type.decl_string == "::A const"