Merge pull request #835 from HorstKakuschke/master
[mono.git] / mcs / class / System / Test / System.ComponentModel / ContainerTest.cs
index 7821ba85c03ca22c7d4538dafaa2bb671c2c571d..16a6a4124dccb83b45d44b3d889503340b92f153 100644 (file)
@@ -9,6 +9,8 @@
 // Copyright (c) 2006 Ivan N. Zlatev
 //
 
+#if !MOBILE
+
 using NUnit.Framework;
 using System;
 using System.ComponentModel;
@@ -20,23 +22,43 @@ namespace MonoTests.System.ComponentModel
        }
        
        class TestContainer : Container {
-               ServiceContainer _services = new ServiceContainer();
+               ServiceContainer _services = new ServiceContainer ();
+               bool allowDuplicateNames;
                
-               public TestContainer() {
-                       _services.AddService( typeof(TestService), new TestService() );
+               public TestContainer()
+               {
+                       _services.AddService (typeof (TestService), new TestService ());
                }
-               
-               protected override object GetService( Type serviceType ) {
-                       return _services.GetService( serviceType );
+
+               public bool AllowDuplicateNames {
+                       get { return allowDuplicateNames; }
+                       set { allowDuplicateNames = value; }
+               }
+
+               protected override object GetService (Type serviceType)
+               {
+                       return _services.GetService (serviceType);
                }
 
 #if NET_2_0
-               public void Remove_WithoutUnsiting (IComponent component)
+               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);
+               }
 #endif
-               
+
                public bool Contains (IComponent component)
                {
                        bool found = false;
@@ -49,6 +71,11 @@ namespace MonoTests.System.ComponentModel
                        }
                        return found;
                }
+
+               public new void Dispose (bool disposing)
+               {
+                       base.Dispose (disposing);
+               }
        }
        
        class TestComponent : Component {
@@ -59,26 +86,285 @@ namespace MonoTests.System.ComponentModel
                        set {
                                base.Site = value;
                                if (value != null) {
-                                       Assert.IsNotNull (value.GetService (typeof (ISite)));
-                                       Assert.IsNotNull (value.GetService (typeof (TestService)));
+                                       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");
+
+#if NET_2_0
+                       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");
+#endif
+               }
+
                [Test]
                public void AddRemove ()
                {
@@ -91,19 +377,402 @@ namespace MonoTests.System.ComponentModel
                        _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);
+               }
+
 #if NET_2_0
+               [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);
-                       _container.Remove_WithoutUnsiting (component);
-                       Assert.IsNotNull (component.Site, "#5");
-                       Assert.IsFalse (_container.Contains (component), "#6");
-#endif
+                       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 GetService1 ()
+               public void ValidateName_Component_Null ()
                {
-                       _container.Add (new TestComponent ());
+                       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");
+               }
+#endif
+
+               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;
+                       }
+
+                       public Container Container {
+                               get { 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