public void Attachments_Stream() { var filePath = Path.GetTempFileName(); try { using (var test = new TestDatabase()) { var db = test.Database; var doc = db.CreateDocument(); var unsaved = doc.CreateRevision(); var output = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); output.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); output.Position = 0; unsaved.SetAttachment("test", "application/data", output); var saved = unsaved.Save(); output.Close(); var attachment = saved.GetAttachment("test"); using (var input = attachment.ContentStream) { var bytes = new byte[10]; Assert.Equal(10, input.Read(bytes, 0, 10)); Assert.Equal(0, input.Read(bytes, 0, 10)); var file = (FileStream)input; } } } finally { File.Delete(filePath); } }
public void Basic() { using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetBinderDocument <TestBinder>("1"); doc.Content.String = "FOO"; doc.Save(); doc = db.GetBinderDocument <TestBinder>("1"); var changed = false; var prop = string.Empty; var propList = new List <string>(); doc.Changed += (s, a) => { changed = true; }; doc.PropertyChanged += (s, a) => { prop = a.PropertyName; propList.Add(a.PropertyName); }; // Verify that we start out with no attachments. Assert.Equal("FOO", doc.Content.String); Assert.Null(doc.TestImage1); Assert.Null(doc.GetAttachment("TestImage1")); Assert.Null(doc.GetTestImage1()); Assert.Null(doc.TestImage2); Assert.Null(doc.GetAttachment("test_image2")); Assert.Null(doc.GetTestImage2()); doc.Revise(); Assert.Equal("FOO", doc.Content.String); Assert.Null(doc.TestImage1); Assert.Null(doc.GetAttachment("TestImage1")); Assert.Null(doc.GetTestImage1()); Assert.Null(doc.TestImage2); Assert.Null(doc.GetAttachment("test_image2")); Assert.Null(doc.GetTestImage2()); // Verify that we see property change notifications when we set // attachments via byte arrays and streams and also that the // attachment properties return a path to the attachment file. prop = null; changed = false; doc.SetTestImage1(new byte[] { 0, 1, 2, 3, 4 }, "test-content"); Assert.Equal("TestImage1", prop); Assert.True(changed); Assert.True(File.Exists(doc.TestImage1)); Assert.NotNull(doc.GetAttachment("TestImage1")); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, File.ReadAllBytes(doc.TestImage1)); prop = null; changed = false; doc.SetTestImage2(new MemoryStream(new byte[] { 5, 6, 7, 8, 9 }), "test-content"); Assert.Equal("TestImage2", prop); Assert.True(changed); Assert.True(File.Exists(doc.TestImage2)); Assert.NotNull(doc.GetAttachment("test_image2")); Assert.Equal(new byte[] { 5, 6, 7, 8, 9 }, File.ReadAllBytes(doc.TestImage2)); // Verify that we see attachment property change notifications when we // persist the document, confirm that the attachment file paths changed // and the temporary files no longer exist. var tempImage1 = doc.TestImage1; var tempImage2 = doc.TestImage2; propList.Clear(); doc.Save(); Assert.True(propList.Count(p => p == "TestImage1") > 0); Assert.True(propList.Count(p => p == "TestImage2") > 0); Assert.NotEqual(tempImage1, doc.TestImage1); Assert.NotEqual(tempImage2, doc.TestImage2); Assert.False(File.Exists(tempImage1)); Assert.False(File.Exists(tempImage2)); Assert.True(File.Exists(doc.TestImage1)); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, File.ReadAllBytes(doc.TestImage1)); Assert.True(File.Exists(doc.TestImage2)); Assert.Equal(new byte[] { 5, 6, 7, 8, 9 }, File.ReadAllBytes(doc.TestImage2)); // Reload the document and verify. doc = db.GetBinderDocument <TestBinder>("1"); doc.Changed += (s, a) => { changed = true; }; doc.PropertyChanged += (s, a) => { prop = a.PropertyName; propList.Add(a.PropertyName); }; Assert.NotNull(doc.TestImage1); Assert.True(File.Exists(doc.TestImage1)); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, File.ReadAllBytes(doc.TestImage1)); Assert.NotNull(doc.TestImage2); Assert.True(File.Exists(doc.TestImage2)); Assert.Equal(new byte[] { 5, 6, 7, 8, 9 }, File.ReadAllBytes(doc.TestImage2)); // Verify that attachment removal works as expected. doc.Revise(); prop = null; propList.Clear(); changed = false; Assert.True(File.Exists(doc.TestImage1)); Assert.True(File.Exists(doc.TestImage2)); doc.RemoveTestImage1(); Assert.True(changed); Assert.Equal("TestImage1", prop); doc.Save(); Assert.Null(doc.TestImage1); Assert.Null(doc.GetTestImage1()); Assert.True(File.Exists(doc.TestImage2)); Assert.NotNull(doc.GetTestImage2()); // Now remove the second attachment that has a custom name // and verify. doc.Revise(); prop = null; propList.Clear(); changed = false; Assert.True(File.Exists(doc.TestImage2)); doc.RemoveTestImage2(); Assert.True(changed); Assert.Equal("TestImage2", prop); doc.Save(); Assert.Null(doc.TestImage1); Assert.Null(doc.GetTestImage1()); Assert.Null(doc.TestImage2); Assert.Null(doc.GetTestImage2()); } }
public void DocumentChange() { // Verify that we see the attachment property change notifications // when we see document change notifications. using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetBinderDocument <TestBinder>("1"); var propList = new List <string>(); doc.PropertyChanged += (s, a) => { propList.Add(a.PropertyName); }; doc.Save(); var docCopy = db.GetBinderDocument <TestBinder>("1"); Assert.Empty(propList); // Add a new attachment. docCopy.Revise(); docCopy.SetTestImage1(new byte[] { 0, 1, 2, 3, 4 }); Assert.Empty(propList); // Haven't saved anything yet docCopy.Save(); Assert.Single(propList); Assert.Equal("TestImage1", propList[0]); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, File.ReadAllBytes(doc.TestImage1)); // Update an existing attachment propList.Clear(); docCopy.Revise(); docCopy.SetTestImage1(new byte[] { 5, 6, 7, 8, 9 }); Assert.Empty(propList); // Haven't saved anything yet docCopy.Save(); Assert.Single(propList); Assert.Equal("TestImage1", propList[0]); Assert.Equal(new byte[] { 5, 6, 7, 8, 9 }, File.ReadAllBytes(doc.TestImage1)); // Add a second attachment propList.Clear(); docCopy.Revise(); docCopy.SetTestImage2(new byte[] { 9, 8, 7, 6, 5 }); Assert.Empty(propList); // Haven't saved anything yet docCopy.Save(); Assert.Single(propList); Assert.Equal("TestImage2", propList[0]); Assert.Equal(new byte[] { 9, 8, 7, 6, 5 }, File.ReadAllBytes(doc.TestImage2)); // Delete both attachments propList.Clear(); docCopy.Revise(); docCopy.RemoveTestImage1(); docCopy.RemoveTestImage2(); Assert.Empty(propList); // Haven't saved anything yet docCopy.Save(); Assert.Equal(2, propList.Count); Assert.Contains("TestImage1", propList); Assert.Contains("TestImage2", propList); Assert.Null(doc.TestImage1); Assert.Null(doc.TestImage2); } }
public void Basic() { using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetEntityDocument <TestEntity>("1"); var prop = string.Empty; var changed = false; doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; Assert.Null(doc.Content.ChildList); changed = false; prop = null; //--------------------- // Assign a collection. doc.Content.ChildList = new TestEntity[] { new TestEntity() { String = "1" }, new TestEntity() { String = "2" } }; Assert.True(changed); Assert.Equal("ChildList", prop); Assert.NotNull(doc.Content.ChildList); Assert.True(Match(new string[] { "1", "2" }, doc.Content.ChildList)); //--------------------- // Persist and verify doc.Save(); doc = db.GetEntityDocument <TestEntity>("1"); Assert.NotNull(doc.Content.ChildList); Assert.Equal("1", doc.Content.ChildList[0].String); Assert.Equal("2", doc.Content.ChildList[1].String); Assert.True(Match(new string[] { "1", "2" }, doc.Content.ChildList)); //--------------------- // Assign element values then persist and verify. doc.Revise(); doc.Content.ChildList[0].String = "AAA"; doc.Content.ChildList[1] = null; Assert.Equal("AAA", doc.Content.ChildList[0].String); Assert.Null(doc.Content.ChildList[1]); doc.Save(); doc = db.GetEntityDocument <TestEntity>("1"); Assert.Equal("AAA", doc.Content.ChildList[0].String); Assert.Null(doc.Content.ChildList[1]); //--------------------- // Assign NULL. doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; doc.Revise(); doc.Content.ChildList = null; Assert.True(changed); Assert.Equal("ChildList", prop); Assert.Null(doc.Content.ChildList); doc.Save(); doc = db.GetEntityDocument <TestEntity>("1"); Assert.Null(doc.Content.ChildList); } }
public void Operations() { // Verify that entity list operations work and also raise the correct // change events. using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetEntityDocument <TestEntity>("1"); var prop = string.Empty; var changed = false; var collectionChanged = false; doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; Assert.Null(doc.Content.ChildList); //--------------------- // Assignment changed = false; prop = null; var item1 = new TestEntity() { String = "1" }; var item2 = new TestEntity() { String = "2" }; doc.Content.ChildList = new TestEntity[] { item1, item2 }; Assert.True(changed); Assert.Equal("ChildList", prop); Assert.NotNull(doc.Content.ChildList); Assert.True(Match(new string[] { "1", "2" }, doc.Content.ChildList)); Assert.Equal(2, doc.Content.ChildList.Count); //--------------------- // IndexOf changed = false; prop = null; Assert.Equal(0, doc.Content.ChildList.IndexOf(item1)); Assert.Equal(1, doc.Content.ChildList.IndexOf(item2)); Assert.Equal(-1, doc.Content.ChildList.IndexOf(new TestEntity())); Assert.False(changed); Assert.Null(prop); //--------------------- // Contains changed = false; prop = null; Assert.True(doc.Content.ChildList.Contains(item1)); Assert.True(doc.Content.ChildList.Contains(item2)); Assert.False(doc.Content.ChildList.Contains(new TestEntity())); Assert.False(changed); Assert.Null(prop); //--------------------- // Indexing collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.Equal("1", doc.Content.ChildList[0].String); Assert.Equal("2", doc.Content.ChildList[1].String); doc.Content.ChildList[0] = new TestEntity() { String = "one" }; Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal("one", doc.Content.ChildList[0].String); Assert.Equal("2", doc.Content.ChildList[1].String); Assert.True(Match(new string[] { "one", "2" }, doc.Content.ChildList)); //--------------------- // Insert collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; doc.Content.ChildList.Insert(0, new TestEntity() { String = "zero" }); doc.Content.ChildList.Insert(3, new TestEntity() { String = "three" }); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(4, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "zero", "one", "2", "three" }, doc.Content.ChildList)); //--------------------- // Remove collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.True(doc.Content.ChildList.Remove(doc.Content.ChildList[3])); Assert.False(doc.Content.ChildList.Remove(new TestEntity() { String = "four" })); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "zero", "one", "2" }, doc.Content.ChildList)); //--------------------- // RemoveAt collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; doc.Content.ChildList.RemoveAt(2); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(2, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "zero", "one" }, doc.Content.ChildList)); //--------------------- // Add collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; doc.Content.ChildList.Add(new TestEntity() { String = "two" }); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "zero", "one", "two" }, doc.Content.ChildList)); //--------------------- // CopyTo collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; var copy = new TestEntity[3]; doc.Content.ChildList.CopyTo(copy, 0); Assert.True(Match(new string[] { "zero", "one", "two" }, copy)); Assert.False(changed); Assert.False(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "zero", "one", "two" }, doc.Content.ChildList)); //--------------------- // Clear collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.ChildList).CollectionChanged += (s, a) => { collectionChanged = true; }; doc.Content.ChildList.Clear(); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(0, doc.Content.ChildList.Count); Assert.True(Match(new string[0], doc.Content.ChildList)); //--------------------- // Ensure that the array changes are persisted. doc.Content.ChildList.Add(new TestEntity() { String = "a" }); doc.Content.ChildList.Add(new TestEntity() { String = "b" }); doc.Content.ChildList.Add(new TestEntity() { String = "c" }); Assert.True(changed); Assert.Null(prop); Assert.Equal(3, doc.Content.ChildList.Count); Assert.True(Match(new string[] { "a", "b", "c" }, doc.Content.ChildList)); doc.Save(); doc = db.GetEntityDocument <TestEntity>("1"); Assert.NotNull(doc.Content.ChildList); Assert.True(Match(new string[] { "a", "b", "c" }, doc.Content.ChildList)); //--------------------- // Test enumeration doc.Revise(); doc.Content.ChildList.Clear(); doc.Content.ChildList.Add(new TestEntity() { String = "a" }); doc.Content.ChildList.Add(new TestEntity() { String = "b" }); doc.Content.ChildList.Add(new TestEntity() { String = "c" }); doc.Content.ChildList.Add(null); doc.Save(); var list = new List <TestEntity>(); foreach (var element in doc.Content.ChildList) { list.Add(element); } Assert.Equal(4, list.Count); Assert.Equal("a", list[0].String); Assert.Equal("b", list[1].String); Assert.Equal("c", list[2].String); Assert.Null(list[3]); //--------------------- // Test NULL list values. doc = db.GetEntityDocument <TestEntity>("2"); Assert.Null(doc.Content.ChildList); doc.Content.ChildList = new TestEntity[] { null, new TestEntity() { String = "one" } }; Assert.Equal(2, doc.Content.ChildList.Count); Assert.Null(doc.Content.ChildList[0]); Assert.Equal("one", doc.Content.ChildList[1].String); doc.Save(); doc = db.GetEntityDocument <TestEntity>("2"); Assert.Equal(2, doc.Content.ChildList.Count); Assert.Null(doc.Content.ChildList[0]); Assert.Equal("one", doc.Content.ChildList[1].String); //--------------------- // Verify that changes to property of a list item bubble up. doc.Revise(); doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; changed = false; doc.Content.ChildList[1].Int = 100; Assert.True(changed); //--------------------- // Verify that list items are detached when they // replaced so that they will no longer modify the // document. var item = doc.Content.ChildList[1]; changed = false; doc.Content.ChildList[1].Int = 10; Assert.True(changed); changed = false; doc.Content.ChildList[1] = null; Assert.True(changed); changed = false; item.Int = 20; Assert.False(changed); doc.Content.ChildList.Add(item); changed = false; item.Int = 30; Assert.True(changed); doc.Content.ChildList.Remove(item); changed = false; item.Int = 40; Assert.False(changed); doc.Content.ChildList.Add(item); changed = false; item.Int = 50; Assert.True(changed); doc.Content.ChildList.RemoveAt(doc.Content.ChildList.Count - 1); changed = false; item.Int = 60; Assert.False(changed); //--------------------- // Verify that list items are detached when the // list is cleared so that they will no longer // modify the document. item1 = new TestEntity() { String = "one" }; item2 = new TestEntity() { String = "two" }; doc.Content.ChildList = new TestEntity[] { item1, item2, null }; changed = false; doc.Content.ChildList[1].Int = 10; Assert.True(changed); changed = false; doc.Content.ChildList.Clear(); Assert.Equal(0, doc.Content.ChildList.Count); Assert.True(changed); changed = false; item1.Int = 20; Assert.False(changed); changed = false; item2.Int = 30; Assert.False(changed); doc.Cancel(); } }
public void KnownTypes() { // Verify that we can read/write derived entities with known types. using (var test = new TestDatabase()) { var db = test.Database; //------------------------------- var productDoc = db.GetEntityDocument <Product>("product"); productDoc.Content.Name = "Computer"; Assert.Equal(ProductTypes.Product, productDoc.Content.ProductType); Assert.Equal("product", productDoc.Type); Assert.Equal("Computer", productDoc.Content.Name); productDoc.Save(); productDoc = db.GetEntityDocument <Product>("product"); Assert.Equal(ProductTypes.Product, productDoc.Content.ProductType); Assert.Equal("product", productDoc.Type); Assert.Equal("Computer", productDoc.Content.Name); //------------------------------- var candyDoc = db.GetEntityDocument <Candy>("candy"); candyDoc.Content.Name = "candy"; candyDoc.Content.Calories = 100; Assert.Equal(ProductTypes.Candy, candyDoc.Content.ProductType); Assert.Equal("product.candy", candyDoc.Type); Assert.Equal("candy", candyDoc.Content.Name); Assert.Equal(100, candyDoc.Content.Calories); candyDoc.Save(); candyDoc = db.GetEntityDocument <Candy>("candy"); Assert.Equal(ProductTypes.Candy, candyDoc.Content.ProductType); Assert.Equal("product.candy", candyDoc.Type); Assert.Equal("candy", candyDoc.Content.Name); Assert.Equal(100, candyDoc.Content.Calories); //------------------------------- var gumDoc = db.GetEntityDocument <Gum>("gum"); gumDoc.Content.Name = "gum"; gumDoc.Content.Calories = 1; gumDoc.Content.Flavor = "spearmint"; Assert.Equal(ProductTypes.Gum, gumDoc.Content.ProductType); Assert.Equal("product.candy.gum", gumDoc.Type); Assert.Equal("gum", gumDoc.Content.Name); Assert.Equal(1, gumDoc.Content.Calories); Assert.Equal("spearmint", gumDoc.Content.Flavor); gumDoc.Save(); gumDoc = db.GetEntityDocument <Gum>("gum"); Assert.Equal(ProductTypes.Gum, gumDoc.Content.ProductType); Assert.Equal("product.candy.gum", gumDoc.Type); Assert.Equal("gum", gumDoc.Content.Name); Assert.Equal(1, gumDoc.Content.Calories); Assert.Equal("spearmint", gumDoc.Content.Flavor); //------------------------------- // Read [Candy] as [Product] productDoc = db.GetEntityDocument <Product>("candy"); Assert.Equal("product.candy", productDoc.Type); Assert.Equal(ProductTypes.Candy, productDoc.Content.ProductType); Assert.Equal("candy", candyDoc.Content.Name); var candy = (Candy)productDoc.Content; Assert.Equal("product.candy", productDoc.Type); Assert.Equal(ProductTypes.Candy, candy.ProductType); Assert.Equal("candy", candy.Name); Assert.Equal(100, candy.Calories); //------------------------------- // Read [Gum] as [Product] productDoc = db.GetEntityDocument <Product>("gum"); Assert.Equal("product.candy.gum", productDoc.Type); Assert.Equal(ProductTypes.Gum, productDoc.Content.ProductType); Assert.Equal("gum", productDoc.Content.Name); var gum = (Gum)productDoc.Content; Assert.Equal("product.candy.gum", gumDoc.Type); Assert.Equal(ProductTypes.Gum, gum.ProductType); Assert.Equal("gum", gum.Name); Assert.Equal(1, gum.Calories); Assert.Equal("spearmint", gum.Flavor); //------------------------------- // Read [Gum] as [Candy] candyDoc = db.GetEntityDocument <Candy>("gum"); Assert.Equal("product.candy.gum", candyDoc.Type); Assert.Equal(ProductTypes.Gum, productDoc.Content.ProductType); Assert.Equal("gum", candyDoc.Content.Name); gum = (Gum)productDoc.Content; Assert.Equal("product.candy.gum", gumDoc.Type); Assert.Equal(ProductTypes.Gum, gum.ProductType); Assert.Equal("gum", gum.Name); Assert.Equal(1, gum.Calories); Assert.Equal("spearmint", gum.Flavor); } }
public void UnknownTypes() { // Verify that we can we can read an entity with an unknown derived type. using (var test = new TestDatabase()) { var db = test.Database; //------------------------------- // Create some documents var productDoc = db.GetEntityDocument <Product>("product"); productDoc.Content.Name = "Computer"; productDoc.Save(); var candyDoc = db.GetEntityDocument <Candy>("candy"); candyDoc.Content.Name = "candy"; candyDoc.Content.Calories = 100; candyDoc.Save(); candyDoc = db.GetEntityDocument <Candy>("candy"); var gumDoc = db.GetEntityDocument <Gum>("gum"); gumDoc.Content.Name = "gum"; gumDoc.Content.Calories = 1; gumDoc.Content.Flavor = "spearmint"; gumDoc.Save(); gumDoc = db.GetEntityDocument <Gum>("gum"); //------------------------------- // We're going to munge the [gum] document entity's type path // to simulate an unknown candy type. Changing: // // FROM: // [product.candy.gum:product.candy:product] // // TO: // [product.candy.unknown:product.candy:product] // // $hack(jeff.lill): // // This makes assumptions about how entity type paths are formatted. var doc = db.GetDocument("gum"); var unsaved = doc.CreateRevision(); var content = (JObject)unsaved.Properties[NeonPropertyNames.Content]; var typePath = (string)content[DynamicEntity.EntityTypePathName]; typePath = typePath.Replace("product.candy.gum:", "product.candy.unknown:"); content = (JObject)content.DeepClone(); content[DynamicEntity.EntityTypePathName] = typePath; unsaved.Properties[NeonPropertyNames.Content] = content; unsaved.Save(); //------------------------------- // Read [Unknown] as [Product] productDoc = db.GetEntityDocument <Product>("gum"); Assert.Equal(ProductTypes.Gum, productDoc.Content.ProductType); Assert.Equal("gum", productDoc.Content.Name); var candy = (Candy)productDoc.Content; Assert.Equal(ProductTypes.Gum, candy.ProductType); Assert.Equal("gum", candy.Name); Assert.Equal(1, candy.Calories); //------------------------------- // Read [Unknown] as [Candy] candyDoc = db.GetEntityDocument <Candy>("gum"); Assert.Equal(ProductTypes.Gum, productDoc.Content.ProductType); Assert.Equal("gum", candyDoc.Content.Name); Assert.Equal(1, candyDoc.Content.Calories); } }
public void Subentities() { using (var test = new TestDatabase()) { var db = test.Database; //------------------------------- var catalogDoc = db.GetEntityDocument <Catalog>("catalog"); catalogDoc.Content.TopSeller = new CandyBar() { Name = "BabyRuth", Calories = 150, HasNuts = true }; catalogDoc.Content.Products = new Product[] { new CandyBar() { Name = "BabyRuth", Calories = 150, HasNuts = true }, new Gum() { Name = "Juicyfruit", Calories = 50, Flavor = "Spearmint" }, new Product() { Name = "Pepsi Cola" } }; catalogDoc.Save(); catalogDoc = db.GetEntityDocument <Catalog>("catalog"); Assert.Equal("CATALOG", catalogDoc.Type); Assert.Equal("CATALOG", catalogDoc.Content.EntityType); Assert.Equal(ProductTypes.CandyBar, catalogDoc.Content.TopSeller.ProductType); Assert.Equal("BabyRuth", ((CandyBar)catalogDoc.Content.TopSeller).Name); Assert.Equal(150, ((CandyBar)catalogDoc.Content.TopSeller).Calories); Assert.True(((CandyBar)catalogDoc.Content.TopSeller).HasNuts); Assert.Equal(3, catalogDoc.Content.Products.Count); Assert.Equal(ProductTypes.CandyBar, catalogDoc.Content.Products[0].ProductType); Assert.Equal("BabyRuth", ((CandyBar)catalogDoc.Content.Products[0]).Name); Assert.Equal(150, ((CandyBar)catalogDoc.Content.Products[0]).Calories); Assert.True(((CandyBar)catalogDoc.Content.Products[0]).HasNuts); Assert.Equal(ProductTypes.Gum, catalogDoc.Content.Products[1].ProductType); Assert.Equal("Juicyfruit", ((Gum)catalogDoc.Content.Products[1]).Name); Assert.Equal(50, ((Gum)catalogDoc.Content.Products[1]).Calories); Assert.Equal("Spearmint", ((Gum)catalogDoc.Content.Products[1]).Flavor); Assert.Equal(ProductTypes.Product, catalogDoc.Content.Products[2].ProductType); Assert.Equal("Pepsi Cola", catalogDoc.Content.Products[2].Name); } }
public void EntityQuery() { // Test synchronous entity queries. using (var test = new TestDatabase()) { var db = test.Database; var view = test.Database.GetView("view"); view.SetMap <TestEntity>( (doc, emit) => { emit(doc.Content.String, doc); }, "1"); for (int i = 0; i < 10; i++) { var doc = db.CreateEntityDocument <TestEntity>(); doc.Content.String = $"Jeff-{i}"; doc.Content.Int = i; doc.Save(); } // Verify that we can query for all of the view rows. var query = view.CreateQuery <TestEntity>(); var results = query.Run().ToList(); Assert.Equal(10, results.Count); for (var i = 0; i < 10; i++) { var row = results[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } // Verify that we can query for a specific key. query.Keys = new object[] { "Jeff-5" }; results = query.Run().ToList(); Assert.Single(results); Assert.Equal($"Jeff-5", results[0].Key); Assert.Equal($"Jeff-5", results[0].KeyString); Assert.Equal($"Jeff-5", results[0].Document.Content.String); Assert.Equal(5, results[0].Document.Content.Int); query.Keys = null; // Test post filters. query.PostFilter = row => { return(row.Document.Content.Int < 5); }; results = query.Run().ToList(); Assert.Equal(5, results.Count); for (var i = 0; i < 5; i++) { var row = results[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } } }
public async Task EntityLiveQuery_PostFilter() { // Verify that post filters work for live queries. using (var test = new TestDatabase()) { var db = test.Database; var view = test.Database.GetView("view"); view.SetMap <TestEntity>( (doc, emit) => { emit(doc.Content.String, doc); }, "1"); for (int i = 0; i < 10; i++) { var doc = db.CreateEntityDocument <TestEntity>(); doc.Content.String = $"Jeff-{i}"; doc.Content.Int = i; doc.Save(); } // Create a live query with a post filter. var query = view.CreateQuery <TestEntity>(); query.PostFilter = row => { return(row.Document.Content.Int < 5); }; var liveQuery = query.ToLiveQuery(); // Wait for the initial query to complete. await liveQuery.WaitForRowsAsync(); Assert.Equal(5, liveQuery.Count); for (var i = 0; i < 5; i++) { var row = liveQuery[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } // Remove the 5th document and verify that we see the change. var fifthDoc = db.GetExistingEntityDocument <TestEntity>(liveQuery[4].Document.Id); fifthDoc.Delete(); NeonHelper.WaitFor(() => liveQuery.Count == 4, TimeSpan.FromSeconds(10)); Assert.Equal(4, liveQuery.Count); for (var i = 0; i < 4; i++) { var row = liveQuery[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } } }
public async Task EntityLiveQuery() { // Test live entity queries. using (var test = new TestDatabase()) { var db = test.Database; var view = test.Database.GetView("view"); view.SetMap <TestEntity>( (doc, emit) => { emit(doc.Content.String, doc); }, "1"); for (int i = 0; i < 5; i++) { var doc = db.CreateEntityDocument <TestEntity>(); doc.Content.String = $"Jeff-{i}"; doc.Content.Int = i; doc.Save(); } // Create a live query. var liveQuery = view.CreateQuery <TestEntity>().ToLiveQuery(); // Wait for the initial query to complete. await liveQuery.WaitForRowsAsync(); Assert.Equal(5, liveQuery.Count); for (var i = 0; i < 5; i++) { var row = liveQuery[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } // Add a sixth document and verify that we see the change. var sixthDoc = db.CreateEntityDocument <TestEntity>(); sixthDoc.Content.String = $"Jeff-5"; sixthDoc.Content.Int = 5; sixthDoc.Save(); NeonHelper.WaitFor(() => liveQuery.Count == 6, TimeSpan.FromSeconds(10)); Assert.Equal(6, liveQuery.Count); for (var i = 0; i < 6; i++) { var row = liveQuery[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } // Delete the 6th document and verify that the query updates. sixthDoc.Delete(); NeonHelper.WaitFor(() => liveQuery.Count == 5, TimeSpan.FromSeconds(10)); Assert.Equal(5, liveQuery.Count); for (var i = 0; i < 5; i++) { var row = liveQuery[i]; Assert.Equal($"Jeff-{i}", row.Key); Assert.Equal($"Jeff-{i}", row.KeyString); Assert.Equal($"Jeff-{i}", row.Document.Content.String); Assert.Equal(i, row.Document.Content.Int); } } }
public void Basic() { using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetEntityDocument <TestEntity>("0"); var prop = string.Empty; var changed = false; doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; Assert.Null(doc.Content.LinkList); changed = false; prop = null; //--------------------- // Assign a collection of linkable entities. var doc1 = db.GetEntityDocument <TestEntity>("1"); var doc2 = db.GetEntityDocument <TestEntity>("2"); doc1.Content.String = "1"; doc2.Content.String = "2"; doc1.Save(); doc2.Save(); doc.Content.LinkList = new TestEntity[] { doc1.Content, doc2.Content }; Assert.True(changed); Assert.Equal("LinkList", prop); Assert.NotNull(doc.Content.LinkList); Assert.True(Match(new string[] { "1", "2" }, doc.Content.LinkList)); //--------------------- // Persist and verify doc.Save(); doc = db.GetEntityDocument <TestEntity>("0"); Assert.NotNull(doc.Content.LinkList); Assert.Equal("1", doc.Content.LinkList[0].String); Assert.Equal("2", doc.Content.LinkList[1].String); Assert.True(Match(new string[] { "1", "2" }, doc.Content.LinkList)); //--------------------- // Assign NULL. doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; doc.Revise(); doc.Content.LinkList = null; Assert.True(changed); Assert.Equal("LinkList", prop); Assert.Null(doc.Content.LinkList); doc.Save(); doc = db.GetEntityDocument <TestEntity>("1"); Assert.Null(doc.Content.LinkList); } }
public void Operations() { // Verify that entity link list operations work and also raise the correct // change events. using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetEntityDocument <TestEntity>("0"); var prop = string.Empty; var changed = false; var collectionChanged = false; doc.Changed += (s, a) => { changed = true; }; doc.Content.PropertyChanged += (s, a) => { prop = a.PropertyName; }; Assert.Null(doc.Content.LinkList); //--------------------- // Assignment var doc1 = db.GetEntityDocument <TestEntity>("1"); var doc2 = db.GetEntityDocument <TestEntity>("2"); var doc3 = db.GetEntityDocument <TestEntity>("3"); doc1.Content.String = "1"; doc2.Content.String = "2"; doc3.Content.String = "3"; doc1.Save(); doc2.Save(); doc3.Save(); changed = false; prop = null; var item1 = doc1.Content; var item2 = doc2.Content; var item3 = doc3.Content; doc.Content.LinkList = new TestEntity[] { item1, item2 }; Assert.True(changed); Assert.Equal("LinkList", prop); Assert.NotNull(doc.Content.LinkList); Assert.True(Match(new string[] { "1", "2" }, doc.Content.LinkList)); Assert.Equal(2, doc.Content.LinkList.Count); //--------------------- // IndexOf collectionChanged = false; changed = false; prop = null; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.Equal(0, doc.Content.LinkList.IndexOf(item1)); Assert.Equal(1, doc.Content.LinkList.IndexOf(item2)); Assert.Equal(-1, doc.Content.LinkList.IndexOf(item3)); Assert.Equal(-1, doc.Content.LinkList.IndexOf(null)); Assert.Throws <ArgumentException>(() => doc.Content.LinkList.IndexOf(new TestEntity())); Assert.False(changed); Assert.False(collectionChanged); Assert.Null(prop); //--------------------- // Contains ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.True(doc.Content.LinkList.Contains(item1)); Assert.True(doc.Content.LinkList.Contains(item2)); Assert.False(doc.Content.LinkList.Contains(item3)); Assert.Throws <ArgumentException>(() => doc.Content.LinkList.Contains(new TestEntity())); Assert.False(changed); Assert.False(collectionChanged); Assert.Null(prop); //--------------------- // Indexing ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.Equal("1", doc.Content.LinkList[0].String); Assert.Equal("2", doc.Content.LinkList[1].String); doc.Content.LinkList[0] = item3; Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal("3", doc.Content.LinkList[0].String); Assert.Equal("2", doc.Content.LinkList[1].String); Assert.True(Match(new string[] { "3", "2" }, doc.Content.LinkList)); doc.Content.LinkList[0] = null; Assert.Null(doc.Content.LinkList[0]); Assert.Throws <ArgumentException>(() => doc.Content.LinkList[0] = new TestEntity()); //--------------------- // Insert doc.Content.LinkList = new TestEntity[] { item1, item2 }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; prop = null; changed = false; collectionChanged = false; doc.Content.LinkList.Insert(0, item3); doc.Content.LinkList.Insert(3, null); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(4, doc.Content.LinkList.Count); Assert.Equal("3", doc.Content.LinkList[0].String); Assert.Equal("1", doc.Content.LinkList[1].String); Assert.Equal("2", doc.Content.LinkList[2].String); Assert.Null(doc.Content.LinkList[3]); Assert.Throws <ArgumentException>(() => doc.Content.LinkList.Insert(4, new TestEntity())); //--------------------- // Remove doc.Content.LinkList = new TestEntity[] { item1, item2 }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; prop = null; changed = false; collectionChanged = false; Assert.True(doc.Content.LinkList.Remove(item1)); Assert.False(doc.Content.LinkList.Remove(item3)); Assert.False(doc.Content.LinkList.Remove(null)); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(1, doc.Content.LinkList.Count); Assert.True(Match(new string[] { "2" }, doc.Content.LinkList)); Assert.Throws <ArgumentException>(() => doc.Content.LinkList.Remove(new TestEntity())); //--------------------- // RemoveAt doc.Content.LinkList = new TestEntity[] { item1, item2 }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; prop = null; changed = false; collectionChanged = false; doc.Content.LinkList.RemoveAt(1); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(1, doc.Content.LinkList.Count); Assert.True(Match(new string[] { "1" }, doc.Content.LinkList)); //--------------------- // Add doc.Content.LinkList = new TestEntity[] { item1, item2 }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; prop = null; changed = false; collectionChanged = false; doc.Content.LinkList.Add(item3); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.LinkList.Count); Assert.True(Match(new string[] { "1", "2", "3" }, doc.Content.LinkList)); doc.Content.LinkList.Add(null); Assert.Equal(4, doc.Content.LinkList.Count); Assert.Null(doc.Content.LinkList[3]); Assert.Throws <ArgumentException>(() => doc.Content.LinkList.Add(new TestEntity())); //--------------------- // CopyTo doc.Content.LinkList = new TestEntity[] { item1, item2, null }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; prop = null; changed = false; collectionChanged = false; var copy = new TestEntity[3]; doc.Content.LinkList.CopyTo(copy, 0); Assert.Equal("1", copy[0].String); Assert.Equal("2", copy[1].String); Assert.Null(copy[2]); Assert.False(changed); Assert.False(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.LinkList.Count); Assert.Equal("1", doc.Content.LinkList[0].String); Assert.Equal("2", doc.Content.LinkList[1].String); Assert.Null(doc.Content.LinkList[2]); //--------------------- // Clear doc.Content.LinkList = new TestEntity[] { item1, item2 }; ((INotifyCollectionChanged)doc.Content.LinkList).CollectionChanged += (s, a) => { collectionChanged = true; }; Assert.Equal(2, doc.Content.LinkList.Count); prop = null; changed = false; collectionChanged = false; doc.Content.LinkList.Clear(); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(0, doc.Content.LinkList.Count); Assert.True(Match(new string[0], doc.Content.LinkList)); //--------------------- // Ensure that the array changes are persisted. prop = null; changed = false; collectionChanged = false; doc.Content.LinkList.Clear(); doc.Content.LinkList.Add(item1); doc.Content.LinkList.Add(null); doc.Content.LinkList.Add(item3); Assert.True(changed); Assert.True(collectionChanged); Assert.Null(prop); Assert.Equal(3, doc.Content.LinkList.Count); Assert.Equal("1", doc.Content.LinkList[0].String); Assert.Null(doc.Content.LinkList[1]); Assert.Equal("3", doc.Content.LinkList[2].String); doc.Save(); doc = db.GetEntityDocument <TestEntity>("0"); Assert.NotNull(doc.Content.LinkList); Assert.Equal(3, doc.Content.LinkList.Count); Assert.Equal("1", doc.Content.LinkList[0].String); Assert.Null(doc.Content.LinkList[1]); Assert.Equal("3", doc.Content.LinkList[2].String); //--------------------- // Enumeration var list = new List <TestEntity>(); foreach (var element in doc.Content.LinkList) { list.Add(element); } Assert.Equal(3, list.Count); Assert.Equal("1", list[0].String); Assert.Null(list[1]); Assert.Equal("3", list[2].String); } }
public void Basic() { using (var test = new TestDatabase()) { var db = test.Database; var doc = db.GetEntityDocument <Product>("1"); var changed = false; //----------------------------------------- // Verify that we start out with no attachments. Assert.Empty(doc.Attachments); Assert.Empty(doc.AttachmentNames); Assert.Null(doc.GetAttachment("not-there")); //----------------------------------------- // Add an attachment and partially verify. Note that // the attachment contents or metadata can't be accessed // until the document is saved. doc.Changed += (s, a) => { changed = true; }; changed = false; doc.SetAttachment("attach-1", new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, "type-1"); Assert.True(changed); Assert.Single(doc.Attachments); Assert.Single(doc.AttachmentNames); Assert.NotNull(doc.GetAttachment("attach-1")); //----------------------------------------- // Save, reload, and fully verify. doc.Save(); doc = db.GetEntityDocument <Product>("1"); doc.Changed += (s, a) => { changed = true; }; Assert.Single(doc.Attachments); Assert.Single(doc.AttachmentNames); using (var attachment = doc.GetAttachment("attach-1")) { Assert.NotNull(attachment); Assert.Equal("attach-1", attachment.Name); Assert.Equal("type-1", attachment.ContentType); Assert.Equal(10, attachment.Length); Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, attachment.Content.ToArray()); } //----------------------------------------- // Add another attachment using a stream, save and verify. doc.Revise(); changed = false; doc.SetAttachment("attach-2", new MemoryStream(new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }), "type-2"); Assert.True(changed); doc.Save(); Assert.Equal(2, doc.Attachments.Count()); Assert.Equal(2, doc.AttachmentNames.Count()); using (var attachment = doc.GetAttachment("attach-2")) { Assert.NotNull(attachment); Assert.Equal("attach-2", attachment.Name); Assert.Equal("type-2", attachment.ContentType); Assert.Equal(10, attachment.Length); Assert.Equal(new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, attachment.Content.ToArray()); } //----------------------------------------- // Remove an attachment and verify after saving. doc.Revise(); changed = false; doc.RemoveAttachment("attach-1"); Assert.True(changed); doc.Save(); Assert.Single(doc.Attachments); Assert.Single(doc.AttachmentNames); Assert.Null(doc.GetAttachment("attach-1")); using (var attachment = doc.GetAttachment("attach-2")) { Assert.NotNull(attachment); } } }