2
# -*- coding: utf-8 -*-
3
# Copyright (c) 2009-2011, Nicolas Clairon
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are met:
8
# * Redistributions of source code must retain the above copyright
9
# notice, this list of conditions and the following disclaimer.
10
# * Redistributions in binary form must reproduce the above copyright
11
# notice, this list of conditions and the following disclaimer in the
12
# documentation and/or other materials provided with the distribution.
13
# * Neither the name of the University of California, Berkeley nor the
14
# names of its contributors may be used to endorse or promote products
15
# derived from this software without specific prior written permission.
17
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
18
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
21
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
from mongokit import *
32
class StructureTestCase(unittest.TestCase):
34
self.connection = Connection()
35
self.col = self.connection['test']['mongokit']
38
self.connection['test'].drop_collection('mongokit')
40
def test_no_structure(self):
43
class MyDoc(SchemaDocument): pass
44
except StructureError:
46
self.assertEqual(failed, False)
48
def test_empty_structure(self):
49
class MyDoc(SchemaDocument):
53
def test_structure_not_dict(self):
56
class MyDoc(SchemaDocument):
58
except StructureError:
60
self.assertEqual(failed, True)
62
def test_load_with_dict(self):
63
doc = {"foo":1, "bla":{"bar":u"spam"}}
64
class MyDoc(SchemaDocument):
65
structure = {"foo":int, "bla":{"bar":unicode}}
70
def test_simple_structure(self):
71
class MyDoc(SchemaDocument):
76
assert MyDoc() == {"foo":None, "bar":None}
78
def test_missed_field(self):
80
class MyDoc(SchemaDocument):
86
self.assertRaises(StructureError, mydoc.validate)
88
def test_unknown_field(self):
89
class MyDoc(SchemaDocument):
95
self.assertRaises(StructureError, mydoc.validate)
98
class MyDoc(SchemaDocument):
106
mydoc['foo'] = u'bla'
109
mydoc['bar']['bla'] = 2
112
self.assertRaises(AuthorizedTypeError, mydoc.validate)
114
def test_big_nested_structure(self):
115
class MyDoc(SchemaDocument):
135
assert mydoc._namespaces == ['1', '1.2', '1.2.3', '1.2.3.4', '1.2.3.4.5', '1.2.3.4.5.6', '1.2.3.4.5.6.8', '1.2.3.4.5.6.8.$unicode', '1.2.3.4.5.6.8.$unicode.$int', '1.2.3.4.5.6.7']
136
mydoc['1']['2']['3']['4']['5']['6']['7'] = 8
137
mydoc['1']['2']['3']['4']['5']['6']['8'] = {u"bla":{3:u"bla"}}
138
self.assertRaises(SchemaTypeError, mydoc.validate)
139
mydoc['1']['2']['3']['4']['5']['6']['8'] = {9:{3:10}}
140
self.assertRaises(SchemaTypeError, mydoc.validate)
141
mydoc['1']['2']['3']['4']['5']['6']['8'] = {u"bla":{3:4}}
144
def test_big_nested_structure_mongo_document(self):
145
class MyDoc(Document):
155
unicode:{unicode:int}
164
self.connection.register([MyDoc])
165
mydoc = self.col.MyDoc()
166
assert mydoc._namespaces == ['1', '1.2', '1.2.3', '1.2.3.4', '1.2.3.4.5', '1.2.3.4.5.6', '1.2.3.4.5.6.8', '1.2.3.4.5.6.8.$unicode', '1.2.3.4.5.6.8.$unicode.$unicode', '1.2.3.4.5.6.7']
167
mydoc['1']['2']['3']['4']['5']['6']['7'] = 8
168
mydoc['1']['2']['3']['4']['5']['6']['8'] = {u"bla":{"3":u"bla"}}
169
self.assertRaises(SchemaTypeError, mydoc.validate)
170
mydoc['1']['2']['3']['4']['5']['6']['8'] = {"9":{"3":10}}
171
self.assertRaises(SchemaTypeError, mydoc.validate)
172
mydoc['1']['2']['3']['4']['5']['6']['8'] = {u"bla":{u"3":4}}
175
def test_dot_notation(self):
176
class MyDoc(SchemaDocument):
177
use_dot_notation = True
185
self.assertRaises(SchemaTypeError, mydoc.validate)
187
assert mydoc['foo'] == 3
188
assert mydoc == {'foo':3, 'bar':None}
191
assert mydoc == {'foo':3, 'bar':'bar'}
194
def test_dot_notation_nested(self):
195
class MyDoc(SchemaDocument):
196
use_dot_notation = True
205
self.assertRaises(SchemaTypeError, mydoc.validate)
206
mydoc.foo.bar = u"bar"
207
assert mydoc.foo.bar == u'bar'
209
assert mydoc.foo.bla == 2
210
assert mydoc['foo'] == {"bar":"bar"}, mydoc
211
assert mydoc['foo']['bar'] == 'bar'
212
assert mydoc == {'foo':{'bar':'bar'}}
215
def test_document_dot_notation_nested(self):
216
class MyDoc(Document):
217
use_dot_notation = True
223
self.connection.register([MyDoc])
225
mydoc = self.col.MyDoc()
226
mydoc.foo.bar = u"bar"
227
self.assertEqual(mydoc.foo.bar, u'bar')
229
assert isinstance(mydoc.foo, DotedDict), type(mydoc.foo)
230
self.assertEqual(mydoc.foo.bla, 2)
231
self.assertEqual(mydoc['foo'], {"bar":"bar"})
232
self.assertEqual(mydoc['foo']['bar'], 'bar')
233
self.assertEqual(mydoc, {'foo':{'bar':'bar'}})
236
fetched_doc = self.col.MyDoc.find_one()
237
assert isinstance(fetched_doc.foo, DotedDict), type(fetched_doc.foo)
238
self.assertEqual(fetched_doc.foo.bar, "bar")
241
def test_dot_notation_field_not_in_structure(self):
242
class MyDoc(SchemaDocument):
243
use_dot_notation = True
252
logging.basicConfig()
255
assert mydoc == {'foo':{'bar':None}, 'spam':None}
256
assert mydoc.eggs == 4
259
except AttributeError, e:
262
assert mydoc == {'foo':{'bar':None}, 'spam':None}, mydoc
266
def test_field_changed(self):
267
class MyDoc(Document):
272
self.connection.register([MyDoc])
274
doc = self.col.MyDoc()
278
class MyDoc(Document):
283
self.connection.register([MyDoc])
285
fetched_doc = self.col.MyDoc.find_one()
286
self.assertRaises(StructureError, fetched_doc.validate)
287
fetched_doc['foo'] = 2
288
fetched_doc.save(validate=False)
290
fetched_doc = self.col.MyDoc.find_one()
291
self.assertRaises(StructureError, fetched_doc.validate)
294
def test_exception_bad_structure(self):
298
class MyDoc(SchemaDocument):
301
'when': datetime.datetime.utcnow,
304
assert str(e).startswith("MyDoc: <built-in method utcnow of type object at "), str(e)
305
assert str(e).endswith("is not a type")
307
self.assertEqual(failed, True)