[REF][WIP]Yaltik DSL : new tests, refacoring of xml_base, ADTs

This commit is contained in:
Fabien BOURGEOIS 2020-04-30 10:58:36 +02:00
parent 1202e3c6d4
commit cfb99c113d
4 changed files with 114 additions and 105 deletions

View File

@ -27,19 +27,19 @@ class TestXMLBase(unittest.TestCase):
def test_xmln(self):
# Tags
(xmln(), {'tag': '', 'attrs': {}, 'children': []}) |*> self.assertEquals
(xmln <| 'a tag' |> .get <| 'tag', 'a tag') |*> self.assertEquals
(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []}) |*> self.assertEquals
(xmln <| 'a tag' |> getattr$(?, 'tag'), 'a tag') |*> self.assertEquals
# Attrs
(xmln(attrs={'a good': 'one'}).get('attrs'), {'a good': 'one'}) |*> self.assertEquals
(xmln <**| {'attrs': {'a good': 'one'}} |> .get <| 'attrs', {'a good': 'one'}) |*> self.assertEquals
(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'}) |*> self.assertEquals
(xmln <**| {'attrs': {'a good': 'one'}} |> getattr$(?, 'attrs'), {'a good': 'one'}) |*> self.assertEquals
# Childrens
attrs ={'children': [1, 2, 3]}
(xmln <**| attrs |> .get <| 'children' == [1, 2, 3]) |> self.assertTrue
(xmln <**| attrs |> getattr$(?, 'children') == [1, 2, 3]) |> self.assertTrue
attrs = {'children': 'Some text'}
(xmln <**| attrs |> .get <| 'children' == ['Some text']) |> self.assertTrue
(xmln <**| attrs |> getattr$(?, 'children') == ['Some text']) |> self.assertTrue
try:
xmln <**| {'children': False}
@ -51,27 +51,35 @@ class TestXMLBase(unittest.TestCase):
parent = {'tag': 'root', 'attrs': {}, 'children': []} |> xmlroot
xmlc_par = xmlchild$ <| parent
(xmlc_par <| []) `self.assertEquals` None
# Bad arguments
try:
xmlc_par <| False
xmlc_par <| False
except TypeError as err:
'is not iterable' `self.assertIn` err.message
'Invalid arguments for xmlchild' `self.assertIn` err.message
try:
xmlc_par <| []
except TypeError as err:
'Invalid arguments for xmlchild' `self.assertIn` err.message
try: # Need XMLDictElement, not dict
xmlc_par <| [{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]
except TypeError as err:
'Invalid arguments for xmlchild' `self.assertIn` err.message
xmlc_par <| ['some text']
parent.text `self.assertEquals` 'some text'
xmlc_par <| [{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]
xmlc_par <| [xmln <**| {'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]
child = parent.iter <| 't' |> next
child.tag `self.assertEquals` 't'
child.attrib `self.assertEquals` {'a': 'b'}
(child |> list) `self.assertEquals` []
xmlc_par <| [{'tag': 't2', 'attrs': {1: 2}, 'children': []}]
xmlc_par <| [xmln <**| {'tag': 't2', 'attrs': {1: 2}, 'children': []}]
child = parent.iter <| 't2' |> next
child.attrib `self.assertEquals` {'1': '2'}
xmlc_par <| [{'tag': 'tchildren', 'attrs': {},
'children': [{'tag': 'subchild', 'attrs': {}, 'children': []}]}]
xmlc_par <| [xmln <**| {'tag': 'tchildren', 'attrs': {},
'children': [xmln <**| {'tag': 'subchild', 'attrs': {}, 'children': []}]}]
child = parent.iter <| 'tchildren' |> next
subchildren = (child |> list)
(subchildren |> len) `self.assertEquals` 1

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# __coconut_hash__ = 0xf82711d8
# __coconut_hash__ = 0x6e1a1e05
# Compiled with Coconut version 1.4.3 [Ernest Scribbler]
@ -52,19 +52,19 @@ class TestXMLBase(unittest.TestCase):
def test_xmln(self):
# Tags
(self.assertEquals)(*(xmln(), {'tag': '', 'attrs': {}, 'children': []}))
(self.assertEquals)(*((((xmln)('a tag')).get)('tag'), 'a tag'))
(self.assertEquals)(*(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []}))
(self.assertEquals)(*((_coconut_partial(getattr, {1: 'tag'}, 2))((xmln)('a tag')), 'a tag'))
# Attrs
(self.assertEquals)(*(xmln(attrs={'a good': 'one'}).get('attrs'), {'a good': 'one'}))
(self.assertEquals)(*((((xmln)(**{'attrs': {'a good': 'one'}})).get)('attrs'), {'a good': 'one'}))
(self.assertEquals)(*(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'}))
(self.assertEquals)(*((_coconut_partial(getattr, {1: 'attrs'}, 2))((xmln)(**{'attrs': {'a good': 'one'}})), {'a good': 'one'}))
# Childrens
attrs = {'children': [1, 2, 3]}
(self.assertTrue)(((((xmln)(**attrs)).get)('children') == [1, 2, 3]))
(self.assertTrue)(((_coconut_partial(getattr, {1: 'children'}, 2))((xmln)(**attrs)) == [1, 2, 3]))
attrs = {'children': 'Some text'}
(self.assertTrue)(((((xmln)(**attrs)).get)('children') == ['Some text']))
(self.assertTrue)(((_coconut_partial(getattr, {1: 'children'}, 2))((xmln)(**attrs)) == ['Some text']))
try:
(xmln)(**{'children': False})
@ -76,26 +76,34 @@ class TestXMLBase(unittest.TestCase):
parent = (xmlroot)({'tag': 'root', 'attrs': {}, 'children': []})
xmlc_par = (_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent)
(self.assertEquals)(((xmlc_par)([])), None)
# Bad arguments
try:
(xmlc_par)(False)
except TypeError as err:
(self.assertIn)('is not iterable', err.message)
(self.assertIn)('Invalid arguments for xmlchild', err.message)
try:
(xmlc_par)([])
except TypeError as err:
(self.assertIn)('Invalid arguments for xmlchild', err.message)
try: # Need XMLDictElement, not dict
(xmlc_par)([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}])
except TypeError as err:
(self.assertIn)('Invalid arguments for xmlchild', err.message)
(xmlc_par)(['some text'])
(self.assertEquals)(parent.text, 'some text')
(xmlc_par)([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}])
(xmlc_par)([(xmln)(**{'tag': 't', 'attrs': {'a': 'b'}, 'children': []})])
child = (next)((parent.iter)('t'))
(self.assertEquals)(child.tag, 't')
(self.assertEquals)(child.attrib, {'a': 'b'})
(self.assertEquals)(((list)(child)), [])
(xmlc_par)([{'tag': 't2', 'attrs': {1: 2}, 'children': []}])
(xmlc_par)([(xmln)(**{'tag': 't2', 'attrs': {1: 2}, 'children': []})])
child = (next)((parent.iter)('t2'))
(self.assertEquals)(child.attrib, {'1': '2'})
(xmlc_par)([{'tag': 'tchildren', 'attrs': {}, 'children': [{'tag': 'subchild', 'attrs': {}, 'children': []}]}])
(xmlc_par)([(xmln)(**{'tag': 'tchildren', 'attrs': {}, 'children': [(xmln)(**{'tag': 'subchild', 'attrs': {}, 'children': []})]})])
child = (next)((parent.iter)('tchildren'))
subchildren = ((list)(child))
(self.assertEquals)(((len)(subchildren)), 1)

View File

@ -23,16 +23,15 @@ from xml.dom import minidom
from typing import Dict, List, Union, Any
# TODO: ADT for XMLchild children**s**
# REF xml_write
# TODO: fix MyPy / typing
# REF and test xml_write
data XMLChildren(clist: List[Union[XMLDict, XMLText]])
data XMLDictElement(tag: XMLText, attrs: XMLAttrs, children: List[Any])
data XMLText(text: Union[str, unicode])
data XMLDict(tag: str, attrs: Dict[str, str], children: XMLChildren)
XMLText = Union[str, unicode]
XMLAttrs = Dict[str, str]
XMLChild = Union[XMLDictElement, XMLText, List]
data XMLTag(tag: str)
data XMLAttrs(attrs: Dict[str, str])
def xmlroot(tree: Dict[str, Any]) -> ET.Element:
""" Special process for root XML Node """
@ -41,30 +40,35 @@ def xmlroot(tree: Dict[str, Any]) -> ET.Element:
(rootel, tree['children']) |*> xmlchild
return rootel
def xmlchild(parent: ET.Element, children: Any) -> None:
def xmlchild(parent: ET.Element, children: XMLDictElement) -> None:
""" Handling of children (ie non root) XML Nodes with/o text and
subchildren (recursive) """
match _ is (str, unicode) in children:
parent.text = children
return
match _ is dict in children:
attrs = {unicode(k): unicode(v) for [k, v] in children['attrs'].items()}
new_parent = (parent, children['tag'], attrs) |*> ET.SubElement
subchildren = children['children']
if subchildren:
(new_parent, subchildren) |*> xmlchild
match _ is list in children:
((xmlchild$ <| parent), children) |*> map |> consume
case children:
match _ is XMLText:
parent.text = children
match _ is XMLDictElement:
attrs = {unicode(k): unicode(v) for [k, v] in children.attrs.items()}
new_parent = (parent, children.tag, attrs) |*> ET.SubElement
subchildren = children.children
if subchildren:
(new_parent, subchildren) |*> xmlchild
match _ is list:
((xmlchild$ <| parent), children) |*> map |> consume
else:
raise TypeError('Invalid arguments for xmlchild')
def xmln(tag: str = '',
attrs: Dict[str, str] = {},
children: Union[str, List] = []) -> Dict:
def xmln(tag: XMLText = '',
attrs: XMLAttrs = {},
children: Union[str, List] = []) -> XMLDictElement:
""" XMLNode with default children, not attributes """
match c is str in children:
return {'tag': tag, 'attrs': attrs, 'children': [c]}
else: match c is list in children:
return {'tag': tag, 'attrs': attrs, 'children': c}
case children:
match c is str:
return XMLDictElement(tag=tag, attrs=attrs, children=[c])
# return {'tag': tag, 'attrs': attrs, 'children': [c]}
match c is list:
return XMLDictElement(tag=tag, attrs=attrs, children=c)
# return {'tag': tag, 'attrs': attrs, 'children': c}
else:
raise TypeError('Invalid arguments for xmln')

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# __coconut_hash__ = 0xd881e1a
# __coconut_hash__ = 0x65805ba7
# Compiled with Coconut version 1.4.3 [Ernest Scribbler]
@ -49,9 +49,10 @@ from typing import Union
from typing import Any
# TODO: ADT for XMLchild children**s**
# TODO: fix MyPy / typing
# REF and test xml_write
class XMLChildren(_coconut.typing.NamedTuple("XMLChildren", [("clist", 'List[Union[XMLChildDict, XMLChildText]]')]), _coconut.object):
class XMLDictElement(_coconut.typing.NamedTuple("XMLDictElement", [("tag", 'XMLText'), ("attrs", 'XMLAttrs'), ("children", 'List[Any]')]), _coconut.object):
__slots__ = ()
__ne__ = _coconut.object.__ne__
def __eq__(self, other):
@ -59,21 +60,10 @@ class XMLChildren(_coconut.typing.NamedTuple("XMLChildren", [("clist", 'List[Uni
def __hash__(self):
return _coconut.tuple.__hash__(self) ^ hash(self.__class__)
class XMLChildText(_coconut.typing.NamedTuple("XMLChildText", [("text", 'Union[str, unicode]')]), _coconut.object):
__slots__ = ()
__ne__ = _coconut.object.__ne__
def __eq__(self, other):
return self.__class__ is other.__class__ and _coconut.tuple.__eq__(self, other)
def __hash__(self):
return _coconut.tuple.__hash__(self) ^ hash(self.__class__)
class XMLChildDict(_coconut.typing.NamedTuple("XMLChildDict", [("tag", 'str'), ("attrs", 'Dict[str, str]'), ("children", 'XMLChildren')]), _coconut.object):
__slots__ = ()
__ne__ = _coconut.object.__ne__
def __eq__(self, other):
return self.__class__ is other.__class__ and _coconut.tuple.__eq__(self, other)
def __hash__(self):
return _coconut.tuple.__hash__(self) ^ hash(self.__class__)
XMLText = Union[str, unicode]
XMLAttrs = Dict[str, str]
XMLChild = Union[XMLDictElement, XMLText, List]
def xmlroot(tree # type: Dict[str, Any]
@ -86,59 +76,58 @@ def xmlroot(tree # type: Dict[str, Any]
return rootel
def xmlchild(parent, # type: ET.Element
children # type: Any
children # type: XMLDictElement
):
# type: (...) -> None
""" Handling of children (ie non root) XML Nodes with/o text and
subchildren (recursive) """
_coconut_match_to = children
_coconut_match_check = False
if _coconut.isinstance(_coconut_match_to, (str, unicode)):
_coconut_match_check = True
if _coconut_match_check:
_coconut_case_check_0 = False
if _coconut.isinstance(_coconut_match_to, XMLText):
_coconut_case_check_0 = True
if _coconut_case_check_0:
parent.text = children
return
_coconut_match_to = children
_coconut_match_check = False
if _coconut.isinstance(_coconut_match_to, dict):
_coconut_match_check = True
if _coconut_match_check:
attrs = dict(((unicode(k)), (unicode(v))) for [k, v] in children['attrs'].items())
new_parent = (ET.SubElement)(*(parent, children['tag'], attrs))
subchildren = children['children']
if subchildren:
(xmlchild)(*(new_parent, subchildren))
_coconut_match_to = children
_coconut_match_check = False
if _coconut.isinstance(_coconut_match_to, list):
_coconut_match_check = True
if _coconut_match_check:
(consume)((map)(*(((_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent)), children)))
if not _coconut_case_check_0:
if _coconut.isinstance(_coconut_match_to, XMLDictElement):
_coconut_case_check_0 = True
if _coconut_case_check_0:
attrs = dict(((unicode(k)), (unicode(v))) for [k, v] in children.attrs.items())
new_parent = (ET.SubElement)(*(parent, children.tag, attrs))
subchildren = children.children
if subchildren:
(xmlchild)(*(new_parent, subchildren))
if not _coconut_case_check_0:
if _coconut.isinstance(_coconut_match_to, list):
_coconut_case_check_0 = True
if _coconut_case_check_0:
(consume)((map)(*(((_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent)), children)))
if not _coconut_case_check_0:
raise TypeError('Invalid arguments for xmlchild')
def xmln(tag='', # type: str
attrs={}, # type: Dict[str, str]
def xmln(tag='', # type: XMLText
attrs={}, # type: XMLAttrs
children=[] # type: Union[str, List]
):
# type: (...) -> Dict
# type: (...) -> XMLDictElement
""" XMLNode with default children, not attributes """
_coconut_match_to = children
_coconut_match_check = False
_coconut_case_check_1 = False
if _coconut.isinstance(_coconut_match_to, str):
c = _coconut_match_to
_coconut_match_check = True
if _coconut_match_check:
return {'tag': tag, 'attrs': attrs, 'children': [c]}
else:
_coconut_match_to = children
_coconut_match_check = False
_coconut_case_check_1 = True
if _coconut_case_check_1:
return XMLDictElement(tag=tag, attrs=attrs, children=[c])
# return {'tag': tag, 'attrs': attrs, 'children': [c]}
if not _coconut_case_check_1:
if _coconut.isinstance(_coconut_match_to, list):
c = _coconut_match_to
_coconut_match_check = True
if _coconut_match_check:
return {'tag': tag, 'attrs': attrs, 'children': c}
else:
raise TypeError('Invalid arguments for xmln')
_coconut_case_check_1 = True
if _coconut_case_check_1:
return XMLDictElement(tag=tag, attrs=attrs, children=c)
# return {'tag': tag, 'attrs': attrs, 'children': c}
if not _coconut_case_check_1:
raise TypeError('Invalid arguments for xmln')
def xml_write(filepath, tree):
""" Write XML file according to filename and given tree """