From 4a460b419bbc8d147b268f704d9a876708a7614c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 11:38:15 +0200 Subject: [PATCH 01/11] Fix build in Visual Studio Building in Visual Studio causes some tasks to be run concurrently that would be run in a specific order in MSBuild instead. The symptom would look like this: MSB4044: The "GenerateWindowsAppManifest" task was not given a value for the required parameter "Version". Let's help Visual Studio realize that there are certain dependencies between the `GetVersion` and the `GenerateWindowsAppManifest` task. Reported by Michael J. Lyons. Signed-off-by: Johannes Schindelin --- Directory.Build.targets | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 72d4712e7..7ec523390 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -6,7 +6,7 @@ - + @@ -21,6 +21,7 @@ Date: Mon, 30 Sep 2024 12:24:13 +0200 Subject: [PATCH 02/11] Update the InnoSetup dependency to v6.3.1 There is actually v6.3.3 already, but it does not seem to have propagated to nuget.org yet. While at it, use a centrally-defined property instead of repeating the version number several times. Signed-off-by: Johannes Schindelin --- src/windows/Installer.Windows/Installer.Windows.csproj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/windows/Installer.Windows/Installer.Windows.csproj b/src/windows/Installer.Windows/Installer.Windows.csproj index 99253c445..bbd49a291 100644 --- a/src/windows/Installer.Windows/Installer.Windows.csproj +++ b/src/windows/Installer.Windows/Installer.Windows.csproj @@ -7,6 +7,7 @@ false false $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\win-x86 + 6.3.1 @@ -18,7 +19,7 @@ - + @@ -26,8 +27,8 @@ - "$(NuGetPackageRoot)Tools.InnoSetup\6.0.5\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" - "$(NuGetPackageRoot)Tools.InnoSetup\6.0.5\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" + "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" + "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" From c6d28d378623601fbcef9c48b707aa512dfd7777 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 12:52:07 +0200 Subject: [PATCH 03/11] installer: do require Windows 7 SP1 or later Previously, we only required Windows 7, but that is not recommended by InnoSetup. Let's do enforce at least SP1 of that Windows version, which is past its end-of-life, anyway. Signed-off-by: Johannes Schindelin --- src/windows/Installer.Windows/Setup.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/Installer.Windows/Setup.iss b/src/windows/Installer.Windows/Setup.iss index f3ce31cbb..9fc8ff674 100644 --- a/src/windows/Installer.Windows/Setup.iss +++ b/src/windows/Installer.Windows/Setup.iss @@ -73,7 +73,7 @@ OutputBaseFilename={#GcmSetupExe}-win-{#GcmArch}-{#GcmVersionSimple} DefaultDirName={autopf}\{#GcmShortName} Compression=lzma2 SolidCompression=yes -MinVersion=6.1.7600 +MinVersion=6.1sp1 DisableDirPage=yes UninstallDisplayIcon={app}\{#GcmExe} SetupIconFile={#GcmAssets}\gcmicon.ico From 5441da03bf0240ffa9304aeae1d3df9d65011f0f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 12:58:09 +0200 Subject: [PATCH 04/11] installer: avoid using the deprecated `ParseVersion()` function It has been renamed to `GetVersionComponents()` (leaving a deprecated shim in place of the original name). Signed-off-by: Johannes Schindelin --- src/windows/Installer.Windows/Setup.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/Installer.Windows/Setup.iss b/src/windows/Installer.Windows/Setup.iss index 9fc8ff674..ae7167892 100644 --- a/src/windows/Installer.Windows/Setup.iss +++ b/src/windows/Installer.Windows/Setup.iss @@ -51,7 +51,7 @@ #define VerMinor #define VerBuild #define VerRevision -#expr ParseVersion(PayloadDir + "\" + GcmExe, VerMajor, VerMinor, VerBuild, VerRevision) +#expr GetVersionComponents(PayloadDir + "\" + GcmExe, VerMajor, VerMinor, VerBuild, VerRevision) #define GcmVersionSimple str(VerMajor) + "." + str(VerMinor) + "." + str(VerBuild) #define GcmVersion str(GcmVersionSimple) + "." + str(VerRevision) From cf935a76af43d0e39ca6578d88f2bdb8bed93ec4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 12:59:21 +0200 Subject: [PATCH 05/11] installer: avoid running the `UninstallRun` entry more than once Under certain circumstances, it is possible for `[UninstallRun]` entries to be run multiple times. To avoid that, we now use a `RunOnceId`. Signed-off-by: Johannes Schindelin --- src/windows/Installer.Windows/Setup.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/Installer.Windows/Setup.iss b/src/windows/Installer.Windows/Setup.iss index ae7167892..f03d16c9b 100644 --- a/src/windows/Installer.Windows/Setup.iss +++ b/src/windows/Installer.Windows/Setup.iss @@ -100,7 +100,7 @@ Name: full; Description: "Full installation"; Flags: iscustom; Filename: "{app}\{#GcmExe}"; Parameters: "configure {#GcmConfigureCmdArgs}"; Flags: runhidden [UninstallRun] -Filename: "{app}\{#GcmExe}"; Parameters: "unconfigure {#GcmConfigureCmdArgs}"; Flags: runhidden +Filename: "{app}\{#GcmExe}"; Parameters: "unconfigure {#GcmConfigureCmdArgs}"; Flags: runhidden; RunOnceId: "unconfigure" [Files] Source: "{#PayloadDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs From a749c9217aa977efb49f2ba351e62254c1225076 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 11:46:16 +0200 Subject: [PATCH 06/11] Update the remaining dependencies Visual Studio pointed out that a couple of dependencies were in need of being updated. After already upgrading InnoSetup over the preceding commits, this here commit does _almost_ what Visual Studio suggested. The only exception is that we continue to define the `System.Text.Json` version centrally, in `Directory.Build.props`, which Visual Studio did not know how to update (and therefore wanted to add the dependency individually to seven `.csproj` files instead). Signed-off-by: Johannes Schindelin --- Directory.Build.props | 2 +- .../Atlassian.Bitbucket.Tests.csproj | 11 +++++++---- src/shared/Core.Tests/Core.Tests.csproj | 11 +++++++---- src/shared/Core/Core.csproj | 18 +++++++++--------- src/shared/GitHub.Tests/GitHub.Tests.csproj | 11 +++++++---- src/shared/GitLab.Tests/GitLab.Tests.csproj | 11 +++++++---- .../Microsoft.AzureRepos.Tests.csproj | 11 +++++++---- .../TestInfrastructure.csproj | 6 +++--- 8 files changed, 48 insertions(+), 33 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 8c94238ca..5c0d87bdb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -28,7 +28,7 @@ - 7.0.2 + 8.0.4 diff --git a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj index d5d08797c..9e768b91c 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj +++ b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj @@ -8,13 +8,16 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/shared/Core.Tests/Core.Tests.csproj b/src/shared/Core.Tests/Core.Tests.csproj index db045a83b..e3ae7e6b0 100644 --- a/src/shared/Core.Tests/Core.Tests.csproj +++ b/src/shared/Core.Tests/Core.Tests.csproj @@ -9,13 +9,16 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/shared/Core/Core.csproj b/src/shared/Core/Core.csproj index fb3a189d3..f2804177b 100644 --- a/src/shared/Core/Core.csproj +++ b/src/shared/Core/Core.csproj @@ -13,25 +13,25 @@ - - + + - + - - + + - - - + + + - + diff --git a/src/shared/GitHub.Tests/GitHub.Tests.csproj b/src/shared/GitHub.Tests/GitHub.Tests.csproj index 1b892075e..0574e00d1 100644 --- a/src/shared/GitHub.Tests/GitHub.Tests.csproj +++ b/src/shared/GitHub.Tests/GitHub.Tests.csproj @@ -8,13 +8,16 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/shared/GitLab.Tests/GitLab.Tests.csproj b/src/shared/GitLab.Tests/GitLab.Tests.csproj index 253c36db4..098878aec 100644 --- a/src/shared/GitLab.Tests/GitLab.Tests.csproj +++ b/src/shared/GitLab.Tests/GitLab.Tests.csproj @@ -8,13 +8,16 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj index 01ec9d411..1c673bcc9 100644 --- a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj +++ b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj @@ -8,13 +8,16 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/shared/TestInfrastructure/TestInfrastructure.csproj b/src/shared/TestInfrastructure/TestInfrastructure.csproj index 569b64cd5..63f6fee89 100644 --- a/src/shared/TestInfrastructure/TestInfrastructure.csproj +++ b/src/shared/TestInfrastructure/TestInfrastructure.csproj @@ -9,9 +9,9 @@ - - - + + + From 6f13e76a2730162dbb2cb33502f979f02aa75e25 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 11:50:21 +0200 Subject: [PATCH 07/11] Properly await `Assert.ThrowsAsync()` calls Pointed out by Visual Studio. Signed-off-by: Johannes Schindelin --- .../Core.Tests/Authentication/BasicAuthenticationTests.cs | 8 ++++---- src/shared/Core.Tests/HostProviderRegistryTests.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs b/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs index 446d5c9bf..18f477382 100644 --- a/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs +++ b/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs @@ -12,12 +12,12 @@ namespace GitCredentialManager.Tests.Authentication public class BasicAuthenticationTests { [Fact] - public void BasicAuthentication_GetCredentials_NullResource_ThrowsException() + public async Task BasicAuthentication_GetCredentials_NullResource_ThrowsException() { var context = new TestCommandContext(); var basicAuth = new BasicAuthentication(context); - Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(null)); + await Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(null)); } [Fact] @@ -58,7 +58,7 @@ public async Task BasicAuthentication_GetCredentials_NonDesktopSession_Resource_ } [Fact] - public void BasicAuthentication_GetCredentials_NonDesktopSession_NoTerminalPrompts_ThrowsException() + public async Task BasicAuthentication_GetCredentials_NonDesktopSession_NoTerminalPrompts_ThrowsException() { const string testResource = "https://example.com"; @@ -70,7 +70,7 @@ public void BasicAuthentication_GetCredentials_NonDesktopSession_NoTerminalPromp var basicAuth = new BasicAuthentication(context); - Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(testResource)); + await Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(testResource)); } [Fact] diff --git a/src/shared/Core.Tests/HostProviderRegistryTests.cs b/src/shared/Core.Tests/HostProviderRegistryTests.cs index 8bae48d33..c8345a5ca 100644 --- a/src/shared/Core.Tests/HostProviderRegistryTests.cs +++ b/src/shared/Core.Tests/HostProviderRegistryTests.cs @@ -35,13 +35,13 @@ public void HostProviderRegistry_Register_AutoAuthorityId_ThrowException() } [Fact] - public void HostProviderRegistry_GetProvider_NoProviders_ThrowException() + public async Task HostProviderRegistry_GetProvider_NoProviders_ThrowException() { var context = new TestCommandContext(); var registry = new HostProviderRegistry(context); var input = new InputArguments(new Dictionary()); - Assert.ThrowsAsync(() => registry.GetProviderAsync(input)); + await Assert.ThrowsAsync(() => registry.GetProviderAsync(input)); } [Fact] From da12fc9ce77b6e66abf7160077c30700fab36a71 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 11:53:56 +0200 Subject: [PATCH 08/11] Use `Assert.Fail(message)` as appropriate Visual Studio pointed out that this coding pattern is preferred to `Assert.True(false, message)`. Signed-off-by: Johannes Schindelin --- src/shared/Core.Tests/HostProviderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/Core.Tests/HostProviderTests.cs b/src/shared/Core.Tests/HostProviderTests.cs index 64dd444d9..60d0cfba8 100644 --- a/src/shared/Core.Tests/HostProviderTests.cs +++ b/src/shared/Core.Tests/HostProviderTests.cs @@ -30,7 +30,7 @@ public async Task HostProvider_GetCredentialAsync_CredentialExists_ReturnsExisti IsSupportedFunc = _ => true, GenerateCredentialFunc = _ => { - Assert.True(false, "Should never be called"); + Assert.Fail("Should never be called"); return null; }, }; From 48d06a759aa8fe77c5f51ba10af06cbd01c7c830 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 11:51:01 +0200 Subject: [PATCH 09/11] Use preferred `Assert.*` patterns Visual Studio pointed out a couple of instances where `Assert.Equal(0, X.Count)` was used instead of `Assert.Empty(X)`, and similarly `Assert.Equal(1, X.Count)` instead of `Assert.Single(X)`. Let's accept the suggested fixes and thereby address the last remaining warnings when building in Visual Studio. Signed-off-by: Johannes Schindelin --- src/shared/Core.Tests/ApplicationTests.cs | 2 +- src/shared/Core.Tests/CurlCookieTests.cs | 2 +- src/shared/Core.Tests/HostProviderRegistryTests.cs | 4 ++-- src/shared/Core.Tests/IniFileTests.cs | 6 +++--- src/shared/Core.Tests/StreamExtensionsTests.cs | 10 +++++----- .../Objects/TestHttpMessageHandler.cs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shared/Core.Tests/ApplicationTests.cs b/src/shared/Core.Tests/ApplicationTests.cs index d62782f10..f983e8d54 100644 --- a/src/shared/Core.Tests/ApplicationTests.cs +++ b/src/shared/Core.Tests/ApplicationTests.cs @@ -244,7 +244,7 @@ public async Task Application_UnconfigureAsync_EmptyAndGcmWithOthersBefore_Remov Assert.Single(context.Git.Configuration.Global); Assert.True(context.Git.Configuration.Global.TryGetValue(key, out var actualValues)); - Assert.Equal(1, actualValues.Count); + Assert.Single(actualValues); Assert.Equal(beforeHelper, actualValues[0]); } diff --git a/src/shared/Core.Tests/CurlCookieTests.cs b/src/shared/Core.Tests/CurlCookieTests.cs index 811bdd2c2..3d161d76d 100644 --- a/src/shared/Core.Tests/CurlCookieTests.cs +++ b/src/shared/Core.Tests/CurlCookieTests.cs @@ -37,7 +37,7 @@ public void CurlCookieParser_Parse_MissingFields_SkipsInvalidLines() IList actual = parser.Parse(content); - Assert.Equal(1, actual.Count); + Assert.Single(actual); AssertCookie(actual[0], ".example.com", "/path/here", true, 0, "cookie1", "value1"); } diff --git a/src/shared/Core.Tests/HostProviderRegistryTests.cs b/src/shared/Core.Tests/HostProviderRegistryTests.cs index c8345a5ca..5406ba918 100644 --- a/src/shared/Core.Tests/HostProviderRegistryTests.cs +++ b/src/shared/Core.Tests/HostProviderRegistryTests.cs @@ -119,7 +119,7 @@ public async Task HostProviderRegistry_GetProvider_Auto_HasProviders_DynamicMatc Assert.Same(providerMock.Object, result); Assert.True(context.Git.Configuration.Global.TryGetValue(configKey, out IList config)); - Assert.Equal(1, config.Count); + Assert.Single(config); Assert.Equal(providerId, config[0]); } @@ -148,7 +148,7 @@ public async Task HostProviderRegistry_GetProvider_Auto_HasProviders_DynamicMatc Assert.Same(providerMock.Object, result); Assert.True(context.Git.Configuration.Global.TryGetValue(configKey, out IList config)); - Assert.Equal(1, config.Count); + Assert.Single(config); Assert.Equal(providerId, config[0]); } diff --git a/src/shared/Core.Tests/IniFileTests.cs b/src/shared/Core.Tests/IniFileTests.cs index a661547d4..2cbbf8aa0 100644 --- a/src/shared/Core.Tests/IniFileTests.cs +++ b/src/shared/Core.Tests/IniFileTests.cs @@ -79,7 +79,7 @@ recovery tests] Assert.Equal(6, ini.Sections.Count); AssertSection(ini, "one", out IniSection one); - Assert.Equal(1, one.Properties.Count); + Assert.Single(one.Properties); AssertProperty(one, "foo", "123"); AssertSection(ini, "two", out IniSection twoA); @@ -88,7 +88,7 @@ recovery tests] AssertProperty(twoA, "widget", "Hello, World!"); AssertSection(ini, "two", "subsection name", out IniSection twoB); - Assert.Equal(1, twoB.Properties.Count); + Assert.Single(twoB.Properties); AssertProperty(twoB, "foo", "this is different"); AssertSection(ini, "three", out IniSection three); @@ -97,7 +97,7 @@ recovery tests] AssertProperty(three, "empty", ""); AssertSection(ini, "four", out IniSection four); - Assert.Equal(0, four.Properties.Count); + Assert.Empty(four.Properties); AssertSection(ini, "five", out IniSection five); Assert.Equal(3, five.Properties.Count); diff --git a/src/shared/Core.Tests/StreamExtensionsTests.cs b/src/shared/Core.Tests/StreamExtensionsTests.cs index 56a7c762b..09153ad26 100644 --- a/src/shared/Core.Tests/StreamExtensionsTests.cs +++ b/src/shared/Core.Tests/StreamExtensionsTests.cs @@ -21,7 +21,7 @@ public void StreamExtensions_ReadDictionary_EmptyString_ReturnsEmptyDictionary() var output = ReadStringStream(input, StreamExtensions.ReadDictionary); Assert.NotNull(output); - Assert.Equal(0, output.Count); + Assert.Empty(output); } [Fact] @@ -73,7 +73,7 @@ public void StreamExtensions_ReadDictionary_CaseInsensitive_ReturnsDictionaryWit var output = ReadStringStream(input, x => StreamExtensions.ReadDictionary(x, StringComparer.OrdinalIgnoreCase)); Assert.NotNull(output); - Assert.Equal(1, output.Count); + Assert.Single(output); AssertDictionary("2", "a", output); } @@ -197,7 +197,7 @@ public void StreamExtensions_ReadMultiDictionary_EmptyString_ReturnsEmptyDiction var output = ReadStringStream(input, StreamExtensions.ReadMultiDictionary); Assert.NotNull(output); - Assert.Equal(0, output.Count); + Assert.Empty(output); } [Fact] @@ -250,7 +250,7 @@ public void StreamExtensions_ReadMultiDictionary_CaseInsensitive_ReturnsDictiona var output = ReadStringStream(input, x => StreamExtensions.ReadMultiDictionary(x, StringComparer.OrdinalIgnoreCase)); Assert.NotNull(output); - Assert.Equal(1, output.Count); + Assert.Single(output); AssertMultiDictionary(new[] { "2" }, "a", output); } @@ -262,7 +262,7 @@ public void StreamExtensions_ReadMultiDictionary_EmptyString_ReturnsKeyWithEmpty var output = ReadStringStream(input, StreamExtensions.ReadMultiDictionary); Assert.NotNull(output); - Assert.Equal(1, output.Count); + Assert.Single(output); AssertMultiDictionary(new[] { String.Empty, }, "a", output); } diff --git a/src/shared/TestInfrastructure/Objects/TestHttpMessageHandler.cs b/src/shared/TestInfrastructure/Objects/TestHttpMessageHandler.cs index 0a2c46e18..afe2ee77b 100644 --- a/src/shared/TestInfrastructure/Objects/TestHttpMessageHandler.cs +++ b/src/shared/TestInfrastructure/Objects/TestHttpMessageHandler.cs @@ -65,7 +65,7 @@ public void AssertRequest(HttpMethod method, Uri uri, int expectedNumberOfCalls) public void AssertNoRequests() { - Assert.Equal(0, _requestCounts.Count); + Assert.Empty(_requestCounts); } #region HttpMessageHandler From 8bfe765a1b650f243c08eda713941140b8892b79 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 12:50:46 +0200 Subject: [PATCH 10/11] Use the `Trace2Exception` It seems that (probably due to updated dependencies), there is a problem where the `Trace2Exception` no longer inherits from `InvalidOperationException`. Let's use the former, then. Signed-off-by: Johannes Schindelin --- .../Core.Tests/Authentication/BasicAuthenticationTests.cs | 2 +- src/shared/Core.Tests/HostProviderRegistryTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs b/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs index 18f477382..ba42b3b05 100644 --- a/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs +++ b/src/shared/Core.Tests/Authentication/BasicAuthenticationTests.cs @@ -70,7 +70,7 @@ public async Task BasicAuthentication_GetCredentials_NonDesktopSession_NoTermina var basicAuth = new BasicAuthentication(context); - await Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(testResource)); + await Assert.ThrowsAsync(() => basicAuth.GetCredentialsAsync(testResource)); } [Fact] diff --git a/src/shared/Core.Tests/HostProviderRegistryTests.cs b/src/shared/Core.Tests/HostProviderRegistryTests.cs index 5406ba918..33725758d 100644 --- a/src/shared/Core.Tests/HostProviderRegistryTests.cs +++ b/src/shared/Core.Tests/HostProviderRegistryTests.cs @@ -41,7 +41,7 @@ public async Task HostProviderRegistry_GetProvider_NoProviders_ThrowException() var registry = new HostProviderRegistry(context); var input = new InputArguments(new Dictionary()); - await Assert.ThrowsAsync(() => registry.GetProviderAsync(input)); + await Assert.ThrowsAsync(() => registry.GetProviderAsync(input)); } [Fact] From 1a774c1c2bf637bc3589b24c78fe58103499b0db Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Sep 2024 13:12:29 +0200 Subject: [PATCH 11/11] Replace broken `PlatformFact()` constructs We just upgraded XUnit to a newer version, which unfortunately no longer works with the `PlatformFact()` constructs of `Xunit.SkippableFact` even though we updated to the latest version, v1.4.13. It might have something to do with the fact that that package has not been updated since July 9th, 2024. Happily, XUnit has grown equivalent features in the meantime that we can use instead. So let's use those XUnit-native constructs instead. Note that we still cannot drop the `SkippableFact` dependency altogether because we need it in the `MacOSKeychain_ReadWriteDelete` test case. It is needed to work around a flaky test that is caused by semi-random broken states of macOS' key-chain, and that can only be detected while the test case is running (and hence _needs_ `AssertEx.Skip()`, which in turn requires `Xunit.Skip.If()` that is provided only via the `SkippableFact` package and there is no equivalent native XUnit functionality). Helped-by: Matthew Cheetham Signed-off-by: Johannes Schindelin --- src/shared/Core.Tests/EnvironmentTests.cs | 22 ++--- .../Core.Tests/GenericHostProviderTests.cs | 4 +- .../Interop/Linux/LinuxFileSystemTests.cs | 12 +-- .../Linux/SecretServiceCollectionTests.cs | 6 +- .../Interop/MacOS/MacOSFileSystemTests.cs | 12 +-- .../Interop/MacOS/MacOSKeychainTests.cs | 6 +- .../Posix/GnuPassCredentialStoreTests.cs | 6 +- .../Interop/Posix/PosixFileSystemTests.cs | 4 +- .../Windows/DpapiCredentialStoreTests.cs | 8 +- .../Windows/WindowsCredentialManagerTests.cs | 26 +++--- .../Interop/Windows/WindowsFileSystemTests.cs | 10 +-- src/shared/Core.Tests/Trace2Tests.cs | 4 +- src/shared/Core.Tests/WslUtilsTests.cs | 4 +- .../AzureReposHostProviderTests.cs | 10 +-- .../TestInfrastructure/PlatformAttributes.cs | 87 +++++++++++-------- 15 files changed, 120 insertions(+), 101 deletions(-) diff --git a/src/shared/Core.Tests/EnvironmentTests.cs b/src/shared/Core.Tests/EnvironmentTests.cs index bd7a8c99b..d9b7cb67c 100644 --- a/src/shared/Core.Tests/EnvironmentTests.cs +++ b/src/shared/Core.Tests/EnvironmentTests.cs @@ -15,7 +15,7 @@ public class EnvironmentTests private const string PosixPathVar = "/home/john.doe/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"; private const string PosixExecName = "foo"; - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsEnvironment_TryLocateExecutable_NotExists_ReturnFalse() { var fs = new TestFileSystem(); @@ -28,7 +28,7 @@ public void WindowsEnvironment_TryLocateExecutable_NotExists_ReturnFalse() Assert.Null(actualPath); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() { string expectedPath = @"C:\Windows\system32\foo.exe"; @@ -48,7 +48,7 @@ public void WindowsEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() Assert.Equal(expectedPath, actualPath); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFirstPath() { string expectedPath = @"C:\Users\john.doe\bin\foo.exe"; @@ -70,7 +70,7 @@ public void WindowsEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndF Assert.Equal(expectedPath, actualPath); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void PosixEnvironment_TryLocateExecutable_NotExists_ReturnFalse() { var fs = new TestFileSystem(); @@ -83,7 +83,7 @@ public void PosixEnvironment_TryLocateExecutable_NotExists_ReturnFalse() Assert.Null(actualPath); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void PosixEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() { string expectedPath = "/usr/local/bin/foo"; @@ -103,7 +103,7 @@ public void PosixEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() Assert.Equal(expectedPath, actualPath); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void PosixEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFirstPath() { string expectedPath = "/home/john.doe/bin/foo"; @@ -125,7 +125,7 @@ public void PosixEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFir Assert.Equal(expectedPath, actualPath); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public void MacOSEnvironment_TryLocateExecutable_Paths_Are_Ignored() { List pathsToIgnore = new List() @@ -150,8 +150,8 @@ public void MacOSEnvironment_TryLocateExecutable_Paths_Are_Ignored() Assert.True(actualResult); Assert.Equal(expectedPath, actualPath); } - - [PlatformFact(Platforms.Posix)] + + [PosixFact] public void PosixEnvironment_SetEnvironmentVariable_Sets_Expected_Value() { var variable = "FOO_BAR"; @@ -166,8 +166,8 @@ public void PosixEnvironment_SetEnvironmentVariable_Sets_Expected_Value() Assert.Contains(env.Variables, item => item.Key.Equals(variable) && item.Value.Equals(value)); } - - [PlatformFact(Platforms.Windows)] + + [WindowsFact] public void WindowsEnvironment_SetEnvironmentVariable_Sets_Expected_Value() { var variable = "FOO_BAR"; diff --git a/src/shared/Core.Tests/GenericHostProviderTests.cs b/src/shared/Core.Tests/GenericHostProviderTests.cs index 39ed85cfe..8f9594b06 100644 --- a/src/shared/Core.Tests/GenericHostProviderTests.cs +++ b/src/shared/Core.Tests/GenericHostProviderTests.cs @@ -169,13 +169,13 @@ public async Task GenericHostProvider_CreateCredentialAsync_NonHttpProtocol_Retu basicAuthMock.Verify(x => x.GetCredentialsAsync(It.IsAny(), It.IsAny()), Times.Once); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public async Task GenericHostProvider_CreateCredentialAsync_NonWindows_WiaSupported_ReturnsBasicCredential() { await TestCreateCredentialAsync_ReturnsBasicCredential(wiaSupported: true); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task GenericHostProvider_CreateCredentialAsync_Windows_WiaSupported_ReturnsEmptyCredential() { await TestCreateCredentialAsync_ReturnsEmptyCredential(wiaSupported: true); diff --git a/src/shared/Core.Tests/Interop/Linux/LinuxFileSystemTests.cs b/src/shared/Core.Tests/Interop/Linux/LinuxFileSystemTests.cs index 4f283294c..2cd6d3cc1 100644 --- a/src/shared/Core.Tests/Interop/Linux/LinuxFileSystemTests.cs +++ b/src/shared/Core.Tests/Interop/Linux/LinuxFileSystemTests.cs @@ -7,7 +7,7 @@ namespace GitCredentialManager.Tests.Interop.Linux { public class LinuxFileSystemTests { - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_SamePath_ReturnsTrue() { var fs = new LinuxFileSystem(); @@ -18,7 +18,7 @@ public static void LinuxFileSystem_IsSamePath_SamePath_ReturnsTrue() Assert.True(fs.IsSamePath(fileA, fileA)); } - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_DifferentFile_ReturnsFalse() { var fs = new LinuxFileSystem(); @@ -31,7 +31,7 @@ public static void LinuxFileSystem_IsSamePath_DifferentFile_ReturnsFalse() Assert.False(fs.IsSamePath(fileB, fileA)); } - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_SameFileDifferentCase_ReturnsFalse() { var fs = new LinuxFileSystem(); @@ -44,7 +44,7 @@ public static void LinuxFileSystem_IsSamePath_SameFileDifferentCase_ReturnsFalse Assert.False(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_SameFileDifferentPathNormalization_ReturnsTrue() { var fs = new LinuxFileSystem(); @@ -58,7 +58,7 @@ public static void LinuxFileSystem_IsSamePath_SameFileDifferentPathNormalization Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_SameFileViaSymlink_ReturnsTrue() { var fs = new LinuxFileSystem(); @@ -71,7 +71,7 @@ public static void LinuxFileSystem_IsSamePath_SameFileViaSymlink_ReturnsTrue() Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.Linux)] + [LinuxFact] public static void LinuxFileSystem_IsSamePath_SameFileRelativePath_ReturnsTrue() { var fs = new LinuxFileSystem(); diff --git a/src/shared/Core.Tests/Interop/Linux/SecretServiceCollectionTests.cs b/src/shared/Core.Tests/Interop/Linux/SecretServiceCollectionTests.cs index 1237e2907..8cc6c7272 100644 --- a/src/shared/Core.Tests/Interop/Linux/SecretServiceCollectionTests.cs +++ b/src/shared/Core.Tests/Interop/Linux/SecretServiceCollectionTests.cs @@ -8,7 +8,7 @@ public class SecretServiceCollectionTests { private const string TestNamespace = "git-test"; - [PlatformFact(Platforms.Linux, Skip = "Cannot run headless")] + [LinuxFact(Skip = "Cannot run headless")] public void SecretServiceCollection_ReadWriteDelete() { var collection = new SecretServiceCollection(TestNamespace); @@ -37,7 +37,7 @@ public void SecretServiceCollection_ReadWriteDelete() } } - [PlatformFact(Platforms.Linux, Skip = "Cannot run headless")] + [LinuxFact(Skip = "Cannot run headless")] public void SecretServiceCollection_Get_NotFound_ReturnsNull() { var collection = new SecretServiceCollection(TestNamespace); @@ -49,7 +49,7 @@ public void SecretServiceCollection_Get_NotFound_ReturnsNull() Assert.Null(credential); } - [PlatformFact(Platforms.Linux, Skip = "Cannot run headless")] + [LinuxFact(Skip = "Cannot run headless")] public void SecretServiceCollection_Remove_NotFound_ReturnsFalse() { var collection = new SecretServiceCollection(TestNamespace); diff --git a/src/shared/Core.Tests/Interop/MacOS/MacOSFileSystemTests.cs b/src/shared/Core.Tests/Interop/MacOS/MacOSFileSystemTests.cs index 54916103a..85643f8fd 100644 --- a/src/shared/Core.Tests/Interop/MacOS/MacOSFileSystemTests.cs +++ b/src/shared/Core.Tests/Interop/MacOS/MacOSFileSystemTests.cs @@ -7,7 +7,7 @@ namespace GitCredentialManager.Tests.Interop.MacOS { public class MacOSFileSystemTests { - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_SamePath_ReturnsTrue() { var fs = new MacOSFileSystem(); @@ -18,7 +18,7 @@ public static void MacOSFileSystem_IsSamePath_SamePath_ReturnsTrue() Assert.True(fs.IsSamePath(fileA, fileA)); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_DifferentFile_ReturnsFalse() { var fs = new MacOSFileSystem(); @@ -31,7 +31,7 @@ public static void MacOSFileSystem_IsSamePath_DifferentFile_ReturnsFalse() Assert.False(fs.IsSamePath(fileB, fileA)); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_SameFileDifferentCase_ReturnsTrue() { var fs = new MacOSFileSystem(); @@ -44,7 +44,7 @@ public static void MacOSFileSystem_IsSamePath_SameFileDifferentCase_ReturnsTrue( Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_SameFileDifferentPathNormalization_ReturnsTrue() { var fs = new MacOSFileSystem(); @@ -58,7 +58,7 @@ public static void MacOSFileSystem_IsSamePath_SameFileDifferentPathNormalization Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_SameFileViaSymlink_ReturnsTrue() { var fs = new MacOSFileSystem(); @@ -71,7 +71,7 @@ public static void MacOSFileSystem_IsSamePath_SameFileViaSymlink_ReturnsTrue() Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public static void MacOSFileSystem_IsSamePath_SameFileRelativePath_ReturnsTrue() { var fs = new MacOSFileSystem(); diff --git a/src/shared/Core.Tests/Interop/MacOS/MacOSKeychainTests.cs b/src/shared/Core.Tests/Interop/MacOS/MacOSKeychainTests.cs index 8ad1caead..e9c517d88 100644 --- a/src/shared/Core.Tests/Interop/MacOS/MacOSKeychainTests.cs +++ b/src/shared/Core.Tests/Interop/MacOS/MacOSKeychainTests.cs @@ -10,7 +10,7 @@ public class MacOSKeychainTests { private const string TestNamespace = "git-test"; - [SkippablePlatformFact(Platforms.MacOS)] + [MacOSFact] public void MacOSKeychain_ReadWriteDelete() { var keychain = new MacOSKeychain(TestNamespace); @@ -52,7 +52,7 @@ public void MacOSKeychain_ReadWriteDelete() } } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public void MacOSKeychain_Get_NotFound_ReturnsNull() { var keychain = new MacOSKeychain(TestNamespace); @@ -64,7 +64,7 @@ public void MacOSKeychain_Get_NotFound_ReturnsNull() Assert.Null(credential); } - [PlatformFact(Platforms.MacOS)] + [MacOSFact] public void MacOSKeychain_Remove_NotFound_ReturnsFalse() { var keychain = new MacOSKeychain(TestNamespace); diff --git a/src/shared/Core.Tests/Interop/Posix/GnuPassCredentialStoreTests.cs b/src/shared/Core.Tests/Interop/Posix/GnuPassCredentialStoreTests.cs index 423868bd7..7ff80f03d 100644 --- a/src/shared/Core.Tests/Interop/Posix/GnuPassCredentialStoreTests.cs +++ b/src/shared/Core.Tests/Interop/Posix/GnuPassCredentialStoreTests.cs @@ -11,7 +11,7 @@ public class GnuPassCredentialStoreTests { private const string TestNamespace = "git-test"; - [PlatformFact(Platforms.Posix)] + [PosixFact] public void GnuPassCredentialStore_ReadWriteDelete() { var fs = new TestFileSystem(); @@ -54,7 +54,7 @@ public void GnuPassCredentialStore_ReadWriteDelete() } } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void GnuPassCredentialStore_Get_NotFound_ReturnsNull() { var fs = new TestFileSystem(); @@ -70,7 +70,7 @@ public void GnuPassCredentialStore_Get_NotFound_ReturnsNull() Assert.Null(credential); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void GnuPassCredentialStore_Remove_NotFound_ReturnsFalse() { var fs = new TestFileSystem(); diff --git a/src/shared/Core.Tests/Interop/Posix/PosixFileSystemTests.cs b/src/shared/Core.Tests/Interop/Posix/PosixFileSystemTests.cs index 56dc3a4e3..607eb2e66 100644 --- a/src/shared/Core.Tests/Interop/Posix/PosixFileSystemTests.cs +++ b/src/shared/Core.Tests/Interop/Posix/PosixFileSystemTests.cs @@ -7,7 +7,7 @@ namespace GitCredentialManager.Tests.Interop.Posix { public class PosixFileSystemTests { - [PlatformFact(Platforms.Posix)] + [PosixFact] public void PosixFileSystem_ResolveSymlinks_FileLinks() { string baseDir = GetTempDirectory(); @@ -19,7 +19,7 @@ public void PosixFileSystem_ResolveSymlinks_FileLinks() Assert.Equal(realPath, actual); } - [PlatformFact(Platforms.Posix)] + [PosixFact] public void PosixFileSystem_ResolveSymlinks_DirectoryLinks() { // diff --git a/src/shared/Core.Tests/Interop/Windows/DpapiCredentialStoreTests.cs b/src/shared/Core.Tests/Interop/Windows/DpapiCredentialStoreTests.cs index 202924f69..bb7026903 100644 --- a/src/shared/Core.Tests/Interop/Windows/DpapiCredentialStoreTests.cs +++ b/src/shared/Core.Tests/Interop/Windows/DpapiCredentialStoreTests.cs @@ -13,7 +13,7 @@ public class DpapiCredentialStoreTests private const string TestStoreRoot = @"C:\dpapi_store"; private const string TestNamespace = "git-test"; - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void DpapiCredentialStore_AddOrUpdate_CreatesUTF8ProtectedFile() { var fs = new TestFileSystem(); @@ -49,7 +49,7 @@ public void DpapiCredentialStore_AddOrUpdate_CreatesUTF8ProtectedFile() Assert.True(string.IsNullOrWhiteSpace(lines[3])); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void DpapiCredentialStore_Get_KeyNotFound_ReturnsNull() { var fs = new TestFileSystem(); @@ -62,7 +62,7 @@ public void DpapiCredentialStore_Get_KeyNotFound_ReturnsNull() Assert.Null(credential); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void DpapiCredentialStore_Get_ReadProtectedFile() { var fs = new TestFileSystem(); @@ -97,7 +97,7 @@ public void DpapiCredentialStore_Get_ReadProtectedFile() Assert.Equal(userName, credential.Account); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void DpapiCredentialStore_Remove_KeyNotFound_ReturnsFalse() { var fs = new TestFileSystem(); diff --git a/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs b/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs index b7b5cef62..ba4659ec0 100644 --- a/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs +++ b/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs @@ -9,7 +9,7 @@ public class WindowsCredentialManagerTests { private const string TestNamespace = "git-test"; - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_ReadWriteDelete() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -45,7 +45,7 @@ public void WindowsCredentialManager_ReadWriteDelete() } } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_AddOrUpdate_UsernameWithAtCharacter() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -81,7 +81,7 @@ public void WindowsCredentialManager_AddOrUpdate_UsernameWithAtCharacter() } } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_Get_KeyNotFound_ReturnsNull() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -93,7 +93,7 @@ public void WindowsCredentialManager_Get_KeyNotFound_ReturnsNull() Assert.Null(credential); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_Remove_KeyNotFound_ReturnsFalse() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -105,7 +105,7 @@ public void WindowsCredentialManager_Remove_KeyNotFound_ReturnsFalse() Assert.False(result); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_AddOrUpdate_TargetNameAlreadyExists_CreatesWithUserInTargetName() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -155,7 +155,7 @@ public void WindowsCredentialManager_AddOrUpdate_TargetNameAlreadyExists_Creates } } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_AddOrUpdate_TargetNameAlreadyExistsAndUserWithAtCharacter_CreatesWithEscapedUserInTargetName() { var credManager = new WindowsCredentialManager(TestNamespace); @@ -235,7 +235,7 @@ public void WindowsCredentialManager_RemoveUriUserInfo(string input, string expe Assert.Equal(expected, actual); } - [PlatformTheory(Platforms.Windows)] + [WindowsTheory] [InlineData("https://example.com", null, "https://example.com", "alice", true)] [InlineData("https://example.com", "alice", "https://example.com", "alice", true)] [InlineData("https://example.com", null, "https://example.com:443", "alice", true)] @@ -270,7 +270,7 @@ public void WindowsCredentialManager_IsMatch( Assert.Equal(expected, actual); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_IsMatch_NoNamespace_NotMatched() { var win32Cred = new Win32Credential @@ -286,7 +286,7 @@ public void WindowsCredentialManager_IsMatch_NoNamespace_NotMatched() Assert.False(result); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_IsMatch_DifferentNamespace_NotMatched() { var win32Cred = new Win32Credential @@ -302,7 +302,7 @@ public void WindowsCredentialManager_IsMatch_DifferentNamespace_NotMatched() Assert.False(result); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_IsMatch_CaseSensitiveNamespace_NotMatched() { var win32Cred = new Win32Credential @@ -318,7 +318,7 @@ public void WindowsCredentialManager_IsMatch_CaseSensitiveNamespace_NotMatched() Assert.False(result); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WindowsCredentialManager_IsMatch_NoNamespaceInQuery_IsMatched() { var win32Cred = new Win32Credential @@ -334,7 +334,7 @@ public void WindowsCredentialManager_IsMatch_NoNamespaceInQuery_IsMatched() Assert.True(result); } - [PlatformTheory(Platforms.Windows)] + [WindowsTheory] [InlineData("https://example.com", null, "https://example.com")] [InlineData("https://example.com", "bob", "https://bob@example.com")] [InlineData("https://example.com", "bob@id.example.com", "https://bob_id.example.com@example.com")] // @ in user @@ -355,7 +355,7 @@ public void WindowsCredentialManager_CreateTargetName(string service, string acc Assert.Equal(fullExpected, actual); } - [PlatformTheory(Platforms.Windows)] + [WindowsTheory] [InlineData(TestNamespace, "https://example.com", null, $"{TestNamespace}:https://example.com")] [InlineData(null, "https://example.com", null, "https://example.com")] [InlineData("", "https://example.com", null, "https://example.com")] diff --git a/src/shared/Core.Tests/Interop/Windows/WindowsFileSystemTests.cs b/src/shared/Core.Tests/Interop/Windows/WindowsFileSystemTests.cs index a94a76597..be89bc1fc 100644 --- a/src/shared/Core.Tests/Interop/Windows/WindowsFileSystemTests.cs +++ b/src/shared/Core.Tests/Interop/Windows/WindowsFileSystemTests.cs @@ -7,7 +7,7 @@ namespace GitCredentialManager.Tests.Interop.Windows { public class WindowsFileSystemTests { - [PlatformFact(Platforms.Windows)] + [WindowsFact] public static void WindowsFileSystem_IsSamePath_SamePath_ReturnsTrue() { var fs = new WindowsFileSystem(); @@ -18,7 +18,7 @@ public static void WindowsFileSystem_IsSamePath_SamePath_ReturnsTrue() Assert.True(fs.IsSamePath(fileA, fileA)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public static void WindowsFileSystem_IsSamePath_DifferentFile_ReturnsFalse() { var fs = new WindowsFileSystem(); @@ -31,7 +31,7 @@ public static void WindowsFileSystem_IsSamePath_DifferentFile_ReturnsFalse() Assert.False(fs.IsSamePath(fileB, fileA)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public static void WindowsFileSystem_IsSamePath_SameFileDifferentCase_ReturnsTrue() { var fs = new WindowsFileSystem(); @@ -44,7 +44,7 @@ public static void WindowsFileSystem_IsSamePath_SameFileDifferentCase_ReturnsTru Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public static void WindowsFileSystem_IsSamePath_SameFileDifferentPathNormalization_ReturnsTrue() { var fs = new WindowsFileSystem(); @@ -58,7 +58,7 @@ public static void WindowsFileSystem_IsSamePath_SameFileDifferentPathNormalizati Assert.True(fs.IsSamePath(fileA2, fileA1)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public static void WindowsFileSystem_IsSamePath_SameFileRelativePath_ReturnsTrue() { var fs = new WindowsFileSystem(); diff --git a/src/shared/Core.Tests/Trace2Tests.cs b/src/shared/Core.Tests/Trace2Tests.cs index 60d89ac2f..26df5ab98 100644 --- a/src/shared/Core.Tests/Trace2Tests.cs +++ b/src/shared/Core.Tests/Trace2Tests.cs @@ -4,7 +4,7 @@ namespace GitCredentialManager.Tests; public class Trace2Tests { - [PlatformTheory(Platforms.Posix)] + [PosixTheory] [InlineData("af_unix:foo", "foo")] [InlineData("af_unix:stream:foo-bar", "foo-bar")] [InlineData("af_unix:dgram:foo-bar-baz", "foo-bar-baz")] @@ -16,7 +16,7 @@ public void TryGetPipeName_Posix_Returns_Expected_Value(string input, string exp Assert.Matches(actual, expected); } - [PlatformTheory(Platforms.Windows)] + [WindowsTheory] [InlineData("\\\\.\\pipe\\git-foo", "git-foo")] [InlineData("\\\\.\\pipe\\git-foo-bar", "git-foo-bar")] [InlineData("\\\\.\\pipe\\foo\\git-bar", "git-bar")] diff --git a/src/shared/Core.Tests/WslUtilsTests.cs b/src/shared/Core.Tests/WslUtilsTests.cs index 722a8654d..330e42c84 100644 --- a/src/shared/Core.Tests/WslUtilsTests.cs +++ b/src/shared/Core.Tests/WslUtilsTests.cs @@ -92,7 +92,7 @@ public void WslUtils_ConvertToDistroPath_Invalid_ThrowsException(string path) Assert.Throws(() => WslUtils.ConvertToDistroPath(path, out _)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WslUtils_CreateWslProcess() { const string distribution = "ubuntu"; @@ -112,7 +112,7 @@ public void WslUtils_CreateWslProcess() Assert.False(process.StartInfo.UseShellExecute); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public void WslUtils_CreateWslProcess_WorkingDirectory() { const string distribution = "ubuntu"; diff --git a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs index e8da8d79c..e379aaa3b 100644 --- a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs +++ b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs @@ -705,7 +705,7 @@ public async Task AzureReposHostProvider_UnconfigureAsync_UseHttpPathSet_Removes Assert.Empty(context.Git.Configuration.Global); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttpPathSetAndManagerHelper_DoesNotRemoveEntry() { var context = new TestCommandContext(); @@ -721,7 +721,7 @@ public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttp Assert.Equal("true", actualValues[0]); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttpPathSetAndManagerCoreHelper_DoesNotRemoveEntry() { var context = new TestCommandContext(); @@ -737,7 +737,7 @@ public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttp Assert.Equal("true", actualValues[0]); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttpPathSetNoManagerCoreHelper_RemovesEntry() { var context = new TestCommandContext(); @@ -750,7 +750,7 @@ public async Task AzureReposHostProvider_UnconfigureAsync_System_Windows_UseHttp Assert.Empty(context.Git.Configuration.System); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task AzureReposHostProvider_UnconfigureAsync_User_Windows_UseHttpPathSetAndManagerHelper_RemovesEntry() { var context = new TestCommandContext(); @@ -764,7 +764,7 @@ public async Task AzureReposHostProvider_UnconfigureAsync_User_Windows_UseHttpPa Assert.False(context.Git.Configuration.Global.TryGetValue(AzDevUseHttpPathKey, out _)); } - [PlatformFact(Platforms.Windows)] + [WindowsFact] public async Task AzureReposHostProvider_UnconfigureAsync_User_Windows_UseHttpPathSetAndManagerCoreHelper_RemovesEntry() { var context = new TestCommandContext(); diff --git a/src/shared/TestInfrastructure/PlatformAttributes.cs b/src/shared/TestInfrastructure/PlatformAttributes.cs index 24217602d..50d9d6c34 100644 --- a/src/shared/TestInfrastructure/PlatformAttributes.cs +++ b/src/shared/TestInfrastructure/PlatformAttributes.cs @@ -1,76 +1,95 @@ -using System; using System.Runtime.InteropServices; using Xunit; namespace GitCredentialManager.Tests { - public class PlatformFactAttribute : FactAttribute + public class WindowsFactAttribute : FactAttribute { - public PlatformFactAttribute(Platforms platforms) + public WindowsFactAttribute() { - if (!XunitHelpers.IsSupportedPlatform(platforms)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Skip = "Test not supported on this platform."; } } } - public class PlatformTheoryAttribute : TheoryAttribute + public class MacOSFactAttribute : FactAttribute { - public PlatformTheoryAttribute(Platforms platforms) + public MacOSFactAttribute() { - if (!XunitHelpers.IsSupportedPlatform(platforms)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Skip = "Test not supported on this platform."; } } } - public class SkippablePlatformFactAttribute : SkippableFactAttribute + public class LinuxFactAttribute : FactAttribute { - public SkippablePlatformFactAttribute(Platforms platforms) + public LinuxFactAttribute() { - Xunit.Skip.IfNot( - XunitHelpers.IsSupportedPlatform(platforms), - "Test not supported on this platform." - ); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Skip = "Test not supported on this platform."; + } } } - public class SkippablePlatformTheoryAttribute : SkippableTheoryAttribute + public class PosixFactAttribute : FactAttribute { - public SkippablePlatformTheoryAttribute(Platforms platforms) + public PosixFactAttribute() { - Xunit.Skip.IfNot( - XunitHelpers.IsSupportedPlatform(platforms), - "Test not supported on this platform." - ); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Skip = "Test not supported on this platform."; + } } } - internal static class XunitHelpers + public class WindowsTheoryAttribute : TheoryAttribute { - public static bool IsSupportedPlatform(Platforms platforms) + public WindowsTheoryAttribute() { - if (platforms.HasFlag(Platforms.Windows) && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || - platforms.HasFlag(Platforms.MacOS) && RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || - platforms.HasFlag(Platforms.Linux) && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - return true; + Skip = "Test not supported on this platform."; } + } + } - return false; + public class MacOSTheoryAttribute : TheoryAttribute + { + public MacOSTheoryAttribute() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Skip = "Test not supported on this platform."; + } } } - [Flags] - public enum Platforms + public class LinuxTheoryAttribute : TheoryAttribute { - None = 0, - Windows = 1 << 0, - MacOS = 1 << 2, - Linux = 1 << 3, - Posix = MacOS | Linux, - All = Windows | Posix + public LinuxTheoryAttribute() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Skip = "Test not supported on this platform."; + } + } + } + + public class PosixTheoryAttribute : TheoryAttribute + { + public PosixTheoryAttribute() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Skip = "Test not supported on this platform."; + } + } } }