~clint-fewbar/+junk/python-pymongo-packaging

« back to all changes in this revision

Viewing changes to tests/test_structure.py

  • Committer: Clint Byrum
  • Date: 2012-01-25 21:53:57 UTC
  • Revision ID: clint@ubuntu.com-20120125215357-j603u9d5alv1bt9v
Tags: upstream-0.7.2
ImportĀ upstreamĀ versionĀ 0.7.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
# Copyright (c) 2009-2011, Nicolas Clairon
 
4
# All rights reserved.
 
5
# Redistribution and use in source and binary forms, with or without
 
6
# modification, are permitted provided that the following conditions are met:
 
7
#
 
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.
 
16
#
 
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.
 
27
 
 
28
import unittest
 
29
 
 
30
from mongokit import *
 
31
 
 
32
class StructureTestCase(unittest.TestCase):
 
33
    def setUp(self):
 
34
        self.connection = Connection()
 
35
        self.col = self.connection['test']['mongokit']
 
36
        
 
37
    def tearDown(self):
 
38
        self.connection['test'].drop_collection('mongokit')
 
39
 
 
40
    def test_no_structure(self):
 
41
        failed = False
 
42
        try:
 
43
            class MyDoc(SchemaDocument): pass
 
44
        except StructureError:
 
45
            failed = True
 
46
        self.assertEqual(failed, False)
 
47
 
 
48
    def test_empty_structure(self):
 
49
        class MyDoc(SchemaDocument):
 
50
            structure = {}
 
51
        assert MyDoc() == {}
 
52
 
 
53
    def test_structure_not_dict(self):
 
54
        failed = False
 
55
        try:
 
56
            class MyDoc(SchemaDocument):
 
57
                structure = 3
 
58
        except StructureError:
 
59
            failed = True
 
60
        self.assertEqual(failed, True)
 
61
 
 
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}}
 
66
        mydoc = MyDoc(doc)
 
67
        assert mydoc == doc
 
68
        mydoc.validate()
 
69
        
 
70
    def test_simple_structure(self):
 
71
        class MyDoc(SchemaDocument):
 
72
            structure = {
 
73
                "foo":unicode,
 
74
                "bar":int
 
75
            }
 
76
        assert MyDoc() == {"foo":None, "bar":None}
 
77
 
 
78
    def test_missed_field(self):
 
79
        doc = {"foo":u"arf"}
 
80
        class MyDoc(SchemaDocument):
 
81
            structure = {
 
82
                "foo":unicode,
 
83
                "bar":{"bla":int}
 
84
            }
 
85
        mydoc = MyDoc(doc)
 
86
        self.assertRaises(StructureError, mydoc.validate)
 
87
 
 
88
    def test_unknown_field(self):
 
89
        class MyDoc(SchemaDocument):
 
90
            structure = {
 
91
                "foo":unicode,
 
92
            }
 
93
        mydoc = MyDoc()
 
94
        mydoc["bar"] = 4
 
95
        self.assertRaises(StructureError, mydoc.validate)
 
96
 
 
97
    def test_None(self):
 
98
        class MyDoc(SchemaDocument):
 
99
            structure = {
 
100
                "foo":None,
 
101
                "bar":{
 
102
                    "bla":None
 
103
                }
 
104
            }
 
105
        mydoc = MyDoc()
 
106
        mydoc['foo'] = u'bla'
 
107
        mydoc.validate()
 
108
        mydoc['foo'] = 3
 
109
        mydoc['bar']['bla'] = 2
 
110
        mydoc.validate()
 
111
        mydoc['foo'] = 'arf'
 
112
        self.assertRaises(AuthorizedTypeError, mydoc.validate)
 
113
 
 
114
    def test_big_nested_structure(self):
 
115
        class MyDoc(SchemaDocument):
 
116
            structure = {
 
117
                "1":{
 
118
                    "2":{
 
119
                        "3":{
 
120
                            "4":{
 
121
                                "5":{
 
122
                                    "6":{
 
123
                                        "7":int,
 
124
                                        "8":{
 
125
                                            unicode:{int:int}
 
126
                                        }
 
127
                                    }
 
128
                                }
 
129
                            }
 
130
                        }
 
131
                    }
 
132
                }
 
133
            }
 
134
        mydoc = MyDoc()
 
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}}
 
142
        mydoc.validate()
 
143
 
 
144
    def test_big_nested_structure_mongo_document(self):
 
145
        class MyDoc(Document):
 
146
            structure = {
 
147
                "1":{
 
148
                    "2":{
 
149
                        "3":{
 
150
                            "4":{
 
151
                                "5":{
 
152
                                    "6":{
 
153
                                        "7":int,
 
154
                                        "8":{
 
155
                                            unicode:{unicode:int}
 
156
                                        }
 
157
                                    }
 
158
                                }
 
159
                            }
 
160
                        }
 
161
                    }
 
162
                }
 
163
            }
 
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}}
 
173
        mydoc.validate()
 
174
            
 
175
    def test_dot_notation(self):
 
176
        class MyDoc(SchemaDocument):
 
177
            use_dot_notation = True
 
178
            structure = {
 
179
                "foo":int,
 
180
                "bar":unicode
 
181
            }
 
182
 
 
183
        mydoc = MyDoc()
 
184
        mydoc.foo = "3"
 
185
        self.assertRaises(SchemaTypeError, mydoc.validate)
 
186
        mydoc.foo = 3
 
187
        assert mydoc['foo'] == 3
 
188
        assert mydoc == {'foo':3, 'bar':None}
 
189
        mydoc.validate()
 
190
        mydoc.bar = u"bar"
 
191
        assert mydoc == {'foo':3, 'bar':'bar'}
 
192
        mydoc.validate()
 
193
        
 
194
    def test_dot_notation_nested(self):
 
195
        class MyDoc(SchemaDocument):
 
196
            use_dot_notation = True
 
197
            structure = {
 
198
                "foo":{
 
199
                    "bar":unicode
 
200
                }
 
201
            }
 
202
 
 
203
        mydoc = MyDoc()
 
204
        mydoc.foo.bar = 3
 
205
        self.assertRaises(SchemaTypeError, mydoc.validate)
 
206
        mydoc.foo.bar = u"bar"
 
207
        assert mydoc.foo.bar == u'bar'
 
208
        mydoc.foo.bla = 2
 
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'}}
 
213
        mydoc.validate()
 
214
 
 
215
    def test_document_dot_notation_nested(self):
 
216
        class MyDoc(Document):
 
217
            use_dot_notation = True
 
218
            structure = {
 
219
                "foo":{
 
220
                    "bar":unicode
 
221
                }
 
222
            }
 
223
        self.connection.register([MyDoc])
 
224
 
 
225
        mydoc = self.col.MyDoc()
 
226
        mydoc.foo.bar = u"bar"
 
227
        self.assertEqual(mydoc.foo.bar, u'bar')
 
228
        mydoc.foo.bla = 2
 
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'}})
 
234
        mydoc.save()
 
235
 
 
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")
 
239
 
 
240
 
 
241
    def test_dot_notation_field_not_in_structure(self):
 
242
        class MyDoc(SchemaDocument):
 
243
            use_dot_notation = True
 
244
            structure = {
 
245
                "foo":{
 
246
                    "bar":unicode,
 
247
                },
 
248
                "spam":int,
 
249
            }
 
250
 
 
251
        import logging
 
252
        logging.basicConfig()
 
253
        mydoc = MyDoc()
 
254
        mydoc.eggs = 4
 
255
        assert mydoc == {'foo':{'bar':None}, 'spam':None}
 
256
        assert mydoc.eggs == 4
 
257
        try:
 
258
            mydoc.not_found
 
259
        except AttributeError, e:
 
260
            print str(e)
 
261
        mydoc.foo.eggs = 4
 
262
        assert mydoc == {'foo':{'bar':None}, 'spam':None}, mydoc
 
263
        mydoc.validate()
 
264
 
 
265
 
 
266
    def test_field_changed(self):
 
267
        class MyDoc(Document):
 
268
            structure = {
 
269
                'foo':int,
 
270
                'bar':unicode,
 
271
            }
 
272
        self.connection.register([MyDoc])
 
273
        
 
274
        doc = self.col.MyDoc()
 
275
        doc['foo'] = 3
 
276
        doc.save()
 
277
 
 
278
        class MyDoc(Document):
 
279
            structure = {
 
280
                'foo':int,
 
281
                'arf': unicode,
 
282
            }
 
283
        self.connection.register([MyDoc])
 
284
        
 
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)
 
289
 
 
290
        fetched_doc = self.col.MyDoc.find_one()
 
291
        self.assertRaises(StructureError, fetched_doc.validate)
 
292
 
 
293
 
 
294
    def test_exception_bad_structure(self):
 
295
        import datetime
 
296
        failed = False
 
297
        try:
 
298
            class MyDoc(SchemaDocument):
 
299
                structure = {
 
300
                    'topic': unicode,
 
301
                    'when': datetime.datetime.utcnow,
 
302
                }
 
303
        except TypeError, e:
 
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")
 
306
            failed = True
 
307
        self.assertEqual(failed, True)
 
308