Beispiel #1
0
    def search_active(self, active=True):
        if active and not self.parent:
            if not self.fields_view_tree:
                try:
                    self.fields_view_tree = RPCExecute('model',
                                                       self.model_name,
                                                       'fields_view_get',
                                                       False,
                                                       'tree',
                                                       context=self.context)
                except RPCException:
                    return

            if not self.domain_parser:
                fields = copy.deepcopy(self.fields_view_tree['fields'])
                for name, props in fields.iteritems():
                    if props['type'] not in ('selection', 'reference'):
                        continue
                    if isinstance(props['selection'], (tuple, list)):
                        continue
                    props['selection'] = self.get_selection(props)

                # Filter only fields in XML view
                xml_dom = xml.dom.minidom.parseString(
                    self.fields_view_tree['arch'])
                root_node, = xml_dom.childNodes
                xml_fields = [
                    node_attributes(node).get('name')
                    for node in root_node.childNodes
                    if node.nodeName == 'field'
                ]
                if hasattr(collections, 'OrderedDict'):
                    odict = collections.OrderedDict
                else:
                    odict = dict
                fields = odict((name, fields[name]) for name in xml_fields)
                for name, string, type_ in (
                    ('id', _('ID'), 'integer'),
                    ('create_uid', _('Creation User'), 'many2one'),
                    ('create_date', _('Creation Date'), 'datetime'),
                    ('write_uid', _('Modification User'), 'many2one'),
                    ('write_date', _('Modification Date'), 'datetime'),
                ):
                    if name not in fields:
                        fields[name] = {
                            'string': string.decode('utf-8'),
                            'name': name,
                            'type': type_,
                        }
                        if type_ == 'datetime':
                            fields[name]['format'] = '"%H:%M:%S"'

                self.domain_parser = DomainParser(fields)

            self.screen_container.set_screen(self)
            self.screen_container.show_filter()
        else:
            self.screen_container.hide_filter()
Beispiel #2
0
    def domain_parser(self):
        view_id = self.current_view.view_id if self.current_view else None

        if view_id in self._domain_parser:
            return self._domain_parser[view_id]

        if view_id not in self.fields_view_tree:
            try:
                self.fields_view_tree[view_id] = view_tree = RPCExecute(
                    'model', self.model_name, 'fields_view_get', False, 'tree',
                    context=self.context)
            except RPCException:
                view_tree = {
                    'fields': {},
                    }
        else:
            view_tree = self.fields_view_tree[view_id]

        fields = copy.deepcopy(view_tree['fields'])
        for name, props in fields.iteritems():
            if props['type'] not in ('selection', 'reference'):
                continue
            if isinstance(props['selection'], (tuple, list)):
                continue
            props['selection'] = self.get_selection(props)

        if 'arch' in view_tree:
            # Filter only fields in XML view
            xml_dom = xml.dom.minidom.parseString(view_tree['arch'])
            root_node, = xml_dom.childNodes
            xml_fields = [node_attributes(node).get('name')
                for node in root_node.childNodes
                if node.nodeName == 'field']
            fields = collections.OrderedDict(
                (name, fields[name]) for name in xml_fields)

        # Add common fields
        for name, string, type_ in (
                ('id', _('ID'), 'integer'),
                ('create_uid', _('Creation User'), 'many2one'),
                ('create_date', _('Creation Date'), 'datetime'),
                ('write_uid', _('Modification User'), 'many2one'),
                ('write_date', _('Modification Date'), 'datetime'),
                ):
            if name not in fields:
                fields[name] = {
                    'string': string.decode('utf-8'),
                    'name': name,
                    'type': type_,
                    }
                if type_ == 'datetime':
                    fields[name]['format'] = '"%H:%M:%S"'

        context = rpc.CONTEXT.copy()
        context.update(self.context)
        domain_parser = DomainParser(fields, context)
        self._domain_parser[view_id] = domain_parser
        return domain_parser
 def test_stringable(self):
     "Test stringable"
     dom = DomainParser({
             'name': {
                 'string': 'Name',
                 'type': 'char',
                 },
             'multiselection': {
                 'string': "MultiSelection",
                 'type': 'multiselection',
                 'selection': [
                     ('foo', "Foo"),
                     ('bar', "Bar"),
                     ('baz', "Baz"),
                     ],
                 },
             'relation': {
                 'string': 'Relation',
                 'type': 'many2one',
                 'relation_fields': {
                     'name': {
                         'string': "Name",
                         'type': 'char',
                         },
                     },
                 },
             'relations': {
                 'string': 'Relations',
                 'type': 'many2many',
                 },
             })
     valid = ('name', '=', 'Doe')
     invalid = ('surname', '=', 'John')
     self.assertTrue(dom.stringable([valid]))
     self.assertFalse(dom.stringable([invalid]))
     self.assertTrue(dom.stringable(['AND', valid]))
     self.assertFalse(dom.stringable(['AND', valid, invalid]))
     self.assertTrue(dom.stringable([[valid]]))
     self.assertFalse(dom.stringable([[valid], [invalid]]))
     self.assertTrue(dom.stringable([('multiselection', '=', None)]))
     self.assertTrue(dom.stringable([('multiselection', '=', '')]))
     self.assertFalse(dom.stringable([('multiselection', '=', 'foo')]))
     self.assertTrue(dom.stringable([('multiselection', '=', ['foo'])]))
     self.assertTrue(dom.stringable([('relation', '=', None)]))
     self.assertTrue(dom.stringable([('relation', '=', "Foo")]))
     self.assertTrue(dom.stringable([('relation.rec_name', '=', "Foo")]))
     self.assertFalse(dom.stringable([('relation', '=', 1)]))
     self.assertTrue(dom.stringable([('relations', '=', "Foo")]))
     self.assertTrue(dom.stringable([('relations', 'in', ["Foo"])]))
     self.assertFalse(dom.stringable([('relations', 'in', [42])]))
     self.assertTrue(dom.stringable([('relation.name', '=', "Foo")]))
 def test_completion_char(self):
     "Test completion char"
     dom = DomainParser({
             'name': {
                 'string': 'Name',
                 'name': 'name',
                 'type': 'char',
                 },
             })
     self.assertEqual(list(dom.completion('Nam')), ['Name: '])
     self.assertEqual(list(dom.completion('Name:')), ['Name: '])
     self.assertEqual(list(dom.completion('Name: foo')), [])
     self.assertEqual(list(dom.completion('Name: !=')), [])
     self.assertEqual(list(dom.completion('Name: !=foo')), [])
     self.assertEqual(list(dom.completion('')), ['Name: '])
     self.assertEqual(list(dom.completion(' ')), ['', 'Name: '])
    def test_completion_boolean(self):
        "Test completion boolean"
        dom = DomainParser({
            'name': {
                'string': "Active",
                'name': 'active',
                'type': 'boolean',
            },
        })

        self.assertEqual(list(dom.completion("Act")), ["Active: "])
        self.assertEqual(list(dom.completion("Active:")),
                         ["Active: ", "Active: True", "Active: False"])
        self.assertEqual(list(dom.completion("Active: t")),
                         ["Active: True", "Active: False"])
        self.assertEqual(list(dom.completion("Active: f")),
                         ["Active: False", "Active: True"])
 def test_completion_many2one(self):
     "Test completion many2one"
     dom = DomainParser({
         'relation': {
             'name': 'relation',
             'string': "Relation",
             'type': 'many2one',
             'relation_fields': {
                 'name': {
                     'name': 'name',
                     'string': "Name",
                     'type': 'char',
                 },
             },
         },
     })
     self.assertEqual(list(dom.completion('Relatio')),
                      ['Relation: ', 'Relation.Name: '])
Beispiel #7
0
 def invalid_message(self, record=None):
     if record is None:
         record = self.current_record
     domain_string = _('"%s" is not valid according to its domain')
     domain_parser = DomainParser(
         {n: f.attrs for n, f in record.group.fields.iteritems()})
     fields = []
     for field, invalid in sorted(record.invalid_fields.items()):
         string = record.group.fields[field].attrs['string']
         if invalid == 'required' or invalid == [[field, '!=', None]]:
             fields.append(_('"%s" is required') % string)
         elif invalid == 'domain':
             fields.append(domain_string % string)
         elif invalid == 'children':
             fields.append(_('The values of "%s" are not valid') % string)
         else:
             if domain_parser.stringable(invalid):
                 fields.append(domain_parser.string(invalid))
             else:
                 fields.append(domain_string % string)
     if len(fields) > 5:
         fields = fields[:5] + ['...']
     return '\n'.join(fields)
Beispiel #8
0
    def domain_parser(self):
        view_id = self.current_view.view_id if self.current_view else None

        if view_id in self._domain_parser:
            return self._domain_parser[view_id]

        if view_id not in self.fields_view_tree:
            try:
                self.fields_view_tree[view_id] = view_tree = RPCExecute(
                    'model', self.model_name, 'fields_view_get', False, 'tree',
                    context=self.context)
            except RPCException:
                view_tree = {
                    'fields': {},
                    }
        else:
            view_tree = self.fields_view_tree[view_id]

        fields = copy.deepcopy(view_tree['fields'])
        for name, props in fields.items():
            if props['type'] not in ('selection', 'reference'):
                continue
            if isinstance(props['selection'], (tuple, list)):
                continue
            props['selection'] = self.get_selection(props)

        if 'arch' in view_tree:
            # Filter only fields in XML view
            xml_dom = xml.dom.minidom.parseString(view_tree['arch'])
            root_node, = xml_dom.childNodes
            ofields = collections.OrderedDict()
            for node in root_node.childNodes:
                if node.nodeName != 'field':
                    continue
                attributes = node_attributes(node)
                name = attributes['name']
                # If a field is defined multiple times in the XML,
                # take only the first definition
                if name in ofields:
                    continue
                ofields[name] = fields[name]
                for attr in ['string', 'factor']:
                    if attributes.get(attr):
                        ofields[name][attr] = attributes[attr]
            fields = ofields

        if 'active' in view_tree['fields']:
            self.screen_container.but_active.show()
        else:
            self.screen_container.but_active.hide()

        # Add common fields
        for name, string, type_ in (
                ('id', _('ID'), 'integer'),
                ('create_uid', _('Create by'), 'many2one'),
                ('create_date', _('Created at'), 'datetime'),
                ('write_uid', _('Edited by'), 'many2one'),
                ('write_date', _('Edited at'), 'datetime'),
                ):
            if name not in fields:
                fields[name] = {
                    'string': string,
                    'name': name,
                    'type': type_,
                    }
                if type_ == 'datetime':
                    fields[name]['format'] = '"%H:%M:%S"'

        domain_parser = DomainParser(fields, self.context)
        self._domain_parser[view_id] = domain_parser
        return domain_parser
 def test_parse_clause(self):
     "Test parse clause"
     dom = DomainParser({
             'name': {
                 'string': 'Name',
                 'name': 'name',
                 'type': 'char',
                 },
             'integer': {
                 'string': 'Integer',
                 'name': 'integer',
                 'type': 'integer',
                 },
             'selection': {
                 'string': 'Selection',
                 'name': 'selection',
                 'type': 'selection',
                 'selection': [
                     ('male', 'Male'),
                     ('female', 'Female'),
                     ],
                 },
             'multiselection': {
                 'string': "MultiSelection",
                 'name': 'multiselection',
                 'type': 'multiselection',
                 'selection': [
                     ('foo', "Foo"),
                     ('bar', "Bar"),
                     ('baz', "Baz"),
                     ],
                 },
             'reference': {
                 'string': 'Reference',
                 'name': 'reference',
                 'type': 'reference',
                 'selection': [
                     ('spam', 'Spam'),
                     ('ham', 'Ham'),
                     ]
                 },
             'many2one': {
                 'string': 'Many2One',
                 'name': 'many2one',
                 'type': 'many2one',
                 },
             'relation': {
                 'string': "Relation",
                 'relation': 'relation',
                 'name': 'relation',
                 'relation_fields': {
                     'name': {
                         'string': "Name",
                         'name': 'name',
                         'type': 'char',
                         },
                     },
                 },
             })
     self.assertEqual(
         rlist(dom.parse_clause([('John',)])), [
             ('rec_name', 'ilike', '%John%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', None, None)])), [
             ('name', 'ilike', '%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', '', None)])), [
             ('name', 'ilike', '%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', '=', None)])), [
             ('name', '=', None),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', '=', '')])), [
             ('name', '=', ''),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', None, 'Doe')])), [
             ('name', 'ilike', '%Doe%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', '!', 'Doe')])), [
             ('name', 'not ilike', '%Doe%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', None, ['John', 'Jane'])])), [
             ('name', 'in', ['John', 'Jane']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Name', '!', ['John', 'Jane'])])), [
             ('name', 'not in', ['John', 'Jane']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Selection', None, None)])), [
             ('selection', '=', None),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Selection', None, '')])), [
             ('selection', '=', ''),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Selection', None, ['Male', 'Female'])])),
         [('selection', 'in', ['male', 'female'])])
     self.assertEqual(
         rlist(dom.parse_clause([('MultiSelection', None, None)])), [
             ('multiselection', '=', None),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('MultiSelection', None, '')])), [
             ('multiselection', 'in', ['']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('MultiSelection', '=', '')])), [
             ('multiselection', '=', ['']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('MultiSelection', '!', '')])), [
             ('multiselection', 'not in', ['']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('MultiSelection', '!=', '')])), [
             ('multiselection', '!=', ['']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(
             [('MultiSelection', None, ['Foo', 'Bar'])])), [
             ('multiselection', 'in', ['foo', 'bar']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(
             [('MultiSelection', '=', ['Foo', 'Bar'])])), [
             ('multiselection', '=', ['foo', 'bar']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(
             [('MultiSelection', '!', ['Foo', 'Bar'])])), [
             ('multiselection', 'not in', ['foo', 'bar']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(
             [('MultiSelection', '!=', ['Foo', 'Bar'])])), [
             ('multiselection', '!=', ['foo', 'bar']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Integer', None, None)])), [
             ('integer', '=', None),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Integer', None, '3..5')])), [[
                 ('integer', '>=', 3),
                 ('integer', '<=', 5),
                 ]])
     self.assertEqual(
         rlist(dom.parse_clause([('Reference', None, 'foo')])), [
             ('reference', 'ilike', '%foo%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Reference', None, 'Spam')])), [
             ('reference', 'ilike', '%spam%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Reference', None, 'Spam,bar')])), [
             ('reference.rec_name', 'ilike', '%bar%', 'spam'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Reference', None, ['foo', 'bar'])])), [
             ('reference', 'in', ['foo', 'bar']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(['OR',
                 ('Name', None, 'John'), ('Name', None, 'Jane')])),
         ['OR',
             ('name', 'ilike', '%John%'),
             ('name', 'ilike', '%Jane%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Many2One', None, 'John')])), [
             ('many2one', 'ilike', '%John%'),
             ])
     self.assertEqual(
         rlist(dom.parse_clause([('Many2One', None, ['John', 'Jane'])])), [
             ('many2one.rec_name', 'in', ['John', 'Jane']),
             ])
     self.assertEqual(
         rlist(dom.parse_clause(iter([iter([['John']])]))), [
             [('rec_name', 'ilike', '%John%')]])
     self.assertEqual(
         rlist(dom.parse_clause(iter([['Relation.Name', None, "Test"]]))),
         [('relation.name', 'ilike', "%Test%")])
     self.assertEqual(
         rlist(dom.parse_clause(iter([['OR']]))),
         [('rec_name', 'ilike', "%OR%")])
     self.assertEqual(
         rlist(dom.parse_clause(iter([['AND']]))),
         [('rec_name', 'ilike', "%AND%")])
 def test_group(self):
     "Test group"
     dom = DomainParser({
             'name': {
                 'string': 'Name',
                 },
             'firstname': {
                 'string': 'First Name',
                 },
             'surname': {
                 'string': '(Sur)Name',
                 },
             'relation': {
                 'string': "Relation",
                 'relation': 'relation',
                 'relation_fields': {
                     'name': {
                         'string': "Name",
                         },
                     },
                 },
             })
     self.assertEqual(
         rlist(dom.group(udlex('Name: Doe'))), [('Name', None, 'Doe')])
     self.assertEqual(
         rlist(dom.group(udlex('"(Sur)Name": Doe'))), [
             ('(Sur)Name', None, 'Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: Doe Name: John'))), [
             ('Name', None, 'Doe'),
             ('Name', None, 'John'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: Name: John'))), [
             ('Name', None, None),
             ('Name', None, 'John')])
     self.assertEqual(
         rlist(dom.group(udlex('First Name: John'))), [
             ('First Name', None, 'John'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: Doe First Name: John'))), [
             ('Name', None, 'Doe'),
             ('First Name', None, 'John'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('First Name: John Name: Doe'))), [
             ('First Name', None, 'John'),
             ('Name', None, 'Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('First Name: John First Name: Jane'))), [
             ('First Name', None, 'John'),
             ('First Name', None, 'Jane'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: John Doe'))), [
             ('Name', None, 'John'),
             ('Doe',),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: "John Doe"'))), [
             ('Name', None, 'John Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Doe Name: John'))), [
             ('Doe',),
             ('Name', None, 'John'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: =Doe'))), [('Name', '=', 'Doe')])
     self.assertEqual(
         rlist(dom.group(udlex('Name: =Doe Name: >John'))), [
             ('Name', '=', 'Doe'),
             ('Name', '>', 'John'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('First Name: =John First Name: =Jane'))), [
             ('First Name', '=', 'John'),
             ('First Name', '=', 'Jane'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: John;Jane'))), [
             ('Name', None, ['John', 'Jane'])
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: John;'))), [
             ('Name', None, ['John'])
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: John;Jane Name: Doe'))), [
             ('Name', None, ['John', 'Jane']),
             ('Name', None, 'Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: John; Name: Doe'))), [
             ('Name', None, ['John']),
             ('Name', None, 'Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name:'))), [
             ('Name', None, None),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: ='))), [
             ('Name', '=', None),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: =""'))), [
             ('Name', '=', ''),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: = ""'))), [
             ('Name', '=', ''),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: = Name: Doe'))), [
             ('Name', '=', None),
             ('Name', None, 'Doe'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: \\"foo\\"'))), [
             ('Name', None, '"foo"'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Name: "" <'))), [
             ('Name', '', '<'),
             ])
     self.assertEqual(
         rlist(dom.group(udlex('Relation.Name: Test'))), [
             ('Relation.Name', None, "Test"),
             ])
 def test_string(self):
     dom = DomainParser({
             'name': {
                 'string': 'Name',
                 'type': 'char',
                 },
             'surname': {
                 'string': '(Sur)Name',
                 'type': 'char',
                 },
             'date': {
                 'string': 'Date',
                 'type': 'date',
                 },
             'selection': {
                 'string': 'Selection',
                 'type': 'selection',
                 'selection': [
                     ('male', 'Male'),
                     ('female', 'Female'),
                     ('', ''),
                     ],
                 },
             'multiselection': {
                 'string': "MultiSelection",
                 'type': 'multiselection',
                 'selection': [
                     ('foo', "Foo"),
                     ('bar', "Bar"),
                     ('baz', "Baz"),
                     ],
                 },
             'reference': {
                 'string': 'Reference',
                 'type': 'reference',
                 'selection': [
                     ('spam', 'Spam'),
                     ('ham', 'Ham'),
                     ]
                 },
             'many2one': {
                 'string': 'Many2One',
                 'name': 'many2one',
                 'type': 'many2one',
                 'relation_fields': {
                     'name': {
                         'string': "Name",
                         'type': 'char',
                         },
                     },
                 },
             })
     self.assertEqual(dom.string([('name', '=', 'Doe')]), 'Name: =Doe')
     self.assertEqual(dom.string([('name', '=', None)]), 'Name: =')
     self.assertEqual(dom.string([('name', '=', '')]), 'Name: =""')
     self.assertEqual(dom.string([('name', 'ilike', '%')]), 'Name: ')
     self.assertEqual(dom.string([('name', 'ilike', '%Doe%')]), 'Name: Doe')
     self.assertEqual(
         dom.string([('name', 'ilike', '%<%')]), 'Name: "" "<"')
     self.assertEqual(dom.string([('name', 'ilike', 'Doe')]), 'Name: =Doe')
     self.assertEqual(dom.string([('name', 'ilike', 'Doe%')]), 'Name: Doe%')
     self.assertEqual(
         dom.string([('name', 'ilike', 'Doe%%')]), 'Name: =Doe%')
     self.assertEqual(
         dom.string([('name', 'not ilike', '%Doe%')]), 'Name: !Doe')
     self.assertEqual(
         dom.string([('name', 'in', ['John', 'Jane'])]), 'Name: John;Jane')
     self.assertEqual(
         dom.string([('name', 'not in', ['John', 'Jane'])]),
         'Name: !John;Jane')
     self.assertEqual(
         dom.string([
                 ('name', 'ilike', '%Doe%'),
                 ('name', 'ilike', '%Jane%')]),
         'Name: Doe Name: Jane')
     self.assertEqual(
         dom.string(['AND',
             ('name', 'ilike', '%Doe%'),
             ('name', 'ilike', '%Jane%')]),
         'Name: Doe Name: Jane')
     self.assertEqual(
         dom.string(['OR',
             ('name', 'ilike', '%Doe%'),
             ('name', 'ilike', '%Jane%')]),
         'Name: Doe or Name: Jane')
     self.assertEqual(
         dom.string([
             ('name', 'ilike', '%Doe%'),
             ['OR',
                 ('name', 'ilike', '%John%'),
                 ('name', 'ilike', '%Jane%')]]),
         'Name: Doe (Name: John or Name: Jane)')
     self.assertEqual(dom.string([]), '')
     self.assertEqual(
         dom.string([('surname', 'ilike', '%Doe%')]), '"(Sur)Name": Doe')
     self.assertEqual(
         dom.string([('date', '>=', dt.date(2012, 10, 24))]),
         dt.date(2012, 10, 24).strftime('Date: >=%x'))
     self.assertEqual(dom.string([('selection', '=', '')]), 'Selection: ')
     self.assertEqual(dom.string([('selection', '=', None)]), 'Selection: ')
     self.assertEqual(
         dom.string([('selection', '!=', '')]), 'Selection: !""')
     self.assertEqual(
         dom.string([('selection', '=', 'male')]), 'Selection: Male')
     self.assertEqual(
         dom.string([('selection', '!=', 'male')]), 'Selection: !Male')
     self.assertEqual(
         dom.string([('multiselection', '=', None)]), "MultiSelection: =")
     self.assertEqual(
         dom.string([('multiselection', '=', '')]), "MultiSelection: =")
     self.assertEqual(
         dom.string([('multiselection', '!=', '')]), "MultiSelection: !=")
     self.assertEqual(
         dom.string([('multiselection', '=', ['foo'])]),
         "MultiSelection: =Foo")
     self.assertEqual(
         dom.string([('multiselection', '!=', ['foo'])]),
         "MultiSelection: !=Foo")
     self.assertEqual(
         dom.string([('multiselection', '=', ['foo', 'bar'])]),
         "MultiSelection: =Foo;Bar")
     self.assertEqual(
         dom.string([('multiselection', '!=', ['foo', 'bar'])]),
         "MultiSelection: !=Foo;Bar")
     self.assertEqual(
         dom.string([('multiselection', 'in', ['foo'])]),
         "MultiSelection: Foo")
     self.assertEqual(
         dom.string([('multiselection', 'not in', ['foo'])]),
         "MultiSelection: !Foo")
     self.assertEqual(
         dom.string([('multiselection', '=', ['foo', 'bar'])]),
         "MultiSelection: =Foo;Bar")
     self.assertEqual(
         dom.string([('multiselection', '!=', ['foo', 'bar'])]),
         "MultiSelection: !=Foo;Bar")
     self.assertEqual(
         dom.string([('multiselection', 'in', ['foo', 'bar'])]),
         "MultiSelection: Foo;Bar")
     self.assertEqual(
         dom.string([('multiselection', 'not in', ['foo', 'bar'])]),
         "MultiSelection: !Foo;Bar")
     self.assertEqual(
         dom.string([('reference', 'ilike', '%foo%')]),
         'Reference: foo')
     self.assertEqual(
         dom.string([('reference.rec_name', 'ilike', '%bar%', 'spam')]),
         'Reference: Spam,bar')
     self.assertEqual(
         dom.string([('reference', 'in', ['foo', 'bar'])]),
         'Reference: foo;bar')
     self.assertEqual(
         dom.string([('many2one', 'ilike', '%John%')]), 'Many2One: John')
     self.assertEqual(
         dom.string([('many2one.rec_name', 'in', ['John', 'Jane'])]),
         'Many2One: John;Jane')
     self.assertEqual(
         dom.string([('many2one.name', 'ilike', '%Foo%')]),
         "Many2One.Name: Foo")