diff --git a/pyodata/v2/model.py b/pyodata/v2/model.py index 171c8c44..feb5257d 100644 --- a/pyodata/v2/model.py +++ b/pyodata/v2/model.py @@ -6,6 +6,7 @@ """ # pylint: disable=missing-docstring,too-many-instance-attributes,too-many-arguments,protected-access,no-member,line-too-long,logging-format-interpolation,too-few-public-methods,too-many-lines, too-many-public-methods +import base64 import collections import datetime from enum import Enum, auto @@ -194,7 +195,7 @@ def _build_types(): Types.Types = {} Types.register_type(Typ('Null', 'null')) - Types.register_type(Typ('Edm.Binary', 'binary\'\'')) + Types.register_type(Typ('Edm.Binary', 'binary\'\'', EdmBinaryTypTraits('(?:binary|X)'))) Types.register_type(Typ('Edm.Boolean', 'false', EdmBooleanTypTraits())) Types.register_type(Typ('Edm.Byte', '0')) Types.register_type(Typ('Edm.DateTime', 'datetime\'2000-01-01T00:00\'', EdmDateTimeTypTraits())) @@ -361,6 +362,18 @@ def from_literal(self, value): return matches.group(1) +class EdmBinaryTypTraits(EdmPrefixedTypTraits): + """Edm.Binary traits""" + + def to_literal(self, value): + binary = base64.b64decode(value, validate=True) + return f"binary'{base64.b16encode(binary).decode()}'" + + def from_literal(self, value): + binary = base64.b16decode(super().from_literal(value), casefold=True) + return base64.b64encode(binary).decode() + + class EdmDateTimeTypTraits(EdmPrefixedTypTraits): """Emd.DateTime traits diff --git a/tests/test_model_v2.py b/tests/test_model_v2.py index 27957d03..c3a33942 100644 --- a/tests/test_model_v2.py +++ b/tests/test_model_v2.py @@ -367,10 +367,19 @@ def test_traits(): """Test individual traits""" # generic - typ = Types.from_name('Edm.Binary') + typ = Types.from_name('Edm.Byte') assert repr(typ.traits) == 'TypTraits' - assert typ.traits.to_literal('bincontent') == 'bincontent' - assert typ.traits.from_literal('some bin content') == 'some bin content' + assert typ.traits.to_literal('85') == '85' + assert typ.traits.from_literal('170') == '170' + + # binary + typ = Types.from_name('Edm.Binary') + assert repr(typ.traits) == 'EdmBinaryTypTraits' + assert typ.traits.to_literal('wAHK/rqt8A0=') == 'binary\'C001CAFEBAADF00D\'' + assert typ.traits.from_literal('binary\'C001cafeBAADF00D\'') == 'wAHK/rqt8A0=' + assert typ.traits.from_literal('X\'C001cafeBAADF00D\'') == 'wAHK/rqt8A0=' + assert typ.traits.to_json('cHlvZGF0YQ==') == 'cHlvZGF0YQ==' + assert typ.traits.from_json('cHlvZGF0YQ==') == 'cHlvZGF0YQ==' # string typ = Types.from_name('Edm.String') @@ -1462,4 +1471,4 @@ def test_invalid_xml(xml_builder_factory): with pytest.raises(PyODataParserError) as e_info: MetadataBuilder(xml).build() - assert str(e_info.value) == 'Metadata document syntax error' \ No newline at end of file + assert str(e_info.value) == 'Metadata document syntax error'