Skip to content

Commit 895e1cd

Browse files
author
Ricardo Bossan (BEYONDSOFT CONSULTING INC) (from Dev Box)
committed
Add unit tests for FlatButton, RadioButton, CheckBox, RadioButtonRenderer and CheckBoxRenderer
1 parent d152b3c commit 895e1cd

File tree

5 files changed

+596
-0
lines changed

5 files changed

+596
-0
lines changed

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9244,6 +9244,52 @@ public void ButtonBase_WndProc_InvokeSetStateWithHandle_Success(FlatStyle flatSt
92449244
Assert.Equal(0, createdCallCount);
92459245
}
92469246

9247+
[WinFormsTheory]
9248+
[InlineData(-1)]
9249+
[InlineData(0)]
9250+
[InlineData(1)]
9251+
public unsafe void Button_Flat_ValidBorder(int borderSize)
9252+
{
9253+
using SubButton button = new()
9254+
{
9255+
FlatStyle = FlatStyle.Flat,
9256+
};
9257+
9258+
Assert.Throws<NotSupportedException>(() => button.FlatAppearance.BorderColor = Color.Transparent);
9259+
9260+
if (borderSize < 0)
9261+
{
9262+
Assert.Throws<ArgumentOutOfRangeException>(() => button.FlatAppearance.BorderSize = borderSize);
9263+
}
9264+
else
9265+
{
9266+
button.FlatAppearance.BorderSize = borderSize;
9267+
Assert.Equal(borderSize, button.FlatAppearance.BorderSize);
9268+
}
9269+
}
9270+
9271+
[WinFormsTheory]
9272+
[InlineData(255, 0, 0)]
9273+
[InlineData(0, 255, 0)]
9274+
[InlineData(0, 0, 255)]
9275+
public unsafe void Button_Flat_ProperColor(int red, int green, int blue)
9276+
{
9277+
Color expectedColor = Color.FromArgb(red, green, blue);
9278+
9279+
using SubButton button = new()
9280+
{
9281+
FlatStyle = FlatStyle.Flat,
9282+
BackColor = expectedColor
9283+
};
9284+
9285+
button.FlatAppearance.CheckedBackColor = expectedColor;
9286+
button.FlatAppearance.BorderColor = expectedColor;
9287+
9288+
Assert.Equal(expectedColor, button.BackColor);
9289+
Assert.Equal(expectedColor, button.FlatAppearance.BorderColor);
9290+
Assert.Equal(expectedColor, button.FlatAppearance.CheckedBackColor);
9291+
}
9292+
92479293
private class SubButton : Button
92489294
{
92499295
public new bool GetStyle(ControlStyles flag) => base.GetStyle(flag);
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
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+
using System.Windows.Forms.Metafiles;
6+
using System.Windows.Forms.VisualStyles;
7+
8+
namespace System.Windows.Forms.Tests;
9+
10+
public class CheckBoxRenderingTests
11+
{
12+
[WinFormsTheory]
13+
[InlineData(CheckBoxState.CheckedNormal)]
14+
[InlineData(CheckBoxState.MixedNormal)]
15+
public void CheckBoxRenderer_DrawCheckBox(CheckBoxState state)
16+
{
17+
using Bitmap bitmap = new(100, 100);
18+
using Graphics graphics = Graphics.FromImage(bitmap);
19+
Point rectangle = new Point(10, 20);
20+
21+
CheckBoxRenderer.DrawCheckBox(graphics, rectangle, state);
22+
}
23+
24+
[WinFormsTheory]
25+
[InlineData(CheckBoxState.CheckedNormal)]
26+
[InlineData(CheckBoxState.MixedNormal)]
27+
public void CheckBoxRenderer_DrawCheckBox_OverloadWithSizeAndText(CheckBoxState state)
28+
{
29+
using Bitmap bitmap = new(100, 100);
30+
using Graphics graphics = Graphics.FromImage(bitmap);
31+
Point point = new Point(10, 20);
32+
Rectangle bounds = new Rectangle(10, 20, 30, 40);
33+
34+
CheckBoxRenderer.DrawCheckBox(graphics, point, bounds, "Text", SystemFonts.DefaultFont, false, state);
35+
}
36+
37+
[WinFormsTheory]
38+
[InlineData(TextFormatFlags.Default, CheckBoxState.CheckedNormal)]
39+
[InlineData(TextFormatFlags.Default, CheckBoxState.MixedNormal)]
40+
[InlineData(TextFormatFlags.GlyphOverhangPadding, CheckBoxState.MixedHot)]
41+
[InlineData(TextFormatFlags.PreserveGraphicsTranslateTransform, CheckBoxState.CheckedPressed)]
42+
[InlineData(TextFormatFlags.TextBoxControl, CheckBoxState.UncheckedNormal)]
43+
public void CheckBoxRenderer_DrawCheckBox_OverloadWithTextFormat(TextFormatFlags textFormat, CheckBoxState state)
44+
{
45+
using Bitmap bitmap = new(100, 100);
46+
using Graphics graphics = Graphics.FromImage(bitmap);
47+
Point point = new Point(10, 20);
48+
Rectangle bounds = new Rectangle(10, 20, 30, 40);
49+
50+
CheckBoxRenderer.DrawCheckBox(graphics, point, bounds, "Text", SystemFonts.DefaultFont, textFormat, false, state);
51+
}
52+
53+
[WinFormsFact]
54+
public unsafe void CaptureButton()
55+
{
56+
using CheckBox checkBox = new();
57+
using EmfScope emf = new();
58+
checkBox.PrintToMetafile(emf);
59+
60+
List<ENHANCED_METAFILE_RECORD_TYPE> types = [];
61+
List<string> details = [];
62+
emf.Enumerate((ref EmfRecord record) =>
63+
{
64+
types.Add(record.Type);
65+
details.Add(record.ToString());
66+
return true;
67+
});
68+
}
69+
70+
[WinFormsFact]
71+
public unsafe void Button_VisualStyles_off_Default_LineDrawing()
72+
{
73+
if (Application.RenderWithVisualStyles)
74+
{
75+
return;
76+
}
77+
78+
using CheckBox checkBox = new();
79+
using EmfScope emf = new();
80+
DeviceContextState state = new(emf);
81+
Rectangle bounds = checkBox.Bounds;
82+
83+
checkBox.PrintToMetafile(emf);
84+
85+
emf.Validate(
86+
state,
87+
Validate.Repeat(Validate.SkipType(ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT), 1),
88+
Validate.LineTo(
89+
new(bounds.Right - 1, 0), new(0, 0),
90+
State.PenColor(SystemColors.ControlLightLight)),
91+
Validate.LineTo(
92+
new(0, 0), new(0, bounds.Bottom - 1),
93+
State.PenColor(SystemColors.ControlLightLight)),
94+
Validate.LineTo(
95+
new(0, bounds.Bottom - 1), new(bounds.Right - 1, bounds.Bottom - 1),
96+
State.PenColor(SystemColors.ControlDarkDark)),
97+
Validate.LineTo(
98+
new(bounds.Right - 1, bounds.Bottom - 1), new(bounds.Right - 1, -1),
99+
State.PenColor(SystemColors.ControlDarkDark)),
100+
Validate.LineTo(
101+
new(bounds.Right - 2, 1), new(1, 1),
102+
State.PenColor(SystemColors.Control)),
103+
Validate.LineTo(
104+
new(1, 1), new(1, bounds.Bottom - 2),
105+
State.PenColor(SystemColors.Control)),
106+
Validate.LineTo(
107+
new(1, bounds.Bottom - 2), new(bounds.Right - 2, bounds.Bottom - 2),
108+
State.PenColor(SystemColors.ControlDark)),
109+
Validate.LineTo(
110+
new(bounds.Right - 2, bounds.Bottom - 2), new(bounds.Right - 2, 0),
111+
State.PenColor(SystemColors.ControlDark)));
112+
}
113+
114+
[WinFormsFact]
115+
public unsafe void Button_VisualStyles_off_Default_WithText_LineDrawing()
116+
{
117+
if (Application.RenderWithVisualStyles)
118+
{
119+
return;
120+
}
121+
122+
using CheckBox checkBox = new() { Text = "Hello" };
123+
using EmfScope emf = new();
124+
DeviceContextState state = new(emf);
125+
Rectangle bounds = checkBox.Bounds;
126+
127+
checkBox.PrintToMetafile(emf);
128+
129+
emf.Validate(
130+
state,
131+
Validate.SkipType(ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT),
132+
Validate.TextOut("Hello"),
133+
Validate.LineTo(
134+
new(bounds.Right - 1, 0), new(0, 0),
135+
State.PenColor(SystemColors.ControlLightLight)),
136+
Validate.LineTo(
137+
new(0, 0), new(0, bounds.Bottom - 1),
138+
State.PenColor(SystemColors.ControlLightLight)),
139+
Validate.LineTo(
140+
new(0, bounds.Bottom - 1), new(bounds.Right - 1, bounds.Bottom - 1),
141+
State.PenColor(SystemColors.ControlDarkDark)),
142+
Validate.LineTo(
143+
new(bounds.Right - 1, bounds.Bottom - 1), new(bounds.Right - 1, -1),
144+
State.PenColor(SystemColors.ControlDarkDark)),
145+
Validate.LineTo(
146+
new(bounds.Right - 2, 1), new(1, 1),
147+
State.PenColor(SystemColors.Control)),
148+
Validate.LineTo(
149+
new(1, 1), new(1, bounds.Bottom - 2),
150+
State.PenColor(SystemColors.Control)),
151+
Validate.LineTo(
152+
new(1, bounds.Bottom - 2), new(bounds.Right - 2, bounds.Bottom - 2),
153+
State.PenColor(SystemColors.ControlDark)),
154+
Validate.LineTo(
155+
new(bounds.Right - 2, bounds.Bottom - 2), new(bounds.Right - 2, 0),
156+
State.PenColor(SystemColors.ControlDark)));
157+
}
158+
159+
[WinFormsFact]
160+
public unsafe void CaptureButtonOnForm()
161+
{
162+
using Form form = new();
163+
using CheckBox checkBox = new();
164+
form.Controls.Add(checkBox);
165+
166+
using EmfScope emf = new();
167+
form.PrintToMetafile(emf);
168+
169+
string details = emf.RecordsToString();
170+
}
171+
}

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

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ public class SubCheckBox : CheckBox
493493
public new bool GetTopLevel() => base.GetTopLevel();
494494

495495
public new void OnClick(EventArgs e) => base.OnClick(e);
496+
public new void OnMouseUp(MouseEventArgs e) => base.OnMouseUp(e);
497+
internal new void OnMouseClick(MouseEventArgs e) => base.OnMouseClick(e);
498+
internal new void OnMouseDown(MouseEventArgs e) => base.OnMouseDown(e);
496499
}
497500

498501
private class TestCheckBox : CheckBox
@@ -527,4 +530,162 @@ internal override bool RaiseAutomationPropertyChangedEvent(UIA_PROPERTY_ID prope
527530
return base.RaiseAutomationPropertyChangedEvent(propertyId, oldValue, newValue);
528531
}
529532
}
533+
534+
[WinFormsFact]
535+
public void CheckBox_CheckedChangedEvent_Fires()
536+
{
537+
CheckBox checkBox = new CheckBox();
538+
bool eventFired = false;
539+
540+
checkBox.CheckedChanged += (sender, args) => eventFired = true;
541+
checkBox.Checked = !checkBox.Checked;
542+
543+
Assert.True(eventFired);
544+
}
545+
546+
[WinFormsFact]
547+
public void CheckBox_CheckStateChangedEvent_Fires()
548+
{
549+
CheckBox checkBox = new CheckBox();
550+
bool eventFired = false;
551+
552+
checkBox.CheckStateChanged += (sender, args) => eventFired = true;
553+
checkBox.CheckState = checkBox.CheckState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked;
554+
555+
Assert.True(eventFired);
556+
}
557+
558+
[WinFormsTheory]
559+
[InlineData(Appearance.Button, FlatStyle.Standard)]
560+
[InlineData(Appearance.Button, FlatStyle.Flat)]
561+
[InlineData(Appearance.Button, FlatStyle.Popup)]
562+
[InlineData(Appearance.Button, FlatStyle.System)]
563+
[InlineData(Appearance.Normal, FlatStyle.Standard)]
564+
[InlineData(Appearance.Normal, FlatStyle.Flat)]
565+
[InlineData(Appearance.Normal, FlatStyle.Popup)]
566+
[InlineData(Appearance.Normal, FlatStyle.System)]
567+
public void CheckBox_OverChangeRectangle_ReturnsExpectedRectangle(Appearance appearance, FlatStyle flatStyle)
568+
{
569+
SubCheckBox checkBox = new SubCheckBox()
570+
{
571+
Appearance = appearance,
572+
FlatStyle = flatStyle
573+
};
574+
575+
Rectangle overChangeRectangle = new();
576+
// ButtonBase.Adapter prohibits this
577+
if (appearance == Appearance.Normal && (flatStyle != FlatStyle.Standard && flatStyle != FlatStyle.Popup && flatStyle != FlatStyle.Flat))
578+
{
579+
Assert.ThrowsAny<Exception>(() => overChangeRectangle = checkBox.OverChangeRectangle);
580+
581+
return;
582+
}
583+
else
584+
{
585+
overChangeRectangle = checkBox.OverChangeRectangle;
586+
}
587+
588+
if (appearance == Appearance.Button)
589+
{
590+
if (flatStyle == FlatStyle.Standard)
591+
Assert.Equal(new Rectangle(-1, -1, 1, 1), overChangeRectangle);
592+
else
593+
{
594+
Assert.Equal(checkBox.ClientRectangle, overChangeRectangle);
595+
}
596+
}
597+
else if (flatStyle == FlatStyle.Standard)
598+
{
599+
Assert.Equal(new Rectangle(-1, -1, 1, 1), overChangeRectangle);
600+
}
601+
else
602+
{
603+
Assert.Equal(checkBox.Adapter.CommonLayout().Layout().CheckBounds, overChangeRectangle);
604+
}
605+
}
606+
607+
[WinFormsTheory]
608+
[InlineData(Appearance.Button, FlatStyle.Standard)]
609+
[InlineData(Appearance.Button, FlatStyle.Flat)]
610+
[InlineData(Appearance.Button, FlatStyle.Popup)]
611+
[InlineData(Appearance.Button, FlatStyle.System)]
612+
[InlineData(Appearance.Normal, FlatStyle.Standard)]
613+
[InlineData(Appearance.Normal, FlatStyle.Flat)]
614+
[InlineData(Appearance.Normal, FlatStyle.Popup)]
615+
[InlineData(Appearance.Normal, FlatStyle.System)]
616+
public void CheckBox_DownChangeRectangle_ReturnsExpectedRectangle(Appearance appearance, FlatStyle flatStyle)
617+
{
618+
SubCheckBox checkBox = new SubCheckBox()
619+
{
620+
Appearance = appearance,
621+
FlatStyle = flatStyle
622+
};
623+
624+
Rectangle downChangeRectangle = checkBox.DownChangeRectangle;
625+
626+
if (appearance == Appearance.Button || flatStyle == FlatStyle.System)
627+
{
628+
Assert.Equal(checkBox.ClientRectangle, downChangeRectangle);
629+
}
630+
else
631+
{
632+
Assert.Equal(checkBox.Adapter.CommonLayout().Layout().CheckBounds, downChangeRectangle);
633+
}
634+
}
635+
636+
[WinFormsTheory]
637+
[InlineData(true)]
638+
[InlineData(false)]
639+
public void CheckBox_LeftClick_MouseUpCounts(bool capture)
640+
{
641+
Form form = new();
642+
SubCheckBox control = new() { Capture = capture };
643+
form.Controls.Add(control);
644+
control.TabIndex = 9999;
645+
form.Show();
646+
647+
MouseEventArgs eventArgs = new MouseEventArgs(MouseButtons.Left, 1, new Point(0, 0), 0);
648+
649+
int callCountOnMouseUp = 0;
650+
651+
control.MouseUp += (sender, e) =>
652+
{
653+
Assert.Same(control, sender);
654+
Assert.Same(eventArgs, e);
655+
callCountOnMouseUp++;
656+
};
657+
658+
control.OnMouseUp(eventArgs);
659+
Assert.True(callCountOnMouseUp == 1);
660+
}
661+
662+
[WinFormsTheory]
663+
[InlineData(true, '&', "&MnemonicText")]
664+
[InlineData(true, 'N', "NonMnemonicText")]
665+
[InlineData(true, 'M', "&MnemonicText")]
666+
[InlineData(false, 'M', "&MnemonicText")]
667+
public void CheckBox_ProcessMnemonic_ValidCases(bool useMnemonic, char charCode, string buttonText)
668+
{
669+
Form form = new();
670+
using SubCheckBox checkBox = new()
671+
{
672+
UseMnemonic = useMnemonic,
673+
Text = buttonText,
674+
};
675+
form.Controls.Add(checkBox);
676+
form.Show();
677+
678+
bool result = checkBox.ProcessMnemonic(charCode);
679+
680+
if (useMnemonic && charCode != '&' && buttonText.Contains($"&{charCode}", StringComparison.OrdinalIgnoreCase))
681+
{
682+
Assert.True(result);
683+
684+
Assert.True(checkBox.Focused);
685+
}
686+
else
687+
{
688+
Assert.False(result);
689+
}
690+
}
530691
}

0 commit comments

Comments
 (0)