All files
[pithos-ms-client] / trunk / Libraries / Json40r2 / Source / Src / Newtonsoft.Json.Tests / Bson / BsonWriterTests.cs
1 #region License
2 // Copyright (c) 2007 James Newton-King
3 //
4 // Permission is hereby granted, free of charge, to any person
5 // obtaining a copy of this software and associated documentation
6 // files (the "Software"), to deal in the Software without
7 // restriction, including without limitation the rights to use,
8 // copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following
11 // conditions:
12 //
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 // OTHER DEALINGS IN THE SOFTWARE.
24 #endregion
25
26 using System;
27 using System.Collections.Generic;
28 using System.Linq;
29 using System.Text;
30 using NUnit.Framework;
31 using Newtonsoft.Json.Bson;
32 using System.IO;
33 using Newtonsoft.Json.Utilities;
34 using Newtonsoft.Json.Tests.TestObjects;
35 using System.Globalization;
36
37 namespace Newtonsoft.Json.Tests.Bson
38 {
39   public class BsonWriterTests : TestFixtureBase
40   {
41     [Test]
42     public void CloseOutput()
43     {
44       MemoryStream ms = new MemoryStream();
45       BsonWriter writer = new BsonWriter(ms);
46
47       Assert.IsTrue(ms.CanRead);
48       writer.Close();
49       Assert.IsFalse(ms.CanRead);
50
51       ms = new MemoryStream();
52       writer = new BsonWriter(ms) { CloseOutput = false };
53
54       Assert.IsTrue(ms.CanRead);
55       writer.Close();
56       Assert.IsTrue(ms.CanRead);
57     }
58
59     [Test]
60     public void WriteSingleObject()
61     {
62       MemoryStream ms = new MemoryStream();
63       BsonWriter writer = new BsonWriter(ms);
64
65       writer.WriteStartObject();
66       writer.WritePropertyName("Blah");
67       writer.WriteValue(1);
68       writer.WriteEndObject();
69
70       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
71       Assert.AreEqual("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00", bson);
72     }
73
74 #if !PocketPC && !NET20
75     [Test]
76     public void WriteValues()
77     {
78       MemoryStream ms = new MemoryStream();
79       BsonWriter writer = new BsonWriter(ms);
80
81       writer.WriteStartArray();
82       writer.WriteValue(long.MaxValue);
83       writer.WriteValue((ulong)long.MaxValue);
84       writer.WriteValue(int.MaxValue);
85       writer.WriteValue((uint)int.MaxValue);
86       writer.WriteValue(byte.MaxValue);
87       writer.WriteValue(sbyte.MaxValue);
88       writer.WriteValue('a');
89       writer.WriteValue(decimal.MaxValue);
90       writer.WriteValue(double.MaxValue);
91       writer.WriteValue(float.MaxValue);
92       writer.WriteValue(true);
93       writer.WriteValue(new byte[] { 0, 1, 2, 3, 4 });
94       writer.WriteValue(new DateTimeOffset(2000, 12, 29, 12, 30, 0, TimeSpan.Zero));
95       writer.WriteValue(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc));
96       writer.WriteEnd();
97
98       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
99       Assert.AreEqual("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-00-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00", bson);
100     }
101 #endif
102
103     [Test]
104     public void WriteArrayBsonFromSite()
105     {
106       MemoryStream ms = new MemoryStream();
107       BsonWriter writer = new BsonWriter(ms);
108       writer.WriteStartArray();
109       writer.WriteValue("a");
110       writer.WriteValue("b");
111       writer.WriteValue("c");
112       writer.WriteEndArray();
113       
114       writer.Flush();
115
116       ms.Seek(0, SeekOrigin.Begin);
117
118       string expected = "20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00";
119       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
120
121       Assert.AreEqual(expected, bson);
122     }
123
124     [Test]
125     public void WriteBytes()
126     {
127       byte[] data = Encoding.UTF8.GetBytes("Hello world!");
128
129       MemoryStream ms = new MemoryStream();
130       BsonWriter writer = new BsonWriter(ms);
131       writer.WriteStartArray();
132       writer.WriteValue("a");
133       writer.WriteValue("b");
134       writer.WriteValue(data);
135       writer.WriteEndArray();
136
137       writer.Flush();
138
139       ms.Seek(0, SeekOrigin.Begin);
140
141       string expected = "2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-00-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00";
142       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
143
144       Assert.AreEqual(expected, bson);
145
146       BsonReader reader = new BsonReader(new MemoryStream(ms.ToArray()));
147       reader.ReadRootValueAsArray = true;
148       reader.Read();
149       reader.Read();
150       reader.Read();
151       reader.Read();
152       Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
153       Assert.AreEqual(data, reader.Value);
154     }
155
156     [Test]
157     public void WriteNestedArray()
158     {
159       MemoryStream ms = new MemoryStream();
160       BsonWriter writer = new BsonWriter(ms);
161       writer.WriteStartObject();
162
163       writer.WritePropertyName("_id");
164       writer.WriteValue(MiscellaneousUtils.HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF"));
165
166       writer.WritePropertyName("a");
167       writer.WriteStartArray();
168       for (int i = 1; i <= 8; i++)
169       {
170         double value = (i != 5)
171                          ? Convert.ToDouble(i)
172                          : 5.78960446186581E+77d;
173
174         writer.WriteValue(value);
175       }
176       writer.WriteEndArray();
177
178       writer.WritePropertyName("b");
179       writer.WriteValue("test");
180
181       writer.WriteEndObject();
182
183       writer.Flush();
184
185       ms.Seek(0, SeekOrigin.Begin);
186
187       string expected = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00";
188       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
189
190       Assert.AreEqual(expected, bson);
191     }
192
193     [Test]
194     public void WriteSerializedStore()
195     {
196       MemoryStream ms = new MemoryStream();
197       BsonWriter writer = new BsonWriter(ms);
198
199       Store s1 = new Store();
200       s1.Color = StoreColor.White;
201       s1.Cost = 999.59m;
202       s1.Employees = int.MaxValue - 1;
203       s1.Open = true;
204       s1.product.Add(new Product
205                        {
206                          ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Local),
207                          Name = "BSON!",
208                          Price = -0.1m,
209                          Sizes = new [] { "First", "Second" }
210                        });
211       s1.Establised = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local);
212
213       JsonSerializer serializer = new JsonSerializer();
214       serializer.Serialize(writer, s1);
215
216       ms.Seek(0, SeekOrigin.Begin);
217       BsonReader reader = new BsonReader(ms);
218       Store s2 = (Store)serializer.Deserialize(reader, typeof (Store));
219
220       Assert.AreNotEqual(s1, s2);
221       Assert.AreEqual(s1.Color, s2.Color);
222       Assert.AreEqual(s1.Cost, s2.Cost);
223       Assert.AreEqual(s1.Employees, s2.Employees);
224       Assert.AreEqual(s1.Escape, s2.Escape);
225       Assert.AreEqual(s1.Establised, s2.Establised);
226       Assert.AreEqual(s1.Mottos.Count, s2.Mottos.Count);
227       Assert.AreEqual(s1.Mottos.First(), s2.Mottos.First());
228       Assert.AreEqual(s1.Mottos.Last(), s2.Mottos.Last());
229       Assert.AreEqual(s1.Open, s2.Open);
230       Assert.AreEqual(s1.product.Count, s2.product.Count);
231       Assert.AreEqual(s1.RoomsPerFloor.Length, s2.RoomsPerFloor.Length);
232       Assert.AreEqual(s1.Symbol, s2.Symbol);
233       Assert.AreEqual(s1.Width, s2.Width);
234
235       MemoryStream ms1 = new MemoryStream();
236       BsonWriter writer1 = new BsonWriter(ms1);
237
238       serializer.Serialize(writer1, s1);
239
240       Assert.AreEqual(ms.ToArray(), ms1.ToArray());
241
242       string s = JsonConvert.SerializeObject(s1);
243       byte[] textData = Encoding.UTF8.GetBytes(s);
244
245       int l1 = textData.Length;
246       int l2 = ms.ToArray().Length;
247
248       Console.WriteLine(l1);
249       Console.WriteLine(l2);
250     }
251
252     [Test]
253     public void WriteLargeStrings()
254     {
255       MemoryStream ms = new MemoryStream();
256       BsonWriter writer = new BsonWriter(ms);
257
258       StringBuilder largeStringBuilder = new StringBuilder();
259       for (int i = 0; i < 100; i++)
260       {
261         if (i > 0)
262           largeStringBuilder.Append("-");
263
264         largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture));
265       }
266       string largeString = largeStringBuilder.ToString();
267
268       writer.WriteStartObject();
269       writer.WritePropertyName(largeString);
270       writer.WriteValue(largeString);
271       writer.WriteEndObject();
272
273       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
274       Assert.AreEqual("4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00", bson);
275     }
276
277     [Test]
278     public void SerializeGoogleGeoCode()
279     {
280       string json = @"{
281   ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
282   ""Status"": {
283     ""code"": 200,
284     ""request"": ""geocode""
285   },
286   ""Placemark"": [
287     {
288       ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
289       ""AddressDetails"": {
290         ""Country"": {
291           ""CountryNameCode"": ""US"",
292           ""AdministrativeArea"": {
293             ""AdministrativeAreaName"": ""CA"",
294             ""SubAdministrativeArea"": {
295               ""SubAdministrativeAreaName"": ""Santa Clara"",
296               ""Locality"": {
297                 ""LocalityName"": ""Mountain View"",
298                 ""Thoroughfare"": {
299                   ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
300                 },
301                 ""PostalCode"": {
302                   ""PostalCodeNumber"": ""94043""
303                 }
304               }
305             }
306           }
307         },
308         ""Accuracy"": 8
309       },
310       ""Point"": {
311         ""coordinates"": [-122.083739, 37.423021, 0]
312       }
313     }
314   ]
315 }";
316
317       GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
318
319       MemoryStream ms = new MemoryStream();
320       BsonWriter writer = new BsonWriter(ms);
321
322       JsonSerializer serializer = new JsonSerializer();
323       serializer.Serialize(writer, jsonGoogleMapGeocoder);
324
325       ms.Seek(0, SeekOrigin.Begin);
326       BsonReader reader = new BsonReader(ms);
327       GoogleMapGeocoderStructure bsonGoogleMapGeocoder = (GoogleMapGeocoderStructure)serializer.Deserialize(reader, typeof (GoogleMapGeocoderStructure));
328
329       Assert.IsNotNull(bsonGoogleMapGeocoder);
330       Assert.AreEqual("1600 Amphitheatre Parkway, Mountain View, CA, USA", bsonGoogleMapGeocoder.Name);
331       Assert.AreEqual("200", bsonGoogleMapGeocoder.Status.Code);
332       Assert.AreEqual("geocode", bsonGoogleMapGeocoder.Status.Request);
333
334       IList<Placemark> placemarks = bsonGoogleMapGeocoder.Placemark;
335       Assert.IsNotNull(placemarks);
336       Assert.AreEqual(1, placemarks.Count);
337
338       Placemark placemark = placemarks[0];
339       Assert.AreEqual("1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", placemark.Address);
340       Assert.AreEqual(8, placemark.AddressDetails.Accuracy);
341       Assert.AreEqual("US", placemark.AddressDetails.Country.CountryNameCode);
342       Assert.AreEqual("CA", placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName);
343       Assert.AreEqual("Santa Clara", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName);
344       Assert.AreEqual("Mountain View", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName);
345       Assert.AreEqual("1600 Amphitheatre Pkwy", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName);
346       Assert.AreEqual("94043", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber);
347       Assert.AreEqual(-122.083739m, placemark.Point.Coordinates[0]);
348       Assert.AreEqual(37.423021m, placemark.Point.Coordinates[1]);
349       Assert.AreEqual(0m, placemark.Point.Coordinates[2]);
350     }
351
352     [Test]
353     public void WriteEmptyStrings()
354     {
355       MemoryStream ms = new MemoryStream();
356       BsonWriter writer = new BsonWriter(ms);
357
358       writer.WriteStartObject();
359       writer.WritePropertyName("");
360       writer.WriteValue("");
361       writer.WriteEndObject();
362
363       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
364       Assert.AreEqual("0C-00-00-00-02-00-01-00-00-00-00-00", bson);
365     }
366
367     [Test]
368     [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write JSON comment as BSON.")]
369     public void WriteComment()
370     {
371       MemoryStream ms = new MemoryStream();
372       BsonWriter writer = new BsonWriter(ms);
373
374       writer.WriteStartArray();
375       writer.WriteComment("fail");
376     }
377
378     [Test]
379     [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write JSON constructor as BSON.")]
380     public void WriteConstructor()
381     {
382       MemoryStream ms = new MemoryStream();
383       BsonWriter writer = new BsonWriter(ms);
384
385       writer.WriteStartArray();
386       writer.WriteStartConstructor("fail");
387     }
388
389     [Test]
390     [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write raw JSON as BSON.")]
391     public void WriteRaw()
392     {
393       MemoryStream ms = new MemoryStream();
394       BsonWriter writer = new BsonWriter(ms);
395
396       writer.WriteStartArray();
397       writer.WriteRaw("fail");
398     }
399
400     [Test]
401     [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write raw JSON as BSON.")]
402     public void WriteRawValue()
403     {
404       MemoryStream ms = new MemoryStream();
405       BsonWriter writer = new BsonWriter(ms);
406
407       writer.WriteStartArray();
408       writer.WriteRawValue("fail");
409     }
410
411     [Test]
412     public void Example()
413     {
414       Product p = new Product();
415       p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
416       p.Name = "Carlos' Spicy Wieners";
417       p.Price = 9.95m;
418       p.Sizes = new[] { "Small", "Medium", "Large" };
419
420       MemoryStream ms = new MemoryStream();
421       JsonSerializer serializer = new JsonSerializer();
422
423       // serialize product to BSON
424       BsonWriter writer = new BsonWriter(ms);
425       serializer.Serialize(writer, p);
426
427       Console.WriteLine(BitConverter.ToString(ms.ToArray()));
428       // 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C-
429       // 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00-
430       // 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01-
431       // 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04-
432       // 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53-
433       // 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D-
434       // 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00
435
436
437       ms.Seek(0, SeekOrigin.Begin);
438
439       // deserialize product from BSON
440       BsonReader reader = new BsonReader(ms);
441       Product deserializedProduct = serializer.Deserialize<Product>(reader);
442
443       Console.WriteLine(deserializedProduct.Name);
444       // Carlos' Spicy Wieners
445
446
447       Assert.AreEqual("Carlos' Spicy Wieners", deserializedProduct.Name);
448       Assert.AreEqual(9.95m, deserializedProduct.Price);
449       Assert.AreEqual(3, deserializedProduct.Sizes.Length);
450     }
451
452     [Test]
453     public void WriteOid()
454     {
455       MemoryStream ms = new MemoryStream();
456       BsonWriter writer = new BsonWriter(ms);
457
458       byte[] oid = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
459
460       writer.WriteStartObject();
461       writer.WritePropertyName("_oid");
462       writer.WriteObjectId(oid);
463       writer.WriteEndObject();
464
465       string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
466       Assert.AreEqual("17-00-00-00-07-5F-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00", bson);
467
468       ms.Seek(0, SeekOrigin.Begin);
469       BsonReader reader = new BsonReader(ms);
470
471       Assert.IsTrue(reader.Read());
472       Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
473
474       Assert.IsTrue(reader.Read());
475       Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
476
477       Assert.IsTrue(reader.Read());
478       Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
479       Assert.AreEqual(oid, reader.Value);
480
481       Assert.IsTrue(reader.Read());
482       Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
483     }
484
485     [Test]
486     public void WriteOidPlusContent()
487     {
488       MemoryStream ms = new MemoryStream();
489       BsonWriter writer = new BsonWriter(ms);
490
491       writer.WriteStartObject();
492       writer.WritePropertyName("_id");
493       writer.WriteObjectId(MiscellaneousUtils.HexToBytes("4ABBED9D1D8B0F0218000001"));
494       writer.WritePropertyName("test");
495       writer.WriteValue("1234£56");
496       writer.WriteEndObject();
497
498       byte[] expected = MiscellaneousUtils.HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000");
499
500       Assert.AreEqual(expected, ms.ToArray());
501     }
502
503     [Test]
504     public void WriteRegexPlusContent()
505     {
506       MemoryStream ms = new MemoryStream();
507       BsonWriter writer = new BsonWriter(ms);
508
509       writer.WriteStartObject();
510       writer.WritePropertyName("regex");
511       writer.WriteRegex("abc", "i");
512       writer.WritePropertyName("test");
513       writer.WriteRegex(string.Empty, null);
514       writer.WriteEndObject();
515
516       byte[] expected = MiscellaneousUtils.HexToBytes("1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00");
517
518       Assert.AreEqual(expected, ms.ToArray());
519     }
520
521     [Test]
522     public void SerializeEmptyAndNullStrings()
523     {
524       Product p = new Product();
525       p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
526       p.Name = null;
527       p.Price = 9.95m;
528       p.Sizes = new[] { "Small", "", null };
529
530       MemoryStream ms = new MemoryStream();
531       JsonSerializer serializer = new JsonSerializer();
532
533       BsonWriter writer = new BsonWriter(ms);
534       serializer.Serialize(writer, p);
535
536       ms.Seek(0, SeekOrigin.Begin);
537
538       BsonReader reader = new BsonReader(ms);
539       Product deserializedProduct = serializer.Deserialize<Product>(reader);
540
541       Console.WriteLine(deserializedProduct.Name);
542
543       Assert.AreEqual(null, deserializedProduct.Name);
544       Assert.AreEqual(9.95m, deserializedProduct.Price);
545       Assert.AreEqual(3, deserializedProduct.Sizes.Length);
546       Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
547       Assert.AreEqual("", deserializedProduct.Sizes[1]);
548       Assert.AreEqual(null, deserializedProduct.Sizes[2]);
549     }
550
551     [Test]
552     public void WriteReadEmptyAndNullStrings()
553     {
554       MemoryStream ms = new MemoryStream();
555       BsonWriter writer = new BsonWriter(ms);
556
557       writer.WriteStartArray();
558       writer.WriteValue("Content!");
559       writer.WriteValue("");
560       writer.WriteValue((string)null);
561       writer.WriteEndArray();
562
563       ms.Seek(0, SeekOrigin.Begin);
564
565       BsonReader reader = new BsonReader(ms);
566       reader.ReadRootValueAsArray = true;
567
568       Assert.IsTrue(reader.Read());
569       Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
570
571       Assert.IsTrue(reader.Read());
572       Assert.AreEqual(JsonToken.String, reader.TokenType);
573       Assert.AreEqual("Content!", reader.Value);
574
575       Assert.IsTrue(reader.Read());
576       Assert.AreEqual(JsonToken.String, reader.TokenType);
577       Assert.AreEqual("", reader.Value);
578
579       Assert.IsTrue(reader.Read());
580       Assert.AreEqual(JsonToken.Null, reader.TokenType);
581       Assert.AreEqual(null, reader.Value);
582
583       Assert.IsTrue(reader.Read());
584       Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
585
586       Assert.IsFalse(reader.Read());
587     }
588
589     [Test]
590     public void WriteDateTimes()
591     {
592       MemoryStream ms = new MemoryStream();
593       BsonWriter writer = new BsonWriter(ms);
594       writer.DateTimeKindHandling = DateTimeKind.Unspecified;
595
596       writer.WriteStartArray();
597       writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc));
598       writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Local));
599       writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Unspecified));
600       writer.WriteEndArray();
601
602       ms.Seek(0, SeekOrigin.Begin);
603
604       BsonReader reader = new BsonReader(ms);
605       reader.ReadRootValueAsArray = true;
606       reader.DateTimeKindHandling = DateTimeKind.Utc;
607
608       Assert.IsTrue(reader.Read());
609       Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
610
611       Assert.IsTrue(reader.Read());
612       Assert.AreEqual(JsonToken.Date, reader.TokenType);
613       Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
614
615       Assert.IsTrue(reader.Read());
616       Assert.AreEqual(JsonToken.Date, reader.TokenType);
617       Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
618
619       Assert.IsTrue(reader.Read());
620       Assert.AreEqual(JsonToken.Date, reader.TokenType);
621       Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
622
623       Assert.IsTrue(reader.Read());
624       Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
625
626       Assert.IsFalse(reader.Read());
627     }
628   }
629 }