Skip to content

Commit 32bc644

Browse files
Merge pull request #10693 from ricardobossan/Add_Code_Coverage_For_Buttons
Add code coverage for buttons
2 parents 66f0b18 + 656d3c9 commit 32bc644

File tree

9 files changed

+620
-19
lines changed

9 files changed

+620
-19
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Windows.Forms.Metafiles;
7+
8+
namespace System.Windows.Forms.misc.Tests;
9+
10+
public class EmfValidateHelper
11+
{
12+
/// <summary>
13+
/// Helps immensely with debugging metafile tests.
14+
/// </summary>
15+
/// <param name="emf">The EmfScope instance to extract log information from.</param>
16+
/// <param name="methodName">The name of the calling method. Use <see cref="MethodBase.GetCurrentMethod()"/> and property <see cref="MemberInfo.Name"/>.</param>
17+
/// <param name="parameters">Optional parameters to include in the log information.</param>
18+
internal void LogEmfValidateToFile(EmfScope emf, string methodName, params object[] parameters)
19+
{
20+
ArgumentNullException.ThrowIfNull(emf, nameof(emf));
21+
22+
string timestamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm");
23+
24+
StringBuilder sb = new();
25+
sb.Append($"# {timestamp}. Parameters: ");
26+
sb.AppendJoin(", ", parameters);
27+
sb.AppendLine("\r\n\r\n```c");
28+
sb.AppendLine($"{emf.RecordsToString()}```\r\n");
29+
30+
File.AppendAllText(@$"c:\temp\{methodName}.md", sb.ToString());
31+
}
32+
}
33+
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
4+
using System.Drawing;
5+
6+
namespace System.Windows.Forms.Tests;
7+
8+
public abstract class AbstractButtonBaseTests
9+
{
10+
protected abstract ButtonBase CreateButton();
11+
12+
protected void ButtonBase_FlatStyle_ValidFlatButtonBorder(int borderSize)
13+
{
14+
using var control = CreateButton();
15+
control.FlatStyle = FlatStyle.Flat;
16+
17+
control.Invoking(y => y.FlatAppearance.BorderColor = Color.Transparent)
18+
.Should().Throw<NotSupportedException>();
19+
20+
if (borderSize < 0)
21+
{
22+
control.Invoking(y => y.FlatAppearance.BorderSize = borderSize)
23+
.Should().Throw<ArgumentOutOfRangeException>();
24+
}
25+
else
26+
{
27+
control.FlatAppearance.BorderSize = borderSize;
28+
control.FlatAppearance.BorderSize.Should().Be(borderSize);
29+
}
30+
}
31+
32+
protected void ButtonBase_FlatStyle_ProperFlatButtonColor(int red, int green, int blue)
33+
{
34+
Color expectedColor = Color.FromArgb(red, green, blue);
35+
36+
using var control = CreateButton();
37+
control.FlatStyle = FlatStyle.Flat;
38+
control.BackColor = expectedColor;
39+
40+
control.FlatAppearance.CheckedBackColor = expectedColor;
41+
control.FlatAppearance.BorderColor = expectedColor;
42+
43+
control.BackColor.Should().Be(expectedColor);
44+
control.FlatAppearance.BorderColor.Should().Be(expectedColor);
45+
control.FlatAppearance.CheckedBackColor.Should().Be(expectedColor);
46+
}
47+
48+
protected virtual void ButtonBase_OverChangeRectangle_Get(Appearance appearance, FlatStyle flatStyle)
49+
{
50+
using dynamic control = CreateButton();
51+
52+
if (control is null)
53+
{
54+
return;
55+
}
56+
57+
control.Appearance = appearance;
58+
control.FlatStyle = flatStyle;
59+
60+
Rectangle overChangeRectangle;
61+
62+
// ButtonBase.Adapter prohibits this
63+
if (appearance == Appearance.Normal
64+
&& (flatStyle != FlatStyle.Standard
65+
&& flatStyle != FlatStyle.Popup
66+
&& flatStyle != FlatStyle.Flat))
67+
{
68+
// Compiler requires casting lambda expression to delegate or expression
69+
// before using it as a dynamically dispatched operation
70+
Action act = () => overChangeRectangle = control.OverChangeRectangle;
71+
act.Should().Throw<Exception>();
72+
73+
return;
74+
}
75+
76+
overChangeRectangle = control.OverChangeRectangle;
77+
78+
if (control.FlatStyle == FlatStyle.Standard)
79+
{
80+
overChangeRectangle.Should().Be(new Rectangle(-1, -1, 1, 1));
81+
}
82+
83+
if (control.Appearance == Appearance.Button)
84+
{
85+
if (control.FlatStyle != FlatStyle.Standard)
86+
{
87+
overChangeRectangle.Should().Be(control.ClientRectangle);
88+
}
89+
}
90+
else if (control.FlatStyle != FlatStyle.Standard)
91+
{
92+
overChangeRectangle.Should().Be(control.Adapter.CommonLayout().Layout().CheckBounds);
93+
}
94+
}
95+
}

src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ButtonBaseTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace System.Windows.Forms.Tests;
1414

15-
public class ButtonBaseTests
15+
public class ButtonBaseTests : AbstractButtonBaseTests
1616
{
1717
[WinFormsFact]
1818
public void ButtonBase_Ctor_Default()
@@ -9335,7 +9335,7 @@ private class SubButtonBase : ButtonBase
93359335
public new bool GetStyle(ControlStyles flag) => base.GetStyle(flag);
93369336

93379337
public new bool GetTopLevel() => base.GetTopLevel();
9338-
9338+
93399339
public new void OnClick(EventArgs e) => base.OnClick(e);
93409340

93419341
public new void OnEnabledChanged(EventArgs e) => base.OnEnabledChanged(e);
@@ -9376,4 +9376,6 @@ private class SubButtonBase : ButtonBase
93769376

93779377
public new void WndProc(ref Message m) => base.WndProc(ref m);
93789378
}
9379+
9380+
protected override ButtonBase CreateButton() => new Button();
93799381
}

src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ButtonRenderingTests.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
namespace System.Windows.Forms.Tests;
88

9-
public class ButtonRenderingTests
9+
public class ButtonRenderingTests : AbstractButtonBaseTests
1010
{
1111
[WinFormsFact]
1212
public unsafe void CaptureButton()
1313
{
14-
using Button button = new();
14+
using Button button = (Button)CreateButton();
1515
using EmfScope emf = new();
1616
button.PrintToMetafile(emf);
1717

@@ -33,7 +33,7 @@ public unsafe void Button_VisualStyles_off_Default_LineDrawing()
3333
return;
3434
}
3535

36-
using Button button = new();
36+
using Button button = (Button)CreateButton();
3737
using EmfScope emf = new();
3838
DeviceContextState state = new(emf);
3939
Rectangle bounds = button.Bounds;
@@ -77,7 +77,7 @@ public unsafe void Button_VisualStyles_on_Default_LineDrawing()
7777
return;
7878
}
7979

80-
using Button button = new();
80+
using Button button = (Button)CreateButton();
8181
using EmfScope emf = new();
8282
DeviceContextState state = new(emf);
8383
Rectangle bounds = button.Bounds;
@@ -117,7 +117,8 @@ public unsafe void Button_VisualStyles_off_Default_WithText_LineDrawing()
117117
return;
118118
}
119119

120-
using Button button = new() { Text = "Hello" };
120+
using Button button = (Button)CreateButton();
121+
button.Text = "Hello";
121122
using EmfScope emf = new();
122123
DeviceContextState state = new(emf);
123124
Rectangle bounds = button.Bounds;
@@ -162,7 +163,8 @@ public unsafe void Button_VisualStyles_on_Default_WithText_LineDrawing()
162163
return;
163164
}
164165

165-
using Button button = new() { Text = "Hello" };
166+
using Button button = (Button)CreateButton();
167+
button.Text = "Hello";
166168
using EmfScope emf = new();
167169
DeviceContextState state = new(emf);
168170
Rectangle bounds = button.Bounds;
@@ -210,7 +212,7 @@ public unsafe void Button_VisualStyles_on_Default_WithText_LineDrawing()
210212
public unsafe void CaptureButtonOnForm()
211213
{
212214
using Form form = new();
213-
using Button button = new();
215+
using Button button = (Button)CreateButton();
214216
form.Controls.Add(button);
215217

216218
using EmfScope emf = new();
@@ -222,11 +224,9 @@ public unsafe void CaptureButtonOnForm()
222224
[WinFormsFact]
223225
public unsafe void Button_FlatStyle_WithText_Rectangle()
224226
{
225-
using Button button = new()
226-
{
227-
Text = "Flat Style",
228-
FlatStyle = FlatStyle.Flat,
229-
};
227+
using Button button = (Button)CreateButton();
228+
button.Text = "Flat Style";
229+
button.FlatStyle = FlatStyle.Flat;
230230

231231
using EmfScope emf = new();
232232
DeviceContextState state = new(emf);
@@ -245,4 +245,6 @@ public unsafe void Button_FlatStyle_WithText_Rectangle()
245245
State.BrushStyle(BRUSH_STYLE.BS_NULL), // Regressed in https://github.com/dotnet/winforms/pull/3667
246246
State.Rop2(R2_MODE.R2_COPYPEN)));
247247
}
248+
249+
protected override ButtonBase CreateButton() => new Button();
248250
}

src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ButtonTests.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
namespace System.Windows.Forms.Tests;
1515

16-
public class ButtonTests
16+
public class ButtonTests : AbstractButtonBaseTests
1717
{
1818
[WinFormsFact]
1919
public void Button_Ctor_Default()
@@ -3578,6 +3578,17 @@ public static IEnumerable<object[]> WndProc_ReflectCommandWithoutHandle_TestData
35783578
yield return new object[] { FlatStyle.System, PARAM.FromLowHigh(123, 456), (IntPtr)250, 0 };
35793579
}
35803580

3581+
[WinFormsFact]
3582+
public void ButtonBase_Click_RaisesEvent()
3583+
{
3584+
using var button = (SubButton)CreateButton();
3585+
bool clickEventRaised = false;
3586+
button.Click += (sender, e) => clickEventRaised = true;
3587+
button.PerformClick();
3588+
3589+
clickEventRaised.Should().BeTrue();
3590+
}
3591+
35813592
[WinFormsTheory]
35823593
[MemberData(nameof(WndProc_ReflectCommandWithoutHandle_TestData))]
35833594
public void Button_WndProc_InvokeReflectCommandWithoutHandle_Success(FlatStyle flatStyle, IntPtr wParam, IntPtr expectedResult, int expectedCallCount)
@@ -3649,6 +3660,20 @@ public void Button_WndProc_InvokeReflectCommandWithHandle_Success(FlatStyle flat
36493660
Assert.Equal(0, createdCallCount);
36503661
}
36513662

3663+
[WinFormsTheory]
3664+
[InlineData(-1)]
3665+
[InlineData(0)]
3666+
[InlineData(1)]
3667+
public void Button_Flat_ValidBorder(int borderSize) => base.ButtonBase_FlatStyle_ValidFlatButtonBorder(borderSize);
3668+
3669+
[WinFormsTheory]
3670+
[InlineData(255, 0, 0)]
3671+
[InlineData(0, 255, 0)]
3672+
[InlineData(0, 0, 255)]
3673+
public void Button_Flat_ProperColor(int red, int green, int blue) => base.ButtonBase_FlatStyle_ProperFlatButtonColor(red, green, blue);
3674+
3675+
protected override ButtonBase CreateButton() => new SubButton();
3676+
36523677
private class SubButton : Button
36533678
{
36543679
public new bool CanEnableIme => base.CanEnableIme;

0 commit comments

Comments
 (0)