59
63
self.assertRaises(TypeError, is_valid, u"test")
60
64
self.assertRaises(TypeError, is_valid, 10.4)
62
self.assertFalse(is_valid("test"))
66
self.assertFalse(is_valid(b("test")))
64
68
# the simplest valid BSON document
65
self.assert_(is_valid("\x05\x00\x00\x00\x00"))
66
self.assert_(is_valid(BSON("\x05\x00\x00\x00\x00")))
67
self.assertFalse(is_valid("\x04\x00\x00\x00\x00"))
68
self.assertFalse(is_valid("\x05\x00\x00\x00\x01"))
69
self.assertFalse(is_valid("\x05\x00\x00\x00"))
70
self.assertFalse(is_valid("\x05\x00\x00\x00\x00\x00"))
71
self.assertFalse(is_valid("\x07\x00\x00\x00\x02a\x00\x78\x56\x34\x12"))
72
self.assertFalse(is_valid("\x09\x00\x00\x00\x10a\x00\x05\x00"))
69
self.assertTrue(is_valid(b("\x05\x00\x00\x00\x00")))
70
self.assertTrue(is_valid(BSON(b("\x05\x00\x00\x00\x00"))))
71
self.assertFalse(is_valid(b("\x04\x00\x00\x00\x00")))
72
self.assertFalse(is_valid(b("\x05\x00\x00\x00\x01")))
73
self.assertFalse(is_valid(b("\x05\x00\x00\x00")))
74
self.assertFalse(is_valid(b("\x05\x00\x00\x00\x00\x00")))
75
self.assertFalse(is_valid(b("\x07\x00\x00\x00\x02a\x00\x78\x56\x34\x12")))
76
self.assertFalse(is_valid(b("\x09\x00\x00\x00\x10a\x00\x05\x00")))
74
78
def test_random_data_is_not_bson(self):
75
79
qcheck.check_unittest(self, qcheck.isnt(is_valid),
78
82
def test_basic_decode(self):
79
83
self.assertEqual({"test": u"hello world"},
80
BSON("\x1B\x00\x00\x00\x0E\x74\x65\x73\x74\x00\x0C"
81
"\x00\x00\x00\x68\x65\x6C\x6C\x6F\x20\x77\x6F"
82
"\x72\x6C\x64\x00\x00").decode())
84
BSON(b("\x1B\x00\x00\x00\x0E\x74\x65\x73\x74\x00\x0C"
85
"\x00\x00\x00\x68\x65\x6C\x6C\x6F\x20\x77\x6F"
86
"\x72\x6C\x64\x00\x00")).decode())
83
87
self.assertEqual([{"test": u"hello world"}, {}],
84
decode_all("\x1B\x00\x00\x00\x0E\x74\x65\x73\x74\x00"
85
"\x0C\x00\x00\x00\x68\x65\x6C\x6C\x6F\x20"
86
"\x77\x6F\x72\x6C\x64\x00\x00\x05\x00\x00"
88
decode_all(b("\x1B\x00\x00\x00\x0E\x74\x65\x73\x74"
89
"\x00\x0C\x00\x00\x00\x68\x65\x6C\x6C"
90
"\x6f\x20\x77\x6F\x72\x6C\x64\x00\x00"
91
"\x05\x00\x00\x00\x00")))
89
93
def test_data_timestamp(self):
90
94
self.assertEqual({"test": Timestamp(4, 20)},
91
BSON("\x13\x00\x00\x00\x11\x74\x65\x73\x74\x00\x14"
92
"\x00\x00\x00\x04\x00\x00\x00\x00").decode())
95
BSON(b("\x13\x00\x00\x00\x11\x74\x65\x73\x74\x00\x14"
96
"\x00\x00\x00\x04\x00\x00\x00\x00")).decode())
94
98
def test_basic_encode(self):
95
99
self.assertRaises(TypeError, BSON.encode, 100)
97
101
self.assertRaises(TypeError, BSON.encode, None)
98
102
self.assertRaises(TypeError, BSON.encode, [])
100
self.assertEqual(BSON.encode({}), BSON("\x05\x00\x00\x00\x00"))
104
self.assertEqual(BSON.encode({}), BSON(b("\x05\x00\x00\x00\x00")))
101
105
self.assertEqual(BSON.encode({"test": u"hello world"}),
102
"\x1B\x00\x00\x00\x02\x74\x65\x73\x74\x00\x0C\x00\x00"
103
"\x00\x68\x65\x6C\x6C\x6F\x20\x77\x6F\x72\x6C\x64\x00"
106
b("\x1B\x00\x00\x00\x02\x74\x65\x73\x74\x00\x0C\x00"
107
"\x00\x00\x68\x65\x6C\x6C\x6F\x20\x77\x6F\x72\x6C"
105
109
self.assertEqual(BSON.encode({u"mike": 100}),
106
"\x0F\x00\x00\x00\x10\x6D\x69\x6B\x65\x00\x64\x00\x00"
110
b("\x0F\x00\x00\x00\x10\x6D\x69\x6B\x65\x00\x64\x00"
108
112
self.assertEqual(BSON.encode({"hello": 1.5}),
109
"\x14\x00\x00\x00\x01\x68\x65\x6C\x6C\x6F\x00\x00\x00"
110
"\x00\x00\x00\x00\xF8\x3F\x00")
113
b("\x14\x00\x00\x00\x01\x68\x65\x6C\x6C\x6F\x00\x00"
114
"\x00\x00\x00\x00\x00\xF8\x3F\x00"))
111
115
self.assertEqual(BSON.encode({"true": True}),
112
"\x0C\x00\x00\x00\x08\x74\x72\x75\x65\x00\x01\x00")
116
b("\x0C\x00\x00\x00\x08\x74\x72\x75\x65\x00\x01\x00"))
113
117
self.assertEqual(BSON.encode({"false": False}),
114
"\x0D\x00\x00\x00\x08\x66\x61\x6C\x73\x65\x00\x00"
118
b("\x0D\x00\x00\x00\x08\x66\x61\x6C\x73\x65\x00\x00"
116
120
self.assertEqual(BSON.encode({"empty": []}),
117
"\x11\x00\x00\x00\x04\x65\x6D\x70\x74\x79\x00\x05\x00"
121
b("\x11\x00\x00\x00\x04\x65\x6D\x70\x74\x79\x00\x05"
122
"\x00\x00\x00\x00\x00"))
119
123
self.assertEqual(BSON.encode({"none": {}}),
120
"\x10\x00\x00\x00\x03\x6E\x6F\x6E\x65\x00\x05\x00\x00"
122
self.assertEqual(BSON.encode({"test": Binary("test", 0)}),
123
"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00\x00"
124
"\x00\x00\x74\x65\x73\x74\x00")
125
self.assertEqual(BSON.encode({"test": Binary("test", 2)}),
126
"\x18\x00\x00\x00\x05\x74\x65\x73\x74\x00\x08\x00\x00"
127
"\x00\x02\x04\x00\x00\x00\x74\x65\x73\x74\x00")
128
self.assertEqual(BSON.encode({"test": Binary("test", 128)}),
129
"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00\x00"
130
"\x00\x80\x74\x65\x73\x74\x00")
124
b("\x10\x00\x00\x00\x03\x6E\x6F\x6E\x65\x00\x05\x00"
126
self.assertEqual(BSON.encode({"test": Binary(b("test"), 0)}),
127
b("\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00"
128
"\x00\x00\x00\x74\x65\x73\x74\x00"))
129
self.assertEqual(BSON.encode({"test": Binary(b("test"), 2)}),
130
b("\x18\x00\x00\x00\x05\x74\x65\x73\x74\x00\x08\x00"
131
"\x00\x00\x02\x04\x00\x00\x00\x74\x65\x73\x74\x00"))
132
self.assertEqual(BSON.encode({"test": Binary(b("test"), 128)}),
133
b("\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00"
134
"\x00\x00\x80\x74\x65\x73\x74\x00"))
131
135
self.assertEqual(BSON.encode({"test": None}),
132
"\x0B\x00\x00\x00\x0A\x74\x65\x73\x74\x00\x00")
136
b("\x0B\x00\x00\x00\x0A\x74\x65\x73\x74\x00\x00"))
133
137
self.assertEqual(BSON.encode({"date": datetime.datetime(2007, 1, 8,
135
"\x13\x00\x00\x00\x09\x64\x61\x74\x65\x00\x38\xBE\x1C"
136
"\xFF\x0F\x01\x00\x00\x00")
137
self.assertEqual(BSON.encode({"regex": re.compile("a*b",
139
b("\x13\x00\x00\x00\x09\x64\x61\x74\x65\x00\x38\xBE"
140
"\x1C\xFF\x0F\x01\x00\x00\x00"))
141
self.assertEqual(BSON.encode({"regex": re.compile(b("a*b"),
138
142
re.IGNORECASE)}),
139
"\x12\x00\x00\x00\x0B\x72\x65\x67\x65\x78\x00\x61\x2A"
140
"\x62\x00\x69\x00\x00")
143
b("\x12\x00\x00\x00\x0B\x72\x65\x67\x65\x78\x00\x61"
144
"\x2A\x62\x00\x69\x00\x00"))
141
145
self.assertEqual(BSON.encode({"$where": Code("test")}),
142
"\x1F\x00\x00\x00\x0F\x24\x77\x68\x65\x72\x65\x00\x12"
143
"\x00\x00\x00\x05\x00\x00\x00\x74\x65\x73\x74\x00\x05"
144
"\x00\x00\x00\x00\x00")
145
a = ObjectId("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B")
146
b("\x16\x00\x00\x00\r$where\x00\x05\x00\x00\x00test"
148
self.assertEqual(BSON.encode({"$field":
149
Code("function(){ return true;}", scope=None)}),
150
b("+\x00\x00\x00\r$field\x00\x1a\x00\x00\x00"
151
"function(){ return true;}\x00\x00"))
152
self.assertEqual(BSON.encode({"$field":
153
Code("return function(){ return x; }",
154
scope={'x': False})}),
155
b("=\x00\x00\x00\x0f$field\x000\x00\x00\x00\x1f\x00"
156
"\x00\x00return function(){ return x; }\x00\t\x00"
157
"\x00\x00\x08x\x00\x00\x00\x00"))
158
a = ObjectId(b("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"))
146
159
self.assertEqual(BSON.encode({"oid": a}),
147
"\x16\x00\x00\x00\x07\x6F\x69\x64\x00\x00\x01\x02\x03"
148
"\x04\x05\x06\x07\x08\x09\x0A\x0B\x00")
160
b("\x16\x00\x00\x00\x07\x6F\x69\x64\x00\x00\x01\x02"
161
"\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x00"))
149
162
self.assertEqual(BSON.encode({"ref": DBRef("coll", a)}),
150
"\x2F\x00\x00\x00\x03ref\x00\x25\x00\x00\x00\x02$ref"
151
"\x00\x05\x00\x00\x00coll\x00\x07$id\x00\x00\x01\x02"
152
"\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x00\x00")
163
b("\x2F\x00\x00\x00\x03ref\x00\x25\x00\x00\x00\x02"
164
"$ref\x00\x05\x00\x00\x00coll\x00\x07$id\x00\x00"
165
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x00"
154
168
def test_encode_then_decode(self):
168
182
helper({"false": False})
169
183
helper({"an array": [1, True, 3.8, u"world"]})
170
184
helper({"an object": {"test": u"something"}})
171
helper({"a binary": Binary("test", 100)})
172
helper({"a binary": Binary("test", 128)})
173
helper({"a binary": Binary("test", 254)})
174
helper({"another binary": Binary("test")})
185
helper({"a binary": Binary(b("test"), 100)})
186
helper({"a binary": Binary(b("test"), 128)})
187
helper({"a binary": Binary(b("test"), 254)})
188
helper({"another binary": Binary(b("test"), 2)})
175
189
helper(SON([(u'test dst', datetime.datetime(1993, 4, 4, 2))]))
176
190
helper(SON([(u'test negative dst', datetime.datetime(1, 1, 1, 1, 1, 1))]))
177
191
helper({"big float": float(10000000000)})
182
196
helper({"ref": Timestamp(1, 2)})
183
197
helper({"foo": MinKey()})
184
198
helper({"foo": MaxKey()})
186
def encode_then_decode(dict):
187
return dict == (BSON.encode(dict)).decode()
199
helper({"$field": Code("function(){ return true; }")})
200
helper({"$field": Code("return function(){ return x; }", scope={'x': False})})
203
# Work around http://bugs.jython.org/issue1728
204
if (sys.platform.startswith('java') and
205
sys.version_info[:3] == (2, 5, 2)):
208
def encode_then_decode(doc):
209
return doc == (BSON.encode(doc)).decode(as_class=doc_class)
189
211
qcheck.check_unittest(self, encode_then_decode,
190
212
qcheck.gen_mongo_dict(3))
214
def test_bytes_as_keys(self):
215
doc = {b("foo"): 'bar'}
216
# Since `bytes` are stored as Binary you can't use them
217
# as keys in python 3.x. Using binary data as a key makes
218
# no sense in BSON anyway and little sense in python.
220
self.assertRaises(InvalidDocument, BSON.encode, doc)
222
self.assertTrue(BSON.encode(doc))
192
224
def test_datetime_encode_decode(self):
193
225
# Negative timestamps
194
226
dt1 = datetime.datetime(1, 1, 1, 1, 1, 1)
303
343
w = {u"aéあ": u"aéあ"}
304
344
self.assertEqual(w, BSON.encode(w).decode())
306
x = {u"aéあ".encode("utf-8"): u"aéあ".encode("utf-8")}
307
self.assertEqual(w, BSON.encode(x).decode())
309
y = {"hello": u"aé".encode("iso-8859-1")}
310
self.assertRaises(InvalidStringData, BSON.encode, y)
312
z = {u"aé".encode("iso-8859-1"): "hello"}
313
self.assertRaises(InvalidStringData, BSON.encode, z)
347
# In python3 this would be stored as BSON binary
348
# subtype 0 and wouldn't raise an exception.
349
y = {"hello": u"aé".encode("iso-8859-1")}
350
self.assertRaises(InvalidStringData, BSON.encode, y)
352
# The next two tests only make sense in python 2.x since
353
# you can't use `bytes` type as document keys in python 3.x.
354
x = {u"aéあ".encode("utf-8"): u"aéあ".encode("utf-8")}
355
self.assertEqual(w, BSON.encode(x).decode())
357
z = {u"aé".encode("iso-8859-1"): "hello"}
358
self.assertRaises(InvalidStringData, BSON.encode, z)
315
360
def test_null_character(self):
316
361
doc = {"a": "\x00"}
317
362
self.assertEqual(doc, BSON.encode(doc).decode())
364
# This test doesn't make much sense in Python2
365
# since {'a': '\x00'} == {'a': u'\x00'}.
366
# Decoding here actually returns {'a': '\x00'}
319
367
doc = {"a": u"\x00"}
320
368
self.assertEqual(doc, BSON.encode(doc).decode())
322
self.assertRaises(InvalidDocument, BSON.encode, {"\x00": "a"})
370
self.assertRaises(InvalidDocument, BSON.encode, {b("\x00"): "a"})
323
371
self.assertRaises(InvalidDocument, BSON.encode, {u"\x00": "a"})
325
373
self.assertRaises(InvalidDocument, BSON.encode,
326
{"a": re.compile("ab\x00c")})
374
{"a": re.compile(b("ab\x00c"))})
327
375
self.assertRaises(InvalidDocument, BSON.encode,
328
376
{"a": re.compile(u"ab\x00c")})
330
378
def test_move_id(self):
331
self.assertEqual("\x19\x00\x00\x00\x02_id\x00\x02\x00\x00\x00a\x00"
332
"\x02a\x00\x02\x00\x00\x00a\x00\x00",
379
self.assertEqual(b("\x19\x00\x00\x00\x02_id\x00\x02\x00\x00\x00a\x00"
380
"\x02a\x00\x02\x00\x00\x00a\x00\x00"),
333
381
BSON.encode(SON([("a", "a"), ("_id", "a")])))
335
self.assertEqual("\x2c\x00\x00\x00"
336
"\x02_id\x00\x02\x00\x00\x00b\x00"
338
"\x19\x00\x00\x00\x02a\x00\x02\x00\x00\x00a\x00"
339
"\x02_id\x00\x02\x00\x00\x00a\x00\x00\x00",
383
self.assertEqual(b("\x2c\x00\x00\x00"
384
"\x02_id\x00\x02\x00\x00\x00b\x00"
386
"\x19\x00\x00\x00\x02a\x00\x02\x00\x00\x00a\x00"
387
"\x02_id\x00\x02\x00\x00\x00a\x00\x00\x00"),
340
388
BSON.encode(SON([("b",
341
389
SON([("a", "a"), ("_id", "a")])),