def __parse_object(self, name: str, values: dict) -> DataObject: required = {'_xpath', '_xref', '_ref'} path_value = required & values.keys() if len(path_value) != 1: error = f'QueryBuilder - DataObject({name}) is missing an anchor. Possible anchors are \'_xpath\', \'_ref\' or \'_xref\'' self.logger.error(error) raise ValueError(error) if '_xpath' in path_value: xpath = values['_xpath'].split(self.__path_separator)[-1] path = DataQuery.XPath(xpath) elif '_xref' in path_value: xpath = values['_xref'].split(self.__path_separator)[-1] path = DataQuery.XPath(xpath, True) else: ref = values['_ref'].split(self.__path_separator)[-1] path = DataQuery.Reference(ref) data_values = [] for key, value in values.items(): if key in required: continue if isinstance(value, dict): data_object = self.__parse_object(key, value) data_values.append(data_object) else: data_value = self.__parse_value(key, value) data_values.append(data_value) return DataObject(name, path, data_values)
def test_returns_empty_list_if_reference_not_found(only_value): data_object = DataObject('CAN Cluster', DataQuery.Reference('/Cluster/CAN1'), [DataValue('Name', DataQuery(DataQuery.XPath('./SHORT-NAME')))]) query_handler = QueryHandler() result = query_handler.handle_queries(arxml, [data_object]) assert result['CAN Cluster'] == []
def test_create_data_query_with_relative_xpath(): path = DataQuery.XPath('/SHORT-NAME') query = DataQuery(path) assert query.path == path assert query.value == 'text' assert query.format == DataQuery.Format.String
def test_create_data_query_with_absolute_xpath(): path = DataQuery.XPath('/AR-PACKAGE/SHORT-NAME', False) query = DataQuery(path) assert query.path == path assert query.value == 'text' assert query.format == DataQuery.Format.String
def test_create_data_query_with_default_value(): path = DataQuery.XPath('/SHORT-NAME') format = DataQuery.Format.Date query = DataQuery(path, format=format) assert query.path == path assert query.value == 'text' assert query.format == format
def test_returns_none_value_if_no_element_found_with_xpath(): data_object = DataObject('CAN Cluster', DataQuery.Reference('/Cluster/CAN'), [DataValue('Name', DataQuery(DataQuery.XPath('/SHORT-NAME')))]) query_handler = QueryHandler() result = query_handler.handle_queries(arxml, [data_object]) assert isinstance(result['CAN Cluster'], dict) assert result['CAN Cluster']['Name'] is None
def test_returns_none_value_if_no_attribute_found_with_specified_name(): data_object = DataObject('CAN Cluster', DataQuery.Reference('/Cluster/CAN'), [DataValue('UUID', DataQuery(DataQuery.XPath('.'), value='@S'))]) query_handler = QueryHandler() result = query_handler.handle_queries(arxml, [data_object]) assert isinstance(result['CAN Cluster'], dict) assert result['CAN Cluster']['UUID'] is None
def test_values_contain_data_objects(value): sub_object = DataObject('Timings', DataQuery.XPath('//TIMING'), [value]) data_object = DataObject('Signals', DataQuery.XPath('//I-SIGNALS'), [sub_object]) assert data_object.name == 'Signals' data_object_value = data_object.values[0] assert isinstance(data_object_value, DataObject) assert data_object_value == sub_object assert data_object_value.values[0] == value
def complex_object_by_xpath(): return DataObject('CAN Cluster', DataQuery.XPath('.//CAN-CLUSTER'), [ DataValue('Name', DataQuery(DataQuery.XPath('./SHORT-NAME'))), DataValue( 'Baudrate', DataQuery( DataQuery.XPath('CAN-CLUSTER-VARIANTS/CAN-CLUSTER-CONDITIONAL/BAUDRATE'), format=DataQuery.Format.Integer)), DataObject('Long Name', DataQuery.XPath('LONG-NAME/L-4'), [ DataValue('Language', DataQuery(DataQuery.XPath('.'), value='@L')), DataValue('Name', DataQuery(DataQuery.XPath('.'))) ]) ])
def __get_path(self, path: str) -> DataQuery.XPath: illegal_character = [self.__path_separator, self.__format_separator] if any(c in illegal_character for c in path): error = f'QueryBuilder - illegal characters found on path \'{path}\'. Path must not contain any of the following characters: \':\', \'>\'' self.logger.error(error) raise ValueError(error) if path[0] != '&': return DataQuery.XPath(path) else: if path[1] != '(': error = f'QueryBuilder - invalid syntax on inline reference \'{path}\'. Inline references must start with \'&(\'' self.logger.error(error) raise ValueError(error) return DataQuery.XPath(path, True)
def test_handle_inline_reference(): data_object = DataObject('SignalMapping', DataQuery.Reference('/PDU/TxMessage'), [ DataValue( 'Name', DataQuery( DataQuery.XPath( '&(I-SIGNAL-TO-PDU-MAPPINGS/I-SIGNAL-TO-I-PDU-MAPPING/I-SIGNAL-REF)SHORT-NAME', True))) ]) query_handler = QueryHandler() results = query_handler.handle_queries(arxml, [data_object]) assert isinstance(results, dict) assert isinstance(results['SignalMapping'], dict) assert results['SignalMapping']['Name'] == 'Signal1'
def __parse_query(self, text: str) -> DataQuery: if self.__path_separator not in text: path = self.__get_path(text) return DataQuery(path) raw_value_format, raw_path = text.split(self.__path_separator, 2) path = self.__get_path(raw_path) if self.__format_separator in raw_value_format: raw_value, raw_format = raw_value_format.split( self.__format_separator) value = self.__get_value(raw_value) format = self.__get_format(raw_format) else: value = self.__get_value(raw_value_format) format = DataQuery.Format.String return DataQuery(path, value, format)
def test_text_value_with_invalid_format(): config = { 'SimpleObject': { '_xpath': '/path/element', 'SimpleValue': 'text>bool:/SHORT-NAME' } } builder = QueryBuilder() data_objects = builder.build(config) data_value = data_objects[0].values[0] assert isinstance(data_value, DataValue) assert data_value.name == 'SimpleValue' assert data_value.query.path == DataQuery.XPath('/SHORT-NAME') assert data_value.query.value == 'text' assert data_value.query.format == DataQuery.Format.String
def test_attribute_value(): config = { 'SimpleObject': { '_xpath': '/path/element', 'SimpleValue': '@T:/SHORT-NAME' } } builder = QueryBuilder() data_objects = builder.build(config) data_value = data_objects[0].values[0] assert isinstance(data_value, DataValue) assert data_value.name == 'SimpleValue' assert data_value.query.path == DataQuery.XPath('/SHORT-NAME') assert data_value.query.value == '@T' assert data_value.query.format == DataQuery.Format.String
def test_invalid_value_raise_value_error(): with pytest.raises(ValueError): DataQuery(DataQuery.XPath('/SHORT-NAME'), 'something')
def test_create_data_query_with_default_format(path, value): query = DataQuery(path, value) assert query.path == path assert query.value == value assert query.format == DataQuery.Format.String
def test_create_data_query(path, value, format): query = DataQuery(path, value, format) assert query.path == path assert query.value == value assert query.format == format
import pytest from arxml_data_extractor.query.data_query import DataQuery @pytest.mark.parametrize("path, value, format", [ (DataQuery.Reference('/Signals/Signal1'), 'text', DataQuery.Format.String), (DataQuery.Reference('/Signals/Signal1'), 'tag', DataQuery.Format.Integer), (DataQuery.Reference('/Signals/Signal1'), '@', DataQuery.Format.Float), (DataQuery.Reference('/Signals/Signal1'), '@attribute', DataQuery.Format.Date), (DataQuery.XPath('/SHORT-NAME', False), 'text', DataQuery.Format.String), (DataQuery.XPath('/SHORT-NAME', True), 'tag', DataQuery.Format.Integer), (DataQuery.XPath('/SHORT-NAME'), '@', DataQuery.Format.Float), (DataQuery.XPath('/SHORT-NAME'), '@attribute', DataQuery.Format.Date), ]) def test_create_data_query(path, value, format): query = DataQuery(path, value, format) assert query.path == path assert query.value == value assert query.format == format @pytest.mark.parametrize("path, value", [ (DataQuery.Reference('/Signals/Signal1'), 'text'), (DataQuery.Reference('/Signals/Signal1'), '@attribute'), (DataQuery.XPath('/SHORT-NAME', True), 'tag'), (DataQuery.XPath('/SHORT-NAME'), '@'), ]) def test_create_data_query_with_default_format(path, value):
import pytest from arxml_data_extractor.query.data_query import DataQuery from arxml_data_extractor.query.data_value import DataValue @pytest.mark.parametrize("name, query", [ ('Signal', DataQuery(DataQuery.XPath('/SHORT-NAME'))), ('Signal123', DataQuery(DataQuery.XPath('/SHORT-NAME'))), ('Signal_123', DataQuery(DataQuery.XPath('/SHORT-NAME'))), ('Signal 123', DataQuery(DataQuery.XPath('/SHORT-NAME'))), ]) def test_create_data_value(name, query): value = DataValue(name, query) assert value.name == name assert value.query == query def test_none_query_raises_exception(): with pytest.raises(Exception): DataValue('name', None)
def test_empty_values_raises_value_error(): with pytest.raises(ValueError): DataObject('Signals', DataQuery.XPath('/SHORT-NAME'), [])
import pytest from arxml_data_extractor.query.data_query import DataQuery from arxml_data_extractor.query.data_object import DataObject from arxml_data_extractor.query.data_value import DataValue @pytest.fixture def value(): query = DataQuery(DataQuery.XPath('/SHORT-NAME')) return DataValue('Name', query) @pytest.mark.parametrize("name, path", [ ('Signal', DataQuery.XPath('//I-SIGNALS')), ('Signal123', DataQuery.XPath('//I-SIGNALS')), ('Signal_123', DataQuery.XPath('//I-SIGNALS')), ('Signal 123', DataQuery.XPath('//I-SIGNALS')), ('Signal 123', DataQuery.Reference('/Signals')), ]) def test_create_data_object(name, path, value): data_object = DataObject(name, path, [value]) assert data_object.name == name assert data_object.path == path assert data_object.values[0] == value def test_values_contain_data_objects(value): sub_object = DataObject('Timings', DataQuery.XPath('//TIMING'), [value]) data_object = DataObject('Signals', DataQuery.XPath('//I-SIGNALS'),
def multi_value_complex_object(): return DataObject('PDUs', DataQuery.XPath('.//I-SIGNAL-I-PDU'), [ DataValue('Name', DataQuery(DataQuery.XPath('SHORT-NAME'))), DataValue('Length', DataQuery(DataQuery.XPath('LENGTH'), format=DataQuery.Format.Integer)), DataValue( 'Unused Bit Pattern', (DataQuery(DataQuery.XPath('UNUSED-BIT-PATTERN'), format=DataQuery.Format.Integer))), DataObject('Timing Specification', DataQuery.XPath('./*/I-PDU-TIMING'), [ DataValue('Minimum Delay', DataQuery(DataQuery.XPath('MINIMUM-DELAY'), format=DataQuery.Format.Integer)), DataValue( 'Cyclic Timing', DataQuery( DataQuery.XPath( 'TRANSMISSION-MODE-DECLARATION/TRANSMISSION-MODE-TRUE-TIMING/CYCLIC-TIMING/TIME-PERIOD/VALUE' ), format=DataQuery.Format.Float)) ]), DataObject('Signal Mappings', DataQuery.XPath('.//I-SIGNAL-TO-I-PDU-MAPPING'), [ DataValue('Signal Name', DataQuery(DataQuery.XPath('SHORT-NAME'))), DataValue('Start Position', DataQuery(DataQuery.XPath('START-POSITION'), format=DataQuery.Format.Integer)), DataValue('Transfer Property', DataQuery(DataQuery.XPath('TRANSFER-PROPERTY'))), DataObject('Signal', DataQuery.XPath('I-SIGNAL-REF', is_reference=True), [ DataValue('Init Value', DataQuery(DataQuery.XPath('.//VALUE'), format=DataQuery.Format.Integer)), DataValue('Length', DataQuery(DataQuery.XPath('LENGTH'), format=DataQuery.Format.Integer)) ]) ]) ])
def test_invalid_values_raise_type_error(value): with pytest.raises(TypeError): DataObject('Signals', DataQuery.XPath('/SHORT-NAME'), value)
def test_xpath_containing_namespaces_raise_value_error(): with pytest.raises(ValueError): DataQuery(DataQuery.XPath('/ar:SHORT-NAME'))
def test_invalid_path_raises_exception(): with pytest.raises(TypeError): DataQuery('/SHORT-NAME')
def value(): query = DataQuery(DataQuery.XPath('/SHORT-NAME')) return DataValue('Name', query)
def test_reference_containing_namespaces_raise_value_error(): with pytest.raises(ValueError): DataQuery(DataQuery.Reference('/ar:Signals'))
def only_value(): return DataValue( 'CAN Cluster', DataQuery(DataQuery.Reference('/Cluster/CAN1'), 'text', DataQuery.Format.String))