Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: tests/model_test.py

Issue 11414143: Change models.py to use typed class members instead of a list of strings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/commit-queue
Patch Set: Address review comments Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pending_manager.py ('k') | tests/pending_manager_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Unit tests for model.py.""" 6 """Unit tests for model.py."""
7 7
8 import logging
8 import os 9 import os
9 import sys 10 import sys
10 import unittest 11 import unittest
11 12
12 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 13 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
13 sys.path.insert(0, os.path.join(ROOT_DIR, '..')) 14 sys.path.insert(0, os.path.join(ROOT_DIR, '..'))
14 from model import MODULE_FLAG, PersistentMixIn, TYPE_FLAG 15 from model import PersistentMixIn, TYPE_FLAG
15 16
16 17
17 class Invalid(PersistentMixIn): 18 # Used a marker to determine that the check must ignore the value.
19 IGNORE = object()
20
21
22 def _members(instance):
23 return sorted(i for i in dir(instance) if not i.startswith('_'))
24
25
26 class Empty(PersistentMixIn):
18 pass 27 pass
19 28
20 29
21 class MemberNotFound(PersistentMixIn):
22 persistent = ('a',)
23
24 @staticmethod
25 def test_me(x):
26 return x + 1
27
28
29 class Basic(PersistentMixIn): 30 class Basic(PersistentMixIn):
30 persistent = ('a', 'b') 31 a = int
31 a = None 32 b = float
32 b = None 33
34 def test_me(self):
35 return self.a + 1
33 36
34 37
35 class Inner(PersistentMixIn): 38 class Inner(PersistentMixIn):
36 persistent = ('c', 'd') 39 c = Basic
37 40 d = str
41
42
43 class Subclass(Inner):
44 e = list
45
46
47 class MultiValue(PersistentMixIn):
48 f = (None, int)
49 g = (str, float)
50
51
52 class WithInit(PersistentMixIn):
53 h = str
38 def __init__(self): 54 def __init__(self):
39 super(Inner, self).__init__() 55 # The values are overriden when loaded.
40 self.c = Basic() 56 super(WithInit, self).__init__(h='baz')
41 self.c.a = 'hello' 57 # i is not serialized.
42 self.d = 'foo' 58 self.i = 3
43 self.extra = 'extra' 59
44 60
45 61 class NotType(PersistentMixIn):
46 class Serialize(unittest.TestCase): 62 j = set
47 def testInvalid(self): 63 # k is not a type so it's not serialized.
48 a = Invalid() 64 k = 23
49 self.assertRaises(AssertionError, a.as_dict) 65
50 66
51 def testMemberNotFound(self): 67 class TypeOrDict(PersistentMixIn):
52 a = MemberNotFound() 68 # Accepts a Basic or a dict.
53 self.assertRaises(AttributeError, a.as_dict) 69 l = (Basic, dict)
70
71
72 class Base(unittest.TestCase):
73 def _check(self, actual, expected_type, **kwargs):
74 kwargs['as_dict'] = IGNORE
75 kwargs['from_dict'] = IGNORE
76 self.assertEqual(expected_type, type(actual))
77 self.assertEqual(sorted(kwargs), _members(actual))
78 for member in sorted(kwargs):
79 expected = kwargs[member]
80 if expected == IGNORE:
81 continue
82 self.assertEqual(expected, getattr(actual, member))
83
84
85 class Serialize(Base):
86 def testEmpty(self):
87 expected = {
88 TYPE_FLAG: 'Empty',
89 }
90 self.assertEqual(expected, Empty().as_dict())
54 91
55 def testBasic(self): 92 def testBasic(self):
56 a = Basic() 93 data = Basic(b=23.2)
57 a.b = 23.2 94 expected = {
58 expected = { 95 'a': 0,
59 'a': None,
60 'b': 23.2, 96 'b': 23.2,
61 TYPE_FLAG: 'Basic', 97 TYPE_FLAG: 'Basic',
62 MODULE_FLAG: '__main__', 98 }
63 } 99 self.assertEqual(expected, data.as_dict())
64 self.assertEquals(expected, a.as_dict())
65 100
66 def testInner(self): 101 def testInner(self):
67 a = Inner() 102 data = Inner(c=Basic(a=21, b=23.2), d='foo')
68 expected = { 103 expected = {
69 'c': { 104 'c': {
70 'a': 'hello', 105 'a': 21,
71 'b': None, 106 'b': 23.2,
72 TYPE_FLAG: 'Basic', 107 TYPE_FLAG: 'Basic',
73 MODULE_FLAG: '__main__',
74 }, 108 },
75 TYPE_FLAG: 'Inner', 109 TYPE_FLAG: 'Inner',
76 MODULE_FLAG: '__main__',
77 'd': 'foo', 110 'd': 'foo',
78 } 111 }
79 self.assertEquals(expected, a.as_dict()) 112 self.assertEqual(expected, data.as_dict())
80 113
81 def testInnerList(self): 114 def testSubclass(self):
82 """Test serialization of: 115 data = Subclass(c=Basic(a=23), e=[Basic()])
83 - Embedded objects 116 expected = {
84 - list 117 'c': {
85 - dict 118 'a': 23,
86 - string 119 'b': 0.,
87 - int 120 TYPE_FLAG: 'Basic',
88 """ 121 },
89 a = Basic() 122 'e': [
90 a.b = [Basic(), 23]
91 a.a = {'x': 'y'}
92 expected = {
93 'a': {'x': 'y'},
94 'b': [
95 { 123 {
96 'a': None, 124 'a': 0,
97 'b': None, 125 'b': 0.,
98 TYPE_FLAG: 'Basic', 126 TYPE_FLAG: 'Basic',
99 MODULE_FLAG: '__main__',
100 }, 127 },
101 23
102 ], 128 ],
103 TYPE_FLAG: 'Basic', 129 'd': '',
104 MODULE_FLAG: '__main__', 130 TYPE_FLAG: 'Subclass',
105 } 131 }
106 self.assertEquals(expected, a.as_dict()) 132 self.assertEqual(expected, data.as_dict())
107 133
108 134 def testMultiValue_default(self):
109 class Unas_dict(unittest.TestCase): 135 data = MultiValue()
110 def testInvalid(self): 136 expected = {
111 data = { TYPE_FLAG: 'Invalid' } 137 'f': None,
112 self.assertRaises(TypeError, PersistentMixIn.from_dict, data) 138 'g': '',
113 139 TYPE_FLAG: 'MultiValue',
140 }
141 self.assertEqual(expected, data.as_dict())
142
143 def testMultiValue_first(self):
144 data = MultiValue(f=None, g='foo')
145 expected = {
146 'f': None,
147 'g': 'foo',
148 TYPE_FLAG: 'MultiValue',
149 }
150 self.assertEqual(expected, data.as_dict())
151
152 def testMultiValue_second(self):
153 data = MultiValue(f=2, g=3.1)
154 expected = {
155 'f': 2,
156 'g': 3.1,
157 TYPE_FLAG: 'MultiValue',
158 }
159 self.assertEqual(expected, data.as_dict())
160
161 def testWithInit(self):
162 data = WithInit()
163 self._check(data, WithInit, h='baz', i=3)
164 expected = {
165 'h': 'baz',
166 TYPE_FLAG: 'WithInit',
167 }
168 self.assertEqual(expected, data.as_dict())
169
170 def testNotType(self):
171 data = NotType()
172 self._check(data, NotType, j=set(), k=23)
173 expected = {
174 'j': [],
175 TYPE_FLAG: 'NotType',
176 }
177 self.assertEqual(expected, data.as_dict())
178
179 def testTypeOrDict_Basic(self):
180 data = TypeOrDict()
181 self._check(data, TypeOrDict, l=IGNORE)
182 self._check(data.l, Basic, a=0, b=0., test_me=IGNORE)
183 expected = {
184 'l': {
185 'a': 0,
186 'b': 0.0,
187 TYPE_FLAG: 'Basic',
188 },
189 TYPE_FLAG: 'TypeOrDict',
190 }
191 self.assertEqual(expected, data.as_dict())
192
193 def testTypeOrDict_dict(self):
194 data = TypeOrDict(l={'foo': 'bar'})
195 self._check(data, TypeOrDict, l={'foo': 'bar'})
196 expected = {
197 'l': {
198 'foo': 'bar',
199 },
200 TYPE_FLAG: 'TypeOrDict',
201 }
202 self.assertEqual(expected, data.as_dict())
203
204
205
206 class Deserialize(Base):
114 def testNotFound(self): 207 def testNotFound(self):
115 data = { TYPE_FLAG: 'DoesNotExists' } 208 data = { TYPE_FLAG: 'DoesNotExists' }
116 self.assertRaises(KeyError, PersistentMixIn.from_dict, data) 209 self.assertRaises(KeyError, PersistentMixIn.from_dict, data)
117 210
118 def testEmpty(self): 211 def testEmpty(self):
119 data = { } 212 data = { }
120 self.assertRaises(KeyError, PersistentMixIn.from_dict, data) 213 self.assertRaises(KeyError, PersistentMixIn.from_dict, data)
121 214
122 def testBasic(self): 215 def testBasic(self):
123 data = { 216 data = {
124 'a': None, 217 'a': 22,
125 'b': 23.2, 218 'b': 23.2,
126 TYPE_FLAG: 'Basic', 219 TYPE_FLAG: 'Basic',
127 MODULE_FLAG: '__main__',
128 } 220 }
129 a = PersistentMixIn.from_dict(data) 221 actual = PersistentMixIn.from_dict(data)
130 self.assertEquals(Basic, type(a)) 222 self._check(actual, Basic, a=22, b=23.2, test_me=IGNORE)
131 self.assertEquals(None, a.a) 223
132 self.assertEquals(23.2, a.b) 224 def testBasic_WrongType(self):
225 data = {
226 'a': None,
227 TYPE_FLAG: 'Basic',
228 }
229 self.assertRaises(TypeError, PersistentMixIn.from_dict, data)
133 230
134 def testInner(self): 231 def testInner(self):
135 data = { 232 data = {
136 'c': { 233 'c': {
137 'a': 42, 234 'a': 42,
138 'b': [1, 2], 235 'b': .1,
139 TYPE_FLAG: 'Basic', 236 TYPE_FLAG: 'Basic',
140 MODULE_FLAG: '__main__',
141 }, 237 },
142 TYPE_FLAG: 'Inner', 238 TYPE_FLAG: 'Inner',
143 MODULE_FLAG: '__main__',
144 'd': 'foo2', 239 'd': 'foo2',
145 } 240 }
146 a = PersistentMixIn.from_dict(data) 241 actual = PersistentMixIn.from_dict(data)
147 self.assertEquals(Inner, type(a)) 242 self._check(actual, Inner, c=IGNORE, d='foo2')
148 self.assertEquals(Basic, type(a.c)) 243 self._check(actual.c, Basic, a=42, b=.1, test_me=IGNORE)
149 self.assertEquals(42, a.c.a)
150 self.assertEquals([1, 2], a.c.b)
151 self.assertEquals('foo2', a.d)
152 # Make sure __init__ is not called.
153 self.assertFalse(hasattr(a, 'extra'))
154 244
155 def testInnerList(self): 245 def testSubclass(self):
156 """Test unserialization of:
157 - Embedded objects
158 - list
159 - dict
160 - string
161 - int
162 """
163 data = { 246 data = {
164 'a': None, 247 'd': 'bar',
165 'b': [ 248 'e': [
166 { 249 {
167 'a': {'x': 'y'}, 250 'a': 1,
168 'b': None, 251 'b': 2.,
169 TYPE_FLAG: 'Basic', 252 TYPE_FLAG: 'Basic',
170 MODULE_FLAG: '__main__',
171 }, 253 },
172 23
173 ], 254 ],
174 TYPE_FLAG: 'Basic', 255 TYPE_FLAG: 'Subclass',
175 MODULE_FLAG: '__main__',
176 } 256 }
177 a = PersistentMixIn.from_dict(data) 257 actual = PersistentMixIn.from_dict(data)
178 self.assertEquals(Basic, type(a)) 258 self._check(actual, Subclass, c=IGNORE, d='bar', e=IGNORE)
179 self.assertEquals(None, a.a) 259 self._check(actual.c, Basic, a=0, b=0., test_me=IGNORE)
180 self.assertEquals(2, len(a.b)) 260 self.assertEqual(list, type(actual.e))
181 self.assertEquals(Basic, type(a.b[0])) 261 self.assertEqual(1, len(actual.e))
182 self.assertEquals({'x': 'y'}, a.b[0].a) 262 self._check(actual.e[0], Basic, a=1, b=2., test_me=IGNORE)
183 self.assertEquals(None, a.b[0].b)
184 self.assertEquals(23, a.b[1])
185 263
186 def testMemberFunction(self): 264 def testMemberFunction(self):
265 # Make sure the member functions are accessible.
187 data = { 266 data = {
188 TYPE_FLAG: 'MemberNotFound', 267 TYPE_FLAG: 'Basic',
268 'ignored': 'really',
189 } 269 }
190 a = PersistentMixIn.from_dict(data) 270 actual = PersistentMixIn.from_dict(data)
191 self.assertEquals(MemberNotFound, type(a)) 271 self._check(actual, Basic, a=0, b=0., test_me=IGNORE)
192 # Make sure the member functions are accessible. 272 self.assertEqual(1, actual.test_me())
193 self.assertEquals(3, a.test_me(2)) 273
274 def testMultiValue_default(self):
275 data = {
276 TYPE_FLAG: 'MultiValue',
277 }
278 actual = PersistentMixIn.from_dict(data)
279 self._check(actual, MultiValue, f=None, g='')
280
281 def testMultiValue_first(self):
282 data = {
283 'f': None,
284 'g': 'foo',
285 TYPE_FLAG: 'MultiValue',
286 }
287 actual = PersistentMixIn.from_dict(data)
288 self._check(actual, MultiValue, f=None, g='foo')
289
290 def testMultiValue_second(self):
291 data = {
292 'f': 2,
293 'g': 3.1,
294 TYPE_FLAG: 'MultiValue',
295 }
296 actual = PersistentMixIn.from_dict(data)
297 self._check(actual, MultiValue, f=2, g=3.1)
298
299 def testWithInit_default(self):
300 data = {
301 TYPE_FLAG: 'WithInit',
302 }
303 actual = PersistentMixIn.from_dict(data)
304 self._check(actual, WithInit, h='', i=3)
305
306 def testWithInit_values(self):
307 data = {
308 'h': 'foo',
309 'i': 4,
310 TYPE_FLAG: 'WithInit',
311 }
312 actual = PersistentMixIn.from_dict(data)
313 self._check(actual, WithInit, h='foo', i=3)
314
315 def testNotType(self):
316 data = {
317 'j': ['a', 2],
318 TYPE_FLAG: 'NotType',
319 }
320 actual = PersistentMixIn.from_dict(data)
321 self._check(actual, NotType, j=set(['a', 2]), k=23)
322
323 def testTypeOrDict_Basic(self):
324 data = {
325 'l': {
326 'a': 3,
327 'b': 4.0,
328 TYPE_FLAG: 'Basic',
329 },
330 TYPE_FLAG: 'TypeOrDict',
331 }
332 actual = PersistentMixIn.from_dict(data)
333 self._check(actual, TypeOrDict, l=IGNORE)
334 self._check(actual.l, Basic, a=3, b=4., test_me=IGNORE)
335
336 def testTypeOrDict_dict(self):
337 data = {
338 'l': {
339 'foo': 'bar',
340 },
341 TYPE_FLAG: 'TypeOrDict',
342 }
343 actual = PersistentMixIn.from_dict(data)
344 self._check(actual, TypeOrDict, l={'foo': 'bar'})
194 345
195 346
196 if __name__ == '__main__': 347 if __name__ == '__main__':
348 logging.basicConfig(
349 level=logging.DEBUG if '-v' in sys.argv else logging.WARNING,
350 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
197 unittest.main() 351 unittest.main()
OLDNEW
« no previous file with comments | « pending_manager.py ('k') | tests/pending_manager_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698