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
1=== modified file 'desktopcouch/records/field_registry.py'
2--- desktopcouch/records/field_registry.py 2010-04-05 17:46:53 +0000
3+++ desktopcouch/records/field_registry.py 2010-11-02 23:33:40 +0000
4@@ -21,6 +21,7 @@
5
6 import copy
7
8+from desktopcouch.records.record import MergeableList
9 ANNOTATION_NAMESPACE = 'application_annotations'
10
11
12@@ -132,7 +133,8 @@
13 values.update({self._field_name: value})
14 if not root_list:
15 # This is the first value we add to the list
16- record[self._root_list] = [values]
17+ ml = MergeableList.from_list([values])
18+ record[self._root_list] = ml
19 uuid_key = record[self._root_list].get_uuid_for_index(-1)
20 application_annotations[self._uuid_field] = uuid_key
21 return
22
23=== modified file 'desktopcouch/records/record.py'
24--- desktopcouch/records/record.py 2010-10-31 23:20:14 +0000
25+++ desktopcouch/records/record.py 2010-11-02 23:33:40 +0000
26@@ -42,19 +42,8 @@
27 """Create a RecordDict or RecordList from passed data."""
28 if isinstance(data, dict):
29 return _build_from_dict(data)
30- if isinstance(data, (list, tuple)):
31- return _build_from_list(data)
32 return data
33
34-def _build_from_list(data):
35- """Create a RecordList from passed data."""
36- if not data:
37- raise ValueError("Can't set empty list values.'")
38- result = MergeableList({})
39- for value in data:
40- result.append(record_factory(value))
41- return result
42-
43 def _build_from_dict(data):
44 """Create a RecordDict from passed data."""
45 result = RecordDict({})
46@@ -155,7 +144,7 @@
47 return value
48
49 def __setitem__(self, key, item):
50- if isinstance(item, (list, tuple, dict)):
51+ if isinstance(item, dict):
52 item = record_factory(item)
53 if hasattr(item, '_data'):
54 item = item._data
55@@ -258,6 +247,16 @@
56 class MergeableList(RecordData):
57 """An object that represents a list of complex values."""
58
59+ @classmethod
60+ def from_list(klass, data):
61+ """Create a RecordList from passed data."""
62+ if not data:
63+ raise ValueError("Can't set empty list values.'")
64+ result = klass({})
65+ for value in data:
66+ result.append(record_factory(value))
67+ return result
68+
69 def __getitem__(self, index):
70 if not isinstance(index, int):
71 raise TypeError(
72
73=== modified file 'desktopcouch/records/tests/test_record.py'
74--- desktopcouch/records/tests/test_record.py 2010-10-31 15:52:12 +0000
75+++ desktopcouch/records/tests/test_record.py 2010-11-02 23:33:40 +0000
76@@ -1,4 +1,4 @@
77-# Copyright 2009 Canonical Ltd.
78+# Copyright 2009-2010 Canonical Ltd.
79 #
80 # This file is part of desktopcouch.
81 #
82@@ -15,6 +15,7 @@
83 # along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
84 #
85 # Authors: Eric Casteleijn <eric.casteleijn@canonical.com>
86+# Vincenzo Di Somma <vincenzo.di.somma@canonical.com>
87
88 """Tests for the RecordDict object on which the Contacts API is built."""
89
90@@ -55,6 +56,8 @@
91 self.record = Record(self.dict)
92
93 def test_revision(self):
94+ """Test document always has a revision field and that the revision
95+ changes when the document is updated"""
96 self.assertEquals(self.record.record_revision, None)
97 def set_rev(rec): rec.record_revision = "1"
98 self.assertRaises(AttributeError, set_rev, self.record)
99@@ -77,6 +80,7 @@
100 db.delete_record(record_id)
101
102 def test_delitem(self):
103+ """Test removing a field from the record"""
104 def f(r):
105 del r["_id"]
106 self.assertRaises(KeyError, f, self.record)
107@@ -84,25 +88,28 @@
108 del self.record["a"]
109
110 def test_iter(self):
111+ """Tests it is possible to iterate over the record fields"""
112 self.assertEquals(sorted(list(iter(self.record))),
113 ['a', 'b', 'record_type', 'subfield', 'subfield_uuid'])
114
115 def test_setitem_internal(self):
116+ """Test it is not possible to set a private field on a record"""
117 def f(r):
118 r["_id"] = "new!"
119 self.assertRaises(IllegalKeyException, f, self.record)
120
121 def test_no_record_type(self):
122+ """Test that creating a record with no record type fails"""
123 self.assertRaises(NoRecordTypeSpecified, Record, {})
124
125 def test_get_item(self):
126- "Does a RecordDict basically wrap a dict properly?"
127+ """Does a RecordDict basically wrap a dict properly?"""
128 self.assertEqual(self.dict["a"], self.record["a"])
129 self.assertRaises(KeyError,
130 self.record.__getitem__, "application_annotations")
131
132 def test_get(self):
133- "Does a RecordDict get() work?"
134+ """Does a RecordDict get() work?"""
135 self.assertEqual(self.dict["a"], self.record.get("a"))
136 self.assertEqual(None, self.record.get("application_annotations"))
137
138@@ -131,7 +138,7 @@
139 my_app_data['foo'])
140
141 def test_loads_dict_subdict(self):
142- "Are subdicts supported?"
143+ """Are subdicts supported?"""
144 self.assertEqual(2, len(self.record["subfield"]))
145 subfield_single = self.record["subfield"]
146 self.assertEqual(
147@@ -139,7 +146,7 @@
148 self.dict["subfield"]["field11s"])
149
150 def test_loads_dict_multi_subdict(self):
151- "Are subdicts with multiple entries supported?"
152+ """Are subdicts with multiple entries supported?"""
153 self.assertEqual(2, len(self.record["subfield_uuid"]))
154
155 def test_mergeable_list_index(self):
156@@ -212,21 +219,22 @@
157 """Test missing data rmeoval"""
158 self.assertRaises(ValueError, self.record["subfield_uuid"].remove,
159 "missing_data")
160+
161 def test_mergeable_list_remove_last(self):
162 """Test that exception is raised when removing last item."""
163- self.record["subfield_uuid"] = [1]
164+ self.record["subfield_uuid"] = MergeableList.from_list([1])
165 self.assertRaises(ValueError, self.record["subfield_uuid"].remove, 1)
166
167 def test_mergeable_list_pop_correct_index(self):
168 """Test the pop method when working with a correct index."""
169 value = [1, 2, 3, 4, 5]
170- self.record["subfield_uuid"] = value
171+ self.record["subfield_uuid"] = MergeableList.from_list(value)
172 # test with negative index
173- poped_value = self.record["subfield_uuid"].pop(-2)
174- self.assertEqual(value[-2], poped_value)
175+ popped_value = self.record["subfield_uuid"].pop(-2)
176+ self.assertEqual(value[-2], popped_value)
177 # test with positive index
178- poped_value = self.record["subfield_uuid"].pop(1)
179- self.assertEqual(value[1], poped_value)
180+ popped_value = self.record["subfield_uuid"].pop(1)
181+ self.assertEqual(value[1], popped_value)
182
183 def test_mergeable_list_pop_wrong_index(self):
184 """Test pop when index is out or range."""
185@@ -237,20 +245,20 @@
186
187 def test_mergeable_list_pop_last(self):
188 """Test that exception is raised when poping last item"""
189- self.record["subfield_uuid"] = [1]
190+ self.record["subfield_uuid"] = MergeableList.from_list([1])
191 self.assertRaises(ValueError, self.record["subfield_uuid"].pop, 0)
192
193- def test_tuple(self):
194- """Test assigning tuples to a key results in mergeable lists."""
195- rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
196- rec['key'] = (1, 2, 3, 4)
197- self.assert_(isinstance(rec['key'], MergeableList))
198- self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
199-
200 def test_list(self):
201 """Test assigning lists to a key results in mergeable lists."""
202 rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
203 rec['key'] = [1, 2, 3, 4]
204+ self.assert_(isinstance(rec['key'], list))
205+ self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
206+
207+ def test_mergeable_list(self):
208+ """Test assigning lists to a key results in mergeable lists."""
209+ rec = Record({'record_type': 'http://fnord.org/smorgasbord'})
210+ rec['key'] = MergeableList.from_list([1, 2, 3, 4])
211 self.assert_(isinstance(rec['key'], MergeableList))
212 self.assertEqual([1, 2, 3, 4], [value for value in rec['key']])
213
214@@ -291,12 +299,14 @@
215 self.record.record_type)
216
217 def test_run_doctests(self):
218+ """Run all doc tests from here to set the proper context (ctx)"""
219 ctx = test_environment.test_context
220 globs = { "db": CouchDatabase('testing', create=True, ctx=ctx) }
221 results = doctest.testfile('../doc/records.txt', globs=globs)
222 self.assertEqual(0, results.failed)
223
224 def test_record_id(self):
225+ """Test all passible way to assign a record id"""
226 data = {"_id":"recordid"}
227 record = Record(data, record_type="url")
228 self.assertEqual(data["_id"], record.record_id)
229@@ -309,6 +319,7 @@
230 Record, data, record_id=record_id, record_type="url")
231
232 def test_record_type_version(self):
233+ """Test record type version support"""
234 data = {"_id":"recordid"}
235 record1 = Record(data, record_type="url")
236 self.assertIs(None, record1.record_type_version)

Subscribers

People subscribed via source and target branches