зеркало из https://github.com/dotnet/winforms.git
Avoid Application.Exit in unit tests (#3097)
This commit is contained in:
Родитель
e45b38a61c
Коммит
7f5fd6e30b
15
Winforms.sln
15
Winforms.sln
|
@ -1,4 +1,3 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28627.84
|
||||
|
@ -124,6 +123,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Design.Editors.Facade3x", "src\System.Windows.Forms.Design.Editors\src\System.Windows.Forms.Design.Editors.Facade3x.csproj", "{E0681991-228A-420E-85D5-A9E796F0AAE0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiPropertyGridViewTests", "src\System.Windows.Forms\tests\IntegrationTests\MauiTests\MauiPropertyGridViewTests\MauiPropertyGridViewTests.csproj", "{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiMonthCalendarTests", "src\System.Windows.Forms\tests\IntegrationTests\MauiTests\MauimonthCalendarTests\MauiMonthCalendarTests.csproj", "{9DDC6936-9197-4C09-8640-AF0BE4918700}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiTestsHelper", "src\System.Windows.Forms\tests\IntegrationTests\MauiTests\MauiTestsHelper\MauiTestsHelper.csproj", "{44BB1092-1844-4EAF-8DF5-338DE4C3149A}"
|
||||
|
@ -132,6 +133,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Primit
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.TestUtilities", "src\System.Windows.Forms\tests\TestUtilities\System.Windows.Forms.TestUtilities.csproj", "{86418F0B-39DC-4B5A-8145-6D607E6150AC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiToolStripTests", "src\System.Windows.Forms\tests\IntegrationTests\MauiTests\MauiToolStripTests\MauiToolStripTests.csproj", "{83634671-CF3A-43B0-B729-42CCBA62DF2C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -250,6 +253,10 @@ Global
|
|||
{E0681991-228A-420E-85D5-A9E796F0AAE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0681991-228A-420E-85D5-A9E796F0AAE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0681991-228A-420E-85D5-A9E796F0AAE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9DDC6936-9197-4C09-8640-AF0BE4918700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9DDC6936-9197-4C09-8640-AF0BE4918700}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9DDC6936-9197-4C09-8640-AF0BE4918700}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -266,6 +273,10 @@ Global
|
|||
{86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83634671-CF3A-43B0-B729-42CCBA62DF2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83634671-CF3A-43B0-B729-42CCBA62DF2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83634671-CF3A-43B0-B729-42CCBA62DF2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83634671-CF3A-43B0-B729-42CCBA62DF2C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -304,10 +315,12 @@ Global
|
|||
{90B27178-F535-43F7-886E-0AB75203F246} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7}
|
||||
{9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC}
|
||||
{E0681991-228A-420E-85D5-A9E796F0AAE0} = {434C00C3-E498-4BA7-9764-9F0FC8CFE457}
|
||||
{F4E4EB7A-1A93-4D85-9E8E-8171809BEA4D} = {8F20A905-BD37-4D80-B8DF-FA45276FC23F}
|
||||
{9DDC6936-9197-4C09-8640-AF0BE4918700} = {8F20A905-BD37-4D80-B8DF-FA45276FC23F}
|
||||
{44BB1092-1844-4EAF-8DF5-338DE4C3149A} = {8F20A905-BD37-4D80-B8DF-FA45276FC23F}
|
||||
{73B0857A-966B-4E7D-8A83-FECFE0281AB9} = {DF68A171-D27B-4E6A-8A7E-63A651622355}
|
||||
{86418F0B-39DC-4B5A-8145-6D607E6150AC} = {DF68A171-D27B-4E6A-8A7E-63A651622355}
|
||||
{83634671-CF3A-43B0-B729-42CCBA62DF2C} = {8F20A905-BD37-4D80-B8DF-FA45276FC23F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7B1B0433-F612-4E5A-BE7E-FCF5B9F6E136}
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: System.Runtime.InteropServices.ComVisible(false)]
|
||||
|
||||
[assembly: InternalsVisibleTo("System.Windows.Forms.Tests, PublicKey=00000000000000000400000000000000")]
|
||||
[assembly: InternalsVisibleTo("MauiPropertyGridViewTests, PublicKey=00000000000000000400000000000000")]
|
||||
[assembly: InternalsVisibleTo("MauiMonthCalendarTests, PublicKey=00000000000000000400000000000000")]
|
||||
|
||||
// This is needed in order to Moq internal interfaces for testing
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\References.targets"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,78 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms.IntegrationTests.Common;
|
||||
using System.Windows.Forms.PropertyGridInternal;
|
||||
using ReflectTools;
|
||||
using WFCTestLib.Log;
|
||||
|
||||
namespace System.Windows.Forms.IntegrationTests.MauiTests
|
||||
{
|
||||
public class PropertyGridViewRowsAccessibleObjectTests : ReflectBase
|
||||
{
|
||||
private readonly DomainUpDown _domainUpDown;
|
||||
private readonly PropertyGrid _propertyGrid;
|
||||
|
||||
private const int bottomBorder = 1;
|
||||
private const int topBorder = 1;
|
||||
|
||||
public PropertyGridViewRowsAccessibleObjectTests(string[] args) : base(args)
|
||||
{
|
||||
this.BringToForeground();
|
||||
|
||||
_domainUpDown = new DomainUpDown();
|
||||
_propertyGrid = new PropertyGrid();
|
||||
_propertyGrid.Size = new Size(223, 244);
|
||||
ClientSize = new Size(508, 367);
|
||||
Controls.Add(_propertyGrid);
|
||||
Controls.Add(_domainUpDown);
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Thread.CurrentThread.SetCulture("en-US");
|
||||
Application.Run(new PropertyGridViewRowsAccessibleObjectTests(args));
|
||||
}
|
||||
|
||||
[Scenario(true)]
|
||||
public ScenarioResult PropertyGridViewRowsAccessibleObject_Ctor_Default(TParams p)
|
||||
{
|
||||
_propertyGrid.SelectedObject = _domainUpDown;
|
||||
int heightSum = 0;
|
||||
int entriesBorders = 0;
|
||||
|
||||
GridEntryCollection entries = _propertyGrid.GetPropEntries();
|
||||
PropertyGridView propertyGridView = (PropertyGridView)_propertyGrid.ActiveControl;
|
||||
|
||||
foreach (GridEntry entry in entries)
|
||||
{
|
||||
int entryHeight = propertyGridView.AccessibilityGetGridEntryBounds(entry).Height;
|
||||
heightSum += entryHeight;
|
||||
if (entryHeight > 0)
|
||||
{
|
||||
entriesBorders++;
|
||||
}
|
||||
|
||||
foreach (GridEntry item in entry.GridItems)
|
||||
{
|
||||
int itemHeight = propertyGridView.AccessibilityGetGridEntryBounds(item).Height;
|
||||
heightSum += itemHeight;
|
||||
if (itemHeight > 0)
|
||||
{
|
||||
entriesBorders++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (heightSum != propertyGridView.AccessibilityObject.Bounds.Height - topBorder - bottomBorder - entriesBorders)
|
||||
{
|
||||
return new ScenarioResult(false, "Incorrect dimensions");
|
||||
}
|
||||
|
||||
return new ScenarioResult(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Threading;
|
||||
using WFCTestLib.Log;
|
||||
using ReflectTools;
|
||||
using System.Windows.Forms.IntegrationTests.Common;
|
||||
|
||||
namespace System.Windows.Forms.IntegrationTests.MauiTests
|
||||
{
|
||||
public class MauiToolStripDropDownTests : ReflectBase
|
||||
{
|
||||
private readonly SubToolStripDropDown _toolStrip;
|
||||
|
||||
public MauiToolStripDropDownTests(string[] args) : base(args)
|
||||
{
|
||||
this.BringToForeground();
|
||||
_toolStrip = new SubToolStripDropDown();
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Thread.CurrentThread.SetCulture("en-US");
|
||||
Application.Run(new MauiToolStripDropDownTests(args));
|
||||
}
|
||||
|
||||
[Scenario(true)]
|
||||
public ScenarioResult KeyboardAccelerators_Test(TParams p)
|
||||
{
|
||||
bool _result = true;
|
||||
|
||||
_toolStrip.Enabled = true; // it needs for correct work of Control.CanProcessMnemonic method
|
||||
_toolStrip.Visible = true; //
|
||||
|
||||
_result &= !_toolStrip.ProcessDialogChar('F');
|
||||
|
||||
_toolStrip.DisplayedItems.Add("&First item");
|
||||
_toolStrip.DisplayedItems.Add("&Second item");
|
||||
_toolStrip.DisplayedItems.Add("Third item");
|
||||
_toolStrip.Visible = true; // it needs for correct work of Control.CanProcessMnemonic method
|
||||
|
||||
_result &= _toolStrip.ProcessDialogChar('F');
|
||||
_result &= _toolStrip.ProcessDialogChar('S');
|
||||
_result &= !_toolStrip.ProcessDialogChar('T');
|
||||
|
||||
return new ScenarioResult(_result);
|
||||
}
|
||||
|
||||
private class SubToolStripDropDown : ToolStripDropDown
|
||||
{
|
||||
public new ToolStripItemCollection DisplayedItems => base.DisplayedItems;
|
||||
|
||||
public new bool ProcessDialogChar(char charCode) => base.ProcessDialogChar(charCode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\References.targets"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,37 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Windows.Forms.Maui.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// This class runs a maui executable, which contains one or more scenarios.
|
||||
///
|
||||
/// We want to be able to represent each scenario as a seperate xUnit test, but it's not
|
||||
/// possible to run them independently. The workaround is to have a MauiTestRunner execute all
|
||||
/// the scenarios once and store the results, then feed the scenario names in as member data.
|
||||
///
|
||||
/// However, MemberData is resolved before any constructors (even static) are called.
|
||||
/// This means the scenario names will not be available yet.
|
||||
///
|
||||
/// The solution to this is to inherit from MemberDataAttribute and execute custom code
|
||||
/// (running the maui test) before returning the expected data. See MauiMemberDataAttribute.cs for more info.
|
||||
///
|
||||
/// Also [Collection("Maui")] is used put all maui tests in the same collection, which makes them run sequentially
|
||||
/// instead of in parallel. This is to migitate race conditions of multiple forms open at once.
|
||||
/// </summary>
|
||||
[Collection("Maui")]
|
||||
public class WinformsMauiPropertyGridViewTests
|
||||
{
|
||||
private const string ProjectName = "MauiPropertyGridViewTests";
|
||||
|
||||
[Theory]
|
||||
[MauiData(ProjectName)]
|
||||
public void MauiPropertyGridViewTests(string scenarioName)
|
||||
{
|
||||
MauiTestHelper.ValidateScenarioPassed(ProjectName, scenarioName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Windows.Forms.Maui.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// This class runs a maui executable, which contains one or more scenarios.
|
||||
///
|
||||
/// We want to be able to represent each scenario as a seperate xUnit test, but it's not
|
||||
/// possible to run them independently. The workaround is to have a MauiTestRunner execute all
|
||||
/// the scenarios once and store the results, then feed the scenario names in as member data.
|
||||
///
|
||||
/// However, MemberData is resolved before any constructors (even static) are called.
|
||||
/// This means the scenario names will not be available yet.
|
||||
///
|
||||
/// The solution to this is to inherit from MemberDataAttribute and execute custom code
|
||||
/// (running the maui test) before returning the expected data. See MauiMemberDataAttribute.cs for more info.
|
||||
///
|
||||
/// Also [Collection("Maui")] is used put all maui tests in the same collection, which makes them run sequentially
|
||||
/// instead of in parallel. This is to migitate race conditions of multiple forms open at once.
|
||||
/// </summary>
|
||||
[Collection("Maui")]
|
||||
public class WinformsMauiToolStripTests
|
||||
{
|
||||
private const string ProjectName = "MauiToolStripTests";
|
||||
|
||||
[Theory]
|
||||
[MauiData(ProjectName)]
|
||||
public void MauiToolStripTest(string scenarioName)
|
||||
{
|
||||
MauiTestHelper.ValidateScenarioPassed(ProjectName, scenarioName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms.PropertyGridInternal;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Windows.Forms.Tests.AccessibleObjects
|
||||
{
|
||||
public class PropertyGridViewRowsAccessibleObjectTests : IClassFixture<ThreadExceptionFixture>
|
||||
{
|
||||
[WinFormsFact(Skip = "Suspect causing deadlocks, see: https://github.com/dotnet/winforms/issues/3095")]
|
||||
public void PropertyGridViewRowsAccessibleObject_Ctor_Default()
|
||||
{
|
||||
TestForm form = new TestForm();
|
||||
Application.Run(form);
|
||||
|
||||
const int topBorder = 1;
|
||||
const int bottomBorder = 1;
|
||||
int entriesBorders = form.entriesBorders;
|
||||
|
||||
Assert.True(form.AccRowHeightSum == form.AccPropertyGridViewHeight - topBorder - bottomBorder - entriesBorders);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestForm : Form
|
||||
{
|
||||
public int AccPropertyGridViewHeight { get; set; }
|
||||
public int AccRowHeightSum { get; set; }
|
||||
|
||||
DomainUpDown domainUpDown;
|
||||
PropertyGrid propertyGrid;
|
||||
|
||||
public int entriesBorders = 0;
|
||||
|
||||
private void TestForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
propertyGrid.SelectedObject = domainUpDown;
|
||||
|
||||
GridEntryCollection entries = propertyGrid.GetPropEntries();
|
||||
PropertyGridView propertyGridView = (PropertyGridView)propertyGrid.ActiveControl;
|
||||
|
||||
foreach (GridEntry entry in entries)
|
||||
{
|
||||
int entryHeight = propertyGridView.AccessibilityGetGridEntryBounds(entry).Height;
|
||||
AccRowHeightSum += entryHeight;
|
||||
if (entryHeight > 0)
|
||||
{
|
||||
entriesBorders++;
|
||||
}
|
||||
|
||||
foreach (GridEntry item in entry.GridItems)
|
||||
{
|
||||
int itemHeight = propertyGridView.AccessibilityGetGridEntryBounds(item).Height;
|
||||
AccRowHeightSum += itemHeight;
|
||||
if (itemHeight > 0)
|
||||
{
|
||||
entriesBorders++;
|
||||
}
|
||||
}
|
||||
}
|
||||
AccPropertyGridViewHeight = propertyGridView.AccessibilityObject.Bounds.Height;
|
||||
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
public TestForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
domainUpDown = new DomainUpDown();
|
||||
propertyGrid = new PropertyGrid();
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
propertyGrid.Size = new Size(223, 244);
|
||||
//
|
||||
// TestForm
|
||||
//
|
||||
ClientSize = new Size(508, 367);
|
||||
Controls.Add(propertyGrid);
|
||||
Controls.Add(domainUpDown);
|
||||
Load += TestForm_Load;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4912,51 +4912,6 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[WinFormsFact(Skip = "Suspect causing deadlocks, see: https://github.com/dotnet/winforms/issues/3095")]
|
||||
public void ToolStripDropDown_KeyboardAccelerators_Test()
|
||||
{
|
||||
TestForm testForm = new TestForm();
|
||||
Application.Run(testForm); //it needs for correct work of ToolStripDropDown.CanProcessMnemonic method
|
||||
|
||||
//TestResult property is made as separate for the reason that
|
||||
//when the Assert is inside FormLoaded method and it fails,
|
||||
//the Application doesn't exit and the process freezes.
|
||||
Assert.True(testForm.TestResult);
|
||||
}
|
||||
|
||||
class TestForm : Form
|
||||
{
|
||||
private SubToolStripDropDown toolStrip;
|
||||
private bool _result = true;
|
||||
|
||||
public TestForm()
|
||||
{
|
||||
toolStrip = new SubToolStripDropDown();
|
||||
Load += FormLoaded;
|
||||
}
|
||||
|
||||
public bool TestResult => _result;
|
||||
|
||||
private void FormLoaded(object sender, EventArgs e)
|
||||
{
|
||||
toolStrip.Enabled = true; // it needs for correct work of Control.CanProcessMnemonic method
|
||||
toolStrip.Visible = true; //
|
||||
|
||||
_result &= !(toolStrip.ProcessDialogChar('F'));
|
||||
|
||||
toolStrip.DisplayedItems.Add("&First item");
|
||||
toolStrip.DisplayedItems.Add("&Second item");
|
||||
toolStrip.DisplayedItems.Add("Third item");
|
||||
toolStrip.Visible = true; // it needs for correct work of Control.CanProcessMnemonic method
|
||||
|
||||
_result &= toolStrip.ProcessDialogChar('F');
|
||||
_result &= toolStrip.ProcessDialogChar('S');
|
||||
_result &= !(toolStrip.ProcessDialogChar('T'));
|
||||
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
private class SubAxHost : AxHost
|
||||
{
|
||||
public SubAxHost(string clsid) : base(clsid)
|
||||
|
|
Загрузка…
Ссылка в новой задаче