diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index de7dd0b0..3c68ef7a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,10 @@ -on: [push, pull_request] +on: + push: + branches: + - main + - develop + pull_request: + jobs: tests: name: ${{ matrix.os }}-${{ matrix.compiler }}-${{ matrix.version }}-python-${{ matrix.python-version }}-${{ matrix.castxml-epic }} @@ -93,12 +99,7 @@ jobs: if: matrix.os == 'macos-12' run: | wget -q -O - https://data.kitware.com/api/v1/file/hashsum/sha512/5d937e938f7b882a3a3e7941e68f8312d0898aaf2082e00003dd362b1ba70b98b0a08706a1be28e71652a6a0f1e66f89768b5eaa20e5a100592d5b3deefec3f0/download | tar zxf - -C ~/ - - name: Setup castxml config - if: matrix.compiler == 'gcc' && matrix.version == '9' - run: mv unittests/configs/gcc9.cfg unittests/xml_generator.cfg; - name: Run tests run: | export PATH=~/castxml/bin:$PATH - coverage run -m unittests.test_all - coverage combine - coverage xml + pytest tests diff --git a/.gitignore b/.gitignore index e849f161..1492c159 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ *.pyo *~ docs/_build +tests/temp +tests/data/pygccxml.cache +tests/data/directory_cache_test +tests/data/ogre.1.7.xml unittests/temp unittests/data/pygccxml.cache unittests/data/directory_cache_test diff --git a/CHANGELOG.md b/CHANGELOG.md index a27edbe0..ec5e3902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ Changes ======= +Version 2.6.0 +------------- + +1. Drop utils.is_str function + +2. Massive unit test refactoring: migrated all the tests to pytest. + +3. Make sure has_mutable, has_static, has_extern functions always return a boolean + +4. Fix a bug in unordered_set_traits and unordered_multiset_traits + +5. Fix a bug in build_decl_string with elaborated type specifiers + Version 2.5.0 ------------- diff --git a/docs/install.rst b/docs/install.rst index 75913ec2..89953d21 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -47,7 +47,7 @@ These instructions are only here for historical reasons. `GCC-XML`_ was the tool to generate the xml files before CastXML existed. **From version v1.8.0 on, pygccxml uses CastXML by default. -The support for GCC-XML will finally be dropped in pygccxml v2.0.0.** +The support for GCC-XML was finally dropped in pygccxml v2.0.0.** There are few different ways to install GCC-XML on your system: @@ -58,8 +58,8 @@ There are few different ways to install GCC-XML on your system: .. _`instructions`: http://gccxml.org/HTML/Install.html .. _`GCC-XML`: http://www.gccxml.org .. _`CastXML`: https://github.com/CastXML/CastXML -.. _`Linux`: https://midas3.kitware.com/midas/folder/13152 -.. _`OS X`: https://midas3.kitware.com/midas/folder/13152 -.. _`Windows`: https://midas3.kitware.com/midas/folder/13152 +.. _`Linux`: https://github.com/CastXML/CastXMLSuperbuild/releases/latest +.. _`OS X`: https://github.com/CastXML/CastXMLSuperbuild/releases/latest +.. _`Windows`: https://github.com/CastXML/CastXMLSuperbuild/releases/latest .. _`SuperBuild`: https://github.com/thewtex/CastXMLSuperbuild .. _`full install instructions`: https://github.com/CastXML/CastXML#build diff --git a/pyproject.toml b/pyproject.toml index de3e3f10..3dbe90f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ keywords = [ "CastXML", "gccxml", ] -version = "2.5.0" +version = "2.6.0" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -55,6 +55,7 @@ test = [ "coverage", "coveralls", "pycodestyle", + "pytest", ] docs = [ "sphinx", diff --git a/src/pygccxml/declarations/container_traits.py b/src/pygccxml/declarations/container_traits.py index d4f6658e..e5035782 100644 --- a/src/pygccxml/declarations/container_traits.py +++ b/src/pygccxml/declarations/container_traits.py @@ -647,14 +647,14 @@ def remove_defaults(self, type_or_string): unordered_set_traits = container_traits_impl_t( 'unordered_set', - 1, + 0, 'value_type', 'erase_hash_allocator', unordered_maps_and_sets=True) unordered_multiset_traits = container_traits_impl_t( 'unordered_multiset', - 1, + 0, 'value_type', 'erase_hash_allocator', unordered_maps_and_sets=True) diff --git a/src/pygccxml/declarations/cpptypes.py b/src/pygccxml/declarations/cpptypes.py index b8b1769a..b2ab2e1e 100644 --- a/src/pygccxml/declarations/cpptypes.py +++ b/src/pygccxml/declarations/cpptypes.py @@ -9,6 +9,7 @@ from . import algorithms_cache from . import byte_info +from . import elaborated_info class type_t(byte_info.byte_info): @@ -593,10 +594,10 @@ def __init__(self, base): compound_t.__init__(self, base) def build_decl_string(self, with_defaults=True): - if hasattr(self.base.declaration, "elaborated_type_specifier"): + prefix = "" + if isinstance(self.base, type(declarated_t)) and \ + isinstance(self.base.declaration, type(elaborated_info)): prefix = self.base.declaration.elaborated_type_specifier + " " - else: - prefix = "" return prefix + self.base.build_decl_string(with_defaults) def _clone_impl(self): diff --git a/src/pygccxml/parser/config.py b/src/pygccxml/parser/config.py index e2db56d8..4fe4a6a0 100644 --- a/src/pygccxml/parser/config.py +++ b/src/pygccxml/parser/config.py @@ -11,6 +11,7 @@ import os import copy import platform +import shutil import subprocess import warnings # In py3, ConfigParser was renamed to the more-standard configparser. @@ -129,16 +130,12 @@ def compiler(self, compiler): @property def xml_generator(self): - """get xml_generator (gccxml or castxml)""" + """get xml_generator""" return self.__xml_generator @xml_generator.setter def xml_generator(self, xml_generator): - """set xml_generator (gccxml or castxml)""" - if "real" in xml_generator: - # Support for gccxml.real from newer gccxml package - # Can be removed once gccxml support is dropped. - xml_generator = "gccxml" + """set xml_generator""" self.__xml_generator = xml_generator @property @@ -241,9 +238,8 @@ def raise_on_wrong_settings(self): self.__ensure_dir_exists(self.working_directory, 'working directory') for idir in self.include_paths: self.__ensure_dir_exists(idir, 'include directory') - if self.__xml_generator not in ["castxml", "gccxml"]: - msg = ('xml_generator("%s") should either be ' + - '"castxml" or "gccxml".') % self.xml_generator + if self.__xml_generator != "castxml": + msg = f"xml_generator ({self.xml_generator}) can only be 'castxml'" raise RuntimeError(msg) @@ -456,35 +452,20 @@ def create_compiler_path(xml_generator, compiler_path): if xml_generator == 'castxml' and compiler_path is None: if platform.system() == 'Windows': # Look for msvc - compiler_path = __get_first_compiler_in_path('where', 'cl') + compiler_path = shutil.which('cl') # No msvc found; look for mingw - if compiler_path == '': - compiler_path = __get_first_compiler_in_path('where', 'mingw') + if compiler_path is None: + compiler_path = shutil.which('mingw') else: # OS X or Linux # Look for clang first, then gcc - compiler_path = __get_first_compiler_in_path('which', 'clang++') + compiler_path = shutil.which('clang++') # No clang found; use gcc - if compiler_path == '': - compiler_path = __get_first_compiler_in_path('which', 'c++') - - if compiler_path == "": - compiler_path = None + if compiler_path is None: + compiler_path = shutil.which('c++') return compiler_path -def __get_first_compiler_in_path(command, compiler_name): - p = subprocess.Popen( - [command, compiler_name], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - path = p.stdout.read().decode("utf-8").rstrip().split("\r\n")[0].rstrip() - p.wait() - p.stdout.close() - p.stderr.close() - return path - - if __name__ == '__main__': print(load_xml_generator_configuration('xml_generator.cfg').__dict__) diff --git a/src/pygccxml/parser/scanner.py b/src/pygccxml/parser/scanner.py index 63f9cbd7..f39dd05d 100644 --- a/src/pygccxml/parser/scanner.py +++ b/src/pygccxml/parser/scanner.py @@ -56,6 +56,7 @@ XML_AN_STATIC = "static" XML_AN_THROW = "throw" XML_AN_TYPE = "type" +XML_AN_ORIGINAL_TYPE = "original_type" XML_AN_VIRTUAL = "virtual" XML_AN_VOLATILE = "volatile" XML_NN_ARGUMENT = "Argument" @@ -558,7 +559,10 @@ def __read_argument(self, attrs): XML_AN_NAME, 'arg%d' % len( self.__inst.arguments)) - argument.decl_type = attrs[XML_AN_TYPE] + argument.decl_type = attrs.get( + XML_AN_ORIGINAL_TYPE, + attrs.get(XML_AN_TYPE) + ) argument.default_value = attrs.get(XML_AN_DEFAULT) self.__read_attributes(argument, attrs) self.__inst.arguments.append(argument) @@ -576,8 +580,8 @@ def __read_calldef(self, calldef, attrs, is_declaration): if is_declaration: self.__calldefs.append(calldef) calldef.name = attrs.get(XML_AN_NAME, '') - calldef.has_extern = attrs.get(XML_AN_EXTERN, False) - calldef.has_inline = bool(attrs.get(XML_AN_INLINE, "") == "1") + calldef.has_extern = bool(attrs.get(XML_AN_EXTERN, False)) + calldef.has_inline = bool(attrs.get(XML_AN_INLINE, False)) throw_stmt = attrs.get(XML_AN_THROW) if None is throw_stmt: calldef.does_throw = True @@ -593,9 +597,9 @@ def __read_calldef(self, calldef, attrs, is_declaration): def __read_member_function(self, calldef, attrs, is_declaration): self.__read_calldef(calldef, attrs, is_declaration) - calldef.has_const = attrs.get(XML_AN_CONST, False) + calldef.has_const = bool(attrs.get(XML_AN_CONST, False)) if is_declaration: - calldef.has_static = attrs.get(XML_AN_STATIC, False) + calldef.has_static = bool(attrs.get(XML_AN_STATIC, False)) if XML_AN_PURE_VIRTUAL in attrs: calldef.virtuality = declarations.VIRTUALITY_TYPES.PURE_VIRTUAL elif XML_AN_VIRTUAL in attrs: @@ -626,9 +630,9 @@ def __read_typedef(self, attrs): def __read_variable(self, attrs): type_qualifiers = declarations.type_qualifiers_t() - type_qualifiers.has_mutable = attrs.get(XML_AN_MUTABLE, False) - type_qualifiers.has_static = attrs.get(XML_AN_STATIC, False) - type_qualifiers.has_extern = attrs.get(XML_AN_EXTERN, False) + type_qualifiers.has_mutable = bool(attrs.get(XML_AN_MUTABLE, False)) + type_qualifiers.has_static = bool(attrs.get(XML_AN_STATIC, False)) + type_qualifiers.has_extern = bool(attrs.get(XML_AN_EXTERN, False)) bits = attrs.get(XML_AN_BITS) if bits: bits = int(bits) diff --git a/src/pygccxml/utils/__init__.py b/src/pygccxml/utils/__init__.py index 1730aee0..84df5cf6 100644 --- a/src/pygccxml/utils/__init__.py +++ b/src/pygccxml/utils/__init__.py @@ -8,7 +8,6 @@ """ -from .utils import is_str from .utils import get_architecture from .utils import loggers from .utils import create_temp_file_name diff --git a/src/pygccxml/utils/utils.py b/src/pygccxml/utils/utils.py index 7a9deb5a..0d1022dc 100644 --- a/src/pygccxml/utils/utils.py +++ b/src/pygccxml/utils/utils.py @@ -7,36 +7,12 @@ import os import sys -import platform import logging import tempfile import shutil -import subprocess import warnings -def is_str(string): - """ - Python 2 and 3 compatible string checker. - - Args: - string (str | basestring): the string to check - - Returns: - bool: True or False - - """ - warnings.warn( - "The is_str function is deprecated. \ - Use isinstance(string, str) instead.", - DeprecationWarning) - - if sys.version_info[:2] >= (3, 0): - return isinstance(string, str) - - return isinstance(string, basestring) - - def find_xml_generator(name="castxml", search_path=None): """ Try to find a c++ parser (xml generator) diff --git a/unittests/__init__.py b/tests/__init__.py similarity index 100% rename from unittests/__init__.py rename to tests/__init__.py diff --git a/unittests/autoconfig.py b/tests/autoconfig.py similarity index 96% rename from unittests/autoconfig.py rename to tests/autoconfig.py index 29c784f9..2e43239b 100644 --- a/unittests/autoconfig.py +++ b/tests/autoconfig.py @@ -18,6 +18,9 @@ data_directory = os.path.join(this_module_dir_path, 'data') build_directory = os.path.join(this_module_dir_path, 'temp') +if not os.path.exists(build_directory): + os.makedirs(build_directory) + sys.path.insert(1, os.path.join(os.curdir, '..')) # The tests are run on the parent pygccxml directory, not the one # in site-packages. Insert the directory's path. diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..fb110455 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,43 @@ +# 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 pytest + + +class Helpers: + @staticmethod + def _test_type_composition(type_, expected_compound, expected_base): + assert isinstance(type_, expected_compound) + assert isinstance(type_.base, expected_base) + + @staticmethod + def _test_calldef_args(calldef, expected_args): + assert len(calldef.arguments) == len(expected_args) + + for i, expected_arg in enumerate(expected_args): + arg = calldef.arguments[i] + assert arg == expected_arg + + @staticmethod + def _test_calldef_return_type(calldef, expected_type): + assert isinstance(calldef.return_type, expected_type) + + @staticmethod + def _test_calldef_exceptions(global_ns, calldef, exceptions): + # exceptions is list of classes names + exception_decls = [] + for name in exceptions: + exception_decl = global_ns.class_(name) + assert exception_decl is not None + exception_decls.append(exception_decl) + exception_decls.sort() + assert len(calldef.exceptions) == len(exception_decls) + exceptions_indeed = sorted(calldef.exceptions[:]) + assert exception_decls == exceptions_indeed + + +@pytest.fixture +def helpers(): + return Helpers diff --git a/unittests/data/abstract_classes.hpp b/tests/data/abstract_classes.hpp similarity index 100% rename from unittests/data/abstract_classes.hpp rename to tests/data/abstract_classes.hpp diff --git a/unittests/data/attributes_castxml.hpp b/tests/data/attributes_castxml.hpp similarity index 100% rename from unittests/data/attributes_castxml.hpp rename to tests/data/attributes_castxml.hpp diff --git a/unittests/data/attributes_gccxml.hpp b/tests/data/attributes_gccxml.hpp similarity index 100% rename from unittests/data/attributes_gccxml.hpp rename to tests/data/attributes_gccxml.hpp diff --git a/unittests/data/better_templates_matcher_tester.hpp b/tests/data/better_templates_matcher_tester.hpp similarity index 100% rename from unittests/data/better_templates_matcher_tester.hpp rename to tests/data/better_templates_matcher_tester.hpp diff --git a/unittests/data/binary_parsers/libconfig.h b/tests/data/binary_parsers/libconfig.h similarity index 100% rename from unittests/data/binary_parsers/libconfig.h rename to tests/data/binary_parsers/libconfig.h diff --git a/unittests/data/binary_parsers/mydll.cpp b/tests/data/binary_parsers/mydll.cpp similarity index 100% rename from unittests/data/binary_parsers/mydll.cpp rename to tests/data/binary_parsers/mydll.cpp diff --git a/unittests/data/binary_parsers/mydll.h b/tests/data/binary_parsers/mydll.h similarity index 100% rename from unittests/data/binary_parsers/mydll.h rename to tests/data/binary_parsers/mydll.h diff --git a/unittests/data/binary_parsers/sconscript b/tests/data/binary_parsers/sconscript similarity index 100% rename from unittests/data/binary_parsers/sconscript rename to tests/data/binary_parsers/sconscript diff --git a/unittests/data/binary_parsers/sconstruct b/tests/data/binary_parsers/sconstruct similarity index 100% rename from unittests/data/binary_parsers/sconstruct rename to tests/data/binary_parsers/sconstruct diff --git a/unittests/data/bit_fields.hpp b/tests/data/bit_fields.hpp similarity index 100% rename from unittests/data/bit_fields.hpp rename to tests/data/bit_fields.hpp diff --git a/unittests/data/classes.hpp b/tests/data/classes.hpp similarity index 100% rename from unittests/data/classes.hpp rename to tests/data/classes.hpp diff --git a/unittests/data/complex_types.hpp b/tests/data/complex_types.hpp similarity index 100% rename from unittests/data/complex_types.hpp rename to tests/data/complex_types.hpp diff --git a/unittests/data/const_volatile_arg.hpp b/tests/data/const_volatile_arg.hpp similarity index 100% rename from unittests/data/const_volatile_arg.hpp rename to tests/data/const_volatile_arg.hpp diff --git a/unittests/data/core_cache.hpp b/tests/data/core_cache.hpp similarity index 100% rename from unittests/data/core_cache.hpp rename to tests/data/core_cache.hpp diff --git a/unittests/data/core_class_hierarchy.hpp b/tests/data/core_class_hierarchy.hpp similarity index 100% rename from unittests/data/core_class_hierarchy.hpp rename to tests/data/core_class_hierarchy.hpp diff --git a/unittests/data/core_class_hierarchy.hpp.xml b/tests/data/core_class_hierarchy.hpp.xml similarity index 100% rename from unittests/data/core_class_hierarchy.hpp.xml rename to tests/data/core_class_hierarchy.hpp.xml diff --git a/unittests/data/core_diamand_hierarchy_base.hpp b/tests/data/core_diamand_hierarchy_base.hpp similarity index 100% rename from unittests/data/core_diamand_hierarchy_base.hpp rename to tests/data/core_diamand_hierarchy_base.hpp diff --git a/unittests/data/core_diamand_hierarchy_derived1.hpp b/tests/data/core_diamand_hierarchy_derived1.hpp similarity index 100% rename from unittests/data/core_diamand_hierarchy_derived1.hpp rename to tests/data/core_diamand_hierarchy_derived1.hpp diff --git a/unittests/data/core_diamand_hierarchy_derived2.hpp b/tests/data/core_diamand_hierarchy_derived2.hpp similarity index 100% rename from unittests/data/core_diamand_hierarchy_derived2.hpp rename to tests/data/core_diamand_hierarchy_derived2.hpp diff --git a/unittests/data/core_diamand_hierarchy_final_derived.hpp b/tests/data/core_diamand_hierarchy_final_derived.hpp similarity index 100% rename from unittests/data/core_diamand_hierarchy_final_derived.hpp rename to tests/data/core_diamand_hierarchy_final_derived.hpp diff --git a/unittests/data/core_membership.hpp b/tests/data/core_membership.hpp similarity index 100% rename from unittests/data/core_membership.hpp rename to tests/data/core_membership.hpp diff --git a/unittests/data/core_ns_join_1.hpp b/tests/data/core_ns_join_1.hpp similarity index 100% rename from unittests/data/core_ns_join_1.hpp rename to tests/data/core_ns_join_1.hpp diff --git a/unittests/data/core_ns_join_2.hpp b/tests/data/core_ns_join_2.hpp similarity index 100% rename from unittests/data/core_ns_join_2.hpp rename to tests/data/core_ns_join_2.hpp diff --git a/unittests/data/core_ns_join_3.hpp b/tests/data/core_ns_join_3.hpp similarity index 100% rename from unittests/data/core_ns_join_3.hpp rename to tests/data/core_ns_join_3.hpp diff --git a/unittests/data/core_overloads_1.hpp b/tests/data/core_overloads_1.hpp similarity index 100% rename from unittests/data/core_overloads_1.hpp rename to tests/data/core_overloads_1.hpp diff --git a/unittests/data/core_overloads_2.hpp b/tests/data/core_overloads_2.hpp similarity index 100% rename from unittests/data/core_overloads_2.hpp rename to tests/data/core_overloads_2.hpp diff --git a/unittests/data/core_types.hpp b/tests/data/core_types.hpp similarity index 100% rename from unittests/data/core_types.hpp rename to tests/data/core_types.hpp diff --git a/unittests/data/covariant_returns.hpp b/tests/data/covariant_returns.hpp similarity index 100% rename from unittests/data/covariant_returns.hpp rename to tests/data/covariant_returns.hpp diff --git a/unittests/data/cpp_standards.hpp b/tests/data/cpp_standards.hpp similarity index 100% rename from unittests/data/cpp_standards.hpp rename to tests/data/cpp_standards.hpp diff --git a/unittests/data/decl_cache_file1.txt b/tests/data/decl_cache_file1.txt similarity index 100% rename from unittests/data/decl_cache_file1.txt rename to tests/data/decl_cache_file1.txt diff --git a/unittests/data/decl_cache_file1_duplicate.txt b/tests/data/decl_cache_file1_duplicate.txt similarity index 100% rename from unittests/data/decl_cache_file1_duplicate.txt rename to tests/data/decl_cache_file1_duplicate.txt diff --git a/unittests/data/decl_cache_file2.txt b/tests/data/decl_cache_file2.txt similarity index 100% rename from unittests/data/decl_cache_file2.txt rename to tests/data/decl_cache_file2.txt diff --git a/unittests/data/declaration_string.hpp b/tests/data/declaration_string.hpp similarity index 100% rename from unittests/data/declaration_string.hpp rename to tests/data/declaration_string.hpp diff --git a/unittests/data/declarations_calldef.hpp b/tests/data/declarations_calldef.hpp similarity index 100% rename from unittests/data/declarations_calldef.hpp rename to tests/data/declarations_calldef.hpp diff --git a/unittests/data/declarations_comparison.hpp b/tests/data/declarations_comparison.hpp similarity index 100% rename from unittests/data/declarations_comparison.hpp rename to tests/data/declarations_comparison.hpp diff --git a/unittests/data/declarations_enums.hpp b/tests/data/declarations_enums.hpp similarity index 100% rename from unittests/data/declarations_enums.hpp rename to tests/data/declarations_enums.hpp diff --git a/unittests/data/declarations_for_filtering.hpp b/tests/data/declarations_for_filtering.hpp similarity index 100% rename from unittests/data/declarations_for_filtering.hpp rename to tests/data/declarations_for_filtering.hpp diff --git a/unittests/data/declarations_variables.hpp b/tests/data/declarations_variables.hpp similarity index 100% rename from unittests/data/declarations_variables.hpp rename to tests/data/declarations_variables.hpp diff --git a/unittests/data/find_noncopyable_vars.hpp b/tests/data/find_noncopyable_vars.hpp similarity index 100% rename from unittests/data/find_noncopyable_vars.hpp rename to tests/data/find_noncopyable_vars.hpp diff --git a/unittests/data/free_operators.hpp b/tests/data/free_operators.hpp similarity index 100% rename from unittests/data/free_operators.hpp rename to tests/data/free_operators.hpp diff --git a/unittests/data/has_public_binary_operator_traits.hpp b/tests/data/has_public_binary_operator_traits.hpp similarity index 100% rename from unittests/data/has_public_binary_operator_traits.hpp rename to tests/data/has_public_binary_operator_traits.hpp diff --git a/unittests/data/include_all.hpp b/tests/data/include_all.hpp similarity index 100% rename from unittests/data/include_all.hpp rename to tests/data/include_all.hpp diff --git a/unittests/data/include_std.hpp b/tests/data/include_std.hpp similarity index 100% rename from unittests/data/include_std.hpp rename to tests/data/include_std.hpp diff --git a/unittests/data/indexing_suites2.hpp b/tests/data/indexing_suites2.hpp similarity index 100% rename from unittests/data/indexing_suites2.hpp rename to tests/data/indexing_suites2.hpp diff --git a/unittests/data/inline_specifier.hpp b/tests/data/inline_specifier.hpp similarity index 100% rename from unittests/data/inline_specifier.hpp rename to tests/data/inline_specifier.hpp diff --git a/unittests/data/itkImage.xml b/tests/data/itkImage.xml similarity index 100% rename from unittests/data/itkImage.xml rename to tests/data/itkImage.xml diff --git a/unittests/data/merge_free_functions.hpp b/tests/data/merge_free_functions.hpp similarity index 100% rename from unittests/data/merge_free_functions.hpp rename to tests/data/merge_free_functions.hpp diff --git a/unittests/data/msvc_build/all.cpp b/tests/data/msvc_build/all.cpp similarity index 100% rename from unittests/data/msvc_build/all.cpp rename to tests/data/msvc_build/all.cpp diff --git a/unittests/data/msvc_build/msvc_build.sln b/tests/data/msvc_build/msvc_build.sln similarity index 100% rename from unittests/data/msvc_build/msvc_build.sln rename to tests/data/msvc_build/msvc_build.sln diff --git a/unittests/data/msvc_build/msvc_build.vcproj b/tests/data/msvc_build/msvc_build.vcproj similarity index 100% rename from unittests/data/msvc_build/msvc_build.vcproj rename to tests/data/msvc_build/msvc_build.vcproj diff --git a/unittests/data/non_copyable_classes.hpp b/tests/data/non_copyable_classes.hpp similarity index 100% rename from unittests/data/non_copyable_classes.hpp rename to tests/data/non_copyable_classes.hpp diff --git a/unittests/data/noncopyable.hpp b/tests/data/noncopyable.hpp similarity index 100% rename from unittests/data/noncopyable.hpp rename to tests/data/noncopyable.hpp diff --git a/unittests/data/null_comparison.hpp b/tests/data/null_comparison.hpp similarity index 100% rename from unittests/data/null_comparison.hpp rename to tests/data/null_comparison.hpp diff --git a/unittests/data/ogre.1.7.xml.bz2 b/tests/data/ogre.1.7.xml.bz2 similarity index 100% rename from unittests/data/ogre.1.7.xml.bz2 rename to tests/data/ogre.1.7.xml.bz2 diff --git a/unittests/data/patcher.hpp b/tests/data/patcher.hpp similarity index 100% rename from unittests/data/patcher.hpp rename to tests/data/patcher.hpp diff --git a/unittests/data/patcher_tester_64bit.xml b/tests/data/patcher_tester_64bit.xml similarity index 100% rename from unittests/data/patcher_tester_64bit.xml rename to tests/data/patcher_tester_64bit.xml diff --git a/unittests/data/plain_c.c b/tests/data/plain_c.c similarity index 100% rename from unittests/data/plain_c.c rename to tests/data/plain_c.c diff --git a/unittests/data/remove_template_defaults.hpp b/tests/data/remove_template_defaults.hpp similarity index 100% rename from unittests/data/remove_template_defaults.hpp rename to tests/data/remove_template_defaults.hpp diff --git a/unittests/data/separate_compilation/all.h b/tests/data/separate_compilation/all.h similarity index 100% rename from unittests/data/separate_compilation/all.h rename to tests/data/separate_compilation/all.h diff --git a/unittests/data/separate_compilation/base.h b/tests/data/separate_compilation/base.h similarity index 100% rename from unittests/data/separate_compilation/base.h rename to tests/data/separate_compilation/base.h diff --git a/unittests/data/separate_compilation/data.h b/tests/data/separate_compilation/data.h similarity index 100% rename from unittests/data/separate_compilation/data.h rename to tests/data/separate_compilation/data.h diff --git a/unittests/data/separate_compilation/derived.h b/tests/data/separate_compilation/derived.h similarity index 100% rename from unittests/data/separate_compilation/derived.h rename to tests/data/separate_compilation/derived.h diff --git a/unittests/data/string_traits.hpp b/tests/data/string_traits.hpp similarity index 100% rename from unittests/data/string_traits.hpp rename to tests/data/string_traits.hpp diff --git a/unittests/data/test_argument_without_name.hpp b/tests/data/test_argument_without_name.hpp similarity index 100% rename from unittests/data/test_argument_without_name.hpp rename to tests/data/test_argument_without_name.hpp diff --git a/tests/data/test_array_argument.hpp b/tests/data/test_array_argument.hpp new file mode 100644 index 00000000..8973e0e2 --- /dev/null +++ b/tests/data/test_array_argument.hpp @@ -0,0 +1,13 @@ +// 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 + +class test +{ + public: + // A constructor + test(const float & t0){}; + + void function(int arg1[1024], int arg2[512]) {}; +}; diff --git a/unittests/data/test_ccflags.hpp b/tests/data/test_ccflags.hpp similarity index 100% rename from unittests/data/test_ccflags.hpp rename to tests/data/test_ccflags.hpp diff --git a/unittests/data/test_comments.hpp b/tests/data/test_comments.hpp similarity index 100% rename from unittests/data/test_comments.hpp rename to tests/data/test_comments.hpp diff --git a/unittests/data/test_copy_constructor.hpp b/tests/data/test_copy_constructor.hpp similarity index 100% rename from unittests/data/test_copy_constructor.hpp rename to tests/data/test_copy_constructor.hpp diff --git a/unittests/data/test_deprecation.hpp b/tests/data/test_deprecation.hpp similarity index 100% rename from unittests/data/test_deprecation.hpp rename to tests/data/test_deprecation.hpp diff --git a/unittests/data/test_elaborated_types.hpp b/tests/data/test_elaborated_types.hpp similarity index 100% rename from unittests/data/test_elaborated_types.hpp rename to tests/data/test_elaborated_types.hpp diff --git a/unittests/data/test_function_pointer.hpp b/tests/data/test_function_pointer.hpp similarity index 100% rename from unittests/data/test_function_pointer.hpp rename to tests/data/test_function_pointer.hpp diff --git a/unittests/data/test_map_gcc5.hpp b/tests/data/test_map_gcc5.hpp similarity index 100% rename from unittests/data/test_map_gcc5.hpp rename to tests/data/test_map_gcc5.hpp diff --git a/unittests/data/test_non_copyable_recursive.hpp b/tests/data/test_non_copyable_recursive.hpp similarity index 100% rename from unittests/data/test_non_copyable_recursive.hpp rename to tests/data/test_non_copyable_recursive.hpp diff --git a/unittests/data/test_order.hpp b/tests/data/test_order.hpp similarity index 100% rename from unittests/data/test_order.hpp rename to tests/data/test_order.hpp diff --git a/unittests/data/test_overrides.hpp b/tests/data/test_overrides.hpp similarity index 100% rename from unittests/data/test_overrides.hpp rename to tests/data/test_overrides.hpp diff --git a/unittests/data/test_pattern_parser.hpp b/tests/data/test_pattern_parser.hpp similarity index 100% rename from unittests/data/test_pattern_parser.hpp rename to tests/data/test_pattern_parser.hpp diff --git a/unittests/data/test_smart_pointer.hpp b/tests/data/test_smart_pointer.hpp similarity index 100% rename from unittests/data/test_smart_pointer.hpp rename to tests/data/test_smart_pointer.hpp diff --git a/unittests/data/type_as_exception_bug.h b/tests/data/type_as_exception_bug.h similarity index 100% rename from unittests/data/type_as_exception_bug.h rename to tests/data/type_as_exception_bug.h diff --git a/unittests/data/type_traits.hpp b/tests/data/type_traits.hpp similarity index 100% rename from unittests/data/type_traits.hpp rename to tests/data/type_traits.hpp diff --git a/unittests/data/typedefs1.hpp b/tests/data/typedefs1.hpp similarity index 100% rename from unittests/data/typedefs1.hpp rename to tests/data/typedefs1.hpp diff --git a/unittests/data/typedefs2.hpp b/tests/data/typedefs2.hpp similarity index 100% rename from unittests/data/typedefs2.hpp rename to tests/data/typedefs2.hpp diff --git a/unittests/data/typedefs_base.hpp b/tests/data/typedefs_base.hpp similarity index 100% rename from unittests/data/typedefs_base.hpp rename to tests/data/typedefs_base.hpp diff --git a/unittests/data/unnamed_classes.hpp b/tests/data/unnamed_classes.hpp similarity index 100% rename from unittests/data/unnamed_classes.hpp rename to tests/data/unnamed_classes.hpp diff --git a/unittests/data/unnamed_enums_bug1.hpp b/tests/data/unnamed_enums_bug1.hpp similarity index 100% rename from unittests/data/unnamed_enums_bug1.hpp rename to tests/data/unnamed_enums_bug1.hpp diff --git a/unittests/data/unnamed_enums_bug2.hpp b/tests/data/unnamed_enums_bug2.hpp similarity index 100% rename from unittests/data/unnamed_enums_bug2.hpp rename to tests/data/unnamed_enums_bug2.hpp diff --git a/unittests/data/unnamed_ns_bug.hpp b/tests/data/unnamed_ns_bug.hpp similarity index 100% rename from unittests/data/unnamed_ns_bug.hpp rename to tests/data/unnamed_ns_bug.hpp diff --git a/unittests/data/vector_traits.hpp b/tests/data/vector_traits.hpp similarity index 100% rename from unittests/data/vector_traits.hpp rename to tests/data/vector_traits.hpp diff --git a/unittests/example_tester_wrap.py b/tests/example_tester_wrap.py similarity index 85% rename from unittests/example_tester_wrap.py rename to tests/example_tester_wrap.py index a75642fc..000fb849 100644 --- a/unittests/example_tester_wrap.py +++ b/tests/example_tester_wrap.py @@ -28,9 +28,6 @@ sys.modules[__name__].__file__ = example_file # Run the example -if sys.version_info[:2] >= (3, 0): - with open(example_file) as f: - code = compile(f.read(), example_file, "exec") - exec(code, None, None) -else: - execfile(example_file) +with open(example_file) as f: + code = compile(f.read(), example_file, "exec") + exec(code, None, None) diff --git a/tests/test_algorithms_cache.py b/tests/test_algorithms_cache.py new file mode 100644 index 00000000..1e30185b --- /dev/null +++ b/tests/test_algorithms_cache.py @@ -0,0 +1,60 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = ['core_membership.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_name_based(global_ns): + cls = global_ns.class_(name='class_for_nested_enums_t') + + cls_full_name = declarations.full_name(cls) + assert cls.cache.full_name == cls_full_name + + cls_declaration_path = declarations.declaration_path(cls) + assert cls.cache.declaration_path == cls_declaration_path + + enum = cls.enumeration('ENestedPublic') + + enum_full_name = declarations.full_name(enum) + assert enum.cache.full_name == enum_full_name + + 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 + + assert not enum.cache.full_name + assert not enum.cache.declaration_path + + +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 new file mode 100644 index 00000000..93a457c9 --- /dev/null +++ b/tests/test_argument_without_name.py @@ -0,0 +1,43 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ['test_argument_without_name.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_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 & )'. + + See bug #55 + + """ + + 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 new file mode 100644 index 00000000..9b25d61c --- /dev/null +++ b/tests/test_array_argument.py @@ -0,0 +1,55 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +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 new file mode 100644 index 00000000..3236a849 --- /dev/null +++ b/tests/test_array_bug.py @@ -0,0 +1,86 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +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_attributes.py b/tests/test_attributes.py new file mode 100644 index 00000000..c45d0cf9 --- /dev/null +++ b/tests/test_attributes.py @@ -0,0 +1,66 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + # TODO: once gccxml is removed; rename this to something like + # annotate_tester + "attributes_castxml.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 test_attributes(global_ns): + numeric = global_ns.class_('numeric_t') + do_nothing = numeric.member_function('do_nothing') + arg = do_nothing.arguments[0] + assert "annotate(sealed)" == numeric.attributes + assert "annotate(no throw)" == do_nothing.attributes + assert "annotate(out)" == arg.attributes + assert numeric.member_operators(name="=")[0].attributes is None + + +def test_attributes_thiscall(): + """ + Test attributes with the "f2" flag + + """ + + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + + config.flags = ["f2"] + config.castxml_epic_version = 1 + + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + global_ns.init_optimizer() + + numeric = global_ns.class_('numeric_t') + do_nothing = numeric.member_function('do_nothing') + arg = do_nothing.arguments[0] + + assert "annotate(sealed)" == numeric.attributes + assert "annotate(out)" == arg.attributes + + assert "annotate(no throw)" == do_nothing.attributes + assert numeric.member_operators(name="=")[0].attributes is None diff --git a/tests/test_better_templates_matcher.py b/tests/test_better_templates_matcher.py new file mode 100644 index 00000000..97bc80d9 --- /dev/null +++ b/tests/test_better_templates_matcher.py @@ -0,0 +1,38 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "better_templates_matcher_tester.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 test_better_templates_matcher(global_ns): + classes = [ + "::Ogre::PlaneBoundedVolume", + "::Ogre::Plane", + "::Ogre::Singleton", + "::Ogre::PCZoneFactoryManager", + ] + for i in classes: + global_ns.class_(i) diff --git a/tests/test_bit_fields.py b/tests/test_bit_fields.py new file mode 100644 index 00000000..ec9aa738 --- /dev/null +++ b/tests/test_bit_fields.py @@ -0,0 +1,38 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "bit_fields.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 test_bit_fields(global_ns): + bf_x = global_ns.variable('x') + assert bf_x.bits == 1 + + bf_y = global_ns.variable('y') + assert bf_y.bits == 7 + + mv_z = global_ns.variable('z') + assert mv_z.bits is None diff --git a/tests/test_cache_enums.py b/tests/test_cache_enums.py new file mode 100644 index 00000000..1bd07e69 --- /dev/null +++ b/tests/test_cache_enums.py @@ -0,0 +1,41 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "declarations_enums.hpp", +] + + +def test_cache(): + cache_file = os.path.join(autoconfig.data_directory, 'pygccxml.cache') + if os.path.exists(cache_file) and os.path.isfile(cache_file): + os.remove(cache_file) + + config = autoconfig.cxx_parsers_cfg.config.clone() + + cache = parser.file_cache_t(cache_file) + reader = parser.source_reader_t(config, cache) + decls1 = reader.read_file(TEST_FILES[0]) + cache.flush() + cache = parser.file_cache_t(cache_file) + reader = parser.source_reader_t(config, cache) + decls2 = reader.read_file(TEST_FILES[0]) + + enum_matcher = declarations.declaration_matcher_t( + name="EColor", + decl_type=declarations.enumeration_t + ) + + color1 = declarations.matcher.get_single(enum_matcher, decls1) + color2 = declarations.matcher.get_single(enum_matcher, decls2) + assert color1.values == color2.values diff --git a/tests/test_cached_source_file.py b/tests/test_cached_source_file.py new file mode 100644 index 00000000..bdb6836f --- /dev/null +++ b/tests/test_cached_source_file.py @@ -0,0 +1,39 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import stat + +from . import autoconfig + +from pygccxml import utils +from pygccxml import parser + +TEST_FILES = [ + "core_types.hpp", +] + + +def test_cached_source_file(): + + config = autoconfig.cxx_parsers_cfg.config.clone() + + fconfig = parser.file_configuration_t( + data=TEST_FILES[0], + content_type=parser.CONTENT_TYPE.CACHED_SOURCE_FILE) + try: + prj_reader = parser.project_reader_t(config) + prj_reader.read_files( + [fconfig], + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + assert os.path.exists(fconfig.cached_source_file) + mtime1 = os.stat(fconfig.cached_source_file)[stat.ST_MTIME] + prj_reader.read_files( + [fconfig], + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + mtime2 = os.stat(fconfig.cached_source_file)[stat.ST_MTIME] + assert mtime1 == mtime2 + finally: + utils.remove_file_no_raise(fconfig.cached_source_file, config) diff --git a/tests/test_call_invocation.py b/tests/test_call_invocation.py new file mode 100644 index 00000000..9115254d --- /dev/null +++ b/tests/test_call_invocation.py @@ -0,0 +1,87 @@ +# 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 + +from pygccxml import declarations + + +def __test_split_impl(decl_string, name, args): + assert (name, args) == \ + declarations.call_invocation.split(decl_string) + + +def __test_split_recursive_impl(decl_string, control_seq): + assert control_seq == \ + list(declarations.call_invocation.split_recursive(decl_string)) + + +def __test_is_call_invocation_impl(decl_string): + assert declarations.call_invocation.is_call_invocation(decl_string) + + +def test_split_on_vector(): + __test_is_call_invocation_impl("vector(int,std::allocator(int) )") + + __test_split_impl( + "vector(int,std::allocator(int) )", + "vector", + ["int", "std::allocator(int)"]) + + __test_split_recursive_impl( + "vector(int,std::allocator(int) )", + [("vector", ["int", "std::allocator(int)"]), + ("std::allocator", ["int"])]) + + +def test_split_on_string(): + __test_is_call_invocation_impl( + "basic_string(char,std::char_traits(char),std::allocator(char) )") + + __test_split_impl( + "basic_string(char,std::char_traits(char),std::allocator(char) )", + "basic_string", + ["char", "std::char_traits(char)", "std::allocator(char)"]) + + +def test_split_on_map(): + __test_is_call_invocation_impl( + "map(long int,std::vector(int, std::allocator(int) )," + + "std::less(long int),std::allocator(std::pair" + + "(const long int, std::vector(int, std::allocator(int) ) ) ) )") + + __test_split_impl( + "map(long int,std::vector(int, std::allocator(int) )," + + "std::less(long int),std::allocator(std::pair" + + "(const long int, std::vector(int, std::allocator(int) ) ) ) )", + "map", + ["long int", "std::vector(int, std::allocator(int) )", + "std::less(long int)", + "std::allocator(std::pair(const long int," + + " std::vector(int, std::allocator(int) ) ) )"]) + + +def test_join_on_vector(): + assert "vector( int, std::allocator(int) )" == \ + declarations.call_invocation.join( + "vector", ("int", "std::allocator(int)")) + + +def test_find_args(): + temp = 'x()()' + found = declarations.call_invocation.find_args(temp) + assert (1, 2) == found + found = declarations.call_invocation.find_args(temp, found[1] + 1) + assert (3, 4) == found + temp = 'x(int,int)(1,2)' + found = declarations.call_invocation.find_args(temp) + assert (1, 9) == found + found = declarations.call_invocation.find_args(temp, found[1] + 1) + assert (10, 14) == found + + +def test_bug_unmatched_brace(): + src = 'AlternativeName((&string("")), (&string("")), (&string("")))' + __test_split_impl( + src, 'AlternativeName', [ + '(&string(""))', '(&string(""))', '(&string(""))']) diff --git a/tests/test_calldef_matcher.py b/tests/test_calldef_matcher.py new file mode 100644 index 00000000..cc02c61a --- /dev/null +++ b/tests/test_calldef_matcher.py @@ -0,0 +1,33 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "declarations_calldef.hpp", +] + + +@pytest.fixture +def decls(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + return decls + + +def test_calldef_matcher(decls): + criteria = declarations.calldef_matcher_t( + name='return_default_args', + return_type='int', + arg_types=[None, declarations.bool_t()]) + rda = declarations.matcher.get_single(criteria, decls) + assert rda is not None diff --git a/tests/test_calling_convention.py b/tests/test_calling_convention.py new file mode 100644 index 00000000..eab26161 --- /dev/null +++ b/tests/test_calling_convention.py @@ -0,0 +1,19 @@ +# 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 + +from pygccxml import declarations + + +def test_extract(): + data = [ + ('thiscall', + '(public: __thiscall std::auto_ptr' + + '::auto_ptr(class std::auto_ptr' + + ' &))'), + ('', "(const pof::number_t::`vftable')")] + + for expected, text in data: + got = declarations.CALLING_CONVENTION_TYPES.extract(text) + assert got == expected diff --git a/tests/test_castxml_wrong_epic.py b/tests/test_castxml_wrong_epic.py new file mode 100644 index 00000000..902c00d2 --- /dev/null +++ b/tests/test_castxml_wrong_epic.py @@ -0,0 +1,22 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser + + +def test_castxml_epic_version_check(): + """ + Test using a forbidden value for the castxml epic version. + + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 2 + with pytest.raises(RuntimeError): + parser.parse_string("", config) diff --git a/tests/test_ccflags.py b/tests/test_ccflags.py new file mode 100644 index 00000000..fe25b300 --- /dev/null +++ b/tests/test_ccflags.py @@ -0,0 +1,49 @@ +# Copyright 2014-2021 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "test_ccflags.hpp", +] + +COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + + +@pytest.fixture +def config(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + config.append_cflags("-fopenmp") + return config + + +def test_ccflags(config): + # First check that macro is not defined. + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + + namespace_names = [ + n.name for n in global_ns.namespaces(allow_empty=True) + ] + assert "ccflags_test_namespace" not in namespace_names + + # Next check that macro is defined when passed directly as ccflag + + if "clang++" in config.compiler_path: + config.append_ccflags("-Xpreprocessor") + config.append_ccflags("-fopenmp") + + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + + namespace_names = [n.name for n in global_ns.namespaces()] + assert "ccflags_test_namespace" in namespace_names diff --git a/tests/test_comments.py b/tests/test_comments.py new file mode 100644 index 00000000..214bd17e --- /dev/null +++ b/tests/test_comments.py @@ -0,0 +1,99 @@ +# Copyright 2014-2020 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "test_comments.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def _check_comment_content(list, comment_decl): + if comment_decl.text: + assert list == comment_decl.text + else: + print("No text in comment to check") + + +def test_comments(global_ns): + """ + Check the comment parsing + """ + tnamespace = global_ns.namespace("comment") + + assert "comment" in dir(tnamespace) + _check_comment_content( + [ + "//! Namespace Comment", + "//! Across multiple lines" + ], + tnamespace.comment + ) + + tenumeration = tnamespace.enumeration("com_enum") + assert "comment" in dir(tenumeration) + _check_comment_content( + ['/// Outside Class enum comment'], + tenumeration.comment + ) + + tclass = tnamespace.class_("test") + assert "comment" in dir(tclass) + _check_comment_content( + ["/** class comment */"], + tclass.comment + ) + + tcls_enumeration = tclass.enumeration("test_enum") + assert "comment" in dir(tcls_enumeration) + _check_comment_content( + ['/// inside class enum comment'], + tcls_enumeration.comment + ) + + tmethod = tclass.member_functions()[0] + + assert "comment" in dir(tmethod) + _check_comment_content( + ["/// cxx comment", "/// with multiple lines"], + tmethod.comment + ) + + tconstructor = tclass.constructors()[0] + + assert "comment" in dir(tconstructor) + _check_comment_content( + ["/** doc comment */"], + tconstructor.comment + ) + + for indx, cmt in enumerate( + [ + '//! mutable field comment', + "/// bit field comment" + ] + ): + tvariable = tclass.variables()[indx] + assert "comment" in dir(tvariable) + _check_comment_content([cmt], tvariable.comment) diff --git a/tests/test_complex_types.py b/tests/test_complex_types.py new file mode 100644 index 00000000..25f511e6 --- /dev/null +++ b/tests/test_complex_types.py @@ -0,0 +1,38 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import declarations +from pygccxml import parser + + +TEST_FILES = [ + "complex_types.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_complex_types(): + """ + This test tests presence of complex long double, float within + FUNDAMENTAL_TYPES map + """ + pass + # TODO: write test diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 00000000..06f0ddb0 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,58 @@ +# 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 pytest + +from pygccxml import parser +from pygccxml import utils + + +def test_config(): + """Test config setup with wrong xml generator setups.""" + + # Some code to parse for the example + code = "int a;" + + # Find the location of the xml generator (castxml) + generator_path, name = utils.find_xml_generator() + + # No xml generator path + config = parser.xml_generator_configuration_t(xml_generator=name) + with pytest.raises(RuntimeError): + parser.parse_string(code, config) + + # Invalid path + config = parser.xml_generator_configuration_t( + xml_generator_path="wrong/path", + xml_generator=name) + with pytest.raises(RuntimeError): + parser.parse_string(code, config) + + # None path + config = parser.xml_generator_configuration_t( + xml_generator_path=None, + xml_generator=name) + with pytest.raises(RuntimeError): + parser.parse_string(code, config) + + # No name + config = parser.xml_generator_configuration_t( + xml_generator_path=generator_path) + with pytest.raises(RuntimeError): + parser.parse_string(code, config) + + # Random name + config = parser.xml_generator_configuration_t( + xml_generator_path=generator_path, + xml_generator="not_a_generator") + with pytest.raises(RuntimeError): + parser.parse_string(code, config) + + # None name + config = parser.xml_generator_configuration_t( + xml_generator_path=generator_path, + xml_generator=None) + with pytest.raises(RuntimeError): + parser.parse_string(code, config) diff --git a/tests/test_const_volatile_arg.py b/tests/test_const_volatile_arg.py new file mode 100644 index 00000000..929024f0 --- /dev/null +++ b/tests/test_const_volatile_arg.py @@ -0,0 +1,38 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "const_volatile_arg.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_const_volatile_arg(global_ns): + f = global_ns.free_function('pygccxml_bug') + t = f.arguments[0].decl_type + assert isinstance(t, declarations.pointer_t) + assert isinstance(t.base, declarations.volatile_t) + assert isinstance(t.base.base, declarations.const_t) + assert declarations.is_integral(t.base.base.base) diff --git a/tests/test_copy_constructor.py b/tests/test_copy_constructor.py new file mode 100644 index 00000000..975c470b --- /dev/null +++ b/tests/test_copy_constructor.py @@ -0,0 +1,61 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "test_copy_constructor.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_copy_constructor(global_ns): + """ + Check the is_copy_constructor method. + + This fails when using CastXML, see issue #27. + + """ + + tclass = global_ns.class_("test") + ctors = [] + for decl in tclass.declarations: + if isinstance(decl, declarations.constructor_t): + ctors.append(decl) + + # test::test(test const & t0) [copy constructor] + assert declarations.is_copy_constructor(ctors[0]) + # test::test(float const & t0) [constructor] + assert not declarations.is_copy_constructor(ctors[1]) + # test::test(myvar t0) [constructor] + assert not declarations.is_copy_constructor(ctors[2]) + + t2class = global_ns.class_("test2") + ctors = [] + for decl in t2class.declarations: + if isinstance(decl, declarations.constructor_t): + ctors.append(decl) + + # test2::test2() [constructor] + assert not declarations.is_copy_constructor(ctors[0]) + # test2::test2(test2 const & arg0) [copy constructor] + assert declarations.is_copy_constructor(ctors[1]) diff --git a/tests/test_copy_constructor2.py b/tests/test_copy_constructor2.py new file mode 100644 index 00000000..a6e60fd8 --- /dev/null +++ b/tests/test_copy_constructor2.py @@ -0,0 +1,45 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import bz2 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +def test_copy_constructor2(): + # Extract the xml file from the bz2 archive + bz2_path = os.path.join( + autoconfig.data_directory, + 'ogre.1.7.xml.bz2') + xml_path = os.path.join( + autoconfig.data_directory, + 'ogre.1.7.xml') + with open(xml_path, 'wb') as new_file: + # bz2.BZ2File can not be used in a with statement in python 2.6 + bz2_file = bz2.BZ2File(bz2_path, 'rb') + for data in iter(lambda: bz2_file.read(100 * 1024), b''): + new_file.write(data) + bz2_file.close() + + reader = parser.source_reader_t(autoconfig.cxx_parsers_cfg.config) + global_ns = declarations.get_global_namespace( + reader.read_xml_file(xml_path) + ) + global_ns.init_optimizer() + + for x in global_ns.typedefs('SettingsMultiMap'): + assert declarations.is_noncopyable(x) is False + + for x in global_ns.typedefs('SettingsIterator'): + assert declarations.is_noncopyable(x) is False + + for x in global_ns.typedefs('SectionIterator'): + assert declarations.is_noncopyable(x) is False + + os.remove(xml_path) diff --git a/tests/test_core.py b/tests/test_core.py new file mode 100644 index 00000000..5ab852d6 --- /dev/null +++ b/tests/test_core.py @@ -0,0 +1,675 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import utils +from pygccxml import parser +from pygccxml import declarations + + +def is_sub_path(root, some_path): + root = utils.normalize_path(root) + some_path = utils.normalize_path(some_path) + return some_path.startswith(root) + + +TEST_FILES = [ + "core_ns_join_1.hpp", + "core_ns_join_2.hpp", + "core_ns_join_3.hpp", + "core_membership.hpp", + "core_class_hierarchy.hpp", + "core_types.hpp", + "core_diamand_hierarchy_base.hpp", + "core_diamand_hierarchy_derived1.hpp", + "core_diamand_hierarchy_derived2.hpp", + "core_diamand_hierarchy_final_derived.hpp", + "core_overloads_1.hpp", + "core_overloads_2.hpp", + "abstract_classes.hpp", +] + + +@pytest.fixture +def global_ns_fixture_all_at_once1(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 + + +@pytest.fixture +def global_ns_fixture_all_at_once2(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = False + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 + + +@pytest.fixture +def global_ns_fixture_file_by_file1(): + COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE + INIT_OPTIMIZER = True + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 + + +@pytest.fixture +def global_ns_fixture_file_by_file2(): + COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE + INIT_OPTIMIZER = False + config = autoconfig.cxx_parsers_cfg.config.clone() + 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 + + +@pytest.fixture +def global_ns(request): + return request.getfixturevalue(request.param) + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_top_parent(global_ns): + enum = global_ns.enumeration("::ns::ns32::E33") + assert global_ns is enum.top_parent + + +# tests namespaces join functionality. described in gccxml.py +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_nss_join(global_ns): + # list of all namespaces + nss = ["::ns", "::ns::ns12", "::ns::ns22", "::ns::ns32"] + # list of all namespaces that have unnamed namespace + # unnamed_nss = nss[1:] doing nothing with this list ? + # list of all enums [0:2] [3:5] [6:8] - has same parent + enums = [ + "::E11", + "::E21", + "::E31", + "::ns::E12", + "::ns::E22", + "::ns::E32", + "::ns::ns12::E13", + "::ns::ns22::E23", + "::ns::ns32::E33", + ] + + for ns in nss: + global_ns.namespace(ns) + + for enum in enums: + global_ns.enumeration(enum) + + ns = global_ns.namespace(nss[0]) + ns12 = global_ns.namespace(nss[1]) + ns22 = global_ns.namespace(nss[2]) + ns32 = global_ns.namespace(nss[3]) + assert ns is ns12.parent is ns22.parent is ns32.parent + + e11 = global_ns.enumeration(enums[0]) + e21 = global_ns.enumeration(enums[1]) + e31 = global_ns.enumeration(enums[2]) + assert e11.parent is e21.parent is e31.parent + + nse12 = global_ns.enumeration(enums[3]) + nse23 = global_ns.enumeration(enums[4]) + nse33 = global_ns.enumeration(enums[5]) + assert ns is nse12.parent is nse23.parent is nse33.parent + + +def _test_ns_membership(ns, enum_name): + unnamed_enum = ns.enumeration( + lambda d: d.name == "" + and is_sub_path(autoconfig.data_directory, d.location.file_name), + recursive=False, + ) + assert unnamed_enum in ns.declarations + + enum = ns.enumeration(enum_name, recursive=False) + assert enum in ns.declarations + assert unnamed_enum.parent is ns + assert enum.parent is ns + + +def _test_class_membership(class_inst, enum_name, access): + # getting enum through get_members function + nested_enum1 = class_inst.enumeration( + name=enum_name, function=declarations.access_type_matcher_t(access) + ) + + # getting enum through declarations property + nested_enum2 = class_inst.enumeration(enum_name) + + # it shoud be same object + assert nested_enum1 is nested_enum2 + + # check whether we meaning same class instance + assert class_inst is nested_enum1.parent is nested_enum2.parent + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +# test gccxml_file_reader_t._update_membership algorithm +def test_membership(global_ns): + core_membership = global_ns.namespace("membership") + _test_ns_membership(global_ns, "EGlobal") + _test_ns_membership(core_membership.namespace("enums_ns"), "EWithin") + _test_ns_membership(core_membership.namespace(""), "EWithinUnnamed") + class_nested_enums = core_membership.class_("class_for_nested_enums_t") + _test_class_membership( + class_nested_enums, + "ENestedPublic", + declarations.ACCESS_TYPES.PUBLIC + ) + _test_class_membership( + class_nested_enums, + "ENestedProtected", + declarations.ACCESS_TYPES.PROTECTED + ) + _test_class_membership( + class_nested_enums, + "ENestedPrivate", + declarations.ACCESS_TYPES.PRIVATE + ) + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_mangled_name_namespace(global_ns): + std = global_ns.namespace("std") + assert std is not None + assert std.mangled is None + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_mangled_name_functions(global_ns): + # This works with gccxml and castxml + ns = global_ns.namespace("overloads") + do_nothing = ns.calldefs("do_nothing", recursive=False) + assert do_nothing.mangled is not None + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_mangled_name_variable(global_ns): + # This works with gccxml and castxml + var_inst = global_ns.variable("array255") + assert var_inst.mangled is not None + + +def _test_is_based_and_derived(base, derived, access): + dhi_v = declarations.hierarchy_info_t(derived, access, True) + dhi_not_v = declarations.hierarchy_info_t(derived, access, False) + assert dhi_v in base.derived or dhi_not_v in base.derived + + bhi_v = declarations.hierarchy_info_t(base, access, True) + bhi_not_v = declarations.hierarchy_info_t(base, access, False) + + assert bhi_v in derived.bases or bhi_not_v in derived.bases + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_class_hierarchy(global_ns): + class_hierarchy = global_ns.namespace("class_hierarchy") + + base = class_hierarchy.class_("base_t") + other_base = class_hierarchy.class_("other_base_t") + derived_public = class_hierarchy.class_("derived_public_t") + derived_protected = class_hierarchy.class_("derived_protected_t") + derived_private = class_hierarchy.class_("derived_private_t") + multi_derived = class_hierarchy.class_("multi_derived_t") + + _test_is_based_and_derived( + base, + derived_public, + declarations.ACCESS_TYPES.PUBLIC + ) + _test_is_based_and_derived( + base, + derived_protected, + declarations.ACCESS_TYPES.PROTECTED + ) + _test_is_based_and_derived( + base, + derived_private, + declarations.ACCESS_TYPES.PRIVATE + ) + _test_is_based_and_derived( + base, multi_derived, + declarations.ACCESS_TYPES.PROTECTED + ) + _test_is_based_and_derived( + other_base, + multi_derived, + declarations.ACCESS_TYPES.PRIVATE + ) + _test_is_based_and_derived( + derived_private, + multi_derived, + declarations.ACCESS_TYPES.PRIVATE + ) + + +def _test_is_same_bases(derived1, derived2): + bases1 = set( + [id(hierarchy_info.related_class) for hierarchy_info in derived1.bases] + ) + bases2 = set( + [id(hierarchy_info.related_class) for hierarchy_info in derived2.bases] + ) + assert bases1 == bases2 + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_class_join(global_ns): + diamand_hierarchy = global_ns.namespace("diamand_hierarchy") + base = diamand_hierarchy.class_("base_t") + derived1 = diamand_hierarchy.class_("derived1_t") + derived2 = diamand_hierarchy.class_("derived2_t") + final_derived = diamand_hierarchy.class_("final_derived_t") + + _test_is_based_and_derived( + base, + derived1, + declarations.ACCESS_TYPES.PUBLIC + ) + _test_is_based_and_derived( + base, + derived2, + declarations.ACCESS_TYPES.PUBLIC + ) + _test_is_based_and_derived( + derived1, + final_derived, + declarations.ACCESS_TYPES.PUBLIC + ) + _test_is_based_and_derived( + derived2, + final_derived, + declarations.ACCESS_TYPES.PUBLIC + ) + _test_is_same_bases(derived1, derived2) + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_fundamental_types(global_ns): + # check whether all build in types could be constructed + errors = [] + for ( + fundamental_type_name, + fundamental_type, + ) in declarations.FUNDAMENTAL_TYPES.items(): + if "complex" in fundamental_type_name: + continue # I check this in an other tester + if isinstance( + fundamental_type, (declarations.int128_t, declarations.uint128_t) + ): + continue # I don't have test case for this + if isinstance(fundamental_type, declarations.java_fundamental_t): + continue # I don't check this at all + typedef_name = "typedef_" + fundamental_type_name.replace(" ", "_") + typedef = global_ns.decl( + decl_type=declarations.typedef_t, + name=typedef_name + ) + assert typedef is not None + if typedef.decl_type.decl_string != fundamental_type.decl_string: + errors.append( + "there is a difference between typedef base type " + + "name('%s') and expected one('%s')" + % (typedef.decl_type.decl_string, fundamental_type.decl_string) + ) + assert len(errors) == 0 + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_compound_types(global_ns, helpers): + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, name="typedef_const_int" + ) + helpers._test_type_composition( + typedef_inst.decl_type, declarations.const_t, declarations.int_t + ) + + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, name="typedef_pointer_int" + ) + helpers._test_type_composition( + typedef_inst.decl_type, declarations.pointer_t, declarations.int_t + ) + + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, name="typedef_reference_int" + ) + helpers._test_type_composition( + typedef_inst.decl_type, declarations.reference_t, declarations.int_t + ) + + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, + name="typedef_const_unsigned_int_const_pointer", + ) + helpers._test_type_composition( + typedef_inst.decl_type, + declarations.const_t, + declarations.pointer_t + ) + helpers._test_type_composition( + typedef_inst.decl_type.base, + declarations.pointer_t, + declarations.const_t + ) + helpers._test_type_composition( + typedef_inst.decl_type.base.base, + declarations.const_t, + declarations.unsigned_int_t, + ) + + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, + name="typedef_volatile_int" + ) + helpers._test_type_composition( + typedef_inst.decl_type, + declarations.volatile_t, + declarations.int_t + ) + + var_inst = global_ns.variable("array255") + helpers._test_type_composition( + var_inst.decl_type, + declarations.array_t, + declarations.int_t + ) + + typedef_inst = global_ns.decl( + decl_type=declarations.typedef_t, + name="typedef_EFavoriteDrinks" + ) + assert isinstance(typedef_inst.decl_type, declarations.declarated_t) + enum_declaration = global_ns.enumeration("EFavoriteDrinks") + assert typedef_inst.decl_type.declaration is enum_declaration + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_free_function_type(global_ns, helpers): + function_ptr = global_ns.decl( + decl_type=declarations.typedef_t, + name="function_ptr") + helpers._test_type_composition( + function_ptr.decl_type, + declarations.pointer_t, + declarations.free_function_type_t, + ) + function_type = function_ptr.decl_type.base + assert isinstance(function_type.return_type, declarations.int_t) + assert len(function_type.arguments_types) == 2 + assert isinstance(function_type.arguments_types[0], declarations.int_t) + assert isinstance(function_type.arguments_types[1], declarations.double_t) + + +@pytest.mark.parametrize( + "global_ns", + ["global_ns_fixture_all_at_once1"], + indirect=True + ) +def test_member_function_type(global_ns, helpers): + function_ptr = global_ns.decl( + decl_type=declarations.typedef_t, name="member_function_ptr_t" + ) + helpers._test_type_composition( + function_ptr.decl_type, + declarations.pointer_t, + declarations.member_function_type_t, + ) + + function_type = function_ptr.decl_type.base + + members_pointers = global_ns.class_("members_pointers_t") + assert function_type.class_inst.declaration is members_pointers + + assert isinstance(function_type.return_type, declarations.int_t) + assert len(function_type.arguments_types) == 1 + assert isinstance(function_type.arguments_types[0], declarations.double_t) + assert function_type.has_const is True + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_member_variable_type(global_ns, helpers): + mv = global_ns.decl( + decl_type=declarations.typedef_t, + name="member_variable_ptr_t" + ) + helpers._test_type_composition( + mv.decl_type, + declarations.pointer_t, + declarations.member_variable_type_t + ) + + members_pointers = global_ns.class_("members_pointers_t") + assert members_pointers is not None + helpers._test_type_composition( + mv.decl_type.base, + declarations.member_variable_type_t, + declarations.declarated_t, + ) + mv_type = mv.decl_type.base + assert mv_type.base.declaration == members_pointers + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_overloading(global_ns): + ns = global_ns.namespace("overloads") + + do_nothings = ns.calldefs("do_nothing", recursive=False) + assert 4 == len(do_nothings) + for index, do_nothing in enumerate(do_nothings): + others = do_nothings[:index] + do_nothings[index + 1:] + if set(do_nothing.overloads) != set(others): + print("\nexisting: ") + for x in do_nothing.overloads: + print(str(x)) + print("\nexpected: ") + for x in others: + print(str(x)) + + assert set(do_nothing.overloads) == set(others) + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_abstract_classes(global_ns): + ns = global_ns.namespace("abstract_classes") + abstract_i = ns.class_("abstract_i") + assert abstract_i.is_abstract is True + derived_abstract_i = ns.class_("derived_abstract_i") + assert derived_abstract_i.is_abstract is True + implementation = ns.class_("implementation") + assert implementation.is_abstract is not True + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_byte_size(global_ns): + mptrs = global_ns.class_("members_pointers_t") + assert mptrs.byte_size != 0 + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_byte_align(global_ns): + mptrs = global_ns.class_("members_pointers_t") + assert mptrs.byte_align != 0 + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once1", + "global_ns_fixture_all_at_once2", + "global_ns_fixture_file_by_file1", + "global_ns_fixture_file_by_file2", + ], + indirect=True, +) +def test_byte_offset(global_ns): + mptrs = global_ns.class_("members_pointers_t") + assert mptrs.variable("xxx").byte_offset != 0 diff --git a/tests/test_cpp_standards.py b/tests/test_cpp_standards.py new file mode 100644 index 00000000..36ea3c97 --- /dev/null +++ b/tests/test_cpp_standards.py @@ -0,0 +1,46 @@ +# 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 pytest + +import platform + +from . import autoconfig + +from pygccxml import parser + + +def test_cpp_standards(): + """ + Test different compilation standards by setting cflags. + + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + + parser.parse(["cpp_standards.hpp"], config) + + if platform.system() != 'Windows': + config.cflags = "-std=c++98" + parser.parse(["cpp_standards.hpp"], config) + + config.cflags = "-std=c++03" + parser.parse(["cpp_standards.hpp"], config) + + config.cflags = "-std=c++11" + + parser.parse(["cpp_standards.hpp"], config) + + config.cflags = "-std=c++14" + parser.parse(["cpp_standards.hpp"], config) + + config.cflags = "-std=c++1z" + parser.parse(["cpp_standards.hpp"], config) + + # Pass down a flag that does not exist. + # This should raise an exception. + config.cflags = "-std=c++00" + with pytest.raises(RuntimeError): + parser.parse(["cpp_standards.hpp"], config) diff --git a/tests/test_create_decl_string.py b/tests/test_create_decl_string.py new file mode 100644 index 00000000..aed3f0cf --- /dev/null +++ b/tests/test_create_decl_string.py @@ -0,0 +1,53 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "declaration_string.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_create_decl_string(global_ns): + """ + Test the create_decl_string method. + + """ + + myfunc = global_ns.free_function("myfunc") + + decl = declarations.free_function_type_t.create_decl_string( + myfunc.return_type, myfunc.argument_types) + + assert decl != "('int (*)( int,int )', 'int (*)( int,int )')" + + box = global_ns.class_("Box") + myinternfunc = box.member_function("myinternfunc") + decl = declarations.member_function_type_t.create_decl_string( + myinternfunc.return_type, + box.decl_string, + myinternfunc.argument_types, + myinternfunc.has_const) + + assert decl != "short int ( ::Box::* )( ) " diff --git a/tests/test_decl_printer.py b/tests/test_decl_printer.py new file mode 100644 index 00000000..0a3542ef --- /dev/null +++ b/tests/test_decl_printer.py @@ -0,0 +1,61 @@ +# 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 sys +import pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + 'core_ns_join_1.hpp', + 'core_ns_join_2.hpp', + 'core_ns_join_3.hpp', + 'core_membership.hpp', + 'core_class_hierarchy.hpp', + 'core_types.hpp', + 'core_diamand_hierarchy_base.hpp', + 'core_diamand_hierarchy_derived1.hpp', + 'core_diamand_hierarchy_derived2.hpp', + 'core_diamand_hierarchy_final_derived.hpp', + 'core_overloads_1.hpp', + 'core_overloads_2.hpp', + 'typedefs_base.hpp', +] + + +@pytest.fixture +def decls(): + COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + return decls + + +def test_printer(decls): + # Redirect sys.stdout to a class with a writer doing nothing + # This greatly reduces the size of the test output and makes + # test log files readable. + # Note: flush needs to be defined; because if not this will + # result in an AttributeError on call. + class DontPrint(object): + def write(*args): + pass + + def flush(*args): + pass + sys.stdout = DontPrint() + + declarations.print_declarations(decls) + + +def test__str__(decls): + decls = declarations.make_flatten(decls) + for decl in decls: + str(decl) diff --git a/tests/test_decl_string.py b/tests/test_decl_string.py new file mode 100644 index 00000000..fe13fde2 --- /dev/null +++ b/tests/test_decl_string.py @@ -0,0 +1,71 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "declarations_calldef.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +TEMPLATE = """ + //test generated declaration string using gcc(xml) compiler + #include "declarations_calldef.hpp" + void test_generated_decl_string( %s ); + """ + + +def test_member_function(global_ns): + config = autoconfig.cxx_parsers_cfg.config.clone() + member_inline_call = \ + global_ns.member_function('member_inline_call') + decls = parser.parse_string( + TEMPLATE % + member_inline_call.decl_string, + config) + assert decls is not None + + +def test_free_function(global_ns): + config = autoconfig.cxx_parsers_cfg.config.clone() + return_default_args = \ + global_ns.free_function('return_default_args') + decls = parser.parse_string( + TEMPLATE % + return_default_args.decl_string, + config) + assert decls is not None + + +def test_all_mem_and_free_funs(global_ns): + config = autoconfig.cxx_parsers_cfg.config.clone() + ns = global_ns.namespace('::declarations::calldef') + for f in ns.member_functions(): + decls = parser.parse_string( + TEMPLATE % f.decl_string, config) + assert decls is not None + for f in ns.free_functions(): + decls = parser.parse_string( + TEMPLATE % f.decl_string, config) + assert decls is not None diff --git a/tests/test_declaration_files.py b/tests/test_declaration_files.py new file mode 100644 index 00000000..845f8495 --- /dev/null +++ b/tests/test_declaration_files.py @@ -0,0 +1,41 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + 'core_ns_join_1.hpp', + 'core_ns_join_2.hpp', + 'core_ns_join_3.hpp', + 'core_membership.hpp', + 'core_class_hierarchy.hpp', + 'core_types.hpp', + 'core_diamand_hierarchy_base.hpp', + 'core_diamand_hierarchy_derived1.hpp', + 'core_diamand_hierarchy_derived2.hpp', + 'core_diamand_hierarchy_final_derived.hpp', + 'core_overloads_1.hpp', + 'core_overloads_2.hpp', + 'typedefs_base.hpp', +] + + +def test_declaration_files(): + config = autoconfig.cxx_parsers_cfg.config.clone() + prj_reader = parser.project_reader_t(config) + decls = prj_reader.read_files( + TEST_FILES, + compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE) + files = declarations.declaration_files(decls) + result = set() + for fn in files: + result.add(os.path.split(fn)[1]) + assert set(TEST_FILES).issubset(result) is True diff --git a/tests/test_declaration_matcher.py b/tests/test_declaration_matcher.py new file mode 100644 index 00000000..3a36d5b0 --- /dev/null +++ b/tests/test_declaration_matcher.py @@ -0,0 +1,68 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "classes.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_global(global_ns): + global_ns.class_('cls') + global_ns.class_('::cls') + + +def test_typedefs(global_ns): + global_ns.class_('cls2') + global_ns.typedef('cls2') + global_ns.class_('::cls2') + + global_ns.class_('cls3') + global_ns.typedef('cls3') + cls3 = global_ns.class_('::cls3') + cls3.variable('i') + + +def test_ns1(global_ns): + ns1 = global_ns.namespace('ns') + + global_ns.class_('nested_cls') + with pytest.raises(Exception): + global_ns.class_('ns::nested_cls') + global_ns.class_('::ns::nested_cls') + + with pytest.raises(Exception): + ns1.class_('::nested_cls') + ns1.class_('nested_cls') + ns1.class_('::ns::nested_cls') + + global_ns.class_('nested_cls2') + with pytest.raises(Exception): + global_ns.class_('ns::nested_cls2') + global_ns.class_('::ns::nested_cls2') + + global_ns.class_('nested_cls3') + with pytest.raises(Exception): + global_ns.class_('ns::nested_cls3') + global_ns.class_('::ns::nested_cls3') diff --git a/tests/test_declarations.py b/tests/test_declarations.py new file mode 100644 index 00000000..66b7a561 --- /dev/null +++ b/tests/test_declarations.py @@ -0,0 +1,304 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "declarations_enums.hpp", + "declarations_variables.hpp", + "declarations_calldef.hpp", +] + + +@pytest.fixture +def global_ns_fixture_all_at_once(): + 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) + return global_ns + + +@pytest.fixture +def global_ns_fixture_file_by_file(): + COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config, COMPILATION_MODE) + global_ns = declarations.get_global_namespace(decls) + return global_ns + + +@pytest.fixture +def global_ns(request): + return request.getfixturevalue(request.param) + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_enumeration_t(global_ns): + enum = global_ns.enumeration("ENumbers") + expected_values = list( + zip( + ["e%d" % index for index in range(10)], + [index for index in range(10)] + ) + ) + assert expected_values == enum.values + + +def test_namespace(): + pass # tested in core_tester + + +def test_types(): + pass # tested in core_tester + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_variables(global_ns, helpers): + global_ns.namespace("variables") + initialized = global_ns.variable(name="initialized") + + expected_value = "10122004" + assert initialized.value == expected_value + helpers._test_type_composition( + initialized.decl_type, + declarations.const_t, + declarations.long_unsigned_int_t + ) + + m_mutable = global_ns.variable(name="m_mutable") + assert m_mutable.type_qualifiers.has_static is False + assert m_mutable.type_qualifiers.has_mutable is True + + # External static variable + extern_var = global_ns.variable(name="extern_var") + assert extern_var.type_qualifiers.has_extern is True + assert extern_var.type_qualifiers.has_static is False + assert extern_var.type_qualifiers.has_mutable is False + + # Static variable + static_var = global_ns.variable(name="static_var") + assert static_var.type_qualifiers.has_static is True + assert static_var.type_qualifiers.has_extern is False + assert static_var.type_qualifiers.has_mutable is False + + ssv_static_var = global_ns.variable(name="ssv_static_var") + assert ssv_static_var.type_qualifiers.has_static is True + assert ssv_static_var.type_qualifiers.has_extern is False + assert ssv_static_var.type_qualifiers.has_mutable is False + + ssv_static_var_value = global_ns.variable(name="ssv_static_var_value") + assert ssv_static_var_value.type_qualifiers.has_static is True + assert ssv_static_var_value.type_qualifiers.has_extern is False + assert ssv_static_var_value.type_qualifiers.has_mutable is False + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_calldef_free_functions(global_ns, helpers): + ns = global_ns.namespace("calldef") + + no_return_no_args = ns.free_function("no_return_no_args") + + helpers._test_calldef_return_type(no_return_no_args, declarations.void_t) + assert no_return_no_args.has_extern is False + + # Static_call is explicetely defined as extern, this works with gccxml + # and castxml. + static_call = ns.free_function("static_call") + assert static_call is not None + + return_no_args = ns.free_function("return_no_args") + helpers._test_calldef_return_type(return_no_args, declarations.int_t) + # from now there is no need to check return type. + no_return_1_arg = ns.free_function(name="no_return_1_arg") + assert no_return_1_arg is not None + assert no_return_1_arg.arguments[0].name in ["arg", "arg0"] + helpers._test_calldef_args( + no_return_1_arg, + [ + declarations.argument_t( + name=no_return_1_arg.arguments[0].name, + decl_type=declarations.int_t() + ) + ], + ) + + return_default_args = ns.free_function("return_default_args") + assert return_default_args.arguments[0].name in ["arg", "arg0"] + assert return_default_args.arguments[1].name in ["arg1", "flag"] + helpers._test_calldef_args( + return_default_args, + [ + declarations.argument_t( + name=return_default_args.arguments[0].name, + decl_type=declarations.int_t(), + default_value="1", + ), + declarations.argument_t( + name=return_default_args.arguments[1].name, + decl_type=declarations.bool_t(), + default_value="false", + ), + ], + ) + helpers._test_calldef_exceptions(global_ns, return_default_args, []) + + calldef_with_throw = ns.free_function("calldef_with_throw") + assert calldef_with_throw is not None + helpers._test_calldef_exceptions( + global_ns, calldef_with_throw, + ["some_exception_t", "other_exception_t"] + ) + # from now there is no need to check exception specification + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_calldef_member_functions(global_ns, helpers): + struct_calldefs = global_ns.class_("calldefs_t") + + member_inline_call = struct_calldefs.member_function("member_inline_call") + helpers._test_calldef_args( + member_inline_call, + [declarations.argument_t(name="i", decl_type=declarations.int_t())], + ) + + member_const_call = struct_calldefs.member_function("member_const_call") + assert member_const_call.has_const + assert member_const_call.virtuality == \ + declarations.VIRTUALITY_TYPES.NOT_VIRTUAL + + member_virtual_call = struct_calldefs.member_function( + name="member_virtual_call" + ) + assert member_virtual_call.virtuality == \ + declarations.VIRTUALITY_TYPES.VIRTUAL + + member_pure_virtual_call = struct_calldefs.member_function( + "member_pure_virtual_call" + ) + assert ( + member_pure_virtual_call.virtuality + == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL + ) + + static_call = struct_calldefs.member_function("static_call") + assert static_call.has_static is True + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_constructors_destructors(global_ns, helpers): + struct_calldefs = global_ns.class_("calldefs_t") + + destructor = struct_calldefs.calldef("~calldefs_t") + helpers._test_calldef_args(destructor, []) + helpers._test_calldef_return_type(destructor, None.__class__) + + # well, now we have a few functions ( constructors ) with the same + # name, there is no easy way to find the desired one. Well in my case + # I have only 4 constructors + # 1. from char + # 2. from (int,double) + # 3. default + # 4. copy constructor + constructor_found = struct_calldefs.constructors("calldefs_t") + assert len(constructor_found) == 5 + assert ( + len( + [ + constructor + for constructor in constructor_found + if declarations.is_copy_constructor(constructor) + ] + ) + == 1 + ) + # there is nothing to check about constructors - I know the + # implementation of parser. + # In this case it doesn't different from any other function + + c = struct_calldefs.constructor("calldefs_t", arg_types=["char"]) + assert c.explicit is True + + arg_type = declarations.declarated_t(global_ns.class_("some_exception_t")) + c = struct_calldefs.constructor("calldefs_t", arg_types=[arg_type]) + assert c.explicit is False + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_operator_symbol(global_ns): + calldefs_operators = ["=", "=="] + calldefs_cast_operators = ["char *", "double"] + struct_calldefs = global_ns.class_("calldefs_t") + assert struct_calldefs is not None + for decl in struct_calldefs.declarations: + if not isinstance(decl, declarations.operator_t): + continue + if not isinstance(decl, declarations.casting_operator_t): + assert decl.symbol in calldefs_operators + else: + assert decl.return_type.decl_string in calldefs_cast_operators + + +@pytest.mark.parametrize( + "global_ns", + [ + "global_ns_fixture_all_at_once", + "global_ns_fixture_file_by_file", + ], + indirect=True, +) +def test_ellipsis(global_ns): + ns = global_ns.namespace("ellipsis_tester") + do_smth = ns.member_function("do_smth") + assert do_smth.has_ellipsis is True + do_smth_else = ns.free_function("do_smth_else") + assert do_smth_else.has_ellipsis is True diff --git a/tests/test_declarations_cache.py b/tests/test_declarations_cache.py new file mode 100644 index 00000000..204cc0bc --- /dev/null +++ b/tests/test_declarations_cache.py @@ -0,0 +1,144 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import os.path + +from . import autoconfig + +from pygccxml.parser.config import xml_generator_configuration_t +from pygccxml.parser import declarations_cache + + +def test_file_signature(): + file1 = os.path.join(autoconfig.data_directory, 'decl_cache_file1.txt') + file1_dup = os.path.join( + autoconfig.data_directory, + 'decl_cache_file1_duplicate.txt') + file2 = os.path.join(autoconfig.data_directory, 'decl_cache_file2.txt') + sig1 = declarations_cache.file_signature(file1) + sig1_dup = declarations_cache.file_signature(file1_dup) + sig2 = declarations_cache.file_signature(file2) + assert sig1 == sig1_dup + assert sig1 != sig2 + + +def test_config_signature(): + diff_cfg_list = build_differing_cfg_list() + def_cfg = diff_cfg_list[0] + def_sig = declarations_cache.configuration_signature(def_cfg) + + # Test changes that should cause sig changes + for cfg in diff_cfg_list[1:]: + assert declarations_cache.configuration_signature(cfg) != def_sig + + # Test changes that should not cause sig changes + no_changes = def_cfg.clone() + assert declarations_cache.configuration_signature(no_changes) == def_sig + + ignore_changed = def_cfg.clone() + ignore_changed.ignore_gccxml_output = True + assert ( + declarations_cache.configuration_signature(ignore_changed) == def_sig + ) + + +def test_cache_interface(): + cache_file = os.path.join( + autoconfig.build_directory, + 'decl_cache_test.test_cache_read.cache') + file1 = os.path.join(autoconfig.data_directory, 'decl_cache_file1.txt') + file1_dup = os.path.join( + autoconfig.data_directory, + 'decl_cache_file1_duplicate.txt') + file2 = os.path.join(autoconfig.data_directory, 'decl_cache_file2.txt') + diff_cfg_list = build_differing_cfg_list() + def_cfg = diff_cfg_list[0] + + if os.path.exists(cache_file): + os.remove(cache_file) + + cache = declarations_cache.file_cache_t(cache_file) + assert len(cache._file_cache_t__cache) == 0 + + # test creating new entries for differing files + cache.update(file1, def_cfg, 1, []) + assert len(cache._file_cache_t__cache) == 1 + cache.update(file1_dup, def_cfg, 2, []) + assert len(cache._file_cache_t__cache) == 1 + cache.update(file2, def_cfg, 3, []) + assert len(cache._file_cache_t__cache) == 2 + + assert cache.cached_value(file1, def_cfg) == 2 + assert cache.cached_value(file2, def_cfg) == 3 + + # Test reading again + cache.flush() + cache = declarations_cache.file_cache_t(cache_file) + assert len(cache._file_cache_t__cache) == 2 + assert cache.cached_value(file1, def_cfg) == 2 + assert cache.cached_value(file2, def_cfg) == 3 + + # Test flushing doesn't happen if we don't touch the cache + cache = declarations_cache.file_cache_t(cache_file) + assert cache.cached_value(file1, def_cfg) == 2 # Read from cache + cache.flush() # should not actually flush + cache = declarations_cache.file_cache_t(cache_file) + assert len(cache._file_cache_t__cache) == 2 + + # Test flush culling + cache = declarations_cache.file_cache_t(cache_file) + cache.update(file1_dup, def_cfg, 4, []) # Modify cache + cache.flush() # should cull off one entry + cache = declarations_cache.file_cache_t(cache_file) + assert len(cache._file_cache_t__cache) == 1 + + +def build_differing_cfg_list(): + """ Return a list of configurations that all differ. """ + cfg_list = [] + def_cfg = xml_generator_configuration_t( + "xml_generator_path", + '.', ['tmp'], ['sym'], ['unsym'], None, False, "") + cfg_list.append(def_cfg) + + # Test changes that should cause sig changes + gccxml_changed = def_cfg.clone() + gccxml_changed.xml_generator_path = "other_path" + cfg_list.append(gccxml_changed) + + wd_changed = def_cfg.clone() + wd_changed.working_directory = "other_dir" + cfg_list.append(wd_changed) + + # inc_changed = def_cfg.clone() + # inc_changed.include_paths = ["/var/tmp"] + # assert configuration_signature(inc_changed) != def_sig) + inc_changed = xml_generator_configuration_t( + "xml_generator_path", '.', ['/var/tmp'], ['sym'], ['unsym'], + None, False, "") + cfg_list.append(inc_changed) + + # def_changed = def_cfg.clone() + # def_changed.define_symbols = ["symbol"] + # assert configuration_signature(def_changed) != def_sig) + def_changed = xml_generator_configuration_t( + "xml_generator_path", '.', ['/var/tmp'], ['new-sym'], ['unsym'], + None, False, "") + cfg_list.append(def_changed) + + # undef_changed = def_cfg.clone() + # undef_changed.undefine_symbols = ["symbol"] + # assert configuration_signature(undef_changed) != def_sig) + undef_changed = xml_generator_configuration_t( + "xml_generator_path", '.', ['/var/tmp'], ['sym'], ['new-unsym'], + None, False, "") + cfg_list.append(undef_changed) + + cflags_changed = def_cfg.clone() + cflags_changed.cflags = "new flags" + cfg_list.append(cflags_changed) + + return cfg_list diff --git a/tests/test_declarations_comparison.py b/tests/test_declarations_comparison.py new file mode 100644 index 00000000..6510e682 --- /dev/null +++ b/tests/test_declarations_comparison.py @@ -0,0 +1,73 @@ +# 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 copy + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "declarations_comparison.hpp", +] + + +def test_comparison_declaration_by_declaration(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + parsed = parser.parse(TEST_FILES, config) + copied = copy.deepcopy(parsed) + parsed = declarations.make_flatten(parsed) + copied = declarations.make_flatten(copied) + parsed.sort() + copied.sort() + failuers = [] + for parsed_decl, copied_decl, index in \ + zip(parsed, copied, list(range(len(copied)))): + + if parsed_decl != copied_decl: + failuers.append( + ("__lt__ and/or __qe__ does not working " + + "properly in case of %s, %s, index %d") % + (parsed_decl.__class__.__name__, + copied_decl.__class__.__name__, index)) + assert failuers == [] + + +def test_comparison_from_reverse(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + parsed = parser.parse(TEST_FILES, config) + copied = copy.deepcopy(parsed) + parsed.sort() + copied.reverse() + copied.sort() + x = parsed[4:6] + x.sort() + y = copied[4:6] + y.sort() + assert parsed == copied + + +def test___lt__transitivnost(): + ns_std = declarations.namespace_t(name='std') + ns_global = declarations.namespace_t(name='::') + ns_internal = declarations.namespace_t(name='ns') + ns_internal.parent = ns_global + ns_global.declarations.append(ns_internal) + left2right = [ns_std, ns_global] + right2left = [ns_global, ns_std] + left2right.sort() + right2left.sort() + assert left2right == right2left + + +def test_same_declarations_different_intances(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + parsed = parser.parse(TEST_FILES, config) + copied = copy.deepcopy(parsed) + assert parsed == copied diff --git a/tests/test_dependencies.py b/tests/test_dependencies.py new file mode 100644 index 00000000..b217c90c --- /dev/null +++ b/tests/test_dependencies.py @@ -0,0 +1,170 @@ +# 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 pytest +import warnings + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "include_all.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def test_variable(global_ns): + ns_vars = global_ns.namespace('::declarations::variables') + static_var = ns_vars.variable('static_var') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = static_var.i_depend_on_them() + warnings.simplefilter("error", Warning) + assert len(dependencies_old) == 1 + assert dependencies_old[0].declaration is static_var + assert dependencies_old[0].depend_on_it.decl_string == 'int' + + dependencies_new = declarations.get_dependencies_from_decl(static_var) + assert len(dependencies_new) == 1 + assert dependencies_new[0].declaration is static_var + assert dependencies_new[0].depend_on_it.decl_string == 'int' + + m_mutable = ns_vars.variable('m_mutable') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = m_mutable.i_depend_on_them() + warnings.simplefilter("error", Warning) + assert len(dependencies_old) == 1 + assert dependencies_old[0].declaration is m_mutable + assert dependencies_old[0].depend_on_it.decl_string == 'int' + + dependencies_new = declarations.get_dependencies_from_decl(m_mutable) + assert len(dependencies_new) == 1 + assert dependencies_new[0].declaration is m_mutable + assert dependencies_new[0].depend_on_it.decl_string == 'int' + + +def test_class(global_ns): + ns_vars = global_ns.namespace('::declarations::variables') + + cls = ns_vars.class_('struct_variables_t') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = cls.i_depend_on_them() + warnings.simplefilter("error", Warning) + dependencies_old = [ + d for d in dependencies_old if not d.declaration.is_artificial] + assert len(dependencies_old) == 1 + + dependencies_new = declarations.get_dependencies_from_decl(cls) + dependencies_new = [ + d for d in dependencies_new if not d.declaration.is_artificial] + assert len(dependencies_new) == 1 + + m_mutable = ns_vars.variable('m_mutable') + + # Legacy way of fetching dependencies. Is still valid but deprecated + dependencies_old = [ + dependency for dependency in dependencies_old if + dependency.declaration is m_mutable] + assert len(dependencies_old) == 1 + assert dependencies_old[0].depend_on_it.decl_string == 'int' + assert dependencies_old[0].access_type == 'public' + + dependencies_new = [ + dependency for dependency in dependencies_new if + dependency.declaration is m_mutable] + assert len(dependencies_new) == 1 + assert dependencies_new[0].depend_on_it.decl_string == 'int' + assert dependencies_new[0].access_type == 'public' + + ns_dh = global_ns.namespace('::core::diamand_hierarchy') + fd_cls = ns_dh.class_('final_derived_t') + derived1_cls = ns_dh.class_('derived1_t') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = declarations.get_dependencies_from_decl(fd_cls) + warnings.simplefilter("error", Warning) + dependencies_old = [ + dependency for dependency in dependencies_old if + dependency.depend_on_it is derived1_cls] + assert len(dependencies_old) == 1 + assert dependencies_old[0].depend_on_it is derived1_cls + assert dependencies_old[0].access_type == 'public' + + dependencies_new = declarations.get_dependencies_from_decl(fd_cls) + dependencies_new = [ + dependency for dependency in dependencies_new if + dependency.depend_on_it is derived1_cls] + assert len(dependencies_new) == 1 + assert dependencies_new[0].depend_on_it is derived1_cls + assert dependencies_new[0].access_type == 'public' + + +def test_calldefs(global_ns): + ns = global_ns.namespace('::declarations::calldef') + return_default_args = ns.calldef('return_default_args') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = return_default_args.i_depend_on_them() + warnings.simplefilter("error", Warning) + assert len(dependencies_old) == 3 + used_types = [ + dependency.depend_on_it.decl_string + for dependency in dependencies_old] + assert used_types == ['int', 'int', 'bool'] + + dependencies_new = declarations.get_dependencies_from_decl( + return_default_args) + assert len(dependencies_new) == 3 + used_types = [ + dependency.depend_on_it.decl_string + for dependency in dependencies_new] + assert used_types == ['int', 'int', 'bool'] + + some_exception = ns.class_('some_exception_t') + other_exception = ns.class_('other_exception_t') + calldef_with_throw = ns.calldef('calldef_with_throw') + + # Legacy way of fetching dependencies. Is still valid but deprecated + warnings.simplefilter("ignore", Warning) + dependencies_old = calldef_with_throw.i_depend_on_them() + warnings.simplefilter("error", Warning) + assert len(dependencies_old) == 3 + dependencies_old = [ + dependency for dependency in dependencies_old if + dependency.depend_on_it in (some_exception, other_exception)] + assert len(dependencies_old) == 2 + + dependencies_new = declarations.get_dependencies_from_decl( + calldef_with_throw) + assert len(dependencies_new) == 3 + dependencies_new = [ + dependency for dependency in dependencies_new if + dependency.depend_on_it in (some_exception, other_exception)] + assert len(dependencies_new) == 2 + + +def test_coverage(global_ns): + declarations.get_dependencies_from_decl(global_ns) diff --git a/tests/test_deprecation.py b/tests/test_deprecation.py new file mode 100644 index 00000000..deed1741 --- /dev/null +++ b/tests/test_deprecation.py @@ -0,0 +1,70 @@ +# Copyright 2021 Insight Software Consortium. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "test_deprecation.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + INIT_OPTIMIZER = True + 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) + if INIT_OPTIMIZER: + global_ns.init_optimizer() + return global_ns + + +def _check_text_content(desired_text, deprecation_string): + assert desired_text == deprecation_string + + +def test_comment_deprecation(global_ns): + """ + Check the comment parsing + """ + + tnamespace = global_ns.namespace("deprecation") + + tenumeration = tnamespace.enumeration("com_enum") + assert "deprecation" in dir(tenumeration) + _check_text_content( + 'Enumeration is Deprecated', + tenumeration.deprecation) + + tclass = tnamespace.class_("test") + assert "deprecation" in dir(tclass) + _check_text_content( + "Test class Deprecated", + tclass.deprecation) + + tmethod = tclass.member_functions()[0] + tmethod_dep = tclass.member_functions()[1] + + assert "deprecation", dir(tmethod) + assert tmethod.deprecation is None + _check_text_content( + "Function is deprecated", + tmethod_dep.deprecation) + + tconstructor = tclass.constructors()[0] + tconstructor_dep = tclass.constructors()[1] + + assert tconstructor.deprecation is None + assert "deprecation" in dir(tconstructor_dep) + _check_text_content( + "One arg constructor is Deprecated", + tconstructor_dep.deprecation) diff --git a/tests/test_directory_cache.py b/tests/test_directory_cache.py new file mode 100644 index 00000000..930d7c5b --- /dev/null +++ b/tests/test_directory_cache.py @@ -0,0 +1,81 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import shutil + +import pytest + +from . import autoconfig + +from pygccxml import parser + +TEST_FILES = [ + "typedefs1.hpp" +] + +CACHE_DIR = os.path.join(autoconfig.data_directory, "directory_cache_test") + + +def set_up(): + if os.path.isdir(CACHE_DIR): + shutil.rmtree(CACHE_DIR) + if os.path.isfile(CACHE_DIR): + os.remove(CACHE_DIR) + + +def test_directory_cache_without_compression(): + """ + Test the directory cache without compression + + """ + config = autoconfig.cxx_parsers_cfg.config.clone() + set_up() + # Test with compression OFF + cache = parser.directory_cache_t(directory=CACHE_DIR) + # Generate a cache on first read + parser.parse(TEST_FILES, config, cache=cache) + # Read from the cache the second time + parser.parse(TEST_FILES, config, cache=cache) + + +def test_directory_cache_with_compression(): + """ + Test the directory cache wit compression + + """ + config = autoconfig.cxx_parsers_cfg.config.clone() + set_up() + # Test with compression ON + cache = parser.directory_cache_t( + directory=CACHE_DIR, compression=True) + # Generate a cache on first read + parser.parse(TEST_FILES, config, cache=cache) + # Read from the cache the second time + parser.parse(TEST_FILES, config, cache=cache) + + +def test_directory_cache_twice(): + """ + Setup two caches in a row. + + The second run will reload the same cache directory. + """ + config = autoconfig.cxx_parsers_cfg.config.clone() + set_up() + cache = parser.directory_cache_t(directory=CACHE_DIR) + parser.parse(TEST_FILES, config, cache=cache) + cache = parser.directory_cache_t(directory=CACHE_DIR) + parser.parse(TEST_FILES, config, cache=cache) + + +def test_directory_existing_dir(): + """ + Setup a cache when there is already a file at the cache's location. + """ + set_up() + open(CACHE_DIR, "a").close() + with pytest.raises(ValueError): + parser.directory_cache_t(directory=CACHE_DIR) diff --git a/tests/test_elaborated_types.py b/tests/test_elaborated_types.py new file mode 100644 index 00000000..36f82691 --- /dev/null +++ b/tests/test_elaborated_types.py @@ -0,0 +1,60 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = ['test_elaborated_types.hpp'] + + +@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 + + +def test_is_elaborated_type(global_ns): + """ + Test for the is_elaborated function + """ + + 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(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_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 _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 new file mode 100644 index 00000000..12ff9136 --- /dev/null +++ b/tests/test_example.py @@ -0,0 +1,33 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import fnmatch +import subprocess + + +def test_example(): + """Runs the example in the docs directory""" + + env = os.environ.copy() + + # 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, _, 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: + 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 new file mode 100644 index 00000000..4fcb4723 --- /dev/null +++ b/tests/test_file_cache.py @@ -0,0 +1,74 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser + +TEST_FILE = os.path.join(autoconfig.data_directory, 'core_cache.hpp') +cache_file = os.path.join( + autoconfig.data_directory, + 'pygccxml.cache') + + +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 new file mode 100644 index 00000000..699c0e74 --- /dev/null +++ b/tests/test_filters_tester.py @@ -0,0 +1,83 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ['declarations_calldef.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_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_container_traits.py b/tests/test_find_container_traits.py new file mode 100644 index 00000000..dbf6fd67 --- /dev/null +++ b/tests/test_find_container_traits.py @@ -0,0 +1,168 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["remove_template_defaults.hpp", "indexing_suites2.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 __cmp_traits(global_ns, typedef, expected, partial_name, key_type=None): + if isinstance(typedef, str): + typedef = global_ns.typedef(typedef) + traits = declarations.find_container_traits(typedef) + assert traits is not None + assert traits == expected + cls = declarations.remove_declarated(typedef) + assert declarations.find_container_traits(cls) == expected + assert cls.partial_name == partial_name + cls = traits.class_declaration(cls) + print("xxxx", traits, typedef) + assert traits.element_type(typedef) is not None + assert cls.cache.container_element_type is not None + + if key_type: + assert traits.is_mapping(typedef) is not None + real_key_type = traits.key_type(typedef) + assert real_key_type.decl_string == key_type + assert cls.cache.container_key_type is not None + else: + assert traits.is_sequence(typedef) + + +def test_find_traits(global_ns): + __cmp_traits( + global_ns, + "v_int", + declarations.vector_traits, + "vector< int >" + ) + __cmp_traits( + global_ns, + "l_int", + declarations.list_traits, + "list< int >" + ) + __cmp_traits( + global_ns, "d_v_int", + declarations.deque_traits, + "deque< std::vector< int > >" + ) + __cmp_traits( + global_ns, "q_int", + declarations.queue_traits, + "queue< int >" + ) + __cmp_traits( + global_ns, "pq_int", + declarations.priority_queue_traits, + "priority_queue< int >" + ) + __cmp_traits( + global_ns, "s_v_int", + declarations.set_traits, + "set< std::vector< int > >" + ) + __cmp_traits( + global_ns, + "ms_v_int", + declarations.multiset_traits, + "multiset< std::vector< int > >", + ) + __cmp_traits( + global_ns, "m_i2d", + declarations.map_traits, + "map< int, double >", + "int" + ) + __cmp_traits( + global_ns, + "mm_i2d", + declarations.multimap_traits, + "multimap< int, double >", + "int", + ) + __cmp_traits( + global_ns, + "hs_v_int", + declarations.unordered_set_traits, + "unordered_set< std::vector< int > >", + ) + __cmp_traits( + global_ns, + "mhs_v_int", + declarations.unordered_multiset_traits, + "unordered_multiset< std::vector< int > >", + ) + __cmp_traits( + global_ns, + "hm_i2d", + declarations.unordered_map_traits, + "unordered_map< int, double >", + "int", + ) + __cmp_traits( + global_ns, + "hmm_i2d", + declarations.unordered_multimap_traits, + "unordered_multimap< int, double >", + "int", + ) + + +def test_multimap(global_ns): + m = global_ns.class_(lambda decl: decl.name.startswith("multimap")) + declarations.find_container_traits(m) + assert m.partial_name == "multimap< int, int >" + + +def test_recursive_partial_name(global_ns): + f1 = global_ns.free_function("f1") + t1 = declarations.class_traits.get_declaration(f1.arguments[0].decl_type) + assert "type< std::set< std::vector< int > > >" == t1.partial_name + + +def test_remove_defaults_partial_name_namespace(global_ns): + f2 = global_ns.free_function("f2") + type_info = f2.return_type + traits = declarations.find_container_traits(type_info) + cls = traits.class_declaration(type_info) + decl_string = cls.partial_decl_string + key_type_string = traits.key_type(type_info).partial_decl_string + assert decl_string.startswith("::std::") + assert key_type_string.startswith("::std::") + + +def test_from_ogre(): + x = ( + "map, " + + "std::allocator > >" + ) + ct = declarations.find_container_traits(x) + ct.remove_defaults(x) + + +def test_infinite_loop(global_ns): + rt = global_ns.free_function("test_infinite_loop").return_type + map_traits = declarations.find_container_traits(rt) + assert map_traits == declarations.map_traits + elem = map_traits.element_type(rt) + assert elem.decl_string == "int" diff --git a/tests/test_find_noncopyable_vars.py b/tests/test_find_noncopyable_vars.py new file mode 100644 index 00000000..8b31d9d2 --- /dev/null +++ b/tests/test_find_noncopyable_vars.py @@ -0,0 +1,40 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = ['find_noncopyable_vars.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_find_noncopyable_vars(global_ns): + """ + Test the find_noncopyable_vars function + + """ + + # 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 new file mode 100644 index 00000000..c3e2d193 --- /dev/null +++ b/tests/test_free_operators.py @@ -0,0 +1,35 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = ['free_operators.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_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 new file mode 100644 index 00000000..95e80186 --- /dev/null +++ b/tests/test_function_pointer.py @@ -0,0 +1,74 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +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 new file mode 100644 index 00000000..96280bfd --- /dev/null +++ b/tests/test_function_traits.py @@ -0,0 +1,34 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ['covariant_returns.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_is_same_function(global_ns): + d = global_ns.class_('better_algorithm_t') + b = global_ns.class_('algorithm_t') + + df = d.member_function('f') + bf = b.member_function('f') + + assert id(df) != id(bf) + assert declarations.is_same_function(df, bf) is True diff --git a/tests/test_gccxml10184.py b/tests/test_gccxml10184.py new file mode 100644 index 00000000..db4ccf12 --- /dev/null +++ b/tests/test_gccxml10184.py @@ -0,0 +1,27 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +code = \ + """ +class A { +public: + virtual ~A() = 0; + unsigned int a : 1; + unsigned int unused : 31; +}; +""" + + +def test_gccxml_10184(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse_string(code, config) + global_ns = declarations.get_global_namespace(decls) + assert global_ns.variable('a').bits == 1 + assert global_ns.variable('unused').bits == 31 diff --git a/tests/test_gccxml10185.py b/tests/test_gccxml10185.py new file mode 100644 index 00000000..51e3f558 --- /dev/null +++ b/tests/test_gccxml10185.py @@ -0,0 +1,40 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +code = \ + """ +template struct A {}; +template struct A +{ static int size(const char[N]) { return N - 1; } }; +""" + + +def test_partial_template(): + """ + The purpose of this test was to check if changes to GCCXML + would lead to changes in the outputted xml file (Meaning + the bug was fixed). + + GCCXML wrongly outputted partial template specialization. + CastXML does not have this bug. In this case we check if + the template specialization can not be found; which is the + expected/wanted behaviour. + + https://github.com/CastXML/CastXML/issues/20 + + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse_string(code, config) + global_ns = declarations.get_global_namespace(decls) + with pytest.raises(declarations.declaration_not_found_t): + global_ns.class_('A') diff --git a/tests/test_has_binary_operator_traits.py b/tests/test_has_binary_operator_traits.py new file mode 100644 index 00000000..e7eb0f00 --- /dev/null +++ b/tests/test_has_binary_operator_traits.py @@ -0,0 +1,47 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["has_public_binary_operator_traits.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_yes_equal(global_ns): + yes_ns = global_ns.namespace('yesequal') + for typedef in yes_ns.typedefs(): + assert declarations.has_public_equal(typedef) is True + + +def test_no_equal(global_ns): + no_ns = global_ns.namespace('noequal') + for typedef in no_ns.typedefs(): + assert declarations.has_public_equal(typedef) is False + + +def test_yes_less(global_ns): + yes_ns = global_ns.namespace('yesless') + for typedef in yes_ns.typedefs(): + assert declarations.has_public_less(typedef) + + +def test_no_less(global_ns): + no_ns = global_ns.namespace('noless') + for typedef in no_ns.typedefs(): + assert declarations.has_public_less(typedef) is False diff --git a/tests/test_hash.py b/tests/test_hash.py new file mode 100644 index 00000000..a994cdfd --- /dev/null +++ b/tests/test_hash.py @@ -0,0 +1,86 @@ +# 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 inspect + +from pygccxml import declarations + + +def test_types_hashes(): + """ + Test if all the type_t instances implement a hash method. + + The hash is part of the public API, as there are multiple tools + that rely on it to compare type_t instances. + + The best way to test this is to instanciate dummy type_t objects + for each class that subclasses type_t, and check that the hash of + these objects is not None. + + """ + + members = inspect.getmembers(declarations, inspect.isclass) + for member in members: + member_type = member[1] + is_type_t_subclass = issubclass(member_type, declarations.type_t) + is_not_type_t = member_type != declarations.type_t + if is_type_t_subclass and is_not_type_t: + type_mockup = _create_type_t_mockup(member_type) + assert hash(type_mockup) is not None + + +def test_declarations_hashes(): + """ + Test if all the declaration_t instances implement a hash method. + + The hash is part of the public API, as there are multiple tools + that rely on it to compare declaration_t instances. + + The best way to test this is to instanciate dummy declaration_t objects + for each class that subclasses declaration_t, and check that the hash + of these objects is not None. + + """ + members = inspect.getmembers(declarations, inspect.isclass) + for member in members: + member_type = member[1] + if issubclass(member_type, declarations.declaration_t): + assert hash(member_type()) is not None + + +def test_type_qualifiers_t_hash(): + """ + Test if the type_qualifiers_t instance implements a hash method. + + The hash is part of the public API, as there are multiple tools + that rely on it to compare type_qualifiers_t instances. + + """ + assert hash(declarations.type_qualifiers_t()) is not None + + +def _create_type_t_mockup(member_type): + nbr_parameters = len(inspect.signature(member_type).parameters) + if nbr_parameters == 0: + m = member_type() + else: + if member_type == declarations.array_t: + m = member_type(_base_mockup(), size=1) + else: + m = member_type(_base_mockup()) + m.cache.decl_string = "" + return m + + +class _base_mockup(declarations.type_t): + + def __init__(self): + declarations.type_t.__init__(self) + self.cache.decl_string = "" + self._decl_string = "" + self.variable_type = declarations.type_t() + + def build_decl_string(self, with_defaults=False): + return self._decl_string diff --git a/tests/test_hierarchy_traveling.py b/tests/test_hierarchy_traveling.py new file mode 100644 index 00000000..d299d817 --- /dev/null +++ b/tests/test_hierarchy_traveling.py @@ -0,0 +1,78 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +__code = os.linesep.join([ + 'struct a{};', + 'struct b{};', + 'struct c{};', + 'struct d : public a{};', + 'struct e : public a, public b{};', + 'struct f{};', + 'struct g : public d, public f{};', + 'struct h : public f{};', + 'struct i : public h, public g{};']) + + +__recursive_bases = { + 'a': set(), + 'b': set(), + 'c': set(), + 'd': {'a'}, + 'e': {'a', 'b'}, + 'f': set(), + 'g': {'d', 'f', 'a'}, + 'h': {'f'}, + 'i': {'h', 'g', 'd', 'f', 'a'}} + +__recursive_derived = { + 'a': {'d', 'e', 'g', 'i'}, + 'b': {'e'}, + 'c': set(), + 'd': {'g', 'i'}, + 'e': set(), + 'f': {'g', 'h', 'i'}, + 'g': {'i'}, + 'h': {'i'}, + 'i': set()} + + +def test_recursive_bases(): + config = autoconfig.cxx_parsers_cfg.config.clone() + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) + classes = [ + inst for inst in decls if isinstance(inst, declarations.class_t)] + for class_ in classes: + assert class_.name in __recursive_bases + all_bases = class_.recursive_bases + control_bases = __recursive_bases[class_.name] + assert len(control_bases) == len(all_bases) + all_bases_names = [hi.related_class.name for hi in all_bases] + assert set(all_bases_names) == control_bases + + +def test_recursive_derived(): + config = autoconfig.cxx_parsers_cfg.config.clone() + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) + classes = [ + inst for inst in decls if isinstance( + inst, + declarations.class_t)] + for class_ in classes: + assert class_.name in __recursive_derived + all_derived = class_.recursive_derived + control_derived = __recursive_derived[class_.name] + assert len(control_derived) == len(all_derived) + all_derived_names = [hi.related_class.name for hi in all_derived] + assert set(all_derived_names) == control_derived diff --git a/tests/test_inline_specifier.py b/tests/test_inline_specifier.py new file mode 100644 index 00000000..6daf02bd --- /dev/null +++ b/tests/test_inline_specifier.py @@ -0,0 +1,36 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["inline_specifier.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_inline_specifier(global_ns): + inlined_funcs = global_ns.calldefs('inlined') + assert len(inlined_funcs) != 0 + for f in inlined_funcs: + assert f.has_inline is True + + not_inlined_funcs = global_ns.calldefs('not_inlined') + assert len(not_inlined_funcs) != 0 + for f in not_inlined_funcs: + assert f.has_inline is False diff --git a/tests/test_map_gcc5.py b/tests/test_map_gcc5.py new file mode 100644 index 00000000..cbd790ce --- /dev/null +++ b/tests/test_map_gcc5.py @@ -0,0 +1,40 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["test_map_gcc5.hpp"] + + +def test_map_gcc5(): + """ + The code in test_map_gcc5.hpp was breaking pygccxml. + + Test that case (gcc5 + castxml + c++11). + + See issue #45 and #55 + + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + config.cflags = "-std=c++11" + + decls = parser.parse(TEST_FILES, config) + global_ns = declarations.get_global_namespace(decls) + + # This calldef is defined with gcc > 4.9 (maybe earlier, not tested) + # and -std=c++11. Calling create_decl_string is failing with gcc. + # With clang the calldef does not exist so the matcher + # will just return an empty list, letting the test pass. + # See the test_argument_without_name.py for an equivalent test, + # which is not depending on the presence of the _M_clone_node + # method in the stl_tree.h file. + criteria = declarations.calldef_matcher(name="_M_clone_node") + free_funcs = declarations.matcher.find(criteria, global_ns) + for free_funcs in free_funcs: + free_funcs.create_decl_string(with_defaults=False) diff --git a/tests/test_namespace_matcher.py b/tests/test_namespace_matcher.py new file mode 100644 index 00000000..01dcf51e --- /dev/null +++ b/tests/test_namespace_matcher.py @@ -0,0 +1,34 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES1 = ["bit_fields.hpp"] +TEST_FILES2 = ["unnamed_ns_bug.hpp"] + + +def test_namespace_matcher_get_single(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES1, config) + criteria = declarations.namespace_matcher_t(name='bit_fields') + declarations.matcher.get_single(criteria, decls) + assert str(criteria) == '(decl type==namespace_t) and (name==bit_fields)' + + +def test_namespace_matcher_allow_empty(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES1, config) + global_ns = declarations.get_global_namespace(decls) + assert 0 == len(global_ns.namespaces('does not exist', allow_empty=True)) + + +def test_namespace_matcher_upper(): + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES2, config) + declarations.matcher.get_single( + declarations.namespace_matcher_t(name='::'), decls) diff --git a/tests/test_non_copyable_classes.py b/tests/test_non_copyable_classes.py new file mode 100644 index 00000000..b3d88786 --- /dev/null +++ b/tests/test_non_copyable_classes.py @@ -0,0 +1,57 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["non_copyable_classes.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(global_ns): + """ + Search for classes which can not be copied. + + See bug #13 + + 1) non copyable class + 2) non copyable const variable (fundamental type) + 3) non copyable const variable (class type) + 4) non copyable const variable (array type) + 5) non copyable const variable (class type) + + """ + + main_foo_1 = global_ns.class_('MainFoo1') + assert declarations.is_noncopyable(main_foo_1) is True + + main_foo_2 = global_ns.class_('MainFoo2') + assert declarations.is_noncopyable(main_foo_2) is True + + main_foo_3 = global_ns.class_('MainFoo3') + assert declarations.is_noncopyable(main_foo_3) is True + + main_foo_4 = global_ns.class_('MainFoo4') + assert declarations.is_noncopyable(main_foo_4) is True + + main_foo_5 = global_ns.class_('MainFoo5') + assert declarations.is_noncopyable(main_foo_5) is True + + main_foo_6 = global_ns.class_('MainFoo6') + assert declarations.is_noncopyable(main_foo_6) is False diff --git a/tests/test_non_copyable_recursive.py b/tests/test_non_copyable_recursive.py new file mode 100644 index 00000000..fe365447 --- /dev/null +++ b/tests/test_non_copyable_recursive.py @@ -0,0 +1,62 @@ +# Copyright 2014-2016 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = ["test_non_copyable_recursive.hpp"] + + +def test_infinite_recursion_base_classes(): + """ + Test find_noncopyable_vars + + See #71 + + find_noncopyable_vars was throwing: + RuntimeError: maximum recursion depth exceeded while + calling a Python object + """ + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config) + global_ns = declarations.get_global_namespace(decls) + + # Description of the problem (before the fix): + # find_noncopyable_vars (on Child class) looks up the variables, + # and finds aBasePtr2 (a pointer to the Base2 class). + # Then it looks recursively at the base classes of Base2, and finds + # Base1. Then, it looks up the variables from Base, to check if Base1 + # is non copyable. It finds another aBasePtr2 variable, which leads to + # a new check of Base2; this recurses infinitely. + test_ns = global_ns.namespace('Test1') + cls = test_ns.class_('Child') + declarations.type_traits_classes.find_noncopyable_vars(cls) + assert declarations.type_traits_classes.is_noncopyable(cls) is True + + +def test_infinite_recursion_sstream(): + """ + Test find_noncopyable_vars + + See #71 + + find_noncopyable_vars was throwing: + RuntimeError: maximum recursion depth exceeded while + calling a Python object + """ + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config) + global_ns = declarations.get_global_namespace(decls) + + # Real life example of the bug. This leads to a similar error, + # but the situation is more complex as there are multiple + # classes that are related the one to the others + # (basic_istream, basic_ios, ios_base, ...) + test_ns = global_ns.namespace('Test2') + cls = test_ns.class_('FileStreamDataStream') + declarations.type_traits_classes.find_noncopyable_vars(cls) + assert declarations.type_traits_classes.is_noncopyable(cls) is False diff --git a/tests/test_null_comparison.py b/tests/test_null_comparison.py new file mode 100644 index 00000000..af489043 --- /dev/null +++ b/tests/test_null_comparison.py @@ -0,0 +1,31 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + "null_comparison.hpp", +] + + +def test_argument_null_comparison(): + """ + Test for None comparisons with default arguments + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES, config) + global_ns = declarations.get_global_namespace(decls) + + ns = global_ns.namespace("ns") + + func = ns.free_function(name="TestFunction1") + assert (func.arguments[0] > func.arguments[1]) is False + + func = ns.free_function(name="TestFunction2") + assert (func.arguments[0] > func.arguments[1]) is False diff --git a/tests/test_order.py b/tests/test_order.py new file mode 100644 index 00000000..bcb4832d --- /dev/null +++ b/tests/test_order.py @@ -0,0 +1,85 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +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" diff --git a/tests/test_overrides.py b/tests/test_overrides.py new file mode 100644 index 00000000..f641571c --- /dev/null +++ b/tests/test_overrides.py @@ -0,0 +1,37 @@ +# Copyright 2014-2020 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +@pytest.fixture +def global_ns_fixture(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.castxml_epic_version = 1 + config.cflags = "-std=c++11" + decls = parser.parse(["test_overrides.hpp"], config) + global_ns = declarations.get_global_namespace(decls) + return global_ns + + +def test_overrides(global_ns_fixture): + """ + Check that the override information is populated for the + simple::goodbye function. It should contain the decl for the + base::goodbye function. Base::goodbye has no override so it + will be none + """ + base = global_ns_fixture.class_("base").member_function("goodbye") + override_decl = global_ns_fixture.class_("simple")\ + .member_function("goodbye") + + assert base.overrides is None + assert override_decl.overrides is not None + assert override_decl.overrides == base diff --git a/tests/test_parser_raise.py b/tests/test_parser_raise.py new file mode 100644 index 00000000..8181610a --- /dev/null +++ b/tests/test_parser_raise.py @@ -0,0 +1,18 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import pytest + +from . import autoconfig + +from pygccxml import parser + + +def test_raise(): + config = autoconfig.cxx_parsers_cfg.config.clone() + content = "abra cadabra " + os.linesep + with pytest.raises(RuntimeError) as _: + parser.parse_string(content, config) diff --git a/tests/test_patcher.py b/tests/test_patcher.py new file mode 100644 index 00000000..336e57d2 --- /dev/null +++ b/tests/test_patcher.py @@ -0,0 +1,161 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import declarations +from pygccxml import parser +from pygccxml import utils + + +TEST_FILES = [ + "patcher.hpp", +] + +config = autoconfig.cxx_parsers_cfg.config.clone() +project_reader = parser.project_reader_t(config=config, cache=None) +decls = project_reader.read_files( + TEST_FILES, + parser.COMPILATION_MODE.ALL_AT_ONCE +) +config.xml_generator_from_xml_file = project_reader.xml_generator_from_xml_file +config.__cxx_std = utils.cxx_standard(config.cflags) + + +@pytest.fixture +def global_ns(): + global_ns = declarations.get_global_namespace(decls) + return global_ns + + +def test_enum_patcher(global_ns): + fix_enum = global_ns.free_function("fix_enum") + default_val = fix_enum.arguments[0].default_value + if config.__cxx_std.is_cxx11_or_greater: + val = "::ns1::ns2::fruit::apple" + else: + val = "::ns1::ns2::apple" + assert default_val == val + + fix_enum2 = global_ns.free_function("fix_enum2") + default_val = fix_enum2.arguments[0].default_value + assert default_val == val + + ns1 = global_ns.namespace("ns1") + ns2 = ns1.namespace("ns2") + fix_enum2 = ns2.free_function("fix_enum2") + default_val = fix_enum2.arguments[0].default_value + assert default_val == val + + fix_enum3 = global_ns.free_function("fix_enum3") + default_val = fix_enum3.arguments[0].default_value + val = val.replace("apple", "orange") + assert default_val == val + + if config.__cxx_std.is_cxx11_or_greater: + fix_enum4 = global_ns.free_function("fix_enum4") + default_val = fix_enum4.arguments[0].default_value + assert default_val == "::ns4::color::blue" + + fix_enum5 = global_ns.free_function("fix_enum5") + default_val = fix_enum5.arguments[0].default_value + assert default_val == "::ns4::color::blue" + + lpe = global_ns.free_function("log_priority_enabled") + default_val = lpe.arguments[0].default_value + if config.__cxx_std.is_cxx11_or_greater: + val = "(long int)" + \ + "(::ACE_Log_Priority_Index::LM_INVALID_BIT_INDEX)" + else: + val = "(long int)(::LM_INVALID_BIT_INDEX)" + assert default_val == val + + +def test_numeric_patcher(global_ns): + fix_numeric = global_ns.free_function("fix_numeric") + generator = config.xml_generator_from_xml_file + if generator.is_castxml1 or \ + float(generator.xml_output_version) >= 1.137: + val = "(unsigned long long)-1" + else: + val = "(ull)-1" + assert fix_numeric.arguments[0].default_value == val + + +def test_unqualified_integral_patcher(global_ns): + # For this check to be removed, patcher_tester_64bit.xml + # will need to be updated for CastXML + return + + ns1 = global_ns.namespace("ns1") + st1 = ns1.class_("st1") + fun1 = st1.member_function("fun1") + output_verion = xml_generator_from_xml_file.xml_output_version + if xml_generator_from_xml_file.is_castxml1 or \ + float(output_verion) >= 1.137: + val1 = "ns1::DEFAULT_1" + val2 = "ns1::st1::DEFAULT_2" + else: + val1 = "::ns1::DEFAULT_1" + val2 = "::ns1::st1::DEFAULT_2" + assertEqual( + fun1.arguments[0].default_value, val1) + assertEqual( + fun1.arguments[1].default_value, val2) + + fun2 = global_ns.free_function("fun2") + assertEqual( + fun2.arguments[0].default_value, + "::DEFAULT_1") + output_verion = xml_generator_from_xml_file.xml_output_version + if xml_generator_from_xml_file.is_castxml1 or \ + float(output_verion) >= 1.137: + val1 = "ns1::DEFAULT_1" + val2 = "ns1::st1::DEFAULT_2" + else: + # Before XML output version 1.137, the following two + # were unpatched and were identical to the text in + # matcher.hpp + val1 = "ns1::DEFAULT_1" + val2 = "::ns1::st1::DEFAULT_2" + assertEqual( + fun2.arguments[1].default_value, val1) + assertEqual( + fun2.arguments[2].default_value, val2) + + +def test_unnamed_enum_patcher(global_ns): + fix_unnamed = global_ns.free_function("fix_unnamed") + assert fix_unnamed.arguments[0].default_value == "int(::fx::unnamed)" + + +def test_function_call_patcher(global_ns): + fix_function_call = global_ns.free_function("fix_function_call") + default_val = fix_function_call.arguments[0].default_value + output_verion = config.xml_generator_from_xml_file.xml_output_version + if config.xml_generator_from_xml_file.is_castxml1 or \ + float(output_verion) >= 1.137: + val = "function_call::calc(1, 2, 3)" + else: + val = "calc(1, 2, 3)" + assert default_val == val + + +def test_fundamental_patcher(global_ns): + fcall = global_ns.free_function("fix_fundamental") + if config.__cxx_std.is_cxx11_or_greater: + val = "(unsigned int)(::fundamental::spam::eggs)" + else: + val = "(unsigned int)(::fundamental::eggs)" + assert fcall.arguments[0].default_value == val + + +def test_constructor_patcher(global_ns): + typedef__func = global_ns.free_function("typedef__func") + default_val = typedef__func.arguments[0].default_value + val = "typedef_::alias()" + assert default_val == val diff --git a/tests/test_pattern_parser.py b/tests/test_pattern_parser.py new file mode 100644 index 00000000..2f3d8532 --- /dev/null +++ b/tests/test_pattern_parser.py @@ -0,0 +1,169 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + 'test_pattern_parser.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_template_split_std_vector(global_ns): + """ + Demonstrate error in pattern parser, see #60 + + """ + + config = autoconfig.cxx_parsers_cfg.config.clone() + config.cflags = "-std=c++11" + decls = parser.parse(TEST_FILES, config) + + for decl in declarations.make_flatten(decls): + if "myClass" in decl.name: + _ = decl.partial_name + + +def test_matcher(global_ns): + """ + Run the matcher on all the templated classes. + + This exercises the whole pipeline even more. + + """ + + criteria = declarations.declaration_matcher(name="myClass") + _ = declarations.matcher.find(criteria, global_ns) + + +def test_split(): + """ + Test a bunch of tricky name/args splits. More combinations could be + tested but this is already covering most of the cases. + + In test_template_split_std_vector we test for a specific case that + was failing (in a real world scenario). + Here we test more possible combinations to make sure the splitting + method is robust enough. + + """ + + p1 = "std::vector >" + p2 = "std::vector >" + args_list = [ + "const std::basic_string &", "const int &", "const double &"] + + for arg in args_list: + + li = [p1] + name, args = declarations.templates.split( + "myClass0a<" + ", ".join(li) + ">") + assert name == "myClass0a" + assert args == li + + li = [p1, p2] + name, args = declarations.templates.split( + "myClass0b<" + ", ".join(li) + ">") + assert name == "myClass0b" + assert args == li + + li = [p1, p2, p2] + name, args = declarations.templates.split( + "myClass0c<" + ", ".join(li) + ">") + assert name == "myClass0c" + assert args == li + + li = [p1 + " (" + arg + ")"] + name, args = declarations.templates.split( + "myClass1<" + ", ".join(li) + ">") + assert name == "myClass1" + assert args == li + + li = [p1 + " (" + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass2<" + ", ".join(li) + ">") + assert name == "myClass2" + assert args == li + + li = [p2 + " (" + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass3<" + ", ".join(li) + ">") + assert name == "myClass3" + assert args == li + + li = [p1 + " (" + arg + ", " + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass4<" + ", ".join(li) + ">") + assert name == "myClass4" + assert args == li + + li = [ + p1 + " (" + arg + ", " + arg + ", " + arg + ")", + p1] + name, args = declarations.templates.split( + "myClass5<" + ", ".join(li) + ">") + assert name == "myClass5" + assert args == li + + li = [ + p1, + p1 + " (" + arg + ", " + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass6<" + ", ".join(li) + ">") + assert name == "myClass6" + assert args == li + + li = [ + p2 + " (" + arg + ")", + p1, + p1 + " (" + arg + ", " + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass7<" + ", ".join(li) + ">") + assert name == "myClass7" + assert args == li + + li = [ + p1, + p2 + " (" + arg + ")", + p1 + " (" + arg + ", " + arg + ", " + arg + ")"] + name, args = declarations.templates.split( + "myClass8<" + ", ".join(li) + ">") + assert name == "myClass8" + assert args == li + + li = [ + p2 + " (" + arg + ")", + p1 + " (" + arg + ", " + arg + ")", + p1] + name, args = declarations.templates.split( + "myClass9<" + ", ".join(li) + ">") + assert name == "myClass9" + assert args == li + + li = [ + p2 + " (" + arg + ")", + p1 + " (" + arg + ", " + arg + ", " + arg + ")", + p1, + p2] + name, args = declarations.templates.split( + "myClass10<" + ", ".join(li) + ">") + assert name == "myClass10" + assert args == li diff --git a/tests/test_plain_c.py b/tests/test_plain_c.py new file mode 100644 index 00000000..da66ac34 --- /dev/null +++ b/tests/test_plain_c.py @@ -0,0 +1,33 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + 'plain_c.c' +] + + +@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_plain_c(global_ns): + global_ns.free_function('hello_sum') + global_ns.free_function('hello_print') + f = global_ns.free_function('do_smth') + for arg in f.arguments: + assert arg.decl_type.decl_string is not None diff --git a/tests/test_project_reader_correctness.py b/tests/test_project_reader_correctness.py new file mode 100644 index 00000000..030d9835 --- /dev/null +++ b/tests/test_project_reader_correctness.py @@ -0,0 +1,84 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES1 = [ + 'core_types.hpp', + 'core_ns_join_1.hpp', + 'core_ns_join_2.hpp', + 'core_ns_join_3.hpp', + 'core_membership.hpp', + 'core_class_hierarchy.hpp', + 'core_diamand_hierarchy_base.hpp', + 'core_diamand_hierarchy_derived1.hpp', + 'core_diamand_hierarchy_derived2.hpp', + 'core_diamand_hierarchy_final_derived.hpp', + 'core_overloads_1.hpp', + 'core_overloads_2.hpp' +] + +TEST_FILES2 = [ + 'separate_compilation/data.h', + 'separate_compilation/base.h', + 'separate_compilation/derived.h' +] + + +def test_correctness(): + for src in TEST_FILES1: + __test_correctness_impl(src) + + +def __test_correctness_impl(file_name): + config = autoconfig.cxx_parsers_cfg.config.clone() + prj_reader = parser.project_reader_t(config) + prj_decls = prj_reader.read_files( + [file_name] * 2, + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + src_reader = parser.source_reader_t(config) + src_decls = src_reader.read_file(file_name) + if src_decls != prj_decls: + s = src_decls[0] + p = prj_decls[0] + bdir = autoconfig.build_directory + with open(os.path.join(bdir, file_name + '.sr.txt'), 'w+') as sr: + with open( + os.path.join(bdir, file_name + '.pr.txt'), 'w+') as pr: + + declarations.print_declarations( + s, writer=lambda x: sr.write(l + os.linesep)) + declarations.print_declarations( + p, writer=lambda x: pr.write(l + os.linesep)) + raise ( + f"There is a difference between declarations in file {file_name}." + ) + + +def test_separate_compilation(): + config = autoconfig.cxx_parsers_cfg.config.clone() + prj_reader = parser.project_reader_t(config) + prj_decls = prj_reader.read_files( + TEST_FILES2, + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + src_reader = parser.source_reader_t(config) + src_decls = src_reader.read_file('separate_compilation/all.h') + + declarations.dump_declarations( + src_decls, + os.path.join( + autoconfig.build_directory, 'separate_compilation.sr.txt')) + + declarations.dump_declarations( + prj_decls, + os.path.join( + autoconfig.build_directory, 'separate_compilation.pr.txt')) + + assert src_decls == prj_decls diff --git a/tests/test_remove_template_defaults.py b/tests/test_remove_template_defaults.py new file mode 100644 index 00000000..b1706c4c --- /dev/null +++ b/tests/test_remove_template_defaults.py @@ -0,0 +1,178 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations +from pygccxml import utils + +TEST_FILES = [ + 'remove_template_defaults.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_vector(global_ns): + v_int = global_ns.typedef('v_int') + v_traits = declarations.vector_traits + assert 'vector< int >' == v_traits.remove_defaults(v_int) + v_string = global_ns.typedef('v_string') + assert 'vector< std::string >' == \ + v_traits.remove_defaults(v_string) + v_v_int = global_ns.typedef('v_v_int') + assert 'vector< std::vector< int > >' == \ + v_traits.remove_defaults(v_v_int) + + +def test_list(global_ns): + l_int = global_ns.typedef('l_int') + l_traits = declarations.list_traits + assert 'list< int >' == l_traits.remove_defaults(l_int) + l_wstring = global_ns.typedef('l_wstring') + assert 'list< std::wstring >' == l_traits.remove_defaults(l_wstring) + + +def test_deque(global_ns): + d_v_int = global_ns.typedef('d_v_int') + d_v_traits = declarations.deque_traits + assert 'deque< std::vector< int > >' == \ + d_v_traits.remove_defaults(d_v_int) + d_l_string = global_ns.typedef('d_l_string') + assert 'deque< std::list< std::string > >' == \ + d_v_traits.remove_defaults(d_l_string) + + +def test_queue(global_ns): + q_int = global_ns.typedef('q_int') + q_traits = declarations.queue_traits + assert 'queue< int >' == q_traits.remove_defaults(q_int) + q_string = global_ns.typedef('q_string') + assert 'queue< std::string >' == q_traits.remove_defaults(q_string) + + +def test_priority_queue(global_ns): + pq_int = global_ns.typedef('pq_int') + pq_traits = declarations.priority_queue_traits + assert 'priority_queue< int >' == pq_traits.remove_defaults(pq_int) + pq_string = global_ns.typedef('pq_string') + assert 'priority_queue< std::string >' == \ + pq_traits.remove_defaults(pq_string) + + +def test_set(global_ns): + s_v_int = global_ns.typedef('s_v_int') + assert 'set< std::vector< int > >' == \ + declarations.set_traits.remove_defaults(s_v_int) + s_string = global_ns.typedef('s_string') + assert 'set< std::string >' == \ + declarations.set_traits.remove_defaults(s_string) + + +def test_multiset(global_ns): + ms_v_int = global_ns.typedef('ms_v_int') + ms_v_traits = declarations.multiset_traits + assert 'multiset< std::vector< int > >' == \ + ms_v_traits.remove_defaults(ms_v_int) + ms_string = global_ns.typedef('ms_string') + assert 'multiset< std::string >' == \ + ms_v_traits.remove_defaults(ms_string) + + +def test_map(global_ns): + m_i2d = global_ns.typedef('m_i2d') + assert 'map< int, double >' == \ + declarations.map_traits.remove_defaults(m_i2d) + m_wstr2d = global_ns.typedef('m_wstr2d') + assert 'map< std::wstring, double >' == \ + declarations.map_traits.remove_defaults(m_wstr2d) + m_v_i2m_wstr2d = global_ns.typedef('m_v_i2m_wstr2d') + m = 'map< const std::vector< int >, std::map< std::wstring, double > >' + assert m == declarations.map_traits.remove_defaults(m_v_i2m_wstr2d) + + +def test_multimap(global_ns): + mm_i2d = global_ns.typedef('mm_i2d') + mm_traits = declarations.multimap_traits + assert 'multimap< int, double >' == mm_traits.remove_defaults(mm_i2d) + mm_wstr2d = global_ns.typedef('mm_wstr2d') + assert 'multimap< const std::wstring, double >' == \ + mm_traits.remove_defaults(mm_wstr2d) + mm_v_i2mm_wstr2d = global_ns.typedef('mm_v_i2mm_wstr2d') + assert ('multimap< const std::vector< int >, ' + + 'const std::multimap< const std::wstring, double > >') == \ + mm_traits.remove_defaults(mm_v_i2mm_wstr2d) + + +def test_hash_set(global_ns): + hs_v_int = global_ns.typedef('hs_v_int') + hs_traits = declarations.unordered_set_traits + name = 'unordered_set' + assert (name + '< std::vector< int > >') == \ + hs_traits.remove_defaults(hs_v_int), \ + hs_traits.remove_defaults(hs_v_int) + hs_string = global_ns.typedef('hs_string') + assert (name + '< std::string >') == \ + hs_traits.remove_defaults(hs_string) + + +def test_hash_multiset(global_ns): + mhs_v_int = global_ns.typedef('mhs_v_int') + mhs_traits = declarations.unordered_multiset_traits + name = 'unordered_multiset' + assert (name + '< std::vector< int > >') == \ + mhs_traits.remove_defaults(mhs_v_int) + mhs_string = global_ns.typedef('mhs_string') + assert (name + '< std::string >') == \ + mhs_traits.remove_defaults(mhs_string) + + +def test_hash_map(global_ns): + hm_i2d = global_ns.typedef('hm_i2d') + hm_traits = declarations.unordered_map_traits + name = 'unordered_map' + assert (name + '< int, double >') == \ + hm_traits.remove_defaults(hm_i2d) + hm_wstr2d = global_ns.typedef('hm_wstr2d') + assert (name + '< std::wstring, double >') == \ + hm_traits.remove_defaults(hm_wstr2d) + + +def test_hash_multimap(global_ns): + hmm_i2d = global_ns.typedef('hmm_i2d') + hmm_traits = declarations.unordered_multimap_traits + name = 'unordered_multimap' + assert (name + '< int, double >') == \ + hmm_traits.remove_defaults(hmm_i2d) + hmm_wstr2d = global_ns.typedef('hmm_wstr2d') + assert (name + '< const std::wstring, double >') == \ + hmm_traits.remove_defaults(hmm_wstr2d) + + hmm_v_i2mm_wstr2d = global_ns.typedef('hmm_v_i2mm_wstr2d') + + hmm_traits_value = hmm_traits.remove_defaults(hmm_v_i2mm_wstr2d) + + possible_values = ( + name + '< const std::vector< int >, ' + + 'const __gnu_cxx::' + name + '< const std::wstring, double > >', + name + '< const std::vector< int >, ' + + 'const std::' + utils.get_tr1(hmm_traits_value) + name + + '< const std::wstring, double > >', + name + '< const std::vector< int >, ' + + 'const stdext::' + name + '< const std::wstring, double > >') + + assert hmm_traits_value in possible_values, hmm_traits_value diff --git a/tests/test_smart_pointer.py b/tests/test_smart_pointer.py new file mode 100644 index 00000000..6b74d94f --- /dev/null +++ b/tests/test_smart_pointer.py @@ -0,0 +1,95 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + 'test_smart_pointer.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_is_smart_pointer(global_ns): + """ + Test smart_pointer_traits.is_smart_pointer method. + + """ + + criteria = declarations.declaration_matcher(name="yes1") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.smart_pointer_traits.is_smart_pointer( + decls[0].decl_type) is True + + criteria = declarations.declaration_matcher(name="no1") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.smart_pointer_traits.is_smart_pointer( + decls[0].decl_type) is False + + criteria = declarations.declaration_matcher(name="no2") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.smart_pointer_traits.is_smart_pointer( + decls[0].decl_type) is False + + +def test_is_auto_pointer(global_ns): + """ + Test auto_ptr_traits.is_smart_pointer method. + + """ + + criteria = declarations.declaration_matcher(name="yes2") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.auto_ptr_traits.is_smart_pointer( + decls[0].decl_type) is True + + criteria = declarations.declaration_matcher(name="no1") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.auto_ptr_traits.is_smart_pointer( + decls[0].decl_type) is False + + criteria = declarations.declaration_matcher(name="no2") + decls = declarations.matcher.find(criteria, global_ns) + assert declarations.auto_ptr_traits.is_smart_pointer( + decls[0].decl_type) is False + + +def test_smart_pointer_value_type(global_ns): + """ + Test smart_pointer_traits.value_type method. + + """ + + criteria = declarations.declaration_matcher(name="yes1") + decls = declarations.matcher.find(criteria, global_ns) + vt = declarations.smart_pointer_traits.value_type(decls[0].decl_type) + assert isinstance(vt, declarations.int_t) is True + + +def test_auto_pointer_value_type(global_ns): + """ + Test auto_pointer_traits.value_type method. + + """ + + criteria = declarations.declaration_matcher(name="yes2") + decls = declarations.matcher.find(criteria, global_ns) + vt = declarations.auto_ptr_traits.value_type(decls[0].decl_type) + assert isinstance(vt, declarations.double_t) is True diff --git a/tests/test_source_reader.py b/tests/test_source_reader.py new file mode 100644 index 00000000..355e225e --- /dev/null +++ b/tests/test_source_reader.py @@ -0,0 +1,31 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = [ + 'declarations_calldef.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_compound_argument_type(global_ns): + do_smth = global_ns.calldefs('do_smth') + assert do_smth is not None + do_smth.function_type() diff --git a/tests/test_start_with_declarations.py b/tests/test_start_with_declarations.py new file mode 100644 index 00000000..5a778893 --- /dev/null +++ b/tests/test_start_with_declarations.py @@ -0,0 +1,54 @@ +# 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 pytest + +from . import autoconfig + + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILES = "core_ns_join_1.hpp" + + +def __check_result(decls): + E11 = declarations.find_declaration(decls, fullname='::E11') + assert E11 is not None + ns12 = declarations.find_declaration(decls, fullname='::ns::ns12') + assert ns12 is not None + E13 = declarations.find_declaration(ns12.declarations, name='E13') + assert E13 is not None + E14 = declarations.find_declaration(decls, name='E14') + assert E14 is None + + +def test_simple_start_with_declarations(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.start_with_declarations.extend(['E11', 'ns::ns12::E13']) + decls = parser.parse([TEST_FILES], config) + __check_result(decls) + + +def test_project_reader_file_by_file_start_with_declarations(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.start_with_declarations.extend(['E11', 'ns::ns12::E13']) + reader = parser.project_reader_t(config) + decls = reader.read_files( + [parser.file_configuration_t( + TEST_FILES, config.start_with_declarations)], + parser.COMPILATION_MODE.FILE_BY_FILE) + __check_result(decls) + + +def test_project_reader_all_at_once_start_with_declarations(): + config = autoconfig.cxx_parsers_cfg.config.clone() + config.start_with_declarations.extend(['E11', 'ns::ns12::E13']) + reader = parser.project_reader_t(config) + decls = reader.read_files( + [parser.file_configuration_t( + TEST_FILES, config.start_with_declarations)], + parser.COMPILATION_MODE.ALL_AT_ONCE) + __check_result(decls) diff --git a/tests/test_string_traits.py b/tests/test_string_traits.py new file mode 100644 index 00000000..8dc1b2a0 --- /dev/null +++ b/tests/test_string_traits.py @@ -0,0 +1,56 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "string_traits.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_yes(ns, controller): + for typedef in ns.typedefs(): + assert controller(typedef.decl_type) is True + + +def validate_no(ns, controller): + for typedef in ns.typedefs(): + assert controller(typedef.decl_type) is False + + +def test_string(global_ns): + string_traits = global_ns.namespace('string_traits') + validate_yes( + string_traits.namespace('yes'), + declarations.is_std_string) + validate_no( + string_traits.namespace('no'), + declarations.is_std_string) + + +def test_wstring(global_ns): + wstring_traits = global_ns.namespace('wstring_traits') + validate_yes( + wstring_traits.namespace('yes'), + declarations.is_std_wstring) + validate_no( + wstring_traits.namespace('no'), + declarations.is_std_wstring) diff --git a/tests/test_templates.py b/tests/test_templates.py new file mode 100644 index 00000000..25ab5ad4 --- /dev/null +++ b/tests/test_templates.py @@ -0,0 +1,75 @@ +# 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 + +from pygccxml import declarations + + +def __test_split_impl(decl_string, name, args): + assert (name, args) == \ + declarations.templates.split(decl_string) + + +def __test_split_recursive_impl(decl_string, control_seq): + assert control_seq == \ + list(declarations.templates.split_recursive(decl_string)) + + +def __test_is_template_impl(decl_string): + assert declarations.templates.is_instantiation(decl_string) + + +def test_split_on_vector(): + __test_is_template_impl("vector >") + + __test_split_impl( + "vector >", + "vector", + ["int", "std::allocator"]) + + __test_split_recursive_impl( + "vector >", + [("vector", ["int", "std::allocator"]), + ("std::allocator", ["int"])]) + + +def test_split_on_string(): + __test_is_template_impl( + "basic_string,std::allocator >") + + __test_split_impl( + "basic_string,std::allocator >", + "basic_string", + ["char", + "std::char_traits", + "std::allocator"]) + + +def test_split_on_map(): + __test_is_template_impl( + "map >," + + "std::less,std::allocator > > > >") + + __test_split_impl( + "map >," + + "std::less,std::allocator > > > >", + "map", + ["long int", + "std::vector >", + "std::less", + "std::allocator > > >"]) + + +def test_join_on_vector(): + assert "vector< int, std::allocator >" == \ + declarations.templates.join( + "vector", ("int", "std::allocator")) + + +def test_bug_is_tmpl_inst(): + assert declarations.templates.is_instantiation( + "::FX::QMemArray::setRawData") is False diff --git a/tests/test_text_reader.py b/tests/test_text_reader.py new file mode 100644 index 00000000..b2b0584d --- /dev/null +++ b/tests/test_text_reader.py @@ -0,0 +1,27 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +def test_text_reader(): + config = autoconfig.cxx_parsers_cfg.config.clone() + + fconfig = parser.file_configuration_t( + data='int i;', + start_with_declarations=None, + content_type=parser.file_configuration_t.CONTENT_TYPE.TEXT) + + prj_reader = parser.project_reader_t(config) + decls = prj_reader.read_files( + [fconfig], + compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) + + var_i = declarations.find_declaration( + decls, decl_type=declarations.variable_t, name='i') + assert var_i is not None diff --git a/tests/test_type_as_exception_bug.py b/tests/test_type_as_exception_bug.py new file mode 100644 index 00000000..5a6c2cc1 --- /dev/null +++ b/tests/test_type_as_exception_bug.py @@ -0,0 +1,36 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "type_as_exception_bug.h", +] + + +@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) + return global_ns + + +def test_type_as_exception(global_ns): + buggy = global_ns.member_function('buggy') + expression_error = global_ns.class_('ExpressionError') + assert len(buggy.exceptions) == 1 + err = buggy.exceptions[0] + assert declarations.is_reference(err) + err = declarations.remove_declarated( + declarations.remove_reference(err)) + assert err is expression_error diff --git a/tests/test_type_traits.py b/tests/test_type_traits.py new file mode 100644 index 00000000..c3fca574 --- /dev/null +++ b/tests/test_type_traits.py @@ -0,0 +1,404 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "type_traits.hpp", +] + + +@pytest.fixture +def decls(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + 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 new file mode 100644 index 00000000..66b44665 --- /dev/null +++ b/tests/test_typedefs.py @@ -0,0 +1,46 @@ +# 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 + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +def test_typedefs_src_reader(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + 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 + 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 new file mode 100644 index 00000000..50287acb --- /dev/null +++ b/tests/test_unnamed_classes.py @@ -0,0 +1,93 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations +from pygccxml.declarations import type_traits + + +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 new file mode 100644 index 00000000..3cc6f016 --- /dev/null +++ b/tests/test_unnamed_enums_bug.py @@ -0,0 +1,68 @@ +# 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 + + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +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' + ], 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 new file mode 100644 index 00000000..905aa181 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,51 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import warnings + +from pygccxml import utils + + +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")] + + assert utils.utils.contains_parent_dir(path, dirs) is True + + dirs = [os.path.normpath("/home"), os.path.normpath("/mypath/test/")] + + assert utils.utils.contains_parent_dir(path, dirs) is False + + +def test_deprecation_wrapper(): + """ + The DeprecationWrapper is not part of the public API + + 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) + + +class DeprecatedClass(object): + """ + An empty class used for testing purposes. + """ + pass diff --git a/tests/test_va_list_tag_removal.py b/tests/test_va_list_tag_removal.py new file mode 100644 index 00000000..25a001d4 --- /dev/null +++ b/tests/test_va_list_tag_removal.py @@ -0,0 +1,123 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os +import platform + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +""" +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. + +""" + + +__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(): + + if platform.system() == 'Windows': + return True + + config = autoconfig.cxx_parsers_cfg.config.clone() + + config.flags = ["f1"] + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) + + classes = [ + i for i in decls if isinstance(i, declarations.class_t)] + + typedefs = [ + i for i in decls if isinstance(i, declarations.typedef_t)] + + variables = [ + i for i in decls if isinstance(i, declarations.variable_t)] + + tag = "__va_list_tag" + + 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] + + 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] + + assert 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 + assert len(variables) == 4 or len(variables) == 8 + + +def test_remove_va_list_tag(): + + if platform.system() == 'Windows': + return True + + config = autoconfig.cxx_parsers_cfg.config.clone() + + config.flags = [] + src_reader = parser.source_reader_t(config) + decls = declarations.make_flatten(src_reader.read_string(__code)) + + classes = [ + i for i in decls if isinstance(i, declarations.class_t)] + + typedefs = [ + i for i in decls if isinstance(i, declarations.typedef_t)] + + variables = [ + i for i in decls if isinstance(i, declarations.variable_t)] + + tag = "__va_list_tag" + + 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] + + 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 new file mode 100644 index 00000000..49347f7d --- /dev/null +++ b/tests/test_variable_matcher.py @@ -0,0 +1,60 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES1 = [ + "bit_fields.hpp", +] + +TEST_FILES2 = [ + "vector_traits.hpp", +] + + +def test_bit_fields(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + config = autoconfig.cxx_parsers_cfg.config.clone() + decls = parser.parse(TEST_FILES1, config, COMPILATION_MODE) + + 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 + + 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 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 new file mode 100644 index 00000000..81efa62b --- /dev/null +++ b/tests/test_vector_traits.py @@ -0,0 +1,90 @@ +# 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 pytest + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + + +TEST_FILES = [ + "vector_traits.hpp", +] + + +@pytest.fixture +def global_ns(): + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + 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 new file mode 100644 index 00000000..253d2c85 --- /dev/null +++ b/tests/test_warn_missing_include_dirs.py @@ -0,0 +1,32 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +import pytest + +from pygccxml import parser +from pygccxml import utils + + +def test_config_warn(): + """ + Test that a missing include directory is printing a warning, + not raising an error + """ + + # 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() + + # 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 new file mode 100644 index 00000000..b2ecee99 --- /dev/null +++ b/tests/test_xml_generators.py @@ -0,0 +1,69 @@ +# 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 pytest + +import logging + +from pygccxml import utils + + +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 new file mode 100644 index 00000000..ece9d598 --- /dev/null +++ b/tests/test_xmlfile_reader.py @@ -0,0 +1,46 @@ +# Copyright 2014-2017 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import os + +from . import autoconfig + +from pygccxml import parser +from pygccxml import declarations + +TEST_FILE = "core_types.hpp" + + +def test_read_xml_file(): + config = autoconfig.cxx_parsers_cfg.config.clone() + + src_reader = parser.source_reader_t(config) + src_decls = src_reader.read_file(TEST_FILE) + + xmlfile = src_reader.create_xml_file(TEST_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) + + prj_reader = parser.project_reader_t(config) + prj_decls = prj_reader.read_files( + [fconfig], + compilation_mode=parser.COMPILATION_MODE.FILE_BY_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')) + + assert src_decls == prj_decls diff --git a/unittests/algorithms_cache_tester.py b/unittests/algorithms_cache_tester.py deleted file mode 100644 index 3c7146c0..00000000 --- a/unittests/algorithms_cache_tester.py +++ /dev/null @@ -1,77 +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 unittest - -from . import parser_test_case - -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') - - 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) - - 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) - - self.assertTrue(not enum.cache.full_name) - self.assertTrue(not enum.cache.declaration_path) - - 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') - - -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/unittests/array_bug_tester.py b/unittests/array_bug_tester.py deleted file mode 100644 index d811e701..00000000 --- a/unittests/array_bug_tester.py +++ /dev/null @@ -1,131 +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 unittest - -from . import parser_test_case - -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 - if self.config.xml_generator == "gccxml": - self.assertTrue( - 'char [4] const' == arr_type.decl_string, - arr_type.decl_string) - else: - 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 - if self.config.xml_generator == "gccxml": - self.assertTrue( - 'char [4] volatile' == arr_type.decl_string, - arr_type.decl_string) - else: - 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 - if self.config.xml_generator == "gccxml": - self.assertTrue( - 'char [4] const volatile' == arr_type.decl_string, - arr_type.decl_string) - else: - 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() diff --git a/unittests/attributes_tester.py b/unittests/attributes_tester.py deleted file mode 100644 index 38aaf3e6..00000000 --- a/unittests/attributes_tester.py +++ /dev/null @@ -1,100 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - # TODO: once gccxml is removed; rename this to something like - # annotate_tester - self.header = "attributes_" + self.config.xml_generator + ".hpp" - - def setUp(self): - # Reset flags before each test - self.config.flags = "" - - def test_attributes(self): - - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.global_ns.init_optimizer() - - numeric = self.global_ns.class_('numeric_t') - do_nothing = numeric.member_function('do_nothing') - arg = do_nothing.arguments[0] - - generator = self.config.xml_generator_from_xml_file - if generator.is_castxml1 or \ - (generator.is_castxml and - float(generator.xml_output_version) >= 1.137): - # This works since: - # https://github.com/CastXML/CastXML/issues/25 - # https://github.com/CastXML/CastXML/pull/26 - # https://github.com/CastXML/CastXML/pull/27 - # The version bump to 1.137 came way later but this is the - # only way to make sure the test is running correctly - self.assertTrue("annotate(sealed)" == numeric.attributes) - self.assertTrue("annotate(no throw)" == do_nothing.attributes) - self.assertTrue("annotate(out)" == arg.attributes) - self.assertTrue( - numeric.member_operators(name="=")[0].attributes is None) - else: - self.assertTrue("gccxml(no throw)" == do_nothing.attributes) - self.assertTrue("gccxml(out)" == arg.attributes) - - def test_attributes_thiscall(self): - """ - Test attributes with the "f2" flag - - """ - if self.config.compiler != "msvc": - return - - self.config.flags = ["f2"] - - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.global_ns.init_optimizer() - - numeric = self.global_ns.class_('numeric_t') - do_nothing = numeric.member_function('do_nothing') - arg = do_nothing.arguments[0] - - generator = self.config.xml_generator_from_xml_file - if generator.is_castxml1 or ( - generator.is_castxml and - float(generator.xml_output_version) >= 1.137): - self.assertTrue("annotate(sealed)" == numeric.attributes) - self.assertTrue("annotate(out)" == arg.attributes) - - self.assertTrue( - "__thiscall__ annotate(no throw)" == do_nothing.attributes) - self.assertTrue( - numeric.member_operators(name="=")[0].attributes == - "__thiscall__") - - -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/unittests/better_templates_matcher_tester.py b/unittests/better_templates_matcher_tester.py deleted file mode 100644 index ebb4ae77..00000000 --- a/unittests/better_templates_matcher_tester.py +++ /dev/null @@ -1,50 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'better_templates_matcher_tester.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(self): - classes = [ - ('::std::vector>'), - '::std::vector>', - '::Ogre::Singleton< Ogre::PCZoneFactoryManager>'] - for i in classes: - self.global_ns.class_(i) - - -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/unittests/bit_fields_tester.py b/unittests/bit_fields_tester.py deleted file mode 100644 index fad14692..00000000 --- a/unittests/bit_fields_tester.py +++ /dev/null @@ -1,54 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'bit_fields.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(self): - bf_x = self.global_ns.variable('x') - self.assertTrue(bf_x.bits == 1) - - bf_y = self.global_ns.variable('y') - self.assertTrue(bf_y.bits == 7) - - mv_z = self.global_ns.variable('z') - self.assertTrue(mv_z.bits is None) - - def test2(self): - 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/unittests/cache_enums_tester.py b/unittests/cache_enums_tester.py deleted file mode 100644 index 5a726e78..00000000 --- a/unittests/cache_enums_tester.py +++ /dev/null @@ -1,64 +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 os -import unittest - -from . import autoconfig -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class tester_impl_t(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, - 'declarations_enums.hpp') - self.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 test_cache(self): - cache = parser.file_cache_t(self.cache_file) - reader = parser.source_reader_t(self.config, cache) - decls1 = reader.read_file(self.header) - cache.flush() - cache = parser.file_cache_t(self.cache_file) - reader = parser.source_reader_t(self.config, cache) - decls2 = reader.read_file(self.header) - - enum_matcher = declarations.declaration_matcher_t( - name="EColor", - decl_type=declarations.enumeration_t) - - color1 = declarations.matcher.get_single(enum_matcher, decls1) - color2 = declarations.matcher.get_single(enum_matcher, decls2) - self.assertTrue(color1.values == color2.values) - - -class Test(tester_impl_t): - CXX_PARSER_CFG = autoconfig.cxx_parsers_cfg.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() diff --git a/unittests/cached_source_file_tester.py b/unittests/cached_source_file_tester.py deleted file mode 100644 index 5995badc..00000000 --- a/unittests/cached_source_file_tester.py +++ /dev/null @@ -1,54 +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 os -import stat -import unittest - -from . import parser_test_case - -from pygccxml import utils -from pygccxml import parser - - -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' - - def test(self): - fconfig = parser.file_configuration_t( - data=self.__fname, - content_type=parser.CONTENT_TYPE.CACHED_SOURCE_FILE) - try: - prj_reader = parser.project_reader_t(self.config) - prj_reader.read_files( - [fconfig], - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - self.assertTrue(os.path.exists(fconfig.cached_source_file)) - mtime1 = os.stat(fconfig.cached_source_file)[stat.ST_MTIME] - prj_reader.read_files( - [fconfig], - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - mtime2 = os.stat(fconfig.cached_source_file)[stat.ST_MTIME] - self.assertTrue(mtime1 == mtime2) - finally: - utils.remove_file_no_raise(fconfig.cached_source_file, self.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() diff --git a/unittests/call_invocation_tester.py b/unittests/call_invocation_tester.py deleted file mode 100644 index 68b6c5c8..00000000 --- a/unittests/call_invocation_tester.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 unittest - -from . import parser_test_case - -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - def __test_split_impl(self, decl_string, name, args): - self.assertTrue( - (name, args) == declarations.call_invocation.split(decl_string)) - - def __test_split_recursive_impl(self, decl_string, control_seq): - self.assertTrue( - control_seq == - list(declarations.call_invocation.split_recursive(decl_string))) - - def __test_is_call_invocation_impl(self, decl_string): - self.assertTrue( - declarations.call_invocation.is_call_invocation(decl_string)) - - def test_split_on_vector(self): - self.__test_is_call_invocation_impl("vector(int,std::allocator(int) )") - - self.__test_split_impl( - "vector(int,std::allocator(int) )", - "vector", - ["int", "std::allocator(int)"]) - - self.__test_split_recursive_impl( - "vector(int,std::allocator(int) )", - [("vector", ["int", "std::allocator(int)"]), - ("std::allocator", ["int"])]) - - def test_split_on_string(self): - self.__test_is_call_invocation_impl( - "basic_string(char,std::char_traits(char),std::allocator(char) )") - - self.__test_split_impl( - "basic_string(char,std::char_traits(char),std::allocator(char) )", - "basic_string", - ["char", "std::char_traits(char)", "std::allocator(char)"]) - - def test_split_on_map(self): - self.__test_is_call_invocation_impl( - "map(long int,std::vector(int, std::allocator(int) )," + - "std::less(long int),std::allocator(std::pair" + - "(const long int, std::vector(int, std::allocator(int) ) ) ) )") - - self.__test_split_impl( - "map(long int,std::vector(int, std::allocator(int) )," + - "std::less(long int),std::allocator(std::pair" + - "(const long int, std::vector(int, std::allocator(int) ) ) ) )", - "map", - ["long int", "std::vector(int, std::allocator(int) )", - "std::less(long int)", - "std::allocator(std::pair(const long int," + - " std::vector(int, std::allocator(int) ) ) )"]) - - def test_join_on_vector(self): - self.assertTrue( - "vector( int, std::allocator(int) )" == - declarations.call_invocation.join( - "vector", ("int", "std::allocator(int)"))) - - def test_find_args(self): - temp = 'x()()' - found = declarations.call_invocation.find_args(temp) - self.assertTrue((1, 2) == found) - found = declarations.call_invocation.find_args(temp, found[1] + 1) - self.assertTrue((3, 4) == found) - temp = 'x(int,int)(1,2)' - found = declarations.call_invocation.find_args(temp) - self.assertTrue((1, 9) == found) - found = declarations.call_invocation.find_args(temp, found[1] + 1) - self.assertTrue((10, 14) == found) - - def test_bug_unmatched_brace(self): - src = 'AlternativeName((&string("")), (&string("")), (&string("")))' - self.__test_split_impl( - src, 'AlternativeName', [ - '(&string(""))', '(&string(""))', '(&string(""))']) - - -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/unittests/calldef_matcher_tester.py b/unittests/calldef_matcher_tester.py deleted file mode 100644 index b658d19c..00000000 --- a/unittests/calldef_matcher_tester.py +++ /dev/null @@ -1,47 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -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 = 'declarations_calldef.hpp' - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse([self.header], self.config) - - def test(self): - criteria = declarations.calldef_matcher_t( - name='return_default_args', - return_type='int', - arg_types=[None, declarations.bool_t()]) - rda = declarations.matcher.get_single(criteria, self.declarations) - self.assertTrue(rda, "return_default_args function was not found.") - - -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/unittests/calling_convention_tester.py b/unittests/calling_convention_tester.py deleted file mode 100644 index 381f476d..00000000 --- a/unittests/calling_convention_tester.py +++ /dev/null @@ -1,42 +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 unittest - -from . import parser_test_case - -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - def test_extract(self): - data = [ - ('thiscall', - '(public: __thiscall std::auto_ptr' + - '::auto_ptr(class std::auto_ptr' + - ' &))'), - ('', "(const pof::number_t::`vftable')")] - - for expected, text in data: - got = declarations.CALLING_CONVENTION_TYPES.extract(text) - self.assertTrue( - got == expected, "Expected calling convention: %s, got %s" % - (expected, got)) - - -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/unittests/complex_types_tester.py b/unittests/complex_types_tester.py deleted file mode 100644 index 5fe8a255..00000000 --- a/unittests/complex_types_tester.py +++ /dev/null @@ -1,47 +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 os -import unittest - -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 = 'complex_types.hpp' - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse([self.header], self.config) - - def test(self): - """ - This test tests presence of complex long double, float within - FUNDAMENTAL_TYPES map - """ - pass - - -def create_suite(): - suite = unittest.TestSuite() - if os.name != 'nt': - 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/unittests/configs/appveyor.cfg b/unittests/configs/appveyor.cfg deleted file mode 100644 index 3c95c6e9..00000000 --- a/unittests/configs/appveyor.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[xml_generator] -compiler=msvc -compiler_path=C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin/cl.exe -cflags=-std=c++11 -include_paths=C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/include diff --git a/unittests/configs/castxml_epic1.cfg b/unittests/configs/castxml_epic1.cfg deleted file mode 100644 index 95fca817..00000000 --- a/unittests/configs/castxml_epic1.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[xml_generator] -castxml_epic_version=1 \ No newline at end of file diff --git a/unittests/configs/gcc9.cfg b/unittests/configs/gcc9.cfg deleted file mode 100644 index d8a2b6ef..00000000 --- a/unittests/configs/gcc9.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[xml_generator] -compiler=/usr/bin/gcc-9 -cflags=-std=c++98 -include_paths=/usr/lib/gcc/x86_64-linux-gnu/9 \ No newline at end of file diff --git a/unittests/const_volatile_arg_tester.py b/unittests/const_volatile_arg_tester.py deleted file mode 100644 index 099ee1b0..00000000 --- a/unittests/const_volatile_arg_tester.py +++ /dev/null @@ -1,50 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'const_volatile_arg.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() - self.global_ns = Test.global_ns - - def test(self): - f = self.global_ns.free_function('pygccxml_bug') - t = f.arguments[0].decl_type - self.assertTrue(isinstance(t, declarations.pointer_t)) - self.assertTrue(isinstance(t.base, declarations.volatile_t)) - self.assertTrue(isinstance(t.base.base, declarations.const_t)) - self.assertTrue(declarations.is_integral(t.base.base.base)) - - -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/unittests/copy_constructor_tester.py b/unittests/copy_constructor_tester.py deleted file mode 100644 index 0fadd860..00000000 --- a/unittests/copy_constructor_tester.py +++ /dev/null @@ -1,74 +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 os -import bz2 -import unittest - -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): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.global_ns = None - self.xml_path = None - - def setUp(self): - if not self.global_ns: - - # Extract the xml file from the bz2 archive - bz2_path = os.path.join( - autoconfig.data_directory, - 'ogre.1.7.xml.bz2') - self.xml_path = os.path.join( - autoconfig.data_directory, - 'ogre.1.7.xml') - with open(self.xml_path, 'wb') as new_file: - # bz2.BZ2File can not be used in a with statement in python 2.6 - bz2_file = bz2.BZ2File(bz2_path, 'rb') - for data in iter(lambda: bz2_file.read(100 * 1024), b''): - new_file.write(data) - bz2_file.close() - - reader = parser.source_reader_t(autoconfig.cxx_parsers_cfg.config) - self.global_ns = declarations.get_global_namespace( - reader.read_xml_file( - self.xml_path)) - self.global_ns.init_optimizer() - - def tearDown(self): - # Delete the extracted xml file - os.remove(self.xml_path) - - def test(self): - for x in self.global_ns.typedefs('SettingsMultiMap'): - self.assertTrue(not declarations.is_noncopyable(x)) - - for x in self.global_ns.typedefs('SettingsIterator'): - self.assertTrue(not declarations.is_noncopyable(x)) - - for x in self.global_ns.typedefs('SectionIterator'): - self.assertTrue(not declarations.is_noncopyable(x)) - - -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/unittests/core_tester.py b/unittests/core_tester.py deleted file mode 100644 index 5f7c8710..00000000 --- a/unittests/core_tester.py +++ /dev/null @@ -1,615 +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 unittest - -from . import autoconfig -from . import parser_test_case - -from pygccxml import utils -from pygccxml import parser -from pygccxml import declarations - - -def is_sub_path(root, some_path): - root = utils.normalize_path(root) - some_path = utils.normalize_path(some_path) - return some_path.startswith(root) - - -class Core(parser_test_case.parser_test_case_t): - """Tests core algorithms of GCC-XML and CastXML file readers.""" - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.global_ns = None - - def test_top_parent(self): - enum = self.global_ns.enumeration('::ns::ns32::E33') - self.assertTrue(self.global_ns is enum.top_parent) - - # tests namespaces join functionality. described in gccxml.py - def test_nss_join(self): - # list of all namespaces - nss = ['::ns', '::ns::ns12', '::ns::ns22', '::ns::ns32'] - # list of all namespaces that have unnamed namespace - # unnamed_nss = nss[1:] doing nothing with this list ? - # list of all enums [0:2] [3:5] [6:8] - has same parent - enums = [ - '::E11', - '::E21', - '::E31', - '::ns::E12', - '::ns::E22', - '::ns::E32', - '::ns::ns12::E13', - '::ns::ns22::E23', - '::ns::ns32::E33'] - - for ns in nss: - self.global_ns.namespace(ns) - - for enum in enums: - self.global_ns.enumeration(enum) - - ns = self.global_ns.namespace(nss[0]) - ns12 = self.global_ns.namespace(nss[1]) - ns22 = self.global_ns.namespace(nss[2]) - ns32 = self.global_ns.namespace(nss[3]) - self.assertTrue( - ns and ( - ns is ns12.parent is ns22.parent is ns32.parent), - 'There are 2 or more instances of ns namespace.') - - e11 = self.global_ns.enumeration(enums[0]) - e21 = self.global_ns.enumeration(enums[1]) - e31 = self.global_ns.enumeration(enums[2]) - self.assertTrue( - e11.parent is e21.parent is e31.parent, - 'There are 2 or more instances of global namespace.') - - nse12 = self.global_ns.enumeration(enums[3]) - nse23 = self.global_ns.enumeration(enums[4]) - nse33 = self.global_ns.enumeration(enums[5]) - self.assertTrue( - ns and ( - ns is nse12.parent is nse23.parent is nse33.parent), - 'There are 2 or more instances of ns namespace.') - - def _test_ns_membership(self, ns, enum_name): - unnamed_enum = ns.enumeration( - lambda d: d.name == '' and is_sub_path( - autoconfig.data_directory, - d.location.file_name), - recursive=False) - self.assertTrue( - unnamed_enum in ns.declarations, - "namespace '%s' does not contains unnamed enum." % - ns.name) - - enum = ns.enumeration(enum_name, recursive=False) - - self.assertTrue( - enum in ns.declarations, - "namespace '%s' does not contains enum '%s'" % - (ns.name, enum.name)) - - self.assertTrue( - unnamed_enum.parent is ns, - ("unnamed enum belong to namespace '%s' but this namespace " + - "is not it's parent.") % ns.name) - - self.assertTrue( - enum.parent is ns, - ("enum '%s' belong to namespace '%s' but this namespace" + - " is not it's parent.") % (enum.name, ns.name)) - - def _test_class_membership(self, class_inst, enum_name, access): - # getting enum through get_members function - nested_enum1 = class_inst.enumeration( - name=enum_name, - function=declarations.access_type_matcher_t(access)) - - # getting enum through declarations property - nested_enum2 = class_inst.enumeration(enum_name) - - # it shoud be same object - self.assertTrue( - nested_enum1 is nested_enum2, - ("enum accessed through access definition('%s') and " + - "through declarations('%s') are different enums " + - "or instances.") % - (nested_enum1.name, nested_enum2.name)) - - # check whether we meaning same class instance - self.assertTrue( - class_inst is nested_enum1.parent is nested_enum2.parent, - 'There are 2 or more instances of ns namespace.') - - # test gccxml_file_reader_t._update_membership algorithm - def test_membership(self): - core_membership = self.global_ns.namespace('membership') - self._test_ns_membership(self.global_ns, 'EGlobal') - self._test_ns_membership( - core_membership.namespace('enums_ns'), - 'EWithin') - self._test_ns_membership( - core_membership.namespace(''), - 'EWithinUnnamed') - class_nested_enums = core_membership.class_('class_for_nested_enums_t') - self._test_class_membership( - class_nested_enums, - 'ENestedPublic', - declarations.ACCESS_TYPES.PUBLIC) - self._test_class_membership( - class_nested_enums, - 'ENestedProtected', - declarations.ACCESS_TYPES.PROTECTED) - self._test_class_membership( - class_nested_enums, - 'ENestedPrivate', - declarations.ACCESS_TYPES.PRIVATE) - - def test_mangled_name_namespace(self): - std = self.global_ns.namespace("std") - self.assertTrue(std, "std namespace has not been found") - self.assertIsNone(std.mangled) - - def test_mangled_name_functions(self): - # This works with gccxml and castxml - ns = self.global_ns.namespace("overloads") - do_nothing = ns.calldefs("do_nothing", recursive=False) - self.assertTrue( - do_nothing.mangled, - "Mangled name of do_nothing function should be different +" - "from None") - - def test_mangled_name_variable(self): - # This works with gccxml and castxml - var_inst = self.global_ns.variable('array255') - self.assertTrue( - var_inst.mangled, - "Mangled name of array255 variable should be different +" - "from None") - - def _test_is_based_and_derived(self, base, derived, access): - dhi_v = declarations.hierarchy_info_t(derived, access, True) - dhi_not_v = declarations.hierarchy_info_t(derived, access, False) - self.assertTrue( - dhi_v in base.derived or dhi_not_v in base.derived, - "base class '%s' doesn't has derived class '%s'" % - (base.name, derived.name)) - - bhi_v = declarations.hierarchy_info_t(base, access, True) - bhi_not_v = declarations.hierarchy_info_t(base, access, False) - - self.assertTrue( - bhi_v in derived.bases or bhi_not_v in derived.bases, - "derive class '%s' doesn't has base class '%s'" % - (derived.name, base.name)) - - def test_class_hierarchy(self): - class_hierarchy = self.global_ns.namespace('class_hierarchy') - - base = class_hierarchy.class_('base_t') - other_base = class_hierarchy.class_('other_base_t') - derived_public = class_hierarchy.class_('derived_public_t') - derived_protected = class_hierarchy.class_('derived_protected_t') - derived_private = class_hierarchy.class_('derived_private_t') - multi_derived = class_hierarchy.class_('multi_derived_t') - - self._test_is_based_and_derived( - base, - derived_public, - declarations.ACCESS_TYPES.PUBLIC) - self._test_is_based_and_derived( - base, - derived_protected, - declarations.ACCESS_TYPES.PROTECTED) - self._test_is_based_and_derived( - base, - derived_private, - declarations.ACCESS_TYPES.PRIVATE) - self._test_is_based_and_derived( - base, - multi_derived, - declarations.ACCESS_TYPES.PROTECTED) - self._test_is_based_and_derived( - other_base, - multi_derived, - declarations.ACCESS_TYPES.PRIVATE) - self._test_is_based_and_derived( - derived_private, - multi_derived, - declarations.ACCESS_TYPES.PRIVATE) - - def _test_is_same_bases(self, derived1, derived2): - bases1 = set([id(hierarchy_info.related_class) - for hierarchy_info in derived1.bases]) - bases2 = set([id(hierarchy_info.related_class) - for hierarchy_info in derived2.bases]) - self.assertTrue( - bases1 == bases2, - ("derived class '%s' and derived class '%s' has references to " + - "different instance of base classes ") % - (derived1.name, derived2.name)) - - def test_class_join(self): - diamand_hierarchy = self.global_ns.namespace('diamand_hierarchy') - base = diamand_hierarchy.class_('base_t') - derived1 = diamand_hierarchy.class_('derived1_t') - derived2 = diamand_hierarchy.class_('derived2_t') - final_derived = diamand_hierarchy.class_('final_derived_t') - - self._test_is_based_and_derived( - base, - derived1, - declarations.ACCESS_TYPES.PUBLIC) - self._test_is_based_and_derived( - base, - derived2, - declarations.ACCESS_TYPES.PUBLIC) - self._test_is_based_and_derived( - derived1, - final_derived, - declarations.ACCESS_TYPES.PUBLIC) - self._test_is_based_and_derived( - derived2, - final_derived, - declarations.ACCESS_TYPES.PUBLIC) - self._test_is_same_bases(derived1, derived2) - - def test_fundamental_types(self): - # check whether all build in types could be constructed - errors = [] - for fundamental_type_name, fundamental_type in \ - declarations.FUNDAMENTAL_TYPES.items(): - if 'complex' in fundamental_type_name: - continue # I check this in an other tester - if isinstance( - fundamental_type, - (declarations.int128_t, declarations.uint128_t)): - continue # I don't have test case for this - if isinstance(fundamental_type, declarations.java_fundamental_t): - continue # I don't check this at all - typedef_name = 'typedef_' + fundamental_type_name.replace(' ', '_') - typedef = self.global_ns.decl( - decl_type=declarations.typedef_t, - name=typedef_name) - self.assertTrue( - typedef, - "unable to find typedef to build-in type '%s'" % - fundamental_type_name) - if typedef.decl_type.decl_string != fundamental_type.decl_string: - errors.append( - "there is a difference between typedef base type " + - "name('%s') and expected one('%s')" % - (typedef.decl_type.decl_string, - fundamental_type.decl_string)) - self.assertFalse(errors, pprint.pformat(errors)) - - def test_compound_types(self): - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_const_int') - self._test_type_composition( - typedef_inst.decl_type, - declarations.const_t, - declarations.int_t) - - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_pointer_int') - self._test_type_composition( - typedef_inst.decl_type, - declarations.pointer_t, - declarations.int_t) - - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_reference_int') - self._test_type_composition( - typedef_inst.decl_type, - declarations.reference_t, - declarations.int_t) - - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_const_unsigned_int_const_pointer') - self._test_type_composition( - typedef_inst.decl_type, - declarations.const_t, - declarations.pointer_t) - self._test_type_composition( - typedef_inst.decl_type.base, - declarations.pointer_t, - declarations.const_t) - self._test_type_composition( - typedef_inst.decl_type.base.base, - declarations.const_t, - declarations.unsigned_int_t) - - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_volatile_int') - self._test_type_composition( - typedef_inst.decl_type, - declarations.volatile_t, - declarations.int_t) - - var_inst = self.global_ns.variable('array255') - self._test_type_composition( - var_inst.decl_type, - declarations.array_t, - declarations.int_t) - - typedef_inst = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='typedef_EFavoriteDrinks') - self.assertTrue( - isinstance( - typedef_inst.decl_type, - declarations.declarated_t), - " typedef to enum should be 'declarated_t' instead of '%s'" % - typedef_inst.decl_type.__class__.__name__) - enum_declaration = self.global_ns.enumeration('EFavoriteDrinks') - self.assertTrue( - typedef_inst.decl_type.declaration is enum_declaration, - "instance of declaration_t has reference to '%s' instead of '%s'" % - (typedef_inst.decl_type.declaration.name, - enum_declaration.name)) - - def test_free_function_type(self): - function_ptr = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='function_ptr') - self._test_type_composition( - function_ptr.decl_type, - declarations.pointer_t, - declarations.free_function_type_t) - function_type = function_ptr.decl_type.base - self.assertTrue( - isinstance( - function_type.return_type, - declarations.int_t), - "return function type of typedef 'function_ptr' should be " + - "'%s' instead of '%s' " % - ('int_t', function_type.return_type.__class__.__name__)) - self.assertTrue( - len(function_type.arguments_types) == 2, - "number of arguments of function of typedef 'function_ptr' " + - "should be 2 instead of '%d' " % - len(function_type.arguments_types)) - self.assertTrue( - isinstance( - function_type.arguments_types[0], - declarations.int_t), - "first argument of function of typedef 'function_ptr' should be " + - "'%s' instead of '%s' " % - ('int_t', function_type.arguments_types[0].__class__.__name__)) - self.assertTrue( - isinstance( - function_type.arguments_types[1], - declarations.double_t), - "first argument of function of typedef 'function_ptr' should be " + - "'%s' instead of '%s' " % - ('double_t', function_type.arguments_types[0].__class__.__name__)) - - def test_member_function_type(self): - function_ptr = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='member_function_ptr_t') - self._test_type_composition( - function_ptr.decl_type, - declarations.pointer_t, - declarations.member_function_type_t) - - function_type = function_ptr.decl_type.base - - members_pointers = self.global_ns.class_('members_pointers_t') - self.assertTrue( - function_type.class_inst.declaration is members_pointers, - "member function type class should be '%s' instead of '%s'" % - (members_pointers.decl_string, - function_type.class_inst.decl_string)) - - self.assertTrue( - isinstance( - function_type.return_type, - declarations.int_t), - "return function type of typedef 'member_function_ptr_t' should " + - "be '%s' instead of '%s' " % - ('int_t', function_type.return_type.__class__.__name__)) - self.assertTrue( - len( - function_type.arguments_types) == 1, - "number of arguments of function of typedef " + - "'member_function_ptr_t' should be 1 instead of '%d' " % len( - function_type.arguments_types)) - self.assertTrue( - isinstance( - function_type.arguments_types[0], - declarations.double_t), - "first argument of function of typedef 'member_function_ptr_t' " + - "should be '%s' instead of '%s' " % - ('double_t', function_type.arguments_types[0].__class__.__name__)) - - self.assertTrue( - function_type.has_const, - " 'member_function_ptr_t' should be const function.") - - def test_member_variable_type(self): - mv = self.global_ns.decl( - decl_type=declarations.typedef_t, - name='member_variable_ptr_t') - self._test_type_composition( - mv.decl_type, - declarations.pointer_t, - declarations.member_variable_type_t) - - members_pointers = self.global_ns.class_('members_pointers_t') - self.assertTrue( - members_pointers, - "unable to find class('%s')" % - 'members_pointers_t') - self._test_type_composition( - mv.decl_type.base, - declarations.member_variable_type_t, - declarations.declarated_t) - mv_type = mv.decl_type.base - self.assertTrue( - mv_type.base.declaration is members_pointers, - "member function type class should be '%s' instead of '%s'" % - (members_pointers.decl_string, - mv_type.base.decl_string)) - - def test_overloading(self): - ns = self.global_ns.namespace('overloads') - - do_nothings = ns.calldefs('do_nothing', recursive=False) - self.assertTrue( - 4 == len(do_nothings), - ("expected number of overloaded 'do_nothing' functions is %d " + - "and existing(%d) is different") % - (4, len(do_nothings))) - for index, do_nothing in enumerate(do_nothings): - others = do_nothings[:index] + do_nothings[index + 1:] - if set(do_nothing.overloads) != set(others): - print('\nexisting: ') - for x in do_nothing.overloads: - print(str(x)) - print('\nexpected: ') - for x in others: - print(str(x)) - - self.assertTrue(set(do_nothing.overloads) == set( - others), "there is a difference between expected function " + - "overloads and existing ones.") - - def test_abstract_classes(self): - ns = self.global_ns.namespace('abstract_classes') - abstract_i = ns.class_('abstract_i') - self.assertTrue( - abstract_i.is_abstract, - "class 'abstract_i' should be abstract") - derived_abstract_i = ns.class_('derived_abstract_i') - self.assertTrue( - derived_abstract_i.is_abstract, - "class 'derived_abstract_i' should be abstract") - implementation = ns.class_('implementation') - self.assertTrue( - not implementation.is_abstract, - "class 'implementation' should not be abstract") - - def test_byte_size(self): - mptrs = self.global_ns.class_('members_pointers_t') - self.assertTrue(mptrs.byte_size != 0) - - def test_byte_align(self): - mptrs = self.global_ns.class_('members_pointers_t') - self.assertTrue(mptrs.byte_align != 0) - - def test_byte_offset(self): - mptrs = self.global_ns.class_('members_pointers_t') - self.assertTrue(mptrs.variable('xxx').byte_offset != 0) - - -class CoreXMLGenerator(Core): - """Tests core algorithms of GCC-XML and CastXML file readers.""" - global_ns = None - COMPILATION_MODE = None - INIT_OPTIMIZER = None - - def __init__(self, *args): - Core.__init__(self, *args) - self.test_files = [ - 'core_ns_join_1.hpp', - 'core_ns_join_2.hpp', - 'core_ns_join_3.hpp', - 'core_membership.hpp', - 'core_class_hierarchy.hpp', - 'core_types.hpp', - 'core_diamand_hierarchy_base.hpp', - 'core_diamand_hierarchy_derived1.hpp', - 'core_diamand_hierarchy_derived2.hpp', - 'core_diamand_hierarchy_final_derived.hpp', - 'core_overloads_1.hpp', - 'core_overloads_2.hpp', - 'abstract_classes.hpp'] - self.global_ns = None - - def setUp(self): - if not Core.global_ns: - decls = parser.parse( - self.test_files, - self.config, - self.COMPILATION_MODE) - Core.global_ns = declarations.get_global_namespace( - decls) - if self.INIT_OPTIMIZER: - Core.global_ns.init_optimizer() - Core.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.global_ns = Core.global_ns - self.xml_generator_from_xml_file = Core.xml_generator_from_xml_file - - -class core_all_at_once_t(CoreXMLGenerator): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - INIT_OPTIMIZER = True - - def __init__(self, *args): - CoreXMLGenerator.__init__(self, *args) - - -class core_all_at_once_no_opt_t(CoreXMLGenerator): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - INIT_OPTIMIZER = False - - def __init__(self, *args): - CoreXMLGenerator.__init__(self, *args) - - -class core_file_by_file_t(CoreXMLGenerator): - COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE - INIT_OPTIMIZER = True - - def __init__(self, *args): - CoreXMLGenerator.__init__(self, *args) - - -class core_file_by_file_no_opt_t(CoreXMLGenerator): - COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE - INIT_OPTIMIZER = False - - def __init__(self, *args): - CoreXMLGenerator.__init__(self, *args) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=core_all_at_once_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=core_all_at_once_no_opt_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=core_file_by_file_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=core_file_by_file_no_opt_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/decl_printer_tester.py b/unittests/decl_printer_tester.py deleted file mode 100644 index 571b0f02..00000000 --- a/unittests/decl_printer_tester.py +++ /dev/null @@ -1,79 +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 sys -import unittest - -from . import parser_test_case - -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.__files = [ - 'core_ns_join_1.hpp', - 'core_ns_join_2.hpp', - 'core_ns_join_3.hpp', - 'core_membership.hpp', - 'core_class_hierarchy.hpp', - 'core_types.hpp', - 'core_diamand_hierarchy_base.hpp', - 'core_diamand_hierarchy_derived1.hpp', - 'core_diamand_hierarchy_derived2.hpp', - 'core_diamand_hierarchy_final_derived.hpp', - 'core_overloads_1.hpp', - 'core_overloads_2.hpp', - 'typedefs_base.hpp'] - - # for i, f in enumerate(self.__files): - # f = parser.create_cached_source_fc( - # os.path.join( autoconfig.data_directory, f) - # , os.path.join( autoconfig.data_directory, f + '.xml') ) - # self.__files[i] = f - prj_reader = parser.project_reader_t(self.config) - self.decls = prj_reader.read_files( - self.__files, - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - - def test_printer(self): - - # Redirect sys.stdout to a class with a writer doing nothing - # This greatly reduces the size of the test output and makes - # test log files readable. - # Note: flush needs to be defined; because if not this will - # result in an AttributeError on call. - class DontPrint(object): - def write(*args): - pass - - def flush(*args): - pass - sys.stdout = DontPrint() - - declarations.print_declarations(self.decls) - - def test__str__(self): - decls = declarations.make_flatten(self.decls) - for decl in decls: - str(decl) - - -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/unittests/decl_string_tester.py b/unittests/decl_string_tester.py deleted file mode 100644 index 1205dd6a..00000000 --- a/unittests/decl_string_tester.py +++ /dev/null @@ -1,87 +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 os -import unittest - -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): - 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 = os.path.join( - autoconfig.data_directory, - 'declarations_calldef.hpp') - self.template = """ - //test generated declaration string using gcc(xml) compiler - #include "declarations_calldef.hpp" - void test_generated_decl_string( %s ); - """ - - 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_member_function(self): - member_inline_call = \ - self.global_ns.member_function('member_inline_call') - decls = parser.parse_string( - self.template % - member_inline_call.decl_string, - self.config) - self.assertTrue( - decls, - "Created decl_string for member function contains mistake") - - def test_free_function(self): - return_default_args = \ - self.global_ns.free_function('return_default_args') - decls = parser.parse_string( - self.template % - return_default_args.decl_string, - self.config) - self.assertTrue( - decls, - "Created decl_string for global function contains mistake") - - def test_all_mem_and_free_funs(self): - ns = self.global_ns.namespace('::declarations::calldef') - for f in ns.member_functions(): - decls = parser.parse_string( - self.template % f.decl_string, self.config) - self.assertTrue( - decls, - "Created decl_string for member function contains mistake") - for f in ns.free_functions(): - decls = parser.parse_string( - self.template % f.decl_string, self.config) - self.assertTrue( - decls, - "Created decl_string for member function contains mistake") - - -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/unittests/declaration_files_tester.py b/unittests/declaration_files_tester.py deleted file mode 100644 index 871d1181..00000000 --- a/unittests/declaration_files_tester.py +++ /dev/null @@ -1,57 +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 os -import unittest - -from . import parser_test_case - -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.__files = [ - 'core_ns_join_1.hpp', - 'core_ns_join_2.hpp', - 'core_ns_join_3.hpp', - 'core_membership.hpp', - 'core_class_hierarchy.hpp', - 'core_types.hpp', - 'core_diamand_hierarchy_base.hpp', - 'core_diamand_hierarchy_derived1.hpp', - 'core_diamand_hierarchy_derived2.hpp', - 'core_diamand_hierarchy_final_derived.hpp', - 'core_overloads_1.hpp', - 'core_overloads_2.hpp'] - - def test(self): - prj_reader = parser.project_reader_t(self.config) - decls = prj_reader.read_files( - self.__files, - compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE) - files = declarations.declaration_files(decls) - result = set() - for fn in files: - result.add(os.path.split(fn)[1]) - self.assertTrue(set(self.__files).issubset(result)) - - -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/unittests/declaration_matcher_tester.py b/unittests/declaration_matcher_tester.py deleted file mode 100644 index 3dc848e7..00000000 --- a/unittests/declaration_matcher_tester.py +++ /dev/null @@ -1,81 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -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 = 'classes.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() - self.global_ns = Test.global_ns - - def test_global(self): - gns = self.global_ns - gns.class_('cls') - gns.class_('::cls') - - def test_typedefs(self): - gns = self.global_ns - gns.class_('cls2') - if self.config.xml_generator == "castxml": - gns.typedef('cls2') - gns.class_('::cls2') - - gns.class_('cls3') - if self.config.xml_generator == "castxml": - gns.typedef('cls3') - cls3 = gns.class_('::cls3') - cls3.variable('i') - - def test_ns1(self): - gns = self.global_ns - ns1 = gns.namespace('ns') - - gns.class_('nested_cls') - self.assertRaises(Exception, lambda: gns.class_('ns::nested_cls')) - gns.class_('::ns::nested_cls') - - self.assertRaises(Exception, lambda: ns1.class_('::nested_cls')) - ns1.class_('nested_cls') - ns1.class_('::ns::nested_cls') - - gns.class_('nested_cls2') - self.assertRaises(Exception, lambda: gns.class_('ns::nested_cls2')) - gns.class_('::ns::nested_cls2') - - gns.class_('nested_cls3') - self.assertRaises(Exception, lambda: gns.class_('ns::nested_cls3')) - gns.class_('::ns::nested_cls3') - - -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/unittests/declarations_cache_tester.py b/unittests/declarations_cache_tester.py deleted file mode 100644 index 862da48c..00000000 --- a/unittests/declarations_cache_tester.py +++ /dev/null @@ -1,175 +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 os -import unittest -import os.path - -from . import autoconfig -from . import parser_test_case - -from pygccxml.parser.config import xml_generator_configuration_t -from pygccxml.parser import declarations_cache - - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - if not os.path.exists(autoconfig.build_directory): - os.makedirs(autoconfig.build_directory) - - def test_file_signature(self): - file1 = os.path.join(autoconfig.data_directory, 'decl_cache_file1.txt') - file1_dup = os.path.join( - autoconfig.data_directory, - 'decl_cache_file1_duplicate.txt') - file2 = os.path.join(autoconfig.data_directory, 'decl_cache_file2.txt') - sig1 = declarations_cache.file_signature(file1) - sig1_dup = declarations_cache.file_signature(file1_dup) - sig2 = declarations_cache.file_signature(file2) - self.assertTrue(sig1 == sig1_dup) - self.assertTrue(sig1 != sig2) - - def test_config_signature(self): - diff_cfg_list = self.build_differing_cfg_list() - def_cfg = diff_cfg_list[0] - def_sig = declarations_cache.configuration_signature(def_cfg) - - # Test changes that should cause sig changes - for cfg in diff_cfg_list[1:]: - self.assertTrue( - declarations_cache.configuration_signature(cfg) != def_sig) - - # Test changes that should not cause sig changes - no_changes = def_cfg.clone() - self.assertTrue( - declarations_cache.configuration_signature(no_changes) == def_sig) - - # start_decls_changed = def_cfg.clone() - # start_decls_changed.start_with_declarations = "test object" - # self.assertTrue( - # configuration_signature(start_decls_changed) == def_sig) - - ignore_changed = def_cfg.clone() - ignore_changed.ignore_gccxml_output = True - self.assertTrue( - declarations_cache.configuration_signature( - ignore_changed) == def_sig) - - def test_cache_interface(self): - cache_file = os.path.join( - autoconfig.build_directory, - 'decl_cache_test.test_cache_read.cache') - file1 = os.path.join(autoconfig.data_directory, 'decl_cache_file1.txt') - file1_dup = os.path.join( - autoconfig.data_directory, - 'decl_cache_file1_duplicate.txt') - file2 = os.path.join(autoconfig.data_directory, 'decl_cache_file2.txt') - diff_cfg_list = self.build_differing_cfg_list() - def_cfg = diff_cfg_list[0] - - if os.path.exists(cache_file): - os.remove(cache_file) - - cache = declarations_cache.file_cache_t(cache_file) - self.assertTrue(len(cache._file_cache_t__cache) == 0) - - # test creating new entries for differing files - cache.update(file1, def_cfg, 1, []) - self.assertTrue(len(cache._file_cache_t__cache) == 1) - cache.update(file1_dup, def_cfg, 2, []) - self.assertTrue(len(cache._file_cache_t__cache) == 1) - cache.update(file2, def_cfg, 3, []) - self.assertTrue(len(cache._file_cache_t__cache) == 2) - - self.assertTrue(cache.cached_value(file1, def_cfg) == 2) - self.assertTrue(cache.cached_value(file2, def_cfg) == 3) - - # Test reading again - cache.flush() - cache = declarations_cache.file_cache_t(cache_file) - self.assertTrue(len(cache._file_cache_t__cache) == 2) - self.assertTrue(cache.cached_value(file1, def_cfg) == 2) - self.assertTrue(cache.cached_value(file2, def_cfg) == 3) - - # Test flushing doesn't happen if we don't touch the cache - cache = declarations_cache.file_cache_t(cache_file) - self.assertTrue( - cache.cached_value( - file1, def_cfg) == 2) # Read from cache - cache.flush() # should not actually flush - cache = declarations_cache.file_cache_t(cache_file) - self.assertTrue(len(cache._file_cache_t__cache) == 2) - - # Test flush culling - cache = declarations_cache.file_cache_t(cache_file) - cache.update(file1_dup, def_cfg, 4, []) # Modify cache - cache.flush() # should cull off one entry - cache = declarations_cache.file_cache_t(cache_file) - self.assertTrue(len(cache._file_cache_t__cache) == 1) - - @staticmethod - def build_differing_cfg_list(): - """ Return a list of configurations that all differ. """ - cfg_list = [] - def_cfg = xml_generator_configuration_t( - "xml_generator_path", - '.', ['tmp'], ['sym'], ['unsym'], None, False, "") - cfg_list.append(def_cfg) - - # Test changes that should cause sig changes - gccxml_changed = def_cfg.clone() - gccxml_changed.xml_generator_path = "other_path" - cfg_list.append(gccxml_changed) - - wd_changed = def_cfg.clone() - wd_changed.working_directory = "other_dir" - cfg_list.append(wd_changed) - - # inc_changed = def_cfg.clone() - # inc_changed.include_paths = ["/var/tmp"] - # self.assertTrue(configuration_signature(inc_changed) != def_sig) - inc_changed = xml_generator_configuration_t( - "xml_generator_path", '.', ['/var/tmp'], ['sym'], ['unsym'], - None, False, "") - cfg_list.append(inc_changed) - - # def_changed = def_cfg.clone() - # def_changed.define_symbols = ["symbol"] - # self.assertTrue(configuration_signature(def_changed) != def_sig) - def_changed = xml_generator_configuration_t( - "xml_generator_path", '.', ['/var/tmp'], ['new-sym'], ['unsym'], - None, False, "") - cfg_list.append(def_changed) - - # undef_changed = def_cfg.clone() - # undef_changed.undefine_symbols = ["symbol"] - # self.assertTrue(configuration_signature(undef_changed) != def_sig) - undef_changed = xml_generator_configuration_t( - "xml_generator_path", '.', ['/var/tmp'], ['sym'], ['new-unsym'], - None, False, "") - cfg_list.append(undef_changed) - - cflags_changed = def_cfg.clone() - cflags_changed.cflags = "new flags" - cfg_list.append(cflags_changed) - - return cfg_list - - -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/unittests/declarations_comparison_tester.py b/unittests/declarations_comparison_tester.py deleted file mode 100644 index a6a008b4..00000000 --- a/unittests/declarations_comparison_tester.py +++ /dev/null @@ -1,87 +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 copy -import unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -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 = 'declarations_comparison.hpp' - - def test_comparison_declaration_by_declaration(self): - parsed = parser.parse([self.header], self.config) - copied = copy.deepcopy(parsed) - parsed = declarations.make_flatten(parsed) - copied = declarations.make_flatten(copied) - parsed.sort() - copied.sort() - failuers = [] - for parsed_decl, copied_decl, index in \ - zip(parsed, copied, list(range(len(copied)))): - - if parsed_decl != copied_decl: - failuers.append( - ("__lt__ and/or __qe__ does not working " + - "properly in case of %s, %s, index %d") % - (parsed_decl.__class__.__name__, - copied_decl.__class__.__name__, index)) - self.assertTrue(not failuers, 'Failures: ' + '\n\t'.join(failuers)) - - def test_comparison_from_reverse(self): - parsed = parser.parse([self.header], self.config) - copied = copy.deepcopy(parsed) - parsed.sort() - copied.reverse() - copied.sort() - x = parsed[4:6] - x.sort() - y = copied[4:6] - y.sort() - self.assertTrue( - parsed == copied, - "__lt__ and/or __qe__ does not working properly") - - def test___lt__transitivnost(self): - ns_std = declarations.namespace_t(name='std') - ns_global = declarations.namespace_t(name='::') - ns_internal = declarations.namespace_t(name='ns') - ns_internal.parent = ns_global - ns_global.declarations.append(ns_internal) - left2right = [ns_std, ns_global] - right2left = [ns_global, ns_std] - left2right.sort() - right2left.sort() - self.assertTrue(left2right == right2left, "bug: find me") - - def test_same_declarations_different_intances(self): - parsed = parser.parse([self.header], self.config) - copied = copy.deepcopy(parsed) - self.assertTrue( - parsed == copied, - "__lt__ and/or __qe__ does not working properly") - - -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/unittests/declarations_tester.py b/unittests/declarations_tester.py deleted file mode 100644 index 2f1921b9..00000000 --- a/unittests/declarations_tester.py +++ /dev/null @@ -1,344 +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 unittest - -from . import autoconfig -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class declarations_t(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.global_ns = None - - def test_enumeration_t(self): - enum = self.global_ns.enumeration('ENumbers') - expected_values = list( - zip(['e%d' % index for index in range(10)], - [index for index in range(10)])) - self.assertTrue( - expected_values == enum.values, - ("expected enum values ( '%s' ) and existings ( '%s' ) are " + - "different") % - (pprint.pformat(expected_values), pprint.pformat(enum.values))) - - def test_namespace(self): - pass # tested in core_tester - - def test_types(self): - pass # tested in core_tester - - def test_variables(self): - self.global_ns.namespace('variables') - initialized = self.global_ns.variable(name='initialized') - - expected_value = '10122004' - self.assertTrue( - initialized.value == expected_value, - ("there is a difference between expected value( %s ) and real " + - "value(%s) of 'initialized' variable") % - (expected_value, initialized.value)) - self._test_type_composition( - initialized.decl_type, - declarations.const_t, - declarations.long_unsigned_int_t) - - m_mutable = self.global_ns.variable(name="m_mutable") - self.assertFalse( - m_mutable.type_qualifiers.has_static, - "m_mutable must not have static type qualifier") - - self.assertTrue( - m_mutable.type_qualifiers.has_mutable, - "m_mutable must have mutable type qualifier") - - # External static variable - extern_var = self.global_ns.variable(name="extern_var") - self.assertTrue( - extern_var.type_qualifiers.has_extern, - "extern_var must have extern type qualifier") - self.assertFalse( - extern_var.type_qualifiers.has_static, - "extern_var must not have a static type qualifier") - self.assertFalse( - extern_var.type_qualifiers.has_mutable, - "static_var must not have mutable type qualifier") - - # Static variable - static_var = self.global_ns.variable(name="static_var") - self.assertTrue( - static_var.type_qualifiers.has_static, - "static_var must have static type qualifier") - self.assertFalse( - static_var.type_qualifiers.has_extern, - "static_var must not have an extern type qualifier") - self.assertFalse( - static_var.type_qualifiers.has_mutable, - "static_var must not have mutable type qualifier") - - ssv_static_var = self.global_ns.variable(name="ssv_static_var") - self.assertTrue( - ssv_static_var.type_qualifiers.has_static, - "ssv_static_var must have static type qualifier") - self.assertFalse( - ssv_static_var.type_qualifiers.has_extern, - "ssv_static_var must not have an extern type qualifier") - self.assertFalse( - ssv_static_var.type_qualifiers.has_mutable, - "ssv_static_var must not have mutable type qualifier") - - ssv_static_var_value = self.global_ns.variable( - name="ssv_static_var_value") - self.assertTrue( - ssv_static_var_value.type_qualifiers.has_static, - "ssv_static_var_value must have static type qualifier") - self.assertFalse( - ssv_static_var_value.type_qualifiers.has_extern, - "ssv_static_var_value must not have an extern type qualifier") - self.assertFalse( - ssv_static_var_value.type_qualifiers.has_mutable, - "ssv_static_var_value must not have mutable type qualifier") - - def test_calldef_free_functions(self): - ns = self.global_ns.namespace('calldef') - - no_return_no_args = ns.free_function('no_return_no_args') - - self._test_calldef_return_type(no_return_no_args, declarations.void_t) - self.assertTrue( - not no_return_no_args.has_extern, - "function 'no_return_no_args' should have an extern qualifier") - - # Static_call is explicetely defined as extern, this works with gccxml - # and castxml. - static_call = ns.free_function('static_call') - self.assertTrue( - static_call, - "function 'no_return_no_args' should have an extern qualifier") - - return_no_args = ns.free_function('return_no_args') - self._test_calldef_return_type(return_no_args, declarations.int_t) - # from now there is no need to check return type. - no_return_1_arg = ns.free_function(name='no_return_1_arg') - self.assertTrue( - no_return_1_arg, - "unable to find 'no_return_1_arg' function") - self.assertTrue(no_return_1_arg.arguments[0].name in ['arg', 'arg0']) - self._test_calldef_args( - no_return_1_arg, - [declarations.argument_t( - name=no_return_1_arg.arguments[0].name, - decl_type=declarations.int_t())]) - - return_default_args = ns.free_function('return_default_args') - self.assertTrue( - return_default_args.arguments[0].name in ['arg', 'arg0']) - self.assertTrue( - return_default_args.arguments[1].name in ['arg1', 'flag']) - self._test_calldef_args( - return_default_args, - [declarations.argument_t( - name=return_default_args.arguments[0].name, - decl_type=declarations.int_t(), - default_value='1'), - declarations.argument_t( - name=return_default_args.arguments[1].name, - decl_type=declarations.bool_t(), - default_value='false')]) - self._test_calldef_exceptions(return_default_args, []) - - calldef_with_throw = ns.free_function('calldef_with_throw') - self.assertTrue( - calldef_with_throw, - "unable to find 'calldef_with_throw' function") - self._test_calldef_exceptions( - calldef_with_throw, [ - 'some_exception_t', 'other_exception_t']) - # from now there is no need to check exception specification - - def test_calldef_member_functions(self): - struct_calldefs = self.global_ns.class_('calldefs_t') - - member_inline_call = struct_calldefs.member_function( - 'member_inline_call') - self._test_calldef_args( - member_inline_call, [ - declarations.argument_t( - name='i', decl_type=declarations.int_t())]) - - member_const_call = struct_calldefs.member_function( - 'member_const_call') - self.assertTrue( - member_const_call.has_const, - "function 'member_const_call' should have const qualifier") - self.assertTrue( - member_const_call.virtuality == - declarations.VIRTUALITY_TYPES.NOT_VIRTUAL, - "function 'member_const_call' should be non virtual function") - - member_virtual_call = struct_calldefs.member_function( - name='member_virtual_call') - self.assertTrue( - member_virtual_call.virtuality == - declarations.VIRTUALITY_TYPES.VIRTUAL, - "function 'member_virtual_call' should be virtual function") - - member_pure_virtual_call = struct_calldefs.member_function( - 'member_pure_virtual_call') - self.assertTrue( - member_pure_virtual_call.virtuality == - declarations.VIRTUALITY_TYPES.PURE_VIRTUAL, - ("function 'member_pure_virtual_call' should be pure virtual " + - "function")) - - static_call = struct_calldefs.member_function('static_call') - self.assertTrue( - static_call.has_static, - "function 'static_call' should have static qualifier") - # from now we there is no need to check static qualifier - - def test_constructors_destructors(self): - struct_calldefs = self.global_ns.class_('calldefs_t') - - destructor = struct_calldefs.calldef('~calldefs_t') - self._test_calldef_args(destructor, []) - self._test_calldef_return_type(destructor, None.__class__) - - # well, now we have a few functions ( constructors ) with the same - # name, there is no easy way to find the desired one. Well in my case - # I have only 4 constructors - # 1. from char - # 2. from (int,double) - # 3. default - # 4. copy constructor - constructor_found = struct_calldefs.constructors('calldefs_t') - self.assertTrue( - len(constructor_found) == 5, - ("struct 'calldefs_t' has 5 constructors, pygccxml parser " + - "reports only about %d.") % - len(constructor_found)) - error_text = "copy constructor has not been found" - self.assertTrue(1 == len( - [constructor for constructor in constructor_found if - declarations.is_copy_constructor(constructor)]), error_text) - # there is nothing to check about constructors - I know the - # implementation of parser. - # In this case it doesn't different from any other function - - c = struct_calldefs.constructor('calldefs_t', arg_types=['char']) - self.assertTrue( - c.explicit, - ("calldef_t constructor defined with 'explicit' keyword, " + - "for some reason the value is False ")) - - arg_type = declarations.declarated_t( - self.global_ns.class_('some_exception_t')) - c = struct_calldefs.constructor('calldefs_t', arg_types=[arg_type]) - self.assertTrue( - c.explicit is False, - ("calldef_t constructor defined without 'explicit' keyword, " + - "for some reason the value is True ")) - - def test_operator_symbol(self): - calldefs_operators = ['=', '=='] - calldefs_cast_operators = ['char *', 'double'] - struct_calldefs = self.global_ns.class_('calldefs_t') - self.assertTrue(struct_calldefs, "unable to find struct 'calldefs_t'") - for decl in struct_calldefs.declarations: - if not isinstance(decl, declarations.operator_t): - continue - if not isinstance(decl, declarations.casting_operator_t): - self.assertTrue( - decl.symbol in calldefs_operators, - "unable to find operator symbol for operator '%s'" % - decl.decl_string) - else: - self.assertTrue( - decl.return_type.decl_string in calldefs_cast_operators, - "unable to find operator symbol for operator '%s'" % - decl.decl_string) - - def test_ellipsis(self): - ns = self.global_ns.namespace('ellipsis_tester') - do_smth = ns.member_function('do_smth') - self.assertTrue(do_smth.has_ellipsis) - do_smth_else = ns.free_function('do_smth_else') - self.assertTrue(do_smth_else.has_ellipsis) - - -class gccxml_declarations_t(declarations_t): - global_ns = None - - def __init__(self, *args): - declarations_t.__init__(self, *args) - self.test_files = [ - 'declarations_enums.hpp', - 'declarations_variables.hpp', - 'declarations_calldef.hpp'] - self.global_ns = None - - def setUp(self): - if not gccxml_declarations_t.global_ns: - decls = parser.parse( - self.test_files, - self.config, - self.COMPILATION_MODE) - gccxml_declarations_t.global_ns = \ - declarations.get_global_namespace(decls) - gccxml_declarations_t.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - if not self.global_ns: - self.xml_generator_from_xml_file = \ - gccxml_declarations_t.xml_generator_from_xml_file - self.global_ns = gccxml_declarations_t.global_ns - - -class all_at_once_tester_t(gccxml_declarations_t): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE - - def __init__(self, *args): - gccxml_declarations_t.__init__(self, *args) - - -class file_by_file_tester_t(gccxml_declarations_t): - COMPILATION_MODE = parser.COMPILATION_MODE.FILE_BY_FILE - - def __init__(self, *args): - gccxml_declarations_t.__init__(self, *args) - - -class pdb_based_tester_t(declarations_t): - - def __init__(self, *args): - declarations_t.__init__(self, *args) - self.global_ns = autoconfig.get_pdb_global_ns() - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=file_by_file_tester_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=all_at_once_tester_t)) - # if os.name == 'nt' and autoconfig.get_pdb_global_ns(): - # suite.addTest( unittest.makeSuite(pdb_based_tester_t)) - - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/dependencies_tester.py b/unittests/dependencies_tester.py deleted file mode 100644 index 7edc359f..00000000 --- a/unittests/dependencies_tester.py +++ /dev/null @@ -1,183 +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 unittest -import warnings - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'include_all.hpp' - self.global_ns = None - - def setUp(self): - if not Test.global_ns: - decls = parser.parse([self.header], self.config) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - Test.global_ns = declarations.get_global_namespace(decls) - Test.global_ns.init_optimizer() - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - self.global_ns = Test.global_ns - - def test_variable(self): - ns_vars = self.global_ns.namespace('::declarations::variables') - static_var = ns_vars.variable('static_var') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = static_var.i_depend_on_them() - warnings.simplefilter("error", Warning) - self.assertTrue(len(dependencies_old) == 1) - self.assertTrue(dependencies_old[0].declaration is static_var) - self.assertTrue(dependencies_old[0].depend_on_it.decl_string == 'int') - - dependencies_new = declarations.get_dependencies_from_decl(static_var) - self.assertTrue(len(dependencies_new) == 1) - self.assertTrue(dependencies_new[0].declaration is static_var) - self.assertTrue(dependencies_new[0].depend_on_it.decl_string == 'int') - - m_mutable = ns_vars.variable('m_mutable') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = m_mutable.i_depend_on_them() - warnings.simplefilter("error", Warning) - self.assertTrue(len(dependencies_old) == 1) - self.assertTrue(dependencies_old[0].declaration is m_mutable) - self.assertTrue(dependencies_old[0].depend_on_it.decl_string == 'int') - - dependencies_new = declarations.get_dependencies_from_decl(m_mutable) - self.assertTrue(len(dependencies_new) == 1) - self.assertTrue(dependencies_new[0].declaration is m_mutable) - self.assertTrue(dependencies_new[0].depend_on_it.decl_string == 'int') - - def test_class(self): - ns_vars = self.global_ns.namespace('::declarations::variables') - - cls = ns_vars.class_('struct_variables_t') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = cls.i_depend_on_them() - warnings.simplefilter("error", Warning) - dependencies_old = [ - d for d in dependencies_old if not d.declaration.is_artificial] - self.assertTrue(len(dependencies_old) == 1) - - dependencies_new = declarations.get_dependencies_from_decl(cls) - dependencies_new = [ - d for d in dependencies_new if not d.declaration.is_artificial] - self.assertTrue(len(dependencies_new) == 1) - - m_mutable = ns_vars.variable('m_mutable') - - # Legacy way of fetching dependencies. Is still valid but deprecated - dependencies_old = [ - dependency for dependency in dependencies_old if - dependency.declaration is m_mutable] - self.assertTrue(len(dependencies_old) == 1) - self.assertTrue(dependencies_old[0].depend_on_it.decl_string == 'int') - self.assertTrue(dependencies_old[0].access_type == 'public') - - dependencies_new = [ - dependency for dependency in dependencies_new if - dependency.declaration is m_mutable] - self.assertTrue(len(dependencies_new) == 1) - self.assertTrue(dependencies_new[0].depend_on_it.decl_string == 'int') - self.assertTrue(dependencies_new[0].access_type == 'public') - - ns_dh = self.global_ns.namespace('::core::diamand_hierarchy') - fd_cls = ns_dh.class_('final_derived_t') - derived1_cls = ns_dh.class_('derived1_t') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = declarations.get_dependencies_from_decl(fd_cls) - warnings.simplefilter("error", Warning) - dependencies_old = [ - dependency for dependency in dependencies_old if - dependency.depend_on_it is derived1_cls] - self.assertTrue(len(dependencies_old) == 1) - self.assertTrue(dependencies_old[0].depend_on_it is derived1_cls) - self.assertTrue(dependencies_old[0].access_type == 'public') - - dependencies_new = declarations.get_dependencies_from_decl(fd_cls) - dependencies_new = [ - dependency for dependency in dependencies_new if - dependency.depend_on_it is derived1_cls] - self.assertTrue(len(dependencies_new) == 1) - self.assertTrue(dependencies_new[0].depend_on_it is derived1_cls) - self.assertTrue(dependencies_new[0].access_type == 'public') - - def test_calldefs(self): - ns = self.global_ns.namespace('::declarations::calldef') - return_default_args = ns.calldef('return_default_args') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = return_default_args.i_depend_on_them() - warnings.simplefilter("error", Warning) - self.assertTrue(len(dependencies_old) == 3) - used_types = [ - dependency.depend_on_it.decl_string - for dependency in dependencies_old] - self.assertTrue(used_types == ['int', 'int', 'bool']) - - dependencies_new = declarations.get_dependencies_from_decl( - return_default_args) - self.assertTrue(len(dependencies_new) == 3) - used_types = [ - dependency.depend_on_it.decl_string - for dependency in dependencies_new] - self.assertTrue(used_types == ['int', 'int', 'bool']) - - some_exception = ns.class_('some_exception_t') - other_exception = ns.class_('other_exception_t') - calldef_with_throw = ns.calldef('calldef_with_throw') - - # Legacy way of fetching dependencies. Is still valid but deprecated - warnings.simplefilter("ignore", Warning) - dependencies_old = calldef_with_throw.i_depend_on_them() - warnings.simplefilter("error", Warning) - self.assertTrue(len(dependencies_old) == 3) - dependencies_old = [ - dependency for dependency in dependencies_old if - dependency.depend_on_it in (some_exception, other_exception)] - self.assertTrue(len(dependencies_old) == 2) - - dependencies_new = declarations.get_dependencies_from_decl( - calldef_with_throw) - self.assertTrue(len(dependencies_new) == 3) - dependencies_new = [ - dependency for dependency in dependencies_new if - dependency.depend_on_it in (some_exception, other_exception)] - self.assertTrue(len(dependencies_new) == 2) - - def test_coverage(self): - declarations.get_dependencies_from_decl(self.global_ns) - - -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/unittests/deprecation_tester.py b/unittests/deprecation_tester.py deleted file mode 100644 index 6d2180ef..00000000 --- a/unittests/deprecation_tester.py +++ /dev/null @@ -1,36 +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 unittest - -from . import parser_test_case - - -class Test(parser_test_case.parser_test_case_t): - - """ - Used to test deprecated methods/functions. Does nothing for the moment. - """ - - @staticmethod - def _check(w): - assert len(w) == 1 - assert issubclass(w[-1].category, DeprecationWarning) - assert "deprecated" in str(w[-1].message) - - -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/unittests/example_tester.py b/unittests/example_tester.py deleted file mode 100644 index 7347d684..00000000 --- a/unittests/example_tester.py +++ /dev/null @@ -1,63 +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 os -import fnmatch -import unittest -import subprocess - -from . import parser_test_case - - -class Test(parser_test_case.parser_test_case_t): - - def test_example(self): - """Runs the example in the docs directory""" - - env = os.environ.copy() - - # 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() diff --git a/unittests/file_cache_tester.py b/unittests/file_cache_tester.py deleted file mode 100644 index e03b0072..00000000 --- a/unittests/file_cache_tester.py +++ /dev/null @@ -1,98 +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 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( - 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() diff --git a/unittests/filters_tester.py b/unittests/filters_tester.py deleted file mode 100644 index e3d4d747..00000000 --- a/unittests/filters_tester.py +++ /dev/null @@ -1,104 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -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() diff --git a/unittests/find_container_traits_tester.py b/unittests/find_container_traits_tester.py deleted file mode 100644 index 1571c373..00000000 --- a/unittests/find_container_traits_tester.py +++ /dev/null @@ -1,208 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.headers = ['remove_template_defaults.hpp', 'indexing_suites2.hpp'] - - def setUp(self): - if not Test.global_ns: - decls = parser.parse(self.headers, 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.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - self.global_ns = Test.global_ns - - def __cmp_traits(self, typedef, expected, partial_name, key_type=None): - if isinstance(typedef, str): - typedef = self.global_ns.typedef(typedef) - traits = declarations.find_container_traits(typedef) - self.assertTrue( - traits, - 'container traits for "%s" not found' % - str(typedef)) - self.assertTrue( - traits is expected, - 'container "%s", expected %s_traits, got %s_traits' % - (str(typedef), - expected.name(), - traits.name())) - cls = declarations.remove_declarated(typedef) - self.assertTrue(declarations.find_container_traits(cls) is expected) - self.assertTrue(cls.partial_name == partial_name) - cls = traits.class_declaration(cls) - - self.assertTrue(traits.element_type(typedef)) - self.assertTrue( - cls.cache.container_element_type, - "For some reason cache was not updated") - - if key_type: - self.assertTrue(traits.is_mapping(typedef)) - real_key_type = traits.key_type(typedef) - self.assertTrue( - real_key_type.decl_string == key_type, - 'Error extracting key type. Expected type "%s", got "%s"' % - (key_type, - real_key_type.decl_string)) - self.assertTrue( - cls.cache.container_key_type, - "For some reason cache was not updated") - else: - self.assertTrue(traits.is_sequence(typedef)) - - def test_find_traits(self): - self.__cmp_traits('v_int', declarations.vector_traits, "vector< int >") - self.__cmp_traits('l_int', declarations.list_traits, "list< int >") - self.__cmp_traits( - 'd_v_int', - declarations.deque_traits, - "deque< std::vector< int > >") - self.__cmp_traits('q_int', declarations.queue_traits, "queue< int >") - self.__cmp_traits( - 'pq_int', - declarations.priority_queue_traits, - "priority_queue< int >") - self.__cmp_traits( - 's_v_int', - declarations.set_traits, - "set< std::vector< int > >") - self.__cmp_traits( - 'ms_v_int', - declarations.multiset_traits, - "multiset< std::vector< int > >") - self.__cmp_traits( - 'm_i2d', - declarations.map_traits, - "map< int, double >", - 'int') - self.__cmp_traits( - 'mm_i2d', - declarations.multimap_traits, - "multimap< int, double >", - 'int') - - if self.xml_generator_from_xml_file.is_castxml: - self.__cmp_traits( - 'hs_v_int', - declarations.unordered_set_traits, - "unordered_set< std::vector< int > >") - else: - self.__cmp_traits( - 'hs_v_int', - declarations.hash_set_traits, - "hash_set< std::vector< int > >") - - if self.xml_generator_from_xml_file.is_castxml: - self.__cmp_traits( - 'mhs_v_int', - declarations.unordered_multiset_traits, - "unordered_multiset< std::vector< int > >") - else: - self.__cmp_traits( - 'mhs_v_int', - declarations.hash_multiset_traits, - "hash_multiset< std::vector< int > >") - - if self.xml_generator_from_xml_file.is_castxml: - self.__cmp_traits( - 'hm_i2d', - declarations.unordered_map_traits, - "unordered_map< int, double >", - 'int') - else: - self.__cmp_traits( - 'hm_i2d', - declarations.hash_map_traits, - "hash_map< int, double >", - 'int') - - if self.xml_generator_from_xml_file.is_castxml: - self.__cmp_traits( - 'hmm_i2d', - declarations.unordered_multimap_traits, - "unordered_multimap< int, double >", - 'int') - else: - self.__cmp_traits( - 'hmm_i2d', - declarations.hash_multimap_traits, - "hash_multimap< int, double >", - 'int') - - def test_multimap(self): - m = self.global_ns.class_( - lambda decl: decl.name.startswith('multimap')) - declarations.find_container_traits(m) - self.assertTrue(m.partial_name == 'multimap< int, int >') - - def test_recursive_partial_name(self): - f1 = self.global_ns.free_function('f1') - t1 = declarations.class_traits.get_declaration( - f1.arguments[0].decl_type) - self.assertTrue( - 'type< std::set< std::vector< int > > >' == t1.partial_name) - - def test_remove_defaults_partial_name_namespace(self): - f2 = self.global_ns.free_function('f2') - type_info = f2.return_type - traits = declarations.find_container_traits(type_info) - cls = traits.class_declaration(type_info) - # traits.remove_defaults(type_info) - decl_string = cls.partial_decl_string - key_type_string = traits.key_type(type_info).partial_decl_string - self.assertTrue( - decl_string.startswith('::std::'), - "declaration string %r doesn't start with 'std::'" % - decl_string) - self.assertTrue( - key_type_string.startswith('::std::'), - "key type string %r doesn't start with 'std::'" % - key_type_string) - - @staticmethod - def test_from_ogre(): - x = ( - 'map, ' + - 'std::allocator > >') - ct = declarations.find_container_traits(x) - ct.remove_defaults(x) - - def test_infinite_loop(self): - rt = self.global_ns.free_function('test_infinite_loop').return_type - map_traits = declarations.find_container_traits(rt) - self.assertTrue(map_traits is declarations.map_traits) - elem = map_traits.element_type(rt) - self.assertTrue(elem.decl_string == 'int') - - -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/unittests/free_operators_tester.py b/unittests/free_operators_tester.py deleted file mode 100644 index 936b63f1..00000000 --- a/unittests/free_operators_tester.py +++ /dev/null @@ -1,49 +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 unittest - -from . import parser_test_case - -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 = '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) - - 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() diff --git a/unittests/function_traits_tester.py b/unittests/function_traits_tester.py deleted file mode 100644 index 63135210..00000000 --- a/unittests/function_traits_tester.py +++ /dev/null @@ -1,51 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - global_ns = None - - 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(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') - - 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() diff --git a/unittests/gccxml10184_tester.py b/unittests/gccxml10184_tester.py deleted file mode 100644 index 1469dc27..00000000 --- a/unittests/gccxml10184_tester.py +++ /dev/null @@ -1,48 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - -code = \ - """ -class A { -public: - virtual ~A() = 0; - unsigned int a : 1; - unsigned int unused : 31; -}; -""" - - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - - def test(self): - decls = parser.parse_string(code, self.config) - global_ns = declarations.get_global_namespace(decls) - self.assertTrue(global_ns.variable('a').bits == 1) - self.assertTrue(global_ns.variable('unused').bits == 31) - - -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/unittests/gccxml10185_tester.py b/unittests/gccxml10185_tester.py deleted file mode 100644 index 9a6ba293..00000000 --- a/unittests/gccxml10185_tester.py +++ /dev/null @@ -1,60 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - -code = \ - """ -template struct A {}; -template struct A -{ static int size(const char[N]) { return N - 1; } }; -""" - - -class Test(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - - def test(self): - """ - The purpose of this test was to check if changes to GCCXML - would lead to changes in the outputted xml file (Meaning - the bug was fixed). - - GCCXML wrongly outputted partial template specialization. - CastXML does not have this bug. In this case we check if - the template specialization can not be found; which is the - expected/wanted behaviour. - - https://github.com/CastXML/CastXML/issues/20 - - """ - - decls = parser.parse_string(code, self.config) - global_ns = declarations.get_global_namespace(decls) - self.assertRaises( - declarations.declaration_not_found_t, - lambda: global_ns.class_('A')) - - -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/unittests/gccxml_runner_tester.py b/unittests/gccxml_runner_tester.py deleted file mode 100644 index 423c1c40..00000000 --- a/unittests/gccxml_runner_tester.py +++ /dev/null @@ -1,41 +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 os -import unittest - -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.content = "abra cadabra " + os.linesep - - def test_gccxml_on_input_with_errors(self): - self.assertRaises( - RuntimeError, - parser.parse_string, - self.content, - self.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() diff --git a/unittests/has_binary_operator_traits_tester.py b/unittests/has_binary_operator_traits_tester.py deleted file mode 100644 index 699b15c7..00000000 --- a/unittests/has_binary_operator_traits_tester.py +++ /dev/null @@ -1,74 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - 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 = 'has_public_binary_operator_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 test_yes_equal(self): - yes_ns = self.global_ns.namespace('yesequal') - for typedef in yes_ns.typedefs(): - self.assertTrue( - declarations.has_public_equal(typedef), - "Class '%s' should have public operator==" % - typedef.decl_string) - - def test_no_equal(self): - no_ns = self.global_ns.namespace('noequal') - for typedef in no_ns.typedefs(): - self.assertTrue( - not declarations.has_public_equal(typedef), - "Class '%s' should not have public operator==" % - typedef.decl_string) - - def test_yes_less(self): - yes_ns = self.global_ns.namespace('yesless') - for typedef in yes_ns.typedefs(): - self.assertTrue( - declarations.has_public_less(typedef), - "Class '%s' should have public operator<" % - typedef.decl_string) - - def test_no_less(self): - no_ns = self.global_ns.namespace('noless') - for typedef in no_ns.typedefs(): - self.assertTrue( - not declarations.has_public_less(typedef), - "Class '%s' should not have public operator<" % - typedef.decl_string) - - -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/unittests/hierarchy_traveling.py b/unittests/hierarchy_traveling.py deleted file mode 100644 index 06737725..00000000 --- a/unittests/hierarchy_traveling.py +++ /dev/null @@ -1,91 +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 os -import unittest - -from . import parser_test_case - -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.__code = os.linesep.join(['struct a{};', - 'struct b{};', - 'struct c{};', - 'struct d : public a{};', - 'struct e : public a, public b{};', - 'struct f{};', - 'struct g : public d, public f{};', - 'struct h : public f{};', - 'struct i : public h, public g{};']) - - self.__recursive_bases = {'a': set(), - 'b': set(), - 'c': set(), - 'd': {'a'}, - 'e': {'a', 'b'}, - 'f': set(), - 'g': {'d', 'f', 'a'}, - 'h': {'f'}, - 'i': {'h', 'g', 'd', 'f', 'a'}} - - self.__recursive_derived = { - 'a': {'d', 'e', 'g', 'i'}, - 'b': {'e'}, - 'c': set(), - 'd': {'g', 'i'}, - 'e': set(), - 'f': {'g', 'h', 'i'}, - 'g': {'i'}, - 'h': {'i'}, - 'i': set()} - - def test_recursive_bases(self): - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) - classes = [ - inst for inst in decls if isinstance(inst, declarations.class_t)] - for class_ in classes: - self.assertTrue(class_.name in self.__recursive_bases) - all_bases = class_.recursive_bases - control_bases = self.__recursive_bases[class_.name] - self.assertTrue(len(control_bases) == len(all_bases)) - all_bases_names = [hi.related_class.name for hi in all_bases] - self.assertTrue(set(all_bases_names) == control_bases) - - def test_recursive_derived(self): - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) - classes = [ - inst for inst in decls if isinstance( - inst, - declarations.class_t)] - for class_ in classes: - self.assertTrue(class_.name in self.__recursive_derived) - all_derived = class_.recursive_derived - control_derived = self.__recursive_derived[class_.name] - self.assertTrue(len(control_derived) == len(all_derived)) - all_derived_names = [hi.related_class.name for hi in all_derived] - self.assertTrue(set(all_derived_names) == control_derived) - - -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/unittests/inline_specifier_tester.py b/unittests/inline_specifier_tester.py deleted file mode 100644 index dfc3e420..00000000 --- a/unittests/inline_specifier_tester.py +++ /dev/null @@ -1,55 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'inline_specifier.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(self): - inlined_funcs = self.global_ns.calldefs('inlined') - self.assertTrue(len(inlined_funcs)) - for f in inlined_funcs: - self.assertTrue(f.has_inline) - - not_inlined_funcs = self.global_ns.calldefs('not_inlined') - self.assertTrue(len(not_inlined_funcs)) - for f in not_inlined_funcs: - self.assertTrue(f.has_inline is False) - - def test2(self): - 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/unittests/namespace_matcher_tester.py b/unittests/namespace_matcher_tester.py deleted file mode 100644 index 9c1b1c7b..00000000 --- a/unittests/namespace_matcher_tester.py +++ /dev/null @@ -1,72 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -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 = '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.namespace_matcher_t(name='bit_fields') - declarations.matcher.get_single(criteria, self.declarations) - self.assertTrue( - str(criteria) == '(decl type==namespace_t) and (name==bit_fields)') - - def test_allow_empty(self): - global_ns = declarations.get_global_namespace(self.declarations) - global_ns.init_optimizer() - self.assertTrue( - 0 == len(global_ns.namespaces('does not exist', allow_empty=True))) - - -class unnamed_ns_tester_t(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 = 'unnamed_ns_bug.hpp' - self.declarations = None - - def setUp(self): - if not self.declarations: - self.declarations = parser.parse([self.header], self.config) - - def test(self): - declarations.matcher.get_single( - declarations.namespace_matcher_t(name='::'), self.declarations) - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=Test)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=unnamed_ns_tester_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/non_copyable_classes_tester.py b/unittests/non_copyable_classes_tester.py deleted file mode 100644 index e9405a5d..00000000 --- a/unittests/non_copyable_classes_tester.py +++ /dev/null @@ -1,79 +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 unittest - -from . import parser_test_case - -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 = 'non_copyable_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() - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - def test(self): - - """ - Search for classes which can not be copied. - - See bug #13 - - 1) non copyable class - 2) non copyable const variable (fundamental type) - 3) non copyable const variable (class type) - 4) non copyable const variable (array type) - 5) non copyable const variable (class type) - - """ - - main_foo_1 = self.global_ns.class_('MainFoo1') - self.assertTrue(declarations.is_noncopyable(main_foo_1)) - - main_foo_2 = self.global_ns.class_('MainFoo2') - self.assertTrue(declarations.is_noncopyable(main_foo_2)) - - main_foo_3 = self.global_ns.class_('MainFoo3') - self.assertTrue(declarations.is_noncopyable(main_foo_3)) - - main_foo_4 = self.global_ns.class_('MainFoo4') - self.assertTrue(declarations.is_noncopyable(main_foo_4)) - - main_foo_5 = self.global_ns.class_('MainFoo5') - self.assertTrue(declarations.is_noncopyable(main_foo_5)) - - if self.xml_generator_from_xml_file.is_castxml: - # CastXML only test - # MainFoo6 is copyable - main_foo_6 = self.global_ns.class_('MainFoo6') - self.assertFalse(declarations.is_noncopyable(main_foo_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() diff --git a/unittests/parser_test_case.py b/unittests/parser_test_case.py deleted file mode 100644 index b0584774..00000000 --- a/unittests/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/unittests/patcher_tester.py b/unittests/patcher_tester.py deleted file mode 100644 index a0369d82..00000000 --- a/unittests/patcher_tester.py +++ /dev/null @@ -1,240 +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 os -import unittest -import platform - -from . import autoconfig -from . import parser_test_case - -from pygccxml import utils -from pygccxml import parser - - -class tester_impl_t(parser_test_case.parser_test_case_t): - - def __init__(self, architecture, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.architecture = architecture - self.global_ns = None - self.__cxx_std = utils.cxx_standard(self.config.cflags) - - def test_enum_patcher(self): - fix_enum = self.global_ns.free_function("fix_enum") - default_val = fix_enum.arguments[0].default_value - if self.__cxx_std.is_cxx11_or_greater: - val = "::ns1::ns2::fruit::apple" - else: - val = "::ns1::ns2::apple" - self.assertEqual(default_val, val) - - if 32 == self.architecture or \ - self.xml_generator_from_xml_file.is_castxml: - fix_enum2 = self.global_ns.free_function("fix_enum2") - default_val = fix_enum2.arguments[0].default_value - self.assertEqual(default_val, val) - - ns1 = self.global_ns.namespace("ns1") - ns2 = ns1.namespace("ns2") - fix_enum2 = ns2.free_function("fix_enum2") - default_val = fix_enum2.arguments[0].default_value - self.assertEqual(default_val, val) - - fix_enum3 = self.global_ns.free_function("fix_enum3") - default_val = fix_enum3.arguments[0].default_value - val = val.replace("apple", "orange") - self.assertEqual(default_val, val) - - if self.__cxx_std.is_cxx11_or_greater: - fix_enum4 = self.global_ns.free_function("fix_enum4") - default_val = fix_enum4.arguments[0].default_value - self.assertEqual(default_val, "::ns4::color::blue") - - fix_enum5 = self.global_ns.free_function("fix_enum5") - default_val = fix_enum5.arguments[0].default_value - self.assertEqual(default_val, "::ns4::color::blue") - - lpe = self.global_ns.free_function("log_priority_enabled") - default_val = lpe.arguments[0].default_value - if self.__cxx_std.is_cxx11_or_greater: - val = "(long int)" + \ - "(::ACE_Log_Priority_Index::LM_INVALID_BIT_INDEX)" - else: - val = "(long int)(::LM_INVALID_BIT_INDEX)" - self.assertEqual(default_val, val) - - def test_numeric_patcher(self): - fix_numeric = self.global_ns.free_function("fix_numeric") - if 32 == self.architecture: - val = "0xffffffffffffffff" - self.assertEqual( - fix_numeric.arguments[0].default_value, val) - else: - generator = self.xml_generator_from_xml_file - if generator.is_castxml1 or \ - float(generator.xml_output_version) >= 1.137: - val = "(unsigned long long)-1" - else: - val = "(ull)-1" - self.assertEqual( - fix_numeric.arguments[0].default_value, val) - - def test_unqualified_integral_patcher(self): - if 32 != self.architecture: - # For this check to be removed, patcher_tester_64bit.xml - # will need to be updated for CastXML - return - - ns1 = self.global_ns.namespace("ns1") - st1 = ns1.class_("st1") - fun1 = st1.member_function("fun1") - output_verion = self.xml_generator_from_xml_file.xml_output_version - if self.xml_generator_from_xml_file.is_castxml1 or \ - float(output_verion) >= 1.137: - val1 = "ns1::DEFAULT_1" - val2 = "ns1::st1::DEFAULT_2" - else: - val1 = "::ns1::DEFAULT_1" - val2 = "::ns1::st1::DEFAULT_2" - self.assertEqual( - fun1.arguments[0].default_value, val1) - self.assertEqual( - fun1.arguments[1].default_value, val2) - - fun2 = self.global_ns.free_function("fun2") - self.assertEqual( - fun2.arguments[0].default_value, - "::DEFAULT_1") - output_verion = self.xml_generator_from_xml_file.xml_output_version - if self.xml_generator_from_xml_file.is_castxml1 or \ - float(output_verion) >= 1.137: - val1 = "ns1::DEFAULT_1" - val2 = "ns1::st1::DEFAULT_2" - else: - # Before XML output version 1.137, the following two - # were unpatched and were identical to the text in - # matcher.hpp - val1 = "ns1::DEFAULT_1" - val2 = "::ns1::st1::DEFAULT_2" - self.assertEqual( - fun2.arguments[1].default_value, val1) - self.assertEqual( - fun2.arguments[2].default_value, val2) - - def test_unnamed_enum_patcher(self): - fix_unnamed = self.global_ns.free_function("fix_unnamed") - self.assertEqual( - fix_unnamed.arguments[0].default_value, "int(::fx::unnamed)") - - def test_function_call_patcher(self): - fix_function_call = self.global_ns.free_function("fix_function_call") - default_val = fix_function_call.arguments[0].default_value - output_verion = self.xml_generator_from_xml_file.xml_output_version - if self.xml_generator_from_xml_file.is_castxml1 or \ - float(output_verion) >= 1.137: - val = "function_call::calc(1, 2, 3)" - else: - val = "calc(1, 2, 3)" - self.assertEqual(default_val, val) - - def test_fundamental_patcher(self): - fcall = self.global_ns.free_function("fix_fundamental") - if self.__cxx_std.is_cxx11_or_greater: - val = "(unsigned int)(::fundamental::spam::eggs)" - else: - val = "(unsigned int)(::fundamental::eggs)" - self.assertEqual( - fcall.arguments[0].default_value, val) - - def test_constructor_patcher(self): - typedef__func = self.global_ns.free_function("typedef__func") - default_val = typedef__func.arguments[0].default_value - val = "typedef_::alias()" - self.assertEqual(default_val, val) - if 32 == self.architecture: - clone_tree = self.global_ns.free_function("clone_tree") - default_values = [ - ("vector," + - " std::allocator >,std::allocator" + - ", " + - "std::allocator > > >()"), - ("vector," + - "std::allocator >,std::allocator" + - ", " + - "std::allocator > > >((&allocator" + - ", " + - "std::allocator > >()))")] - self.assertIn( - clone_tree.arguments[0].default_value, default_values) - - -class tester_32_t(tester_impl_t): - global_ns = None - - def __init__(self, *args): - tester_impl_t.__init__(self, 32, *args) - - def setUp(self): - if not tester_32_t.global_ns: - reader = parser.source_reader_t(self.config) - tester_32_t.global_ns = reader.read_file( - "patcher.hpp")[0].top_parent - tester_32_t.xml_generator_from_xml_file = \ - reader.xml_generator_from_xml_file - self.global_ns = tester_32_t.global_ns - self.xml_generator_from_xml_file = \ - tester_32_t.xml_generator_from_xml_file - - -class tester_64_t(tester_impl_t): - global_ns = None - - def __init__(self, *args): - tester_impl_t.__init__(self, 64, *args) - self.original_get_architecture = utils.get_architecture - - def setUp(self): - self.original_get_architecture = utils.get_architecture - utils.get_architecture = lambda: 64 - - if not tester_64_t.global_ns: - reader = parser.source_reader_t(self.config) - if "castxml" not in self.config.xml_generator: - tester_64_t.global_ns = reader.read_xml_file( - os.path.join( - autoconfig.data_directory, - "patcher_tester_64bit.xml"))[0].top_parent - else: - tester_64_t.global_ns = reader.read_file( - "patcher.hpp")[0].top_parent - tester_64_t.xml_generator_from_xml_file = \ - reader.xml_generator_from_xml_file - self.global_ns = tester_64_t.global_ns - self.xml_generator_from_xml_file = \ - tester_64_t.xml_generator_from_xml_file - - def tearDown(self): - utils.get_architecture = self.original_get_architecture - - -def create_suite(): - suite = unittest.TestSuite() - if "castxml" not in autoconfig.cxx_parsers_cfg.config.xml_generator: - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=tester_32_t)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase( - testCaseClass=tester_64_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/plain_c_tester.py b/unittests/plain_c_tester.py deleted file mode 100644 index 1014d46e..00000000 --- a/unittests/plain_c_tester.py +++ /dev/null @@ -1,47 +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 unittest - -from . import parser_test_case - -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 = 'plain_c.c' - 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): - self.global_ns.free_function('hello_sum') - self.global_ns.free_function('hello_print') - f = self.global_ns.free_function('do_smth') - for arg in f.arguments: - self.assertTrue(arg.decl_type.decl_string) - - -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/unittests/project_reader_correctness_tester.py b/unittests/project_reader_correctness_tester.py deleted file mode 100644 index dde56600..00000000 --- a/unittests/project_reader_correctness_tester.py +++ /dev/null @@ -1,109 +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 os -import unittest - -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): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.__files = [ - 'core_types.hpp', - 'core_ns_join_1.hpp', - 'core_ns_join_2.hpp', - 'core_ns_join_3.hpp', - 'core_membership.hpp', - 'core_class_hierarchy.hpp', - 'core_diamand_hierarchy_base.hpp', - 'core_diamand_hierarchy_derived1.hpp', - 'core_diamand_hierarchy_derived2.hpp', - 'core_diamand_hierarchy_final_derived.hpp', - 'core_overloads_1.hpp', - 'core_overloads_2.hpp'] - - def __test_correctness_impl(self, file_name): - prj_reader = parser.project_reader_t(self.config) - prj_decls = prj_reader.read_files( - [file_name] * 2, - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - src_reader = parser.source_reader_t(self.config) - src_decls = src_reader.read_file(file_name) - if src_decls != prj_decls: - s = src_decls[0] - p = prj_decls[0] - bdir = autoconfig.build_directory - with open(os.path.join(bdir, file_name + '.sr.txt'), 'w+') as sr: - with open( - os.path.join(bdir, file_name + '.pr.txt'), 'w+') as pr: - - declarations.print_declarations( - s, writer=lambda x: sr.write(l + os.linesep)) - declarations.print_declarations( - p, writer=lambda x: pr.write(l + os.linesep)) - - self.fail( - "There is a difference between declarations in file %s." % - file_name) - - def test_correctness(self): - for src in self.__files: - self.__test_correctness_impl(src) - - -class tester2_t(parser_test_case.parser_test_case_t): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.__files = [ - 'separate_compilation/data.h', - 'separate_compilation/base.h', - 'separate_compilation/derived.h'] - - def test(self): - prj_reader = parser.project_reader_t(self.config) - prj_decls = prj_reader.read_files( - self.__files, - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - src_reader = parser.source_reader_t(self.config) - src_decls = src_reader.read_file('separate_compilation/all.h') - - declarations.dump_declarations( - src_decls, - os.path.join( - autoconfig.build_directory, 'separate_compilation.sr.txt')) - - declarations.dump_declarations( - prj_decls, - os.path.join( - autoconfig.build_directory, 'separate_compilation.pr.txt')) - - self.assertTrue( - src_decls == prj_decls, - "There is a difference between declarations") - - -def create_suite(): - suite = unittest.TestSuite() - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=Test)) - suite.addTest( - unittest.TestLoader().loadTestsFromTestCase(testCaseClass=tester2_t)) - return suite - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/remove_template_defaults_tester.py b/unittests/remove_template_defaults_tester.py deleted file mode 100644 index 0021447f..00000000 --- a/unittests/remove_template_defaults_tester.py +++ /dev/null @@ -1,221 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations -from pygccxml import utils - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'remove_template_defaults.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() - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - def test_vector(self): - v_int = self.global_ns.typedef('v_int') - v_traits = declarations.vector_traits - self.assertTrue('vector< int >' == v_traits.remove_defaults(v_int)) - v_string = self.global_ns.typedef('v_string') - self.assertTrue( - 'vector< std::string >' == v_traits.remove_defaults(v_string)) - v_v_int = self.global_ns.typedef('v_v_int') - self.assertTrue( - 'vector< std::vector< int > >' == - v_traits.remove_defaults(v_v_int)) - - def test_list(self): - l_int = self.global_ns.typedef('l_int') - l_traits = declarations.list_traits - self.assertTrue('list< int >' == l_traits.remove_defaults(l_int)) - l_wstring = self.global_ns.typedef('l_wstring') - self.assertTrue( - 'list< std::wstring >' == l_traits.remove_defaults(l_wstring)) - - def test_deque(self): - d_v_int = self.global_ns.typedef('d_v_int') - d_v_traits = declarations.deque_traits - self.assertTrue( - 'deque< std::vector< int > >' == - d_v_traits.remove_defaults(d_v_int)) - d_l_string = self.global_ns.typedef('d_l_string') - self.assertTrue( - 'deque< std::list< std::string > >' == - d_v_traits.remove_defaults(d_l_string)) - - def test_queue(self): - q_int = self.global_ns.typedef('q_int') - q_traits = declarations.queue_traits - self.assertTrue('queue< int >' == q_traits.remove_defaults(q_int)) - q_string = self.global_ns.typedef('q_string') - self.assertTrue( - 'queue< std::string >' == q_traits.remove_defaults(q_string)) - - def test_priority_queue(self): - pq_int = self.global_ns.typedef('pq_int') - pq_traits = declarations.priority_queue_traits - self.assertTrue( - 'priority_queue< int >' == pq_traits.remove_defaults(pq_int)) - pq_string = self.global_ns.typedef('pq_string') - self.assertTrue( - 'priority_queue< std::string >' == - pq_traits.remove_defaults(pq_string)) - - def test_set(self): - s_v_int = self.global_ns.typedef('s_v_int') - self.assertTrue( - 'set< std::vector< int > >' == - declarations.set_traits.remove_defaults(s_v_int)) - s_string = self.global_ns.typedef('s_string') - self.assertTrue( - 'set< std::string >' == - declarations.set_traits.remove_defaults(s_string)) - - def test_multiset(self): - ms_v_int = self.global_ns.typedef('ms_v_int') - ms_v_traits = declarations.multiset_traits - self.assertTrue( - 'multiset< std::vector< int > >' == - ms_v_traits.remove_defaults(ms_v_int)) - ms_string = self.global_ns.typedef('ms_string') - self.assertTrue( - 'multiset< std::string >' == - ms_v_traits.remove_defaults(ms_string)) - - def test_map(self): - m_i2d = self.global_ns.typedef('m_i2d') - self.assertTrue( - 'map< int, double >' == - declarations.map_traits.remove_defaults(m_i2d)) - m_wstr2d = self.global_ns.typedef('m_wstr2d') - self.assertTrue( - 'map< std::wstring, double >' == - declarations.map_traits.remove_defaults(m_wstr2d)) - m_v_i2m_wstr2d = self.global_ns.typedef('m_v_i2m_wstr2d') - m = 'map< const std::vector< int >, std::map< std::wstring, double > >' - self.assertTrue( - m == declarations.map_traits.remove_defaults(m_v_i2m_wstr2d)) - - def test_multimap(self): - mm_i2d = self.global_ns.typedef('mm_i2d') - mm_traits = declarations.multimap_traits - self.assertTrue( - 'multimap< int, double >' == mm_traits.remove_defaults(mm_i2d)) - mm_wstr2d = self.global_ns.typedef('mm_wstr2d') - self.assertTrue( - 'multimap< const std::wstring, double >' == - mm_traits.remove_defaults(mm_wstr2d)) - mm_v_i2mm_wstr2d = self.global_ns.typedef('mm_v_i2mm_wstr2d') - self.assertTrue( - ('multimap< const std::vector< int >, ' + - 'const std::multimap< const std::wstring, double > >') == - mm_traits.remove_defaults(mm_v_i2mm_wstr2d)) - - def test_hash_set(self): - hs_v_int = self.global_ns.typedef('hs_v_int') - if self.xml_generator_from_xml_file.is_castxml: - hs_traits = declarations.unordered_set_traits - name = 'unordered_set' - else: - hs_traits = declarations.hash_set_traits - name = 'hash_set' - self.assertTrue( - (name + '< std::vector< int > >') == - hs_traits.remove_defaults(hs_v_int), - hs_traits.remove_defaults(hs_v_int)) - hs_string = self.global_ns.typedef('hs_string') - self.assertTrue( - (name + '< std::string >') == hs_traits.remove_defaults(hs_string)) - - def test_hash_multiset(self): - mhs_v_int = self.global_ns.typedef('mhs_v_int') - if self.xml_generator_from_xml_file.is_castxml: - mhs_traits = declarations.unordered_multiset_traits - name = 'unordered_multiset' - else: - mhs_traits = declarations.hash_multiset_traits - name = 'hash_multiset' - self.assertTrue( - (name + '< std::vector< int > >') == - mhs_traits.remove_defaults(mhs_v_int)) - mhs_string = self.global_ns.typedef('mhs_string') - self.assertTrue( - (name + '< std::string >') == - mhs_traits.remove_defaults(mhs_string)) - - def test_hash_map(self): - hm_i2d = self.global_ns.typedef('hm_i2d') - if self.xml_generator_from_xml_file.is_castxml: - hm_traits = declarations.unordered_map_traits - name = 'unordered_map' - else: - hm_traits = declarations.hash_map_traits - name = 'hash_map' - self.assertTrue( - (name + '< int, double >') == hm_traits.remove_defaults(hm_i2d)) - hm_wstr2d = self.global_ns.typedef('hm_wstr2d') - self.assertTrue( - (name + '< std::wstring, double >') == - hm_traits.remove_defaults(hm_wstr2d)) - - def test_hash_multimap(self): - hmm_i2d = self.global_ns.typedef('hmm_i2d') - if self.xml_generator_from_xml_file.is_castxml: - hmm_traits = declarations.unordered_multimap_traits - name = 'unordered_multimap' - else: - hmm_traits = declarations.hash_multimap_traits - name = 'hash_multimap' - self.assertTrue( - (name + '< int, double >') == - hmm_traits.remove_defaults(hmm_i2d)) - hmm_wstr2d = self.global_ns.typedef('hmm_wstr2d') - self.assertTrue( - (name + '< const std::wstring, double >') == - hmm_traits.remove_defaults(hmm_wstr2d)) - - hmm_v_i2mm_wstr2d = self.global_ns.typedef('hmm_v_i2mm_wstr2d') - - hmm_traits_value = hmm_traits.remove_defaults(hmm_v_i2mm_wstr2d) - - possible_values = ( - name + '< const std::vector< int >, ' + - 'const __gnu_cxx::' + name + '< const std::wstring, double > >', - name + '< const std::vector< int >, ' + - 'const std::' + utils.get_tr1(hmm_traits_value) + name + - '< const std::wstring, double > >', - name + '< const std::vector< int >, ' + - 'const stdext::' + name + '< const std::wstring, double > >') - - self.assertTrue(hmm_traits_value in possible_values, hmm_traits_value) - - -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/unittests/source_reader_tester.py b/unittests/source_reader_tester.py deleted file mode 100644 index fbb7c236..00000000 --- a/unittests/source_reader_tester.py +++ /dev/null @@ -1,47 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - 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() - self.global_ns = Test.global_ns - - def test_compound_argument_type(self): - do_smth = self.global_ns.calldefs('do_smth') - self.assertTrue(do_smth, "unable to find do_smth") - do_smth.function_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() diff --git a/unittests/start_with_declarations_tester.py b/unittests/start_with_declarations_tester.py deleted file mode 100644 index 0aad14c6..00000000 --- a/unittests/start_with_declarations_tester.py +++ /dev/null @@ -1,68 +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 unittest - -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): - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'core_ns_join_1.hpp' - self.config = autoconfig.cxx_parsers_cfg.config.clone() - self.config.start_with_declarations.extend(['E11', 'ns::ns12::E13']) - - def __check_result(self, decls): - E11 = declarations.find_declaration(decls, fullname='::E11') - self.assertTrue(E11, "unable to find 'E11' enum") - ns12 = declarations.find_declaration(decls, fullname='::ns::ns12') - self.assertTrue(ns12, "unable to find 'ns12' namespace") - E13 = declarations.find_declaration(ns12.declarations, name='E13') - self.assertTrue(E13, "unable to find 'E13' enum") - E14 = declarations.find_declaration(decls, name='E14') - self.assertTrue( - not E14, - "enum 'E14' should not be found in declarations") - - def test_simple(self): - decls = parser.parse([self.header], self.config) - self.__check_result(decls) - - def test_project_reader_file_by_file(self): - reader = parser.project_reader_t(self.config) - decls = reader.read_files( - [parser.file_configuration_t( - self.header, self.config.start_with_declarations)], - parser.COMPILATION_MODE.FILE_BY_FILE) - self.__check_result(decls) - - def test_project_reader_all_at_once(self): - reader = parser.project_reader_t(self.config) - decls = reader.read_files( - [parser.file_configuration_t( - self.header, self.config.start_with_declarations)], - parser.COMPILATION_MODE.ALL_AT_ONCE) - self.__check_result(decls) - - -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/unittests/string_traits_tester.py b/unittests/string_traits_tester.py deleted file mode 100644 index 5755322e..00000000 --- a/unittests/string_traits_tester.py +++ /dev/null @@ -1,68 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - 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 = 'string_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, ns, controller): - for typedef in ns.typedefs(): - self.assertTrue(controller(typedef.decl_type)) - - def validate_no(self, ns, controller): - for typedef in ns.typedefs(): - self.assertTrue(not controller(typedef.decl_type)) - - def test_string(self): - string_traits = self.global_ns.namespace('string_traits') - self.validate_yes( - string_traits.namespace('yes'), - declarations.is_std_string) - self.validate_no( - string_traits.namespace('no'), - declarations.is_std_string) - - def test_wstring(self): - wstring_traits = self.global_ns.namespace('wstring_traits') - self.validate_yes( - wstring_traits.namespace('yes'), - declarations.is_std_wstring) - self.validate_no( - wstring_traits.namespace('no'), - declarations.is_std_wstring) - - -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/unittests/templates_tester.py b/unittests/templates_tester.py deleted file mode 100644 index 449383a8..00000000 --- a/unittests/templates_tester.py +++ /dev/null @@ -1,101 +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 unittest - -from . import parser_test_case - -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - def __test_split_impl(self, decl_string, name, args): - self.assertTrue( - (name, args) == declarations.templates.split(decl_string)) - - def __test_split_recursive_impl(self, decl_string, control_seq): - self.assertTrue( - control_seq == - list(declarations.templates.split_recursive(decl_string))) - - def __test_is_template_impl(self, decl_string): - self.assertTrue(declarations.templates.is_instantiation(decl_string)) - - def test_split_on_vector(self): - self.__test_is_template_impl("vector >") - - self.__test_split_impl( - "vector >", - "vector", - ["int", "std::allocator"]) - - self.__test_split_recursive_impl( - "vector >", - [("vector", ["int", "std::allocator"]), - ("std::allocator", ["int"])]) - - def test_split_on_string(self): - self.__test_is_template_impl( - "basic_string,std::allocator >") - - self.__test_split_impl( - "basic_string,std::allocator >", - "basic_string", - ["char", - "std::char_traits", - "std::allocator"]) - - def test_split_on_map(self): - self.__test_is_template_impl( - "map >," + - "std::less,std::allocator > > > >") - - self.__test_split_impl( - "map >," + - "std::less,std::allocator > > > >", - "map", - ["long int", - "std::vector >", - "std::less", - "std::allocator > > >"]) - - def test_join_on_vector(self): - self.assertTrue( - "vector< int, std::allocator >" == - declarations.templates.join( - "vector", ("int", "std::allocator"))) - - def test_bug_is_tmpl_inst(self): - self.assertTrue( - declarations.templates.is_instantiation( - "::FX::QMemArray::setRawData") is False) - - # disable broken test - # def test_split_bug_fptr(self): - # x = 'map, ' + - # 'std::allocator > >' - # name, args = declarations.templates.split( x ) - # self.assertTrue( len(x) == 4, "This test is expected to fail." ) - - -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/unittests/test_all.py b/unittests/test_all.py deleted file mode 100644 index cd3408ac..00000000 --- a/unittests/test_all.py +++ /dev/null @@ -1,203 +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 os -import sys -import unittest -import platform - -from . import decl_string_tester -from . import declaration_files_tester -from . import declarations_comparison_tester -from . import declarations_tester -from . import file_cache_tester -from . import gccxml_runner_tester -from . import project_reader_correctness_tester -from . import source_reader_tester -from . import start_with_declarations_tester -from . import templates_tester -from . import type_traits_tester -from . import core_tester -from . import xmlfile_reader_tester -from . import text_reader_tester -from . import hierarchy_traveling -from . import patcher_tester -from . import call_invocation_tester -from . import bit_fields_tester -from . import complex_types_tester -from . import cached_source_file_tester -from . import variable_matcher_tester -from . import namespace_matcher_tester -from . import calldef_matcher_tester -from . import filters_tester -from . import cache_enums_tester -from . import decl_printer_tester -from . import typedefs_tester -from . import non_copyable_classes_tester -from . import unnamed_enums_bug_tester -from . import vector_traits_tester -from . import string_traits_tester -from . import declarations_cache_tester -from . import has_binary_operator_traits_tester -from . import algorithms_cache_tester -from . import dependencies_tester -from . import free_operators_tester -from . import remove_template_defaults_tester -from . import find_container_traits_tester -from . import attributes_tester -from . import type_as_exception_bug_tester -from . import copy_constructor_tester -from . import plain_c_tester -from . import function_traits_tester -from . import better_templates_matcher_tester -from . import declaration_matcher_tester -from . import calling_convention_tester -from . import const_volatile_arg_tester -from . import array_bug_tester -from . import gccxml10184_tester -from . import gccxml10185_tester -from . import inline_specifier_tester -from . import test_create_decl_string -from . import example_tester -from . import test_utils -from . import test_va_list_tag_removal -from . import test_copy_constructor -from . import test_cpp_standards -from . import unnamed_classes_tester -from . import test_map_gcc5 -from . import test_argument_without_name -from . import test_smart_pointer -from . import test_pattern_parser -from . import test_function_pointer -from . import test_directory_cache -from . import test_config -from . import deprecation_tester -from . import test_xml_generators -from . import test_non_copyable_recursive -from . import test_castxml_wrong_epic -from . import test_elaborated_types -from . import test_order -from . import test_find_noncopyable_vars -from . import test_hash -from . import test_null_comparison -from . import test_comments -from . import test_deprecation -from . import test_warn_missing_include_dirs -from . import test_overrides -from . import test_ccflags - -testers = [ - decl_string_tester, - declaration_files_tester, - declarations_comparison_tester, - declarations_tester, file_cache_tester, - gccxml_runner_tester, - project_reader_correctness_tester, - source_reader_tester, - start_with_declarations_tester, - templates_tester, - core_tester, - xmlfile_reader_tester, - text_reader_tester, - hierarchy_traveling, - call_invocation_tester, - bit_fields_tester, - complex_types_tester, - cached_source_file_tester, - variable_matcher_tester, - namespace_matcher_tester, - calldef_matcher_tester, - filters_tester, - cache_enums_tester, - typedefs_tester, - non_copyable_classes_tester, - unnamed_enums_bug_tester, - vector_traits_tester, - string_traits_tester, - declarations_cache_tester, - has_binary_operator_traits_tester, - algorithms_cache_tester, - dependencies_tester, - free_operators_tester, - type_as_exception_bug_tester, - plain_c_tester, - function_traits_tester, - better_templates_matcher_tester, - declaration_matcher_tester, - calling_convention_tester, - const_volatile_arg_tester, - array_bug_tester, - gccxml10184_tester, - gccxml10185_tester, - inline_specifier_tester, - test_create_decl_string, - test_copy_constructor, - unnamed_classes_tester, - test_map_gcc5, - test_argument_without_name, - test_smart_pointer, - test_pattern_parser, - test_function_pointer, - test_directory_cache, - test_config, - test_utils, - test_cpp_standards, - test_va_list_tag_removal, - decl_printer_tester, - attributes_tester, - type_traits_tester, - remove_template_defaults_tester, - patcher_tester, - find_container_traits_tester, - deprecation_tester, - test_xml_generators, - test_non_copyable_recursive, - test_castxml_wrong_epic, - test_elaborated_types, - test_order, - test_find_noncopyable_vars, - test_hash, - test_null_comparison, - test_comments, - test_deprecation, - test_warn_missing_include_dirs, - test_overrides, -] - -if platform.system() != 'Windows': - # Known to fail under windows with VS2013 - testers.append(example_tester) - - # Awaiting Windows CI machine - testers.append(test_ccflags) - -if 'posix' in os.name: - testers.append(copy_constructor_tester) - -if os.path.isfile("test_cost.log"): - # Remove the cost log file when tests are run again. - # See the parser_test_case which generates this file. - os.remove("test_cost.log") # pragma: no cover - - -def create_suite(): - main_suite = unittest.TestSuite() - for tester in testers: - main_suite.addTest(tester.create_suite()) - return main_suite - - -def run_suite(): - result = unittest.TextTestRunner(verbosity=2).run(create_suite()) - error_desc = 'EXCEPTION IN SAFE SELECT 9' - all_errors = result.failures + result.errors - for test_case, description in all_errors: - if error_desc not in description: # pragma: no cover - return 1 # pragma: no cover - return 0 - - -if __name__ == "__main__": - sys.exit(run_suite()) diff --git a/unittests/test_argument_without_name.py b/unittests/test_argument_without_name.py deleted file mode 100644 index 08ce1ed2..00000000 --- a/unittests/test_argument_without_name.py +++ /dev/null @@ -1,59 +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 unittest - -from . import parser_test_case - -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_argument_without_name.hpp" - self.config.cflags = "-std=c++11" - - def test_argument_without_name(self): - - """ - 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 & )'. - - See bug #55 - - """ - - if self.config.xml_generator == "gccxml": - return - - 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() diff --git a/unittests/test_castxml_wrong_epic.py b/unittests/test_castxml_wrong_epic.py deleted file mode 100644 index 607b02de..00000000 --- a/unittests/test_castxml_wrong_epic.py +++ /dev/null @@ -1,45 +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 unittest - -from . import parser_test_case - -from pygccxml import parser - - -class Test(parser_test_case.parser_test_case_t): - - def test_castxml_epic_version_check(self): - """ - Test using a forbidden value for the castxml epic version. - - """ - - if self.config.castxml_epic_version != 1: - # Run this test only with castxml epic version == 1 - return - - self.config.castxml_epic_version = 2 - self.assertRaises( - RuntimeError, lambda: parser.parse_string("", self.config)) - - # Reset castxml epic version - self.config.castxml_epic_version = 1 - - -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/unittests/test_ccflags.py b/unittests/test_ccflags.py deleted file mode 100644 index daf46f05..00000000 --- a/unittests/test_ccflags.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2014-2021 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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_ccflags.hpp" - self.global_ns = None - self.config.castxml_epic_version = 1 - self.config.append_cflags("-fopenmp") - - def _parse_src(self): - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.xml_generator_from_xml_file = ( - self.config.xml_generator_from_xml_file - ) - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - self.global_ns = Test.global_ns - - def _add_ccflags(self): - if "clang++" in self.config.compiler_path: - self.config.append_ccflags("-Xpreprocessor") - - self.config.append_ccflags("-fopenmp") - - def test(self): - # First check that macro is not defined. - self._parse_src() - namespace_names = [ - n.name for n in self.global_ns.namespaces(allow_empty=True) - ] - self.assertNotIn("ccflags_test_namespace", namespace_names) - - # Next check that macro is defined when passed directly as ccflag - self._add_ccflags() - self._parse_src() - namespace_names = [n.name for n in self.global_ns.namespaces()] - self.assertIn("ccflags_test_namespace", namespace_names) - - -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/unittests/test_comments.py b/unittests/test_comments.py deleted file mode 100644 index 4d4e9f05..00000000 --- a/unittests/test_comments.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2014-2020 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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_comments.hpp" - self.global_ns = None - self.config.castxml_epic_version = 1 - - def _check_comment_content(self, list, comment_decl): - if comment_decl.text: - self.assertEqual(list, comment_decl.text) - else: - print("No text in comment to check") - - def setUp(self): - - if not self.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - self.global_ns = Test.global_ns - - def test(self): - """ - Check the comment parsing - """ - if self.config.castxml_epic_version != 1: - # Run this test only with castxml epic version == 1 - return - tnamespace = self.global_ns.namespace("comment") - - self.assertIn("comment", dir(tnamespace)) - self._check_comment_content(["//! Namespace Comment", - "//! Across multiple lines"], - tnamespace.comment) - - tenumeration = tnamespace.enumeration("com_enum") - self.assertIn("comment", dir(tenumeration)) - self._check_comment_content(['/// Outside Class enum comment'], - tenumeration.comment) - - tclass = tnamespace.class_("test") - self.assertIn("comment", dir(tclass)) - self._check_comment_content(["/** class comment */"], tclass.comment) - - tcls_enumeration = tclass.enumeration("test_enum") - self.assertIn("comment", dir(tcls_enumeration)) - self._check_comment_content(['/// inside class enum comment'], - tcls_enumeration.comment) - - tmethod = tclass.member_functions()[0] - - self.assertIn("comment", dir(tmethod)) - self._check_comment_content(["/// cxx comment", - "/// with multiple lines"], - tmethod.comment) - - tconstructor = tclass.constructors()[0] - - self.assertIn("comment", dir(tconstructor)) - self._check_comment_content(["/** doc comment */"], - tconstructor.comment) - - for indx, cmt in enumerate(['//! mutable field comment', - "/// bit field comment"]): - tvariable = tclass.variables()[indx] - self.assertIn("comment", dir(tvariable)) - self._check_comment_content([cmt], tvariable.comment) - - -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/unittests/test_config.py b/unittests/test_config.py deleted file mode 100644 index b703d5cd..00000000 --- a/unittests/test_config.py +++ /dev/null @@ -1,80 +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 sys -import os -import unittest - -sys.path.insert(1, os.path.join(os.curdir, '..')) -sys.path.insert(1, "../pygccxml") - -from pygccxml import parser # nopep8 -from pygccxml import utils # nopep8 - - -class Test(unittest.TestCase): - - def test_config(self): - """Test config setup with wrong xml generator setups.""" - - # 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() - - # No xml generator path - config = parser.xml_generator_configuration_t(xml_generator=name) - self.assertRaises( - RuntimeError, lambda: parser.parse_string(code, config)) - - # Invalid path - config = parser.xml_generator_configuration_t( - xml_generator_path="wrong/path", - xml_generator=name) - self.assertRaises( - RuntimeError, lambda: parser.parse_string(code, config)) - - # None path - config = parser.xml_generator_configuration_t( - xml_generator_path=None, - xml_generator=name) - self.assertRaises( - RuntimeError, lambda: parser.parse_string(code, config)) - - # No name - config = parser.xml_generator_configuration_t( - xml_generator_path=generator_path) - self.assertRaises( - RuntimeError, lambda: parser.parse_string(code, config)) - - # Random name - config = parser.xml_generator_configuration_t( - xml_generator_path=generator_path, - xml_generator="not_a_generator") - self.assertRaises( - RuntimeError, lambda: parser.parse_string(code, config)) - - # None name - config = parser.xml_generator_configuration_t( - xml_generator_path=generator_path, - xml_generator=None) - self.assertRaises( - RuntimeError, lambda: 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() diff --git a/unittests/test_copy_constructor.py b/unittests/test_copy_constructor.py deleted file mode 100644 index 962d5199..00000000 --- a/unittests/test_copy_constructor.py +++ /dev/null @@ -1,76 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_copy_constructor.hpp" - self.global_ns = None - - def setUp(self): - if not self.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - self.global_ns = Test.global_ns - - def test(self): - """ - Check the is_copy_constructor method. - - This fails when using CastXML, see issue #27. - - """ - - tclass = self.global_ns.class_("test") - ctors = [] - for decl in tclass.declarations: - if isinstance(decl, declarations.constructor_t): - ctors.append(decl) - - # test::test(test const & t0) [copy constructor] - self.assertTrue(declarations.is_copy_constructor(ctors[0])) - # test::test(float const & t0) [constructor] - self.assertFalse(declarations.is_copy_constructor(ctors[1])) - # test::test(myvar t0) [constructor] - self.assertFalse(declarations.is_copy_constructor(ctors[2])) - - t2class = self.global_ns.class_("test2") - ctors = [] - for decl in t2class.declarations: - if isinstance(decl, declarations.constructor_t): - ctors.append(decl) - - # test2::test2() [constructor] - self.assertFalse(declarations.is_copy_constructor(ctors[0])) - # test2::test2(test2 const & arg0) [copy constructor] - self.assertTrue(declarations.is_copy_constructor(ctors[1])) - - -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/unittests/test_cpp_standards.py b/unittests/test_cpp_standards.py deleted file mode 100644 index eb284189..00000000 --- a/unittests/test_cpp_standards.py +++ /dev/null @@ -1,68 +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 platform -import unittest - -from . import parser_test_case - -from pygccxml import parser - - -class Test(parser_test_case.parser_test_case_t): - - def test(self): - """ - Test different compilation standards by setting cflags. - - """ - - # Skip this test for gccxml, this is a CastXML feature. - if "gccxml" in self.config.xml_generator: - return True - - parser.parse(["cpp_standards.hpp"], self.config) - - if platform.system() != 'Windows': - self.config.cflags = "-std=c++98" - parser.parse(["cpp_standards.hpp"], self.config) - - self.config.cflags = "-std=c++03" - parser.parse(["cpp_standards.hpp"], self.config) - - self.config.cflags = "-std=c++11" - parser.parse(["cpp_standards.hpp"], self.config) - - # This is broken with llvm 3.6.2 (the one from homebrew) - # It should work with never llvms but I keep the test disabled - # See https://llvm.org/bugs/show_bug.cgi?id=24872 - # self.config.cflags = "-std=c++14" - # parser.parse(["cpp_standards.hpp"], self.config) - - # Same as above - # self.config.cflags = "-std=c++1z" - # parser.parse(["cpp_standards.hpp"], self.config) - - # Pass down a flag that does not exist. - # This should raise an exception. - self.config.cflags = "-std=c++00" - self.assertRaises( - RuntimeError, - lambda: parser.parse(["cpp_standards.hpp"], self.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() diff --git a/unittests/test_create_decl_string.py b/unittests/test_create_decl_string.py deleted file mode 100644 index 14a622c4..00000000 --- a/unittests/test_create_decl_string.py +++ /dev/null @@ -1,63 +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 unittest - -from . import parser_test_case - -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 = "declaration_string.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): - """ - Test the create_decl_string method. - - """ - - myfunc = self.global_ns.free_function("myfunc") - - decl = declarations.free_function_type_t.create_decl_string( - myfunc.return_type, myfunc.argument_types) - - self.assertTrue(decl != "('int (*)( int,int )', 'int (*)( int,int )')") - - box = self.global_ns.class_("Box") - myinternfunc = box.member_function("myinternfunc") - decl = declarations.member_function_type_t.create_decl_string( - myinternfunc.return_type, - box.decl_string, - myinternfunc.argument_types, - myinternfunc.has_const) - - self.assertTrue(decl != "short int ( ::Box::* )( ) ") - - -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/unittests/test_deprecation.py b/unittests/test_deprecation.py deleted file mode 100644 index 6c3e71a6..00000000 --- a/unittests/test_deprecation.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2021 Insight Software Consortium. -# 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 pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_deprecation.hpp" - self.global_ns = None - self.config.castxml_epic_version = 1 - - def _check_text_content(self, desired_text, deprecation_string): - if deprecation_string: - self.assertEqual(desired_text, deprecation_string) - else: - print("No text in deprecation attribute to check") - - def setUp(self): - if not self.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - self.global_ns = Test.global_ns - - def test(self): - """ - Check the comment parsing - """ - - if self.config.castxml_epic_version != 1: - # Run this test only with castxml epic version == 1 - return - tnamespace = self.global_ns.namespace("deprecation") - - tenumeration = tnamespace.enumeration("com_enum") - self.assertIn("deprecation", dir(tenumeration)) - self._check_text_content('Enumeration is Deprecated', - tenumeration.deprecation) - - tclass = tnamespace.class_("test") - self.assertIn("deprecation", dir(tclass)) - self._check_text_content("Test class Deprecated", tclass.deprecation) - - tmethod = tclass.member_functions()[0] - tmethod_dep = tclass.member_functions()[1] - - self.assertIn("deprecation", dir(tmethod)) - self.assertIsNone(tmethod.deprecation) - self._check_text_content("Function is deprecated", - tmethod_dep.deprecation) - - tconstructor = tclass.constructors()[0] - tconstructor_dep = tclass.constructors()[1] - - self.assertIsNone(tconstructor.deprecation) - self.assertIn("deprecation", dir(tconstructor_dep)) - self._check_text_content("One arg constructor is Deprecated", - tconstructor_dep.deprecation) - - -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/unittests/test_directory_cache.py b/unittests/test_directory_cache.py deleted file mode 100644 index eefe35bf..00000000 --- a/unittests/test_directory_cache.py +++ /dev/null @@ -1,90 +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 os -import sys -import shutil -import unittest - -from . import parser_test_case - -from pygccxml import parser - - -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 = "typedefs1.hpp" - this_module_dir_path = os.path.abspath( - os.path.dirname(sys.modules[__name__].__file__)) - self.cache_dir = os.path.join( - this_module_dir_path, "data/directory_cache_test") - - def setUp(self): - # Clear the cache tree - if os.path.isdir(self.cache_dir): # pragma: no cover - shutil.rmtree(self.cache_dir) - - def test_directory_cache_without_compression(self): - """ - Test the directory cache without compression - - """ - # Test with compression OFF - cache = parser.directory_cache_t(directory=self.cache_dir) - # Generate a cache on first read - parser.parse([self.header], self.config, cache=cache) - # Read from the cache the second time - parser.parse([self.header], self.config, cache=cache) - - def test_directory_cache_with_compression(self): - """ - Test the directory cache wit compression - - """ - # Test with compression ON - cache = parser.directory_cache_t( - directory=self.cache_dir, compression=True) - # Generate a cache on first read - parser.parse([self.header], self.config, cache=cache) - # Read from the cache the second time - parser.parse([self.header], self.config, cache=cache) - - def test_directory_cache_twice(self): - """ - Setup two caches in a row. - - The second run will reload the same cache directory. - """ - cache = parser.directory_cache_t(directory=self.cache_dir) - parser.parse([self.header], self.config, cache=cache) - cache = parser.directory_cache_t(directory=self.cache_dir) - parser.parse([self.header], self.config, cache=cache) - - def test_directory_existing_dir(self): - """ - Setup a cache when there is already a file at the cache's location. - """ - open(self.cache_dir, "a").close() - self.assertRaises( - ValueError, - lambda: parser.directory_cache_t(directory=self.cache_dir)) - os.remove(self.cache_dir) - - -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/unittests/test_elaborated_types.py b/unittests/test_elaborated_types.py deleted file mode 100644 index b56aae3f..00000000 --- a/unittests/test_elaborated_types.py +++ /dev/null @@ -1,77 +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 unittest - -from . import parser_test_case - -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_elaborated_types.hpp" - - def test_is_elaborated_type(self): - """ - Test for the is_elaborated function - """ - - if self.config.castxml_epic_version != 1: - return - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - 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) - - 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_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 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/unittests/test_find_noncopyable_vars.py b/unittests/test_find_noncopyable_vars.py deleted file mode 100644 index 78622e3f..00000000 --- a/unittests/test_find_noncopyable_vars.py +++ /dev/null @@ -1,50 +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 unittest - -from . import parser_test_case - -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 = "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 - - """ - - # 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 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/unittests/test_function_pointer.py b/unittests/test_function_pointer.py deleted file mode 100644 index 2c32393a..00000000 --- a/unittests/test_function_pointer.py +++ /dev/null @@ -1,93 +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 unittest - -from . import parser_test_case - -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() diff --git a/unittests/test_hash.py b/unittests/test_hash.py deleted file mode 100644 index f455ffe6..00000000 --- a/unittests/test_hash.py +++ /dev/null @@ -1,108 +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 sys -import unittest -import inspect - -from pygccxml import declarations - - -class Test(unittest.TestCase): - - def test_types_hashes(self): - """ - Test if all the type_t instances implement a hash method. - - The hash is part of the public API, as there are multiple tools - that rely on it to compare type_t instances. - - The best way to test this is to instanciate dummy type_t objects - for each class that subclasses type_t, and check that the hash of - these objects is not None. - - """ - - if sys.version_info[:2] == (2, 7): - # _create_type_t_mockup calls inspect.signature, which does not - # exist for legacy Python - return - - members = inspect.getmembers(declarations, inspect.isclass) - for member in members: - member_type = member[1] - is_type_t_subclass = issubclass(member_type, declarations.type_t) - is_not_type_t = member_type != declarations.type_t - if is_type_t_subclass and is_not_type_t: - type_mockup = _create_type_t_mockup(member_type) - self.assertIsNotNone(hash(type_mockup)) - - def test_declarations_hashes(self): - """ - Test if all the declaration_t instances implement a hash method. - - The hash is part of the public API, as there are multiple tools - that rely on it to compare declaration_t instances. - - The best way to test this is to instanciate dummy declaration_t objects - for each class that subclasses declaration_t, and check that the hash - of these objects is not None. - - """ - members = inspect.getmembers(declarations, inspect.isclass) - for member in members: - member_type = member[1] - if issubclass(member_type, declarations.declaration_t): - self.assertIsNotNone(hash(member_type())) - - def test_type_qualifiers_t_hash(self): - """ - Test if the type_qualifiers_t instance implements a hash method. - - The hash is part of the public API, as there are multiple tools - that rely on it to compare type_qualifiers_t instances. - - """ - self.assertIsNotNone(hash(declarations.type_qualifiers_t())) - - -def _create_type_t_mockup(member_type): - nbr_parameters = len(inspect.signature(member_type).parameters) - if nbr_parameters == 0: - m = member_type() - else: - if member_type == declarations.array_t: - m = member_type(_base_mockup(), size=1) - else: - m = member_type(_base_mockup()) - m.cache.decl_string = "" - return m - - -class _base_mockup(declarations.type_t): - - def __init__(self): - declarations.type_t.__init__(self) - self.cache.decl_string = "" - self._decl_string = "" - self.variable_type = declarations.type_t() - - def build_decl_string(self, with_defaults=False): - return self._decl_string - - -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/unittests/test_map_gcc5.py b/unittests/test_map_gcc5.py deleted file mode 100644 index 49d3340e..00000000 --- a/unittests/test_map_gcc5.py +++ /dev/null @@ -1,62 +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 unittest - -from . import parser_test_case - -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_map_gcc5.hpp" - self.config.cflags = "-std=c++11" - - def test_map_gcc5(self): - """ - The code in test_map_gcc5.hpp was breaking pygccxml. - - Test that case (gcc5 + castxml + c++11). - - See issue #45 and #55 - - """ - - if self.config.xml_generator == "gccxml": - return - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - # This calldef is defined with gcc > 4.9 (maybe earlier, not tested) - # and -std=c++11. Calling create_decl_string is failing with gcc. - # With clang the calldef does not exist so the matcher - # will just return an empty list, letting the test pass. - # See the test_argument_without_name.py for an equivalent test, - # which is not depending on the presence of the _M_clone_node - # method in the stl_tree.h file. - criteria = declarations.calldef_matcher(name="_M_clone_node") - free_funcs = declarations.matcher.find(criteria, global_ns) - for free_funcs in free_funcs: - free_funcs.create_decl_string(with_defaults=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() diff --git a/unittests/test_non_copyable_recursive.py b/unittests/test_non_copyable_recursive.py deleted file mode 100644 index cd78a9ae..00000000 --- a/unittests/test_non_copyable_recursive.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2014-2016 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 unittest - -from . import parser_test_case - -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_non_copyable_recursive.hpp" - - def test_infinite_recursion_base_classes(self): - """ - Test find_noncopyable_vars - - See #71 - - find_noncopyable_vars was throwing: - RuntimeError: maximum recursion depth exceeded while - calling a Python object - """ - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - # Description of the problem (before the fix): - # find_noncopyable_vars (on Child class) looks up the variables, - # and finds aBasePtr2 (a pointer to the Base2 class). - # Then it looks recursively at the base classes of Base2, and finds - # Base1. Then, it looks up the variables from Base, to check if Base1 - # is non copyable. It finds another aBasePtr2 variable, which leads to - # a new check of Base2; this recurses infinitely. - test_ns = global_ns.namespace('Test1') - cls = test_ns.class_('Child') - declarations.type_traits_classes.find_noncopyable_vars(cls) - self.assertTrue(declarations.type_traits_classes.is_noncopyable(cls)) - - def test_infinite_recursion_sstream(self): - """ - Test find_noncopyable_vars - - See #71 - - find_noncopyable_vars was throwing: - RuntimeError: maximum recursion depth exceeded while - calling a Python object - """ - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - # Real life example of the bug. This leads to a similar error, - # but the situation is more complex as there are multiple - # classes that are related the one to the others - # (basic_istream, basic_ios, ios_base, ...) - test_ns = global_ns.namespace('Test2') - cls = test_ns.class_('FileStreamDataStream') - declarations.type_traits_classes.find_noncopyable_vars(cls) - self.assertFalse(declarations.type_traits_classes.is_noncopyable(cls)) - - -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/unittests/test_null_comparison.py b/unittests/test_null_comparison.py deleted file mode 100644 index 51caf4ab..00000000 --- a/unittests/test_null_comparison.py +++ /dev/null @@ -1,49 +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 unittest - -from . import parser_test_case - -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 = "null_comparison.hpp" - - def test_argument_null_comparison(self): - """ - Test for None comparisons with default arguments - """ - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - - ns = global_ns.namespace("ns") - - func = ns.free_function(name="TestFunction1") - assert (func.arguments[0] > func.arguments[1]) is False - - func = ns.free_function(name="TestFunction2") - assert (func.arguments[0] > func.arguments[1]) 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() diff --git a/unittests/test_order.py b/unittests/test_order.py deleted file mode 100644 index 97b50d5a..00000000 --- a/unittests/test_order.py +++ /dev/null @@ -1,102 +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 unittest - -from . import parser_test_case - -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() diff --git a/unittests/test_overrides.py b/unittests/test_overrides.py deleted file mode 100644 index 9204efcc..00000000 --- a/unittests/test_overrides.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2014-2020 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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = "test_overrides.hpp" - self.global_ns = None - self.config.castxml_epic_version = 1 - - def setUp(self): - - if not self.global_ns: - decls = parser.parse([self.header], self.config) - Test.global_ns = declarations.get_global_namespace(decls) - Test.xml_generator_from_xml_file = \ - self.config.xml_generator_from_xml_file - self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file - - self.global_ns = Test.global_ns - - def test(self): - """ - Check that the override information is populated for the - simple::goodbye function. It should contain the decl for the - base::goodbye function. Base::goodbye has no override so it - will be none - """ - base = self.global_ns.class_("base").member_function("goodbye") - override_decl = self.global_ns.class_("simple")\ - .member_function("goodbye") - - self.assertTrue(base.overrides is None) - self.assertFalse(override_decl.overrides is None) - self.assertEqual(override_decl.overrides, base) - - -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/unittests/test_pattern_parser.py b/unittests/test_pattern_parser.py deleted file mode 100644 index 00a6805d..00000000 --- a/unittests/test_pattern_parser.py +++ /dev/null @@ -1,179 +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 unittest - -from . import parser_test_case - -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_pattern_parser.hpp" - self.config.cflags = "-std=c++11" - - def test_template_split_std_vector(self): - """ - Demonstrate error in pattern parser, see #60 - - """ - - if self.config.xml_generator == "gccxml": - return - - decls = parser.parse([self.header], self.config) - - for decl in declarations.make_flatten(decls): - if "myClass" in decl.name: - _ = decl.partial_name - - def test_matcher(self): - """ - Run the matcher on all the templated classes. - - This exercises the whole pipeline even more. - - """ - - if self.config.xml_generator == "gccxml": - return - - decls = parser.parse([self.header], self.config) - global_ns = declarations.get_global_namespace(decls) - criteria = declarations.declaration_matcher(name="myClass") - _ = declarations.matcher.find(criteria, global_ns) - - def test_split(self): - """ - Test a bunch of tricky name/args splits. More combinations could be - tested but this is already covering most of the cases. - - In test_template_split_std_vector we test for a specific case that - was failing (in a real world scenario). - Here we test more possible combinations to make sure the splitting - method is robust enough. - - """ - - p1 = "std::vector >" - p2 = "std::vector >" - args_list = [ - "const std::basic_string &", "const int &", "const double &"] - - for arg in args_list: - - li = [p1] - name, args = declarations.templates.split( - "myClass0a<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass0a") - self.assertEqual(args, li) - - li = [p1, p2] - name, args = declarations.templates.split( - "myClass0b<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass0b") - self.assertEqual(args, li) - - li = [p1, p2, p2] - name, args = declarations.templates.split( - "myClass0c<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass0c") - self.assertEqual(args, li) - - li = [p1 + " (" + arg + ")"] - name, args = declarations.templates.split( - "myClass1<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass1") - self.assertEqual(args, li) - - li = [p1 + " (" + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass2<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass2") - self.assertEqual(args, li) - - li = [p2 + " (" + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass3<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass3") - self.assertEqual(args, li) - - li = [p1 + " (" + arg + ", " + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass4<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass4") - self.assertEqual(args, li) - - li = [ - p1 + " (" + arg + ", " + arg + ", " + arg + ")", - p1] - name, args = declarations.templates.split( - "myClass5<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass5") - self.assertEqual(args, li) - - li = [ - p1, - p1 + " (" + arg + ", " + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass6<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass6") - self.assertEqual(args, li) - - li = [ - p2 + " (" + arg + ")", - p1, - p1 + " (" + arg + ", " + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass7<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass7") - self.assertEqual(args, li) - - li = [ - p1, - p2 + " (" + arg + ")", - p1 + " (" + arg + ", " + arg + ", " + arg + ")"] - name, args = declarations.templates.split( - "myClass8<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass8") - self.assertEqual(args, li) - - li = [ - p2 + " (" + arg + ")", - p1 + " (" + arg + ", " + arg + ")", - p1] - name, args = declarations.templates.split( - "myClass9<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass9") - self.assertEqual(args, li) - - li = [ - p2 + " (" + arg + ")", - p1 + " (" + arg + ", " + arg + ", " + arg + ")", - p1, - p2] - name, args = declarations.templates.split( - "myClass10<" + ", ".join(li) + ">") - self.assertEqual(name, "myClass10") - self.assertEqual(args, li) - - -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/unittests/test_smart_pointer.py b/unittests/test_smart_pointer.py deleted file mode 100644 index e9183b74..00000000 --- a/unittests/test_smart_pointer.py +++ /dev/null @@ -1,120 +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 unittest - -from . import parser_test_case - -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_smart_pointer.hpp" - self.config.cflags = "-std=c++11" - self.global_ns = None - - def setUp(self): - if self.config.xml_generator == "gccxml": - return - decls = parser.parse([self.header], self.config) - self.global_ns = declarations.get_global_namespace(decls) - - def test_is_smart_pointer(self): - """ - Test smart_pointer_traits.is_smart_pointer method. - - """ - - if self.config.xml_generator == "gccxml": - return - - criteria = declarations.declaration_matcher(name="yes1") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertTrue( - declarations.smart_pointer_traits.is_smart_pointer( - decls[0].decl_type)) - - criteria = declarations.declaration_matcher(name="no1") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertFalse( - declarations.smart_pointer_traits.is_smart_pointer( - decls[0].decl_type)) - - criteria = declarations.declaration_matcher(name="no2") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertFalse( - declarations.smart_pointer_traits.is_smart_pointer( - decls[0].decl_type)) - - def test_is_auto_pointer(self): - """ - Test auto_ptr_traits.is_smart_pointer method. - - """ - - if self.config.xml_generator == "gccxml": - return - - criteria = declarations.declaration_matcher(name="yes2") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertTrue( - declarations.auto_ptr_traits.is_smart_pointer(decls[0].decl_type)) - - criteria = declarations.declaration_matcher(name="no1") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertFalse( - declarations.auto_ptr_traits.is_smart_pointer(decls[0].decl_type)) - - criteria = declarations.declaration_matcher(name="no2") - decls = declarations.matcher.find(criteria, self.global_ns) - self.assertFalse( - declarations.auto_ptr_traits.is_smart_pointer(decls[0].decl_type)) - - def test_smart_pointer_value_type(self): - """ - Test smart_pointer_traits.value_type method. - - """ - - if self.config.xml_generator == "gccxml": - return - - criteria = declarations.declaration_matcher(name="yes1") - decls = declarations.matcher.find(criteria, self.global_ns) - vt = declarations.smart_pointer_traits.value_type(decls[0].decl_type) - self.assertIsInstance(vt, declarations.int_t) - - def test_auto_pointer_value_type(self): - """ - Test auto_pointer_traits.value_type method. - - """ - - if self.config.xml_generator == "gccxml": - return - - criteria = declarations.declaration_matcher(name="yes2") - decls = declarations.matcher.find(criteria, self.global_ns) - vt = declarations.auto_ptr_traits.value_type(decls[0].decl_type) - self.assertIsInstance(vt, declarations.double_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() diff --git a/unittests/test_utils.py b/unittests/test_utils.py deleted file mode 100644 index 9fa76c15..00000000 --- a/unittests/test_utils.py +++ /dev/null @@ -1,70 +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 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(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")] - - self.assertTrue(utils.utils.contains_parent_dir(path, dirs)) - - dirs = [os.path.normpath("/home"), os.path.normpath("/mypath/test/")] - - self.assertFalse(utils.utils.contains_parent_dir(path, dirs)) - - def test_deprecation_wrapper(self): - """ - The DeprecationWrapper is not part of the public API - - 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) - - -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/unittests/test_va_list_tag_removal.py b/unittests/test_va_list_tag_removal.py deleted file mode 100644 index ed0e3742..00000000 --- a/unittests/test_va_list_tag_removal.py +++ /dev/null @@ -1,147 +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 os -import platform -import unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - - """ - 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. - - """ - - 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"] - - def test_keep_va_list_tag(self): - - if "gccxml" in self.config.xml_generator or \ - platform.system() == 'Windows': - return True - - self.config.flags = ["f1"] - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) - - classes = [ - i for i in decls if isinstance(i, declarations.class_t)] - - typedefs = [ - i for i in decls if isinstance(i, declarations.typedef_t)] - - variables = [ - i for i in decls if isinstance(i, declarations.variable_t)] - - tag = "__va_list_tag" - - 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]) - - 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]) - - 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): - - if "gccxml" in self.config.xml_generator or \ - platform.system() == 'Windows': - return True - - self.config.flags = [] - src_reader = parser.source_reader_t(self.config) - decls = declarations.make_flatten(src_reader.read_string(self.__code)) - - classes = [ - i for i in decls if isinstance(i, declarations.class_t)] - - typedefs = [ - i for i in decls if isinstance(i, declarations.typedef_t)] - - variables = [ - i for i in decls if isinstance(i, declarations.variable_t)] - - tag = "__va_list_tag" - - 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) - - 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]) - - self.assertFalse( - tag in [var.decl_string.split("::")[1] for var in variables]) - self.assertTrue(len(variables) == 0) - - -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/unittests/test_warn_missing_include_dirs.py b/unittests/test_warn_missing_include_dirs.py deleted file mode 100644 index ec5e9cfd..00000000 --- a/unittests/test_warn_missing_include_dirs.py +++ /dev/null @@ -1,53 +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 io -import sys -import os -import unittest -import warnings - -sys.path.insert(1, os.path.join(os.curdir, '..')) -sys.path.insert(1, "../pygccxml") - -from pygccxml import parser # nopep8 -from pygccxml import utils # nopep8 - - -class Test(unittest.TestCase): - - 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;" - - # 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() diff --git a/unittests/test_xml_generators.py b/unittests/test_xml_generators.py deleted file mode 100644 index e3f79460..00000000 --- a/unittests/test_xml_generators.py +++ /dev/null @@ -1,83 +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 unittest -import logging - -from . import parser_test_case - -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() diff --git a/unittests/text_reader_tester.py b/unittests/text_reader_tester.py deleted file mode 100644 index 8708c496..00000000 --- a/unittests/text_reader_tester.py +++ /dev/null @@ -1,47 +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 unittest - -from . import parser_test_case - -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 test(self): - fconfig = parser.file_configuration_t( - data='int i;', - start_with_declarations=None, - content_type=parser.file_configuration_t.CONTENT_TYPE.TEXT) - - prj_reader = parser.project_reader_t(self.config) - decls = prj_reader.read_files( - [fconfig], - compilation_mode=parser.COMPILATION_MODE.FILE_BY_FILE) - - var_i = declarations.find_declaration( - decls, decl_type=declarations.variable_t, name='i') - self.assertTrue(var_i, "Variable i has not been found.") - - -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/unittests/type_as_exception_bug_tester.py b/unittests/type_as_exception_bug_tester.py deleted file mode 100644 index 57dc5539..00000000 --- a/unittests/type_as_exception_bug_tester.py +++ /dev/null @@ -1,50 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - global_ns = None - - def __init__(self, *args): - parser_test_case.parser_test_case_t.__init__(self, *args) - self.header = 'type_as_exception_bug.h' - - 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(self): - buggy = self.global_ns.member_function('buggy') - expression_error = self.global_ns.class_('ExpressionError') - self.assertTrue(len(buggy.exceptions) == 1) - err = buggy.exceptions[0] - self.assertTrue(declarations.is_reference(err)) - err = declarations.remove_declarated( - declarations.remove_reference(err)) - self.assertTrue(err is expression_error) - - -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/unittests/type_traits_tester.py b/unittests/type_traits_tester.py deleted file mode 100644 index abcde5f1..00000000 --- a/unittests/type_traits_tester.py +++ /dev/null @@ -1,473 +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 unittest - -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): - 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() diff --git a/unittests/typedefs_tester.py b/unittests/typedefs_tester.py deleted file mode 100644 index 8b553afa..00000000 --- a/unittests/typedefs_tester.py +++ /dev/null @@ -1,83 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class tester_src_t(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 = '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 - 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() diff --git a/unittests/unnamed_classes_tester.py b/unittests/unnamed_classes_tester.py deleted file mode 100644 index ec35da15..00000000 --- a/unittests/unnamed_classes_tester.py +++ /dev/null @@ -1,102 +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 unittest - -from . import parser_test_case - -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() diff --git a/unittests/unnamed_enums_bug_tester.py b/unittests/unnamed_enums_bug_tester.py deleted file mode 100644 index c2c81d10..00000000 --- a/unittests/unnamed_enums_bug_tester.py +++ /dev/null @@ -1,114 +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 unittest - -from . import parser_test_case - -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 = [ - '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() diff --git a/unittests/variable_matcher_tester.py b/unittests/variable_matcher_tester.py deleted file mode 100644 index 2bb0f0ff..00000000 --- a/unittests/variable_matcher_tester.py +++ /dev/null @@ -1,88 +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 os -import unittest - -from . import parser_test_case - -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) - - x = declarations.matcher.get_single(criteria, self.declarations) - self.assertTrue(x, "Variable was not found.") - - self.assertTrue('public' == x.access_type) - - -class tester_2_t(parser_test_case.parser_test_case_t): - 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)) - - 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 >') - - -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 - - -def run_suite(): - unittest.TextTestRunner(verbosity=2).run(create_suite()) - - -if __name__ == "__main__": - run_suite() diff --git a/unittests/vector_traits_tester.py b/unittests/vector_traits_tester.py deleted file mode 100644 index d4063fdb..00000000 --- a/unittests/vector_traits_tester.py +++ /dev/null @@ -1,95 +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 unittest - -from . import parser_test_case - -from pygccxml import parser -from pygccxml import declarations - - -class Test(parser_test_case.parser_test_case_t): - 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() diff --git a/unittests/xml_generator.cfg b/unittests/xml_generator.cfg deleted file mode 100644 index cb00818e..00000000 --- a/unittests/xml_generator.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[xml_generator] -# Specify which xml generator you want to use "castxml" or "gccxml" -# "castxml is the default" -xml_generator= -# Path to castxml or gccxml executable file -xml_generator_path= -# Set the path to the compiler (for example "/usr/bin/gcc") for CastXML -compiler_path= -# Gccxml working directory - optional, could be set to your source code directory -working_directory= -# Additional include directories, as list of paths ["path1/file1.h", "path2/file2.h", ...] -include_paths= -# You can explicitly set what compiler it should emulate (for GCCXML) -# Valid options are: g++, msvc6, msvc7, msvc71, msvc8, cl. -compiler= -# Keep xml files after errors (useful for debugging) -keep_xml= diff --git a/unittests/xmlfile_reader_tester.py b/unittests/xmlfile_reader_tester.py deleted file mode 100644 index 8024d2fb..00000000 --- a/unittests/xmlfile_reader_tester.py +++ /dev/null @@ -1,72 +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 os -import unittest - -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): - - 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(self): - src_reader = parser.source_reader_t(self.config) - src_decls = src_reader.read_file(self.__fname) - - 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) - - prj_reader = parser.project_reader_t(self.config) - prj_decls = prj_reader.read_files( - [fconfig], - compilation_mode=parser.COMPILATION_MODE.FILE_BY_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')) - - 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 ) - - -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()