diff --git a/yaltik_dsl/__coconut__.py b/yaltik_dsl/__coconut__.py index 410ec79..4e24dbf 100644 --- a/yaltik_dsl/__coconut__.py +++ b/yaltik_dsl/__coconut__.py @@ -628,6 +628,11 @@ def addpattern(base_func, **kwargs): raise _coconut.TypeError("addpattern() got unexpected keyword arguments " + _coconut.repr(kwargs)) return _coconut.functools.partial(_coconut_base_pattern_func, base_func) _coconut_addpattern = addpattern +def prepattern(base_func, **kwargs): + """DEPRECATED: Use addpattern instead.""" + def pattern_prepender(func): + return addpattern(func, **kwargs)(base_func) + return pattern_prepender class _coconut_partial(object): __slots__ = ("func", "_argdict", "_arglen", "_stargs", "keywords") if hasattr(_coconut.functools.partial, "__doc__"): @@ -709,6 +714,9 @@ def makedata(data_type, *args): if _coconut.issubclass(data_type, _coconut.str): return "".join(args) return data_type(args) +def datamaker(data_type): + """DEPRECATED: Use makedata instead.""" + return _coconut.functools.partial(makedata, data_type) def fmap(func, obj): """fmap(func, obj) creates a copy of obj with func applied to its contents. Override by defining obj.__fmap__(func).""" diff --git a/yaltik_dsl/__init__.py b/yaltik_dsl/__init__.py index da79dde..b577fa5 100644 --- a/yaltik_dsl/__init__.py +++ b/yaltik_dsl/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # -*- coding: utf-8 -*- -# __coconut_hash__ = 0x5812e74d +# __coconut_hash__ = 0xe22b9d74 # Compiled with Coconut version 1.4.3 [Ernest Scribbler] diff --git a/yaltik_dsl/odoo.py b/yaltik_dsl/odoo.py deleted file mode 100644 index 02a8648..0000000 --- a/yaltik_dsl/odoo.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x76f908d8 - -# Compiled with Coconut version 1.4.3 [Ernest Scribbler] - -""" Odoo XML DSL """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os.path as _coconut_os_path -_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_path) -from __coconut__ import * -from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match - - -# Compiled Coconut: ----------------------------------------------------------- - -# -*- coding: utf-8 -*- -# -# Copyright 2019-2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - - - -from .xml_base import xmlroot -from .xml_base import xmln - -# XML helpers functions and macros - -odoo = lambda *args: xmlroot(xmln('odoo', {}, *args)) - -def data(*args): - """ Allow optional args on data tag """ - if len(args) == 1: - return xmln('data', {}, *args) - return xmln('data', *args) - -function = lambda *args: xmln('function', *args) -record = lambda *args: xmln('record', *args) -form = lambda *args: xmln('form', *args) -tree = lambda *args: xmln('tree', *args) -search = lambda *args: xmln('search', *args) - -act_window = lambda *args: xmln('act_window', *args) - -def act_window_model(model, attrs): - """ Build new act_window from model and args """ - model_und = model.replace('.', '_') - model_cap = ' '.join([w.capitalize() for w in model.split('.')]) - xmlid = '{:{}}'.format(model_und, '') + '_view_action' - name = '{:{}}'.format(model_cap, '') + ' Action' - attrs.update({'id': xmlid, 'name': name, 'res_model': model}) - return act_window(attrs) - -menuitem = lambda *args: xmln('menuitem', *args) - -def menuitem_model(model, attrs): - """ Build new menuitem from model and attrs """ - model_und = model.replace('.', '_') - actionid = '{:{}}'.format(model_und, '') + '_view_action' - xmlid = '{:{}}'.format(model_und, '') + '_men' - attrs.update({'id': xmlid, 'action': actionid}) - return menuitem(attrs) - - -group = lambda *args: xmln('group', *args) -header = lambda *args: xmln('header', *args) -footer = lambda *args: xmln('footer', *args) -sheet = lambda *args: xmln('sheet', *args) -button = lambda *args: xmln('button', *args) -p = lambda *args: xmln('p', *args) -xpath = lambda *args: xmln('xpath', *args) -attribute = lambda name, value: xmln('attribute', {'name': name}, [value]) - -field = lambda *args: xmln('field', *args) -field_name = lambda name: field({'name': 'name'}, [name]) -field_model = lambda model: field({'name': 'model'}, [model]) -field_inherit = lambda xmlid: field({'name': 'inherit_id', 'ref': xmlid}, []) -field_arch = lambda *args: field({'name': 'arch', 'type': 'xml'}, *args) - -filter = lambda *args: xmln('filter', *args) - -view = lambda xmlid, children: record({'id': xmlid, 'model': 'ir.ui.view'}, children) - -def view_def(xmlid, name, model, arch): - """ View and first fields simplification with record xmlid, name, targeted model """ - return view(xmlid, [field_name(name), field_model(model), field_arch(arch)]) - -def view_new(view_type, model, arch): - """ View : new view definition, based on type (form, tree, ...) and model ID """ - model_und = model.replace('.', '_') - model_cap = ' '.join([w.capitalize() for w in model.split('.')]) - xmlid = '{:{}}'.format(model_und, '') + '_view_' + '{:{}}'.format(view_type, '') - name = '{:{}}'.format(model_cap, '') + ' ' + '{:{}}'.format(view_type.capitalize(), '') - return view_def(xmlid=xmlid, name=name, model=model, arch=arch) - -def view_inherit(filename, model, inherit, arch): - """ Inherited View simplification with name of the record, xmlid for model - and inherited view """ - module = filename.split('.')[2] - inherited = inherit.split('.')[1] - xmlid = '{:{}}'.format(inherited, '') + '_inherit_' + '{:{}}'.format(module, '') - model_cap = ' '.join([w.capitalize() for w in model.split('.')]) - name = '{:{}}'.format(model_cap, '') + ' Adaptations' - return view(xmlid, [field_name(name), field_model(model), field_inherit(inherit), field_arch(arch)]) - -def actions_server_code(xmlid, name, modelref, code): - """ Server actions of type code """ - return record({'id': xmlid, 'model': 'ir.actions.server'}, [field_name(name), field({'name': 'model_id', 'ref': modelref}, []), field({'name': 'state'}, ['code']), field({'name': 'code'}, [code])]) - -def client_action_multi(xmlid, name, model, action): - """ Client action multi (ir.values), with own xmlid, name, targeted model - and action """ - action = "'ir.actions.server,%d'%" + '{:{}}'.format(action, '') - return record({'id': xmlid, 'model': 'ir.values'}, [field_name(name), field({'name': 'key2', 'eval': "'client_action_multi'"}, []), field({'name': 'model', 'eval': "'" + model + "'"}, []), field({'name': 'value', 'eval': action})]) diff --git a/yaltik_dsl/odoo_dsl.coco b/yaltik_dsl/odoo_dsl.coco index c49a291..9536634 100644 --- a/yaltik_dsl/odoo_dsl.coco +++ b/yaltik_dsl/odoo_dsl.coco @@ -89,38 +89,39 @@ def view(xmlid: Text, children: List) -> XMLDictElement: def view_def(xmlid: Text, name: Text, model: Text, arch: List) -> XMLDictElement: return (xmlid, [field_name(name), field_model(model), field_arch(arch)]) |*> view -def view_new(view_type, model, arch): +def view_new(view_type: Text, model: Text, arch: List) -> XMLDictElement: """ View : new view definition, based on type (form, tree, ...) and model ID """ - model_und = model.replace('.', '_') - model_cap = ' '.join([w.capitalize() for w in model.split('.')]) - xmlid = '{:{}}'.format(model_und, '') + '_view_' + '{:{}}'.format(view_type, '') - name = '{:{}}'.format(model_cap, '') + ' ' + '{:{}}'.format(view_type.capitalize(), '') - return view_def(xmlid=xmlid, name=name, model=model, arch=arch) + model_und = ('.', '_') |*> model.replace + model_cap = ('.' |> model.split |> map$(-> _.capitalize()) |> list |> ' '.join) + xmlid = "%s_view_%s" % (model_und, view_type) + name = (model_cap, view_type.capitalize()) |> ' '.join + return (xmlid, name, model, arch) |*> view_def -def view_inherit(filename, model, inherit, arch): +def view_inherit(filename: Text, model: Text, inherit: Text, arch: List) -> XMLDictElement: """ Inherited View simplification with name of the record, xmlid for model and inherited view """ - module = filename.split('.')[2] - inherited = inherit.split('.')[1] - xmlid = '{:{}}'.format(inherited, '') + '_inherit_' + '{:{}}'.format( - module, '') - model_cap = ' '.join([w.capitalize() for w in model.split('.')]) - name = '{:{}}'.format(model_cap, '') + ' Adaptations' - return view(xmlid, [field_name(name), field_model(model), - field_inherit(inherit), field_arch(arch)]) + module = '.' |> filename.split |> .[2] + inherited = '.' |> inherit.split |> .[1] + xmlid = '%s_inherit_%s' % (inherited, module) + model_cap = ('.' |> model.split |> map$(-> _.capitalize()) |> list |> ' '.join) + name = '%s Adaptations' % model_cap + return view(xmlid, [name |> field_name, model |> field_model, + inherit |> field_inherit, arch |> field_arch]) -def actions_server_code(xmlid, name, modelref, code): +def action_server_code(xmlid: Text, name: Text, modelref: Text, code: Text) -> XMLDictElement: """ Server actions of type code """ - return record({'id': xmlid, 'model': 'ir.actions.server'}, [ - field_name(name), field({'name': 'model_id', 'ref': modelref}, [ - ]), field({'name': 'state'}, ['code']), field({'name': 'code'}, [code])]) + children = [name |> field_name, + ({'name': 'model_id', 'ref': modelref}, []) |*> field, + ({'name': 'state'}, ['code']) |*> field, + ({'name': 'code'}, [code]) |*> field] + return ({'id': xmlid, 'model': 'ir.actions.server'}, children) |*> record -def client_action_multi(xmlid, name, model, action): +def client_action_multi(xmlid: Text, name: Text, model: Text, action: Text) -> XMLDictElement: """ Client action multi (ir.values), with own xmlid, name, targeted model and action """ - action = u"'ir.actions.server,%d'%" + '{:{}}'.format(action, '') - return record({'id': xmlid, 'model': 'ir.values'}, - [field_name(name), - field({'name': 'key2', 'eval': u"'client_action_multi'"}, []), - field({'name': 'model', 'eval': u"'" + model + u"'"}, []), - field({'name': 'value', 'eval': action})]) + action = action |> "'ir.actions.server,%d'%{}".format + children = [name |> field_name, + {'name': 'key2', 'eval': "'client_action_multi'"} |> field, + {'name': 'model', 'eval': "'%s'" % model} |> field, + {'name': 'value', 'eval': action} |> field] + return ({'id': xmlid, 'model': 'ir.values'}, children) |*> record diff --git a/yaltik_dsl/odoo_dsl.py b/yaltik_dsl/odoo_dsl.py new file mode 100644 index 0000000..cdd5164 --- /dev/null +++ b/yaltik_dsl/odoo_dsl.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# __coconut_hash__ = 0x646b8885 + +# Compiled with Coconut version 1.4.3 [Ernest Scribbler] + +""" Odoo XML DSL """ + +# Coconut Header: ------------------------------------------------------------- + +from __future__ import print_function, absolute_import, unicode_literals, division +import sys as _coconut_sys, os.path as _coconut_os_path +_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) +_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") +if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: + del _coconut_sys.modules[b"__coconut__"] +_coconut_sys.path.insert(0, _coconut_file_path) +from __coconut__ import * +from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match + + +# Compiled Coconut: ----------------------------------------------------------- + +# -*- coding: utf-8 -*- +# +# Copyright 2019-2020 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + + +from typing import Text +from typing import Dict +from xml_base import XMLAttrs +from xml_base import XMLDictElement +from xml_base import xmlroot +from xml_base import xmln + +# XML helpers functions and macros + +# Odoo root XML Node +def odoo(children # type: Dict + ): +# type: (...) -> ET.Element + return (xmlroot)({'tag': 'odoo', 'attrs': {}, 'children': children}) + +# Special data Node +def data(*args): + """ Allow optional args on data tag """ + if (len)(args) == 1: + args = (list)(args) + args.insert(0, {}) + return xmln('data', *args) + +# Aliases +def function(*args): +# type: (...) -> XMLDictElement + return xmln('function', *args) +def record(*args): +# type: (...) -> XMLDictElement + return (_coconut_partial(xmln, {}, 1, *args))('record') +def form(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('form'))(*args) +def tree(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('tree'))(*args) +def search(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('search'))(*args) + +# Actions +def act_window(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('act_window'))(*args) +def act_window_model(model, # type: Text + attrs # type: XMLAttrs + ): +# type: (...) -> XMLDictElement + """ Build new act_window from model and args """ + xmlid = '%s_view_action' % ((model.replace)(*('.', '_'))) + name = '%s Action' % ((' '.join)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) + attrs_clone = attrs.copy() # Avoid side-effect + (attrs_clone.update)({'id': xmlid, 'name': name, 'res_model': model}) + return act_window(attrs_clone) + +# Menus +def menuitem(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('menuitem'))(*args) +def menuitem_model(model, # type: Text + attrs # type: XMLAttrs + ): +# type: (...) -> XMLDictElement + """ Build new menuitem from model and attrs """ + model_und = (model.replace)(*('.', '_')) + xmlid = '%s_menu' % model_und + actionid = '%s_view_action' % model_und + attrs_clone = attrs.copy() # Avoid side-effect + (attrs_clone.update)({'id': xmlid, 'action': actionid}) + return menuitem(attrs_clone) + +# Form aliases +def group(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('group'))(*args) +def header(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('header'))(*args) +def footer(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('footer'))(*args) +def sheet(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('sheet'))(*args) +def button(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('button'))(*args) +def p(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('p'))(*args) +def xpath(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('xpath'))(*args) +def attribute(name, # type: Text + value # type: Text + ): +# type: (...) -> XMLDictElement + return (xmln)(*('attribute', {'name': name}, [value])) + +# Fields +def field(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('field'))(*args) +def field_name(name # type: Text + ): +# type: (...) -> XMLDictElement + return (field)(*({'name': 'name'}, [name])) +def field_model(model # type: Text + ): +# type: (...) -> XMLDictElement + return (field)(*({'name': 'model'}, [model])) +def field_inherit(xmlid # type: Text + ): +# type: (...) -> XMLDictElement + return (field)(*({'name': 'inherit_id', 'ref': xmlid}, [])) +def field_arch(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, field))({'name': 'arch', 'type': 'xml'}))(*args) + +# Search +def filter(*args): +# type: (...) -> XMLDictElement + return ((_coconut.functools.partial(_coconut.functools.partial, xmln))('filter'))(*args) + +# Views +def view(xmlid, # type: Text + children # type: List + ): +# type: (...) -> XMLDictElement + return (record)(*({'id': xmlid, 'model': 'ir.ui.view'}, children)) + +def view_def(xmlid, # type: Text + name, # type: Text + model, # type: Text + arch # type: List + ): +# type: (...) -> XMLDictElement + return (view)(*(xmlid, [field_name(name), field_model(model), field_arch(arch)])) + +def view_new(view_type, # type: Text + model, # type: Text + arch # type: List + ): +# type: (...) -> XMLDictElement + """ View : new view definition, based on type (form, tree, ...) and model ID """ + model_und = (model.replace)(*('.', '_')) + model_cap = ((' '.join)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) + xmlid = "%s_view_%s" % (model_und, view_type) + name = (' '.join)((model_cap, view_type.capitalize())) + return (view_def)(*(xmlid, name, model, arch)) + +def view_inherit(filename, # type: Text + model, # type: Text + inherit, # type: Text + arch # type: List + ): +# type: (...) -> XMLDictElement + """ Inherited View simplification with name of the record, xmlid for model + and inherited view """ + module = ((filename.split)('.'))[2] + inherited = ((inherit.split)('.'))[1] + xmlid = '%s_inherit_%s' % (inherited, module) + model_cap = ((' '.join)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) + name = '%s Adaptations' % model_cap + return view(xmlid, [(field_name)(name), (field_model)(model), (field_inherit)(inherit), (field_arch)(arch)]) + +def action_server_code(xmlid, # type: Text + name, # type: Text + modelref, # type: Text + code # type: Text + ): +# type: (...) -> XMLDictElement + """ Server actions of type code """ + children = [(field_name)(name), (field)(*({'name': 'model_id', 'ref': modelref}, [])), (field)(*({'name': 'state'}, ['code'])), (field)(*({'name': 'code'}, [code]))] + return (record)(*({'id': xmlid, 'model': 'ir.actions.server'}, children)) + +def client_action_multi(xmlid, # type: Text + name, # type: Text + model, # type: Text + action # type: Text + ): +# type: (...) -> XMLDictElement + """ Client action multi (ir.values), with own xmlid, name, targeted model + and action """ + action = ("'ir.actions.server,%d'%{}".format)(action) + children = [(field_name)(name), (field)({'name': 'key2', 'eval': "'client_action_multi'"}), (field)({'name': 'model', 'eval': "'%s'" % model}), (field)({'name': 'value', 'eval': action})] + return (record)(*({'id': xmlid, 'model': 'ir.values'}, children)) diff --git a/yaltik_dsl/test_odoo.coco b/yaltik_dsl/test_odoo.coco index 1cc59ad..10d96a6 100644 --- a/yaltik_dsl/test_odoo.coco +++ b/yaltik_dsl/test_odoo.coco @@ -108,7 +108,7 @@ class TestOdooBase(unittest.TestCase): element.attrs['type'] `self.assertEquals` 'xml' element.children |> self.assertFalse - def test_views(self): + def test_view(self): element = od.view('view_xmlid', []) element `self.assertIsInstance` XMLDictElement element.tag `self.assertEquals` 'record' @@ -116,6 +116,7 @@ class TestOdooBase(unittest.TestCase): element.attrs['model'] `self.assertEquals` 'ir.ui.view' element.children |> self.assertFalse + def test_view_def(self): element = od.view_def('view_xmlid', 'View', 'sample.model', []) element `self.assertIsInstance` XMLDictElement element.tag `self.assertEquals` 'record' @@ -136,7 +137,99 @@ class TestOdooBase(unittest.TestCase): element.children[2].attrs['type'] `self.assertEquals` 'xml' element.children[2].children |> self.assertFalse - def test_actions(self): pass + def test_view_new(self): + element = od.view_new('tree', 'sample.model', []) + element `self.assertIsInstance` XMLDictElement + element.tag `self.assertEquals` 'record' + element.attrs['id'] `self.assertEquals` 'sample_model_view_tree' + element.attrs['model'] `self.assertEquals` 'ir.ui.view' + (element.children |> len) `self.assertEquals` 3 + element.children[0] `self.assertIsInstance` XMLDictElement + element.children[0].tag `self.assertEquals` 'field' + element.children[0].attrs['name'] `self.assertEquals` 'name' + element.children[0].children `self.assertEquals` ['Sample Model Tree'] + element.children[1] `self.assertIsInstance` XMLDictElement + element.children[1].tag `self.assertEquals` 'field' + element.children[1].attrs['name'] `self.assertEquals` 'model' + element.children[1].children `self.assertEquals` ['sample.model'] + element.children[2] `self.assertIsInstance` XMLDictElement + element.children[2].tag `self.assertEquals` 'field' + element.children[2].attrs['name'] `self.assertEquals` 'arch' + element.children[2].attrs['type'] `self.assertEquals` 'xml' + element.children[2].children |> self.assertFalse + + def test_view_inherit(self): + element = od.view_inherit('odoo.addons.module', 'sample.model', 'parent.view', []) + element `self.assertIsInstance` XMLDictElement + element.tag `self.assertEquals` 'record' + element.attrs['id'] `self.assertEquals` 'view_inherit_module' + element.attrs['model'] `self.assertEquals` 'ir.ui.view' + (element.children |> len) `self.assertEquals` 4 + element.children[0] `self.assertIsInstance` XMLDictElement + element.children[0].tag `self.assertEquals` 'field' + element.children[0].attrs['name'] `self.assertEquals` 'name' + element.children[0].children `self.assertEquals` ['Sample Model Adaptations'] + element.children[1] `self.assertIsInstance` XMLDictElement + element.children[1].tag `self.assertEquals` 'field' + element.children[1].attrs['name'] `self.assertEquals` 'model' + element.children[1].children `self.assertEquals` ['sample.model'] + element.children[2] `self.assertIsInstance` XMLDictElement + element.children[2].tag `self.assertEquals` 'field' + element.children[2].attrs['name'] `self.assertEquals` 'inherit_id' + element.children[2].children |> self.assertFalse + element.children[3] `self.assertIsInstance` XMLDictElement + element.children[3].tag `self.assertEquals` 'field' + element.children[3].attrs['name'] `self.assertEquals` 'arch' + element.children[3].attrs['type'] `self.assertEquals` 'xml' + element.children[3].children |> self.assertFalse + + def test_action_server_code(self): + element = od.action_server_code('sample.xmlid', 'Code', 'sample.model', + '''record.do_something()''') + element `self.assertIsInstance` XMLDictElement + element.tag `self.assertEquals` 'record' + element.attrs['id'] `self.assertEquals` 'sample.xmlid' + element.attrs['model'] `self.assertEquals` 'ir.actions.server' + (element.children |> len) `self.assertEquals` 4 + element.children[0] `self.assertIsInstance` XMLDictElement + element.children[0].tag `self.assertEquals` 'field' + element.children[0].attrs['name'] `self.assertEquals` 'name' + element.children[0].children `self.assertEquals` ['Code'] + element.children[1] `self.assertIsInstance` XMLDictElement + element.children[1].tag `self.assertEquals` 'field' + element.children[1].attrs['name'] `self.assertEquals` 'model_id' + element.children[1].attrs['ref'] `self.assertEquals` 'sample.model' + element.children[1].children |> self.assertFalse + element.children[2].tag `self.assertEquals` 'field' + element.children[2].attrs['name'] `self.assertEquals` 'state' + element.children[2].children `self.assertEquals` ['code'] + element.children[3].tag `self.assertEquals` 'field' + element.children[3].attrs['name'] `self.assertEquals` 'code' + element.children[3].children `self.assertEquals` ['record.do_something()'] + + def test_client_action_multi(self): + element = od.client_action_multi('sample.xmlid', 'Multi', 'sample.model', 'sample.action') + element `self.assertIsInstance` XMLDictElement + element.tag `self.assertEquals` 'record' + element.attrs['id'] `self.assertEquals` 'sample.xmlid' + element.attrs['model'] `self.assertEquals` 'ir.values' + (element.children |> len) `self.assertEquals` 4 + element.children[0] `self.assertIsInstance` XMLDictElement + element.children[0].tag `self.assertEquals` 'field' + element.children[0].attrs['name'] `self.assertEquals` 'name' + element.children[0].children `self.assertEquals` ['Multi'] + element.children[1] `self.assertIsInstance` XMLDictElement + element.children[1].tag `self.assertEquals` 'field' + element.children[1].attrs['name'] `self.assertEquals` 'key2' + element.children[1].attrs['eval'] `self.assertEquals` "'client_action_multi'" + element.children[1].children |> self.assertFalse + element.children[2].tag `self.assertEquals` 'field' + element.children[2].attrs['name'] `self.assertEquals` 'model' + element.children[2].attrs['eval'] `self.assertEquals` "'sample.model'" + element.children[3].tag `self.assertEquals` 'field' + element.children[3].attrs['name'] `self.assertEquals` 'value' + element.children[3].attrs['eval'] `self.assertEquals` "'ir.actions.server,%d'%sample.action" + if __name__ == '__main__': unittest.main() diff --git a/yaltik_dsl/test_odoo.py b/yaltik_dsl/test_odoo.py new file mode 100644 index 0000000..7afa06b --- /dev/null +++ b/yaltik_dsl/test_odoo.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# __coconut_hash__ = 0xdf0c086d + +# Compiled with Coconut version 1.4.3 [Ernest Scribbler] + +""" Odoo Helpers tests """ + +# Coconut Header: ------------------------------------------------------------- + +from __future__ import print_function, absolute_import, unicode_literals, division +import sys as _coconut_sys, os.path as _coconut_os_path +_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) +_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") +if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: + del _coconut_sys.modules[b"__coconut__"] +_coconut_sys.path.insert(0, _coconut_file_path) +from __coconut__ import * +from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match + + +# Compiled Coconut: ----------------------------------------------------------- + +# -*- coding: utf-8 -*- +# +# Copyright 2020 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + + +import unittest +import xml.etree.ElementTree as ET +from xml_base import XMLDictElement +import odoo_dsl as od + +class TestOdooBase(unittest.TestCase): + """ Odoo Helpers tests """ + + def test_odoo(self): + element = od.odoo([]) + (self.assertIsInstance)(element, ET.Element) + (self.assertEquals)(element.tag, 'odoo') + + def test_data(self): + element = od.data([]) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'data') + (self.assertEquals)(element.attrs, {}) + + element = od.data({"one": "attribute"}, []) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'data') + (self.assertEquals)(element.attrs, {"one": "attribute"}) + + def test_aliases(self): + """ Test simple aliases to xmln """ + element = od.record({"one": "attribute"}, 'A child') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs, {"one": "attribute"}) + (self.assertEquals)(element.children, ['A child']) + + element = od.tree() + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'tree') + + def test_act_window_model(self): + element = (od.act_window_model)(*('sample.model', {'view_type': 'form'})) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'act_window') + (self.assertEquals)(element.attrs['view_type'], 'form') + (self.assertEquals)(element.attrs['id'], 'sample_model_view_action') + (self.assertEquals)(element.attrs['res_model'], 'sample.model') + (self.assertEquals)(element.attrs['name'], 'Sample Model Action') + + def test_menunitem_model(self): + element = (od.menuitem_model)(*('sample.model', {'groups': 'base.user_employee'})) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'menuitem') + (self.assertEquals)(element.attrs['groups'], 'base.user_employee') + (self.assertEquals)(element.attrs['id'], 'sample_model_menu') + (self.assertEquals)(element.attrs['action'], 'sample_model_view_action') + + def test_attribute(self): + element = od.attribute('invisible', "1") + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'attribute') + (self.assertEquals)(element.attrs['name'], 'invisible') + (self.assertEquals)(element.children, ["1"]) + + def test_fields(self): + element = od.field({"one": "attribute"}, 'A child') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'field') + + element = (od.field_name)('A name') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'field') + (self.assertEquals)(element.attrs['name'], 'name') + (self.assertEquals)(element.children, ['A name']) + + element = (od.field_model)('sample.model') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'field') + (self.assertEquals)(element.attrs['name'], 'model') + (self.assertEquals)(element.children, ['sample.model']) + + element = (od.field_inherit)('module.xml_view') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'field') + (self.assertEquals)(element.attrs['name'], 'inherit_id') + (self.assertEquals)(element.attrs['ref'], 'module.xml_view') + (self.assertFalse)(element.children) + + element = od.field_arch() + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'field') + (self.assertEquals)(element.attrs['name'], 'arch') + (self.assertEquals)(element.attrs['type'], 'xml') + (self.assertFalse)(element.children) + + def test_view(self): + element = od.view('view_xmlid', []) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'view_xmlid') + (self.assertEquals)(element.attrs['model'], 'ir.ui.view') + (self.assertFalse)(element.children) + + def test_view_def(self): + element = od.view_def('view_xmlid', 'View', 'sample.model', []) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'view_xmlid') + (self.assertEquals)(element.attrs['model'], 'ir.ui.view') + (self.assertEquals)(((len)(element.children)), 3) + (self.assertIsInstance)(element.children[0], XMLDictElement) + (self.assertEquals)(element.children[0].tag, 'field') + (self.assertEquals)(element.children[0].attrs['name'], 'name') + (self.assertEquals)(element.children[0].children, ['View']) + (self.assertIsInstance)(element.children[1], XMLDictElement) + (self.assertEquals)(element.children[1].tag, 'field') + (self.assertEquals)(element.children[1].attrs['name'], 'model') + (self.assertEquals)(element.children[1].children, ['sample.model']) + (self.assertIsInstance)(element.children[2], XMLDictElement) + (self.assertEquals)(element.children[2].tag, 'field') + (self.assertEquals)(element.children[2].attrs['name'], 'arch') + (self.assertEquals)(element.children[2].attrs['type'], 'xml') + (self.assertFalse)(element.children[2].children) + + def test_view_new(self): + element = od.view_new('tree', 'sample.model', []) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'sample_model_view_tree') + (self.assertEquals)(element.attrs['model'], 'ir.ui.view') + (self.assertEquals)(((len)(element.children)), 3) + (self.assertIsInstance)(element.children[0], XMLDictElement) + (self.assertEquals)(element.children[0].tag, 'field') + (self.assertEquals)(element.children[0].attrs['name'], 'name') + (self.assertEquals)(element.children[0].children, ['Sample Model Tree']) + (self.assertIsInstance)(element.children[1], XMLDictElement) + (self.assertEquals)(element.children[1].tag, 'field') + (self.assertEquals)(element.children[1].attrs['name'], 'model') + (self.assertEquals)(element.children[1].children, ['sample.model']) + (self.assertIsInstance)(element.children[2], XMLDictElement) + (self.assertEquals)(element.children[2].tag, 'field') + (self.assertEquals)(element.children[2].attrs['name'], 'arch') + (self.assertEquals)(element.children[2].attrs['type'], 'xml') + (self.assertFalse)(element.children[2].children) + + def test_view_inherit(self): + element = od.view_inherit('odoo.addons.module', 'sample.model', 'parent.view', []) + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'view_inherit_module') + (self.assertEquals)(element.attrs['model'], 'ir.ui.view') + (self.assertEquals)(((len)(element.children)), 4) + (self.assertIsInstance)(element.children[0], XMLDictElement) + (self.assertEquals)(element.children[0].tag, 'field') + (self.assertEquals)(element.children[0].attrs['name'], 'name') + (self.assertEquals)(element.children[0].children, ['Sample Model Adaptations']) + (self.assertIsInstance)(element.children[1], XMLDictElement) + (self.assertEquals)(element.children[1].tag, 'field') + (self.assertEquals)(element.children[1].attrs['name'], 'model') + (self.assertEquals)(element.children[1].children, ['sample.model']) + (self.assertIsInstance)(element.children[2], XMLDictElement) + (self.assertEquals)(element.children[2].tag, 'field') + (self.assertEquals)(element.children[2].attrs['name'], 'inherit_id') + (self.assertFalse)(element.children[2].children) + (self.assertIsInstance)(element.children[3], XMLDictElement) + (self.assertEquals)(element.children[3].tag, 'field') + (self.assertEquals)(element.children[3].attrs['name'], 'arch') + (self.assertEquals)(element.children[3].attrs['type'], 'xml') + (self.assertFalse)(element.children[3].children) + + def test_action_server_code(self): + element = od.action_server_code('sample.xmlid', 'Code', 'sample.model', '''record.do_something()''') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'sample.xmlid') + (self.assertEquals)(element.attrs['model'], 'ir.actions.server') + (self.assertEquals)(((len)(element.children)), 4) + (self.assertIsInstance)(element.children[0], XMLDictElement) + (self.assertEquals)(element.children[0].tag, 'field') + (self.assertEquals)(element.children[0].attrs['name'], 'name') + (self.assertEquals)(element.children[0].children, ['Code']) + (self.assertIsInstance)(element.children[1], XMLDictElement) + (self.assertEquals)(element.children[1].tag, 'field') + (self.assertEquals)(element.children[1].attrs['name'], 'model_id') + (self.assertEquals)(element.children[1].attrs['ref'], 'sample.model') + (self.assertFalse)(element.children[1].children) + (self.assertEquals)(element.children[2].tag, 'field') + (self.assertEquals)(element.children[2].attrs['name'], 'state') + (self.assertEquals)(element.children[2].children, ['code']) + (self.assertEquals)(element.children[3].tag, 'field') + (self.assertEquals)(element.children[3].attrs['name'], 'code') + (self.assertEquals)(element.children[3].children, ['record.do_something()']) + + def test_client_action_multi(self): + element = od.client_action_multi('sample.xmlid', 'Multi', 'sample.model', 'sample.action') + (self.assertIsInstance)(element, XMLDictElement) + (self.assertEquals)(element.tag, 'record') + (self.assertEquals)(element.attrs['id'], 'sample.xmlid') + (self.assertEquals)(element.attrs['model'], 'ir.values') + (self.assertEquals)(((len)(element.children)), 4) + (self.assertIsInstance)(element.children[0], XMLDictElement) + (self.assertEquals)(element.children[0].tag, 'field') + (self.assertEquals)(element.children[0].attrs['name'], 'name') + (self.assertEquals)(element.children[0].children, ['Multi']) + (self.assertIsInstance)(element.children[1], XMLDictElement) + (self.assertEquals)(element.children[1].tag, 'field') + (self.assertEquals)(element.children[1].attrs['name'], 'key2') + (self.assertEquals)(element.children[1].attrs['eval'], "'client_action_multi'") + (self.assertFalse)(element.children[1].children) + (self.assertEquals)(element.children[2].tag, 'field') + (self.assertEquals)(element.children[2].attrs['name'], 'model') + (self.assertEquals)(element.children[2].attrs['eval'], "'sample.model'") + (self.assertEquals)(element.children[3].tag, 'field') + (self.assertEquals)(element.children[3].attrs['name'], 'value') + (self.assertEquals)(element.children[3].attrs['eval'], "'ir.actions.server,%d'%sample.action") + + +if __name__ == '__main__': + unittest.main() diff --git a/yaltik_dsl/test_xml_base.py b/yaltik_dsl/test_xml_base.py index 67b4020..fb2f699 100644 --- a/yaltik_dsl/test_xml_base.py +++ b/yaltik_dsl/test_xml_base.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # -*- coding: utf-8 -*- -# __coconut_hash__ = 0x48175ba9 +# __coconut_hash__ = 0xb50857dd # Compiled with Coconut version 1.4.3 [Ernest Scribbler] @@ -23,7 +23,7 @@ from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _cocon # -*- coding: utf-8 -*- # -# Copyright 2019-2020 Fabien Bourgeois +# Copyright 2020 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/yaltik_dsl/xml_base.py b/yaltik_dsl/xml_base.py index 46dd746..8e11569 100644 --- a/yaltik_dsl/xml_base.py +++ b/yaltik_dsl/xml_base.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # -*- coding: utf-8 -*- -# __coconut_hash__ = 0xeb6b4b07 +# __coconut_hash__ = 0x970fdbe8 # Compiled with Coconut version 1.4.3 [Ernest Scribbler]