Merge lp:~vds/desktopcouch/mergeable_list_not_default_anymore into lp:desktopcouch

Proposed by Vincenzo Di Somma
Status: Merged
Approved by: John Lenton
Approved revision: 194
Merged at revision: 194
Proposed branch: lp:~vds/desktopcouch/mergeable_list_not_default_anymore
Merge into: lp:desktopcouch
Diff against target: 236 lines (+44/-32)
3 files modified
desktopcouch/records/field_registry.py (+3/-1)
desktopcouch/records/record.py (+11/-12)
desktopcouch/records/tests/test_record.py (+30/-19)
To merge this branch: bzr merge lp:~vds/desktopcouch/mergeable_list_not_default_anymore
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+39912@code.launchpad.net

Commit message

Mergeable lists are not the default for lists anymore, plus clean up a bit.

Description of the change

Mergeable lists are not the default for lists anymore, plus clean up a bit.

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

I love the smell of awesome in the morning.

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

approaved

Revision history for this message
dobey (dobey) wrote :

Voting does not meet specified criteria. Required: Approve >= 2, Disapprove == 0, Needs Fixing == 0, Needs Information == 0, Resubmit == 0. Got: 1 Approve.

Revision history for this message
John Lenton (chipaca) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'desktopcouch/records/field_registry.py'
--- desktopcouch/records/field_registry.py 2010-04-05 17:46:53 +0000
+++ desktopcouch/records/field_registry.py 2010-11-02 23:33:40 +0000
@@ -21,6 +21,7 @@
2121
22import copy22import copy
2323
24from desktopcouch.records.record import MergeableList
24ANNOTATION_NAMESPACE = 'application_annotations'25ANNOTATION_NAMESPACE = 'application_annotations'
2526
2627
@@ -132,7 +133,8 @@
132 values.update({self._field_name: value})133 values.update({self._field_name: value})
133 if not root_list:134 if not root_list:
134 # This is the first value we add to the list135 # This is the first value we add to the list
135 record[self._root_list] = [values]136 ml = MergeableList.from_list([values])
137 record[self._root_list] = ml
136 uuid_key = record[self._root_list].get_uuid_for_index(-1)138 uuid_key = record[self._root_list].get_uuid_for_index(-1)
137 application_annotations[self._uuid_field] = uuid_key139 application_annotations[self._uuid_field] = uuid_key
138 return140 return
139141
=== modified file 'desktopcouch/records/record.py'
--- desktopcouch/records/record.py 2010-10-31 23:20:14 +0000
+++ desktopcouch/records/record.py 2010-11-02 23:33:40 +0000
@@ -42,19 +42,8 @@
42 """Create a RecordDict or RecordList from passed data."""42 """Create a RecordDict or RecordList from passed data."""
43 if isinstance(data, dict):43 if isinstance(data, dict):
44 return _build_from_dict(data)44 return _build_from_dict(data)
45 if isinstance(data, (list, tuple)):
46 return _build_from_list(data)
47 return data45 return data
4846
49def _build_from_list(data):
50 """Create a RecordList from passed data."""
51 if not data:
52 raise ValueError("Can't set empty list values.'")
53 result = MergeableList({})
54 for value in data:
55 result.append(record_factory(value))
56 return result
57
58def _build_from_dict(data):47def _build_from_dict(data):
59 """Create a RecordDict from passed data."""48 """Create a RecordDict from passed data."""
60 result = RecordDict({})49 result = RecordDict({})
@@ -155,7 +144,7 @@
155 return value144 return value
156145
157 def __setitem__(self, key, item):146 def __setitem__(self, key, item):
158 if isinstance(item, (list, tuple, dict)):147 if isinstance(item, dict):
159 item = record_factory(item)148 item = record_factory(item)
160 if hasattr(item, '_data'):149 if hasattr(item, '_data'):
161 item = item._data150 item = item._data
@@ -258,6 +247,16 @@
258class MergeableList(RecordData):247class MergeableList(RecordData):
259 """An object that represents a list of complex values."""248 """An object that represents a list of complex values."""
260249
250 @classmethod
251 def from_list(klass, data):
252 """Create a RecordList from passed data."""
253 if not data:
254 raise ValueError("Can't set empty list values.'")
255 result = klass({})
256 for value in data:
257 result.append(record_factory(value))
258 return result
259
261 def __getitem__(self, index):260 def __getitem__(self, index):
262 if not isinstance(index, int):261 if not isinstance(index, int):
263 raise TypeError(262 raise TypeError(
264263
=== modified file 'desktopcouch/records/tests/test_record.py'
--- desktopcouch/records/tests/test_record.py 2010-10-31 15:52:12 +0000
+++ desktopcouch/records/tests/test_record.py 2010-11-02 23:33:40 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009 Canonical Ltd.1# Copyright 2009-2010 Canonical Ltd.
2#2#
3# This file is part of desktopcouch.3# This file is part of desktopcouch.
4#4#
@@ -15,6 +15,7 @@
15# along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.15# along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
16#16#
17# Authors: Eric Casteleijn <eric.casteleijn@canonical.com>17# Authors: Eric Casteleijn <eric.casteleijn@canonical.com>
18# Vincenzo Di Somma <vincenzo.di.somma@canonical.com>
1819
19"""Tests for the RecordDict object on which the Contacts API is built."""20"""Tests for the RecordDict object on which the Contacts API is built."""
2021
@@ -55,6 +56,8 @@
55 self.record = Record(self.dict)56 self.record = Record(self.dict)
5657
57 def test_revision(self):58 def test_revision(self):
59 """Test document always has a revision field and that the revision
60 changes when the document is updated"""
58 self.assertEquals(self.record.record_revision, None)61 self.assertEquals(self.record.record_revision, None)
59 def set_rev(rec): rec.record_revision = "1"62 def set_rev(rec): rec.record_revision = "1"
60 self.assertRaises(AttributeError, set_rev, self.record)63 self.assertRaises(AttributeError, set_rev, self.record)
@@ -77,6 +80,7 @@
77 db.delete_record(record_id)80 db.delete_record(record_id)
7881
79 def test_delitem(self):82 def test_delitem(self):
83 """Test removing a field from the record"""
80 def f(r):84 def f(r):
81 del r["_id"]85 del r["_id"]
82 self.assertRaises(KeyError, f, self.record)86 self.assertRaises(KeyError, f, self.record)
@@ -84,25 +88,28 @@
84 del self.record["a"]88 del self.record["a"]
8589
86 def test_iter(self):90 def test_iter(self):
91 """Tests it is possible to iterate over the record fields"""
87 self.assertEquals(sorted(list(iter(self.record))),92 self.assertEquals(sorted(list(iter(self.record))),
88 ['a', 'b', 'record_type', 'subfield', 'subfield_uuid'])93 ['a', 'b', 'record_type', 'subfield', 'subfield_uuid'])
8994
90 def test_setitem_internal(self):95 def test_setitem_internal(self):
96 """Test it is not possible to set a private field on a record"""
91 def f(r):97 def f(r):
92 r["_id"] = "new!"98 r["_id"] = "new!"
93 self.assertRaises(IllegalKeyException, f, self.record)99 self.assertRaises(IllegalKeyException, f, self.record)
94100
95 def test_no_record_type(self):101 def test_no_record_type(self):
102 """Test that creating a record with no record type fails"""
96 self.assertRaises(NoRecordTypeSpecified, Record, {})103 self.assertRaises(NoRecordTypeSpecified, Record, {})
97104
98 def test_get_item(self):105 def test_get_item(self):
99 "Does a RecordDict basically wrap a dict properly?"106 """Does a RecordDict basically wrap a dict properly?"""
100 self.assertEqual(self.dict["a"], self.record["a"])107 self.assertEqual(self.dict["a"], self.record["a"])
101 self.assertRaises(KeyError,108 self.assertRaises(KeyError,
102 self.record.__getitem__, "application_annotations")109 self.record.__getitem__, "application_annotations")
103110
104 def test_get(self):111 def test_get(self):
105 "Does a RecordDict get() work?"112 """Does a RecordDict get() work?"""
106 self.assertEqual(self.dict["a"], self.record.get("a"))113 self.assertEqual(self.dict["a"], self.record.get("a"))
107 self.assertEqual(None, self.record.get("application_annotations"))114 self.assertEqual(None, self.record.get("application_annotations"))
108115
@@ -131,7 +138,7 @@
131 my_app_data['foo'])138 my_app_data['foo'])
132139
133 def test_loads_dict_subdict(self):140 def test_loads_dict_subdict(self):
134 "Are subdicts supported?"141 """Are subdicts supported?"""
135 self.assertEqual(2, len(self.record["subfield"]))142 self.assertEqual(2, len(self.record["subfield"]))
136 subfield_single = self.record["subfield"]143 subfield_single = self.record["subfield"]
137 self.assertEqual(144 self.assertEqual(
@@ -139,7 +146,7 @@
139 self.dict["subfield"]["field11s"])146 self.dict["subfield"]["field11s"])
140147
141 def test_loads_dict_multi_subdict(self):148 def test_loads_dict_multi_subdict(self):
142 "Are subdicts with multiple entries supported?"149 """Are subdicts with multiple entries supported?"""
143 self.assertEqual(2, len(self.record["subfield_uuid"]))150 self.assertEqual(2, len(self.record["subfield_uuid"]))
144151
145 def test_mergeable_list_index(self):152 def test_mergeable_list_index(self):
@@ -212,21 +219,22 @@
212 """Test missing data rmeoval"""219 """Test missing data rmeoval"""
213 self.assertRaises(ValueError, self.record["subfield_uuid"].remove, 220 self.assertRaises(ValueError, self.record["subfield_uuid"].remove,
214 "missing_data")221 "missing_data")
222
215 def test_mergeable_list_remove_last(self):223 def test_mergeable_list_remove_last(self):
216 """Test that exception is raised when removing last item."""224 """Test that exception is raised when removing last item."""
217 self.record["subfield_uuid"] = [1]225 self.record["subfield_uuid"] = MergeableList.from_list([1])
218 self.assertRaises(ValueError, self.record["subfield_uuid"].remove, 1)226 self.assertRaises(ValueError, self.record["subfield_uuid"].remove, 1)
219 227
220 def test_mergeable_list_pop_correct_index(self):228 def test_mergeable_list_pop_correct_index(self):
221 """Test the pop method when working with a correct index."""229 """Test the pop method when working with a correct index."""
222 value = [1, 2, 3, 4, 5]230 value = [1, 2, 3, 4, 5]
223 self.record["subfield_uuid"] = value231 self.record["subfield_uuid"] = MergeableList.from_list(value)
224 # test with negative index232 # test with negative index
225 poped_value = self.record["subfield_uuid"].pop(-2)233 popped_value = self.record["subfield_uuid"].pop(-2)
226 self.assertEqual(value[-2], poped_value)234 self.assertEqual(value[-2], popped_value)
227 # test with positive index235 # test with positive index
228 poped_value = self.record["subfield_uuid"].pop(1)236 popped_value = self.record["subfield_uuid"].pop(1)
229 self.assertEqual(value[1], poped_value)237 self.assertEqual(value[1], popped_value)
230 238
231 def test_mergeable_list_pop_wrong_index(self):239 def test_mergeable_list_pop_wrong_index(self):
232 """Test pop when index is out or range."""240 """Test pop when index is out or range."""
@@ -237,20 +245,20 @@
237 245
238 def test_mergeable_list_pop_last(self):246 def test_mergeable_list_pop_last(self):
239 """Test that exception is raised when poping last item"""247 """Test that exception is raised when poping last item"""
240 self.record["subfield_uuid"] = [1]248 self.record["subfield_uuid"] = MergeableList.from_list([1])
241 self.assertRaises(ValueError, self.record["subfield_uuid"].pop, 0)249 self.assertRaises(ValueError, self.record["subfield_uuid"].pop, 0)
242 250
243 def test_tuple(self):
244 """Test assigning tuples to a key results in mergeable lists."""
245 rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
246 rec['key'] = (1, 2, 3, 4)
247 self.assert_(isinstance(rec['key'], MergeableList))
248 self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
249
250 def test_list(self):251 def test_list(self):
251 """Test assigning lists to a key results in mergeable lists."""252 """Test assigning lists to a key results in mergeable lists."""
252 rec = Record({'record_type': 'http://fnord.org/smorgasbord'})253 rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
253 rec['key'] = [1, 2, 3, 4]254 rec['key'] = [1, 2, 3, 4]
255 self.assert_(isinstance(rec['key'], list))
256 self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
257
258 def test_mergeable_list(self):
259 """Test assigning lists to a key results in mergeable lists."""
260 rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
261 rec['key'] = MergeableList.from_list([1, 2, 3, 4])
254 self.assert_(isinstance(rec['key'], MergeableList))262 self.assert_(isinstance(rec['key'], MergeableList))
255 self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])263 self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
256264
@@ -291,12 +299,14 @@
291 self.record.record_type)299 self.record.record_type)
292300
293 def test_run_doctests(self):301 def test_run_doctests(self):
302 """Run all doc tests from here to set the proper context (ctx)"""
294 ctx = test_environment.test_context303 ctx = test_environment.test_context
295 globs = { "db": CouchDatabase('testing', create=True, ctx=ctx) }304 globs = { "db": CouchDatabase('testing', create=True, ctx=ctx) }
296 results = doctest.testfile('../doc/records.txt', globs=globs)305 results = doctest.testfile('../doc/records.txt', globs=globs)
297 self.assertEqual(0, results.failed)306 self.assertEqual(0, results.failed)
298307
299 def test_record_id(self):308 def test_record_id(self):
309 """Test all passible way to assign a record id"""
300 data = {"_id":"recordid"}310 data = {"_id":"recordid"}
301 record = Record(data, record_type="url")311 record = Record(data, record_type="url")
302 self.assertEqual(data["_id"], record.record_id)312 self.assertEqual(data["_id"], record.record_id)
@@ -309,6 +319,7 @@
309 Record, data, record_id=record_id, record_type="url")319 Record, data, record_id=record_id, record_type="url")
310320
311 def test_record_type_version(self):321 def test_record_type_version(self):
322 """Test record type version support"""
312 data = {"_id":"recordid"}323 data = {"_id":"recordid"}
313 record1 = Record(data, record_type="url")324 record1 = Record(data, record_type="url")
314 self.assertIs(None, record1.record_type_version)325 self.assertIs(None, record1.record_type_version)

Subscribers

People subscribed via source and target branches