[FIX] method resolve_2many_commands and its tests

bzr revid: rco@openerp.com-20120907122857-4dro8up51ypx0cr5
This commit is contained in:
Raphael Collet 2012-09-07 14:28:57 +02:00
parent 3b3279c77e
commit 67003bd76f
2 changed files with 28 additions and 33 deletions

View File

@ -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)

View File

@ -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: