def test_config_overrides(gen_paths): # type: ignore """ Test providing different configuration values to a LanguageContext object. """ additional_config_files = [gen_paths.root_dir / Path('tox').with_suffix('.ini')] lctx = LanguageContext(additional_config_files=additional_config_files) assert '.hc' == lctx.get_language('c').extension assert 'This is a test' == lctx.get_language('c').get_config_value('option_not_in_properties')
def test_lang_py_implicit(gen_paths, unique_name_evaluator): # type: ignore """ Generates and verifies JSON with values filtered using the python language support module. """ lctx = LanguageContext() generated_values = ptest_lang_py(gen_paths, True, unique_name_evaluator) lang_any = generated_values["tests"]["lang_any"] assert lang_any['id_0'] == 'zX003123_class__for_u2___zX0028zX002Aother_stuffzX002DzX0026zX002DsuchzX0029' assert lang_any['id_1'] == '_Reserved' assert lang_any['id_2'] == '__also_reserved' assert lang_any['id_3'] == 'register' assert lang_any['id_4'] == 'False_' assert lang_any['id_5'] == 'return_' assert lang_any['id_7'] == 'I_zX2764_UAVCAN' assert lang_any['id_8'] == 'zX0031_zX2764_UAVCAN' assert lang_any['id_9'] == 'str_' assert lang_any['id_A'] == 'strr' assert lang_any['id_B'] == 'UINT_FOO_MIN' assert lang_any['id_C'] == 'INT_C' assert lang_any['id_D'] == 'LC_Is_reserved' assert lang_any['id_E'] == 'NOT_ATOMIC_YO' assert lang_any['id_F'] == 'ATOMIC_YO' assert '_Flight__time' == py_filter_id(lctx.get_language('nunavut.lang.py'), Dummy('_Flight__time'))
def test_lang_cpp(gen_paths): # type: ignore """ Generates and verifies JSON with values filtered using the cpp language module. """ lctx = LanguageContext() generated_values = ptest_lang_cpp(gen_paths, True) lang_any = generated_values["tests"]["lang_any"] assert lang_any['id_0'] == '_123_class_for_u2_zX0028zX002Aother_stuffzX002DzX0026zX002DsuchzX0029' assert lang_any['id_1'] == '_reserved' assert lang_any['id_2'] == 'zX005FzX005Falso_reserved' assert lang_any['id_3'] == '_register' assert lang_any['id_4'] == 'False' assert lang_any['id_5'] == '_return' assert lang_any['id_7'] == 'I_zX2764_UAVCAN' assert lang_any['id_8'] == '_1_zX2764_UAVCAN' assert lang_any['id_9'] == 'str' assert lang_any['id_A'] == 'strr' assert lang_any['id_B'] == '_uINT_FOO_MIN' assert lang_any['id_C'] == '_iNT_C' assert lang_any['id_D'] == 'LC_Is_reserved' assert lang_any['id_E'] == 'NOT_ATOMIC_YO' assert lang_any['id_F'] == '_aTOMIC_YO' lang_cpp = lctx.get_language('nunavut.lang.cpp') assert '_flight_time' == cpp_filter_id(lang_cpp, Dummy('_Flight_time'))
def test_lang_c(gen_paths: Any, unique_name_evaluator: Any, implicit: bool, use_standard_types: bool, configurable_language_context_factory: Callable) -> None: """ Generates and verifies JSON with values filtered using the c language support module. """ lctx = LanguageContext() generated_values = ptest_lang_c(gen_paths, implicit, unique_name_evaluator, use_standard_types, configurable_language_context_factory) if implicit: lang_any = generated_values["tests"]["lang_any"] assert lang_any['id_0'] == 'zX003123_class__for_u2___zX0028zX002Aother_stuffzX002DzX0026zX002DsuchzX0029' assert lang_any['id_1'] == '_reserved' assert lang_any['id_2'] == '_also_reserved' assert lang_any['id_3'] == '_register' assert lang_any['id_4'] == 'False' assert lang_any['id_5'] == '_return' assert lang_any['id_7'] == 'I_zX2764_UAVCAN' assert lang_any['id_8'] == 'zX0031_zX2764_UAVCAN' assert lang_any['id_9'] == 'str' assert lang_any['id_A'] == '_strr' assert lang_any['id_B'] == '_uINT_FOO_MIN' assert lang_any['id_C'] == '_iNT_C' assert lang_any['id_D'] == 'LC_Is_reserved' assert lang_any['id_E'] == 'NOT_ATOMIC_YO' assert lang_any['id_F'] == '_aTOMIC_YO' assert lang_any['id_G'] == '_memory_order_yo' assert '_flight__time' == c_filter_id(lctx.get_language('nunavut.lang.c'), Dummy('_Flight__time'))
def test_python_filter_imports_for_array_type(gen_paths, stropping, sort): # type: ignore lctx = LanguageContext() lctx.config.set('nunavut.lang.py', 'enable_stropping', str(stropping)) uavcan_dir = str(gen_paths.dsdl_dir / pathlib.Path('uavcan')) type_map = read_namespace(str(gen_paths.dsdl_dir / pathlib.Path('new')), [uavcan_dir]) assert len(type_map) == 2 from nunavut.lang.py import filter_imports test_subject = next( filter(lambda type: (type.short_name == 'hotness'), type_map)) imports = filter_imports(lctx.get_language('nunavut.lang.py'), test_subject, sort=sort) assert len(imports) == 3 assert 'new' == imports[0] if stropping: assert 'uavcan.str_' == imports[1] else: assert 'uavcan.str' == imports[1] assert 'uavcan.time' == imports[2]
def test_filter_full_reference_name(gen_paths, language_name, stropping, namespace_separator): """ Cover issue #153 """ lctx = LanguageContext() ln_package_name = 'nunavut.lang.{}'.format(language_name) lctx.config.set(ln_package_name, 'enable_stropping', str(stropping)) ln = lctx.get_language(ln_package_name) import importlib from pydsdl import ServiceType, StructureType, Version test_subject_module = importlib.import_module(ln_package_name) service_request_type = StructureType( name='register.getting.tired.of.Python', version=Version(0, 1), attributes=[], deprecated=False, fixed_port_id=None, source_file_path=Path(), has_parent_service=True) service_response_type = StructureType( name='register.getting.tired.of.Python', version=Version(0, 1), attributes=[], deprecated=False, fixed_port_id=None, source_file_path=Path(), has_parent_service=True) service_type = ServiceType(service_request_type, service_response_type, None) # C++ is special because namespaces are part of the language and therefore each namespace # name must be stropped top_level_name = ('_register' if stropping and language_name == 'cpp' else 'register') assert test_subject_module.filter_full_reference_name( ln, service_type) == '{}.getting.tired.of_0_1'.format( top_level_name).replace('.', namespace_separator) assert test_subject_module.filter_full_reference_name( ln, service_request_type) == '{}.getting.tired.of.Python_0_1'.format(top_level_name)\ .replace('.', namespace_separator) assert test_subject_module.filter_full_reference_name( ln, service_response_type) == '{}.getting.tired.of.Python_0_1'.format(top_level_name)\ .replace('.', namespace_separator)
def test_python_filter_imports(gen_paths): # type: ignore lctx = LanguageContext() type_map = read_namespace(str(gen_paths.dsdl_dir / pathlib.Path('uavcan')), []) from nunavut.lang.py import filter_imports test_subject = next( filter(lambda type: (type.short_name == 'bar'), type_map)) imports = filter_imports(lctx.get_language('nunavut.lang.py'), test_subject) assert len(imports) == 1 assert 'uavcan.time' == imports[0]
def test_python_filter_short_reference_name(gen_paths): # type: ignore lctx = LanguageContext() type_map = read_namespace(str(gen_paths.dsdl_dir / pathlib.Path('uavcan')), []) from nunavut.lang.py import filter_short_reference_name test_subject = next( filter(lambda type: (type.short_name == 'SynchronizedTimestamp'), type_map)) full_reference_name = filter_short_reference_name( lctx.get_language('nunavut.lang.py'), test_subject) assert "SynchronizedTimestamp_1_0" == full_reference_name
def test_python_filter_imports_for_service_type(gen_paths, stropping, sort): # type: ignore lctx = LanguageContext() lctx.config.set('nunavut.lang.py', 'enable_stropping', str(stropping)) assert stropping == lctx.config.getboolean('nunavut.lang.py', 'enable_stropping') type_map = read_namespace(str(gen_paths.dsdl_dir / pathlib.Path('uavcan')), []) from nunavut.lang.py import filter_imports lctx.get_language('nunavut.lang.py').get_reserved_identifiers() test_subject = next( filter(lambda type: (type.short_name == 'bar_svc'), type_map)) imports = filter_imports(lctx.get_language('nunavut.lang.py'), test_subject, sort=sort) assert len(imports) == 2 if stropping: assert 'uavcan.str_' == imports[0] else: assert 'uavcan.str' == imports[0] assert 'uavcan.time' == imports[1]
def _make_filter_test_template(filter_or_list: typing.Union[typing.Callable, typing.List[typing.Callable]], body: str, expected: str, target_language_or_language_context: typing.Union[typing.Optional[str], LanguageContext], **globals: typing.Optional[typing.Dict[str, typing.Any]]) -> str: from nunavut.jinja import CodeGenEnvironment e = CodeGenEnvironment(loader=DictLoader({'test': body})) if globals is not None: e.globals.update(globals) if isinstance(target_language_or_language_context, LanguageContext): lctx = target_language_or_language_context else: lctx = LanguageContext(target_language_or_language_context) filters = (filter_or_list if isinstance(filter_or_list, list) else [filter_or_list]) for filter in filters: filter_name = filter.__name__[7:] if hasattr(filter, ENVIRONMENT_FILTER_ATTRIBUTE_NAME) and \ getattr(filter, ENVIRONMENT_FILTER_ATTRIBUTE_NAME): e.filters[filter_name] = functools.partial(filter, e) else: e.filters[filter_name] = filter if hasattr(filter, CONTEXT_FILTER_ATTRIBUTE_NAME) and getattr(filter, CONTEXT_FILTER_ATTRIBUTE_NAME): context = MagicMock() e.filters[filter_name] = functools.partial(filter, context) else: e.filters[filter_name] = filter if hasattr(filter, LANGUAGE_FILTER_ATTRIBUTE_NAME): language_name = getattr(filter, LANGUAGE_FILTER_ATTRIBUTE_NAME) e.filters[filter_name] = functools.partial(filter, lctx.get_language(language_name)) else: e.filters[filter_name] = filter target_language_resolved = lctx.get_target_language() if target_language_resolved is not None: e.globals.update(target_language_resolved.get_globals()) e.globals['options'].update(target_language_resolved.get_options()) rendered = str(e.get_template('test').render()) if expected != rendered: msg = 'Unexpected template output\n\texpected : {}\n\twas : {}'.format( expected.replace('\n', '\\n'), rendered.replace('\n', '\\n')) raise AssertionError(msg) return rendered
def test_python_filter_includes(gen_paths, stropping, sort): # type: ignore lctx = LanguageContext(target_language='cpp', extension='.h') lctx.config.set('nunavut.lang.cpp', 'enable_stropping', str(stropping)) uavcan_dir = (gen_paths.dsdl_dir / pathlib.Path('uavcan')).as_posix() type_map = read_namespace( (gen_paths.dsdl_dir / pathlib.Path('new')).as_posix(), [uavcan_dir]) from nunavut.lang.cpp import filter_includes test_subject = next( filter(lambda type: (type.short_name == 'hotness'), type_map)) imports = filter_includes(lctx.get_language('nunavut.lang.cpp'), test_subject, sort=sort) assert len(imports) == 5 def assert_path_in_imports(path: str) -> None: nonlocal imports assert path in imports if stropping: if sort: assert [ '"_new/malloc_1_0.h"', '"uavcan/str/bar_1_0.h"', '"uavcan/time/SynchronizedTimestamp_1_0.h"', '<array>', '<cstdint>' ] == imports else: map(assert_path_in_imports, ('"uavcan/time/SynchronizedTimestamp_1_0.h"', '"_new/malloc_1_0.h"', '"uavcan/str/bar_1_0.h"', '<array>', '<cstdint>')) elif sort: assert [ '"new/malloc_1_0.h"', '"uavcan/str/bar_1_0.h"', '"uavcan/time/SynchronizedTimestamp_1_0.h"', '<array>', '<cstdint>' ] == imports else: map(assert_path_in_imports, ('"uavcan/time/SynchronizedTimestamp_1_0.h"', '"new/malloc_1_0.h"', '"uavcan/str/bar_1_0.h"', '<array>', '<cstdint>'))