From b56856f7f8a2683149fffb9cc127b24e405db712 Mon Sep 17 00:00:00 2001 From: "Zheng Li (BEYONDSOFT CONSULTING INC)" Date: Tue, 13 May 2025 16:06:48 +0800 Subject: [PATCH 1/5] Add code coverage for RadioButtonRenderer --- .../Windows/Forms/RadioButtonRendererTests.cs | 231 +++++++++++++++++- 1 file changed, 229 insertions(+), 2 deletions(-) diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs index 5d210e9fb1d..fa56fbad241 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms.Metafiles; @@ -157,5 +155,234 @@ public void RadioButtonRenderer_DrawRadioButton_OverloadWithHandle(bool focus) ); } + [WinFormsTheory] + [InlineData(RadioButtonState.CheckedNormal)] + [InlineData(RadioButtonState.CheckedPressed)] + [InlineData(RadioButtonState.CheckedDisabled)] + [InlineData(RadioButtonState.UncheckedNormal)] + [InlineData(RadioButtonState.UncheckedPressed)] + [InlineData(RadioButtonState.UncheckedDisabled)] + public void IsBackgroundPartiallyTransparent_ReturnsExpected(RadioButtonState state) + { + bool original = RadioButtonRenderer.RenderMatchingApplicationState; + + try + { + RadioButtonRenderer.RenderMatchingApplicationState = false; + bool resultWithVisualStyles = RadioButtonRenderer.IsBackgroundPartiallyTransparent(state); + + RadioButtonRenderer.RenderMatchingApplicationState = true; + bool resultWithoutVisualStyles = RadioButtonRenderer.IsBackgroundPartiallyTransparent(state); + + if (Application.RenderWithVisualStyles) + { + resultWithVisualStyles.Should().BeTrue(); + } + else + { + resultWithVisualStyles.Should().BeFalse(); + } + + if (!Application.RenderWithVisualStyles) + { + resultWithoutVisualStyles.Should().BeFalse(); + } + } + finally + { + RadioButtonRenderer.RenderMatchingApplicationState = original; + } + } + + [WinFormsFact] + public void DrawParentBackground_DoesNotThrow_WhenVisualStylesDisabled() + { + using Form parent = new(); + using Panel child = new(); + parent.Controls.Add(child); + parent.Show(); + + using Bitmap bmp = new(10, 10); + using Graphics g = Graphics.FromImage(bmp); + + bool original = RadioButtonRenderer.RenderMatchingApplicationState; + try + { + RadioButtonRenderer.RenderMatchingApplicationState = true; + RadioButtonRenderer.DrawParentBackground(g, new Rectangle(0, 0, 10, 10), child); + } + finally + { + RadioButtonRenderer.RenderMatchingApplicationState = original; + } + } + + [WinFormsFact] + public void DrawParentBackground_CallsRenderer_WhenVisualStylesEnabled() + { + using Form parent = new(); + using Panel child = new(); + parent.Controls.Add(child); + parent.Show(); + + using Bitmap bmp = new(10, 10); + using Graphics g = Graphics.FromImage(bmp); + + bool original = RadioButtonRenderer.RenderMatchingApplicationState; + try + { + RadioButtonRenderer.RenderMatchingApplicationState = false; + RadioButtonRenderer.DrawParentBackground(g, new Rectangle(0, 0, 10, 10), child); + } + finally + { + RadioButtonRenderer.RenderMatchingApplicationState = original; + } + } + + [WinFormsFact] + public void DrawRadioButton_WithImage_Overload_CallsMainOverload() + { + using Form form = new(); + using RadioButton control = (RadioButton)CreateButton(); + form.Controls.Add(control); + form.Show(); + + using Bitmap bmp = new(20, 20); + using Graphics g = Graphics.FromImage(bmp); + using Image image = new Bitmap(10, 10); + + Point glyphLocation = new(2, 2); + Rectangle textBounds = new(5, 5, 30, 15); + Rectangle imageBounds = new(7, 7, 10, 10); + string radioButtonText = "Radio"; + Font font = SystemFonts.DefaultFont; + bool focused = false; + RadioButtonState state = RadioButtonState.CheckedNormal; + + RadioButtonRenderer.DrawRadioButton( + g, + glyphLocation, + textBounds, + radioButtonText, + font, + image, + imageBounds, + focused, + state + ); + } + + [WinFormsFact] + public void DrawRadioButton_WithImage_Overload_AllowsNullTextAndFont() + { + using Bitmap bmp = new(20, 20); + using Graphics g = Graphics.FromImage(bmp); + using Image image = new Bitmap(10, 10); + + Point glyphLocation = new(0, 0); + Rectangle textBounds = new(0, 0, 10, 10); + Rectangle imageBounds = new(0, 0, 10, 10); + bool focused = false; + RadioButtonState state = RadioButtonState.UncheckedNormal; + + RadioButtonRenderer.DrawRadioButton( + g, + glyphLocation, + textBounds, + null, + null, + image, + imageBounds, + focused, + state + ); + } + + [WinFormsTheory] + [InlineData(RadioButtonState.CheckedNormal)] + [InlineData(RadioButtonState.CheckedPressed)] + [InlineData(RadioButtonState.UncheckedNormal)] + [InlineData(RadioButtonState.UncheckedPressed)] + public void GetGlyphSize_ReturnsExpectedSize(RadioButtonState state) + { + using Bitmap bmp = new(20, 20); + using Graphics g = Graphics.FromImage(bmp); + + Size size = RadioButtonRenderer.GetGlyphSize(g, state); + + if (Application.RenderWithVisualStyles) + { + size.Width.Should().BeGreaterThan(0); + size.Height.Should().BeGreaterThan(0); + } + else + { + size.Should().Be(new Size(13, 13)); + } + } + + [WinFormsFact] + public void DrawRadioButton_Internal_WithImageAndText_DoesNotThrow() + { + using Bitmap bmp = new(30, 30); + using Graphics g = Graphics.FromImage(bmp); + using Image image = new Bitmap(10, 10); + + Point glyphLocation = new(1, 1); + Rectangle textBounds = new(12, 1, 15, 15); + Rectangle imageBounds = new(2, 2, 10, 10); + string radioButtonText = "Test"; + Font font = SystemFonts.DefaultFont; + TextFormatFlags flags = TextFormatFlags.Default; + bool focused = true; + RadioButtonState state = RadioButtonState.CheckedNormal; + HWND hwnd = HWND.Null; + + typeof(RadioButtonRenderer) + .TestAccessor() + .Dynamic + .DrawRadioButton( + g, + glyphLocation, + textBounds, + radioButtonText, + font, + flags, + image, + imageBounds, + focused, + state, + hwnd + ); + } + + [WinFormsTheory] + [InlineData(RadioButtonState.CheckedNormal, ButtonState.Checked)] + [InlineData(RadioButtonState.CheckedHot, ButtonState.Checked)] + [InlineData(RadioButtonState.CheckedPressed, ButtonState.Checked | ButtonState.Pushed)] + [InlineData(RadioButtonState.CheckedDisabled, ButtonState.Checked | ButtonState.Inactive)] + [InlineData(RadioButtonState.UncheckedPressed, ButtonState.Pushed)] + [InlineData(RadioButtonState.UncheckedDisabled, ButtonState.Inactive)] + [InlineData(RadioButtonState.UncheckedNormal, ButtonState.Normal)] + public void ConvertToButtonState_ReturnsExpected(RadioButtonState radioState, ButtonState expected) + { + RadioButtonRenderer.ConvertToButtonState(radioState).Should().Be(expected); + } + + [WinFormsTheory] + [InlineData(ButtonState.Checked, false, RadioButtonState.CheckedNormal)] + [InlineData(ButtonState.Checked, true, RadioButtonState.CheckedHot)] + [InlineData(ButtonState.Checked | ButtonState.Pushed, false, RadioButtonState.CheckedPressed)] + [InlineData(ButtonState.Checked | ButtonState.Inactive, false, RadioButtonState.CheckedDisabled)] + [InlineData(ButtonState.Pushed, false, RadioButtonState.UncheckedPressed)] + [InlineData(ButtonState.Inactive, false, RadioButtonState.UncheckedDisabled)] + [InlineData(ButtonState.Normal, false, RadioButtonState.UncheckedNormal)] + [InlineData(ButtonState.Normal, true, RadioButtonState.UncheckedHot)] + public void ConvertFromButtonState_ReturnsExpected(ButtonState buttonState, bool isHot, RadioButtonState expected) + { + RadioButtonRenderer.ConvertFromButtonState(buttonState, isHot).Should().Be(expected); + } + protected override ButtonBase CreateButton() => new RadioButton(); } From 3f017bcc9241540ee7d3580f383ea5b6d83dd8f2 Mon Sep 17 00:00:00 2001 From: "Zheng Li (BEYONDSOFT CONSULTING INC)" Date: Thu, 15 May 2025 09:25:08 +0800 Subject: [PATCH 2/5] Address FeedBacks --- .../System/Windows/Forms/RadioButtonRendererTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs index fa56fbad241..32ae3f4b964 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs @@ -357,7 +357,7 @@ public void DrawRadioButton_Internal_WithImageAndText_DoesNotThrow() ); } - [WinFormsTheory] + [Theory] [InlineData(RadioButtonState.CheckedNormal, ButtonState.Checked)] [InlineData(RadioButtonState.CheckedHot, ButtonState.Checked)] [InlineData(RadioButtonState.CheckedPressed, ButtonState.Checked | ButtonState.Pushed)] @@ -370,7 +370,7 @@ public void ConvertToButtonState_ReturnsExpected(RadioButtonState radioState, Bu RadioButtonRenderer.ConvertToButtonState(radioState).Should().Be(expected); } - [WinFormsTheory] + [Theory] [InlineData(ButtonState.Checked, false, RadioButtonState.CheckedNormal)] [InlineData(ButtonState.Checked, true, RadioButtonState.CheckedHot)] [InlineData(ButtonState.Checked | ButtonState.Pushed, false, RadioButtonState.CheckedPressed)] From a7427bfd31475c56f5e5bfa519aff8165767a6d5 Mon Sep 17 00:00:00 2001 From: v-zhgl <38325459+Zheng-Li01@users.noreply.github.com> Date: Mon, 16 Jun 2025 17:49:22 +0800 Subject: [PATCH 3/5] Update RadioButtonRendererTests.cs --- .../Windows/Forms/RadioButtonRendererTests.cs | 34 ++++--------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs index 32ae3f4b964..b3b416b95f0 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs @@ -194,44 +194,22 @@ public void IsBackgroundPartiallyTransparent_ReturnsExpected(RadioButtonState st } } - [WinFormsFact] - public void DrawParentBackground_DoesNotThrow_WhenVisualStylesDisabled() - { - using Form parent = new(); - using Panel child = new(); - parent.Controls.Add(child); - parent.Show(); - - using Bitmap bmp = new(10, 10); - using Graphics g = Graphics.FromImage(bmp); - - bool original = RadioButtonRenderer.RenderMatchingApplicationState; - try - { - RadioButtonRenderer.RenderMatchingApplicationState = true; - RadioButtonRenderer.DrawParentBackground(g, new Rectangle(0, 0, 10, 10), child); - } - finally - { - RadioButtonRenderer.RenderMatchingApplicationState = original; - } - } - - [WinFormsFact] - public void DrawParentBackground_CallsRenderer_WhenVisualStylesEnabled() + [WinFormsTheory] + [BoolData] + public void DrawParentBackground_DoesNotThrow_Or_CallsRenderer(bool renderMatchingApplicationState) { using Form parent = new(); using Panel child = new(); parent.Controls.Add(child); parent.Show(); - + using Bitmap bmp = new(10, 10); using Graphics g = Graphics.FromImage(bmp); - + bool original = RadioButtonRenderer.RenderMatchingApplicationState; try { - RadioButtonRenderer.RenderMatchingApplicationState = false; + RadioButtonRenderer.RenderMatchingApplicationState = renderMatchingApplicationState; RadioButtonRenderer.DrawParentBackground(g, new Rectangle(0, 0, 10, 10), child); } finally From 1727a1c87d562ff73d253342875548828de3ab8c Mon Sep 17 00:00:00 2001 From: v-zhgl <38325459+Zheng-Li01@users.noreply.github.com> Date: Tue, 17 Jun 2025 08:51:01 +0800 Subject: [PATCH 4/5] Update RadioButtonRendererTests.cs --- .../System/Windows/Forms/RadioButtonRendererTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs index b3b416b95f0..c743fadebd6 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs @@ -202,10 +202,8 @@ public void DrawParentBackground_DoesNotThrow_Or_CallsRenderer(bool renderMatchi using Panel child = new(); parent.Controls.Add(child); parent.Show(); - using Bitmap bmp = new(10, 10); using Graphics g = Graphics.FromImage(bmp); - bool original = RadioButtonRenderer.RenderMatchingApplicationState; try { From aacd200fc909ba55eb787fe09fb12e6981e629d3 Mon Sep 17 00:00:00 2001 From: v-zhgl <38325459+Zheng-Li01@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:40:51 +0800 Subject: [PATCH 5/5] Update RadioButtonRendererTests.cs --- .../System/Windows/Forms/RadioButtonRendererTests.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs index c743fadebd6..74f8f0e21cf 100644 --- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs +++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/RadioButtonRendererTests.cs @@ -219,11 +219,6 @@ public void DrawParentBackground_DoesNotThrow_Or_CallsRenderer(bool renderMatchi [WinFormsFact] public void DrawRadioButton_WithImage_Overload_CallsMainOverload() { - using Form form = new(); - using RadioButton control = (RadioButton)CreateButton(); - form.Controls.Add(control); - form.Show(); - using Bitmap bmp = new(20, 20); using Graphics g = Graphics.FromImage(bmp); using Image image = new Bitmap(10, 10);