|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
using Moq;
namespace System.ComponentModel.Design.Tests;
public class DesignerHostTests
{
[WinFormsTheory]
[BoolData]
public void DesignerHost_CanReloadWithErrors_Set_GetReturnsExpected(bool value)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.CanReloadWithErrors = value;
Assert.Equal(value, host.CanReloadWithErrors);
// Set same.
host.CanReloadWithErrors = value;
Assert.Equal(value, host.CanReloadWithErrors);
// Set different.
host.CanReloadWithErrors = !value;
Assert.Equal(!value, host.CanReloadWithErrors);
}
[WinFormsFact]
public void DesignerHost_Container_Get_ReturnsHost()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Same(host, host.Container);
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_IgnoreErrorsDuringReload_Set_GetReturnsExpected(bool value)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.IgnoreErrorsDuringReload = value;
Assert.False(host.IgnoreErrorsDuringReload);
// Set same.
host.IgnoreErrorsDuringReload = value;
Assert.False(host.IgnoreErrorsDuringReload);
// Set different.
host.IgnoreErrorsDuringReload = !value;
Assert.False(host.IgnoreErrorsDuringReload);
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_IgnoreErrorsDuringReload_SetWithCanReloadWithErrors_GetReturnsExpected(bool value)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.CanReloadWithErrors = true;
host.IgnoreErrorsDuringReload = value;
Assert.Equal(value, host.IgnoreErrorsDuringReload);
// Set same.
host.IgnoreErrorsDuringReload = value;
Assert.Equal(value, host.IgnoreErrorsDuringReload);
// Set different.
host.IgnoreErrorsDuringReload = !value;
Assert.Equal(!value, host.IgnoreErrorsDuringReload);
}
[WinFormsFact]
public void DesignerHost_InTransaction_GetWithoutTransactions_ReturnsFalse()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.False(host.InTransaction);
}
[WinFormsFact]
public void DesignerHost_IsClosingTransaction_GetWithoutTransaction_ReturnsFalse()
{
using SubDesignSurface surface = new();
IDesignerHostTransactionState hostTransactionState = Assert.IsAssignableFrom<IDesignerHostTransactionState>(surface.Host);
Assert.False(hostTransactionState.IsClosingTransaction);
}
[WinFormsFact]
public void DesignerHost_Loading_GetWithoutComponent_ReturnsFalse()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.False(host.Loading);
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_Loading_GetWithLoader_ReturnsExpected(bool loading)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Mock<DesignerLoader> mockLoader = new(MockBehavior.Strict);
mockLoader
.Setup(l => l.BeginLoad(host));
mockLoader
.Setup(l => l.Loading)
.Returns(loading);
surface.BeginLoad(mockLoader.Object);
Assert.True(host.Loading);
mockLoader.Verify(l => l.Loading, Times.Never());
host.EndLoad(null, true, null);
Assert.Equal(loading, host.Loading);
mockLoader.Verify(l => l.Loading, Times.Once());
}
[WinFormsFact]
public void DesignerHost_RootComponent_GetWithoutComponent_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Null(host.RootComponent);
}
[WinFormsFact]
public void DesignerHost_RootComponentClassName_GetWithoutComponent_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Null(host.RootComponentClassName);
}
[WinFormsFact]
public void DesignerHost_TransactionDescription_GetWithoutTransactions_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.TransactionDescription.Should().BeNullOrEmpty();
}
[WinFormsFact]
public void DesignerHost_Activate_Invoke_CallsViewActivated()
{
using SubDesignSurface surface = new();
int viewActivatedCallCount = 0;
int activatedCallCount = 0;
surface.ViewActivated += (sender, e) =>
{
Assert.Same(surface, sender);
Assert.Same(EventArgs.Empty, e);
viewActivatedCallCount++;
};
IDesignerLoaderHost2 host = surface.Host;
host.Activated += (sender, e) => activatedCallCount++;
host.Activate();
Assert.Equal(1, viewActivatedCallCount);
Assert.Equal(0, activatedCallCount);
}
[WinFormsFact]
public void DesignerHost_Activate_InvokeDisposed_Nop()
{
using SubDesignSurface surface = new();
int viewActivatedCallCount = 0;
int activatedCallCount = 0;
surface.ViewActivated += (sender, e) =>
{
Assert.Same(surface, sender);
Assert.Same(EventArgs.Empty, e);
viewActivatedCallCount++;
};
IDesignerLoaderHost2 host = surface.Host;
surface.Dispose();
host.Activated += (sender, e) => activatedCallCount++;
host.Activate();
Assert.Equal(0, viewActivatedCallCount);
Assert.Equal(0, activatedCallCount);
}
public static IEnumerable<object[]> Add_InvalidNameCreationServiceParentProvider_TestData()
{
yield return new object[] { null };
Mock<IServiceProvider> nullMockServiceProvider = new(MockBehavior.Strict);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(DesignerCommandSet)))
.Returns(new object());
nullMockServiceProvider
.Setup(p => p.GetService(typeof(IInheritanceService)))
.Returns(new object());
yield return new object[] { nullMockServiceProvider.Object };
Mock<IServiceProvider> invalidMockServiceProvider = new(MockBehavior.Strict);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(new object());
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(DesignerCommandSet)))
.Returns(new object());
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(IInheritanceService)))
.Returns(new object());
yield return new object[] { invalidMockServiceProvider.Object };
}
public static IEnumerable<object[]> Add_ComponentParentProvider_TestData()
{
foreach (object[] testData in Add_InvalidNameCreationServiceParentProvider_TestData())
{
yield return new object[] { testData[0], string.Empty };
}
foreach (string name in new string[] { null, string.Empty, "name" })
{
Mock<INameCreationService> mockNameCreationService = new(MockBehavior.Strict);
mockNameCreationService
.Setup(s => s.CreateName(It.IsAny<IContainer>(), It.IsAny<Type>()))
.Returns(name);
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(DesignerCommandSet)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IInheritanceService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(mockNameCreationService.Object);
yield return new object[] { mockServiceProvider.Object, name };
}
}
[WinFormsTheory]
[MemberData(nameof(Add_ComponentParentProvider_TestData))]
public void DesignerHost_Add_ComponentWithRootDesigner_Success(IServiceProvider parentProvider, string expectedName)
{
using SubDesignSurface surface = new(parentProvider);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
using RootDesignerComponent component2 = new();
using DesignerComponent component3 = new();
using Component component4 = new();
host.Container.Add(component1);
Assert.Same(component1, Assert.Single(host.Container.Components));
Assert.Same(expectedName, host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(host, component1.Container);
Assert.Same(component1, component1.Site.Component);
Assert.Same(host, component1.Site.Container);
Assert.True(component1.Site.DesignMode);
Assert.Equal(expectedName, component1.Site.Name);
// Add different - root designer.
host.Container.Add(component2);
Assert.Equal(new IComponent[] { component1, component2 }, host.Container.Components.Cast<IComponent>());
Assert.Same(expectedName, host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(host, component2.Container);
Assert.Same(component2, component2.Site.Component);
Assert.Same(host, component2.Site.Container);
Assert.True(component2.Site.DesignMode);
Assert.Equal(expectedName, component2.Site.Name);
// Add different - non root designer.
host.Container.Add(component3);
Assert.Equal(new IComponent[] { component1, component2, component3 }, host.Container.Components.Cast<IComponent>());
Assert.Same(expectedName, host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(host, component3.Container);
Assert.Same(component3, component3.Site.Component);
Assert.Same(host, component3.Site.Container);
Assert.True(component3.Site.DesignMode);
Assert.Equal(expectedName, component3.Site.Name);
// Add different - non designer.
host.Container.Add(component4);
Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, host.Container.Components.Cast<IComponent>());
Assert.Same(expectedName, host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(host, component4.Container);
Assert.Same(component4, component4.Site.Component);
Assert.Same(host, component4.Site.Container);
Assert.True(component4.Site.DesignMode);
Assert.Equal(expectedName, component4.Site.Name);
}
[WinFormsTheory]
[MemberData(nameof(Add_InvalidNameCreationServiceParentProvider_TestData))]
public void DesignerHost_Add_ComponentStringWithRootDesigner_Success(IServiceProvider parentProvider)
{
using SubDesignSurface surface = new(parentProvider);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
using RootDesignerComponent component2 = new();
using DesignerComponent component3 = new();
using Component component4 = new();
host.Container.Add(component1, "name1");
Assert.Same(component1, Assert.Single(host.Container.Components));
Assert.Equal("name1", host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(host, component1.Container);
Assert.Same(component1, component1.Site.Component);
Assert.Same(host, component1.Site.Container);
Assert.True(component1.Site.DesignMode);
Assert.Equal("name1", component1.Site.Name);
// Add different - root designer.
host.Container.Add(component2, "name2");
Assert.Equal(new IComponent[] { component1, component2 }, host.Container.Components.Cast<IComponent>());
Assert.Same(host, component2.Container);
Assert.Equal("name1", host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(component2, component2.Site.Component);
Assert.Same(host, component2.Site.Container);
Assert.True(component2.Site.DesignMode);
Assert.Equal("name2", component2.Site.Name);
// Add different - non root designer.
host.Container.Add(component3, string.Empty);
Assert.Equal(new IComponent[] { component1, component2, component3 }, host.Container.Components.Cast<IComponent>());
Assert.Same(host, component3.Container);
Assert.Equal("name1", host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(component3, component3.Site.Component);
Assert.Same(host, component3.Site.Container);
Assert.True(component3.Site.DesignMode);
Assert.Empty(component3.Site.Name);
// Add different - non designer.
host.Container.Add(component4, null);
Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, host.Container.Components.Cast<IComponent>());
Assert.Same(host, component4.Container);
Assert.Equal("name1", host.RootComponentClassName);
Assert.Same(component1, host.RootComponent);
Assert.Same(component4, component4.Site.Component);
Assert.Same(host, component4.Site.Container);
Assert.True(component4.Site.DesignMode);
Assert.Empty(component4.Site.Name);
}
public static IEnumerable<object[]> Add_IExtenderProviderServiceWithoutDefault_TestData()
{
yield return new object[] { new RootDesignerComponent(), 0 };
yield return new object[] { new RootExtenderProviderDesignerComponent(), 1 };
RootExtenderProviderDesignerComponent readOnlyComponent = new();
TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly));
yield return new object[] { readOnlyComponent, 0 };
RootExtenderProviderDesignerComponent inheritedComponent = new();
TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited));
yield return new object[] { inheritedComponent, 1 };
RootExtenderProviderDesignerComponent notInheritedComponent = new();
TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited));
yield return new object[] { notInheritedComponent, 1 };
}
[WinFormsTheory]
[MemberData(nameof(Add_IExtenderProviderServiceWithoutDefault_TestData))]
public void DesignerHost_Add_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedCallCount)
{
Mock<IExtenderProviderService> mockExtenderProviderService = new(MockBehavior.Strict);
mockExtenderProviderService
.Setup(s => s.AddExtenderProvider(component as IExtenderProvider))
.Verifiable();
mockExtenderProviderService
.Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider));
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(mockExtenderProviderService.Object)
.Verifiable();
using SubDesignSurface surface = new(mockServiceProvider.Object);
surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService));
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount));
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount));
// Add again.
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount));
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount));
// Add again with name.
host.Container.Add(component, "name");
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Equal("name", component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount));
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount));
}
public static IEnumerable<object[]> Add_IExtenderProviderServiceWithDefault_TestData()
{
yield return new object[] { new RootDesignerComponent() };
yield return new object[] { new RootExtenderProviderDesignerComponent() };
RootExtenderProviderDesignerComponent readOnlyComponent = new();
TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly));
yield return new object[] { readOnlyComponent };
RootExtenderProviderDesignerComponent inheritedComponent = new();
TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited));
yield return new object[] { inheritedComponent };
RootExtenderProviderDesignerComponent notInheritedComponent = new();
TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited));
yield return new object[] { notInheritedComponent };
}
[WinFormsTheory]
[MemberData(nameof(Add_IExtenderProviderServiceWithDefault_TestData))]
public void DesignerHost_Add_IExtenderProviderServiceWithDefault_DoesNotCallGetService(Component component)
{
Mock<IExtenderProviderService> mockExtenderProviderService = new(MockBehavior.Strict);
mockExtenderProviderService
.Setup(s => s.AddExtenderProvider(component as IExtenderProvider))
.Verifiable();
mockExtenderProviderService
.Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider));
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(mockExtenderProviderService.Object)
.Verifiable();
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never());
// Add again.
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never());
// Add again with name.
host.Container.Add(component, "name");
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Equal("name", component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never());
}
public static IEnumerable<object[]> InvalidIExtenderProviderService_TestData()
{
yield return new object[] { null };
Mock<IServiceProvider> nullMockServiceProvider = new(MockBehavior.Strict);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
nullMockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(null)
.Verifiable();
yield return new object[] { nullMockServiceProvider };
Mock<IServiceProvider> invalidMockServiceProvider = new(MockBehavior.Strict);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
invalidMockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(new object())
.Verifiable();
yield return new object[] { invalidMockServiceProvider };
}
[WinFormsTheory]
[MemberData(nameof(InvalidIExtenderProviderService_TestData))]
public void DesignerHost_Add_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock<IServiceProvider> mockParentProvider)
{
using SubDesignSurface surface = new(mockParentProvider?.Object);
surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService));
IDesignerLoaderHost2 host = surface.Host;
using RootExtenderProviderDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once());
}
[WinFormsTheory]
[MemberData(nameof(InvalidIExtenderProviderService_TestData))]
public void DesignerHost_Add_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock<IServiceProvider> mockParentProvider)
{
using SubDesignSurface surface = new(mockParentProvider?.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootExtenderProviderDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
}
[WinFormsFact]
public void DesignerHost_Add_SameComponent_Success()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
// Add again.
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
// Add again with name.
host.Container.Add(component, "name");
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Equal("name", component.Site.Name);
}
[WinFormsFact]
public void DesignerHost_Add_ComponentWithNameCreationServiceWithoutName_CallsCreateName()
{
Mock<INameCreationService> mockNameCreationService = new(MockBehavior.Strict);
mockNameCreationService
.Setup(s => s.CreateName(It.IsAny<IContainer>(), It.IsAny<Type>()))
.Returns("name")
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(mockNameCreationService.Object);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Equal("name", component.Site.Name);
mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once());
host.Container.Add(component, null);
Assert.Equal("name", component.Site.Name);
mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once());
}
[WinFormsFact]
public void DesignerHost_Add_ComponentWithNameCreationServiceWithCustomReflectionType_CallsCreateName()
{
using CustomTypeDescriptionProviderComponent component = new();
Mock<ICustomTypeDescriptor> mockCustomTypeDescriptor = new(MockBehavior.Strict);
mockCustomTypeDescriptor
.Setup(d => d.GetAttributes())
.Returns(TypeDescriptor.GetAttributes(typeof(CustomTypeDescriptionProviderComponent)));
Mock<TypeDescriptionProvider> mockProvider = new(MockBehavior.Strict);
mockProvider
.Setup(p => p.GetReflectionType(typeof(CustomTypeDescriptionProviderComponent), component))
.Returns(typeof(RootDesignerComponent))
.Verifiable();
mockProvider
.Setup(p => p.GetTypeDescriptor(typeof(CustomTypeDescriptionProviderComponent), component))
.Returns(mockCustomTypeDescriptor.Object);
mockProvider
.Setup(p => p.GetCache(component))
.CallBase();
mockProvider
.Setup(p => p.GetExtendedTypeDescriptor(component))
.CallBase();
TypeDescriptor.AddProvider(mockProvider.Object, component);
Mock<INameCreationService> mockNameCreationService = new(MockBehavior.Strict);
mockNameCreationService
.Setup(s => s.CreateName(It.IsAny<IContainer>(), It.IsAny<Type>()))
.Returns("name")
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(mockNameCreationService.Object);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component);
Assert.Equal("name", component.Site.Name);
mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once());
host.Container.Add(component, null);
Assert.Equal("name", component.Site.Name);
mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once());
}
[WinFormsTheory]
[StringData]
public void DesignerHost_Add_ComponentWithNameCreationServiceWithName_CallsValidateName(string name)
{
Mock<INameCreationService> mockNameCreationService = new(MockBehavior.Strict);
mockNameCreationService
.Setup(s => s.ValidateName(It.IsAny<string>()))
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(mockNameCreationService.Object)
.Verifiable();
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
host.Container.Add(component1, name);
Assert.Same(name, component1.Site.Name);
mockNameCreationService.Verify(s => s.ValidateName(name), Times.Once());
mockServiceProvider.Verify(p => p.GetService(typeof(INameCreationService)), Times.Once());
// Add another.
using DesignerComponent component2 = new();
host.Container.Add(component2, "name2");
Assert.Equal("name2", component2.Site.Name);
mockNameCreationService.Verify(s => s.ValidateName("name2"), Times.Once());
mockServiceProvider.Verify(p => p.GetService(typeof(INameCreationService)), Times.Exactly(2));
}
[WinFormsFact]
public void DesignerHost_Add_ComponentWithTypeDescriptionProviderServiceWithoutProjectTargetFrameworkAttribute_AddsProvider()
{
ICustomTypeDescriptor descriptor = TypeDescriptor.GetProvider(typeof(RootDesignerComponent)).GetTypeDescriptor(typeof(RootDesignerComponent));
Mock<TypeDescriptionProvider> mockTypeDescriptionProvider = new(MockBehavior.Strict);
mockTypeDescriptionProvider
.Setup(p => p.IsSupportedType(typeof(int)))
.Returns(false)
.Verifiable();
mockTypeDescriptionProvider
.Setup(p => p.GetTypeDescriptor(It.IsAny<Type>(), It.IsAny<object>()))
.Returns(descriptor);
mockTypeDescriptionProvider
.Setup(p => p.GetCache(It.IsAny<object>()))
.CallBase();
mockTypeDescriptionProvider
.Setup(p => p.GetExtendedTypeDescriptor(It.IsAny<object>()))
.CallBase();
Mock<TypeDescriptionProviderService> mockTypeDescriptionProviderService = new(MockBehavior.Strict);
mockTypeDescriptionProviderService
.Setup(s => s.GetProvider(It.IsAny<object>()))
.Returns(mockTypeDescriptionProvider.Object)
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(mockTypeDescriptionProviderService.Object)
.Verifiable();
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(DesignerCommandSet)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IInheritanceService)))
.Returns(null);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
host.Container.Add(component1, "name1");
Assert.Equal("name1", component1.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once());
mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component1), Times.Once());
// Make sure we added the TypeDescriptionProvider.
Assert.False(TypeDescriptor.GetProvider(component1).IsSupportedType(typeof(int)));
mockTypeDescriptionProvider.Verify(p => p.IsSupportedType(typeof(int)), Times.Once());
// Add again.
using DesignerComponent component2 = new();
host.Container.Add(component2, "name2");
Assert.Equal("name2", component2.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once());
mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component2), Times.Once());
// Make sure we added the TypeDescriptionProvider.
Assert.False(TypeDescriptor.GetProvider(component2).IsSupportedType(typeof(int)));
mockTypeDescriptionProvider.Verify(p => p.IsSupportedType(typeof(int)), Times.Exactly(2));
}
[WinFormsFact]
public void DesignerHost_Add_ComponentWithNullTypeDescriptionProviderService_Success()
{
Mock<TypeDescriptionProviderService> mockTypeDescriptionProviderService = new(MockBehavior.Strict);
mockTypeDescriptionProviderService
.Setup(s => s.GetProvider(It.IsAny<object>()))
.Returns<TypeDescriptionProvider>(null)
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(mockTypeDescriptionProviderService.Object)
.Verifiable();
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component, "name1");
Assert.Equal("name1", component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once());
mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component), Times.Once());
}
[WinFormsFact]
public void DesignerHost_Add_ComponentWithTypeDescriptionProviderServiceWithProjectTargetFrameworkAttribute_DoesNotAddProvider()
{
using RootDesignerComponent component = new();
ICustomTypeDescriptor descriptor = TypeDescriptor.GetProvider(typeof(RootDesignerComponent)).GetTypeDescriptor(typeof(RootDesignerComponent));
Mock<TypeDescriptionProvider> mockTypeDescriptionProvider = new(MockBehavior.Strict);
mockTypeDescriptionProvider
.Setup(p => p.GetTypeDescriptor(It.IsAny<Type>(), It.IsAny<object>()))
.Returns(descriptor);
mockTypeDescriptionProvider
.Setup(p => p.GetCache(component))
.CallBase();
mockTypeDescriptionProvider
.Setup(p => p.GetExtendedTypeDescriptor(It.IsAny<object>()))
.CallBase();
mockTypeDescriptionProvider
.Setup(p => p.GetReflectionType(typeof(object), null))
.Returns(typeof(ClassWithProjectTargetFrameworkAttribute));
TypeDescriptor.AddProvider(mockTypeDescriptionProvider.Object, component);
Mock<TypeDescriptionProviderService> mockTypeDescriptionProviderService = new(MockBehavior.Strict);
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(mockTypeDescriptionProviderService.Object)
.Verifiable();
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component, "name1");
Assert.Equal("name1", component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once());
mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component), Times.Never());
}
[WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")]
public void DesignerHost_Add_DuringUnload_ThrowsException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.BeginLoad(typeof(RootDesignerComponent));
using DesignerComponent component = new();
host.Container.Add(component);
int callCount = 0;
component.Disposed += (sender, e) =>
{
using DesignerComponent newComponent = new();
Assert.Throws<Exception>(() => host.Container.Add(newComponent));
callCount++;
};
surface.Dispose();
Assert.Equal(1, callCount);
Assert.False(surface.IsLoaded);
Assert.Empty(surface.LoadErrors);
Assert.False(host.Loading);
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetKey_NoDictionary_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
Assert.Null(service.GetKey(null));
Assert.Null(service.GetKey(new object()));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetKey_NoSuchKeyWithDictionary_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
object key1 = new();
object value1 = new();
service.SetValue(key1, value1);
Assert.Same(key1, service.GetKey(value1));
Assert.Same(value1, service.GetValue(key1));
Assert.Null(service.GetKey(null));
Assert.Null(service.GetKey(new object()));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetValue_NoDictionary_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
Assert.Null(service.GetValue(new object()));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetValue_NoSuchValueWithDictionary_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
object key1 = new();
object value1 = new();
service.SetValue(key1, value1);
Assert.Same(key1, service.GetKey(value1));
Assert.Same(value1, service.GetValue(key1));
Assert.Null(service.GetValue(new object()));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetValue_NullValueNoDictionary_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
Assert.Throws<ArgumentNullException>("key", () => service.GetValue(null));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceGetValue_NullValueWithDictionary_ThrowsArgumentNullException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
object key1 = new();
object value1 = new();
service.SetValue(key1, value1);
Assert.Same(key1, service.GetKey(value1));
Assert.Same(value1, service.GetValue(key1));
Assert.Throws<ArgumentNullException>("key", () => service.GetValue(null));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceSetValue_Invoke_GetKeyValueReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
object key1 = new();
object value1 = new();
service.SetValue(key1, value1);
Assert.Same(key1, service.GetKey(value1));
Assert.Same(value1, service.GetValue(key1));
// Add another.
object key2 = new();
object value2 = new();
service.SetValue(key2, value2);
Assert.Same(key2, service.GetKey(value2));
Assert.Same(value2, service.GetValue(key2));
// Add same.
object value3 = new();
service.SetValue(key1, value3);
Assert.Same(key1, service.GetKey(value3));
Assert.Null(service.GetKey(value1));
Assert.Same(value3, service.GetValue(key1));
// Add null value.
service.SetValue(key1, null);
Assert.Null(service.GetKey(null));
Assert.Null(service.GetKey(value3));
Assert.Null(service.GetValue(key1));
}
[WinFormsFact]
public void DesignerHost_AddComponentIDictionaryServiceSetValue_NullKey_ThrowsArgumentNullException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
Assert.Throws<ArgumentNullException>("key", () => service.SetValue(null, new object()));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObject_ReturnsExpected()
{
object service = new();
object otherService = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), service);
Assert.Same(service, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObjectPromote_ReturnsExpected()
{
object service = new();
object otherService = new();
ServiceContainer otherContainer = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
mockServiceProvider
.Setup(p => p.GetService(typeof(IServiceContainer)))
.Returns(otherContainer);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), service, true);
Assert.Same(otherService, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
Assert.Same(service, otherContainer.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObjectNoPromote_ReturnsExpected()
{
object service = new();
object otherService = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), service, false);
Assert.Same(service, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallback_ReturnsExpected()
{
object service = new();
ServiceCreatorCallback callback = (c, serviceType) =>
{
Assert.Same(typeof(object), serviceType);
return service;
};
object otherService = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), callback);
Assert.Same(service, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallbackPromote_ReturnsExpected()
{
object service = new();
ServiceCreatorCallback callback = (c, serviceType) =>
{
Assert.Same(typeof(object), serviceType);
return service;
};
object otherService = new();
ServiceContainer otherContainer = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
mockServiceProvider
.Setup(p => p.GetService(typeof(IServiceContainer)))
.Returns(otherContainer);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), callback, true);
Assert.Same(otherService, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
Assert.Same(service, otherContainer.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallbackNoPromote_ReturnsExpected()
{
object service = new();
ServiceCreatorCallback callback = (c, serviceType) =>
{
Assert.Same(typeof(object), serviceType);
return service;
};
object otherService = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(object)))
.Returns(otherService);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IServiceContainer container = Assert.IsAssignableFrom<IServiceContainer>(component.Site);
container.AddService(typeof(object), callback, false);
Assert.Same(service, container.GetService(typeof(object)));
Assert.Same(otherService, surface.GetService(typeof(object)));
}
public static IEnumerable<object[]> AddComponentISiteName_Set_TestData()
{
foreach (object[] testData in Add_InvalidNameCreationServiceParentProvider_TestData())
{
foreach (string oldName in new string[] { null, string.Empty, "oldName" })
{
yield return new object[] { testData[0], oldName, null, string.Empty };
yield return new object[] { testData[0], oldName, string.Empty, string.Empty };
yield return new object[] { testData[0], oldName, "name", "name" };
yield return new object[] { testData[0], oldName, "ldName", "ldName" };
yield return new object[] { testData[0], oldName, "ldName", "ldName" };
}
}
}
[WinFormsTheory]
[MemberData(nameof(AddComponentISiteName_Set_TestData))]
public void DesignerHost_AddComponentISiteName_SetRootComponent_GetReturnsExpected(IServiceProvider parentProvider, string oldName, string value, string expectedName)
{
using SubDesignSurface surface = new(parentProvider);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component, oldName);
component.Site.Name = value;
Assert.Same(expectedName, component.Site.Name);
Assert.Same(expectedName, host.RootComponentClassName);
// Set same.
component.Site.Name = value;
Assert.Same(expectedName, component.Site.Name);
Assert.Same(expectedName, host.RootComponentClassName);
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteName_SetDifferentCase_GetReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component, "name");
component.Site.Name = "NAME";
Assert.Equal("NAME", component.Site.Name);
// Set same.
component.Site.Name = "NAME";
Assert.Equal("NAME", component.Site.Name);
}
[WinFormsTheory]
[StringWithNullData]
public void DesignerHost_AddComponentISiteName_SetWithMultipleComponents_GetReturnsExpected(string value)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
using RootDesignerComponent component2 = new();
using RootDesignerComponent component3 = new();
host.Container.Add(component1);
host.Container.Add(component2, null);
host.Container.Add(component3, "name3");
component1.Site.Name = value;
Assert.Same(value ?? string.Empty, component1.Site.Name);
// Set same.
component1.Site.Name = value;
Assert.Same(value ?? string.Empty, component1.Site.Name);
}
public static IEnumerable<object[]> AddComponentISiteName_SetWithNamespaceInRootComponentClassName_TestData()
{
yield return new object[] { string.Empty, "oldName", null, string.Empty, string.Empty };
yield return new object[] { string.Empty, "oldName", string.Empty, string.Empty, string.Empty };
yield return new object[] { string.Empty, "oldName", "newName", "newName", "newName" };
yield return new object[] { "oldName", "oldName", null, string.Empty, string.Empty };
yield return new object[] { "oldName", "oldName", string.Empty, string.Empty, string.Empty };
yield return new object[] { "oldName", "oldName", "newName", "newName", "newName" };
yield return new object[] { "oldName", "oldName", "oldName", "oldName", "oldName" };
yield return new object[] { "namespace.oldName", "oldName", null, string.Empty, "namespace." };
yield return new object[] { "namespace.oldName", "oldName", string.Empty, string.Empty, "namespace." };
yield return new object[] { "namespace.oldName", "oldName", "newName", "newName", "namespace.newName" };
yield return new object[] { "namespace.oldName", "oldName", "oldName", "oldName", "namespace.oldName" };
yield return new object[] { "namespace.oldName", "ldName", "ldName", "ldName", "namespace.oldName" };
yield return new object[] { "namespace.oldName", "namespace.oldName", null, string.Empty, string.Empty };
yield return new object[] { "namespace.oldName", "namespace.oldName", string.Empty, string.Empty, string.Empty };
yield return new object[] { "namespace.oldName", "namespace.oldName", "newName", "newName", "newName" };
yield return new object[] { "namespace.oldName", "namespace.oldName", "oldName", "oldName", "oldName" };
yield return new object[] { "namespace.oldName", "namespace.oldName", "ldName", "ldName", "ldName" };
yield return new object[] { "namespace.oldName", "name", null, string.Empty, string.Empty };
yield return new object[] { "namespace.oldName", "name", string.Empty, string.Empty, string.Empty };
yield return new object[] { "namespace.oldName", "name", "newName", "newName", "newName" };
yield return new object[] { "namespace.oldName", "name", "oldName", "oldName", "oldName" };
}
[WinFormsTheory]
[MemberData(nameof(AddComponentISiteName_SetWithNamespaceInRootComponentClassName_TestData))]
public void DesignerHost_AddComponentISiteName_SetWithNamespaceInRootComponentClassName_GetReturnsExpected(string oldRootComponentClassName, string oldName, string value, string expectedName, string expectedRootComponentClassName)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.EndLoad(oldRootComponentClassName, true, null);
Assert.Equal(oldRootComponentClassName, host.RootComponentClassName);
Assert.Null(host.RootComponent);
host.Container.Add(component, oldName);
Assert.Equal(oldName, component.Site.Name);
Assert.Equal(oldRootComponentClassName, host.RootComponentClassName);
Assert.Same(component, host.RootComponent);
component.Site.Name = value;
Assert.Equal(expectedName, component.Site.Name);
Assert.Equal(expectedRootComponentClassName, host.RootComponentClassName);
Assert.Same(component, host.RootComponent);
}
[WinFormsTheory]
[StringWithNullData]
public void DesignerHost_AddComponentISiteName_SetNameWithComponentRename_CallsHandler(string value)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
using RootDesignerComponent component = new();
int callCount = 0;
ComponentRenameEventHandler handler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component, e.Component);
Assert.Equal("oldName", e.OldName);
Assert.Same(value ?? string.Empty, e.NewName);
callCount++;
};
changeService.ComponentRename += handler;
host.Container.Add(component, "oldName");
component.Site.Name = value;
Assert.Same(value ?? string.Empty, component.Site.Name);
Assert.Equal(1, callCount);
// Set same.
component.Site.Name = value;
Assert.Same(value ?? string.Empty, component.Site.Name);
Assert.Equal(1, callCount);
// Remove handler.
changeService.ComponentRename -= handler;
component.Site.Name = "name";
Assert.Equal("name", component.Site.Name);
Assert.Equal(1, callCount);
}
[WinFormsTheory]
[InlineData(null, "", 1)]
[InlineData("", "", 1)]
[InlineData("newName", "newName", 1)]
[InlineData("OLDNAME", "OLDNAME", 0)]
public void DesignerHost_AddComponentISite_SetNameWithINameCreateService_CallsValidateName(string value, string expectedName, int expectedCallCount)
{
Mock<INameCreationService> mockNameCreationService = new(MockBehavior.Strict);
mockNameCreationService
.Setup(s => s.ValidateName("oldName"))
.Verifiable();
mockNameCreationService
.Setup(s => s.ValidateName(expectedName))
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(mockNameCreationService.Object);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component, "oldName");
Assert.Equal("oldName", component.Site.Name);
mockNameCreationService.Verify(s => s.ValidateName("oldName"), Times.Once());
component.Site.Name = value;
Assert.Equal(expectedName, component.Site.Name);
mockNameCreationService.Verify(s => s.ValidateName(expectedName), Times.Exactly(expectedCallCount));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteName_SetSameAsOtherComponent_GetReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component1 = new();
using RootDesignerComponent component2 = new();
host.Container.Add(component1, "name1");
host.Container.Add(component2, "name2");
Assert.Throws<InvalidOperationException>(() => component1.Site.Name = "name2");
Assert.Throws<InvalidOperationException>(() => component1.Site.Name = "NAME2");
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_Invoke_ReturnsExpected()
{
object service = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(int)))
.Returns(service);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(service, component.Site.GetService(typeof(int)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_InvokeWithNestedContainer_ReturnsService()
{
object service = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(int)))
.Returns(service);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
INestedContainer nestedContainer = Assert.IsAssignableFrom<INestedContainer>(component.Site.GetService(typeof(INestedContainer)));
Assert.Same(service, component.Site.GetService(typeof(int)));
Assert.Same(component.Site, component.Site.GetService(typeof(IDictionaryService)));
Assert.Same(nestedContainer, component.Site.GetService(typeof(INestedContainer)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_INestedContainer_ReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
INestedContainer container = Assert.IsAssignableFrom<INestedContainer>(component.Site.GetService(typeof(INestedContainer)));
Assert.Same(container, component.Site.GetService(typeof(INestedContainer)));
Assert.Empty(container.Components);
Assert.Same(component, container.Owner);
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetServiceINestedContainerGetService_Invoke_ReturnsExpected()
{
object service = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(DesignerCommandSet)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IInheritanceService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(int)))
.Returns(service);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
NestedContainer container = Assert.IsAssignableFrom<NestedContainer>(component.Site.GetService(typeof(INestedContainer)));
using Component nestedComponent = new();
container.Add(nestedComponent);
Assert.Same(service, nestedComponent.Site.GetService(typeof(int)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_IDictionaryService_ReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component.Site, component.Site.GetService(typeof(IDictionaryService)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_IServiceContainerReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(surface.ServiceContainer, component.Site.GetService(typeof(IServiceContainer)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_IContainerReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(host, component.Site.GetService(typeof(IContainer)));
}
[WinFormsFact]
public void DesignerHost_AddComponentISiteGetService_NullServiceType_ThrowsArgumentNullException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.Throws<ArgumentNullException>("service", () => component.Site.GetService(null));
}
[WinFormsFact]
public void DesignerHost_Add_IComponentWithComponentAddingAndAdded_CallsHandler()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
using RootDesignerComponent component = new();
int componentAddingCallCount = 0;
ComponentEventHandler componentAddingHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component, e.Component);
componentAddingCallCount++;
};
changeService.ComponentAdding += componentAddingHandler;
int componentAddedCallCount = 0;
ComponentEventHandler componentAddedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component, e.Component);
Assert.True(componentAddedCallCount < componentAddingCallCount);
componentAddedCallCount++;
};
changeService.ComponentAdded += componentAddedHandler;
// With handler.
host.Container.Add(component);
Assert.Same(host.Container, component.Container);
Assert.Equal(1, componentAddingCallCount);
Assert.Equal(1, componentAddedCallCount);
// Add again.
host.Container.Add(component);
Assert.Same(host.Container, component.Container);
Assert.Equal(1, componentAddingCallCount);
Assert.Equal(1, componentAddedCallCount);
// Remove handler.
changeService.ComponentAdding -= componentAddingHandler;
changeService.ComponentAdded -= componentAddedHandler;
host.Container.Add(component);
Assert.Same(host.Container, component.Container);
Assert.Equal(1, componentAddingCallCount);
Assert.Equal(1, componentAddedCallCount);
}
public static IEnumerable<object[]> Add_NoRootDesigner_TestData()
{
yield return new object[] { new Component() };
yield return new object[] { new DesignerComponent() };
}
[WinFormsTheory]
[MemberData(nameof(Add_NoRootDesigner_TestData))]
public void DesignerHost_Add_NoRootDesigner_ThrowsException(IComponent component)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Throws<NotImplementedException>(() => host.Container.Add(component));
Assert.Throws<NotImplementedException>(() => host.Container.Add(component, "name"));
Assert.Empty(host.Container.Components);
}
[WinFormsFact]
public void DesignerHost_Add_CyclicRootDesigner_ThrowsException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component, component.GetType().FullName);
Assert.Equal(component.GetType().FullName, host.RootComponentClassName);
Assert.Throws<InvalidOperationException>(() => host.Container.Add(component));
Assert.Throws<InvalidOperationException>(() => host.Container.Add(new RootDesignerComponent(), host.RootComponentClassName));
}
[WinFormsFact]
public void DesignerHost_Add_NonInitializingRootDesigner_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using NonInitializingDesignerComponent component = new();
Assert.Throws<InvalidOperationException>(() => host.Container.Add(component));
Assert.Throws<InvalidOperationException>(() => host.Container.Add(component, "name"));
}
[WinFormsFact]
public void DesignerHost_Add_ThrowingInitializingRootDesigner_RethrowsException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using ThrowingInitializingDesignerComponent component = new();
Assert.Throws<DivideByZeroException>(() => host.Container.Add(component));
Assert.Null(component.Container);
Assert.Null(component.Site);
Assert.Throws<DivideByZeroException>(() => host.Container.Add(component, "name"));
Assert.Null(component.Container);
Assert.Null(component.Site);
}
[WinFormsFact]
public void DesignerHost_Add_CheckoutExceptionThrowingInitializingRootDesigner_RethrowsException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using CheckoutExceptionThrowingInitializingDesignerComponent component = new();
// CheckoutException does not bubble up in xunit.
bool threwCheckoutException = false;
try
{
host.Container.Add(component);
}
catch (CheckoutException)
{
threwCheckoutException = true;
}
Assert.True(threwCheckoutException);
Assert.Same(host.Container, component.Container);
Assert.Empty(component.Site.Name);
host.Container.Add(component, "name");
Assert.Same(host.Container, component.Container);
Assert.Equal("name", component.Site.Name);
}
[WinFormsFact]
public void DesignerHost_AddService_InvokeObject_GetServiceReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
object service = new();
host.AddService(typeof(object), service);
Assert.Same(service, surface.ServiceContainer.GetService(typeof(object)));
Assert.Same(service, surface.GetService(typeof(object)));
Assert.Same(service, host.GetService(typeof(object)));
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_AddService_InvokeObjectBool_GetServiceReturnsExpected(bool promote)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
object service = new();
host.AddService(typeof(object), service, promote);
Assert.Same(service, surface.ServiceContainer.GetService(typeof(object)));
Assert.Same(service, surface.GetService(typeof(object)));
Assert.Same(service, host.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddService_InvokeCallback_GetServiceReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
object service = new();
ServiceCreatorCallback callback = (container, serviceType) => service;
host.AddService(typeof(object), callback);
Assert.Same(service, surface.ServiceContainer.GetService(typeof(object)));
Assert.Same(service, surface.GetService(typeof(object)));
Assert.Same(service, host.GetService(typeof(object)));
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_AddService_InvokeObjectCallback_GetServiceReturnsExpected(bool promote)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
object service = new();
ServiceCreatorCallback callback = (container, serviceType) => service;
host.AddService(typeof(object), callback, promote);
Assert.Same(service, surface.ServiceContainer.GetService(typeof(object)));
Assert.Same(service, surface.GetService(typeof(object)));
Assert.Same(service, host.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_AddService_InvokeDisposed_ThrowsObjectDisposedException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.Dispose();
ServiceCreatorCallback callback = (container, service) => new object();
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), new object()));
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), new object(), true));
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), new object(), false));
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), callback));
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), callback, true));
Assert.Throws<ObjectDisposedException>(() => host.AddService(typeof(object), callback, false));
}
[WinFormsFact]
public void DesignerHost_Dispose_Invoke_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IDisposable disposable = Assert.IsAssignableFrom<IDisposable>(host);
Assert.Throws<InvalidOperationException>(disposable.Dispose);
}
[WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")]
public void DesignerHost_Add_DesignerDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.BeginLoad(typeof(RootDesignerComponent));
using ThrowingDesignerDisposeComponent component = new();
host.Container.Add(component);
Assert.Throws<InvalidOperationException>(surface.Dispose);
Assert.False(surface.IsLoaded);
Assert.Empty(surface.LoadErrors);
Assert.False(host.Loading);
}
[WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1151")]
public void DesignerHost_Add_ComponentDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.BeginLoad(typeof(RootDesignerComponent));
using ThrowingDisposeDesignerComponent component = new();
host.Container.Add(component);
Assert.Throws<InvalidOperationException>(surface.Dispose);
Assert.False(surface.IsLoaded);
Assert.Empty(surface.LoadErrors);
Assert.False(host.Loading);
}
[WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")]
public void DesignerHost_Add_RootDesignerDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.BeginLoad(typeof(ThrowingRootDesignerDisposeComponent));
Assert.Throws<InvalidOperationException>(surface.Dispose);
Assert.False(surface.IsLoaded);
Assert.Empty(surface.LoadErrors);
Assert.False(host.Loading);
}
[WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")]
public void DesignerHost_Add_RootComponentDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.BeginLoad(typeof(ThrowingDisposeRootDesignerComponent));
Assert.Throws<InvalidOperationException>(surface.Dispose);
Assert.False(surface.IsLoaded);
Assert.Empty(surface.LoadErrors);
Assert.False(host.Loading);
}
[WinFormsFact]
public void DesignerHost_CreateComponent_NullComponentType_ThrowsArgumentNullException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Throws<ArgumentNullException>("componentType", () => host.CreateComponent(null));
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_Invoke_ReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction();
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("No Description Available", transaction1.Description);
Assert.True(host.InTransaction);
Assert.Equal("No Description Available", host.TransactionDescription);
DesignerTransaction transaction2 = host.CreateTransaction();
Assert.False(transaction2.Canceled);
Assert.False(transaction2.Committed);
Assert.Equal("No Description Available", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("No Description Available", host.TransactionDescription);
transaction2.Cancel();
}
[WinFormsTheory]
[InlineData(null, "No Description Available")]
[InlineData("", "")]
[InlineData("Description", "Description")]
public void DesignerHost_CreateTransaction_InvokeWithDescription_ReturnsExpected(string description, string expectedDescription)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction(description);
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal(expectedDescription, transaction1.Description);
Assert.True(host.InTransaction);
Assert.Equal(expectedDescription, host.TransactionDescription);
DesignerTransaction transaction2 = host.CreateTransaction("CustomDescription");
Assert.False(transaction2.Canceled);
Assert.False(transaction2.Committed);
Assert.Equal("CustomDescription", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("CustomDescription", host.TransactionDescription);
transaction2.Cancel();
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_InvokeWithTransactionOpeningAndTransactionOpened_CallsHandlers()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
int openingCallCount = 0;
EventHandler openingHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(EventArgs.Empty, e);
openingCallCount++;
};
int openedCallCount = 0;
EventHandler openedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(EventArgs.Empty, e);
Assert.True(openedCallCount < openingCallCount);
openedCallCount++;
};
host.TransactionOpening += openingHandler;
host.TransactionOpened += openedHandler;
// With handler.
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
Assert.Equal(1, openingCallCount);
Assert.Equal(1, openedCallCount);
// Create again.
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
Assert.Equal(2, openingCallCount);
Assert.Equal(2, openedCallCount);
// Remove handler.
host.TransactionOpening -= openingHandler;
host.TransactionOpened -= openedHandler;
DesignerTransaction transaction3 = host.CreateTransaction("Description2");
Assert.Equal(2, openingCallCount);
Assert.Equal(2, openedCallCount);
transaction3.Cancel();
transaction2.Cancel();
transaction1.Cancel();
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_Cancel_Success()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
// Cancel first.
transaction2.Cancel();
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.True(transaction2.Canceled);
Assert.False(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("Description1", host.TransactionDescription);
// Cancel again.
transaction2.Cancel();
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.True(transaction2.Canceled);
Assert.False(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("Description1", host.TransactionDescription);
// Cancel second.
transaction1.Cancel();
Assert.True(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.True(transaction2.Canceled);
Assert.False(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.False(host.InTransaction);
host.TransactionDescription.Should().BeNullOrEmpty();
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_CancelWithTransactionClosingAndTransactionClosed_CallsHandlers()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
bool expectedLastTransaction = false;
int closingCallCount = 0;
DesignerTransactionCloseEventHandler closingHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.False(e.TransactionCommitted);
Assert.Equal(expectedLastTransaction, e.LastTransaction);
closingCallCount++;
};
int closedCallCount = 0;
DesignerTransactionCloseEventHandler closedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.False(e.TransactionCommitted);
Assert.Equal(expectedLastTransaction, e.LastTransaction);
Assert.True(closedCallCount < closingCallCount);
closedCallCount++;
};
host.TransactionClosing += closingHandler;
host.TransactionClosed += closedHandler;
// With handler.
transaction2.Cancel();
Assert.False(transaction1.Canceled);
Assert.True(transaction2.Canceled);
Assert.Equal(1, closingCallCount);
Assert.Equal(1, closedCallCount);
// Cancel again.
transaction2.Cancel();
Assert.False(transaction1.Canceled);
Assert.True(transaction2.Canceled);
Assert.Equal(1, closingCallCount);
Assert.Equal(1, closedCallCount);
// Cancel second.
expectedLastTransaction = true;
transaction1.Cancel();
Assert.True(transaction1.Canceled);
Assert.True(transaction2.Canceled);
Assert.Equal(2, closingCallCount);
Assert.Equal(2, closedCallCount);
// Remove handler.
host.TransactionClosing -= closingHandler;
host.TransactionClosed -= closedHandler;
DesignerTransaction transaction3 = host.CreateTransaction("Description1");
transaction3.Cancel();
Assert.True(transaction3.Canceled);
Assert.Equal(2, closingCallCount);
Assert.Equal(2, closedCallCount);
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_CancelNested_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
Assert.Throws<InvalidOperationException>(transaction1.Cancel);
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_Commit_Success()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
// Commit first.
transaction2.Commit();
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.False(transaction2.Canceled);
Assert.True(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("Description1", host.TransactionDescription);
// Commit again.
transaction2.Commit();
Assert.False(transaction1.Canceled);
Assert.False(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.False(transaction2.Canceled);
Assert.True(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.True(host.InTransaction);
Assert.Equal("Description1", host.TransactionDescription);
// Commit second.
transaction1.Commit();
Assert.False(transaction1.Canceled);
Assert.True(transaction1.Committed);
Assert.Equal("Description1", transaction1.Description);
Assert.False(transaction2.Canceled);
Assert.True(transaction2.Committed);
Assert.Equal("Description2", transaction2.Description);
Assert.False(host.InTransaction);
host.TransactionDescription.Should().BeNullOrEmpty();
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_CommitWithTransactionClosingAndTransactionClosed_CallsHandlers()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
bool expectedLastTransaction = false;
int closingCallCount = 0;
DesignerTransactionCloseEventHandler closingHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.True(e.TransactionCommitted);
Assert.Equal(expectedLastTransaction, e.LastTransaction);
closingCallCount++;
};
int closedCallCount = 0;
DesignerTransactionCloseEventHandler closedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.True(e.TransactionCommitted);
Assert.Equal(expectedLastTransaction, e.LastTransaction);
Assert.True(closedCallCount < closingCallCount);
closedCallCount++;
};
host.TransactionClosing += closingHandler;
host.TransactionClosed += closedHandler;
// With handler.
transaction2.Commit();
Assert.False(transaction1.Committed);
Assert.True(transaction2.Committed);
Assert.Equal(1, closingCallCount);
Assert.Equal(1, closedCallCount);
// Commit again.
transaction2.Commit();
Assert.False(transaction1.Committed);
Assert.True(transaction2.Committed);
Assert.Equal(1, closingCallCount);
Assert.Equal(1, closedCallCount);
// Commit second.
expectedLastTransaction = true;
transaction1.Commit();
Assert.True(transaction1.Committed);
Assert.True(transaction2.Committed);
Assert.Equal(2, closingCallCount);
Assert.Equal(2, closedCallCount);
// Remove handler.
host.TransactionClosing -= closingHandler;
host.TransactionClosed -= closedHandler;
DesignerTransaction transaction3 = host.CreateTransaction("Description1");
transaction3.Commit();
Assert.True(transaction3.Committed);
Assert.Equal(2, closingCallCount);
Assert.Equal(2, closedCallCount);
}
[WinFormsFact]
public void DesignerHost_CreateTransaction_CommitNested_ThrowsInvalidOperationException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
DesignerTransaction transaction1 = host.CreateTransaction("Description1");
DesignerTransaction transaction2 = host.CreateTransaction("Description2");
Assert.Throws<InvalidOperationException>(transaction1.Commit);
}
public static IEnumerable<object[]> DesignerHost_EndLoad_TestData()
{
yield return new object[] { null, true, null };
yield return new object[] { null, true, Array.Empty<object>() };
yield return new object[] { null, true, new object[] { new InvalidOperationException() } };
yield return new object[] { null, true, new object[] { "abc" } };
yield return new object[] { null, true, new object[] { null } };
yield return new object[] { null, false, null };
yield return new object[] { null, false, Array.Empty<object>() };
yield return new object[] { null, false, new object[] { new InvalidOperationException() } };
yield return new object[] { null, false, new object[] { "abc" } };
yield return new object[] { null, false, new object[] { null } };
yield return new object[] { string.Empty, true, null };
yield return new object[] { string.Empty, true, Array.Empty<object>() };
yield return new object[] { string.Empty, true, new object[] { new InvalidOperationException() } };
yield return new object[] { string.Empty, true, new object[] { "abc" } };
yield return new object[] { string.Empty, true, new object[] { null } };
yield return new object[] { string.Empty, false, null };
yield return new object[] { string.Empty, false, Array.Empty<object>() };
yield return new object[] { string.Empty, false, new object[] { new InvalidOperationException() } };
yield return new object[] { string.Empty, false, new object[] { "abc" } };
yield return new object[] { string.Empty, false, new object[] { null } };
yield return new object[] { "baseClassName", true, null };
yield return new object[] { "baseClassName", true, new object[] { new InvalidOperationException() } };
yield return new object[] { "baseClassName", true, new object[] { "abc" } };
yield return new object[] { "baseClassName", true, new object[] { null } };
yield return new object[] { "baseClassName", false, null };
yield return new object[] { "baseClassName", false, new object[] { new InvalidOperationException() } };
yield return new object[] { "baseClassName", false, new object[] { "abc" } };
yield return new object[] { "baseClassName", false, new object[] { null } };
}
[WinFormsTheory]
[MemberData(nameof(DesignerHost_EndLoad_TestData))]
public void DesignerHost_EndLoad_NotCalledBeginLoad_Success(string baseClassName, bool successful, ICollection errorCollection)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.EndLoad(baseClassName, successful, errorCollection);
Assert.False(surface.IsLoaded);
Assert.False(host.Loading);
Assert.Empty(surface.LoadErrors);
Assert.Null(host.RootComponent);
Assert.Same(baseClassName, host.RootComponentClassName);
}
[WinFormsFact]
public void DesignerHost_GetComponents_Invoke_ReturnsFiltered()
{
ComponentCollection collection = new(new Component[] { new() });
Mock<ContainerFilterService> mockFilterService = new(MockBehavior.Strict);
mockFilterService
.Setup(f => f.FilterComponents(new ComponentCollection(Array.Empty<IComponent>())))
.Returns(collection);
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(mockFilterService.Object);
using SubDesignSurface surface = new(mockServiceProvider.Object);
Assert.Same(collection, surface.ComponentContainer.Components);
}
[WinFormsFact]
public void DesignerHost_GetDesigner_InvokeNonEmpty_ReturnsExpected()
{
using SubDesignSurface surface = new();
IDesignerHost host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
Assert.IsType<RootDesigner>(host.GetDesigner(component));
Assert.Null(host.GetDesigner(new Component()));
Assert.Null(host.GetDesigner(new RootDesignerComponent()));
}
[WinFormsFact]
public void DesignerHost_GetDesigner_InvokeEmpty_ReturnsExpected()
{
using SubDesignSurface surface = new();
IDesignerHost host = surface.Host;
Assert.Null(host.GetDesigner(new Component()));
Assert.Null(host.GetDesigner(new RootDesignerComponent()));
}
[WinFormsFact]
public void DesignerHost_GetDesigner_NullComponent_ThrowsArgumentNullException()
{
using SubDesignSurface surface = new();
IDesignerHost host = surface.Host;
Assert.Throws<ArgumentNullException>("component", () => host.GetDesigner(null));
}
public static IEnumerable<object[]> GetService_InvalidLoader_TestData()
{
Mock<DesignerLoader> mockLoader = new(MockBehavior.Strict);
mockLoader
.Setup(l => l.BeginLoad(It.IsAny<IDesignerLoaderHost>()));
yield return new object[] { mockLoader.Object, null };
Mock<DesignerLoader> mockNullServiceProviderLoader = new(MockBehavior.Strict);
mockNullServiceProviderLoader
.Setup(l => l.BeginLoad(It.IsAny<IDesignerLoaderHost>()));
mockNullServiceProviderLoader
.As<IServiceProvider>()
.Setup(p => p.GetService(typeof(IMultitargetHelperService)))
.Returns(null);
yield return new object[] { mockNullServiceProviderLoader.Object, null };
object o = new();
Mock<DesignerLoader> mockInvalidServiceProviderLoader = new(MockBehavior.Strict);
mockInvalidServiceProviderLoader
.Setup(l => l.BeginLoad(It.IsAny<IDesignerLoaderHost>()));
mockInvalidServiceProviderLoader
.As<IServiceProvider>()
.Setup(p => p.GetService(typeof(IMultitargetHelperService)))
.Returns(o);
yield return new object[] { mockInvalidServiceProviderLoader.Object, o };
}
[WinFormsTheory]
[MemberData(nameof(GetService_InvalidLoader_TestData))]
public void DesignerHost_GetService_IMultitargetHelperServiceWithLoader_ReturnsExpected(DesignerLoader loader, object expected)
{
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(IDesignerEventService)))
.Returns(null);
SubDesignSurface surface = new(mockServiceProvider.Object);
surface.BeginLoad(loader);
IDesignerLoaderHost2 host = surface.Host;
Assert.Same(expected, host.GetService(typeof(IMultitargetHelperService)));
}
[WinFormsFact]
public void DesignerHost_GetServiceIMultitargetHelperServiceWithoutLoader_ReturnsNull()
{
object service = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
Assert.Null(host.GetService(typeof(IMultitargetHelperService)));
}
[WinFormsFact]
public void DesignerHost_GetService_InvokeWithServiceProvider_ReturnsExpected()
{
object service = new();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(int)))
.Returns(service)
.Verifiable();
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
Assert.Same(service, host.GetService(typeof(int)));
mockServiceProvider.Verify(p => p.GetService(typeof(int)), Times.Once());
}
[WinFormsFact]
public void DesignerHost_GetService_InvokeWithoutServiceProvider_ReturnsNull()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Null(host.GetService(typeof(int)));
}
[WinFormsFact]
public void DesignerHost_GetService_IContainer_ReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Same(host, host.GetService(typeof(IContainer)));
}
[WinFormsTheory]
[InlineData(typeof(IServiceContainer))]
[InlineData(typeof(ServiceContainer))]
public void DesignerHost_GetService_IServiceContainer_ReturnsExpected(Type serviceType)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Same(surface.ServiceContainer, host.GetService(serviceType));
}
[WinFormsFact]
public void DesignerHost_GetService_NullType_ThrowsArgumentNullException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
Assert.Throws<ArgumentNullException>("service", () => host.GetService(null));
}
[WinFormsTheory]
[InlineData("", null)]
[InlineData("", typeof(int))]
[InlineData("typeName", null)]
[InlineData("typeName", typeof(int))]
[InlineData("System.Object", null)]
[InlineData("System.Object", typeof(int))]
public void DesignerHost_GetType_InvokeWithTypeResolutionService_ReturnsExpected(string typeName, Type expected)
{
Mock<ITypeResolutionService> mockTypeResolutionService = new(MockBehavior.Strict);
mockTypeResolutionService
.Setup(s => s.GetType(typeName))
.Returns(expected)
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(mockTypeResolutionService.Object)
.Verifiable();
using SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerHost host = surface.Host;
Assert.Equal(expected, host.GetType(typeName));
mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once());
mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Once());
}
public static IEnumerable<object[]> GetType_InvalidTypeResolutionService_TestData()
{
yield return new object[] { null };
yield return new object[] { new() };
}
[WinFormsTheory]
[MemberData(nameof(GetType_InvalidTypeResolutionService_TestData))]
public void DesignerHost_GetType_InvokeWithInvalidTypeResolutionService_ReturnsExpected(object service)
{
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(service)
.Verifiable();
using SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerHost host = surface.Host;
Assert.Equal(typeof(int), host.GetType(typeof(int).FullName));
mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once());
}
[WinFormsFact]
public void DesignerHost_GetType_NullTypeName_ThrowsArgumentNullException()
{
using SubDesignSurface surface = new();
IDesignerHost host = surface.Host;
Assert.Throws<ArgumentNullException>("typeName", () => host.GetType(null));
}
private static readonly IDesignerHost s_placeholderHost = new Mock<IDesignerHost>(MockBehavior.Strict).Object;
public static IEnumerable<object[]> ChangeActiveDesigner_TestData()
{
IDesignerLoaderHost2 otherHost = new SubDesignSurface().Host;
yield return new object[] { null, 0, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, s_placeholderHost), 0, 1, 1 };
yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, otherHost), 0, 1, 1 };
yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, null), 0, 1, 1 };
yield return new object[] { new ActiveDesignerEventArgs(otherHost, s_placeholderHost), 1, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(otherHost, otherHost), 0, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(otherHost, null), 0, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(null, s_placeholderHost), 1, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(null, otherHost), 0, 0, 0 };
yield return new object[] { new ActiveDesignerEventArgs(null, null), 0, 0, 0 };
}
[WinFormsTheory]
[MemberData(nameof(ChangeActiveDesigner_TestData))]
public void DesignerHost_ChangeActiveDesigner_Invoke_Success(ActiveDesignerEventArgs eventArgs, int expectedActivatedCallCount, int expectedDeactivatedCallCount, int expectedFlushCount)
{
Mock<IDesignerEventService> mockDesignerEventService = new(MockBehavior.Strict);
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(IDesignerEventService)))
.Returns(mockDesignerEventService.Object);
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
int activatedCallCount = 0;
EventHandler activatedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(EventArgs.Empty, e);
activatedCallCount++;
};
host.Activated += activatedHandler;
int deactivatedCallCount = 0;
EventHandler deactivatedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(EventArgs.Empty, e);
deactivatedCallCount++;
};
host.Deactivated += deactivatedHandler;
int flushCallCount = 0;
EventHandler flushedHandler = (sender, e) =>
{
Assert.Same(surface, sender);
Assert.Same(EventArgs.Empty, e);
flushCallCount++;
};
surface.Flushed += flushedHandler;
Mock<DesignerLoader> mockLoader = new(MockBehavior.Strict);
mockLoader
.Setup(l => l.BeginLoad((IDesignerLoaderHost)surface.ComponentContainer));
mockLoader
.Setup(l => l.Flush());
surface.BeginLoad(mockLoader.Object);
Assert.Equal(0, activatedCallCount);
Assert.Equal(0, deactivatedCallCount);
Assert.Equal(0, flushCallCount);
// Replace placeholders for "this"
ActiveDesignerEventArgs actualEventArgs = null;
if (eventArgs is not null)
{
IDesignerHost newDesigner = eventArgs.NewDesigner == s_placeholderHost ? host : eventArgs.NewDesigner;
IDesignerHost oldDesigner = eventArgs.OldDesigner == s_placeholderHost ? host : eventArgs.OldDesigner;
actualEventArgs = new ActiveDesignerEventArgs(oldDesigner, newDesigner);
}
mockDesignerEventService.Raise(s => s.ActiveDesignerChanged += null, actualEventArgs);
Assert.Equal(expectedActivatedCallCount, activatedCallCount);
Assert.Equal(expectedDeactivatedCallCount, deactivatedCallCount);
Assert.Equal(expectedFlushCount, flushCallCount);
// Should not invoke if removed.
host.Activated -= activatedHandler;
host.Deactivated -= deactivatedHandler;
surface.Flushed -= flushedHandler;
mockDesignerEventService.Raise(s => s.ActiveDesignerChanged += null, actualEventArgs);
Assert.Equal(expectedActivatedCallCount, activatedCallCount);
Assert.Equal(expectedDeactivatedCallCount, deactivatedCallCount);
Assert.Equal(expectedFlushCount, flushCallCount);
}
[WinFormsFact]
public void DesignerHost_Remove_Invoke_Success()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent rootComponent = new();
using DesignerComponent component = new();
host.Container.Add(rootComponent);
host.Container.Add(component);
host.Container.Remove(rootComponent);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Null(host.RootComponent);
Assert.Null(host.RootComponentClassName);
Assert.Null(host.GetDesigner(rootComponent));
Assert.NotNull(host.GetDesigner(component));
Assert.Null(rootComponent.Container);
Assert.Null(rootComponent.Site);
Assert.Same(host.Container, component.Container);
Assert.NotNull(component.Site);
// Remove again.
host.Container.Remove(rootComponent);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Null(host.RootComponent);
Assert.Null(host.RootComponentClassName);
Assert.Null(host.GetDesigner(rootComponent));
Assert.NotNull(host.GetDesigner(component));
Assert.Null(rootComponent.Container);
Assert.Null(rootComponent.Site);
Assert.Same(host.Container, component.Container);
Assert.NotNull(component.Site);
// Remove other.
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
Assert.Null(host.RootComponent);
Assert.Null(host.RootComponentClassName);
Assert.Null(host.GetDesigner(rootComponent));
Assert.Null(host.GetDesigner(component));
Assert.Null(rootComponent.Container);
Assert.Null(rootComponent.Site);
Assert.Null(component.Container);
Assert.Null(component.Site);
}
public static IEnumerable<object[]> Remove_IExtenderProviderServiceWithoutDefault_TestData()
{
yield return new object[] { new RootDesignerComponent(), 0, 0 };
yield return new object[] { new RootExtenderProviderDesignerComponent(), 1, 1 };
RootExtenderProviderDesignerComponent readOnlyComponent = new();
TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly));
yield return new object[] { readOnlyComponent, 0, 1 };
RootExtenderProviderDesignerComponent inheritedComponent = new();
TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited));
yield return new object[] { inheritedComponent, 1, 1 };
RootExtenderProviderDesignerComponent notInheritedComponent = new();
TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited));
yield return new object[] { notInheritedComponent, 1, 1 };
}
[WinFormsTheory]
[MemberData(nameof(Remove_IExtenderProviderServiceWithoutDefault_TestData))]
public void DesignerHost_Remove_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedAddCallCount, int expectedRemoveCallCount)
{
Mock<IExtenderProviderService> mockExtenderProviderService = new(MockBehavior.Strict);
mockExtenderProviderService
.Setup(s => s.AddExtenderProvider(component as IExtenderProvider));
mockExtenderProviderService
.Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider))
.Verifiable();
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(mockExtenderProviderService.Object)
.Verifiable();
using SubDesignSurface surface = new(mockServiceProvider.Object);
surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService));
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Same(host, component.Container);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount));
// Remove.
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
Assert.Null(component.Container);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount));
mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount));
// Remove again.
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
Assert.Null(component.Container);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount));
mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount));
}
public static IEnumerable<object[]> Remove_IExtenderProviderServiceWithDefault_TestData()
{
yield return new object[] { new RootDesignerComponent() };
yield return new object[] { new RootExtenderProviderDesignerComponent() };
RootExtenderProviderDesignerComponent readOnlyComponent = new();
TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly));
yield return new object[] { readOnlyComponent };
RootExtenderProviderDesignerComponent inheritedComponent = new();
TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited));
yield return new object[] { inheritedComponent };
RootExtenderProviderDesignerComponent notInheritedComponent = new();
TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited));
yield return new object[] { notInheritedComponent };
}
[WinFormsTheory]
[MemberData(nameof(Remove_IExtenderProviderServiceWithDefault_TestData))]
public void DesignerHost_Remove_IExtenderProviderServiceWithDefault_Success(Component component)
{
Mock<IExtenderProviderService> mockExtenderProviderService = new(MockBehavior.Strict);
mockExtenderProviderService
.Setup(s => s.AddExtenderProvider(component as IExtenderProvider))
.Verifiable();
mockExtenderProviderService
.Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider));
Mock<IServiceProvider> mockServiceProvider = new(MockBehavior.Strict);
mockServiceProvider
.Setup(p => p.GetService(typeof(ITypeResolutionService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(TypeDescriptionProviderService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(INameCreationService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(ContainerFilterService)))
.Returns(null);
mockServiceProvider
.Setup(p => p.GetService(typeof(IExtenderProviderService)))
.Returns(mockExtenderProviderService.Object)
.Verifiable();
SubDesignSurface surface = new(mockServiceProvider.Object);
IDesignerLoaderHost2 host = surface.Host;
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
Assert.Empty(component.Site.Name);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never());
// Remove.
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
Assert.Null(component.Container);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never());
// Remove again.
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
Assert.Null(component.Container);
mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never());
}
[WinFormsTheory]
[MemberData(nameof(InvalidIExtenderProviderService_TestData))]
public void DesignerHost_Remove_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock<IServiceProvider> mockParentProvider)
{
using SubDesignSurface surface = new(mockParentProvider?.Object);
surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService));
IDesignerLoaderHost2 host = surface.Host;
using RootExtenderProviderDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once());
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(2));
}
[WinFormsTheory]
[MemberData(nameof(InvalidIExtenderProviderService_TestData))]
public void DesignerHost_Remove_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock<IServiceProvider> mockParentProvider)
{
using SubDesignSurface surface = new(mockParentProvider?.Object);
IDesignerLoaderHost2 host = surface.Host;
using RootExtenderProviderDesignerComponent component = new();
host.Container.Add(component);
Assert.Same(component, Assert.Single(host.Container.Components));
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
host.Container.Remove(component);
Assert.Empty(host.Container.Components);
mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never());
}
[WinFormsFact]
public void Remove_ComponentNotInContainerNonEmpty_Nop()
{
using SubDesignSurface surface1 = new();
using SubDesignSurface surface2 = new();
IDesignerLoaderHost2 host1 = surface1.Host;
IDesignerLoaderHost2 host2 = surface2.Host;
RootDesignerComponent otherComponent = new();
using RootDesignerComponent component = new();
host1.Container.Add(otherComponent);
host2.Container.Add(component);
host2.Container.Remove(otherComponent);
host2.Container.Remove(new Component());
Assert.Same(otherComponent, Assert.Single(host1.Container.Components));
Assert.Same(component, Assert.Single(host2.Container.Components));
}
[WinFormsFact]
public void Remove_ComponentNotInContainerEmpty_Nop()
{
using SubDesignSurface surface1 = new();
using SubDesignSurface surface2 = new();
IDesignerLoaderHost2 host1 = surface1.Host;
IDesignerLoaderHost2 host2 = surface2.Host;
using RootDesignerComponent otherComponent = new();
host1.Container.Add(otherComponent);
host2.Container.Remove(otherComponent);
host2.Container.Remove(new Component());
Assert.Same(otherComponent, Assert.Single(host1.Container.Components));
Assert.Empty(host2.Container.Components);
}
[WinFormsFact]
public void Remove_InvokeWithComponentRemoved_CallsHandler()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
using RootDesignerComponent component1 = new();
using DesignerComponent component2 = new();
int componentRemovingCallCount = 0;
ComponentEventHandler componentRemovingHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component1, e.Component);
Assert.NotNull(e.Component.Site);
componentRemovingCallCount++;
};
changeService.ComponentRemoving += componentRemovingHandler;
int componentRemovedCallCount = 0;
ComponentEventHandler componentRemovedHandler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component1, e.Component);
Assert.NotNull(e.Component.Site);
Assert.True(componentRemovedCallCount < componentRemovingCallCount);
componentRemovedCallCount++;
};
changeService.ComponentRemoved += componentRemovedHandler;
host.Container.Add(component1);
host.Container.Add(component2);
// With handler.
host.Container.Remove(component1);
Assert.Null(component1.Container);
Assert.Null(component1.Site);
Assert.Same(host.Container, component2.Container);
Assert.NotNull(component2.Site);
Assert.Same(component2, Assert.Single(host.Container.Components));
Assert.Equal(1, componentRemovingCallCount);
Assert.Equal(1, componentRemovedCallCount);
// Remove again.
host.Container.Remove(component1);
Assert.Null(component1.Container);
Assert.Null(component1.Site);
Assert.Same(host.Container, component2.Container);
Assert.NotNull(component2.Site);
Assert.Same(component2, Assert.Single(host.Container.Components));
Assert.Equal(1, componentRemovingCallCount);
Assert.Equal(1, componentRemovedCallCount);
// Remove handler.
changeService.ComponentRemoving -= componentRemovingHandler;
changeService.ComponentRemoved -= componentRemovedHandler;
host.Container.Remove(component2);
Assert.Null(component1.Container);
Assert.Null(component1.Site);
Assert.Null(component2.Container);
Assert.Null(component2.Site);
Assert.Empty(host.Container.Components);
Assert.Equal(1, componentRemovingCallCount);
Assert.Equal(1, componentRemovedCallCount);
}
[WinFormsFact]
public void DesignerHost_Remove_SetSiteToNullInComponentRemoving_Success()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
using RootDesignerComponent component = new();
int componentRemovingCallCount = 0;
ComponentEventHandler componentRemovingHandler = (sender, e) =>
{
component.Site = null;
componentRemovingCallCount++;
};
changeService.ComponentRemoving += componentRemovingHandler;
host.Container.Add(component);
host.Container.Remove(component);
Assert.Null(component.Container);
Assert.Null(component.Site);
}
[WinFormsFact]
public void DesignerHost_Remove_SiteHasDictionary_ClearsDictionary()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
using RootDesignerComponent component = new();
host.Container.Add(component);
IDictionaryService service = Assert.IsAssignableFrom<IDictionaryService>(component.Site);
service.SetValue("key", "value");
Assert.Equal("value", service.GetValue("key"));
host.Container.Remove(component);
Assert.Null(service.GetValue("key"));
}
[WinFormsFact]
public void DesignerHost_RemoveService_Invoke_GetServiceReturnsExpected()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.AddService(typeof(object), new object());
host.RemoveService(typeof(object));
Assert.Null(surface.ServiceContainer.GetService(typeof(object)));
Assert.Null(surface.GetService(typeof(object)));
Assert.Null(host.GetService(typeof(object)));
}
[WinFormsTheory]
[BoolData]
public void DesignerHost_RemoveService_InvokeBool_GetServiceReturnsExpected(bool promote)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
host.AddService(typeof(object), new object());
host.RemoveService(typeof(object), promote);
Assert.Null(surface.ServiceContainer.GetService(typeof(object)));
Assert.Null(surface.GetService(typeof(object)));
Assert.Null(host.GetService(typeof(object)));
}
[WinFormsFact]
public void DesignerHost_RemoveService_InvokeDisposed_ThrowsObjectDisposedException()
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
surface.Dispose();
ServiceCreatorCallback callback = (container, service) => new object();
Assert.Throws<ObjectDisposedException>(() => host.RemoveService(typeof(object)));
Assert.Throws<ObjectDisposedException>(() => host.RemoveService(typeof(object), true));
Assert.Throws<ObjectDisposedException>(() => host.RemoveService(typeof(object), false));
}
public static IEnumerable<object[]> OnComponentChanging_TestData()
{
yield return new object[] { null, null };
yield return new object[] { new(), TypeDescriptor.GetProperties(typeof(string))[0] };
}
[WinFormsTheory]
[MemberData(nameof(OnComponentChanging_TestData))]
public void DesignerHost_IComponentChangeServiceOnComponentChanging_Invoke_CallsComponentChanging(object component, MemberDescriptor member)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
int callCount = 0;
ComponentChangingEventHandler handler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component, e.Component);
Assert.Same(member, e.Member);
callCount++;
};
changeService.ComponentChanging += handler;
Assert.False(host.Loading);
// With handler.
changeService.OnComponentChanging(component, member);
Assert.Equal(1, callCount);
// Call again.
changeService.OnComponentChanging(component, member);
Assert.Equal(2, callCount);
// Remove handler.
changeService.ComponentChanging -= handler;
changeService.OnComponentChanging(component, member);
Assert.Equal(2, callCount);
}
[WinFormsTheory]
[MemberData(nameof(OnComponentChanging_TestData))]
public void DesignerHost_IComponentChangeServiceOnComponentChanging_InvokeLoading_DoesNotCallHandler(object component, MemberDescriptor member)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
int callCount = 0;
ComponentChangingEventHandler handler = (sender, e) => callCount++;
changeService.ComponentChanging += handler;
Mock<DesignerLoader> mockLoader = new(MockBehavior.Strict);
mockLoader
.Setup(l => l.BeginLoad(host));
surface.BeginLoad(mockLoader.Object);
Assert.True(host.Loading);
// With handler.
changeService.OnComponentChanging(component, member);
Assert.Equal(0, callCount);
// Call again.
changeService.OnComponentChanging(component, member);
Assert.Equal(0, callCount);
// Remove handler.
changeService.ComponentChanging -= handler;
changeService.OnComponentChanging(component, member);
Assert.Equal(0, callCount);
}
public static IEnumerable<object[]> OnComponentChanged_TestData()
{
yield return new object[] { null, null, null, null };
yield return new object[] { new(), TypeDescriptor.GetProperties(typeof(string))[0], new(), new() };
}
[WinFormsTheory]
[MemberData(nameof(OnComponentChanged_TestData))]
public void DesignerHost_IComponentChangeServiceOnComponentChanged_Invoke_CallsComponentChanged(object component, MemberDescriptor member, object oldValue, object newValue)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
int callCount = 0;
ComponentChangedEventHandler handler = (sender, e) =>
{
Assert.Same(host, sender);
Assert.Same(component, e.Component);
Assert.Same(member, e.Member);
Assert.Same(oldValue, e.OldValue);
Assert.Same(newValue, e.NewValue);
callCount++;
};
changeService.ComponentChanged += handler;
Assert.False(host.Loading);
// With handler.
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(1, callCount);
// Call again.
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(2, callCount);
// Remove handler.
changeService.ComponentChanged -= handler;
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(2, callCount);
}
[WinFormsTheory]
[MemberData(nameof(OnComponentChanged_TestData))]
public void DesignerHost_IComponentChangeServiceOnComponentChanged_InvokeLoading_DoesNotCallHandler(object component, MemberDescriptor member, object oldValue, object newValue)
{
SubDesignSurface surface = new();
IDesignerLoaderHost2 host = surface.Host;
IComponentChangeService changeService = Assert.IsAssignableFrom<IComponentChangeService>(host);
int callCount = 0;
ComponentChangedEventHandler handler = (sender, e) => callCount++;
changeService.ComponentChanged += handler;
Mock<DesignerLoader> mockLoader = new(MockBehavior.Strict);
mockLoader
.Setup(l => l.BeginLoad(host));
surface.BeginLoad(mockLoader.Object);
Assert.True(host.Loading);
// With handler.
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(0, callCount);
// Call again.
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(0, callCount);
// Remove handler.
changeService.ComponentChanged -= handler;
changeService.OnComponentChanged(component, member, oldValue, newValue);
Assert.Equal(0, callCount);
}
[WinFormsFact]
public void DesignerHost_IReflect_UnderlyingSystemType_ReturnsExpected()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost), reflect.UnderlyingSystemType);
}
[WinFormsFact]
public void DesignerHost_IReflect_GetField_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetField(nameof(IDesignerHost.Activate)), reflect.GetField(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetFields_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetFields(), reflect.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetMember_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetMember(nameof(IDesignerHost.Container)), reflect.GetMember(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetMembers_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetMembers(), reflect.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetMethod_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetMethod(nameof(IDesignerHost.Activate)), reflect.GetMethod(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
Assert.Equal(typeof(IDesignerHost).GetMethod(nameof(IDesignerHost.Activate)), reflect.GetMethod(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, Array.Empty<Type>(), Array.Empty<ParameterModifier>()));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetMethods_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetMethods(), reflect.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetProperty_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetProperty(nameof(IDesignerHost.Container)), reflect.GetProperty(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
Assert.Equal(typeof(IDesignerHost).GetProperty(nameof(IDesignerHost.Container)), reflect.GetProperty(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, typeof(IContainer), Array.Empty<Type>(), Array.Empty<ParameterModifier>()));
}
[WinFormsFact]
public void DesignerHost_IReflect_GetProperties_Success()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(typeof(IDesignerHost).GetProperties(), reflect.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public));
}
[WinFormsFact]
public void DesignerHost_IReflect_InvokeMember_ReturnsExpected()
{
using SubDesignSurface surface = new();
IReflect reflect = Assert.IsAssignableFrom<IReflect>(surface.Host);
Assert.Equal(surface.Host.Container, reflect.InvokeMember(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty, null, surface.Host, Array.Empty<object>(), Array.Empty<ParameterModifier>(), null, Array.Empty<string>()));
}
private class SubDesignSurface : DesignSurface
{
public SubDesignSurface() : base()
{
}
public SubDesignSurface(IServiceProvider parentProvider) : base(parentProvider)
{
}
public IDesignerLoaderHost2 Host => Assert.IsAssignableFrom<IDesignerLoaderHost2>(ComponentContainer);
public new ServiceContainer ServiceContainer => base.ServiceContainer;
}
private abstract class CustomDesigner : IDesigner
{
protected IComponent _initializedComponent;
public IComponent Component => _initializedComponent;
public DesignerVerbCollection Verbs { get; }
public void DoDefaultAction()
{
}
public void Dispose() => Dispose(true);
protected virtual void Dispose(bool disposing)
{
}
public abstract void Initialize(IComponent component);
}
private class Designer : CustomDesigner
{
public override void Initialize(IComponent component) => _initializedComponent = component;
}
[Designer(typeof(Designer))]
private class DesignerComponent : Component
{
}
private class RootDesigner : Designer, IRootDesigner
{
public ViewTechnology[] SupportedTechnologies { get; }
public object GetView(ViewTechnology technology) => throw new NotImplementedException();
}
[Designer(typeof(RootDesigner), typeof(IRootDesigner))]
private class RootDesignerComponent : Component
{
}
[ProjectTargetFramework("ProjectTargetFramework")]
private class ClassWithProjectTargetFrameworkAttribute
{
}
[Designer(typeof(RootDesigner), typeof(IRootDesigner))]
private class RootExtenderProviderDesignerComponent : Component, IExtenderProvider
{
public bool CanExtend(object extendee) => throw new NotImplementedException();
}
private class NonInitializingDesigner : RootDesigner
{
public override void Initialize(IComponent component)
{
}
}
[Designer(typeof(NonInitializingDesigner), typeof(IRootDesigner))]
private class NonInitializingDesignerComponent : Component
{
}
private class ThrowingInitializingDesigner : RootDesigner
{
public override void Initialize(IComponent component)
{
throw new DivideByZeroException();
}
}
[Designer(typeof(ThrowingInitializingDesigner), typeof(IRootDesigner))]
private class ThrowingInitializingDesignerComponent : Component
{
}
private class CheckoutExceptionThrowingInitializingDesigner : RootDesigner
{
public override void Initialize(IComponent component)
{
throw CheckoutException.Canceled;
}
}
[Designer(typeof(CheckoutExceptionThrowingInitializingDesigner), typeof(IRootDesigner))]
private class CheckoutExceptionThrowingInitializingDesignerComponent : Component
{
}
private class ThrowingDisposeComponentDesigner : Designer
{
protected override void Dispose(bool disposing)
{
throw new NotImplementedException();
}
}
[Designer(typeof(ThrowingDisposeComponentDesigner))]
private class ThrowingDesignerDisposeComponent : Component
{
}
[Designer(typeof(Designer))]
private class ThrowingDisposeDesignerComponent : Component
{
protected override void Dispose(bool disposing)
{
if (disposing)
{
throw new NotImplementedException();
}
}
}
private class ThrowingDisposeRootComponentDesigner : RootDesigner
{
protected override void Dispose(bool disposing)
{
throw new NotImplementedException();
}
}
[Designer(typeof(ThrowingDisposeRootComponentDesigner), typeof(IRootDesigner))]
private class ThrowingRootDesignerDisposeComponent : Component
{
}
[Designer(typeof(RootDesigner), typeof(IRootDesigner))]
private class ThrowingDisposeRootDesignerComponent : Component
{
protected override void Dispose(bool disposing)
{
if (disposing)
{
throw new NotImplementedException();
}
}
}
[Designer(typeof(RootDesigner), typeof(IRootDesigner))]
private class CustomTypeDescriptionProviderComponent : Component
{
}
}
|