Jo Shields 3c1f479b9d Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
2015-04-07 09:35:12 +01:00

769 lines
22 KiB
C#

//
// System.ComponentModel.Container test cases
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
// Ivan N. Zlatev (contact i-nZ.net)
// Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
// Copyright (c) 2006 Ivan N. Zlatev
//
#if !MOBILE
using NUnit.Framework;
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
namespace MonoTests.System.ComponentModel
{
class TestService {
}
class TestContainer : Container {
ServiceContainer _services = new ServiceContainer ();
bool allowDuplicateNames;
public TestContainer()
{
_services.AddService (typeof (TestService), new TestService ());
}
public bool AllowDuplicateNames {
get { return allowDuplicateNames; }
set { allowDuplicateNames = value; }
}
protected override object GetService (Type serviceType)
{
return _services.GetService (serviceType);
}
public new void RemoveWithoutUnsiting (IComponent component)
{
base.RemoveWithoutUnsiting (component);
}
public void InvokeValidateName (IComponent component, string name)
{
ValidateName (component, name);
}
protected override void ValidateName (IComponent component, string name)
{
if (AllowDuplicateNames)
return;
base.ValidateName (component, name);
}
public bool Contains (IComponent component)
{
bool found = false;
foreach (IComponent c in Components) {
if (component.Equals (c)) {
found = true;
break;
}
}
return found;
}
public new void Dispose (bool disposing)
{
base.Dispose (disposing);
}
}
class TestComponent : Component {
public override ISite Site {
get {
return base.Site;
}
set {
base.Site = value;
if (value != null) {
Assert.IsNotNull (value.GetService (typeof (ISite)), "ISite");
Assert.IsNotNull (value.GetService (typeof (TestService)), "TestService");
}
}
}
public bool IsDisposed {
get { return disposed; }
}
public bool ThrowOnDispose {
get { return throwOnDispose; }
set { throwOnDispose = value; }
}
protected override void Dispose (bool disposing)
{
if (ThrowOnDispose)
throw new InvalidOperationException ();
base.Dispose (disposing);
disposed = true;
}
private bool disposed;
private bool throwOnDispose;
}
[TestFixture]
public class ContainerTest
{
private TestContainer _container;
[SetUp]
public void Init ()
{
_container = new TestContainer ();
}
[Test] // Add (IComponent)
public void Add1 ()
{
TestContainer containerA = new TestContainer ();
TestContainer containerB = new TestContainer ();
ISite siteA;
ISite siteB;
TestComponent compA = new TestComponent ();
Assert.IsNull (compA.Site);
TestComponent compB = new TestComponent ();
Assert.IsNull (compB.Site);
Assert.AreEqual (0, containerA.Components.Count);
Assert.AreEqual (0, containerB.Components.Count);
containerA.Add (compA);
siteA = compA.Site;
Assert.IsNotNull (siteA);
Assert.AreSame (compA, siteA.Component);
Assert.AreSame (containerA, siteA.Container);
Assert.IsFalse (siteA.DesignMode);
Assert.IsNull (siteA.Name);
containerA.Add (compB);
siteB = compB.Site;
Assert.IsNotNull (siteB);
Assert.AreSame (compB, siteB.Component);
Assert.AreSame (containerA, siteB.Container);
Assert.IsFalse (siteB.DesignMode);
Assert.IsNull (siteB.Name);
Assert.IsFalse (object.ReferenceEquals (siteA, siteB));
Assert.AreEqual (2, containerA.Components.Count);
Assert.AreEqual (0, containerB.Components.Count);
Assert.AreSame (compA, containerA.Components [0]);
Assert.AreSame (compB, containerA.Components [1]);
// check effect of adding component that is already member of
// another container
containerB.Add (compA);
Assert.IsFalse (object.ReferenceEquals (siteA, compA.Site));
siteA = compA.Site;
Assert.IsNotNull (siteA);
Assert.AreSame (compA, siteA.Component);
Assert.AreSame (containerB, siteA.Container);
Assert.IsFalse (siteA.DesignMode);
Assert.IsNull (siteA.Name);
Assert.AreEqual (1, containerA.Components.Count);
Assert.AreEqual (1, containerB.Components.Count);
Assert.AreSame (compB, containerA.Components [0]);
Assert.AreSame (compA, containerB.Components [0]);
// check effect of add component twice to same container
containerB.Add (compA);
Assert.AreSame (siteA, compA.Site);
Assert.AreEqual (1, containerA.Components.Count);
Assert.AreEqual (1, containerB.Components.Count);
Assert.AreSame (compB, containerA.Components [0]);
Assert.AreSame (compA, containerB.Components [0]);
}
[Test]
public void Add1_Component_Null ()
{
_container.Add ((IComponent) null);
Assert.AreEqual (0, _container.Components.Count);
}
[Test] // Add (IComponent, String)
public void Add2 ()
{
TestContainer containerA = new TestContainer ();
TestContainer containerB = new TestContainer ();
ISite siteA;
ISite siteB;
TestComponent compA = new TestComponent ();
Assert.IsNull (compA.Site);
TestComponent compB = new TestComponent ();
Assert.IsNull (compB.Site);
Assert.AreEqual (0, containerA.Components.Count);
Assert.AreEqual (0, containerB.Components.Count);
containerA.Add (compA, "A");
siteA = compA.Site;
Assert.IsNotNull (siteA);
Assert.AreSame (compA, siteA.Component);
Assert.AreSame (containerA, siteA.Container);
Assert.IsFalse (siteA.DesignMode);
Assert.AreEqual ("A", siteA.Name);
containerA.Add (compB, "B");
siteB = compB.Site;
Assert.IsNotNull (siteB);
Assert.AreSame (compB, siteB.Component);
Assert.AreSame (containerA, siteB.Container);
Assert.IsFalse (siteB.DesignMode);
Assert.AreEqual ("B", siteB.Name);
Assert.IsFalse (object.ReferenceEquals (siteA, siteB));
Assert.AreEqual (2, containerA.Components.Count);
Assert.AreEqual (0, containerB.Components.Count);
Assert.AreSame (compA, containerA.Components [0]);
Assert.AreSame (compB, containerA.Components [1]);
// check effect of adding component that is already member of
// another container
containerB.Add (compA, "A2");
Assert.IsFalse (object.ReferenceEquals (siteA, compA.Site));
siteA = compA.Site;
Assert.IsNotNull (siteA);
Assert.AreSame (compA, siteA.Component);
Assert.AreSame (containerB, siteA.Container);
Assert.IsFalse (siteA.DesignMode);
Assert.AreEqual ("A2", siteA.Name);
Assert.AreEqual (1, containerA.Components.Count);
Assert.AreEqual (1, containerB.Components.Count);
Assert.AreSame (compB, containerA.Components [0]);
Assert.AreSame (compA, containerB.Components [0]);
// check effect of add component twice to same container
containerB.Add (compA, "A2");
Assert.AreSame (siteA, compA.Site);
Assert.AreEqual ("A2", siteA.Name);
Assert.AreEqual (1, containerA.Components.Count);
Assert.AreEqual (1, containerB.Components.Count);
Assert.AreSame (compB, containerA.Components [0]);
Assert.AreSame (compA, containerB.Components [0]);
// add again with different name
containerB.Add (compA, "A3");
Assert.AreSame (siteA, compA.Site);
Assert.AreEqual ("A2", siteA.Name);
Assert.AreEqual (1, containerA.Components.Count);
Assert.AreEqual (1, containerB.Components.Count);
Assert.AreSame (compB, containerA.Components [0]);
Assert.AreSame (compA, containerB.Components [0]);
// check effect of add component twice to same container
containerB.Add (compA, "A2");
Assert.AreSame (siteA, compA.Site);
Assert.AreEqual ("A2", siteA.Name);
}
[Test]
public void Add2_Component_Null ()
{
_container.Add ((IComponent) null, "A");
Assert.AreEqual (0, _container.Components.Count);
_container.Add (new TestComponent (), "A");
Assert.AreEqual (1, _container.Components.Count);
_container.Add ((IComponent) null, "A");
Assert.AreEqual (1, _container.Components.Count);
}
[Test]
public void Add2_Name_Duplicate ()
{
TestContainer container = new TestContainer ();
TestComponent c1 = new TestComponent ();
container.Add (c1, "dup");
// new component, same case
TestComponent c2 = new TestComponent ();
try {
container.Add (c2, "dup");
Assert.Fail ("#A1");
} catch (ArgumentException ex) {
// Duplicate component name 'dup'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#A5");
Assert.IsNull (ex.ParamName, "#A6");
Assert.AreEqual (1, container.Components.Count, "#A7");
}
// new component, different case
TestComponent c3 = new TestComponent ();
try {
container.Add (c3, "duP");
Assert.Fail ("#B1");
} catch (ArgumentException ex) {
// Duplicate component name 'duP'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
Assert.IsTrue (ex.Message.IndexOf ("'duP'") != -1, "#B5");
Assert.IsNull (ex.ParamName, "#B6");
Assert.AreEqual (1, container.Components.Count, "#B7");
}
// existing component, same case
TestComponent c4 = new TestComponent ();
container.Add (c4, "C4");
Assert.AreEqual (2, container.Components.Count, "#C1");
container.Add (c4, "dup");
Assert.AreEqual (2, container.Components.Count, "#C2");
Assert.AreEqual ("C4", c4.Site.Name, "#C3");
// component of other container, same case
TestContainer container2 = new TestContainer ();
TestComponent c5 = new TestComponent ();
container2.Add (c5, "C5");
try {
container.Add (c5, "dup");
Assert.Fail ("#D1");
} catch (ArgumentException ex) {
// Duplicate component name 'dup'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
Assert.IsNull (ex.InnerException, "#D3");
Assert.IsNotNull (ex.Message, "#D4");
Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#D5");
Assert.IsNull (ex.ParamName, "#D6");
Assert.AreEqual (2, container.Components.Count, "#D7");
}
Assert.AreEqual (1, container2.Components.Count, "#D8");
Assert.AreSame (c5, container2.Components [0], "#D9");
container.AllowDuplicateNames = true;
TestComponent c6 = new TestComponent ();
container.Add (c6, "dup");
Assert.AreEqual (3, container.Components.Count, "#E1");
Assert.IsNotNull (c1.Site, "#E2");
Assert.AreEqual ("dup", c1.Site.Name, "#E3");
Assert.IsNotNull (c6.Site, "#E4");
Assert.AreEqual ("dup", c6.Site.Name, "#E5");
Assert.IsFalse (object.ReferenceEquals (c1.Site, c6.Site), "#E6");
}
[Test]
public void AddRemove ()
{
TestComponent component = new TestComponent ();
_container.Add (component);
Assert.IsNotNull (component.Site, "#1");
Assert.IsTrue (_container.Contains (component), "#2");
_container.Remove (component);
Assert.IsNull (component.Site, "#3");
Assert.IsFalse (_container.Contains (component), "#4");
}
[Test] // Dispose ()
public void Dispose1 ()
{
TestComponent compA;
TestComponent compB;
compA = new TestComponent ();
_container.Add (compA);
compB = new TestComponent ();
_container.Add (compB);
_container.Dispose ();
Assert.AreEqual (0, _container.Components.Count, "#A1");
Assert.IsTrue (compA.IsDisposed, "#A2");
Assert.IsNull (compA.Site, "#A3");
Assert.IsTrue (compB.IsDisposed, "#A4");
Assert.IsNull (compB.Site, "#A5");
_container = new TestContainer ();
compA = new TestComponent ();
compA.ThrowOnDispose = true;
_container.Add (compA);
compB = new TestComponent ();
_container.Add (compB);
// assert that component is not removed from components until after
// Dispose of component has succeeded
try {
_container.Dispose ();
Assert.Fail ("#B1");
} catch (InvalidOperationException) {
Assert.AreEqual (0, _container.Components.Count, "#B2");
Assert.IsFalse (compA.IsDisposed, "#B4");
Assert.IsNull (compA.Site, "#B5");
Assert.IsTrue (compB.IsDisposed, "#B6");
Assert.IsNull (compB.Site, "#B7");
} finally {
compA.ThrowOnDispose = false;
}
_container = new TestContainer ();
compA = new TestComponent ();
_container.Add (compA);
compB = new TestComponent ();
compB.ThrowOnDispose = true;
_container.Add (compB);
try {
_container.Dispose ();
Assert.Fail ("#C1");
} catch (InvalidOperationException) {
Assert.AreEqual (1, _container.Components.Count, "#C2");
Assert.AreSame (compA, _container.Components [0], "#C3");
Assert.IsFalse (compA.IsDisposed, "#C4");
Assert.IsNotNull (compA.Site, "#C5");
Assert.IsFalse (compB.IsDisposed, "#C6");
Assert.IsNull (compB.Site, "#C7");
} finally {
compB.ThrowOnDispose = false;
}
}
[Test] // Dispose (Boolean)
public void Dispose2 ()
{
TestComponent compA;
TestComponent compB;
compA = new TestComponent ();
_container.Add (compA);
compB = new TestComponent ();
_container.Add (compB);
_container.Dispose (false);
Assert.AreEqual (2, _container.Components.Count, "#A1");
Assert.IsFalse (compA.IsDisposed, "#A2");
Assert.IsNotNull (compA.Site, "#A3");
Assert.IsFalse (compB.IsDisposed, "#A4");
Assert.IsNotNull (compB.Site, "#A5");
_container.Dispose (true);
Assert.AreEqual (0, _container.Components.Count, "#B1");
Assert.IsTrue (compA.IsDisposed, "#B2");
Assert.IsNull (compA.Site, "#B3");
Assert.IsTrue (compB.IsDisposed, "#B4");
Assert.IsNull (compB.Site, "#B5");
compA = new TestComponent ();
_container.Add (compA);
compB = new TestComponent ();
_container.Add (compB);
Assert.AreEqual (2, _container.Components.Count, "#C1");
Assert.IsFalse (compA.IsDisposed, "#C2");
Assert.IsNotNull (compA.Site, "#C3");
Assert.IsFalse (compB.IsDisposed, "#C4");
Assert.IsNotNull (compB.Site, "#C5");
_container.Dispose (true);
Assert.AreEqual (0, _container.Components.Count, "#D1");
Assert.IsTrue (compA.IsDisposed, "#D2");
Assert.IsNull (compA.Site, "#D3");
Assert.IsTrue (compB.IsDisposed, "#D4");
Assert.IsNull (compB.Site, "#D5");
}
[Test] // bug #522474
public void Dispose_Recursive ()
{
MyComponent comp = new MyComponent ();
Container container = comp.CreateContainer ();
comp.Dispose ();
Assert.AreEqual (0, container.Components.Count);
}
[Test]
public void GetService ()
{
object service;
GetServiceContainer container = new GetServiceContainer ();
container.Add (new MyComponent ());
service = container.GetService (typeof (MyComponent));
Assert.IsNull (service, "#1");
service = container.GetService (typeof (Component));
Assert.IsNull (service, "#2");
service = container.GetService (typeof (IContainer));
Assert.AreSame (container, service, "#3");
service = container.GetService ((Type) null);
Assert.IsNull (service, "#4");
}
[Test]
public void Remove ()
{
TestComponent compA;
TestComponent compB;
ISite siteA;
ISite siteB;
compA = new TestComponent ();
_container.Add (compA);
siteA = compA.Site;
compB = new TestComponent ();
_container.Add (compB);
siteB = compB.Site;
_container.Remove (compB);
Assert.AreSame (siteA, compA.Site, "#A1");
Assert.IsNull (compB.Site, "#A2");
Assert.AreEqual (1, _container.Components.Count, "#A3");
Assert.AreSame (compA, _container.Components [0], "#A4");
// remove component with no site
compB = new TestComponent ();
_container.Remove (compB);
Assert.AreSame (siteA, compA.Site, "#B1");
Assert.IsNull (compB.Site, "#B2");
Assert.AreEqual (1, _container.Components.Count, "#B3");
Assert.AreSame (compA, _container.Components [0], "#B4");
// remove component associated with other container
TestContainer container2 = new TestContainer ();
compB = new TestComponent ();
container2.Add (compB);
siteB = compB.Site;
_container.Remove (compB);
Assert.AreSame (siteA, compA.Site, "#C1");
Assert.AreSame (siteB, compB.Site, "#C2");
Assert.AreEqual (1, _container.Components.Count, "#C3");
Assert.AreSame (compA, _container.Components [0], "#C4");
Assert.AreEqual (1, container2.Components.Count, "#C5");
Assert.AreSame (compB, container2.Components [0], "#C6");
}
[Test]
public void Remove_Component_Null ()
{
_container.Add (new TestComponent ());
_container.Remove ((IComponent) null);
Assert.AreEqual (1, _container.Components.Count);
}
[Test]
public void RemoveWithoutUnsiting ()
{
TestComponent compA;
TestComponent compB;
ISite siteA;
ISite siteB;
compA = new TestComponent ();
_container.Add (compA);
siteA = compA.Site;
compB = new TestComponent ();
_container.Add (compB);
siteB = compB.Site;
_container.RemoveWithoutUnsiting (compB);
Assert.AreSame (siteA, compA.Site, "#A1");
Assert.AreSame (siteB, compB.Site, "#A2");
Assert.AreEqual (1, _container.Components.Count, "#A3");
Assert.AreSame (compA, _container.Components [0], "#A4");
// remove component with no site
compB = new TestComponent ();
_container.RemoveWithoutUnsiting (compB);
Assert.AreSame (siteA, compA.Site, "#B1");
Assert.IsNull (compB.Site, "#B2");
Assert.AreEqual (1, _container.Components.Count, "#B3");
Assert.AreSame (compA, _container.Components [0], "#B4");
// remove component associated with other container
TestContainer container2 = new TestContainer ();
compB = new TestComponent ();
container2.Add (compB);
siteB = compB.Site;
_container.RemoveWithoutUnsiting (compB);
Assert.AreSame (siteA, compA.Site, "#C1");
Assert.AreSame (siteB, compB.Site, "#C2");
Assert.AreEqual (1, _container.Components.Count, "#C3");
Assert.AreSame (compA, _container.Components [0], "#C4");
Assert.AreEqual (1, container2.Components.Count, "#C5");
Assert.AreSame (compB, container2.Components [0], "#C6");
}
[Test]
public void RemoveWithoutUnsiting_Component_Null ()
{
ISite site;
TestComponent component;
component = new TestComponent ();
_container.Add (component);
site = component.Site;
_container.RemoveWithoutUnsiting ((IComponent) null);
Assert.AreSame (site, component.Site, "#1");
Assert.AreEqual (1, _container.Components.Count, "#2");
Assert.AreSame (component, _container.Components [0], "#3");
}
[Test]
public void ValidateName_Component_Null ()
{
try {
_container.InvokeValidateName ((IComponent) null, "A");
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("component", ex.ParamName, "#5");
}
}
[Test]
public void ValidateName_Name_Null ()
{
TestComponent compA = new TestComponent ();
_container.Add (compA, (string) null);
TestComponent compB = new TestComponent ();
_container.InvokeValidateName (compB, (string) null);
}
[Test]
public void ValidateName_Name_Duplicate ()
{
TestComponent compA = new TestComponent ();
_container.Add (compA, "dup");
// same component, same case
_container.InvokeValidateName (compA, "dup");
// existing component, same case
TestComponent compB = new TestComponent ();
_container.Add (compB, "B");
try {
_container.InvokeValidateName (compB, "dup");
Assert.Fail ("#A1");
} catch (ArgumentException ex) {
// Duplicate component name 'duP'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#A5");
Assert.IsNull (ex.ParamName, "#A6");
Assert.AreEqual (2, _container.Components.Count, "#A7");
}
_container.InvokeValidateName (compB, "whatever");
// new component, different case
TestComponent compC = new TestComponent ();
try {
_container.InvokeValidateName (compC, "dup");
Assert.Fail ("#B1");
} catch (ArgumentException ex) {
// Duplicate component name 'duP'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#B5");
Assert.IsNull (ex.ParamName, "#B6");
Assert.AreEqual (2, _container.Components.Count, "#B7");
}
_container.InvokeValidateName (compC, "whatever");
// component of other container, different case
TestContainer container2 = new TestContainer ();
TestComponent compD = new TestComponent ();
container2.Add (compD, "B");
try {
_container.InvokeValidateName (compD, "dup");
Assert.Fail ("#C1");
} catch (ArgumentException ex) {
// Duplicate component name 'duP'. Component names must be
// unique and case-insensitive
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
Assert.IsNull (ex.InnerException, "#C3");
Assert.IsNotNull (ex.Message, "#C4");
Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#C5");
Assert.IsNull (ex.ParamName, "#C6");
Assert.AreEqual (2, _container.Components.Count, "#C7");
}
_container.InvokeValidateName (compD, "whatever");
Assert.AreEqual (1, container2.Components.Count, "#C8");
Assert.AreSame (compD, container2.Components [0], "#C9");
}
class MyComponent : Component
{
private Container container;
protected override void Dispose (bool disposing)
{
if (container != null)
container.Dispose ();
base.Dispose (disposing);
}
public Container CreateContainer ()
{
if (container != null)
throw new InvalidOperationException ();
container = new Container ();
container.Add (new MyComponent ());
container.Add (this);
return container;
}
}
class MyContainer : IContainer
{
private ComponentCollection components = new ComponentCollection (
new Component [0]);
public ComponentCollection Components {
get { return components; }
}
public void Add (IComponent component)
{
}
public void Add (IComponent component, string name)
{
}
public void Remove (IComponent component)
{
}
public void Dispose ()
{
}
}
public class GetServiceContainer : Container
{
public new object GetService (Type service)
{
return base.GetService (service);
}
}
}
}
#endif