1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Reflection;
6 using Xunit;
7 
8 namespace System.ComponentModel.Tests
9 {
10     public class ComponentTests
11     {
12         [Fact]
CanRaiseEvents_Get_ReturnsTrueByDefault()13         public void CanRaiseEvents_Get_ReturnsTrueByDefault()
14         {
15             var component = new SubComponent();
16             Assert.True(component.GetCanRaiseEvents());
17         }
18 
19         [Fact]
Events_Get_ReturnsSameInstance()20         public void Events_Get_ReturnsSameInstance()
21         {
22             var component = new SubComponent();
23             Assert.Same(component.GetEvents(), component.GetEvents());
24         }
25 
26         [Fact]
Site_Set_GetReturnsExpected()27         public void Site_Set_GetReturnsExpected()
28         {
29             var component = new SubComponent();
30             Assert.Null(component.Site);
31 
32             var site = new MockSite();
33             component.Site = site;
34             Assert.Same(site, component.Site);
35         }
36 
37         [Fact]
Container_Set_GetReturnsExpected()38         public void Container_Set_GetReturnsExpected()
39         {
40             var component = new SubComponent();
41             Assert.Null(component.Container);
42 
43             var site = new MockSite { Container = new Container() };
44             component.Site = site;
45             Assert.Same(site.Container, component.Container);
46         }
47 
48         [Fact]
DesignMode_Set_GetReturnsExpected()49         public void DesignMode_Set_GetReturnsExpected()
50         {
51             var component = new SubComponent();
52             Assert.False(component.GetDesignMode());
53 
54             var site = new MockSite { DesignMode = true };
55             component.Site = site;
56             Assert.True(component.GetDesignMode());
57         }
58 
59         [Fact]
GetServiceType_CustomSite_ReturnsExpected()60         public void GetServiceType_CustomSite_ReturnsExpected()
61         {
62             var component = new SubComponent();
63             Assert.Null(component.GetServiceInternal(typeof(int)));
64 
65             var site = new MockSite { ServiceType = typeof(bool) };
66             component.Site = site;
67             Assert.Equal(typeof(bool), component.GetServiceInternal(typeof(int)));
68         }
69 
70         [Fact]
Dispose_NullSite_Success()71         public void Dispose_NullSite_Success()
72         {
73             var component = new SubComponent();
74             component.Dispose();
75             component.Dispose();
76         }
77 
78         [Fact]
Dispose_NullSiteContainer_Success()79         public void Dispose_NullSiteContainer_Success()
80         {
81             var component = new SubComponent()
82             {
83                 Site = new MockSite { Container = null }
84             };
85             component.Dispose();
86             component.Dispose();
87         }
88 
89         [Fact]
Dispose_NonNullSiteContainer_RemovesComponentFromContainer()90         public void Dispose_NonNullSiteContainer_RemovesComponentFromContainer()
91         {
92             var component = new SubComponent()
93             {
94                 Site = new MockSite { Container = new Container() }
95             };
96 
97             component.Dispose();
98             Assert.Null(component.Site);
99 
100             component.Dispose();
101         }
102 
103         [Fact]
Dispose_HasDisposedEvent_InvokesEvent()104         public void Dispose_HasDisposedEvent_InvokesEvent()
105         {
106             var component = new SubComponent();
107             component.Disposed += Component_Disposed;
108 
109             component.Dispose();
110             Assert.True(InvokedDisposed);
111 
112             InvokedDisposed = false;
113             component.Dispose();
114             Assert.True(InvokedDisposed);
115 
116             component.Disposed -= Component_Disposed;
117             InvokedDisposed = false;
118             component.Dispose();
119             Assert.False(InvokedDisposed);
120         }
121 
122         [Fact]
Dispose_HasDisposedWithoutEvents_DoesNotnvokesEvent()123         public void Dispose_HasDisposedWithoutEvents_DoesNotnvokesEvent()
124         {
125             var component = new SubComponent();
126             component.Disposed += Component_Disposed;
127             component.CanRaiseEventsInternal = false;
128 
129             component.Dispose();
130             Assert.False(InvokedDisposed);
131         }
132 
133         [Fact]
Dispose_NotDisposing_DoesNotInvokeEvent()134         public void Dispose_NotDisposing_DoesNotInvokeEvent()
135         {
136             var component = new SubComponent();
137             component.Disposed += Component_Disposed;
138 
139             component.DisposeInternal(false);
140             Assert.False(InvokedDisposed);
141 
142             component.DisposeInternal(true);
143             Assert.True(InvokedDisposed);
144         }
145 
146         [Fact]
Finalize_Invoke_DoesNotCallDisposedEvent()147         public void Finalize_Invoke_DoesNotCallDisposedEvent()
148         {
149             var component = new SubComponent();
150             component.Disposed += Component_Disposed;
151 
152             MethodInfo method = typeof(Component).GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance);
153             Assert.NotNull(method);
154             method.Invoke(component, null);
155             Assert.False(InvokedDisposed);
156         }
157 
158         [Fact]
ToString_HasSite_ReturnsExpected()159         public void ToString_HasSite_ReturnsExpected()
160         {
161             var component = new SubComponent();
162             Assert.Equal("System.ComponentModel.Tests.ComponentTests+SubComponent", component.ToString());
163 
164             component.Site = new MockSite { Name = "name" };
165             Assert.Equal("name [System.ComponentModel.Tests.ComponentTests+SubComponent]", component.ToString());
166         }
167 
168         private bool InvokedDisposed { get; set; }
Component_Disposed(object sender, EventArgs e)169         private void Component_Disposed(object sender, EventArgs e) => InvokedDisposed = true;
170 
171         public class SubComponent : Component
172         {
GetCanRaiseEvents()173             public bool GetCanRaiseEvents() => CanRaiseEvents;
174 
175             public bool? CanRaiseEventsInternal { get; set; }
176             protected override bool CanRaiseEvents => CanRaiseEventsInternal ?? base.CanRaiseEvents;
177 
GetDesignMode()178             public bool GetDesignMode() => DesignMode;
GetEvents()179             public EventHandlerList GetEvents() => Events;
180 
181             public object GetServiceInternal(Type serviceType) => GetService(serviceType);
182 
183             public void DisposeInternal(bool disposing) => Dispose(disposing);
184         }
185     }
186 }
187