2 // System.ComponentModel.Container test cases
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Ivan N. Zlatev (contact i-nZ.net)
8 // Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
9 // Copyright (c) 2006 Ivan N. Zlatev
14 using NUnit.Framework;
16 using System.ComponentModel;
17 using System.ComponentModel.Design;
19 namespace MonoTests.System.ComponentModel
24 class TestContainer : Container {
25 ServiceContainer _services = new ServiceContainer ();
26 bool allowDuplicateNames;
28 public TestContainer()
30 _services.AddService (typeof (TestService), new TestService ());
33 public bool AllowDuplicateNames {
34 get { return allowDuplicateNames; }
35 set { allowDuplicateNames = value; }
38 protected override object GetService (Type serviceType)
40 return _services.GetService (serviceType);
44 public new void RemoveWithoutUnsiting (IComponent component)
46 base.RemoveWithoutUnsiting (component);
49 public void InvokeValidateName (IComponent component, string name)
51 ValidateName (component, name);
54 protected override void ValidateName (IComponent component, string name)
56 if (AllowDuplicateNames)
58 base.ValidateName (component, name);
62 public bool Contains (IComponent component)
66 foreach (IComponent c in Components) {
67 if (component.Equals (c)) {
75 public new void Dispose (bool disposing)
77 base.Dispose (disposing);
81 class TestComponent : Component {
82 public override ISite Site {
89 Assert.IsNotNull (value.GetService (typeof (ISite)), "ISite");
90 Assert.IsNotNull (value.GetService (typeof (TestService)), "TestService");
95 public bool IsDisposed {
96 get { return disposed; }
99 public bool ThrowOnDispose {
100 get { return throwOnDispose; }
101 set { throwOnDispose = value; }
104 protected override void Dispose (bool disposing)
107 throw new InvalidOperationException ();
109 base.Dispose (disposing);
113 private bool disposed;
114 private bool throwOnDispose;
118 public class ContainerTest
120 private TestContainer _container;
125 _container = new TestContainer ();
128 [Test] // Add (IComponent)
131 TestContainer containerA = new TestContainer ();
132 TestContainer containerB = new TestContainer ();
137 TestComponent compA = new TestComponent ();
138 Assert.IsNull (compA.Site);
139 TestComponent compB = new TestComponent ();
140 Assert.IsNull (compB.Site);
141 Assert.AreEqual (0, containerA.Components.Count);
142 Assert.AreEqual (0, containerB.Components.Count);
144 containerA.Add (compA);
146 Assert.IsNotNull (siteA);
147 Assert.AreSame (compA, siteA.Component);
148 Assert.AreSame (containerA, siteA.Container);
149 Assert.IsFalse (siteA.DesignMode);
150 Assert.IsNull (siteA.Name);
151 containerA.Add (compB);
153 Assert.IsNotNull (siteB);
154 Assert.AreSame (compB, siteB.Component);
155 Assert.AreSame (containerA, siteB.Container);
156 Assert.IsFalse (siteB.DesignMode);
157 Assert.IsNull (siteB.Name);
159 Assert.IsFalse (object.ReferenceEquals (siteA, siteB));
160 Assert.AreEqual (2, containerA.Components.Count);
161 Assert.AreEqual (0, containerB.Components.Count);
162 Assert.AreSame (compA, containerA.Components [0]);
163 Assert.AreSame (compB, containerA.Components [1]);
165 // check effect of adding component that is already member of
167 containerB.Add (compA);
168 Assert.IsFalse (object.ReferenceEquals (siteA, compA.Site));
170 Assert.IsNotNull (siteA);
171 Assert.AreSame (compA, siteA.Component);
172 Assert.AreSame (containerB, siteA.Container);
173 Assert.IsFalse (siteA.DesignMode);
174 Assert.IsNull (siteA.Name);
176 Assert.AreEqual (1, containerA.Components.Count);
177 Assert.AreEqual (1, containerB.Components.Count);
178 Assert.AreSame (compB, containerA.Components [0]);
179 Assert.AreSame (compA, containerB.Components [0]);
181 // check effect of add component twice to same container
182 containerB.Add (compA);
183 Assert.AreSame (siteA, compA.Site);
185 Assert.AreEqual (1, containerA.Components.Count);
186 Assert.AreEqual (1, containerB.Components.Count);
187 Assert.AreSame (compB, containerA.Components [0]);
188 Assert.AreSame (compA, containerB.Components [0]);
192 public void Add1_Component_Null ()
194 _container.Add ((IComponent) null);
195 Assert.AreEqual (0, _container.Components.Count);
198 [Test] // Add (IComponent, String)
201 TestContainer containerA = new TestContainer ();
202 TestContainer containerB = new TestContainer ();
207 TestComponent compA = new TestComponent ();
208 Assert.IsNull (compA.Site);
209 TestComponent compB = new TestComponent ();
210 Assert.IsNull (compB.Site);
211 Assert.AreEqual (0, containerA.Components.Count);
212 Assert.AreEqual (0, containerB.Components.Count);
214 containerA.Add (compA, "A");
216 Assert.IsNotNull (siteA);
217 Assert.AreSame (compA, siteA.Component);
218 Assert.AreSame (containerA, siteA.Container);
219 Assert.IsFalse (siteA.DesignMode);
220 Assert.AreEqual ("A", siteA.Name);
221 containerA.Add (compB, "B");
223 Assert.IsNotNull (siteB);
224 Assert.AreSame (compB, siteB.Component);
225 Assert.AreSame (containerA, siteB.Container);
226 Assert.IsFalse (siteB.DesignMode);
227 Assert.AreEqual ("B", siteB.Name);
229 Assert.IsFalse (object.ReferenceEquals (siteA, siteB));
230 Assert.AreEqual (2, containerA.Components.Count);
231 Assert.AreEqual (0, containerB.Components.Count);
232 Assert.AreSame (compA, containerA.Components [0]);
233 Assert.AreSame (compB, containerA.Components [1]);
235 // check effect of adding component that is already member of
237 containerB.Add (compA, "A2");
238 Assert.IsFalse (object.ReferenceEquals (siteA, compA.Site));
240 Assert.IsNotNull (siteA);
241 Assert.AreSame (compA, siteA.Component);
242 Assert.AreSame (containerB, siteA.Container);
243 Assert.IsFalse (siteA.DesignMode);
244 Assert.AreEqual ("A2", siteA.Name);
246 Assert.AreEqual (1, containerA.Components.Count);
247 Assert.AreEqual (1, containerB.Components.Count);
248 Assert.AreSame (compB, containerA.Components [0]);
249 Assert.AreSame (compA, containerB.Components [0]);
251 // check effect of add component twice to same container
252 containerB.Add (compA, "A2");
253 Assert.AreSame (siteA, compA.Site);
254 Assert.AreEqual ("A2", siteA.Name);
256 Assert.AreEqual (1, containerA.Components.Count);
257 Assert.AreEqual (1, containerB.Components.Count);
258 Assert.AreSame (compB, containerA.Components [0]);
259 Assert.AreSame (compA, containerB.Components [0]);
261 // add again with different name
262 containerB.Add (compA, "A3");
263 Assert.AreSame (siteA, compA.Site);
264 Assert.AreEqual ("A2", siteA.Name);
266 Assert.AreEqual (1, containerA.Components.Count);
267 Assert.AreEqual (1, containerB.Components.Count);
268 Assert.AreSame (compB, containerA.Components [0]);
269 Assert.AreSame (compA, containerB.Components [0]);
271 // check effect of add component twice to same container
272 containerB.Add (compA, "A2");
273 Assert.AreSame (siteA, compA.Site);
274 Assert.AreEqual ("A2", siteA.Name);
278 public void Add2_Component_Null ()
280 _container.Add ((IComponent) null, "A");
281 Assert.AreEqual (0, _container.Components.Count);
282 _container.Add (new TestComponent (), "A");
283 Assert.AreEqual (1, _container.Components.Count);
284 _container.Add ((IComponent) null, "A");
285 Assert.AreEqual (1, _container.Components.Count);
289 public void Add2_Name_Duplicate ()
291 TestContainer container = new TestContainer ();
292 TestComponent c1 = new TestComponent ();
293 container.Add (c1, "dup");
295 // new component, same case
296 TestComponent c2 = new TestComponent ();
298 container.Add (c2, "dup");
300 } catch (ArgumentException ex) {
301 // Duplicate component name 'dup'. Component names must be
302 // unique and case-insensitive
303 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
304 Assert.IsNull (ex.InnerException, "#A3");
305 Assert.IsNotNull (ex.Message, "#A4");
306 Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#A5");
307 Assert.IsNull (ex.ParamName, "#A6");
308 Assert.AreEqual (1, container.Components.Count, "#A7");
311 // new component, different case
312 TestComponent c3 = new TestComponent ();
314 container.Add (c3, "duP");
316 } catch (ArgumentException ex) {
317 // Duplicate component name 'duP'. Component names must be
318 // unique and case-insensitive
319 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
320 Assert.IsNull (ex.InnerException, "#B3");
321 Assert.IsNotNull (ex.Message, "#B4");
322 Assert.IsTrue (ex.Message.IndexOf ("'duP'") != -1, "#B5");
323 Assert.IsNull (ex.ParamName, "#B6");
324 Assert.AreEqual (1, container.Components.Count, "#B7");
327 // existing component, same case
328 TestComponent c4 = new TestComponent ();
329 container.Add (c4, "C4");
330 Assert.AreEqual (2, container.Components.Count, "#C1");
331 container.Add (c4, "dup");
332 Assert.AreEqual (2, container.Components.Count, "#C2");
333 Assert.AreEqual ("C4", c4.Site.Name, "#C3");
335 // component of other container, same case
336 TestContainer container2 = new TestContainer ();
337 TestComponent c5 = new TestComponent ();
338 container2.Add (c5, "C5");
340 container.Add (c5, "dup");
342 } catch (ArgumentException ex) {
343 // Duplicate component name 'dup'. Component names must be
344 // unique and case-insensitive
345 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
346 Assert.IsNull (ex.InnerException, "#D3");
347 Assert.IsNotNull (ex.Message, "#D4");
348 Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#D5");
349 Assert.IsNull (ex.ParamName, "#D6");
350 Assert.AreEqual (2, container.Components.Count, "#D7");
352 Assert.AreEqual (1, container2.Components.Count, "#D8");
353 Assert.AreSame (c5, container2.Components [0], "#D9");
356 container.AllowDuplicateNames = true;
357 TestComponent c6 = new TestComponent ();
358 container.Add (c6, "dup");
359 Assert.AreEqual (3, container.Components.Count, "#E1");
360 Assert.IsNotNull (c1.Site, "#E2");
361 Assert.AreEqual ("dup", c1.Site.Name, "#E3");
362 Assert.IsNotNull (c6.Site, "#E4");
363 Assert.AreEqual ("dup", c6.Site.Name, "#E5");
364 Assert.IsFalse (object.ReferenceEquals (c1.Site, c6.Site), "#E6");
369 public void AddRemove ()
371 TestComponent component = new TestComponent ();
373 _container.Add (component);
374 Assert.IsNotNull (component.Site, "#1");
375 Assert.IsTrue (_container.Contains (component), "#2");
377 _container.Remove (component);
378 Assert.IsNull (component.Site, "#3");
379 Assert.IsFalse (_container.Contains (component), "#4");
383 public void Dispose1 ()
388 compA = new TestComponent ();
389 _container.Add (compA);
390 compB = new TestComponent ();
391 _container.Add (compB);
393 _container.Dispose ();
395 Assert.AreEqual (0, _container.Components.Count, "#A1");
396 Assert.IsTrue (compA.IsDisposed, "#A2");
397 Assert.IsNull (compA.Site, "#A3");
398 Assert.IsTrue (compB.IsDisposed, "#A4");
399 Assert.IsNull (compB.Site, "#A5");
401 _container = new TestContainer ();
402 compA = new TestComponent ();
403 compA.ThrowOnDispose = true;
404 _container.Add (compA);
405 compB = new TestComponent ();
406 _container.Add (compB);
408 // assert that component is not removed from components until after
409 // Dispose of component has succeeded
411 _container.Dispose ();
413 } catch (InvalidOperationException) {
414 Assert.AreEqual (0, _container.Components.Count, "#B2");
415 Assert.IsFalse (compA.IsDisposed, "#B4");
416 Assert.IsNull (compA.Site, "#B5");
417 Assert.IsTrue (compB.IsDisposed, "#B6");
418 Assert.IsNull (compB.Site, "#B7");
420 compA.ThrowOnDispose = false;
423 _container = new TestContainer ();
424 compA = new TestComponent ();
425 _container.Add (compA);
426 compB = new TestComponent ();
427 compB.ThrowOnDispose = true;
428 _container.Add (compB);
431 _container.Dispose ();
433 } catch (InvalidOperationException) {
434 Assert.AreEqual (1, _container.Components.Count, "#C2");
435 Assert.AreSame (compA, _container.Components [0], "#C3");
436 Assert.IsFalse (compA.IsDisposed, "#C4");
437 Assert.IsNotNull (compA.Site, "#C5");
438 Assert.IsFalse (compB.IsDisposed, "#C6");
439 Assert.IsNull (compB.Site, "#C7");
441 compB.ThrowOnDispose = false;
445 [Test] // Dispose (Boolean)
446 public void Dispose2 ()
451 compA = new TestComponent ();
452 _container.Add (compA);
453 compB = new TestComponent ();
454 _container.Add (compB);
456 _container.Dispose (false);
458 Assert.AreEqual (2, _container.Components.Count, "#A1");
459 Assert.IsFalse (compA.IsDisposed, "#A2");
460 Assert.IsNotNull (compA.Site, "#A3");
461 Assert.IsFalse (compB.IsDisposed, "#A4");
462 Assert.IsNotNull (compB.Site, "#A5");
464 _container.Dispose (true);
466 Assert.AreEqual (0, _container.Components.Count, "#B1");
467 Assert.IsTrue (compA.IsDisposed, "#B2");
468 Assert.IsNull (compA.Site, "#B3");
469 Assert.IsTrue (compB.IsDisposed, "#B4");
470 Assert.IsNull (compB.Site, "#B5");
472 compA = new TestComponent ();
473 _container.Add (compA);
474 compB = new TestComponent ();
475 _container.Add (compB);
477 Assert.AreEqual (2, _container.Components.Count, "#C1");
478 Assert.IsFalse (compA.IsDisposed, "#C2");
479 Assert.IsNotNull (compA.Site, "#C3");
480 Assert.IsFalse (compB.IsDisposed, "#C4");
481 Assert.IsNotNull (compB.Site, "#C5");
483 _container.Dispose (true);
485 Assert.AreEqual (0, _container.Components.Count, "#D1");
486 Assert.IsTrue (compA.IsDisposed, "#D2");
487 Assert.IsNull (compA.Site, "#D3");
488 Assert.IsTrue (compB.IsDisposed, "#D4");
489 Assert.IsNull (compB.Site, "#D5");
492 [Test] // bug #522474
493 public void Dispose_Recursive ()
495 MyComponent comp = new MyComponent ();
496 Container container = comp.CreateContainer ();
498 Assert.AreEqual (0, container.Components.Count);
502 public void GetService ()
506 GetServiceContainer container = new GetServiceContainer ();
507 container.Add (new MyComponent ());
508 service = container.GetService (typeof (MyComponent));
509 Assert.IsNull (service, "#1");
510 service = container.GetService (typeof (Component));
511 Assert.IsNull (service, "#2");
512 service = container.GetService (typeof (IContainer));
513 Assert.AreSame (container, service, "#3");
514 service = container.GetService ((Type) null);
515 Assert.IsNull (service, "#4");
519 public void Remove ()
526 compA = new TestComponent ();
527 _container.Add (compA);
529 compB = new TestComponent ();
530 _container.Add (compB);
532 _container.Remove (compB);
533 Assert.AreSame (siteA, compA.Site, "#A1");
534 Assert.IsNull (compB.Site, "#A2");
535 Assert.AreEqual (1, _container.Components.Count, "#A3");
536 Assert.AreSame (compA, _container.Components [0], "#A4");
538 // remove component with no site
539 compB = new TestComponent ();
540 _container.Remove (compB);
541 Assert.AreSame (siteA, compA.Site, "#B1");
542 Assert.IsNull (compB.Site, "#B2");
543 Assert.AreEqual (1, _container.Components.Count, "#B3");
544 Assert.AreSame (compA, _container.Components [0], "#B4");
546 // remove component associated with other container
547 TestContainer container2 = new TestContainer ();
548 compB = new TestComponent ();
549 container2.Add (compB);
551 _container.Remove (compB);
552 Assert.AreSame (siteA, compA.Site, "#C1");
553 Assert.AreSame (siteB, compB.Site, "#C2");
554 Assert.AreEqual (1, _container.Components.Count, "#C3");
555 Assert.AreSame (compA, _container.Components [0], "#C4");
556 Assert.AreEqual (1, container2.Components.Count, "#C5");
557 Assert.AreSame (compB, container2.Components [0], "#C6");
561 public void Remove_Component_Null ()
563 _container.Add (new TestComponent ());
564 _container.Remove ((IComponent) null);
565 Assert.AreEqual (1, _container.Components.Count);
570 public void RemoveWithoutUnsiting ()
577 compA = new TestComponent ();
578 _container.Add (compA);
580 compB = new TestComponent ();
581 _container.Add (compB);
583 _container.RemoveWithoutUnsiting (compB);
584 Assert.AreSame (siteA, compA.Site, "#A1");
585 Assert.AreSame (siteB, compB.Site, "#A2");
586 Assert.AreEqual (1, _container.Components.Count, "#A3");
587 Assert.AreSame (compA, _container.Components [0], "#A4");
589 // remove component with no site
590 compB = new TestComponent ();
591 _container.RemoveWithoutUnsiting (compB);
592 Assert.AreSame (siteA, compA.Site, "#B1");
593 Assert.IsNull (compB.Site, "#B2");
594 Assert.AreEqual (1, _container.Components.Count, "#B3");
595 Assert.AreSame (compA, _container.Components [0], "#B4");
597 // remove component associated with other container
598 TestContainer container2 = new TestContainer ();
599 compB = new TestComponent ();
600 container2.Add (compB);
602 _container.RemoveWithoutUnsiting (compB);
603 Assert.AreSame (siteA, compA.Site, "#C1");
604 Assert.AreSame (siteB, compB.Site, "#C2");
605 Assert.AreEqual (1, _container.Components.Count, "#C3");
606 Assert.AreSame (compA, _container.Components [0], "#C4");
607 Assert.AreEqual (1, container2.Components.Count, "#C5");
608 Assert.AreSame (compB, container2.Components [0], "#C6");
612 public void RemoveWithoutUnsiting_Component_Null ()
615 TestComponent component;
617 component = new TestComponent ();
618 _container.Add (component);
619 site = component.Site;
620 _container.RemoveWithoutUnsiting ((IComponent) null);
621 Assert.AreSame (site, component.Site, "#1");
622 Assert.AreEqual (1, _container.Components.Count, "#2");
623 Assert.AreSame (component, _container.Components [0], "#3");
627 public void ValidateName_Component_Null ()
630 _container.InvokeValidateName ((IComponent) null, "A");
632 } catch (ArgumentNullException ex) {
633 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
634 Assert.IsNull (ex.InnerException, "#3");
635 Assert.IsNotNull (ex.Message, "#4");
636 Assert.AreEqual ("component", ex.ParamName, "#5");
641 public void ValidateName_Name_Null ()
643 TestComponent compA = new TestComponent ();
644 _container.Add (compA, (string) null);
645 TestComponent compB = new TestComponent ();
646 _container.InvokeValidateName (compB, (string) null);
650 public void ValidateName_Name_Duplicate ()
652 TestComponent compA = new TestComponent ();
653 _container.Add (compA, "dup");
655 // same component, same case
656 _container.InvokeValidateName (compA, "dup");
658 // existing component, same case
659 TestComponent compB = new TestComponent ();
660 _container.Add (compB, "B");
662 _container.InvokeValidateName (compB, "dup");
664 } catch (ArgumentException ex) {
665 // Duplicate component name 'duP'. Component names must be
666 // unique and case-insensitive
667 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
668 Assert.IsNull (ex.InnerException, "#A3");
669 Assert.IsNotNull (ex.Message, "#A4");
670 Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#A5");
671 Assert.IsNull (ex.ParamName, "#A6");
672 Assert.AreEqual (2, _container.Components.Count, "#A7");
674 _container.InvokeValidateName (compB, "whatever");
676 // new component, different case
677 TestComponent compC = new TestComponent ();
679 _container.InvokeValidateName (compC, "dup");
681 } catch (ArgumentException ex) {
682 // Duplicate component name 'duP'. Component names must be
683 // unique and case-insensitive
684 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
685 Assert.IsNull (ex.InnerException, "#B3");
686 Assert.IsNotNull (ex.Message, "#B4");
687 Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#B5");
688 Assert.IsNull (ex.ParamName, "#B6");
689 Assert.AreEqual (2, _container.Components.Count, "#B7");
691 _container.InvokeValidateName (compC, "whatever");
693 // component of other container, different case
694 TestContainer container2 = new TestContainer ();
695 TestComponent compD = new TestComponent ();
696 container2.Add (compD, "B");
698 _container.InvokeValidateName (compD, "dup");
700 } catch (ArgumentException ex) {
701 // Duplicate component name 'duP'. Component names must be
702 // unique and case-insensitive
703 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
704 Assert.IsNull (ex.InnerException, "#C3");
705 Assert.IsNotNull (ex.Message, "#C4");
706 Assert.IsTrue (ex.Message.IndexOf ("'dup'") != -1, "#C5");
707 Assert.IsNull (ex.ParamName, "#C6");
708 Assert.AreEqual (2, _container.Components.Count, "#C7");
710 _container.InvokeValidateName (compD, "whatever");
711 Assert.AreEqual (1, container2.Components.Count, "#C8");
712 Assert.AreSame (compD, container2.Components [0], "#C9");
716 class MyComponent : Component
718 private Container container;
720 protected override void Dispose (bool disposing)
722 if (container != null)
723 container.Dispose ();
724 base.Dispose (disposing);
727 public Container CreateContainer ()
729 if (container != null)
730 throw new InvalidOperationException ();
731 container = new Container ();
732 container.Add (new MyComponent ());
733 container.Add (this);
737 public Container Container {
738 get { return container; }
742 class MyContainer : IContainer
744 private ComponentCollection components = new ComponentCollection (
747 public ComponentCollection Components {
748 get { return components; }
751 public void Add (IComponent component)
755 public void Add (IComponent component, string name)
759 public void Remove (IComponent component)
763 public void Dispose ()
768 public class GetServiceContainer : Container
770 public new object GetService (Type service)
772 return base.GetService (service);