[ADD] file field type in xml_convert, tests
bzr revid: xmo@openerp.com-20130429112459-ol1ayn2z34j32r54
This commit is contained in:
parent
282a7180ca
commit
45bb6ec7f1
|
@ -172,40 +172,73 @@ is as follows:
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
||||||
Record Tag
|
``<record>``
|
||||||
//////////
|
////////////
|
||||||
|
|
||||||
**Description**
|
Defines a new record in a specified OpenERP model.
|
||||||
|
|
||||||
The addition of new data is made with the record tag. This one takes a
|
``@model`` (required)
|
||||||
mandatory attribute : model. Model is the object name where the insertion has
|
|
||||||
to be done. The tag record can also take an optional attribute: id. If this
|
|
||||||
attribute is given, a variable of this name can be used later on, in the same
|
|
||||||
file, to make reference to the newly created resource ID.
|
|
||||||
|
|
||||||
A record tag may contain field tags. They indicate the record's fields value.
|
Name of the model in which this record will be created/inserted.
|
||||||
If a field is not specified the default value will be used.
|
|
||||||
|
|
||||||
The Record Field tag
|
``@id`` (optional)
|
||||||
////////////////////
|
|
||||||
|
|
||||||
The attributes for the field tag are the following:
|
:term:`external ID` for the record, also allows referring to this record in
|
||||||
|
the rest of this file or in other files (through ``field/@ref`` or the
|
||||||
|
:py:func:`ref() <openerp.tools.convert._ref>` function)
|
||||||
|
|
||||||
name : mandatory
|
A record tag generally contains multiple ``field`` tags specifying the values
|
||||||
the field name
|
set on the record's fields when creating it. Fields left out will be set to
|
||||||
|
their default value unless required.
|
||||||
|
|
||||||
eval : optional
|
``<field>``
|
||||||
python expression that indicating the value to add
|
///////////
|
||||||
|
|
||||||
ref
|
|
||||||
reference to an id defined in this file
|
|
||||||
|
|
||||||
model
|
In its most basic use, the ``field`` tag will set its body (as a string) as
|
||||||
model to be looked up in the search
|
the value of the corresponding ``record``'s ``@name`` field.
|
||||||
|
|
||||||
search
|
Extra attributes can either preprocess the body or replace its use entirely:
|
||||||
a query
|
|
||||||
|
|
||||||
|
``@name`` (mandatory)
|
||||||
|
|
||||||
|
Name of the field in the containing ``record``'s model
|
||||||
|
|
||||||
|
``@type`` (optional)
|
||||||
|
|
||||||
|
One of ``char``, ``int``, ``float``, ``list``, ``tuple``, ``xml`` or
|
||||||
|
``html`` or ``file``. Converts the ``field``'s body to the specified type
|
||||||
|
(or validates the body's content)
|
||||||
|
|
||||||
|
* ``xml`` will join multiple XML nodes under a single ``<data>`` root
|
||||||
|
* in ``xml`` and ``html``, external ids can be referenced using
|
||||||
|
``%(id_name)s``
|
||||||
|
* ``list`` and ``tuple``'s element are specified using ``<value>``
|
||||||
|
sub-nodes with the same attributes as ``field``.
|
||||||
|
* ``file`` expects a module-local path and will save the path prefixed with
|
||||||
|
the current module's name, separated by a ``,`` (comma). For use with
|
||||||
|
:py:func:`~openerp.modules.module.get_module_resource`.
|
||||||
|
|
||||||
|
``@model``
|
||||||
|
|
||||||
|
Model used for ``@search``'s search, or registry object put in context for
|
||||||
|
``@eval``. Required if ``@search`` but optional if ``@eval``.
|
||||||
|
|
||||||
|
``@eval`` (optional)
|
||||||
|
|
||||||
|
A Python expression evaluated to obtain the value to set on the record
|
||||||
|
|
||||||
|
``@ref`` (optional)
|
||||||
|
|
||||||
|
Links to an other record through its :term:`external id`. The module prefix
|
||||||
|
may be ommitted to link to a record defined in the same module.
|
||||||
|
|
||||||
|
``@search`` (optional)
|
||||||
|
|
||||||
|
Search domain (evaluated Python expression) into ``@model`` to get the
|
||||||
|
records to set on the field.
|
||||||
|
|
||||||
|
Sets all the matches found for m2m fields, the first id for other field
|
||||||
|
types.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import test_osv
|
||||||
import test_translate
|
import test_translate
|
||||||
import test_uninstall
|
import test_uninstall
|
||||||
import test_view_validation
|
import test_view_validation
|
||||||
|
import test_convert
|
||||||
# This need a change in `oe run-tests` to only run fast_suite + checks by default.
|
# This need a change in `oe run-tests` to only run fast_suite + checks by default.
|
||||||
# import test_xmlrpc
|
# import test_xmlrpc
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ checks = [
|
||||||
test_misc,
|
test_misc,
|
||||||
test_osv,
|
test_osv,
|
||||||
test_translate,
|
test_translate,
|
||||||
|
test_convert,
|
||||||
]
|
]
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
'name': 'test_convert',
|
||||||
|
'description': "Data for xml conversion tests",
|
||||||
|
'version': '0.0.1',
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
nothing to see here, move along
|
|
@ -0,0 +1,83 @@
|
||||||
|
import collections
|
||||||
|
import unittest2
|
||||||
|
from lxml import etree as ET
|
||||||
|
from lxml.builder import E
|
||||||
|
|
||||||
|
from . import common
|
||||||
|
|
||||||
|
from openerp.tools.convert import _eval_xml
|
||||||
|
|
||||||
|
Field = E.field
|
||||||
|
Value = E.value
|
||||||
|
class TestEvalXML(common.TransactionCase):
|
||||||
|
def eval_xml(self, node, obj=None, idref=None):
|
||||||
|
return _eval_xml(obj, node, pool=None, cr=self.cr, uid=self.uid,
|
||||||
|
idref=idref, context=None)
|
||||||
|
|
||||||
|
def test_char(self):
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field("foo")),
|
||||||
|
"foo")
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field("None")),
|
||||||
|
"None")
|
||||||
|
|
||||||
|
def test_int(self):
|
||||||
|
self.assertIsNone(
|
||||||
|
self.eval_xml(Field("None", type='int')),
|
||||||
|
"what the fuck?")
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field(" 42 ", type="int")),
|
||||||
|
42)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.eval_xml(Field("4.82", type="int"))
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.eval_xml(Field("Whelp", type="int"))
|
||||||
|
|
||||||
|
def test_float(self):
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field("4.78", type="float")),
|
||||||
|
4.78)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.eval_xml(Field("None", type="float"))
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.eval_xml(Field("Foo", type="float"))
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field(type="list")),
|
||||||
|
[])
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field(
|
||||||
|
Value("foo"),
|
||||||
|
Value("5", type="int"),
|
||||||
|
Value("4.76", type="float"),
|
||||||
|
Value("None", type="int"),
|
||||||
|
type="list"
|
||||||
|
)),
|
||||||
|
["foo", 5, 4.76, None])
|
||||||
|
|
||||||
|
def test_file(self):
|
||||||
|
Obj = collections.namedtuple('Obj', 'module')
|
||||||
|
obj = Obj('test_convert')
|
||||||
|
self.assertEqual(
|
||||||
|
self.eval_xml(Field('test_file.txt', type='file'), obj),
|
||||||
|
'test_convert,test_file.txt')
|
||||||
|
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
self.eval_xml(Field('test_nofile.txt', type='file'), obj)
|
||||||
|
|
||||||
|
@unittest2.skip("not tested")
|
||||||
|
def test_xml(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@unittest2.skip("not tested")
|
||||||
|
def test_html(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,12 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None):
|
||||||
if t == 'html':
|
if t == 'html':
|
||||||
return _process("".join([etree.tostring(n, encoding='utf-8')
|
return _process("".join([etree.tostring(n, encoding='utf-8')
|
||||||
for n in node]), idref)
|
for n in node]), idref)
|
||||||
|
if t == 'file':
|
||||||
|
from ..modules import module
|
||||||
|
path = node.text.strip()
|
||||||
|
if not module.get_module_resource(self.module, path):
|
||||||
|
raise IOError("No such file or directory: '%s'" % path)
|
||||||
|
return '%s,%s' % (self.module, path)
|
||||||
if t in ('char', 'int', 'float'):
|
if t in ('char', 'int', 'float'):
|
||||||
d = node.text
|
d = node.text
|
||||||
if t == 'int':
|
if t == 'int':
|
||||||
|
|
Loading…
Reference in New Issue