public void CheckRequiredReference(bool isNull, bool isEmpty) { // Arrange var instance = new RequiredReferenceResource(); var reference = new SimpleResource(); ResourceReferenceTools.InitializeCollections(instance); ResourceReferenceTools.InitializeCollections(reference); var dbMocks = SetupDbMocks(new List <ResourceRelation>()); // Act if (!isNull) { instance.Reference = reference; } if (!isEmpty) { instance.References.Add(reference); } // Assert if (isNull || isEmpty) { Assert.Throws <ValidationException>(() => _linker.SaveReferences(dbMocks.Item1.Object, instance, new ResourceEntity())); } else { Assert.DoesNotThrow(() => _linker.SaveReferences(dbMocks.Item1.Object, instance, new ResourceEntity())); } }
public void ForwardEventsFromProxy() { // Arrange: Create instance and proxy var instance = new SimpleResource { Id = 6 }; var proxy = (ISimpleResource)_typeController.GetProxy(instance); // Act: Register listener and change foo object eventSender = null, eventSender2 = null; int eventValue = 0; var finallyEven = false; Assert.DoesNotThrow(() => instance.Foo = 10); EventHandler <int> eventHandler = (sender, foo) => { eventSender = sender; eventValue = foo; }; proxy.FooChanged += eventHandler; proxy.FooEven += (sender, b) => finallyEven = b; proxy.SomeEvent += (sender, args) => eventSender2 = sender; instance.Foo = 100; instance.RaiseEvent(); proxy.FooChanged -= eventHandler; // Assert: Check if eventSender is not null and equals the proxy Assert.NotNull(eventSender); Assert.NotNull(eventSender2); Assert.AreNotEqual(0, eventValue); Assert.AreEqual(proxy, eventSender); Assert.AreEqual(100, eventValue); Assert.IsTrue(finallyEven); }
public void SetParentWhenAddingChild() { // Arrange // Create resources var parent = new SimpleResource { Id = 1 }; ResourceReferenceTools.InitializeCollections(parent); var child = new SimpleResource { Id = 2 }; ResourceReferenceTools.InitializeCollections(child); var mocks = SetupDbMocks(new List <ResourceRelation>()); // Setup graph mock _graph[1] = new ResourceWrapper(parent); _graph[2] = new ResourceWrapper(child); // Act parent.Children.Add(child); _linker.SaveReferences(mocks.Item1.Object, parent, new ResourceEntity { Id = 1 }); // Assert Assert.IsTrue(parent.Children.Contains(child), "Child was not set"); Assert.AreEqual(parent, child.Parent, "Parent was not set"); }
public void CallMethodOnProxyFromNonPublicResourceApi() { // Arrange var instance = new SimpleResource { Id = 4, Foo = 10 }; // Act: Build proxy var proxy = _typeController.GetProxy(instance); // Assert Assert.IsInstanceOf <INonResourceInterface>(proxy); Assert.DoesNotThrow(() => ((INonResourceInterface)proxy).Validate()); }
public void CallMethodOnProxy() { // Arrange: Create instance var instance = new SimpleResource { Id = 4, Foo = 10 }; // Act: Build proxy and call method var proxy = (ISimpleResource)_typeController.GetProxy(instance); var result = proxy.MultiplyFoo(3); proxy.MultiplyFoo(2, 10); // Assert: Check result and modified foo Assert.AreEqual(30, result); Assert.AreEqual(70, proxy.Foo); }
public void UseBaseProxyForDerivedType() { // Arrange: Create instance var baseInstance = new SimpleResource { Id = 2 }; var instance = new DerivedResource { Id = 3 }; // Act: Build Proxy var baseProxy = (ISimpleResource)_typeController.GetProxy(baseInstance); var proxy = (ISimpleResource)_typeController.GetProxy(instance); // Assert: Make sure proxy is still the base type Assert.AreEqual(baseProxy.GetType(), proxy.GetType()); }
public void ReadAndWriteProperties() { // Arrange: Create instance var resource = new SimpleResource { Id = 1, Foo = 1337 }; // Act: Build Proxy var proxy = (ISimpleResource)_typeController.GetProxy(resource); var duplicate = (IDuplicateFoo)proxy; // Assert Assert.AreEqual(resource.Foo, proxy.Foo); Assert.AreEqual(resource.Foo, duplicate.Foo); proxy.Foo = 187; // duplicate.Foo = 10; ReadOnly but still uses the same property Assert.AreEqual(187, resource.Foo); Assert.AreEqual(187, duplicate.Foo); }
public void SyncChildrenOnParentModification() { // Arrange // Create resources var parent1 = new SimpleResource { Id = 1 }; ResourceReferenceTools.InitializeCollections(parent1); var parent2 = new SimpleResource { Id = 2 }; ResourceReferenceTools.InitializeCollections(parent2); var child = new SimpleResource { Id = 3 }; ResourceReferenceTools.InitializeCollections(child); // Create initial relationship child.Parent = parent1; parent1.Children.Add(child); var relations = new List <ResourceRelation> { Relation(3, 1) // Initial relationship }; var mocks = SetupDbMocks(relations); // Setup graph mock _graph[1] = new ResourceWrapper(parent1); _graph[2] = new ResourceWrapper(parent2); _graph[3] = new ResourceWrapper(child); // Act child.Parent = parent2; _linker.SaveReferences(mocks.Item1.Object, child, new ResourceEntity { Id = 3 }); // Assert Assert.IsFalse(parent1.Children.Contains(child), "Child was not removed"); Assert.IsTrue(parent2.Children.Contains(child), "Child was not set"); }
public void AfterDisposeTheProxyIsDetached() { // Arrange: Create a proxy and register to an event var instance = new SimpleResource { Id = 7 }; var proxy = (ISimpleResource)_typeController.GetProxy(instance); var called = false; proxy.FooChanged += (sender, i) => called = true; instance.Foo = 10; Assert.IsTrue(called); // Act: Dispose the type controller and use the proxy again called = false; _typeController.Stop(); instance.Foo = 10; // Assert: Event was not raised and proxy can no longer be used Assert.IsFalse(called); Assert.Throws <ProxyDetachedException>(() => proxy.MultiplyFoo(2)); }
public void ClearParentWhenRemovingChild() { // Arrange // Create resources var parent = new SimpleResource { Id = 1 }; ResourceReferenceTools.InitializeCollections(parent); var child = new SimpleResource { Id = 2 }; ResourceReferenceTools.InitializeCollections(child); // Create initial relationship child.Parent = parent; parent.Children.Add(child); var relations = new List <ResourceRelation> { Relation(2, 1) // Initial relationship }; var mocks = SetupDbMocks(relations); // Setup graph mock _graph[1] = new ResourceWrapper(parent); _graph[2] = new ResourceWrapper(child); // Act parent.Children.Remove(child); _linker.SaveReferences(mocks.Item1.Object, parent, new ResourceEntity { Id = 1 }); // Assert Assert.IsFalse(parent.Children.Contains(child), "Child was not removed"); Assert.IsNull(child.Parent, "Parent was not cleared"); }
public void ReplaceWithProxy() { // Arrange: Create instance and reference var ref1 = new DerivedResource { Id = 9, Foo = 20 }; var ref2 = new SimpleResource { Id = 10, Foo = 30 }; var nonPub = new NonPublicResource { Name = "NonPublic" }; var instance = new ReferenceResource { Id = 8, Reference = ref1, NonPublic = nonPub }; instance.References = new ReferenceCollection <ISimpleResource>(instance, instance.GetType().GetProperty(nameof(ReferenceResource.References)), new List <IResource>()) { ref2 }; // Act: Convert to proxy and access the reference var proxy = (IReferenceResource)_typeController.GetProxy(instance); var reference = proxy.Reference; var methodRef = proxy.GetReference(); var references = proxy.MoreReferences.ToArray(); var references2 = proxy.GetReferences(); var nonPubProxy = proxy.NonPublic; ISimpleResource eventArgs = null; proxy.ReferenceChanged += (sender, resource) => eventArgs = resource; ISimpleResource[] eventArgs2 = null; proxy.SomeChanged += (sender, resources) => eventArgs2 = resources; // Act: Set resource property through proxy proxy.Reference = references[0]; proxy.SetReference(reference); // Make sure all references where replaced with proxies Assert.AreNotEqual(ref1, reference); Assert.AreNotEqual(ref2, references[0]); Assert.AreNotEqual(ref2, references2[0]); Assert.AreNotEqual(nonPub, nonPubProxy); Assert.AreEqual(20, reference.Foo); Assert.AreEqual(reference, methodRef); Assert.AreEqual(30, references[0].Foo); Assert.AreEqual(30, references2[0].Foo); Assert.NotNull(eventArgs); Assert.AreEqual(30, eventArgs.Foo); Assert.NotNull(eventArgs2); Assert.AreEqual(1, eventArgs2.Length); Assert.AreEqual(30, eventArgs2[0].Foo); Assert.AreEqual("NonPublic", nonPubProxy.Name); // Assert modifications of the setters Assert.AreEqual(instance.Reference, ref2); Assert.AreEqual(instance.References.Count(), 2); Assert.AreEqual(instance.References.ElementAt(1), ref1); }
public void SaveReferences() { // Arrange var instance = new ReferenceResource { Id = 1 }; ResourceReferenceTools.InitializeCollections(instance); // Prepare reference objects var ref1 = new SimpleResource { Id = 2, Name = "Ref1" }; var ref2 = new SimpleResource { Id = 3, Name = "Pos1" }; var ref3 = new DerivedResource { Name = "Ref2" }; ResourceReferenceTools.InitializeCollections(ref3); var ref4 = new DerivedResource { Id = 5, Name = "ChildOnly" }; var ref5 = new DerivedResource { Id = 6, Name = "BackRef" }; ResourceReferenceTools.InitializeCollections(ref5); // Fill graph _graph[1] = new ResourceWrapper(instance); _graph[2] = new ResourceWrapper(ref1); _graph[3] = new ResourceWrapper(ref2); _graph[5] = new ResourceWrapper(ref4); _graph[6] = new ResourceWrapper(ref5); // Set single references instance.Parent = ref5; // Parent is set and // ref5.Children.Add(instance); Bidirectional reference synced --> no longer necessary instance.Reference = ref2; // Reference is changed from ref1 to ref2 instance.Reference2 = ref3; // Reference2 is assigned with a new object // Fill collections instance.References.Add(ref1); // This element remains //instance.References.Add(ref2); // This element was removed instance.References.Add(ref3); // The new element is also added to the list, but is not a child // Fill children with all except the unsaved one to simulate an unchanged collection instance.Children.Add(ref1); instance.Children.Add(ref2); instance.Children.Add(ref4); // Setup uow and repo to simulate the current database var relations = new List <ResourceRelation> { // Parent child relations //Relation(6, ResourceRelationType.ParentChild, ResourceReferenceRole.Source), <-- Represents the missing bidirectional parent relationship created during this test Relation(2, 1), Relation(3, 1), Relation(5, 1), // Current exchangable part Relation(2, 1, ResourceRelationType.CurrentExchangablePart, ResourceReferenceRole.Target, nameof(ReferenceResource.Reference)), // This is changed to ref2 // Possible exchangable part Relation(2, 1, ResourceRelationType.PossibleExchangablePart), // This remains untouched Relation(3, 1, ResourceRelationType.PossibleExchangablePart) // This is removed }; var mocks = SetupDbMocks(relations); // Act var newResources = _linker.SaveReferences(mocks.Item1.Object, instance, new ResourceEntity { Id = 1 }); // Assert Assert.AreEqual(1, newResources.Count); Assert.AreEqual(ref3, newResources[0]); Assert.IsTrue(ref5.Children.Contains(instance), "Backlink sync failed for parent ref5"); Assert.DoesNotThrow(() => mocks.Item3.Verify(repo => repo.Create(), Times.Once), "Linker did not detect the new resource"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Create((int)ResourceRelationType.PossibleExchangablePart), Times.Once), "Linker did not create relation for ref3 in References"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Create((int)ResourceRelationType.ParentChild), Times.Once), "Linker did not create relation for parent ref5"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Remove(It.Is <ResourceRelation>(removed => removed.SourceId == 1 && removed.TargetId == 3)), Times.Once), "Linker did not remove relation 1-3"); var parentChild = relations.Where(r => r.RelationType == (int)ResourceRelationType.ParentChild).ToArray(); Assert.AreEqual(4, parentChild.Length); var currentPart = relations.Where(r => r.RelationType == (int)ResourceRelationType.CurrentExchangablePart).ToArray(); Assert.AreEqual(2, currentPart.Length); Assert.AreEqual(1, currentPart.Count(r => r.Target.Id == 3)); Assert.AreEqual(1, currentPart.Count(r => r.Target.Id == 0)); var possiblePart = relations.Where(r => r.RelationType == (int)ResourceRelationType.PossibleExchangablePart).ToArray(); Assert.AreEqual(2, possiblePart.Length); Assert.AreEqual(1, possiblePart.Count(r => r.Target.Id == 2)); Assert.AreEqual(1, possiblePart.Count(r => r.Target.Id == 0)); }