From bcd6796bf9695e35f7489f8f1d8421c7b5289d24 Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Wed, 6 Nov 2024 23:02:07 +0100 Subject: [PATCH] tests: refactor / simplify --- tests/test_type_traits.py | 851 +++++++++++------------- tests/test_typedefs.py | 105 +-- tests/test_unnamed_classes.py | 171 +++-- tests/test_unnamed_enums_bug.py | 156 ++--- tests/test_utils.py | 71 +- tests/test_va_list_tag_removal.py | 184 +++-- tests/test_variable_matcher.py | 104 ++- tests/test_vector_traits.py | 161 +++-- tests/test_warn_missing_include_dirs.py | 59 +- tests/test_xml_generators.py | 132 ++-- tests/test_xmlfile_reader.py | 78 +-- 11 files changed, 888 insertions(+), 1184 deletions(-) diff --git a/tests/test_type_traits.py b/tests/test_type_traits.py index abcde5f1..c3fca574 100644 --- a/tests/test_type_traits.py +++ b/tests/test_type_traits.py @@ -3,471 +3,402 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest +import pytest from . import autoconfig -from . import parser_test_case from pygccxml import parser from pygccxml import declarations -class Test(parser_test_case.parser_test_case_t): +TEST_FILES = [ + "type_traits.hpp", +] + + +@pytest.fixture +def decls(): COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - declarations = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'type_traits.hpp' - self.declarations = None - - def setUp(self): - if not Test.declarations: - Test.declarations = parser.parse([self.header], self.config) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.declarations = Test.declarations - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - def __test_type_category(self, ns_name, controller): - ns_control = declarations.find_declaration( - self.declarations, - decl_type=declarations.namespace_t, - name=ns_name) - self.assertTrue(ns_control, "unable to find '%s' namespace" % ns_name) - ns_yes = declarations.find_declaration( - ns_control, - decl_type=declarations.namespace_t, - name='yes') - self.assertTrue(ns_yes, "unable to find 'yes' namespace") - ns_no = declarations.find_declaration( - ns_control, - decl_type=declarations.namespace_t, - name='no') - self.assertTrue(ns_no, "unable to find 'no' namespace") - er = 'for type "%s" the answer to the question "%s" should be True' - for decl in ns_yes.declarations: - if isinstance(decl, declarations.variable_t): - self.assertTrue( - controller(decl.decl_type), - er % (decl.decl_type.decl_string, ns_name)) - elif isinstance(decl, declarations.calldef_t) and \ - decl.name.startswith('test_'): - continue - else: - self.assertTrue( - controller(decl), er % (decl.decl_string, ns_name)) - er = 'for type "%s" the answer to the question "%s" should be False' - generator = self.xml_generator_from_xml_file - for decl in ns_no.declarations: - if isinstance(decl, declarations.calldef_t) and \ - decl.name.startswith('test_'): - continue - - if generator.is_castxml1 or ( - generator.is_castxml and - float(generator.xml_output_version) < 1.138): - if decl.name in ['const_item', 'const_container']: - # Skip this test to workaround CastXML bug. - # See https://github.com/CastXML/CastXML/issues/55 - continue - - self.assertFalse( - controller(decl), - er % (decl.decl_string, ns_name)) - - def __test_type_transformation(self, ns_name, transformer): - ns_control = declarations.find_declaration( - self.declarations, - decl_type=declarations.namespace_t, - name=ns_name) - self.assertTrue(ns_control, "unable to find '%s' namespace" % ns_name) - ns_before = declarations.find_declaration( - ns_control, - decl_type=declarations.namespace_t, - name='before') - self.assertTrue(ns_before, "unable to find 'before' namespace") - ns_after = declarations.find_declaration( - ns_control, - decl_type=declarations.namespace_t, - name='after') - self.assertTrue(ns_after, "unable to find 'after' namespace") - - for tbefore in ns_before.declarations: - tafter = declarations.find_declaration( - ns_after, - name=tbefore.name) - self.assertTrue( - tafter, - "unable to find transformed type definition for type '%s'" % - tbefore.decl_string) - transformed = transformer(tbefore) - self.assertTrue( - declarations.is_same( - transformed, - tafter), - ("there is a difference between expected type '{0}' " + - "and result '{1}'. typedef name: {2}").format( - declarations.remove_declarated(tafter).decl_string, - declarations.remove_declarated(transformed).decl_string, - tbefore.decl_string)) - - def test_is_enum(self): - self.__test_type_category('is_enum', declarations.is_enum) - - def test_is_void(self): - self.__test_type_category('is_void', declarations.is_void) - - def test_is_bool(self): - self.__test_type_category('is_bool', declarations.is_bool) - - def test_is_integral(self): - self.__test_type_category('is_integral', declarations.is_integral) - - def test_is_pointer(self): - self.__test_type_category('is_pointer', declarations.is_pointer) - - def test_is_void_pointer(self): - self.__test_type_category( - 'is_void_pointer', declarations.is_void_pointer) - - def test_is_const(self): - self.__test_type_category('is_const', declarations.is_const) - - def test_is_volatile(self): - self.__test_type_category('is_volatile', declarations.is_volatile) - - def test_is_reference(self): - self.__test_type_category('is_reference', declarations.is_reference) - - def test_is_floating_point(self): - self.__test_type_category( - 'is_floating_point', - declarations.is_floating_point) - - def test_is_array(self): - self.__test_type_category('is_array', declarations.is_array) - - def test_is_fundamental(self): - self.__test_type_category( - 'is_fundamental', - declarations.is_fundamental) - - def test_is_noncopyable(self): - self.__test_type_category( - 'is_noncopyable', - declarations.is_noncopyable) - - def test_is_std_ostream(self): - self.__test_type_category( - 'is_std_ostream', - declarations.is_std_ostream) - - def test_is_std_wostream(self): - self.__test_type_category( - 'is_std_wostream', - declarations.is_std_wostream) - - def test_is_calldef_pointer(self): - self.__test_type_category( - 'is_calldef_pointer', - declarations.is_calldef_pointer) - - def test_has_trivial_constructor(self): - self.__test_type_category( - 'has_trivial_constructor', - declarations.has_trivial_constructor) - - def test_has_public_constructor(self): - self.__test_type_category( - 'has_public_constructor', - declarations.has_public_constructor) - - def test_has_public_destructor(self): - self.__test_type_category( - 'has_public_destructor', - declarations.has_public_destructor) - - def test_has_any_non_copyconstructor(self): - self.__test_type_category( - 'has_any_non_copyconstructor', - declarations.has_any_non_copyconstructor) - - def test_has_copy_constructor(self): - self.__test_type_category( - 'has_copy_constructor', - declarations.has_copy_constructor) - - def test_is_base_and_derived(self): - ns = declarations.find_declaration( - self.declarations, - decl_type=declarations.namespace_t, - name='is_base_and_derived') - self.assertTrue(ns, "unable to find 'is_base_and_derived' namespace") - base = declarations.find_declaration( - ns.declarations, - decl_type=declarations.class_t, - name='base') - derived = declarations.find_declaration( - ns.declarations, - decl_type=declarations.class_t, - name='derived') - self.assertTrue( - base and derived and declarations.is_base_and_derived( - base, - derived)) - self.assertTrue( - base and derived and - declarations.is_base_and_derived(base, (derived, derived))) - - unrelated1 = declarations.find_declaration( - ns.declarations, - decl_type=declarations.class_t, - name='unrelated1') - - unrelated2 = declarations.find_declaration( - ns.declarations, - decl_type=declarations.class_t, - name='unrelated2') - self.assertTrue( - base and derived and not declarations.is_base_and_derived( - unrelated1, - unrelated2)) - - def test_is_same(self): - self.assertTrue( - declarations.is_same( - declarations.int_t, - declarations.int_t)) - self.assertFalse( - declarations.is_same( - declarations.int_t, - declarations.float_t)) - - def test_remove_const(self): - self.__test_type_transformation( - 'remove_const', - declarations.remove_const) - - def test_remove_reference(self): - self.__test_type_transformation( - 'remove_reference', - declarations.remove_reference) - - def test_remove_volatile(self): - self.__test_type_transformation( - 'remove_volatile', - declarations.remove_volatile) - - def test_remove_cv(self): - self.__test_type_transformation('remove_cv', declarations.remove_cv) - - def test_remove_pointer(self): - self.__test_type_transformation( - 'remove_pointer', - declarations.remove_pointer) - - def test_is_unary_binary_operator(self): - operator_not = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::dummy::operator!') - self.assertTrue(operator_not, 'operator! was not found') - self.assertTrue( - declarations.is_unary_operator(operator_not), - 'operator! should be idenitified as unary operator') - self.assertTrue( - not declarations.is_binary_operator(operator_not), - 'operator! should be idenitified as unary operator') - - operator_class_p = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::dummy::operator+') - self.assertTrue(operator_class_p, 'operator+ was not found') - self.assertTrue( - not declarations.is_unary_operator(operator_class_p), - 'operator+ should be idenitified as binary operator') - self.assertTrue( - declarations.is_binary_operator(operator_class_p), - 'operator! should be idenitified as binary operator') - - operator_class_pp = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::dummy::operator++') - self.assertTrue(operator_class_pp, 'operator++ was not found') - self.assertTrue( - declarations.is_unary_operator(operator_class_pp), - 'operator++ should be idenitified as unary operator') - self.assertTrue( - not declarations.is_binary_operator(operator_class_pp), - 'operator++ should be idenitified as unary operator') - - operator_pp = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::operator++') - self.assertTrue(operator_pp, 'operator++ was not found') - self.assertTrue( - declarations.is_unary_operator(operator_pp), - 'operator++ should be idenitified as unary operator') - self.assertTrue( - not declarations.is_binary_operator(operator_pp), - 'operator++ should be idenitified as unary operator') - - operator_mm = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::operator*') - self.assertTrue(operator_mm, 'operator-- was not found') - self.assertTrue( - not declarations.is_unary_operator(operator_mm), - 'operator-- should be idenitified as binary operator') - self.assertTrue( - declarations.is_binary_operator(operator_mm), - 'operator-- should be idenitified as binray operator') - - operator_pe = declarations.find_declaration( - self.declarations, - decl_type=declarations.operator_t, - fullname='::is_unary_operator::operator+=') - self.assertTrue(operator_pe, 'operator+= was not found') - self.assertTrue( - not declarations.is_unary_operator(operator_pe), - 'operator+= should be idenitified as binary operator') - self.assertTrue( - declarations.is_binary_operator(operator_pe), - 'operator+= should be idenitified as binray operator') - - def __is_convertible_impl(self, decl): - defs = decl.bases[0].related_class.declarations - source_type = declarations.find_declaration(defs, name='source_type') - target_type = declarations.find_declaration(defs, name='target_type') - expected_type = declarations.find_declaration( - defs, - name='expected', - decl_type=declarations.enumeration_t) - expected_value = bool(expected_type.get_name2value_dict()['value']) - self.assertTrue( - expected_value == declarations.is_convertible( - source_type, - target_type), - 'Check conversion failed for ' + - decl.name) - - def test_is_convertible(self): - ns_is_convertible = declarations.find_declaration( - self.declarations, - decl_type=declarations.namespace_t, - name="is_convertible") - - self.assertTrue( - ns_is_convertible, - "namespace is_convertible was not found") - for tester in [ - decl for decl in ns_is_convertible.declarations if - decl.name.startswith('x')]: - - self.__is_convertible_impl(tester) - - -class missing_decls_tester_t(unittest.TestCase): - - def test(self): - config = autoconfig.cxx_parsers_cfg.config - code = "struct const_item{ const int values[10]; };" - global_ns = parser.parse_string(code, config)[0] - ci = global_ns.class_('const_item') - generator = config.xml_generator_from_xml_file - if generator.is_castxml1 or ( - generator.is_castxml and - float(generator.xml_output_version) >= 1.138): - # Prior to version 1.138, CastXML would incorrectly create a - # default constructor definition. - # See https://github.com/CastXML/CastXML/issues/55 - # Copy constructor, destructor, variable - self.assertEqual(len(ci.declarations), 3) - -# class tester_diff_t( parser_test_case.parser_test_case_t ): - # COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - # declarations = None - # def __init__(self, *args ): - # parser_test_case.parser_test_case_t.__init__( self, *args ) - # self.header = 'type_traits.hpp' - # self.declarations = None - - # def setUp(self): - # if not Test.declarations: - # Test.declarations = parser.parse([self.header], self.config) - # self.declarations = Test.declarations - - # def test( self ): - # x = declarations.find_declaration( self.declarations - # , decl_type=declarations.typedef_t - # , name="s2s_multimap_type" ) - # print declarations.is_noncopyable( x) - # declarations.print_declarations( - # [declarations.class_traits.get_declaration( x )] ) - - -class class_traits_tester_t(unittest.TestCase): - - def test_get_declaration(self): - code = """ - namespace A{ - struct B{ - int c; - }; - - template - struct C: public T{ - int d; - }; - - template - struct D{ - int dD; - }; - - typedef C easy; - typedef D Deasy; - - inline void instantiate(){ - int val = sizeof(easy); - } - - } - """ - - global_ns = parser.parse_string( - code, - autoconfig.cxx_parsers_cfg.config) - global_ns = declarations.get_global_namespace(global_ns) - easy = global_ns.typedef('easy') - declarations.class_traits.get_declaration(easy) - deasy = global_ns.typedef('Deasy') - d_a = declarations.class_traits.get_declaration(deasy) - self.assertTrue(isinstance(d_a, declarations.class_types)) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=class_traits_tester_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=Test)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=missing_decls_tester_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + return decls + + +def __test_type_category(decls, ns_name, controller): + ns_control = declarations.find_declaration( + decls, + decl_type=declarations.namespace_t, + name=ns_name) + assert ns_control is not None + ns_yes = declarations.find_declaration( + ns_control, + decl_type=declarations.namespace_t, + name='yes') + assert ns_yes is not None + ns_no = declarations.find_declaration( + ns_control, + decl_type=declarations.namespace_t, + name='no') + assert ns_no is not None + for decl in ns_yes.declarations: + if isinstance(decl, declarations.variable_t): + assert controller(decl.decl_type) is not None + elif isinstance(decl, declarations.calldef_t) and \ + decl.name.startswith('test_'): + continue + else: + assert controller(decl) is not None + for decl in ns_no.declarations: + if isinstance(decl, declarations.calldef_t) and \ + decl.name.startswith('test_'): + continue + val = controller(decl) + # TODO: This looks bad and should be improved? + # Why a boolean or None? + assert val is False or val is None + + +def __test_type_transformation(decls, ns_name, transformer): + ns_control = declarations.find_declaration( + decls, + decl_type=declarations.namespace_t, + name=ns_name) + assert ns_control is not None + ns_before = declarations.find_declaration( + ns_control, + decl_type=declarations.namespace_t, + name='before') + assert ns_before is not None + ns_after = declarations.find_declaration( + ns_control, + decl_type=declarations.namespace_t, + name='after') + assert ns_after is not None + + for tbefore in ns_before.declarations: + tafter = declarations.find_declaration( + ns_after, + name=tbefore.name) + assert tafter is not None + transformed = transformer(tbefore) + assert declarations.is_same( + transformed, + tafter) is True + + +def test_is_enum(decls): + __test_type_category(decls, 'is_enum', declarations.is_enum) + + +def test_is_void(decls): + __test_type_category(decls, 'is_void', declarations.is_void) + + +def test_is_bool(decls): + __test_type_category(decls, 'is_bool', declarations.is_bool) + + +def test_is_integral(decls): + __test_type_category(decls, 'is_integral', declarations.is_integral) + + +def test_is_pointer(decls): + __test_type_category(decls, 'is_pointer', declarations.is_pointer) + + +def test_is_void_pointer(decls): + __test_type_category( + decls, 'is_void_pointer', declarations.is_void_pointer) + + +def test_is_const(decls): + __test_type_category(decls, 'is_const', declarations.is_const) + + +def test_is_volatile(decls): + __test_type_category(decls, 'is_volatile', declarations.is_volatile) + + +def test_is_reference(decls): + __test_type_category(decls, 'is_reference', declarations.is_reference) + + +def test_is_floating_point(decls): + __test_type_category( + decls, + 'is_floating_point', + declarations.is_floating_point) + + +def test_is_array(decls): + __test_type_category(decls, 'is_array', declarations.is_array) + + +def test_is_fundamental(decls): + __test_type_category( + decls, + 'is_fundamental', + declarations.is_fundamental) + + +def test_is_noncopyable(decls): + __test_type_category( + decls, + 'is_noncopyable', + declarations.is_noncopyable) + + +def test_is_std_ostream(decls): + __test_type_category( + decls, + 'is_std_ostream', + declarations.is_std_ostream) + + +def test_is_std_wostream(decls): + __test_type_category( + decls, + 'is_std_wostream', + declarations.is_std_wostream) + + +def test_is_calldef_pointer(decls): + __test_type_category( + decls, + 'is_calldef_pointer', + declarations.is_calldef_pointer) + + +def test_has_trivial_constructor(decls): + __test_type_category( + decls, + 'has_trivial_constructor', + declarations.has_trivial_constructor) + + +def test_has_public_constructor(decls): + __test_type_category( + decls, + 'has_public_constructor', + declarations.has_public_constructor) + + +def test_has_public_destructor(decls): + __test_type_category( + decls, + 'has_public_destructor', + declarations.has_public_destructor) + + +def test_has_any_non_copyconstructor(decls): + __test_type_category( + decls, + 'has_any_non_copyconstructor', + declarations.has_any_non_copyconstructor) + + +def test_has_copy_constructor(decls): + __test_type_category( + decls, + 'has_copy_constructor', + declarations.has_copy_constructor) + + +def test_is_base_and_derived(decls): + ns = declarations.find_declaration( + decls, + decl_type=declarations.namespace_t, + name='is_base_and_derived') + assert ns is not None + base = declarations.find_declaration( + ns.declarations, + decl_type=declarations.class_t, + name='base') + derived = declarations.find_declaration( + ns.declarations, + decl_type=declarations.class_t, + name='derived') + assert base is not None + assert derived is not None + assert declarations.is_base_and_derived(base, derived) is True + assert declarations.is_base_and_derived(base, (derived, derived)) is True + + unrelated1 = declarations.find_declaration( + ns.declarations, + decl_type=declarations.class_t, + name='unrelated1') + + unrelated2 = declarations.find_declaration( + ns.declarations, + decl_type=declarations.class_t, + name='unrelated2') + assert base is not None + assert derived is not None + assert declarations.is_base_and_derived(unrelated1, unrelated2) is False + + +def test_is_same(): + assert declarations.is_same( + declarations.int_t, + declarations.int_t) is True + assert declarations.is_same( + declarations.int_t, + declarations.float_t) is False + + +def test_remove_const(decls): + __test_type_transformation( + decls, + 'remove_const', + declarations.remove_const) + + +def test_remove_reference(decls): + __test_type_transformation( + decls, + 'remove_reference', + declarations.remove_reference) + + +def test_remove_volatile(decls): + __test_type_transformation( + decls, + 'remove_volatile', + declarations.remove_volatile) + + +def test_remove_cv(decls): + __test_type_transformation( + decls, 'remove_cv', declarations.remove_cv + ) + + +def test_remove_pointer(decls): + __test_type_transformation( + decls, + 'remove_pointer', + declarations.remove_pointer) + + +def test_is_unary_binary_operator(decls): + operator_not = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::dummy::operator!') + assert operator_not is not None + assert declarations.is_unary_operator(operator_not) is True + assert declarations.is_binary_operator(operator_not) is False + + operator_class_p = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::dummy::operator+') + assert operator_class_p is not None + assert declarations.is_unary_operator(operator_class_p) is False + assert declarations.is_binary_operator(operator_class_p) is True + + operator_class_pp = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::dummy::operator++') + assert operator_class_pp is not None + assert declarations.is_unary_operator(operator_class_pp) is True + assert declarations.is_binary_operator(operator_class_pp) is False + + operator_pp = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::operator++') + assert operator_pp is not None + assert declarations.is_unary_operator(operator_pp) is True + assert declarations.is_binary_operator(operator_pp) is False + + operator_mm = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::operator*') + assert operator_mm is not None + assert declarations.is_unary_operator(operator_mm) is False + assert declarations.is_binary_operator(operator_mm) is True + + operator_pe = declarations.find_declaration( + decls, + decl_type=declarations.operator_t, + fullname='::is_unary_operator::operator+=') + assert operator_pe is not None + assert declarations.is_unary_operator(operator_pe) is False + assert declarations.is_binary_operator(operator_pe) is True + + +def __is_convertible_impl(decl): + defs = decl.bases[0].related_class.declarations + source_type = declarations.find_declaration(defs, name='source_type') + target_type = declarations.find_declaration(defs, name='target_type') + expected_type = declarations.find_declaration( + defs, + name='expected', + decl_type=declarations.enumeration_t) + expected_value = bool(expected_type.get_name2value_dict()['value']) + assert expected_value == declarations.is_convertible( + source_type, + target_type + ) + + +def test_is_convertible(decls): + ns_is_convertible = declarations.find_declaration( + decls, + decl_type=declarations.namespace_t, + name="is_convertible") + + assert ns_is_convertible is not None + for tester in [ + decl for decl in ns_is_convertible.declarations if + decl.name.startswith('x')]: + __is_convertible_impl(tester) + + +def test_missing_decls(): + config = autoconfig.cxx_parsers_cfg.config + code = "struct const_item{ const int values[10]; };" + global_ns = parser.parse_string(code, config)[0] + ci = global_ns.class_('const_item') + assert len(ci.declarations) == 3 + + +def test_get_declaration(): + code = """ + namespace A{ + struct B{ + int c; + }; + + template + struct C: public T{ + int d; + }; + + template + struct D{ + int dD; + }; + + typedef C easy; + typedef D Deasy; + + inline void instantiate(){ + int val = sizeof(easy); + } + + } + """ + + global_ns = parser.parse_string( + code, + autoconfig.cxx_parsers_cfg.config) + global_ns = declarations.get_global_namespace(global_ns) + easy = global_ns.typedef('easy') + declarations.class_traits.get_declaration(easy) + deasy = global_ns.typedef('Deasy') + d_a = declarations.class_traits.get_declaration(deasy) + assert isinstance(d_a, declarations.class_types) diff --git a/tests/test_typedefs.py b/tests/test_typedefs.py index 8b553afa..66b44665 100644 --- a/tests/test_typedefs.py +++ b/tests/test_typedefs.py @@ -3,81 +3,44 @@ # 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 tester_src_t(parser_test_case.parser_test_case_t): - # tester source reader +def test_typedefs_src_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 = 'typedefs_base.hpp' - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse([self.header], self.config) - self.global_ns = declarations.find_declaration( - self.declarations, - decl_type=declarations.namespace_t, - name='::') - self.global_ns.init_optimizer() - - def test(self): - item_cls = self.global_ns.class_(name='item_t') - self.assertTrue(item_cls, "unable to find class 'item_t'") - self.assertTrue(len(item_cls.aliases) == 1) - self.assertTrue(item_cls.aliases[0].name == 'Item') - - -class tester_prj_t(parser_test_case.parser_test_case_t): - # tester source reader + header = 'typedefs_base.hpp' + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse([header], config) + global_ns = declarations.find_declaration( + decls, + decl_type=declarations.namespace_t, + name='::') + global_ns.init_optimizer() + + item_cls = global_ns.class_(name='item_t') + assert item_cls is not None + assert len(item_cls.aliases) == 1 + assert item_cls.aliases[0].name == 'Item' + + +def test_typedefs_source_reader(): COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse( - ['typedefs1.hpp', - 'typedefs2.hpp'], - self.config, - self.COMPILATION_MODE) - - def test(self): - item_cls = declarations.find_declaration( - self.declarations, - decl_type=declarations.class_t, - name='item_t') - self.assertTrue(item_cls, "unable to find class 'item_t'") - self.assertTrue(len(item_cls.aliases) == 3) - expected_aliases = {'Item', 'Item1', 'Item2'} - real_aliases = set([typedef.name for typedef in item_cls.aliases]) - self.assertTrue(real_aliases == expected_aliases) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=tester_src_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=tester_prj_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + config = autoconfig.cxx_parsers_cfg.config.clone() + + decls = parser.parse( + ['typedefs1.hpp', 'typedefs2.hpp'], + config, + COMPILATION_MODE + ) + item_cls = declarations.find_declaration( + decls, + decl_type=declarations.class_t, + name='item_t') + assert item_cls is not None + assert len(item_cls.aliases) == 3 + expected_aliases = {'Item', 'Item1', 'Item2'} + real_aliases = set([typedef.name for typedef in item_cls.aliases]) + assert real_aliases == expected_aliases diff --git a/tests/test_unnamed_classes.py b/tests/test_unnamed_classes.py index ec35da15..50287acb 100644 --- a/tests/test_unnamed_classes.py +++ b/tests/test_unnamed_classes.py @@ -3,100 +3,91 @@ # 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 from pygccxml.declarations import type_traits -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 = 'unnamed_classes.hpp' - self.global_ns = None - - def setUp(self): - if not self.global_ns: - decls = parser.parse([self.header], self.config) - self.global_ns = declarations.get_global_namespace(decls) - self.global_ns.init_optimizer() - - def validate_bitfields(self, parent, bitfields): - for key in bitfields: - var = parent.variable(key) - self.assertEqual(var.bits, bitfields[key]) - - def do_union_test(self, union_name, bitfields): - s2 = self.global_ns.class_('S2') - self.assertFalse(declarations.is_union(s2)) - self.assertTrue(declarations.is_struct(s2)) - self.assertEqual(s2.parent.name, 'S1') - self.assertFalse(declarations.is_union(s2.parent)) - - union = s2.variable(union_name) - self.assertTrue(declarations.is_union(union.decl_type)) - self.assertFalse(declarations.is_struct(union.decl_type)) - - union_type = type_traits.remove_declarated(union.decl_type) - self.validate_bitfields(union_type, bitfields) - self.assertIsNotNone(union_type.variable('raw')) - - def test_union_Flags(self): - flags_bitfields = { - 'hasItemIdList': 1, - 'pointsToFileOrDir': 1, - 'hasDescription': 1, - 'hasRelativePath': 1, - 'hasWorkingDir': 1, - 'hasCmdLineArgs': 1, - 'hasCustomIcon': 1, - 'useWorkingDir': 1, - 'unused': 24, - } - self.do_union_test('flags', flags_bitfields) - - def test_unnamed_unions(self): - fileattribs_bitfields = { - 'isReadOnly': 1, - 'isHidden': 1, - 'isSystem': 1, - 'isVolumeLabel': 1, - 'isDir': 1, - 'isModified': 1, - 'isEncrypted': 1, - 'isNormal': 1, - 'isTemporary': 1, - 'isSparse': 1, - 'hasReparsePoint': 1, - 'isCompressed': 1, - 'isOffline': 1, - 'unused': 19, - } - self.do_union_test('fileattribs', fileattribs_bitfields) - - def test_anonymous_unions(self): - s3 = self.global_ns.class_('S3') - self.assertEqual(s3.parent.name, 'S1') - - s3_vars = ['anon_mem_c', 'anon_mem_i', 's3_mem', 's2'] - for var in s3_vars: - self.assertFalse(declarations.is_union(s3.variable(var).decl_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() +TEST_FILES = [ + "unnamed_classes.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 validate_bitfields(parent, bitfields): + for key in bitfields: + var = parent.variable(key) + assert var.bits == bitfields[key] + + +def do_union_test(global_ns, union_name, bitfields): + s2 = global_ns.class_('S2') + assert declarations.is_union(s2) is False + assert declarations.is_struct(s2) is True + assert s2.parent.name == 'S1' + assert declarations.is_union(s2.parent) is False + + union = s2.variable(union_name) + assert declarations.is_union(union.decl_type) is True + assert declarations.is_struct(union.decl_type) is False + + union_type = type_traits.remove_declarated(union.decl_type) + validate_bitfields(union_type, bitfields) + assert union_type.variable('raw') is not None + + +def test_union_Flags(global_ns): + flags_bitfields = { + 'hasItemIdList': 1, + 'pointsToFileOrDir': 1, + 'hasDescription': 1, + 'hasRelativePath': 1, + 'hasWorkingDir': 1, + 'hasCmdLineArgs': 1, + 'hasCustomIcon': 1, + 'useWorkingDir': 1, + 'unused': 24, + } + do_union_test(global_ns, 'flags', flags_bitfields) + + +def test_unnamed_unions(global_ns): + fileattribs_bitfields = { + 'isReadOnly': 1, + 'isHidden': 1, + 'isSystem': 1, + 'isVolumeLabel': 1, + 'isDir': 1, + 'isModified': 1, + 'isEncrypted': 1, + 'isNormal': 1, + 'isTemporary': 1, + 'isSparse': 1, + 'hasReparsePoint': 1, + 'isCompressed': 1, + 'isOffline': 1, + 'unused': 19, + } + do_union_test(global_ns, 'fileattribs', fileattribs_bitfields) + + +def test_anonymous_unions(global_ns): + s3 = global_ns.class_('S3') + assert s3.parent.name == 'S1' + + s3_vars = ['anon_mem_c', 'anon_mem_i', 's3_mem', 's2'] + for var in s3_vars: + assert declarations.is_union(s3.variable(var).decl_type) is False diff --git a/tests/test_unnamed_enums_bug.py b/tests/test_unnamed_enums_bug.py index c2c81d10..3cc6f016 100644 --- a/tests/test_unnamed_enums_bug.py +++ b/tests/test_unnamed_enums_bug.py @@ -3,112 +3,66 @@ # 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 source_reader_tester_t(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'unnamed_enums_bug1.hpp' - self.global_ns = None - - def setUp(self): - if not self.global_ns: - reader = parser.source_reader_t(self.config) - decls = reader.read_file(self.header) - self.global_ns = declarations.get_global_namespace(decls) - self.global_ns.init_optimizer() - - def test(self): - names = [] - enums = self.global_ns.enumerations() - for enum in enums: - names.extend(list(enum.get_name2value_dict().keys())) - self.assertTrue(len(names) == 4) - self.assertTrue('x1' in names) - self.assertTrue('x2' in names) - self.assertTrue('y1' in names) - self.assertTrue('y2' in names) - - -class project_reader_1_tester_t(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'unnamed_enums_bug1.hpp' - self.global_ns = None - - def setUp(self): - if not self.global_ns: - decls = parser.parse([self.header], self.config) - self.global_ns = declarations.get_global_namespace(decls) - self.global_ns.init_optimizer() - - def test(self): - names = [] - for enum in self.global_ns.enumerations(): - names.extend(list(enum.get_name2value_dict().keys())) - self.assertTrue(len(names) == 4) - self.assertTrue('x1' in names) - self.assertTrue('x2' in names) - self.assertTrue('y1' in names) - self.assertTrue('y2' in names) - - -class project_reader_3_tester_t(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.headers = [ +def test_source_reader_enums(): + config = autoconfig.cxx_parsers_cfg.config.clone() + reader = parser.source_reader_t(config) + decls = reader.read_file("unnamed_enums_bug1.hpp") + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + names = [] + enums = global_ns.enumerations() + for enum in enums: + names.extend(list(enum.get_name2value_dict().keys())) + assert len(names) == 4 + assert 'x1' in names + assert 'x2' in names + assert 'y1' in names + assert 'y2' in names + + +def test_project_reader_enums(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(["unnamed_enums_bug1.hpp"], config) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + + names = [] + for enum in global_ns.enumerations(): + names.extend(list(enum.get_name2value_dict().keys())) + assert len(names) == 4 + assert 'x1' in names + assert 'x2' in names + assert 'y1' in names + assert 'y2' in names + + +def test_multiple_files_enums(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse( + [ 'unnamed_enums_bug1.hpp', 'unnamed_enums_bug2.hpp', - 'unnamed_enums_bug1.hpp'] - self.global_ns = None - - def setUp(self): - if not self.global_ns: - decls = parser.parse(self.headers, self.config) - self.global_ns = declarations.get_global_namespace(decls) - self.global_ns.init_optimizer() - - def test(self): - names = [] - enums = self.global_ns.enumerations() - list(map( - lambda enum: names.extend(list(enum.get_name2value_dict().keys())), - enums)) - self.assertTrue(len(names) == 6) - self.assertTrue('x1' in names) - self.assertTrue('x2' in names) - self.assertTrue('y1' in names) - self.assertTrue('y2' in names) - self.assertTrue('z1' in names) - self.assertTrue('z2' in names) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=source_reader_tester_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=project_reader_1_tester_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=project_reader_3_tester_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() + 'unnamed_enums_bug1.hpp' + ], config + ) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + names = [] + enums = global_ns.enumerations() + list(map( + lambda enum: names.extend(list(enum.get_name2value_dict().keys())), + enums)) + assert len(names) == 6 + assert 'x1' in names + assert 'x2' in names + assert 'y1' in names + assert 'y2' in names + assert 'z1' in names + assert 'z2' in names diff --git a/tests/test_utils.py b/tests/test_utils.py index 5f989dd6..905aa181 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,47 +5,43 @@ import os import warnings -import unittest - -from . import parser_test_case from pygccxml import utils -class Test(parser_test_case.parser_test_case_t): +def test_contains_parent_dir(): + path = os.path.normpath("/mypath/folder1/folder2/folder3") + dirs = [ + os.path.normpath("/mypath/folder1/folder2/"), + os.path.normpath("/mypath3/folder1/folder2/folder3"), + os.path.normpath("home"), + os.path.normpath("/test/test1/mypath")] - def test_contains_parent_dir(self): - path = os.path.normpath("/mypath/folder1/folder2/folder3") - dirs = [ - os.path.normpath("/mypath/folder1/folder2/"), - os.path.normpath("/mypath3/folder1/folder2/folder3"), - os.path.normpath("home"), - os.path.normpath("/test/test1/mypath")] + assert utils.utils.contains_parent_dir(path, dirs) is True - self.assertTrue(utils.utils.contains_parent_dir(path, dirs)) + dirs = [os.path.normpath("/home"), os.path.normpath("/mypath/test/")] - dirs = [os.path.normpath("/home"), os.path.normpath("/mypath/test/")] + assert utils.utils.contains_parent_dir(path, dirs) is False - self.assertFalse(utils.utils.contains_parent_dir(path, dirs)) - def test_deprecation_wrapper(self): - """ - The DeprecationWrapper is not part of the public API +def test_deprecation_wrapper(): + """ + The DeprecationWrapper is not part of the public API - We still need to test it. - """ + We still need to test it. + """ - a = utils.utils.DeprecationWrapper( - DeprecatedClass, - "DeprecatedClass", - "NewClass", - "1.9.0") - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - a() - assert len(w) == 1 - assert issubclass(w[-1].category, DeprecationWarning) - assert "deprecated" in str(w[-1].message) + a = utils.utils.DeprecationWrapper( + DeprecatedClass, + "DeprecatedClass", + "NewClass", + "1.9.0") + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + a() + assert len(w) == 1 + assert issubclass(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) class DeprecatedClass(object): @@ -53,18 +49,3 @@ class DeprecatedClass(object): An empty class used for testing purposes. """ pass - - -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() diff --git a/tests/test_va_list_tag_removal.py b/tests/test_va_list_tag_removal.py index 8cbfea5d..25a001d4 100644 --- a/tests/test_va_list_tag_removal.py +++ b/tests/test_va_list_tag_removal.py @@ -5,141 +5,119 @@ import os import platform -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): +""" +Test the remove__va_list_tag option - """ - Test the remove__va_list_tag option +With CastXML and clang some __va_list_tag declarations are present in the +tree. This options allows to remove them when parsing the xml file. - With CastXML and clang some __va_list_tag declarations are present in the - tree. This options allows to remove them when parsing the xml file. +""" - """ - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.__code = os.linesep.join(['struct a{};']) - self.known_typedefs = [ - "__int128_t", "__uint128_t", "__builtin_va_list"] - self.known_typedefs_llvm39 = \ - self.known_typedefs + ["__builtin_ms_va_list"] - self.known_classes = ["a", "__va_list_tag"] - self.known_classes_llvm39 = \ - self.known_classes + ["__NSConstantString_tag"] +__code = os.linesep.join(['struct a{};']) +known_typedefs = ["__int128_t", "__uint128_t", "__builtin_va_list"] +known_typedefs_llvm39 = known_typedefs + ["__builtin_ms_va_list"] +known_classes = ["a", "__va_list_tag"] +known_classes_llvm39 = known_classes + ["__NSConstantString_tag"] - def test_keep_va_list_tag(self): - if platform.system() == 'Windows': - return True +def test_keep_va_list_tag(): - self.config.flags = ["f1"] - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) + if platform.system() == 'Windows': + return True - classes = [ - i for i in decls if isinstance(i, declarations.class_t)] + config = autoconfig.cxx_parsers_cfg.config.clone() - typedefs = [ - i for i in decls if isinstance(i, declarations.typedef_t)] + config.flags = ["f1"] + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) - variables = [ - i for i in decls if isinstance(i, declarations.variable_t)] + classes = [ + i for i in decls if isinstance(i, declarations.class_t)] - tag = "__va_list_tag" + typedefs = [ + i for i in decls if isinstance(i, declarations.typedef_t)] - self.assertTrue(tag in [class_.name for class_ in classes]) - self.assertTrue("a" in [class_.name for class_ in classes]) - if len(classes) == 2: - for c in self.known_classes: - self.assertTrue(c in [cl.name for cl in classes]) - elif len(classes) == 3: - for c in self.known_classes_llvm39: - # This is for llvm 3.9 - self.assertTrue(c in [cl.name for cl in classes]) + variables = [ + i for i in decls if isinstance(i, declarations.variable_t)] - self.assertTrue(len(typedefs) == 4 or len(typedefs) == 5) - if len(typedefs) == 5: - # This is for llvm 3.9. The class __va_list_tag struct is still - # there but the typedef is gone - for t in self.known_typedefs_llvm39: - self.assertTrue(t in [ty.name for ty in typedefs]) - self.assertTrue( - "__NSConstantString_tag" in - [class_.name for class_ in classes]) - self.assertTrue( - "__NSConstantString" in [ty.name for ty in typedefs]) - else: - for t in self.known_typedefs: - self.assertTrue(t in [ty.name for ty in typedefs]) + tag = "__va_list_tag" - self.assertTrue( - tag in [var.decl_string.split("::")[1] for var in variables]) - - # 4 variables in __va_list_tag, and 4 more in __NSConstantString_tag - # for llvm 3.9 - self.assertTrue(len(variables) == 4 or len(variables) == 8) - - def test_remove_va_list_tag(self): + assert tag in [class_.name for class_ in classes] + assert "a" in [class_.name for class_ in classes] + if len(classes) == 2: + for c in known_classes: + assert c in [cl.name for cl in classes] + elif len(classes) == 3: + for c in known_classes_llvm39: + # This is for llvm 3.9 + assert c in [cl.name for cl in classes] - if platform.system() == 'Windows': - return True + assert len(typedefs) == 4 or len(typedefs) == 5 + if len(typedefs) == 5: + # This is for llvm 3.9. The class __va_list_tag struct is still + # there but the typedef is gone + for t in known_typedefs_llvm39: + assert t in [ty.name for ty in typedefs] + assert "__NSConstantString_tag" in [class_.name for class_ in classes] + assert "__NSConstantString" in [ty.name for ty in typedefs] + else: + for t in known_typedefs: + assert t in [ty.name for ty in typedefs] - self.config.flags = [] - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) + assert tag in [var.decl_string.split("::")[1] for var in variables] - classes = [ - i for i in decls if isinstance(i, declarations.class_t)] + # 4 variables in __va_list_tag, and 4 more in __NSConstantString_tag + # for llvm 3.9 + assert len(variables) == 4 or len(variables) == 8 - typedefs = [ - i for i in decls if isinstance(i, declarations.typedef_t)] - variables = [ - i for i in decls if isinstance(i, declarations.variable_t)] +def test_remove_va_list_tag(): - tag = "__va_list_tag" + if platform.system() == 'Windows': + return True - self.assertFalse(tag in [class_.name for class_ in classes]) - self.assertTrue("a" in [class_.name for class_ in classes]) - self.assertTrue(len(classes) == 1) + config = autoconfig.cxx_parsers_cfg.config.clone() - self.assertFalse(tag in [ty.name for ty in typedefs]) - self.assertTrue(len(typedefs) == 3 or len(typedefs) == 4) - if len(typedefs) == 4: - # This is for llvm 3.9 - for t in self.known_typedefs_llvm39: - self.assertTrue(t in [ty.name for ty in typedefs]) - self.assertFalse( - "__NSConstantString_tag" - in [class_.name for class_ in classes]) - self.assertFalse( - "__NSConstantString" in [ty.name for ty in typedefs]) - else: - for t in self.known_typedefs: - self.assertTrue(t in [ty.name for ty in typedefs]) + config.flags = [] + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) - self.assertFalse( - tag in [var.decl_string.split("::")[1] for var in variables]) - self.assertTrue(len(variables) == 0) + classes = [ + i for i in decls if isinstance(i, declarations.class_t)] + typedefs = [ + i for i in decls if isinstance(i, declarations.typedef_t)] -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - return suite + variables = [ + i for i in decls if isinstance(i, declarations.variable_t)] + tag = "__va_list_tag" -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) + assert tag not in [class_.name for class_ in classes] + assert "a" in [class_.name for class_ in classes] + assert len(classes) == 1 + assert tag not in [ty.name for ty in typedefs] + assert len(typedefs) == 3 or len(typedefs) == 4 + if len(typedefs) == 4: + # This is for llvm 3.9 + for t in known_typedefs_llvm39: + assert t in [ty.name for ty in typedefs] + assert "__NSConstantString_tag" not in \ + [class_.name for class_ in classes] + assert "__NSConstantString" not in \ + [ty.name for ty in typedefs] + else: + for t in known_typedefs: + assert t in [ty.name for ty in typedefs] -if __name__ == "__main__": - run_suite() + assert tag not in [var.decl_string.split("::")[1] for var in variables] + assert len(variables) == 0 diff --git a/tests/test_variable_matcher.py b/tests/test_variable_matcher.py index 2bb0f0ff..49347f7d 100644 --- a/tests/test_variable_matcher.py +++ b/tests/test_variable_matcher.py @@ -4,85 +4,57 @@ # See http://www.boost.org/LICENSE_1_0.txt import os -import unittest -from . import parser_test_case +from . import autoconfig from pygccxml import parser from pygccxml import declarations -class tester_1_t(parser_test_case.parser_test_case_t): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - declarations = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'bit_fields.hpp' - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse([self.header], self.config) - - def test(self): - criteria = declarations.variable_matcher_t( - name='x', - decl_type='unsigned int') - x = declarations.matcher.get_single(criteria, self.declarations) - - comp_str = ( - '(decl type==variable_t) and (name==x) and ' + - '(value type==unsigned int)') - self.assertTrue(str(criteria) == comp_str) - - criteria = declarations.variable_matcher_t( - name='::bit_fields::fields_t::x', - decl_type=declarations.unsigned_int_t(), - header_dir=os.path.dirname( - x.location.file_name), - header_file=x.location.file_name) +TEST_FILES1 = [ + "bit_fields.hpp", +] - x = declarations.matcher.get_single(criteria, self.declarations) - self.assertTrue(x, "Variable was not found.") +TEST_FILES2 = [ + "vector_traits.hpp", +] - self.assertTrue('public' == x.access_type) - -class tester_2_t(parser_test_case.parser_test_case_t): +def test_bit_fields(): COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'vector_traits.hpp' - self.global_ns = None - - def setUp(self): - if not self.global_ns: - self.global_ns = declarations.get_global_namespace( - parser.parse([self.header], self.config)) + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES1, config, COMPILATION_MODE) - def test_no_defaults(self): - self.global_ns.decls(lambda decl: 'vector<' in decl.name) - self.global_ns.decl('vector< _0_ >') - self.global_ns.class_('vector< std::vector< int > >') - self.global_ns.class_('vector< std::string >') - self.global_ns.decl('vector< const int >') + criteria = declarations.variable_matcher_t( + name='x', + decl_type='unsigned int') + x = declarations.matcher.get_single(criteria, decls) + comp_str = ( + '(decl type==variable_t) and (name==x) and ' + + '(value type==unsigned int)') + assert str(criteria) == comp_str -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=tester_1_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=tester_2_t)) - return suite + criteria = declarations.variable_matcher_t( + name='::bit_fields::fields_t::x', + decl_type=declarations.unsigned_int_t(), + header_dir=os.path.dirname( + x.location.file_name), + header_file=x.location.file_name) + x = declarations.matcher.get_single(criteria, decls) + assert x is not None + assert 'public' == x.access_type -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - -if __name__ == "__main__": - run_suite() +def test_no_defaults(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES2, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + + global_ns.decls(lambda decl: 'vector<' in decl.name) + global_ns.decl('vector< _0_ >') + global_ns.class_('vector< std::vector< int > >') + global_ns.class_('vector< std::string >') + global_ns.decl('vector< const int >') diff --git a/tests/test_vector_traits.py b/tests/test_vector_traits.py index d4063fdb..81efa62b 100644 --- a/tests/test_vector_traits.py +++ b/tests/test_vector_traits.py @@ -3,93 +3,88 @@ # 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 = [ + "vector_traits.hpp", +] + + +@pytest.fixture +def global_ns(): COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'vector_traits.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) - self.global_ns = Test.global_ns - - def validate_yes(self, value_type, container): - traits = declarations.vector_traits - self.assertTrue(traits.is_my_case(container)) - self.assertTrue( - declarations.is_same( - value_type, - traits.element_type(container))) - self.assertTrue(traits.is_sequence(container)) - - def test_global_ns(self): - value_type = self.global_ns.class_('_0_') - container = self.global_ns.typedef('container', recursive=False) - self.validate_yes(value_type, container) - - def test_yes(self): - yes_ns = self.global_ns.namespace('yes') - for struct in yes_ns.classes(): - if not struct.name.startswith('_'): - continue - if not struct.name.endswith('_'): - continue - self.validate_yes( - struct.typedef('value_type'), - struct.typedef('container')) - - def test_no(self): - traits = declarations.vector_traits - no_ns = self.global_ns.namespace('no') - for struct in no_ns.classes(): - if not struct.name.startswith('_'): - continue - if not struct.name.endswith('_'): - continue - self.assertTrue(not traits.is_my_case(struct.typedef('container'))) - - def test_declaration(self): - cnt = ( - 'std::vector, ' + - 'std::allocator >,std::allocator, std::allocator > > >' + - '@::std::vector, ' + - 'std::allocator >,std::allocator, std::allocator > > >') - traits = declarations.find_container_traits(cnt) - self.assertTrue(declarations.vector_traits is traits) - - def test_element_type(self): - do_nothing = self.global_ns.free_function('do_nothing') - v = declarations.remove_reference( - declarations.remove_declarated( - do_nothing.arguments[0].decl_type)) - declarations.vector_traits.element_type(v) - - -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() + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + # TOOD: this breaks the tests, check why + # config.castxml_epic_version = 1 + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def validate_yes(value_type, container): + traits = declarations.vector_traits + assert traits.is_my_case(container) is True + assert declarations.is_same( + value_type, + traits.element_type(container)) is True + assert traits.is_sequence(container) is True + + +def test_global_ns(global_ns): + value_type = global_ns.class_('_0_') + container = global_ns.typedef('container', recursive=False) + validate_yes(value_type, container) + + +def test_yes(global_ns): + yes_ns = global_ns.namespace('yes') + for struct in yes_ns.classes(): + if not struct.name.startswith('_'): + continue + if not struct.name.endswith('_'): + continue + validate_yes( + struct.typedef('value_type'), + struct.typedef('container')) + + +def test_no(global_ns): + traits = declarations.vector_traits + no_ns = global_ns.namespace('no') + for struct in no_ns.classes(): + if not struct.name.startswith('_'): + continue + if not struct.name.endswith('_'): + continue + assert traits.is_my_case(struct.typedef('container')) is False + + +def test_declaration(): + cnt = ( + 'std::vector, ' + + 'std::allocator >,std::allocator, std::allocator > > >' + + '@::std::vector, ' + + 'std::allocator >,std::allocator, std::allocator > > >') + traits = declarations.find_container_traits(cnt) + assert declarations.vector_traits == traits + + +def test_element_type(global_ns): + do_nothing = global_ns.free_function('do_nothing') + print(do_nothing) + v = declarations.remove_reference( + declarations.remove_declarated( + do_nothing.arguments[0].decl_type)) + print(v, type(v)) + declarations.vector_traits.element_type(v) diff --git a/tests/test_warn_missing_include_dirs.py b/tests/test_warn_missing_include_dirs.py index ec5e9cfd..253d2c85 100644 --- a/tests/test_warn_missing_include_dirs.py +++ b/tests/test_warn_missing_include_dirs.py @@ -3,51 +3,30 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import io -import sys import os -import unittest -import warnings -sys.path.insert(1, os.path.join(os.curdir, '..')) -sys.path.insert(1, "../pygccxml") +import pytest -from pygccxml import parser # nopep8 -from pygccxml import utils # nopep8 +from pygccxml import parser +from pygccxml import utils -class Test(unittest.TestCase): +def test_config_warn(): + """ + Test that a missing include directory is printing a warning, + not raising an error + """ - def test_config(self): - """ - Test that a missing include directory is printing a warning, - not raising an error - """ + # Some code to parse for the example + code = "int a;" - # Some code to parse for the example - code = "int a;" + # Find the location of the xml generator (castxml or gccxml) + generator_path, name = utils.find_xml_generator() - # Find the location of the xml generator (castxml or gccxml) - generator_path, name = utils.find_xml_generator() - - # Path given as include director doesn't exist - config = parser.xml_generator_configuration_t( - xml_generator_path=generator_path, - xml_generator=name, - include_paths=["doesnt/exist", os.getcwd()]) - self.assertWarns(RuntimeWarning, parser.parse_string, code, config) - - -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() + # Path given as include director doesn't exist + config = parser.xml_generator_configuration_t( + xml_generator_path=generator_path, + xml_generator=name, + include_paths=["doesnt/exist", os.getcwd()]) + with pytest.warns(RuntimeWarning): + parser.parse_string(code, config) diff --git a/tests/test_xml_generators.py b/tests/test_xml_generators.py index e3f79460..b2ecee99 100644 --- a/tests/test_xml_generators.py +++ b/tests/test_xml_generators.py @@ -3,81 +3,67 @@ # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt -import unittest -import logging +import pytest -from . import parser_test_case +import logging from pygccxml import utils -class Test(parser_test_case.parser_test_case_t): - mock_logger = logging.getLogger("Test") - - def test_old_xml_generators(self): - """ - Tests for the xml_generators class. - - This is for gccxml and for castxml using the gccxml xml file format - """ - self._test_impl("0.6", False, "is_gccxml_06") - self._test_impl("1.114", False, "is_gccxml_07") - self._test_impl("1.115", False, "is_gccxml_09_buggy") - self._test_impl("1.126", False, "is_gccxml_09_buggy") - self._test_impl("1.127", False, "is_gccxml_09") - self._test_impl("1.136", True, "is_castxml") - - def test_casxtml_epic_version_1(self): - """ - Test with the castxml epic version set to 1 - """ - gen = utils.xml_generators( - self.mock_logger, castxml_format="1.1.0") - self.assertFalse(gen.is_gccxml) - self.assertTrue(gen.is_castxml) - self.assertTrue(gen.is_castxml1) - self.assertEqual(gen.xml_output_version, "1.1.0") - - self.assertRaises(RuntimeError, lambda: utils.xml_generators( - self.mock_logger, "1.136", "1.1.0")) - - self.assertRaises(RuntimeError, lambda: utils.xml_generators( - self.mock_logger, None, None)) - - def _test_impl( - self, gccxml_cvs_revision, is_castxml, - expected_gccxml_cvs_revision): - """ - Implementation detail for the test - - Args: - gccxml_cvs_revision (str|None) : a known cvs revision - is_castxml (bool): check for castxml - expected_gccxml_cvs_revision (str): will be used to check if the - attribute is set to True. - """ - gen = utils.xml_generators( - self.mock_logger, gccxml_cvs_revision) - if is_castxml: - self.assertFalse(gen.is_gccxml) - self.assertTrue(gen.is_castxml) - else: - self.assertTrue(gen.is_gccxml) - self.assertFalse(gen.is_castxml) - self.assertTrue(getattr(gen, expected_gccxml_cvs_revision)) - self.assertEqual(gen.xml_output_version, gccxml_cvs_revision) - - -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() +mock_logger = logging.getLogger("Test") + + +def test_old_xml_generators(): + """ + Tests for the xml_generators class. + + This is for gccxml and for castxml using the gccxml xml file format + """ + _test_impl("0.6", False, "is_gccxml_06") + _test_impl("1.114", False, "is_gccxml_07") + _test_impl("1.115", False, "is_gccxml_09_buggy") + _test_impl("1.126", False, "is_gccxml_09_buggy") + _test_impl("1.127", False, "is_gccxml_09") + _test_impl("1.136", True, "is_castxml") + + +def test_casxtml_epic_version_1(): + """ + Test with the castxml epic version set to 1 + """ + gen = utils.xml_generators( + mock_logger, castxml_format="1.1.0") + assert gen.is_gccxml is False + assert gen.is_castxml is True + assert gen.is_castxml1 is True + assert gen.xml_output_version == "1.1.0" + + with pytest.raises(RuntimeError): + utils.xml_generators(mock_logger, "1.136", "1.1.0") + + with pytest.raises(RuntimeError): + utils.xml_generators(mock_logger, None, None) + + +def _test_impl( + gccxml_cvs_revision, is_castxml, + expected_gccxml_cvs_revision): + """ + Implementation detail for the test + + Args: + gccxml_cvs_revision (str|None) : a known cvs revision + is_castxml (bool): check for castxml + expected_gccxml_cvs_revision (str): will be used to check if the + attribute is set to True. + """ + gen = utils.xml_generators( + mock_logger, gccxml_cvs_revision) + if is_castxml: + assert gen.is_gccxml is False + assert gen.is_castxml is True + else: + assert gen.is_gccxml is True + assert gen.is_castxml is False + assert getattr(gen, expected_gccxml_cvs_revision) is True + assert gen.xml_output_version == gccxml_cvs_revision diff --git a/tests/test_xmlfile_reader.py b/tests/test_xmlfile_reader.py index e22a3688..ece9d598 100644 --- a/tests/test_xmlfile_reader.py +++ b/tests/test_xmlfile_reader.py @@ -4,69 +4,43 @@ # See http://www.boost.org/LICENSE_1_0.txt import os -import unittest from . import autoconfig -from . import parser_test_case from pygccxml import parser from pygccxml import declarations +TEST_FILE = "core_types.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.__fname = 'core_types.hpp' - # self.__fname = 'merge_free_functions.hpp' +def test_read_xml_file(): + config = autoconfig.cxx_parsers_cfg.config.clone() - def test_read_xml_file(self): - src_reader = parser.source_reader_t(self.config) - src_decls = src_reader.read_file(self.__fname) + src_reader = parser.source_reader_t(config) + src_decls = src_reader.read_file(TEST_FILE) - xmlfile = src_reader.create_xml_file(self.__fname) - print(xmlfile) - try: - conf_t = parser.file_configuration_t - fconfig = conf_t( - data=xmlfile, - start_with_declarations=None, - content_type=conf_t.CONTENT_TYPE.GCCXML_GENERATED_FILE) + xmlfile = src_reader.create_xml_file(TEST_FILE) - prj_reader = parser.project_reader_t(self.config) - prj_decls = prj_reader.read_files( - [fconfig], - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + conf_t = parser.file_configuration_t + fconfig = conf_t( + data=xmlfile, + start_with_declarations=None, + content_type=conf_t.CONTENT_TYPE.GCCXML_GENERATED_FILE) - declarations.dump_declarations( - src_decls, - os.path.join( - autoconfig.build_directory, - 'xmlfile_reader.src.txt')) - declarations.dump_declarations( - prj_decls, - os.path.join( - autoconfig.build_directory, - 'xmlfile_reader.prj.txt')) + prj_reader = parser.project_reader_t(config) + prj_decls = prj_reader.read_files( + [fconfig], + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - if src_decls != prj_decls: - self.fail( - "There is a difference between declarations in file %s." % - self.__fname) - finally: - pass # utils.remove_file_no_raise( xmlfile, self.config ) + declarations.dump_declarations( + src_decls, + os.path.join( + autoconfig.build_directory, + 'xmlfile_reader.src.txt')) + declarations.dump_declarations( + prj_decls, + os.path.join( + autoconfig.build_directory, + 'xmlfile_reader.prj.txt')) - -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 src_decls == prj_decls