diff --git a/UltraLiteDB.Tests/Database/AutoId_Tests.cs b/UltraLiteDB.Tests/Database/AutoId_Tests.cs new file mode 100755 index 000000000..a79c26c10 --- /dev/null +++ b/UltraLiteDB.Tests/Database/AutoId_Tests.cs @@ -0,0 +1,244 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + #region Model + + public class EntityInt + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class EntityLong + { + public long Id { get; set; } + public string Name { get; set; } + } + + public class EntityGuid + { + public Guid Id { get; set; } + public string Name { get; set; } + } + + public class EntityOid + { + public ObjectId Id { get; set; } + public string Name { get; set; } + } + + public class EntityString + { + public string Id { get; set; } + public string Name { get; set; } + } + + #endregion + + [TestClass] + public class AutoId_Tests + { + [TestMethod] + public void AutoId_Strong_Typed() + { + var mapper = new BsonMapper(); + + using (var db = new UltraLiteDatabase(new MemoryStream(), mapper)) + { + var cs_int = db.GetCollection("int"); + var cs_long = db.GetCollection("long"); + var cs_guid = db.GetCollection("guid"); + var cs_oid = db.GetCollection("oid"); + var cs_str = db.GetCollection("str"); + + // int32 + var cint_1 = new EntityInt() { Name = "R1" }; + var cint_2 = new EntityInt() { Name = "R2" }; + var cint_3 = new EntityInt() { Name = "R3" }; + var cint_4 = new EntityInt() { Name = "R4" }; + + // long + var clong_1 = new EntityLong() { Name = "R1" }; + var clong_2 = new EntityLong() { Name = "R2" }; + var clong_3 = new EntityLong() { Name = "R3" }; + var clong_4 = new EntityLong() { Name = "R4" }; + + // guid + var cguid_1 = new EntityGuid() { Name = "R1" }; + var cguid_2 = new EntityGuid() { Name = "R2" }; + var cguid_3 = new EntityGuid() { Name = "R3" }; + var cguid_4 = new EntityGuid() { Name = "R4" }; + + // oid + var coid_1 = new EntityOid() { Name = "R1" }; + var coid_2 = new EntityOid() { Name = "R2" }; + var coid_3 = new EntityOid() { Name = "R3" }; + var coid_4 = new EntityOid() { Name = "R4" }; + + // string - there is no AutoId for string + var cstr_1 = new EntityString() { Id = "a", Name = "R1" }; + var cstr_2 = new EntityString() { Id = "b", Name = "R2" }; + var cstr_3 = new EntityString() { Id = "c", Name = "R3" }; + var cstr_4 = new EntityString() { Id = "d", Name = "R4" }; + + // insert first 3 documents + cs_int.Insert(new[] { cint_1, cint_2, cint_3 }); + cs_long.Insert(new[] { clong_1, clong_2, clong_3 }); + cs_guid.Insert(new[] { cguid_1, cguid_2, cguid_3 }); + cs_oid.Insert(new[] { coid_1, coid_2, coid_3 }); + cs_str.Insert(new[] { cstr_1, cstr_2, cstr_3 }); + + // change document 2 + cint_2.Name = "Changed 2"; + clong_2.Name = "Changed 2"; + cguid_2.Name = "Changed 2"; + coid_2.Name = "Changed 2"; + cstr_2.Name = "Changed 2"; + + // update document 2 + var nu_int = cs_int.Update(cint_2); + var nu_long = cs_long.Update(clong_2); + var nu_guid = cs_guid.Update(cguid_2); + var nu_oid = cs_oid.Update(coid_2); + var nu_str = cs_str.Update(cstr_2); + + Assert.IsTrue(nu_int); + Assert.IsTrue(nu_long); + Assert.IsTrue(nu_guid); + Assert.IsTrue(nu_oid); + Assert.IsTrue(nu_str); + + // change document 3 + cint_3.Name = "Changed 3"; + clong_3.Name = "Changed 3"; + cguid_3.Name = "Changed 3"; + coid_3.Name = "Changed 3"; + cstr_3.Name = "Changed 3"; + + // upsert (update) document 3 + var fu_int = cs_int.Upsert(cint_3); + var fu_long = cs_long.Upsert(clong_3); + var fu_guid = cs_guid.Upsert(cguid_3); + var fu_oid = cs_oid.Upsert(coid_3); + var fu_str = cs_str.Upsert(cstr_3); + + Assert.IsFalse(fu_int); + Assert.IsFalse(fu_long); + Assert.IsFalse(fu_guid); + Assert.IsFalse(fu_oid); + Assert.IsFalse(fu_str); + + // test if was changed + Assert.AreEqual(cint_3.Name, cs_int.FindOne(Query.EQ("_id", cint_3.Id)).Name); + Assert.AreEqual(clong_3.Name, cs_long.FindOne(Query.EQ("_id", clong_3.Id)).Name); + Assert.AreEqual(cguid_3.Name, cs_guid.FindOne(Query.EQ("_id", cguid_3.Id)).Name); + Assert.AreEqual(coid_3.Name, cs_oid.FindOne(Query.EQ("_id", coid_3.Id)).Name); + Assert.AreEqual(cstr_3.Name, cs_str.FindOne(Query.EQ("_id", cstr_3.Id)).Name); + + // upsert (insert) document 4 + var tu_int = cs_int.Upsert(cint_4); + var tu_long = cs_long.Upsert(clong_4); + var tu_guid = cs_guid.Upsert(cguid_4); + var tu_oid = cs_oid.Upsert(coid_4); + var tu_str = cs_str.Upsert(cstr_4); + + Assert.IsTrue(tu_int); + Assert.IsTrue(tu_long); + Assert.IsTrue(tu_guid); + Assert.IsTrue(tu_oid); + Assert.IsTrue(tu_str); + + // test if was included + Assert.AreEqual(cint_4.Name, cs_int.FindOne(Query.EQ("_id", cint_4.Id)).Name); + Assert.AreEqual(clong_4.Name, cs_long.FindOne(Query.EQ("_id", clong_4.Id)).Name); + Assert.AreEqual(cguid_4.Name, cs_guid.FindOne(Query.EQ("_id", cguid_4.Id)).Name); + Assert.AreEqual(coid_4.Name, cs_oid.FindOne(Query.EQ("_id", coid_4.Id)).Name); + Assert.AreEqual(cstr_4.Name, cs_str.FindOne(Query.EQ("_id", cstr_4.Id)).Name); + + // count must be 4 + Assert.AreEqual(4, cs_int.Count(Query.All())); + Assert.AreEqual(4, cs_long.Count(Query.All())); + Assert.AreEqual(4, cs_guid.Count(Query.All())); + Assert.AreEqual(4, cs_oid.Count(Query.All())); + Assert.AreEqual(4, cs_str.Count(Query.All())); + + // for Int32 (or Int64) - add "bouble" on sequence + var cint_10 = new EntityInt { Id = 10, Name = "R10" }; + var cint_11 = new EntityInt { Name = "R11" }; + var cint_7 = new EntityInt { Id = 7, Name = "R7" }; + var cint_12 = new EntityInt { Name = "R12" }; + + cs_int.Insert(cint_10); // "loose" sequente between 5-9 + cs_int.Insert(cint_11); // insert as 11 + cs_int.Insert(cint_7); // insert as 7 + cs_int.Insert(cint_12); // insert as 12 + + Assert.AreEqual(10, cint_10.Id); + Assert.AreEqual(11, cint_11.Id); + Assert.AreEqual(7, cint_7.Id); + Assert.AreEqual(12, cint_12.Id); + } + } + + [TestMethod] + public void AutoId_No_Duplicate_After_Delete() + { + // using strong type + using (var db = new UltraLiteDatabase(new MemoryStream())) + { + var col = db.GetCollection("col1"); + + var one = new EntityInt { Name = "One" }; + var two = new EntityInt { Name = "Two" }; + var three = new EntityInt { Name = "Three" }; + var four = new EntityInt { Name = "Four" }; + + // insert + col.Insert(one); + col.Insert(two); + + Assert.AreEqual(1, one.Id); + Assert.AreEqual(2, two.Id); + + // now delete first 2 rows + col.Delete(one.Id); + col.Delete(two.Id); + + // and insert new documents + col.Insert(new EntityInt[] { three, four }); + + Assert.AreEqual(3, three.Id); + Assert.AreEqual(4, four.Id); + } + + // using bsondocument/engine + using (var db = new UltraLiteEngine(new MemoryStream())) + { + var one = new BsonDocument { ["Name"] = "One" }; + var two = new BsonDocument { ["Name"] = "Two" }; + var three = new BsonDocument { ["Name"] = "Three" }; + var four = new BsonDocument { ["Name"] = "Four" }; + + db.Insert("col", one, BsonAutoId.Int32); + db.Insert("col", two, BsonAutoId.Int32); + + Assert.AreEqual(1, one["_id"].AsInt32); + Assert.AreEqual(2, two["_id"].AsInt32); + + // now delete first 2 rows + db.Delete("col", one["_id"].AsInt32); + db.Delete("col", two["_id"].AsInt32); + + // and insert new documents + db.Insert("col", new BsonDocument[] { three, four }, BsonAutoId.Int32); + + Assert.AreEqual(3, three["_id"].AsInt32); + Assert.AreEqual(4, four["_id"].AsInt32); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/ConnectionString_Tests.cs b/UltraLiteDB.Tests/Database/ConnectionString_Tests.cs new file mode 100755 index 000000000..44b2c30bc --- /dev/null +++ b/UltraLiteDB.Tests/Database/ConnectionString_Tests.cs @@ -0,0 +1,124 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + [TestClass] + public class ConnectionString_Tests + { + [TestMethod] + public void ConnectionString_NoArguments() + { + // Verify that the default ConnectionString contains the appropriate defaults + var defaults = new ConnectionString(); + AssertDefaults(defaults, false); + } + + [TestMethod] + public void ConnectionString_Parser() + { + // only filename + var onlyfile = new ConnectionString(@"demo.db"); + + Assert.AreEqual(@"demo.db", onlyfile.Filename); + AssertDefaults(onlyfile, true); + + // file with spaces without " + var normal = new ConnectionString(@"filename=c:\only file\demo.db; journal=false"); + + Assert.AreEqual(@"c:\only file\demo.db", normal.Filename); + Assert.AreEqual(false, normal.Journal); + + // filename with timeout + var filenameTimeout = new ConnectionString(@"filename = my demo.db ; timeout = 1:00:00"); + + Assert.AreEqual(@"my demo.db", filenameTimeout.Filename); + Assert.AreEqual(TimeSpan.FromHours(1), filenameTimeout.Timeout); + + // file with spaces with " and ; + var fullConnectionString = @"filename=""c:\only;file\""d\""emo.db""; + journal =false; + password = ""john-doe "" ; + cache SIZE = 1000 ; + timeout = 00:05:00 ; + initial size = 10 MB ; + mode = excluSIVE ; + limit SIZE = 20mb; + log = 255 ; + utc=true ; + upgrade=true; + async=true"; + var full = new ConnectionString(fullConnectionString); + + Assert.AreEqual(@"c:\only;file""d""emo.db", full.Filename); + Assert.AreEqual(false, full.Journal); + Assert.AreEqual("john-doe ", full.Password); + Assert.AreEqual(1000, full.CacheSize); + Assert.AreEqual(TimeSpan.FromMinutes(5), full.Timeout); + Assert.AreEqual(10 * 1024 * 1024, full.InitialSize); + Assert.AreEqual(20 * 1024 * 1024, full.LimitSize); + Assert.AreEqual(255, full.Log); + Assert.AreEqual(true, full.UtcDate); + Assert.AreEqual(true, full.Async); + } + + [TestMethod] + public void ConnectionString_Sets_Log_Level() + { + var connectionString = "filename=foo;"; + var db = new UltraLiteDatabase(connectionString); + Assert.AreEqual(0, db.Log.Level); + + connectionString = "filename=foo;log=" + Logger.FULL; + db = new UltraLiteDatabase(connectionString); + Assert.AreEqual(Logger.FULL, db.Log.Level); + } + + [TestMethod] + public void ConnectionString_MetaTest() + { + // This test is a meta test that verifies that all of the properties present in ConnectionString are also tested by this test. + // If this test fails, you should make sure that you don't need to update this test. (In particular, you almost certainly need to update AssertDefaults.) + var expectedProperties = new HashSet() + { + "Filename", + "Journal", + "Password", + "CacheSize", + "Timeout", + "Mode", + "InitialSize", + "LimitSize", + "Log", + "UtcDate", + "Upgrade", + "Async", + "Flush" + }; + + var actualProperties = new HashSet(typeof(ConnectionString).GetProperties().Select(p => p.Name)); + actualProperties.ExceptWith(expectedProperties); + + // If the below assert fails, properties were added to ConnectionString without updating this test. + Assert.AreEqual(0, actualProperties.Count); + } + + private void AssertDefaults(ConnectionString connectionString, bool skipFilename) + { + if (!skipFilename) + { Assert.AreEqual("", connectionString.Filename); } + + Assert.AreEqual(true, connectionString.Journal); + Assert.AreEqual(null, connectionString.Password); + Assert.AreEqual(5000, connectionString.CacheSize); + Assert.AreEqual(new TimeSpan(0, 1, 0), connectionString.Timeout); + Assert.AreEqual(0, connectionString.InitialSize); + Assert.AreEqual(long.MaxValue, connectionString.LimitSize); + Assert.AreEqual(Logger.NONE, connectionString.Log); + Assert.AreEqual(false, connectionString.UtcDate); + Assert.AreEqual(false, connectionString.Async); + } + } +} diff --git a/UltraLiteDB.Tests/Database/DateTimeMinMax_Tests.cs b/UltraLiteDB.Tests/Database/DateTimeMinMax_Tests.cs new file mode 100755 index 000000000..74aeaf0c1 --- /dev/null +++ b/UltraLiteDB.Tests/Database/DateTimeMinMax_Tests.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Linq; +using UltraLiteDB; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UltraLiteDB.Tests.Database +{ + #region Model + + public class DateTimeTest + { + public int Id { get; set; } + public DateTime? Date { get; set; } + } + + #endregion + + [TestClass] + public class DateTimeMinMax_Tests + { + [TestMethod] + public void DateTimeMinMax_Test() + { + var memory = new MemoryStream(); + + using (var db = new UltraLiteDatabase(memory)) + { + var col = db.GetCollection(); + col.EnsureIndex("Date"); + + col.Insert(new DateTimeTest() { Id = 1, Date = new DateTime(2018, 02, 22, 0, 0, 0) }); + col.Insert(new DateTimeTest() { Id = 2, Date = new DateTime(2018, 02, 22, 23, 59, 59) }); + + MinMaxCommon(col); + } + + using (var db = new UltraLiteDatabase(memory)) + { + var col = db.GetCollection(); + + MinMaxCommon(col); + + col.Insert(new DateTimeTest() { Id = 3, Date = new DateTime(2018, 02, 21, 23, 59, 59) }); + col.Insert(new DateTimeTest() { Id = 4, Date = new DateTime(2018, 02, 23, 0, 0, 0) }); + col.Insert(new DateTimeTest() { Id = 5, Date = new DateTime(2018, 02, 22, 0, 0, 1) }); + col.Insert(new DateTimeTest() { Id = 6, Date = new DateTime(2018, 02, 22, 23, 59, 58) }); + + MinMaxCommon(col); + } + + using (var db = new UltraLiteDatabase(memory)) + { + var col = db.GetCollection(); + + MinMaxCommon(col); + } + } + + private void MinMaxCommon(UltraLiteCollection coll) + { + var searchdatetime = new DateTime(2018, 02, 22, 0, 0, 10); + + var min = coll.Min("Date").AsDateTime; + var max = coll.Max("Date").AsDateTime; + + var smaller = coll.FindOne(Query.LT("Date", searchdatetime)); + var greater = coll.FindOne(Query.GT("Date", searchdatetime)); + + var all = coll.FindAll().ToList(); + + var linqmin = all.Min(x => x.Date); + var linqmax = all.Max(x => x.Date); + + Assert.AreEqual(min, linqmin); + Assert.AreEqual(max, linqmax); + } + } +} diff --git a/UltraLiteDB.Tests/Database/Delete_By_Name_Tests.cs b/UltraLiteDB.Tests/Database/Delete_By_Name_Tests.cs new file mode 100755 index 000000000..deaff11cb --- /dev/null +++ b/UltraLiteDB.Tests/Database/Delete_By_Name_Tests.cs @@ -0,0 +1,31 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + [TestClass] + public class Delete_By_Name_Tests + { + [TestMethod] + public void Delete_By_Name() + { + using (var f = new TempFile()) + using (var db = new UltraLiteDatabase(f.Filename)) + { + var col = db.GetCollection("Person"); + + col.Insert(new Person { Fullname = "John" }); + col.Insert(new Person { Fullname = "Doe" }); + col.Insert(new Person { Fullname = "Joana" }); + col.Insert(new Person { Fullname = "Marcus" }); + + // lets auto-create index in FullName and delete from a non-pk node + var del = col.Delete(Query.StartsWith("Fullname", "J")); + + Assert.AreEqual(2, del); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/FindAll_Tests.cs b/UltraLiteDB.Tests/Database/FindAll_Tests.cs new file mode 100755 index 000000000..36d4796a8 --- /dev/null +++ b/UltraLiteDB.Tests/Database/FindAll_Tests.cs @@ -0,0 +1,47 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + #region Model + + public class Person + { + public int Id { get; set; } + public string Fullname { get; set; } + } + + #endregion + + [TestClass] + public class FindAll_Tests + { + [TestMethod] + public void FindAll() + { + using (var f = new TempFile()) + { + using (var db = new UltraLiteDatabase(f.Filename)) + { + var col = db.GetCollection("Person"); + + col.Insert(new Person { Fullname = "John" }); + col.Insert(new Person { Fullname = "Doe" }); + col.Insert(new Person { Fullname = "Joana" }); + col.Insert(new Person { Fullname = "Marcus" }); + } + // close datafile + + using (var db = new UltraLiteDatabase(f.Filename)) + { + var p = db.GetCollection("Person").Find(Query.All("Fullname", Query.Ascending)); + + Assert.AreEqual(4, p.Count()); + } + } + + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/IndexSortAndFilter_Tests.cs b/UltraLiteDB.Tests/Database/IndexSortAndFilter_Tests.cs new file mode 100755 index 000000000..99b859331 --- /dev/null +++ b/UltraLiteDB.Tests/Database/IndexSortAndFilter_Tests.cs @@ -0,0 +1,87 @@ +//using Microsoft.VisualStudio.TestTools.UnitTesting; +//using System.Collections.Generic; +//using System.Linq; + +//namespace UltraLiteDB.Tests.Database +//{ +// [TestClass] +// public class IndexSortAndFilterTest +// { +// private UltraLiteCollection _collection; +// private TempFile _tempFile; +// private UltraLiteDatabase _database; + +// [TestInitialize] +// public void Init() +// { +// _tempFile = new TempFile(); +// _database = new UltraLiteDatabase(_tempFile.Filename); +// _collection = _database.GetCollection("items"); +// } + +// [TestCleanup] +// public void Cleanup() +// { +// _database.Dispose(); +// _tempFile.Dispose(); +// } + +// [TestMethod] +// public void FilterAndSortAscending() +// { +// _collection.EnsureIndex(nameof(Item.Value)); + +// PrepareData(_collection); +// var result = FilterAndSortById(_collection, Query.Ascending); + +// Assert.AreEqual("B", result[0].Id); +// Assert.AreEqual("C", result[1].Id); +// } + +// [TestMethod] +// public void FilterAndSortAscendingWithoutIndex() +// { +// PrepareData(_collection); +// var result = FilterAndSortById(_collection, Query.Ascending); + +// Assert.AreEqual("B", result[0].Id); +// Assert.AreEqual("C", result[1].Id); +// } + +// [TestMethod] +// public void FilterAndSortDescending() +// { +// _collection.EnsureIndex(nameof(Item.Value)); + +// PrepareData(_collection); +// var result = FilterAndSortById(_collection, Query.Descending); + +// Assert.AreEqual("C", result[0].Id); +// Assert.AreEqual("B", result[1].Id); +// } + +// private void PrepareData(UltraLiteCollection collection) +// { +// collection.Upsert(new Item() { Id = "C", Value = "Value 1" }); +// collection.Upsert(new Item() { Id = "A", Value = "Value 2" }); +// collection.Upsert(new Item() { Id = "B", Value = "Value 1" }); +// } + +// private List FilterAndSortById(UltraLiteCollection collection, int order) +// { +// var filterQuery = Query.EQ(nameof(Item.Value), "Value 1"); +// var sortQuery = Query.All(order); +// var query = Query.And(sortQuery, filterQuery); + +// var result = collection.Find(query).ToList(); +// return result; +// } + +// public class Item +// { +// public string Id { get; set; } + +// public string Value { get; set; } +// } +// } +//} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/NonIdPoco_Tests.cs b/UltraLiteDB.Tests/Database/NonIdPoco_Tests.cs new file mode 100755 index 000000000..fc8bfe27f --- /dev/null +++ b/UltraLiteDB.Tests/Database/NonIdPoco_Tests.cs @@ -0,0 +1,40 @@ +//using Microsoft.VisualStudio.TestTools.UnitTesting; +//using System.Collections.Generic; +//using System.IO; +//using System.Linq; + +//namespace UltraLiteDB.Tests +//{ +// public class MissingIdDoc +// { +// public string Name { get; set; } +// public int Age { get; set; } +// } + +// [TestClass] +// public class MissingIdDocTest +// { +// [TestMethod] +// public void MissingIdDoc_Test() +// { +// using (var file = new TempFile()) +// using (var db = new UltraLiteDatabase(file.Filename)) +// { +// var col = db.GetCollection("col"); + +// var p = new MissingIdDoc { Name = "John", Age = 39 }; + +// // ObjectID will be generated +// var id = col.Insert(p); + +// p.Age = 41; + +// col.Update(id, p); + +// var r = col.FindById(id); + +// Assert.AreEqual(p.Name, r.Name); +// } +// } +// } +//} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/Query_Min_Max_Tests.cs b/UltraLiteDB.Tests/Database/Query_Min_Max_Tests.cs new file mode 100755 index 000000000..db43e9c3f --- /dev/null +++ b/UltraLiteDB.Tests/Database/Query_Min_Max_Tests.cs @@ -0,0 +1,54 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + #region Model + + public class EntityMinMax + { + public int Id { get; set; } + public byte ByteValue { get; set; } + public int IntValue { get; set; } + public uint UintValue { get; set; } + public long LongValue { get; set; } + } + + #endregion + + [TestClass] + public class Query_Min_Max_Tests + { + [TestMethod] + public void Query_Min_Max() + { + using (var f = new TempFile()) + using (var db = new UltraLiteDatabase(f.Filename)) + { + var c = db.GetCollection("col"); + + c.Insert(new EntityMinMax { }); + c.Insert(new EntityMinMax + { + ByteValue = 200, + IntValue = 443500, + LongValue = 443500, + UintValue = 443500 + }); + + c.EnsureIndex("ByteValue"); + c.EnsureIndex("IntValue"); + c.EnsureIndex("LongValue"); + c.EnsureIndex("UintValue"); + + Assert.AreEqual(200, c.Max("ByteValue").AsInt32); + Assert.AreEqual(443500, c.Max("IntValue").AsInt32); + Assert.AreEqual(443500, c.Max("LongValue").AsInt64); + Assert.AreEqual(443500, c.Max("UintValue").AsInt32); + + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Database/UpgradeScript_Tests.cs b/UltraLiteDB.Tests/Database/UpgradeScript_Tests.cs new file mode 100755 index 000000000..530b6cd5e --- /dev/null +++ b/UltraLiteDB.Tests/Database/UpgradeScript_Tests.cs @@ -0,0 +1,35 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Database +{ + [TestClass] + public class UpgradeScript_Tests + { + // [TestMethod] + public void UpgradeScript_Test() + { + // export data TO JSON + using (var db = new UltraLiteDatabase(new MemoryStream())) + { + var data = new BsonDocument(); + foreach(var name in db.GetCollectionNames()) + { + data[name] = new BsonArray(db.GetCollection(name).FindAll()); + } + File.WriteAllText(@"C:\Temp\dump-data.json", JsonSerializer.Serialize(data)); + } + + // import data FROM JSON + using (var db = new UltraLiteDatabase(new MemoryStream())) + { + var data = JsonSerializer.Deserialize(File.ReadAllText(@"C:\Temp\dump-data.json")).AsDocument; + foreach(var name in data.Keys) + { + db.GetCollection(name).Insert(data[name].AsArray.Select(x => x.AsDocument)); + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Document/Bson_Tests.cs b/UltraLiteDB.Tests/Document/Bson_Tests.cs new file mode 100755 index 000000000..265780b9a --- /dev/null +++ b/UltraLiteDB.Tests/Document/Bson_Tests.cs @@ -0,0 +1,88 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.IO.Compression; + +namespace UltraLiteDB.Tests.Document +{ + [TestClass] + public class Bson_Tests + { + private BsonDocument CreateDoc() + { + // create same object, but using BsonDocument + var doc = new BsonDocument(); + doc["_id"] = 123; + doc["FirstString"] = "BEGIN this string \" has \" \t and this \f \n\r END"; + doc["CustomerId"] = Guid.NewGuid(); + doc["Date"] = DateTime.Now; + doc["MyNull"] = null; + doc["EmptyObj"] = new BsonDocument(); + doc["EmptyString"] = ""; + doc["maxDate"] = DateTime.MaxValue; + doc["minDate"] = DateTime.MinValue; + + + doc["Items"] = new BsonArray(); + + doc["Items"].AsArray.Add(new BsonDocument()); + doc["Items"].AsArray[0].AsDocument["Qtd"] = 3; + doc["Items"].AsArray[0].AsDocument["Description"] = "Big beer package"; + doc["Items"].AsArray[0].AsDocument["Unit"] = (double)10 / (double)3; + + doc["Items"].AsArray.Add("string-one"); + doc["Items"].AsArray.Add(null); + doc["Items"].AsArray.Add(true); + doc["Items"].AsArray.Add(DateTime.Now); + + return doc; + } + + [TestMethod] + public void Convert_To_Json_Bson() + { + var o = CreateDoc(); + + var bson = BsonSerializer.Serialize(o); + var json = JsonSerializer.Serialize(o); + + var doc = BsonSerializer.Deserialize(bson); + + Assert.AreEqual(123, doc["_id"].AsInt32); + Assert.AreEqual(o["_id"].AsInt64, doc["_id"].AsInt64); + + Assert.AreEqual(o["FirstString"].AsString, doc["FirstString"].AsString); + Assert.AreEqual(o["Date"].AsDateTime.ToString(), doc["Date"].AsDateTime.ToString()); + Assert.AreEqual(o["CustomerId"].AsGuid, doc["CustomerId"].AsGuid); + Assert.AreEqual(o["MyNull"].IsNull, doc["MyNull"].IsNull); + Assert.AreEqual(o["EmptyString"].AsString, doc["EmptyString"].AsString); + + Assert.AreEqual(DateTime.MaxValue, doc["maxDate"].AsDateTime); + Assert.AreEqual(DateTime.MinValue, doc["minDate"].AsDateTime); + + Assert.AreEqual(o["Items"].AsArray.Count, doc["Items"].AsArray.Count); + Assert.AreEqual(o["Items"].AsArray[0].AsDocument["Unit"].AsDouble, doc["Items"].AsArray[0].AsDocument["Unit"].AsDouble); + Assert.AreEqual(o["Items"].AsArray[4].AsDateTime.ToString(), doc["Items"].AsArray[4].AsDateTime.ToString()); + } + + [TestMethod] + public void Bson_Using_UTC_Local_Dates() + { + var doc = new BsonDocument { ["now"] = DateTime.Now, ["min"] = DateTime.MinValue, ["max"] = DateTime.MaxValue }; + var bytes = BsonSerializer.Serialize(doc); + + var local = BsonSerializer.Deserialize(bytes, false); + var utc = BsonSerializer.Deserialize(bytes, true); + + // local test + Assert.AreEqual(DateTime.MinValue, local["min"].AsDateTime); + Assert.AreEqual(DateTime.MaxValue, local["max"].AsDateTime); + Assert.AreEqual(DateTimeKind.Local, local["now"].AsDateTime.Kind); + + // utc test + Assert.AreEqual(DateTime.MinValue, utc["min"].AsDateTime); + Assert.AreEqual(DateTime.MaxValue, utc["max"].AsDateTime); + Assert.AreEqual(DateTimeKind.Utc, utc["now"].AsDateTime.Kind); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Document/Decimal_Tests.cs b/UltraLiteDB.Tests/Document/Decimal_Tests.cs new file mode 100755 index 000000000..8b2097594 --- /dev/null +++ b/UltraLiteDB.Tests/Document/Decimal_Tests.cs @@ -0,0 +1,45 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Document +{ + [TestClass] + public class Decimal_Tests + { + [TestMethod] + public void BsonValueDecimal() + { + var d0 = 0m; + var d1 = 1m; + var dmin = new BsonValue(decimal.MinValue); + var dmax = new BsonValue(decimal.MaxValue); + + Assert.AreEqual("{\"$numberDecimal\":\"0\"}", JsonSerializer.Serialize(d0)); + Assert.AreEqual("{\"$numberDecimal\":\"1\"}", JsonSerializer.Serialize(d1)); + Assert.AreEqual("{\"$numberDecimal\":\"-79228162514264337593543950335\"}", JsonSerializer.Serialize(dmin)); + Assert.AreEqual("{\"$numberDecimal\":\"79228162514264337593543950335\"}", JsonSerializer.Serialize(dmax)); + + var b0 = BsonSerializer.Serialize(new BsonDocument { { "A", d0 } }); + var b1 = BsonSerializer.Serialize(new BsonDocument { { "A", d1 } }); + var bmin = BsonSerializer.Serialize(new BsonDocument { { "A", dmin } }); + var bmax = BsonSerializer.Serialize(new BsonDocument { { "A", dmax } }); + + var x0 = BsonSerializer.Deserialize(b0); + var x1 = BsonSerializer.Deserialize(b1); + var xmin = BsonSerializer.Deserialize(bmin); + var xmax = BsonSerializer.Deserialize(bmax); + + Assert.AreEqual(d0, x0["A"].AsDecimal); + Assert.AreEqual(d1, x1["A"].AsDecimal); + Assert.AreEqual(dmin, xmin["A"]); + Assert.AreEqual(dmax, xmax["A"]); + + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Document/Document_Tests.cs b/UltraLiteDB.Tests/Document/Document_Tests.cs new file mode 100755 index 000000000..5e6a48543 --- /dev/null +++ b/UltraLiteDB.Tests/Document/Document_Tests.cs @@ -0,0 +1,69 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Document +{ + [TestClass] + public class Document_Test + { + [TestMethod] + public void Document_ImplicitConvert_Test() + { + var obj = new Dictionary() + { + { "int", 123 }, + { "arr", new object[] { 3.0, 2, 1, "zero", false } }, + { "doc", new Dictionary() + { + { "a", "a" }, + { "b", new int[] { 0 } }, + } + } + }; + + var doc = BsonValue.FromObject(obj); + + var json = JsonSerializer.Serialize(doc); + + Assert.AreEqual("{\"int\":123,\"arr\":[3.0,2,1,\"zero\",false],\"doc\":{\"a\":\"a\",\"b\":[0]}}", json); + } + + [TestMethod] + public void Document_copies_properties_to_KeyValue_array() + { + // ARRANGE + // create a Bson document with all possible value types + + var document = new BsonDocument(); + document.Add("string", new BsonValue("string")); + document.Add("bool", new BsonValue(true)); + document.Add("objectId", new BsonValue(ObjectId.NewObjectId())); + document.Add("DateTime", new BsonValue(DateTime.Now)); + document.Add("decimal", new BsonValue((decimal)1)); + document.Add("double", new BsonValue((double)1.0)); + document.Add("guid", new BsonValue(Guid.NewGuid())); + document.Add("int", new BsonValue((int)1)); + document.Add("long", new BsonValue((long)1)); + document.Add("bytes", new BsonValue(new byte[] { (byte)1 })); + document.Add("bsonDocument", new BsonDocument()); + + // ACT + // copy all properties to destination array + + var result = new KeyValuePair[document.Count()]; + document.CopyTo(result, 0); + + // ASSERT + // all BsonValue instances have been added to the array by reference + + //TODO: implement get from another way + // Assert.IsTrue(result.All(kv => object.ReferenceEquals(document.Get(kv.Key), kv.Value))); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Document/Implicit_Tests.cs b/UltraLiteDB.Tests/Document/Implicit_Tests.cs new file mode 100755 index 000000000..e5276cf01 --- /dev/null +++ b/UltraLiteDB.Tests/Document/Implicit_Tests.cs @@ -0,0 +1,35 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Document +{ + [TestClass] + public class Implicit_Tests + { + [TestMethod] + public void Implicit_Convert() + { + int i = int.MaxValue; + long l = long.MaxValue; + ulong u = ulong.MaxValue; + + BsonValue bi = i; + BsonValue bl = l; + BsonValue bu = u; + + Assert.IsTrue(bi.IsInt32); + Assert.IsTrue(bl.IsInt64); + Assert.IsTrue(bu.IsDouble); + + Assert.AreEqual(i, bi.AsInt32); + Assert.AreEqual(l, bl.AsInt64); + Assert.AreEqual(u, bu.AsDouble); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Bulk_Insert_Tests.cs b/UltraLiteDB.Tests/Engine/Bulk_Insert_Tests.cs new file mode 100755 index 000000000..94458244b --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Bulk_Insert_Tests.cs @@ -0,0 +1,46 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Bulk_Insert_Tests + { + [TestMethod] + public void Bulk_Insert_Engine() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + // let's bulk 500.000 documents + db.InsertBulk("col", GetDocs(1, 60000)); + + // and assert if all are inserted (based on collection header only) + Assert.AreEqual(60000, db.Count("col")); + + // and now count all + Assert.AreEqual(60000, db.Count("col", Query.All())); + } + } + + private IEnumerable GetDocs(int initial, int count, int type = 1) + { + for (var i = initial; i < initial + count; i++) + { + yield return new BsonDocument + { + { "_id", i }, + { "name", Guid.NewGuid().ToString() }, + { "first", "John" }, + { "lorem", TempFile.LoremIpsum(3, 5, 2, 3, 3) } + }; + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Create_Database_Tests.cs b/UltraLiteDB.Tests/Engine/Create_Database_Tests.cs new file mode 100755 index 000000000..c07c8c8e8 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Create_Database_Tests.cs @@ -0,0 +1,69 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Create_Database_Tests + { + [TestMethod] + public void Create_Database_With_Initial_Size() + { + var initial = 40 * 1024; // initial size: 40kb + var minimal = 4096 * 5; // 1 header + 1 lock + 1 collection + 1 data + 1 index = 5 pages minimal + + using (var file = new TempFile()) + using (var db = new UltraLiteDatabase(file.Conn("initial size=40kb"))) + { + // just ensure open datafile + var uv = db.Engine.UserVersion; + + // test if file has 40kb + Assert.AreEqual(initial, file.Size); + + // simple insert to test if datafile still with 40kb + BsonDocument doc = new BsonDocument(); + doc["a"] = 1; + db.Engine.Insert("col1", doc); + + Assert.AreEqual(initial, file.Size); + + // ok, now shrink and test if file are minimal size + db.Shrink(); + + Assert.AreEqual(minimal, file.Size); + } + } + + [TestMethod] + public void Create_Database_With_Initial_Size_Encrypted() + { + var initial = 40 * 1024; // initial size: 40kb + var minimal = 4096 * 5; // 1 header + 1 lock + 1 collection + 1 data + 1 index = 5 pages minimal + + using (var file = new TempFile(checkIntegrity: false)) + using (var db = new UltraLiteDatabase(file.Conn("initial size=40kb; password=123"))) + { + // just ensure open datafile + var uv = db.Engine.UserVersion; + + // test if file has 40kb + Assert.AreEqual(initial, file.Size); + + // simple insert to test if datafile still with 40kb + BsonDocument doc = new BsonDocument(); + doc["a"] = 1; + db.Engine.Insert("col1", doc); + + Assert.AreEqual(initial, file.Size); + + // ok, now shrink and test if file are minimal size + db.Shrink(); + + Assert.AreEqual(minimal, file.Size); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Delete_Query_Tests.cs b/UltraLiteDB.Tests/Engine/Delete_Query_Tests.cs new file mode 100755 index 000000000..b6063d374 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Delete_Query_Tests.cs @@ -0,0 +1,45 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Delete_Query_Tests + { + [TestMethod] + public void Delete_Query() + { + using (var file = new TempFile()) + { + var initial = new DateTime(2000, 01, 01); + + using (var db = new UltraLiteEngine(file.Filename)) + { + for(var i = 0; i < 5000; i++) + { + db.Insert("col", new BsonDocument { { "dt", initial.AddDays(i) } }); + } + + db.EnsureIndex("col", "dt"); + + Assert.AreEqual(5000, db.Count("col")); + + Assert.AreEqual(0, db.Count("col", Query.GT("dd", initial))); + + var del = db.Delete("col", Query.GT("dd", initial)); + + Assert.AreEqual(0, del); + + Assert.AreEqual(0, db.Count("col", Query.GT("dd", initial))); + + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/DropCollection_Tests.cs b/UltraLiteDB.Tests/Engine/DropCollection_Tests.cs new file mode 100755 index 000000000..5fcebfd55 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/DropCollection_Tests.cs @@ -0,0 +1,27 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class DropCollection_Tests + { + [TestMethod] + public void DropCollection() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + Assert.IsFalse(db.GetCollectionNames().Any(x => x == "col")); + + db.Insert("col", new BsonDocument { { "a", 1 } }); + Assert.IsTrue(db.GetCollectionNames().Any(x => x == "col")); + + db.DropCollection("col"); + + Assert.IsFalse(db.GetCollectionNames().Any(x => x == "col")); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Encrypted_Tests.cs b/UltraLiteDB.Tests/Engine/Encrypted_Tests.cs new file mode 100755 index 000000000..d96639df9 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Encrypted_Tests.cs @@ -0,0 +1,60 @@ +using System.IO; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Encrypted_Tests + { + [TestMethod] + public void Encrypted_Database() + { + using (var encrypt = new TempFile()) + using (var plain = new TempFile()) + { + // create a database with no password - plain data + using (var db = new UltraLiteEngine(plain.Filename)) + { + db.Insert("col", new BsonDocument { { "name", "Mauricio David" } }); + } + + // read datafile to find "Mauricio" string + Assert.IsTrue(plain.ReadAsText().Contains("Mauricio David")); + + // create a database with password + using (var db = new UltraLiteEngine(encrypt.Filename, "abc123")) + { + db.Insert("col", new BsonDocument { { "name", "Mauricio David" } }); + } + + // test if is possible find "Mauricio" string + Assert.IsFalse(encrypt.ReadAsText().Contains("Mauricio David")); + + // try access using wrong password + try + { + using (var db = new UltraLiteEngine(encrypt.Filename, "abc1234")) + { + Assert.Fail(); // can't work + } + } + catch (UltraLiteException ex) + { + Assert.IsTrue(ex.ErrorCode == 123); // wrong password + } + + // open encrypted db and read document + using (var db = new UltraLiteEngine(encrypt.Filename, "abc123")) + { + var doc = db.Find("col", Query.All()).First(); + + Assert.AreEqual("Mauricio David", doc["name"].AsString); + + // let's remove password to work CheckIntegrety + db.Shrink(null, null); + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Engine_Tests.cs b/UltraLiteDB.Tests/Engine/Engine_Tests.cs new file mode 100755 index 000000000..c5c03b9d4 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Engine_Tests.cs @@ -0,0 +1,105 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Engine_Tests + { + [TestMethod] + public void Engine_Insert_Documents() + { + using (var file = new TempFile()) + { + using (var db = new UltraLiteEngine(file.Filename)) + { + db.Insert("col", new BsonDocument { { "_id", 1 } , { "name", "John" } }); + db.Insert("col", new BsonDocument { { "_id", 2 }, { "name", "Doe" } }); + } + + using (var db = new UltraLiteEngine(file.Filename)) + { + var john = db.Find("col", Query.EQ("_id", 1)).FirstOrDefault(); + var doe = db.Find("col", Query.EQ("_id", 2)).FirstOrDefault(); + + Assert.AreEqual("John", john["name"].AsString); + Assert.AreEqual("Doe", doe["name"].AsString); + } + } + } + + [TestMethod] + public void Engine_Upsert_Documents() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + var doc1 = new BsonDocument { { "_id", 1 }, { "name", "John" } }; + + var u1 = db.Upsert("col", doc1); // true (insert) + + doc1["name"] = "changed"; + + var u2 = db.Upsert("col", doc1); // false (update) + + Assert.AreEqual(true, u1); + Assert.AreEqual(false, u2); + + // get data from db + var r = db.Find("col", Query.EQ("_id", 1)).Single(); + + // test changed value + Assert.AreEqual(doc1["name"].AsString, r["name"].AsString); + } + } + + [TestMethod] + public void Engine_Delete_Documents() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + var doc1 = new BsonDocument { { "_id", 1 }, { "name", "John" } }; + var doc2 = new BsonDocument { { "_id", 2 }, { "name", "Doe" } }; + + db.Insert("col", doc1); + db.Insert("col", doc2); + + db.Delete("col", Query.GTE("_id", 1)); + + db.Insert("col", doc1); + } + } + + public void Engine_QueryUpdate_Documents() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + db.EnsureIndex("col", "name"); + + // insert 4 documents + db.Insert("col", new BsonDocument { { "_id", 1 } }); + db.Insert("col", new BsonDocument { { "_id", 2 } }); + db.Insert("col", new BsonDocument { { "_id", 3 } }); + db.Insert("col", new BsonDocument { { "_id", 4 } }); + + // query all documents and update name + foreach(var d in db.Find("col", Query.All())) + { + d["name"] = "john"; + db.Update("col", d); + } + + // this simple test if same thread open a read mode and then open write lock mode + Assert.AreEqual(4, db.Count("col", Query.EQ("name", "john"))); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/IndexOrder_Tests.cs b/UltraLiteDB.Tests/Engine/IndexOrder_Tests.cs new file mode 100755 index 000000000..17ad64015 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/IndexOrder_Tests.cs @@ -0,0 +1,44 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class IndexOrder_Tests + { + [TestMethod] + public void Index_Order() + { + using (var tmp = new TempFile()) + using (var db = new UltraLiteEngine(tmp.Filename)) + { + db.Insert("col", new BsonDocument { { "text", "D" } }); + db.Insert("col", new BsonDocument { { "text", "A" } }); + db.Insert("col", new BsonDocument { { "text", "E" } }); + db.Insert("col", new BsonDocument { { "text", "C" } }); + db.Insert("col", new BsonDocument { { "text", "B" } }); + + db.EnsureIndex("col", "text"); + + var asc = string.Join("", + db.Find("col", Query.All("text")) + .Select(x => x["text"].AsString) + .ToArray()); + + var desc = string.Join("", + db.Find("col", Query.All("text", Query.Descending)) + .Select(x => x["text"].AsString) + .ToArray()); + + Assert.AreEqual("ABCDE", asc); + Assert.AreEqual("EDCBA", desc); + + var indexes = db.GetIndexes("col"); + + Assert.AreEqual(1, indexes.Count(x => x.Field == "text")); + + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Json_Tests.cs b/UltraLiteDB.Tests/Engine/Json_Tests.cs new file mode 100755 index 000000000..a2eec0f6d --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Json_Tests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Json_Tests + { + private BsonDocument CreateDoc() + { + // create same object, but using BsonDocument + var doc = new BsonDocument(); + doc["_id"] = 123; + doc["Special"] = "Màçã ámö-î"; + doc["FirstString"] = "BEGIN this string \" has \" \t and this \f \n\r END"; + doc["CustomerId"] = Guid.NewGuid(); + doc["Date"] = new DateTime(2015, 1, 1); + doc["MyNull"] = null; + doc["Items"] = new BsonArray(); + doc["MyObj"] = new BsonDocument(); + doc["EmptyString"] = ""; + var obj = new BsonDocument(); + obj["Qtd"] = 3; + obj["Description"] = "Big beer package"; + obj["Unit"] = 1299.995; + doc["Items"].AsArray.Add(obj); + doc["Items"].AsArray.Add("string-one"); + doc["Items"].AsArray.Add(null); + doc["Items"].AsArray.Add(true); + doc["Items"].AsArray.Add(DateTime.Now); + + + return doc; + } + + [TestMethod] + public void Json_To_Document_Test() + { + var o = CreateDoc(); + + var json = JsonSerializer.Serialize(o); + + var doc = JsonSerializer.Deserialize(json).AsDocument; + + Assert.AreEqual(o["Special"].AsString, doc["Special"].AsString); + Assert.AreEqual(o["Date"].AsDateTime, doc["Date"].AsDateTime); + Assert.AreEqual(o["CustomerId"].AsGuid, doc["CustomerId"].AsGuid); + Assert.AreEqual(o["Items"].AsArray.Count, doc["Items"].AsArray.Count); + Assert.AreEqual(123, doc["_id"].AsInt32); + Assert.AreEqual(o["_id"].AsInt64, doc["_id"].AsInt64); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/MapperInterface_Tests.cs b/UltraLiteDB.Tests/Engine/MapperInterface_Tests.cs new file mode 100755 index 000000000..e551bf0c9 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/MapperInterface_Tests.cs @@ -0,0 +1,72 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Reflection; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class MapperInterface_Tests + { + #region Model + + public interface IMyInterface + { + string Name { get; set; } + } + + public class MyClassImpl : IMyInterface + { + public string Name { get; set; } + } + + // using property as Interface + public class MyClassWithInterface + { + public int Id { get; set; } + public IMyInterface Impl { get; set; } + } + + // using property as base class (object) + public class MyClassWithObject + { + public int Id { get; set; } + public object Impl { get; set; } + } + + // using property as is + public class MyClassWithClassName + { + public int Id { get; set; } + public MyClassImpl Impl { get; set; } + } + + #endregion + + [TestMethod] + public void Map_Interfaces() + { + var mapper = new BsonMapper(); + + var c1 = new MyClassWithInterface { Id = 1, Impl = new MyClassImpl { Name = "John Doe" } }; + var c2 = new MyClassWithObject { Id = 1, Impl = new MyClassImpl { Name = "John Doe" } }; + var c3 = new MyClassWithClassName { Id = 1, Impl = new MyClassImpl { Name = "John Doe" } }; + + var bson1 = mapper.ToDocument(c1); // add _type in Impl property + var bson2 = mapper.ToDocument(c2); // add _type in Impl property + var bson3 = mapper.ToDocument(c3); // do not add _type in Impl property + + //string dllName = this.GetType().Assembly.GetName().Name; + // + //Assert.AreEqual("LiteDB.Tests.MapperInterfaceTest+MyClassImpl, " + dllName, bson1["Impl"].AsDocument["_type"].AsString); + //Assert.AreEqual("LiteDB.Tests.MapperInterfaceTest+MyClassImpl, " + dllName, bson2["Impl"].AsDocument["_type"].AsString); + //Assert.AreEqual(false, bson3["Impl"].AsDocument.ContainsKey("_type")); + + var k1 = mapper.ToObject(bson1); + var k2 = mapper.ToObject(bson2); + var k3 = mapper.ToObject(bson3); + + Assert.AreEqual(c1.Impl.Name, k1.Impl.Name); + Assert.AreEqual((c2.Impl as MyClassImpl).Name, (k2.Impl as MyClassImpl).Name); + Assert.AreEqual(c3.Impl.Name, k3.Impl.Name); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/MemoryStream_Tests.cs b/UltraLiteDB.Tests/Engine/MemoryStream_Tests.cs new file mode 100755 index 000000000..26818311e --- /dev/null +++ b/UltraLiteDB.Tests/Engine/MemoryStream_Tests.cs @@ -0,0 +1,36 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class MemoryStream_Tests + { + [TestMethod] + public void Engine_Using_MemoryStream() + { + var mem = new MemoryStream(); + + using (var db = new UltraLiteEngine(mem)) + { + db.Insert("col", new BsonDocument { { "_id", 1 } , { "name", "John" } }); + db.Insert("col", new BsonDocument { { "_id", 2 }, { "name", "Doe" } }); + } + + using (var db = new UltraLiteEngine(mem)) + { + var john = db.Find("col", Query.EQ("_id", 1)).FirstOrDefault(); + var doe = db.Find("col", Query.EQ("_id", 2)).FirstOrDefault(); + + Assert.AreEqual("John", john["name"].AsString); + Assert.AreEqual("Doe", doe["name"].AsString); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/ObjectId_Tests.cs b/UltraLiteDB.Tests/Engine/ObjectId_Tests.cs new file mode 100755 index 000000000..b5c4ff070 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/ObjectId_Tests.cs @@ -0,0 +1,45 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class ObjectId_Tests + { + [TestMethod] + public void ObjectId_BsonValue() + { + var oid0 = ObjectId.Empty; + var oid1 = ObjectId.NewObjectId(); + var oid2 = ObjectId.NewObjectId(); + var oid3 = ObjectId.NewObjectId(); + + var c1 = new ObjectId(oid1); + var c2 = new ObjectId(oid2.ToString()); + var c3 = new ObjectId(oid3.ToByteArray()); + + Assert.AreEqual(oid0, ObjectId.Empty); + Assert.AreEqual(oid1, c1); + Assert.AreEqual(oid2, c2); + Assert.AreEqual(oid3, c3); + + Assert.AreEqual(c1.CompareTo(c2), -1); // 1 < 2 + Assert.AreEqual(c2.CompareTo(c3), -1); // 2 < 3 + + // serializations + var joid = JsonSerializer.Serialize(c1); + var jc1 = JsonSerializer.Deserialize(joid).AsObjectId; + + Assert.AreEqual(c1, jc1); + } + + [TestMethod] + public void ObjectId_equals_null_does_not_throw() + { + var oid0 = default(ObjectId); + var oid1 = ObjectId.NewObjectId(); + + Assert.IsFalse(oid1.Equals(null)); + Assert.IsFalse(oid1.Equals(oid0)); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Performance_Tests.cs b/UltraLiteDB.Tests/Engine/Performance_Tests.cs new file mode 100755 index 000000000..b87d09c1d --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Performance_Tests.cs @@ -0,0 +1,72 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Performance_Tests + { + const int N1 = 10000; + const int N2 = 1000; + + [TestMethod] + public void Simple_Performance_Runner() + { + // just a simple example to test performance speed + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + var ti = new Stopwatch(); + var tx = new Stopwatch(); + var tu = new Stopwatch(); + var td = new Stopwatch(); + + ti.Start(); + db.Insert("col", GetDocs(N1)); + ti.Stop(); + + tx.Start(); + db.EnsureIndex("col", "name"); + tx.Stop(); + + tu.Start(); + db.Update("col", GetDocs(N1)); + tu.Stop(); + + db.EnsureIndex("col", "name"); + + td.Start(); + db.Delete("col", Query.All()); + td.Stop(); + + Debug.WriteLine("Insert time: " + ti.ElapsedMilliseconds); + Debug.WriteLine("EnsureIndex time: " + tx.ElapsedMilliseconds); + Debug.WriteLine("Update time: " + tu.ElapsedMilliseconds); + Debug.WriteLine("Delete time: " + td.ElapsedMilliseconds); + } + } + + private IEnumerable GetDocs(int count) + { + var rnd = new Random(); + + for(var i = 0; i < count; i++) + { + yield return new BsonDocument + { + { "_id", i }, + { "name", Guid.NewGuid().ToString() }, + { "type", rnd.Next(1, 100) }, + { "lorem", TempFile.LoremIpsum(3, 5, 2, 3, 3) } + }; + } + } + } +} diff --git a/UltraLiteDB.Tests/Engine/Query_Tests.cs b/UltraLiteDB.Tests/Engine/Query_Tests.cs new file mode 100755 index 000000000..88ae6d548 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Query_Tests.cs @@ -0,0 +1,105 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Query_Tests + { + [TestMethod] + public void Query_Using_Index_Search() + { + ExecuteQuery(true); + } + + [TestMethod] + public void Query_Using_Fullscan_Search() + { + ExecuteQuery(false); + } + + public void ExecuteQuery(bool createIndex) + { + using (var db = new UltraLiteEngine(new MemoryStream())) + { + db.Insert("col", new BsonDocument[] + { + new BsonDocument { ["age"] = 1, ["name"] = "a" }, + new BsonDocument { ["age"] = 2, ["name"] = "b" }, + new BsonDocument { ["age"] = 3, ["name"] = "c" }, + new BsonDocument { ["age"] = 4, ["name"] = "d" }, + new BsonDocument { ["age"] = 5, ["name"] = "e" }, + new BsonDocument { ["age"] = 6, ["name"] = "f" }, + new BsonDocument { ["age"] = 7, ["name"] = "g" }, + new BsonDocument { ["age"] = 8, ["name"] = "h" }, + new BsonDocument { ["age"] = 9, ["name"] = "i" }, + new BsonDocument { ["age"] = 9, ["name"] = "j" } + }); + + if (createIndex) + { + db.EnsureIndex("col", "age"); + db.EnsureIndex("col", "name"); + } + + Func result = (q) => string.Join(",", db.Find("col", q).Select(x => x["name"].AsString)); + + Assert.AreEqual("a,b,c,d,e,f,g,h,i,j", result(Query.All())); + + Assert.AreEqual("a", result(Query.EQ("age", 1))); + Assert.AreEqual("g", result(Query.EQ("age", 7))); + + Assert.AreEqual("h,i,j", result(Query.GT("age", 7))); + Assert.AreEqual("g,h,i,j", result(Query.GTE("age", 7))); + + Assert.AreEqual("", result(Query.LT("age", 1))); + Assert.AreEqual("a", result(Query.LTE("age", 1))); + + Assert.AreEqual("g,h,i,j", result(Query.Between("age", 7, 9))); + + Assert.AreEqual("a,b,c,d,e,f,g,h", result(Query.Not("age", 9))); + Assert.AreEqual("a", result(Query.Not(Query.GTE("age", 2)))); + Assert.AreEqual("a,g,i,j", result(Query.In("age", 1, 7, 9))); + Assert.AreEqual("a", result(Query.StartsWith("name", "a"))); + + Assert.AreEqual("j", result(Query.And(Query.EQ("age", 9), Query.EQ("name", "j")))); + + Assert.AreEqual("j", result(Query.And(Query.GTE("age", 1), Query.And(Query.LTE("age", 9), Query.EQ("name", "j"))))); + + Assert.AreEqual("j", result(Query.And(Query.GTE("age", 1), Query.LTE("age", 9), Query.EQ("name", "j")))); + + Assert.AreEqual("a,i,j", result(Query.Or(Query.EQ("age", 1), Query.EQ("age", 9)))); + + Assert.AreEqual("b,d,f,h", result(Query.Where("age", (v) => v.AsInt32 % 2 == 0))); + } + } + + [TestMethod] + public void Query_Using_First_Linq() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + db.Insert("col", new BsonDocument[] + { + new BsonDocument { { "_id", 1 }, { "name", "e" } }, + new BsonDocument { { "_id", 2 }, { "name", "d" } }, + new BsonDocument { { "_id", 3 }, { "name", "c" } }, + new BsonDocument { { "_id", 4 }, { "name", "b" } }, + new BsonDocument { { "_id", 5 }, { "name", "a" } } + }); + + var first = db.Find("col", Query.All()).First(); + + Assert.AreEqual("e", first["name"].AsString); + + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/Shrink_Tests.cs b/UltraLiteDB.Tests/Engine/Shrink_Tests.cs new file mode 100755 index 000000000..e760fe0d2 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/Shrink_Tests.cs @@ -0,0 +1,116 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class Shrink_Tests + { + [TestMethod] + public void Shrink_After_DropCollection() + { + using (var file = new TempFile()) + using (var db = new UltraLiteEngine(file.Filename)) + { + db.InsertBulk("col", GetDocs(1, 10000)); + + db.DropCollection("col"); + + // full disk usage + var size = file.Size; + + var r = db.Shrink(); + + // only header page + reserved lock page + Assert.AreEqual(8192, size - r); + } + } + + [TestMethod] + public void Shrink_Large_Files() + { + // do some tests + Action DoTest = (db) => + { + Assert.AreEqual(1, db.Count("col", null)); + Assert.AreEqual(99, db.UserVersion); + Assert.IsNotNull(db.GetIndexes("col").FirstOrDefault(x => x.Field == "name")); + Assert.IsTrue(db.GetIndexes("col").FirstOrDefault(x => x.Field == "name").Unique); + }; + + using (var file = new TempFile()) + { + using (var dbe = new UltraLiteDatabase(file.Filename)) + { + var db = dbe.Engine; + + db.UserVersion = 99; + db.EnsureIndex("col", "name", true); + db.Insert("col", GetDocs(1, 40000)); + db.Delete("col", Query.GT("_id", 1)); // delete 29.999 docs + + Assert.AreEqual(1, db.Count("col", null)); + + // file still large than 20mb (even with only 1 document) + Assert.IsTrue(file.Size > 20 * 1024 * 1024); + + // reduce datafile (use temp disk) (from UltraLiteDatabase) + dbe.Shrink(); + + // now file are small than 50kb + Assert.IsTrue(file.Size < 50 * 1024); + + DoTest(db); + } + + // re-open datafile to check if is ok + using (var db = new UltraLiteDatabase(file.Filename)) + { + // still 1 doc and 1 name unique index + DoTest(db.Engine); + + // shrink again but now with password + var reduced = db.Shrink("abc123"); + + // file still same size (but now are encrypted) + Assert.AreEqual(0, reduced); + + // still 1 doc and 1 name unique index + DoTest(db.Engine); + } + + // re-open, again, but now with password + using (var db = new UltraLiteEngine(file.Filename, "abc123")) + { + DoTest(db); + + // now, remove password + db.Shrink(); + + // test again + DoTest(db); + } + } + } + + private IEnumerable GetDocs(int initial, int count, int type = 1) + { + for (var i = initial; i < initial + count; i++) + { + yield return new BsonDocument + { + { "_id", i }, + { "name", Guid.NewGuid().ToString() }, + { "first", "John" }, + { "lorem", TempFile.LoremIpsum(3, 5, 2, 3, 3) } + }; + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Engine/UserVersion_Tests.cs b/UltraLiteDB.Tests/Engine/UserVersion_Tests.cs new file mode 100755 index 000000000..f2deea288 --- /dev/null +++ b/UltraLiteDB.Tests/Engine/UserVersion_Tests.cs @@ -0,0 +1,27 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; + +namespace UltraLiteDB.Tests.Engine +{ + [TestClass] + public class UserVersion_Tests + { + [TestMethod] + public void UserVersion_Get_Set() + { + using (var file = new TempFile()) + { + using (var db = new UltraLiteEngine(file.Filename)) + { + Assert.AreEqual(0, db.UserVersion); + db.UserVersion = 5; + } + + using (var db = new UltraLiteEngine(file.Filename)) + { + Assert.AreEqual(5, db.UserVersion); + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Attribute_Mapper_Tests.cs b/UltraLiteDB.Tests/Mapper/Attribute_Mapper_Tests.cs new file mode 100755 index 000000000..ac2b0cd78 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Attribute_Mapper_Tests.cs @@ -0,0 +1,66 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UltraLiteDB; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class AttrCustomer + { + [BsonId] + public int MyPK { get; set; } + [BsonField("name")] + public string NameCustomer { get; set; } + [BsonIgnore] + public bool Ignore { get; set; } + public AttrAddress Address { get; set; } + public List Addresses { get; set; } + } + + public class AttrAddress + { + [BsonId] + public int AddressPK { get; set; } + public string Street { get; set; } + } + + #endregion + + [TestClass] + public class Attribute_Mapper_Tests + { + [TestMethod] + public void Attribute_Mapper() + { + var mapper = new BsonMapper(); + + var c0 = new AttrCustomer + { + MyPK = 1, + NameCustomer = "J", + Address = new AttrAddress { AddressPK = 5, Street = "R" }, + Ignore = true, + Addresses = new List() + { + new AttrAddress { AddressPK = 3 }, + new AttrAddress { AddressPK = 4 } + } + }; + + var j0 = JsonSerializer.Serialize(mapper.ToDocument(c0)); + + var c1 = mapper.ToObject(JsonSerializer.Deserialize(j0).AsDocument); + + Assert.AreEqual(c0.MyPK, c1.MyPK); + Assert.AreEqual(c0.NameCustomer, c1.NameCustomer); + Assert.AreEqual(false, c1.Ignore); + Assert.AreEqual(c0.Address.AddressPK, c1.Address.AddressPK); + Assert.AreEqual(c0.Addresses[0].AddressPK, c1.Addresses[0].AddressPK); + Assert.AreEqual(c0.Addresses[1].AddressPK, c1.Addresses[1].AddressPK); + + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Basic_Mapper_Tests.cs b/UltraLiteDB.Tests/Mapper/Basic_Mapper_Tests.cs new file mode 100755 index 000000000..ba03091c3 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Basic_Mapper_Tests.cs @@ -0,0 +1,264 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Drawing; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class CustomStringEnumerable : IEnumerable + { + private readonly List innerList; + + public CustomStringEnumerable() + { + innerList = new List(); + } + + public CustomStringEnumerable(IEnumerable list) + { + innerList = new List(list); + } + + public void Add(string item) + { + innerList.Add(item); + } + + public IEnumerator GetEnumerator() + { + return innerList.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + public enum MyEnum { First, Second } + + public class MyClass + { + [BsonId(false)] + public int MyId { get; set; } + + [BsonField("MY-STRING")] + public string MyString { get; set; } + + public Guid MyGuid { get; set; } + public DateTime MyDateTime { get; set; } + public DateTime? MyDateTimeNullable { get; set; } + public int? MyIntNullable { get; set; } + public MyEnum MyEnumProp { get; set; } + public char MyChar { get; set; } + public byte MyByte { get; set; } + public sbyte MySByte { get; set; } + public TimeSpan MyTimespan { get; set; } + + public decimal MyDecimal { get; set; } + + public decimal? MyDecimalNullable { get; set; } + + public Uri MyUri { get; set; } + + // do not serialize this properties + [BsonIgnore] + public string MyIgnore { get; set; } + + public string MyReadOnly { get { return "read only"; } } + public string MyWriteOnly { set; private get; } + + // lists + public string[] MyStringArray { get; set; } + + public List MyStringList { get; set; } + public IEnumerable MyStringEnumerable { get; set; } + public CustomStringEnumerable CustomStringEnumerable { get; set; } + public Dictionary MyDict { get; set; } + public Dictionary MyDictEnum { get; set; } + + // list of structs + public ICollection MyCollectionPoint { get; set; } + public IList MyListPoint { get; set; } + public IEnumerable MyEnumerablePoint { get; set; } + + // interfaces + public IMyInterface MyInterface { get; set; } + + public List MyListInterface { get; set; } + public IList MyIListInterface { get; set; } + + // objects + public object MyObjectString { get; set; } + + public object MyObjectInt { get; set; } + public object MyObjectImpl { get; set; } + public List MyObjectList { get; set; } + + // fields + public string MyField; + + + // this is a indexer property - should not be serialized #795 + public string this[string itemName] + { + get + { + return this.MyString; + } + set + { + this.MyString = value; + } + } + + } + + public interface IMyInterface + { + string Name { get; set; } + } + + public class MyImpl : IMyInterface + { + public string Name { get; set; } + } + + public class MyFluentEntity + { + public int MyPrimaryPk { get; set; } + public string CustomName { get; set; } + public bool DoNotIncludeMe { get; set; } + public DateTime MyDateIndexed { get; set; } + } + + #endregion + + [TestClass] + public class Basic_Mapper_Tests + { + private MyClass CreateModel() + { + var c = new MyClass + { + MyId = 123, + MyString = "John", + MyGuid = Guid.NewGuid(), + MyDateTime = DateTime.Now, + //MyProperty = "SerializeTHIS", + MyIgnore = "IgnoreTHIS", + MyIntNullable = 999, + MyStringList = new List() { "String-1", "String-2" }, + MyWriteOnly = "write-only", + //MyInternalProperty = "internal-field", + MyDict = new Dictionary() { { 1, "Row1" }, { 2, "Row2" } }, + MyDictEnum = new Dictionary() { { StringComparison.Ordinal, "ordinal" } }, + MyStringArray = new string[] { "One", "Two" }, + MyStringEnumerable = new string[] { "One", "Two" }, + CustomStringEnumerable = new CustomStringEnumerable(new string[] { "One", "Two" }), + + // list of structs + MyCollectionPoint = new List { new Point(1, 1), Point.Empty }, + MyListPoint = new List { new Point(1, 1), Point.Empty }, + MyEnumerablePoint = new[] { new Point(1, 1), Point.Empty }, + + MyEnumProp = MyEnum.Second, + MyChar = 'Y', + MyUri = new Uri("http://www.numeria.com.br"), + MyByte = 255, + MySByte = -99, + MyField = "Field test", + MyTimespan = TimeSpan.FromDays(1), + MyDecimal = 19.9m, + MyDecimalNullable = 25.5m, + + MyInterface = new MyImpl { Name = "John" }, + MyListInterface = new List() { new MyImpl { Name = "John" } }, + MyIListInterface = new List() { new MyImpl { Name = "John" } }, + + MyObjectString = "MyString", + MyObjectInt = 123, + MyObjectImpl = new MyImpl { Name = "John" }, + MyObjectList = new List() { 1, "ola", new MyImpl { Name = "John" }, new Uri("http://www.cnn.com") } + }; + + return c; + } + + public BsonMapper CreateMapper() + { + var mapper = new BsonMapper(); + mapper.UseLowerCaseDelimiter('_'); + mapper.IncludeFields = true; + return mapper; + } + + [TestMethod] + public void Basic_Mapper() + { + var mapper = CreateMapper(); + var obj = CreateModel(); + var doc = mapper.ToDocument(obj); + + var json = JsonSerializer.Serialize(doc); + + // test read-only + Assert.AreEqual(obj.MyReadOnly, doc["my_read_only"].AsString); + + var nobj = mapper.ToObject(doc); + + // compare object to document + Assert.AreEqual(doc["_id"].AsInt32, obj.MyId); + Assert.AreEqual(doc["MY-STRING"].AsString, obj.MyString); + Assert.AreEqual(doc["my_guid"].AsGuid, obj.MyGuid); + + // compare 2 objects + Assert.AreEqual(obj.MyId, nobj.MyId); + Assert.AreEqual(obj.MyString, nobj.MyString); + Assert.AreEqual(obj.MyGuid, nobj.MyGuid); + Assert.AreEqual(obj.MyDateTime.ToString(), nobj.MyDateTime.ToString()); + Assert.AreEqual(obj.MyDateTimeNullable, nobj.MyDateTimeNullable); + Assert.AreEqual(obj.MyIntNullable, nobj.MyIntNullable); + Assert.AreEqual(obj.MyEnumProp, nobj.MyEnumProp); + Assert.AreEqual(obj.MyChar, nobj.MyChar); + Assert.AreEqual(obj.MyByte, nobj.MyByte); + Assert.AreEqual(obj.MySByte, nobj.MySByte); + Assert.AreEqual(obj.MyField, nobj.MyField); + Assert.AreEqual(obj.MyTimespan, nobj.MyTimespan); + Assert.AreEqual(obj.MyDecimal, nobj.MyDecimal); + Assert.AreEqual(obj.MyUri, nobj.MyUri); + + // list + Assert.AreEqual(obj.MyStringArray[0], nobj.MyStringArray[0]); + Assert.AreEqual(obj.MyStringArray[1], nobj.MyStringArray[1]); + Assert.AreEqual(obj.MyStringEnumerable.First(), nobj.MyStringEnumerable.First()); + Assert.AreEqual(obj.MyStringEnumerable.Take(1).First(), nobj.MyStringEnumerable.Take(1).First()); + Assert.AreEqual(true, obj.CustomStringEnumerable.SequenceEqual(nobj.CustomStringEnumerable)); + Assert.AreEqual(obj.MyDict[2], nobj.MyDict[2]); + Assert.AreEqual(obj.MyDictEnum[StringComparison.Ordinal], nobj.MyDictEnum[StringComparison.Ordinal]); + + // list of structs + Assert.AreEqual(obj.MyCollectionPoint.First(), nobj.MyCollectionPoint.First()); + Assert.AreEqual(obj.MyListPoint.First(), nobj.MyListPoint.First()); + Assert.AreEqual(obj.MyEnumerablePoint.First(), nobj.MyEnumerablePoint.First()); + + // interfaces + Assert.AreEqual(obj.MyInterface.Name, nobj.MyInterface.Name); + Assert.AreEqual(obj.MyListInterface[0].Name, nobj.MyListInterface[0].Name); + Assert.AreEqual(obj.MyIListInterface[0].Name, nobj.MyIListInterface[0].Name); + + // objects + Assert.AreEqual(obj.MyObjectString, nobj.MyObjectString); + Assert.AreEqual(obj.MyObjectInt, nobj.MyObjectInt); + Assert.AreEqual((obj.MyObjectImpl as MyImpl).Name, (nobj.MyObjectImpl as MyImpl).Name); + Assert.AreEqual(obj.MyObjectList[0], obj.MyObjectList[0]); + Assert.AreEqual(obj.MyObjectList[1], obj.MyObjectList[1]); + Assert.AreEqual(obj.MyObjectList[3], obj.MyObjectList[3]); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Custom_Types_Tests.cs b/UltraLiteDB.Tests/Mapper/Custom_Types_Tests.cs new file mode 100755 index 000000000..b8685ef51 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Custom_Types_Tests.cs @@ -0,0 +1,52 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class CustomType + { + public Regex Re1 { get; set; } + public Regex Re2 { get; set; } + + public Uri Url { get; set; } + public TimeSpan Ts { get; set; } + } + + #endregion + + [TestClass] + public class Custom_Types_Tests + { + [TestMethod] + public void Custom_Types() + { + var mapper = new BsonMapper(); + + var o = new CustomType + { + Re1 = new Regex("^a+"), + Re2 = new Regex("^a*", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace), + Url = new Uri("http://www.litedb.org"), + Ts = TimeSpan.FromSeconds(10) + }; + + var doc = mapper.ToDocument(o); + var no = mapper.ToObject(doc); + + Assert.AreEqual("^a+", doc["Re1"].AsString); + Assert.AreEqual("^a*", doc["Re2"].AsDocument["p"].AsString); + + Assert.AreEqual(o.Re1.ToString(), no.Re1.ToString()); + Assert.AreEqual(o.Re2.ToString(), no.Re2.ToString()); + Assert.AreEqual(o.Re2.Options, no.Re2.Options); + Assert.AreEqual(o.Url, no.Url); + Assert.AreEqual(o.Ts, no.Ts); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Derived_Type_Tests.cs b/UltraLiteDB.Tests/Mapper/Derived_Type_Tests.cs new file mode 100755 index 000000000..cf1ae5fbe --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Derived_Type_Tests.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class Base + { + public int Id { get; set; } + } + + public class Derived1 : Base + { + public string Member1 { get; set; } + } + + public class Derived2 : Base + { + public string Member2 { get; set; } + } + + #endregion + + [TestClass] + public class Derived_Type_Tests + { + [TestMethod] + public void Derived_Type() + { + using (var db = new UltraLiteDatabase(new MemoryStream())) + { + var derived1 = new Derived1 { Id = 1, Member1 = "Derived1" }; + var derived2 = new Derived2 { Id = 2, Member2 = "Dereived2" }; + + var colTyped = db.GetCollection("Collection"); + + colTyped.Insert(derived1); + colTyped.Insert(derived2); + + var colBson = db.GetCollection("Collection"); + + var docs = colBson.FindAll().ToList(); + + Assert.IsTrue(docs.Count > 0); + + // checks if BsonDocument contains _type + var doc1 = colBson.FindById(1); + var doc2 = colBson.FindById(2); + + Assert.IsTrue(doc1["_type"].AsString.Contains("Derived1")); + Assert.IsTrue(doc2["_type"].AsString.Contains("Derived2")); + + // now, test if all document will deserialize with right type + var d1 = colTyped.FindById(1); + var d2 = colTyped.FindById(2); + + Assert.IsTrue(d1 is Derived1); + Assert.IsTrue(d2 is Derived2); + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Dictionary_Tests.cs b/UltraLiteDB.Tests/Mapper/Dictionary_Tests.cs new file mode 100755 index 000000000..708f3c61d --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Dictionary_Tests.cs @@ -0,0 +1,81 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class DictListData + { + public int Id { get; set; } + public Dictionary> MyDict { get; set; } + } + + #endregion + + [TestClass] + public class Dictionary_Tests + { + [TestMethod] + public void Nested_Dictionary() + { + var mapper = new BsonMapper(); + + // map dictionary to bsondocument + var dict = new Dictionary + { + ["_id"] = 1, + ["MyString"] = "This is string", + ["Nested"] = new Dictionary() + { + ["One"] = 1, + ["Two"] = 2, + ["Nested2"] = new Dictionary() + { + ["Last"] = true + } + }, + ["Array"] = new string[] { "one", "two" } + }; + + var doc = mapper.ToDocument(dict); + var nobj = mapper.ToObject>(doc); + + Assert.AreEqual(dict["_id"], nobj["_id"]); + Assert.AreEqual(dict["MyString"], nobj["MyString"]); + Assert.AreEqual(((Dictionary)dict["Nested"])["One"], ((Dictionary)nobj["Nested"])["One"]); + Assert.AreEqual(((string[])dict["Array"])[0], ((object[])nobj["Array"])[0].ToString()); + } + + [TestMethod] + public void Dictionary_Of_List_T() + { + var source = new DictListData + { + Id = 1, + MyDict = new Dictionary>() + { + { "one", new List { 1, null, 3, null, 5 } } + } + }; + + var mapper = new BsonMapper(); + + var doc = mapper.ToDocument(source); + var json = doc.ToString(); + + var dest = mapper.ToObject(doc); + + Assert.AreEqual(source.MyDict["one"][0], dest.MyDict["one"][0]); + Assert.AreEqual(source.MyDict["one"][1], dest.MyDict["one"][1]); + Assert.AreEqual(source.MyDict["one"][2], dest.MyDict["one"][2]); + Assert.AreEqual(source.MyDict["one"][3], dest.MyDict["one"][3]); + Assert.AreEqual(source.MyDict["one"][4], dest.MyDict["one"][4]); + + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Fluent_Api_Mapping_Tests.cs b/UltraLiteDB.Tests/Mapper/Fluent_Api_Mapping_Tests.cs new file mode 100755 index 000000000..175256d86 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Fluent_Api_Mapping_Tests.cs @@ -0,0 +1,49 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Drawing; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class FluentClass + { + public int CurrentKey { get; set; } + public Func GetPath { get; set; } + public string PropName { get; set; } + } + + #endregion + + [TestClass] + public class Fluent_Api_Mapping_Tests + { + [TestMethod] + public void Fluent_Api_Mapping() + { + var o = new FluentClass + { + CurrentKey = 1, + GetPath = () => "", + PropName = "name" + }; + + var m = new BsonMapper(); + + m.Entity() + .Id(x => x.CurrentKey) + .Ignore(x => x.GetPath) + .Field(x => x.PropName, "prop_name"); + + var d = m.ToDocument(o); + + Assert.AreEqual(1, d["_id"].AsInt32); + Assert.IsFalse(d.Keys.Contains("GetPath")); + Assert.AreEqual("name", d["prop_name"].AsString); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Interface_Tests.cs b/UltraLiteDB.Tests/Mapper/Interface_Tests.cs new file mode 100755 index 000000000..24842a1ed --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Interface_Tests.cs @@ -0,0 +1,75 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + /// + /// Testing issue #501 + /// + public interface IPartner + { + string PartnerId + { + get; + } + + string HostId + { + get; + } + } + + // must be public + public class Partner : IPartner + { + // must have public non-parameter ctor + public Partner() + { + } + + public Partner(string partnerId, string hostId) + { + this.PartnerId = partnerId; + this.HostId = hostId; + } + + // must have get/set + public string PartnerId + { + get; set; + } + + public string HostId + { + get; set; + } + } + + #endregion + + [TestClass] + public class Interface_Tests + { + [TestMethod] + public void Interface_Base() + { + var m = new BsonMapper(); + var p = new Partner("one", "host1"); + + var doc = m.ToDocument(p); + + Assert.AreEqual("one", doc["_id"].AsString); + Assert.AreEqual("host1", doc["HostId"].AsString); + + var no = m.ToObject(doc); + + Assert.AreEqual("one", no.PartnerId); + Assert.AreEqual("host1", no.HostId); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Mapper_Exceptions_Tests.cs b/UltraLiteDB.Tests/Mapper/Mapper_Exceptions_Tests.cs new file mode 100755 index 000000000..2ecf2f596 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Mapper_Exceptions_Tests.cs @@ -0,0 +1,44 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class DataRecord + { + public Guid Id { get; set; } + public string Value { get; set; } + } + + #endregion + + [TestClass] + public class Mapper_Exceptions_Tests + { + [TestMethod] + public void Mapper_Exceptions() + { + var dataRecord = new DataRecord(); + var serialized = BsonMapper.Global.ToDocument(dataRecord); + serialized.Add("_type", dataRecord.GetType().FullName); + + try + { + BsonMapper.Global.ToObject(serialized); + + Assert.Fail("Throw error"); + } + catch(UltraLiteException ex) + { + if(ex.ErrorCode != 207) + { + Assert.Fail("Error must be 207"); + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Max_Min_Values_Tests.cs b/UltraLiteDB.Tests/Mapper/Max_Min_Values_Tests.cs new file mode 100755 index 000000000..d9378b08d --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Max_Min_Values_Tests.cs @@ -0,0 +1,46 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Drawing; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class MyMaxValueClass + { + public int Id { get; set; } + + public UInt64 Min { get; set; } + public UInt64 Max { get; set; } + } + + #endregion + + [TestClass] + public class Max_Min_Values_Tests + { + [TestMethod] + public void Max_Min_Values() + { + var c1 = new MyMaxValueClass + { + Min = UInt64.MinValue, + Max = UInt64.MaxValue + }; + + var doc = BsonMapper.Global.ToDocument(c1); + var json = JsonSerializer.Serialize(doc); + var bson = BsonSerializer.Serialize(doc); + + var ndoc = BsonSerializer.Deserialize(bson); + var c2 = BsonMapper.Global.ToObject(ndoc); + + Assert.AreEqual(c1.Min, c2.Min); + Assert.AreEqual(c1.Max, c2.Max); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Non_Public_Members_Tests.cs b/UltraLiteDB.Tests/Mapper/Non_Public_Members_Tests.cs new file mode 100755 index 000000000..be447bd25 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Non_Public_Members_Tests.cs @@ -0,0 +1,133 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class MyBsonFieldTestClass + { + [BsonField("MY-STRING")] + public string MyString { get; set; } + + [BsonField] + internal string MyInternalPropertySerializable { get; set; } + + [BsonField] + private string MyPrivatePropertySerializable { get; set; } + + [BsonField] + protected string MyProtectedPropertySerializable { get; set; } + + [BsonField("INTERNAL-PROPERTY")] + internal string MyInternalPropertyNamed { get; set; } + + [BsonField("PRIVATE-PROPERTY")] + private string MyPrivatePropertyNamed { get; set; } + + [BsonField("PROTECTED-PROPERTY")] + protected string MyProtectedPropertyNamed { get; set; } + + internal string MyInternalPropertyNotSerializable { get; set; } + private string MyPrivatePropertyNotSerializable { get; set; } + protected string MyProtectedPropertyNotSerializable { get; set; } + + public void SetPrivateProperties(string str) + { + MyPrivatePropertyNamed = str + "Named"; + MyPrivatePropertySerializable = str + "Serializable"; + MyPrivatePropertyNotSerializable = str + "NotSerialisable"; + } + + public void SetProtectedProperties(string str) + { + MyProtectedPropertyNamed = str + "Named"; + MyProtectedPropertySerializable = str + "Serializable"; + MyProtectedPropertyNotSerializable = str + "NotSerialisable"; + } + + public string GetMyPrivatePropertySerializable() + { + return MyPrivatePropertySerializable; + } + + public string GetMyProtectedPropertySerializable() + { + return MyProtectedPropertySerializable; + } + + public string GetMyPrivatePropertyNamed() + { + return MyPrivatePropertyNamed; + } + + public string GetMyProtectedPropertyNamed() + { + return MyProtectedPropertyNamed; + } + + public string GetMyPrivatePropertyNotSerializable() + { + return MyPrivatePropertyNotSerializable; + } + + public string GetMyProtectedPropertyNotSerializable() + { + return MyProtectedPropertyNotSerializable; + } + } + + #endregion + + [TestClass] + public class Non_Public_Members_Tests + { + private MyBsonFieldTestClass CreateModel() + { + var c = new MyBsonFieldTestClass + { + MyString = "MyString", + MyInternalPropertyNamed = "InternalPropertyNamed", + MyInternalPropertyNotSerializable = "InternalPropertyNotSerializable", + MyInternalPropertySerializable = "InternalPropertySerializable", + }; + + c.SetProtectedProperties("ProtectedProperties"); + c.SetPrivateProperties("PrivateProperty"); + + return c; + } + + [TestMethod] + public void Non_Public_Members() + { + var mapper = new BsonMapper(); + mapper.UseLowerCaseDelimiter('_'); + mapper.IncludeNonPublic = true; + + var obj = CreateModel(); + var doc = mapper.ToDocument(obj); + + var json = JsonSerializer.Serialize(doc); + var nobj = mapper.ToObject(doc); + + Assert.AreEqual(doc["MY-STRING"].AsString, obj.MyString); + Assert.AreEqual(doc["INTERNAL-PROPERTY"].AsString, obj.MyInternalPropertyNamed); + Assert.AreEqual(doc["PRIVATE-PROPERTY"].AsString, obj.GetMyPrivatePropertyNamed()); + Assert.AreEqual(doc["PROTECTED-PROPERTY"].AsString, obj.GetMyProtectedPropertyNamed()); + Assert.AreEqual(obj.MyString, nobj.MyString); + + //Internal + Assert.AreEqual(obj.MyInternalPropertyNamed, nobj.MyInternalPropertyNamed); + Assert.AreEqual(obj.MyInternalPropertySerializable, nobj.MyInternalPropertySerializable); + // Assert.AreEqual(nobj.MyInternalPropertyNotSerializable, null); + //Private + Assert.AreEqual(obj.GetMyPrivatePropertyNamed(), nobj.GetMyPrivatePropertyNamed()); + Assert.AreEqual(obj.GetMyPrivatePropertySerializable(), nobj.GetMyPrivatePropertySerializable()); + // Assert.AreEqual(nobj.GetMyPrivatePropertyNotSerializable(), null); + //protected + Assert.AreEqual(obj.GetMyProtectedPropertyNamed(), nobj.GetMyProtectedPropertyNamed()); + Assert.AreEqual(obj.GetMyProtectedPropertySerializable(), nobj.GetMyProtectedPropertySerializable()); + //Assert.AreEqual(nobj.GetMyProtectedPropertyNotSerializable(), null); + } + } +} diff --git a/UltraLiteDB.Tests/Mapper/Polymorphic_Tests.cs b/UltraLiteDB.Tests/Mapper/Polymorphic_Tests.cs new file mode 100755 index 000000000..bef6ac26d --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Polymorphic_Tests.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class MyBase + { + public int Id { get; set; } + public string Text { get; set; } + } + + public class Descendant1 : MyBase + { + public string Field1 { get; set; } + } + + public class Descendant2 : MyBase + { + public string Field2 { get; set; } + } + + public class Container + { + public Guid Id { get; set; } + public List Bases { get; set; } + } + + #endregion + + [TestClass] + public class Polymorphic_Tests + { + [TestMethod] + public void Simple_Polymorphics() + { + using (var file = new TempFile()) + { + using (var db = new UltraLiteDatabase(file.Filename)) + { + var col = db.GetCollection("col1"); + + col.Insert(new Descendant1() { Id = 1 }); + col.Insert(new Descendant2() { Id = 2 }); + } + + using (var db = new UltraLiteDatabase(file.Filename)) + { + var col = db.GetCollection("col1"); + + var d1 = col.FindById(1); + var d2 = col.FindById(2); + + Assert.AreEqual(typeof(Descendant1), d1.GetType()); + Assert.AreEqual(typeof(Descendant2), d2.GetType()); + } + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Reflection_Getter_Setter_Tests.cs b/UltraLiteDB.Tests/Mapper/Reflection_Getter_Setter_Tests.cs new file mode 100755 index 000000000..2f529fbf4 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Reflection_Getter_Setter_Tests.cs @@ -0,0 +1,177 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Drawing; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class GetterSetterClass + { + public string PublicProperty { get; set; } + internal string InternalProperty { get; set; } + protected string ProtectedProperty { get; set; } + private string PrivateProperty { get; set; } + + public string PublicField; + internal string InternalField; + protected string ProtectedField; + private string PrivateField; + + public string GetProtectedProperty() + { + return ProtectedProperty; + } + + public string GetPrivateProperty() + { + return PrivateProperty; + } + + public void SetProtectedProperty(string value) + { + ProtectedProperty = value; + } + + public void SetPrivateProperty(string value) + { + PrivateProperty = value; + } + + public string GetProtectedField() + { + return ProtectedField; + } + + public string GetPrivateField() + { + return PrivateField; + } + + public void SetProtectedField(string value) + { + ProtectedField = value; + } + + public void SetPrivateField(string value) + { + PrivateField = value; + } + } + + public struct GetterSetterStruct + { + public string PublicProperty { get; set; } + internal string InternalProperty { get; set; } + private string PrivateProperty { get; set; } + + public string PublicField; + internal string InternalField; + private string PrivateField; + + public string GetPrivateProperty() + { + return PrivateProperty; + } + + public void SetPrivateProperty(string value) + { + PrivateProperty = value; + } + + public string GetPrivateField() + { + return PrivateField; + } + + public void SetPrivateField(string value) + { + PrivateField = value; + } + } + + #endregion + + [TestClass] + public class Reflection_Getter_Setter_Tests + { + [TestMethod] + public void Getter_Setter_Classes() + { + var o = new GetterSetterClass + { + PublicProperty = "PublicProperty", + InternalProperty = "InternalProperty", + + PublicField = "PublicField", + InternalField = "InternalField" + }; + + o.SetProtectedProperty("ProtectedProperty"); + o.SetPrivateProperty("PrivateProperty"); + + o.SetProtectedField("ProtectedField"); + o.SetPrivateField("PrivateField"); + + var m = new BsonMapper + { + IncludeFields = true + }; + + m.IncludeNonPublic = true; + + var clone = m.ToObject(m.ToDocument(o)); + + Assert.AreEqual(o.PublicProperty, clone.PublicProperty); + Assert.AreEqual(o.InternalProperty, clone.InternalProperty); + + Assert.AreEqual(o.PublicField, clone.PublicField); + Assert.AreEqual(o.InternalField, clone.InternalField); + + Assert.AreEqual(o.GetProtectedProperty(), clone.GetProtectedProperty()); + Assert.AreEqual(o.GetProtectedField(), clone.GetProtectedField()); + + Assert.AreEqual(o.GetPrivateProperty(), clone.GetPrivateProperty()); + Assert.AreEqual(o.GetPrivateField(), clone.GetPrivateField()); + } + + [TestMethod] + public void Getter_Setter_Structs() + { + var o = new GetterSetterStruct + { + PublicProperty = "PublicProperty", + InternalProperty = "InternalProperty", + + PublicField = "PublicField", + InternalField = "InternalField" + }; + + o.SetPrivateProperty("PrivateProperty"); + + o.SetPrivateField("PrivateField"); + + var m = new BsonMapper + { + IncludeFields = true + }; + + m.IncludeNonPublic = true; + + var clone = m.ToObject(m.ToDocument(o)); + + Assert.AreEqual(o.PublicProperty, clone.PublicProperty); + Assert.AreEqual(o.InternalProperty, clone.InternalProperty); + + Assert.AreEqual(o.PublicField, clone.PublicField); + Assert.AreEqual(o.InternalField, clone.InternalField); + + Assert.AreEqual(o.GetPrivateProperty(), clone.GetPrivateProperty()); + Assert.AreEqual(o.GetPrivateField(), clone.GetPrivateField()); + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/Struct_Tests.cs b/UltraLiteDB.Tests/Mapper/Struct_Tests.cs new file mode 100755 index 000000000..b46edffae --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/Struct_Tests.cs @@ -0,0 +1,51 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public struct StructValue + { + public string Property { get; set; } + } + + public class ContainerValue + { + public Guid Id { get; set; } + public StructValue Struct { get; set; } + } + + #endregion + + [TestClass] + public class Struct_Tests + { + [TestMethod] + public void Struct_Mapper() + { + var mapper = new BsonMapper + { + IncludeFields = true + }; + + var obj = new ContainerValue + { + Id = Guid.NewGuid(), + Struct = new StructValue + { + Property = "PropertyValue" + } + }; + + var doc = mapper.ToDocument(obj); + var nobj = mapper.ToObject(doc); + + Assert.AreEqual(obj.Id, nobj.Id); + Assert.AreEqual(obj.Struct.Property, nobj.Struct.Property); + + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/Mapper/ULongList_Tests.cs b/UltraLiteDB.Tests/Mapper/ULongList_Tests.cs new file mode 100755 index 000000000..4291a8b61 --- /dev/null +++ b/UltraLiteDB.Tests/Mapper/ULongList_Tests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System; + +namespace UltraLiteDB.Tests.Mapper +{ + #region Model + + public class Gang + { + public ObjectId Id { get; set; } + public string Name { get; set; } + public ulong LeaderId { get; set; } + public ulong GuildId { get; set; } + public List Members { get; set; } + public double Wealth { get; set; } = 0.0; + public DateTime Raid { get; set; } = DateTime.UtcNow.AddYears(-1); + } + + #endregion + + [TestClass] + public class ULongList_Tests + { + [TestMethod] + public void ULongList_Mapper() + { + using (var file = new TempFile()) + using (var db = new UltraLiteDatabase(file.Filename)) + { + var col = db.GetCollection(); + + col.Insert(new Gang + { + GuildId = 1, + LeaderId = 2, + Members = new List { 5, 6, 7} + }); + + ulong userId = 5; + ulong guildId = 1; + + Query q = Query.And(Query.EQ("GuildId", guildId), Query.EQ("LeaderId", userId)); + var e = col.Exists(q); + + //Assert.IsTrue(e); + + } + } + } +} \ No newline at end of file diff --git a/UltraLiteDB.Tests/UltraLiteDB.Tests.csproj b/UltraLiteDB.Tests/UltraLiteDB.Tests.csproj new file mode 100755 index 000000000..23a52f05a --- /dev/null +++ b/UltraLiteDB.Tests/UltraLiteDB.Tests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.0 + UltraLiteDB.Tests + UltraLiteDB.Tests + Maurício David + MIT + en-US + false + 1701;1702;1705;1591;0618 + + + + + + + + + + + + + + diff --git a/UltraLiteDB.Tests/Utils/TempFile.cs b/UltraLiteDB.Tests/Utils/TempFile.cs new file mode 100755 index 000000000..c88891247 --- /dev/null +++ b/UltraLiteDB.Tests/Utils/TempFile.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace UltraLiteDB.Tests +{ + public class TempFile : IDisposable + { + private bool _checkIntegrity = false; + + public string Filename { get; private set; } + + public TempFile(string ext = "db", bool checkIntegrity = true) + { + this.Filename = Path.Combine(Path.GetTempPath(), string.Format("test-{0}.{1}", Guid.NewGuid(), ext)); + _checkIntegrity = checkIntegrity; + } + + public void CreateDatafile() + { + using (var s = new FileStream(Filename, System.IO.FileMode.CreateNew)) + { + UltraLiteEngine.CreateDatabase(s); + } + } + + public IDiskService Disk(bool journal = true) + { + return new FileDiskService(Filename, journal); + } + + public IDiskService Disk(FileOptions options) + { + return new FileDiskService(Filename, options); + } + + public string Conn(string connectionString) + { + return "filename=\"" + this.Filename + "\";" + connectionString; + } + + #region Dispose + + private bool _disposed; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~TempFile() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + // free other managed objects that implement + // IDisposable only + } + + // check file integrity + if (_checkIntegrity) + { + this.CheckIntegrity(); + } + + File.Delete(this.Filename); + + _disposed = true; + } + + #endregion + + public long Size + { + get { return new FileInfo(this.Filename).Length; } + } + + public string ReadAsText() + { + return File.ReadAllText(this.Filename); + } + + /// + /// Read all colleciton, indexes and documents inside current datafile + /// Drop per index, per collection and shrink + /// This steps will check/validate all file data + /// + private void CheckIntegrity() + { + using (var db = new UltraLiteEngine(this.Filename)) + { + var cols = db.GetCollectionNames().ToArray(); + + foreach(var col in cols) + { + var indexes = db.GetIndexes(col).ToArray(); + + foreach(var idx in indexes) + { + var q = db.Find(col, Query.All(idx.Field)); + + foreach(var doc in q) + { + // document are ok! + } + + // lets drop this index (if not _id) + if(idx.Field != "_id") + { + db.DropIndex(col, idx.Field); + } + } + + // and drop collection + db.DropCollection(col); + } + + // and now shrink + db.Shrink(); + } + } + + #region LoremIpsum Generator + + public static string LoremIpsum(int minWords, int maxWords, + int minSentences, int maxSentences, + int numParagraphs) + { + var words = new[] { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", + "adipiscing", "elit", "sed", "diam", "nonummy", "nibh", "euismod", + "tincidunt", "ut", "laoreet", "dolore", "magna", "aliquam", "erat" }; + + var rand = new Random(DateTime.Now.Millisecond); + var numSentences = rand.Next(maxSentences - minSentences) + minSentences + 1; + var numWords = rand.Next(maxWords - minWords) + minWords + 1; + + var result = new StringBuilder(); + + for (int p = 0; p < numParagraphs; p++) + { + for (int s = 0; s < numSentences; s++) + { + for (int w = 0; w < numWords; w++) + { + if (w > 0) { result.Append(" "); } + result.Append(words[rand.Next(words.Length)]); + } + result.Append(". "); + } + result.AppendLine(); + } + + return result.ToString(); + } + + #endregion + } +} \ No newline at end of file diff --git a/UltraLiteDB.sln b/UltraLiteDB.sln index 73789d91b..47ade1a6b 100644 --- a/UltraLiteDB.sln +++ b/UltraLiteDB.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.26730.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UltraLiteDB", "UltraLiteDB\UltraLiteDB.csproj", "{9497DA19-1FCA-4C2E-A1AB-8DFAACBC76E1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteDB.Tests", "UltraLiteDB.Tests\UltraLiteDB.Tests.csproj", "{DC3C8B07-0FB3-45B3-BE60-04609DBC0208}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {9497DA19-1FCA-4C2E-A1AB-8DFAACBC76E1}.Debug|Any CPU.Build.0 = Debug|Any CPU {9497DA19-1FCA-4C2E-A1AB-8DFAACBC76E1}.Release|Any CPU.ActiveCfg = Release|Any CPU {9497DA19-1FCA-4C2E-A1AB-8DFAACBC76E1}.Release|Any CPU.Build.0 = Release|Any CPU + {DC3C8B07-0FB3-45B3-BE60-04609DBC0208}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC3C8B07-0FB3-45B3-BE60-04609DBC0208}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC3C8B07-0FB3-45B3-BE60-04609DBC0208}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC3C8B07-0FB3-45B3-BE60-04609DBC0208}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE