From 67003bd76fdbc89f9d4b6367c1414fbb8846f0b5 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Fri, 7 Sep 2012 14:28:57 +0200 Subject: [PATCH] [FIX] method resolve_2many_commands and its tests bzr revid: rco@openerp.com-20120907122857-4dro8up51ypx0cr5 --- openerp/osv/orm.py | 12 +++++----- openerp/tests/test_orm.py | 49 ++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 889230759d2..79ea88e84f3 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -5029,21 +5029,21 @@ class BaseModel(object): :rtype: list(dict) """ result = [] # result (list of dict) - record_ids = set() # ids of records to read + record_ids = [] # ids of records to read updates = {} # {id: dict} of updates on particular records for command in commands: if not isinstance(command, (list, tuple)): - record_ids.add(command) + record_ids.append(command) elif command[0] == 0: result.append(command[2]) elif command[0] == 1: - record_ids.add(command[1]) + record_ids.append(command[1]) updates.setdefault(command[1], {}).update(command[2]) elif command[0] in (2, 3): - record_ids.discard(command[1]) + record_ids = [id for id in record_ids if id != command[1]] elif command[0] == 4: - record_ids.add(command[1]) + record_ids.append(command[1]) elif command[0] == 5: result, record_ids = [], [] elif command[0] == 6: @@ -5051,7 +5051,7 @@ class BaseModel(object): # read the records and apply the updates other_model = self.pool.get(self._all_columns[field_name].column._obj) - for record in other_model.read(cr, uid, list(record_ids), fields=fields, context=context): + for record in other_model.read(cr, uid, record_ids, fields=fields, context=context): record.update(updates.get(record['id'], {})) result.append(record) diff --git a/openerp/tests/test_orm.py b/openerp/tests/test_orm.py index f04b9d77747..fd033316e62 100644 --- a/openerp/tests/test_orm.py +++ b/openerp/tests/test_orm.py @@ -15,6 +15,10 @@ LINK_TO = lambda id: (4, id, False) DELETE_ALL = lambda: (5, False, False) REPLACE_WITH = lambda ids: (6, False, ids) +def sorted_by_id(list_of_dicts): + "sort dictionaries by their 'id' field; useful for comparisons" + return sorted(list_of_dicts, key=lambda d: d.get('id')) + class TestO2MSerialization(common.TransactionCase): def setUp(self): @@ -30,14 +34,11 @@ class TestO2MSerialization(common.TransactionCase): def test_CREATE_commands(self): " returns the VALUES dict as-is " + values = [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}] results = self.partner.resolve_2many_commands( - self.cr, UID, 'address', - map(CREATE, [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}])) - self.assertEqual(results, [ - {'foo': 'bar'}, - {'foo': 'baz'}, - {'foo': 'baq'} - ]) + self.cr, UID, 'address', map(CREATE, values)) + + self.assertEqual(results, values) def test_LINK_TO_command(self): " reads the records from the database, records are returned with their ids. " @@ -51,11 +52,11 @@ class TestO2MSerialization(common.TransactionCase): results = self.partner.resolve_2many_commands( self.cr, UID, 'address', commands, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_bare_ids_command(self): " same as the equivalent LINK_TO commands " @@ -68,11 +69,11 @@ class TestO2MSerialization(common.TransactionCase): results = self.partner.resolve_2many_commands( self.cr, UID, 'address', ids, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_UPDATE_command(self): " take the in-db records and merge the provided information in " @@ -87,11 +88,11 @@ class TestO2MSerialization(common.TransactionCase): UPDATE(id_baz, {'name': 'quux'}) ], ['name', 'city']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': id_foo, 'name': 'foo', 'city': False}, {'id': id_bar, 'name': 'qux', 'city': 'tagtag'}, {'id': id_baz, 'name': 'quux', 'city': 'tag'} - ]) + ])) def test_DELETE_command(self): " deleted records are not returned at all. " @@ -105,10 +106,7 @@ class TestO2MSerialization(common.TransactionCase): results = self.partner.resolve_2many_commands( self.cr, UID, 'address', commands, ['name']) - self.assertEqual(results, [ - {'id': ids[0], 'name': 'foo'}, - {'id': ids[2], 'name': 'baz'} - ]) + self.assertEqual(results, []) def test_mixed_commands(self): ids = [ @@ -128,7 +126,7 @@ class TestO2MSerialization(common.TransactionCase): LINK_TO(ids[5]) ], ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'name': 'foo'}, {'id': ids[0], 'name': 'bar'}, {'id': ids[1], 'name': 'baz'}, @@ -136,7 +134,7 @@ class TestO2MSerialization(common.TransactionCase): {'id': ids[4], 'name': 'corge'}, {'name': 'grault'}, {'id': ids[5], 'name': 'garply'} - ]) + ])) def test_LINK_TO_pairs(self): "LINK_TO commands can be written as pairs, instead of triplets" @@ -150,20 +148,17 @@ class TestO2MSerialization(common.TransactionCase): results = self.partner.resolve_2many_commands( self.cr, UID, 'address', commands, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_singleton_commands(self): "DELETE_ALL can appear as a singleton" + results = self.partner.resolve_2many_commands( + self.cr, UID, 'address', [DELETE_ALL()], ['name']) - try: - self.partner.resolve_2many_commands( - self.cr, UID, 'address', [(5,)], ['name']) - except AssertionError: - # 5 should fail with an assert error, but not e.g. a ValueError - pass + self.assertEqual(results, []) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: