public void DisposesEventHandlersWhenOwnerComponentRemoved() { // Arrange var renderer = new TestRenderer(); var eventCount = 0; UIEventHandler origEventHandler = args => { eventCount++; }; var component = new ConditionalParentComponent <EventComponent> { IncludeChild = true, ChildParameters = new Dictionary <string, object> { { nameof(EventComponent.OnTest), origEventHandler } } }; var rootComponentId = renderer.AssignComponentId(component); component.TriggerRender(); var batch = renderer.Batches.Single(); var rootComponentDiff = batch.DiffsByComponentId[rootComponentId].Single(); var rootComponentFrame = batch.ReferenceFrames[0]; var childComponentFrame = rootComponentDiff.Edits .Select(e => batch.ReferenceFrames[e.ReferenceFrameIndex]) .Where(f => f.FrameType == RenderTreeFrameType.Component) .Single(); var childComponentId = childComponentFrame.ComponentId; var childComponentDiff = batch.DiffsByComponentId[childComponentFrame.ComponentId].Single(); var eventHandlerId = batch.ReferenceFrames .Skip(childComponentDiff.Edits[0].ReferenceFrameIndex) // Search from where the child component frames start .Where(f => f.FrameType == RenderTreeFrameType.Attribute) .Single(f => f.AttributeEventHandlerId != 0) .AttributeEventHandlerId; // Act/Assert 1: Event handler fires when we trigger it Assert.Equal(0, eventCount); renderer.DispatchEvent(childComponentId, eventHandlerId, args: null); Assert.Equal(1, eventCount); // Now remove the EventComponent component.IncludeChild = false; component.TriggerRender(); // Act/Assert 2: Can no longer fire the original event Assert.Throws <ArgumentException>(() => { renderer.DispatchEvent(eventHandlerId, eventHandlerId, args: null); }); Assert.Equal(1, eventCount); }
public void NotifiesIHandlePropertiesChangedWhenChanged() { // Arrange var renderer = new TestRenderer(); var component = new ConditionalParentComponent <HandlePropertiesChangedComponent> { IncludeChild = true, ChildParameters = new Dictionary <string, object> { { nameof(HandlePropertiesChangedComponent.IntProperty), 123 } } }; var rootComponentId = renderer.AssignComponentId(component); // Act/Assert 0: Initial render renderer.RenderNewBatch(rootComponentId); var batch1 = renderer.Batches.Single(); var childComponentFrame = batch1 .ReferenceFrames.Where(frame => frame.FrameType == RenderTreeFrameType.Component).Single(); var childComponentId = childComponentFrame.ComponentId; var diffForChildComponent0 = batch1.DiffsByComponentId[childComponentId].Single(); var childComponentInstance = (HandlePropertiesChangedComponent)childComponentFrame.Component; Assert.Equal(1, childComponentInstance.NotificationsCount); Assert.Collection(diffForChildComponent0.Edits, edit => { Assert.Equal(RenderTreeEditType.PrependFrame, edit.Type); AssertFrame.Text(batch1.ReferenceFrames[edit.ReferenceFrameIndex], "Notifications: 1", 0); }); // Act/Assert 1: If properties didn't change, we don't notify renderer.RenderNewBatch(rootComponentId); Assert.Equal(1, childComponentInstance.NotificationsCount); // Act/Assert 2: If properties did change, we do notify component.ChildParameters[nameof(HandlePropertiesChangedComponent.IntProperty)] = 456; renderer.RenderNewBatch(rootComponentId); Assert.Equal(2, childComponentInstance.NotificationsCount); var batch3 = renderer.Batches.Skip(2).Single(); var diffForChildComponent2 = batch3.DiffsByComponentId[childComponentId].Single(); Assert.Equal(2, childComponentInstance.NotificationsCount); AssertFrame.Text(batch3.ReferenceFrames[0], "Notifications: 2", 0); }