diff --git a/global.json b/global.json
index 1dc269111cae..2b0f56d196c0 100644
--- a/global.json
+++ b/global.json
@@ -26,6 +26,6 @@
"Microsoft.Build.NoTargets": "3.7.134",
"Microsoft.Build.Traversal": "4.1.82",
"Microsoft.WixToolset.Sdk": "6.0.3-dotnet.4",
- "MSTest.Sdk": "4.3.0-preview.26307.5"
+ "MSTest.Sdk": "4.3.0-preview.26311.10"
}
}
diff --git a/sdk.slnx b/sdk.slnx
index df9722223799..07d879bec7b9 100644
--- a/sdk.slnx
+++ b/sdk.slnx
@@ -367,6 +367,7 @@
+
diff --git a/src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs b/src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs
index 74a1e15ab7a8..3d48d3fc6f5e 100644
--- a/src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs
+++ b/src/Dotnet.Watch/Watch.Aspire/Properties/AssemblyInfo.cs
@@ -4,4 +4,5 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.DotNet.HotReload.Watch.Aspire.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("dotnet-watch.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/src/Dotnet.Watch/dotnet-watch.slnf b/src/Dotnet.Watch/dotnet-watch.slnf
index 48e156d1458e..b5600195a12e 100644
--- a/src/Dotnet.Watch/dotnet-watch.slnf
+++ b/src/Dotnet.Watch/dotnet-watch.slnf
@@ -33,6 +33,7 @@
"test\\dotnet-watch-test-browser\\dotnet-watch-test-browser.csproj",
"test\\Microsoft.DotNet.HotReload.Test.Utilities\\Microsoft.DotNet.HotReload.Test.Utilities.csproj",
"test\\Microsoft.DotNet.HotReload.Watch.Aspire.Tests\\Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj",
+ "test\\Microsoft.DotNet.Test.MSTest.Utilities\\Microsoft.DotNet.Test.MSTest.Utilities.csproj",
"test\\Microsoft.Extensions.DotNetDeltaApplier.Tests\\Microsoft.Extensions.DotNetDeltaApplier.Tests.csproj",
"test\\dotnet-watch.Tests\\dotnet-watch.Tests.csproj"
]
diff --git a/test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj b/test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj
index 898749c592b6..3802f96de8ab 100644
--- a/test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj
+++ b/test/Microsoft.DotNet.ApiCompat.Tests/Microsoft.DotNet.ApiCompat.Tests.csproj
@@ -1,8 +1,7 @@
-
+
$(SdkTargetFramework)
- Exe
@@ -12,10 +11,9 @@
-
-
+
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs b/test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs
index bed3d912cfbd..683d3a626cbd 100644
--- a/test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs
+++ b/test/Microsoft.DotNet.ApiCompat.Tests/RegexStringTransformerTests.cs
@@ -1,13 +1,14 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.DotNet.ApiCompat;
namespace Microsoft.DotNet.ApiCompatibility.Tests
{
+ [TestClass]
public class RegexStringTransformerTests
{
- [Fact]
+ [TestMethod]
public void Transform_CaptureGroupPatternDoesNotMatchInput_ReturnsInput()
{
const string CaptureGroupPattern = "(abc)def";
@@ -16,10 +17,10 @@ public void Transform_CaptureGroupPatternDoesNotMatchInput_ReturnsInput()
string output = new RegexStringTransformer(CaptureGroupPattern, ReplacementPattern).Transform(Input);
- Assert.Equal(Input, output);
+ Assert.AreEqual(Input, output);
}
- [Fact]
+ [TestMethod]
public void Transform_ReplacementPatternWithoutCaptureGroups_ReturnsReplacementPattern()
{
const string CaptureGroupPattern = "(abc)d*";
@@ -28,10 +29,10 @@ public void Transform_ReplacementPatternWithoutCaptureGroups_ReturnsReplacementP
string output = new RegexStringTransformer(CaptureGroupPattern, ReplacementPattern).Transform(Input);
- Assert.Equal(ReplacementPattern, output);
+ Assert.AreEqual(ReplacementPattern, output);
}
- [Fact]
+ [TestMethod]
public void Transform_ReplacementPatternWithTooManyReplacementMarkers_ReturnOutputWithoutTransformedReplacementMarkers()
{
const string CaptureGroupPattern = "(abc)(def)ghi";
@@ -40,10 +41,10 @@ public void Transform_ReplacementPatternWithTooManyReplacementMarkers_ReturnOutp
string output = new RegexStringTransformer(CaptureGroupPattern, ReplacementPattern).Transform(Input);
- Assert.Equal("1:abc, 2:def, 3:$3", output);
+ Assert.AreEqual("1:abc, 2:def, 3:$3", output);
}
- [Fact]
+ [TestMethod]
public void Transform_SameNumberOfGroupsAndMarkers_ReturnsExpected()
{
const string CaptureGroupPattern = @".+\\(.+)\\(.+)";
@@ -52,10 +53,10 @@ public void Transform_SameNumberOfGroupsAndMarkers_ReturnsExpected()
string output = new RegexStringTransformer(CaptureGroupPattern, ReplacementPattern).Transform(Input);
- Assert.Equal("lib/net7.0-android/System.Linq.dll", output);
+ Assert.AreEqual("lib/net7.0-android/System.Linq.dll", output);
}
- [Fact]
+ [TestMethod]
public void Transform_MultiplePatterns_ReturnsExpected()
{
var patterns = new (string, string)[]
@@ -69,7 +70,7 @@ public void Transform_MultiplePatterns_ReturnsExpected()
string output = new RegexStringTransformer(patterns).Transform(Input);
- Assert.Equal("runtimes/android/lib/net7.0/System.Linq.dll", output);
+ Assert.AreEqual("runtimes/android/lib/net7.0/System.Linq.dll", output);
}
}
}
diff --git a/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj b/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
index 7500dad99340..ef519bdfcde4 100644
--- a/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
+++ b/test/Microsoft.DotNet.HotReload.Client.Tests/Microsoft.DotNet.HotReload.Client.Tests.csproj
@@ -17,6 +17,10 @@
+
+
+
+
diff --git a/test/Microsoft.DotNet.HotReload.Client.Tests/StaticWebAssetsManifestTests.cs b/test/Microsoft.DotNet.HotReload.Client.Tests/StaticWebAssetsManifestTests.cs
index 87d3eadc3176..e82b59ba8884 100644
--- a/test/Microsoft.DotNet.HotReload.Client.Tests/StaticWebAssetsManifestTests.cs
+++ b/test/Microsoft.DotNet.HotReload.Client.Tests/StaticWebAssetsManifestTests.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.DotNet.Watch.UnitTests;
+using Microsoft.DotNet.Test.MSTest.Utilities;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.DotNet.HotReload.UnitTests;
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherCliTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherCliTests.cs
index b7d9c7f69059..c5b3e40cf567 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherCliTests.cs
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherCliTests.cs
@@ -1,145 +1,146 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Extensions.Logging;
namespace Microsoft.DotNet.Watch.UnitTests;
+[TestClass]
public class AspireHostLauncherCliTests
{
- [Fact]
+ [TestMethod]
public void RequiredSdkOption()
{
// --sdk option is missing
var args = new[] { "host", "--entrypoint", "proj", "a", "b" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void RequiredEntryPointOption()
{
// --entrypoint option is missing
var args = new[] { "host", "--sdk", "sdk", "--verbose" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void ProjectAndSdkPaths()
{
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "myproject.csproj" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("sdk", launcher.EnvironmentOptions.SdkDirectory);
- Assert.True(launcher.EntryPoint.IsProjectFile);
- Assert.Equal("myproject.csproj", launcher.EntryPoint.PhysicalPath);
- Assert.Empty(launcher.ApplicationArguments);
- Assert.Equal(LogLevel.Information, launcher.GlobalOptions.LogLevel);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("sdk", launcher.EnvironmentOptions.SdkDirectory);
+ Assert.IsTrue(launcher.EntryPoint.IsProjectFile);
+ Assert.AreEqual("myproject.csproj", launcher.EntryPoint.PhysicalPath);
+ Assert.IsEmpty(launcher.ApplicationArguments);
+ Assert.AreEqual(LogLevel.Information, launcher.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void FilePath()
{
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "file.cs" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("sdk", launcher.EnvironmentOptions.SdkDirectory);
- Assert.False(launcher.EntryPoint.IsProjectFile);
- Assert.Equal("file.cs", launcher.EntryPoint.EntryPointFilePath);
- Assert.Empty(launcher.ApplicationArguments);
- Assert.Equal(LogLevel.Information, launcher.GlobalOptions.LogLevel);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("sdk", launcher.EnvironmentOptions.SdkDirectory);
+ Assert.IsFalse(launcher.EntryPoint.IsProjectFile);
+ Assert.AreEqual("file.cs", launcher.EntryPoint.EntryPointFilePath);
+ Assert.IsEmpty(launcher.ApplicationArguments);
+ Assert.AreEqual(LogLevel.Information, launcher.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void ApplicationArguments()
{
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--verbose", "a", "b" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- AssertEx.SequenceEqual(["a", "b"], launcher.ApplicationArguments);
- Assert.Equal(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreSequenceEqual(["a", "b"], launcher.ApplicationArguments);
+ Assert.AreEqual(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void VerboseOption()
{
// With verbose flag
var argsVerbose = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--verbose" };
- var launcherVerbose = Assert.IsType(AspireLauncher.TryCreate(argsVerbose));
- Assert.Equal(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
+ var launcherVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsVerbose));
+ Assert.AreEqual(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
// Without verbose flag
var argsNotVerbose = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj" };
- var launcherNotVerbose = Assert.IsType(AspireLauncher.TryCreate(argsNotVerbose));
- Assert.Equal(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
+ var launcherNotVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotVerbose));
+ Assert.AreEqual(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void QuietOption()
{
// With quiet flag
var argsQuiet = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--quiet" };
- var launcherQuiet = Assert.IsType(AspireLauncher.TryCreate(argsQuiet));
- Assert.Equal(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
+ var launcherQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsQuiet));
+ Assert.AreEqual(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
// Without quiet flag
var argsNotQuiet = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj" };
- var launcherNotQuiet = Assert.IsType(AspireLauncher.TryCreate(argsNotQuiet));
- Assert.Equal(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
+ var launcherNotQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotQuiet));
+ Assert.AreEqual(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void NoLaunchProfileOption()
{
// With no-launch-profile flag
var argsNoProfile = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--no-launch-profile" };
- var launcherNoProfile = Assert.IsType(AspireLauncher.TryCreate(argsNoProfile));
- Assert.False(launcherNoProfile.LaunchProfileName.HasValue);
+ var launcherNoProfile = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNoProfile));
+ Assert.IsFalse(launcherNoProfile.LaunchProfileName.HasValue);
// Without no-launch-profile flag
var argsDefault = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj" };
- var launcherDefault = Assert.IsType(AspireLauncher.TryCreate(argsDefault));
- Assert.True(launcherDefault.LaunchProfileName.HasValue);
- Assert.Null(launcherDefault.LaunchProfileName.Value);
+ var launcherDefault = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsDefault));
+ Assert.IsTrue(launcherDefault.LaunchProfileName.HasValue);
+ Assert.IsNull(launcherDefault.LaunchProfileName.Value);
}
- [Fact]
+ [TestMethod]
public void LaunchProfileOption()
{
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--launch-profile", "MyProfile" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.True(launcher.LaunchProfileName.HasValue);
- Assert.Equal("MyProfile", launcher.LaunchProfileName.Value);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.IsTrue(launcher.LaunchProfileName.HasValue);
+ Assert.AreEqual("MyProfile", launcher.LaunchProfileName.Value);
}
- [Fact]
+ [TestMethod]
public void ConflictingOptions()
{
// Cannot specify both --quiet and --verbose
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj", "--quiet", "--verbose" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void EntryPoint_MultipleValues()
{
// EntryPoint option should only accept one value; extra values become application arguments
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "proj1", "proj2" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("proj1", launcher.EntryPoint.ProjectOrEntryPointFilePath);
- AssertEx.SequenceEqual(["proj2"], launcher.ApplicationArguments);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("proj1", launcher.EntryPoint.ProjectOrEntryPointFilePath);
+ Assert.AreSequenceEqual(["proj2"], launcher.ApplicationArguments);
}
- [Fact]
+ [TestMethod]
public void AllOptionsSet()
{
var args = new[] { "host", "--sdk", "sdk", "--entrypoint", "myapp.csproj", "--verbose", "--no-launch-profile", "arg1", "arg2", "arg3" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
-
- Assert.True(launcher.EntryPoint.IsProjectFile);
- Assert.Equal("myapp.csproj", launcher.EntryPoint.PhysicalPath);
- Assert.Equal("sdk", launcher.EnvironmentOptions.SdkDirectory);
- Assert.Equal(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
- Assert.False(launcher.LaunchProfileName.HasValue);
- AssertEx.SequenceEqual(["arg1", "arg2", "arg3"], launcher.ApplicationArguments);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+
+ Assert.IsTrue(launcher.EntryPoint.IsProjectFile);
+ Assert.AreEqual("myapp.csproj", launcher.EntryPoint.PhysicalPath);
+ Assert.AreEqual("sdk", launcher.EnvironmentOptions.SdkDirectory);
+ Assert.AreEqual(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
+ Assert.IsFalse(launcher.LaunchProfileName.HasValue);
+ Assert.AreSequenceEqual(["arg1", "arg2", "arg3"], launcher.ApplicationArguments);
}
-}
+}
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherTests.cs
index 94abac0ac2ca..23ca92043e70 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherTests.cs
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireHostLauncherTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Immutable;
@@ -6,6 +6,7 @@
namespace Microsoft.DotNet.Watch.UnitTests;
+[TestClass]
public class AspireHostLauncherTests
{
private static AspireHostLauncher CreateLauncher(
@@ -33,13 +34,13 @@ private static AspireHostLauncher CreateLauncher(
private static void AssertCommonProperties(ProjectOptions options, AspireHostLauncher launcher)
{
- Assert.True(options.IsMainProject);
- Assert.Equal("run", options.Command);
- Assert.Equal(launcher.EntryPoint, options.Representation);
- Assert.Empty(options.LaunchEnvironmentVariables);
+ Assert.IsTrue(options.IsMainProject);
+ Assert.AreEqual("run", options.Command);
+ Assert.AreEqual(launcher.EntryPoint, options.Representation);
+ Assert.IsEmpty(options.LaunchEnvironmentVariables);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_ProjectFile_UsesProjectFlag()
{
var launcher = CreateLauncher("myapp.csproj");
@@ -47,11 +48,11 @@ public void GetProjectOptions_ProjectFile_UsesProjectFlag()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.False(options.LaunchProfileName.HasValue);
- AssertEx.SequenceEqual(["--project", "myapp.csproj", "--no-launch-profile"], options.CommandArguments);
+ Assert.IsFalse(options.LaunchProfileName.HasValue);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj", "--no-launch-profile"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_EntryPointFile_UsesFileFlag()
{
var launcher = CreateLauncher("Program.cs");
@@ -59,11 +60,11 @@ public void GetProjectOptions_EntryPointFile_UsesFileFlag()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.False(options.LaunchProfileName.HasValue);
- AssertEx.SequenceEqual(["--file", "Program.cs", "--no-launch-profile"], options.CommandArguments);
+ Assert.IsFalse(options.LaunchProfileName.HasValue);
+ Assert.AreSequenceEqual(["--file", "Program.cs", "--no-launch-profile"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_WithLaunchProfile_AddsLaunchProfileArguments()
{
var launcher = CreateLauncher("myapp.csproj", launchProfileName: "MyProfile");
@@ -71,12 +72,12 @@ public void GetProjectOptions_WithLaunchProfile_AddsLaunchProfileArguments()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.True(options.LaunchProfileName.HasValue);
- Assert.Equal("MyProfile", options.LaunchProfileName.Value);
- AssertEx.SequenceEqual(["--project", "myapp.csproj", "--launch-profile", "MyProfile"], options.CommandArguments);
+ Assert.IsTrue(options.LaunchProfileName.HasValue);
+ Assert.AreEqual("MyProfile", options.LaunchProfileName.Value);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj", "--launch-profile", "MyProfile"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_NoLaunchProfile_AddsNoLaunchProfileFlag()
{
var launcher = CreateLauncher("myapp.csproj", launchProfileName: Optional.NoValue);
@@ -84,11 +85,11 @@ public void GetProjectOptions_NoLaunchProfile_AddsNoLaunchProfileFlag()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.False(options.LaunchProfileName.HasValue);
- AssertEx.SequenceEqual(["--project", "myapp.csproj", "--no-launch-profile"], options.CommandArguments);
+ Assert.IsFalse(options.LaunchProfileName.HasValue);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj", "--no-launch-profile"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_NullLaunchProfile_UsesDefault()
{
// null value (HasValue=true) means use default launch profile - no --launch-profile or --no-launch-profile flag
@@ -97,12 +98,12 @@ public void GetProjectOptions_NullLaunchProfile_UsesDefault()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.True(options.LaunchProfileName.HasValue);
- Assert.Null(options.LaunchProfileName.Value);
- AssertEx.SequenceEqual(["--project", "myapp.csproj"], options.CommandArguments);
+ Assert.IsTrue(options.LaunchProfileName.HasValue);
+ Assert.IsNull(options.LaunchProfileName.Value);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_WithApplicationArguments_AppendsArguments()
{
var launcher = CreateLauncher("myapp.csproj", launchProfileName: "Profile", applicationArguments: ["arg1", "arg2"]);
@@ -110,12 +111,12 @@ public void GetProjectOptions_WithApplicationArguments_AppendsArguments()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.True(options.LaunchProfileName.HasValue);
- Assert.Equal("Profile", options.LaunchProfileName.Value);
- AssertEx.SequenceEqual(["--project", "myapp.csproj", "--launch-profile", "Profile", "arg1", "arg2"], options.CommandArguments);
+ Assert.IsTrue(options.LaunchProfileName.HasValue);
+ Assert.AreEqual("Profile", options.LaunchProfileName.Value);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj", "--launch-profile", "Profile", "arg1", "arg2"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_SetsCustomWorkingDirectory()
{
var launcher = CreateLauncher("myapp.csproj", workingDirectory: "/custom/path");
@@ -123,10 +124,10 @@ public void GetProjectOptions_SetsCustomWorkingDirectory()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.Equal("/custom/path", options.WorkingDirectory);
+ Assert.AreEqual("/custom/path", options.WorkingDirectory);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_EntryPointFile_WithLaunchProfileAndArguments()
{
var launcher = CreateLauncher("Program.cs", launchProfileName: "Dev", applicationArguments: ["--port", "8080"]);
@@ -134,12 +135,12 @@ public void GetProjectOptions_EntryPointFile_WithLaunchProfileAndArguments()
var options = launcher.GetHostProjectOptions()!;
AssertCommonProperties(options, launcher);
- Assert.True(options.LaunchProfileName.HasValue);
- Assert.Equal("Dev", options.LaunchProfileName.Value);
- AssertEx.SequenceEqual(["--file", "Program.cs", "--launch-profile", "Dev", "--port", "8080"], options.CommandArguments);
+ Assert.IsTrue(options.LaunchProfileName.HasValue);
+ Assert.AreEqual("Dev", options.LaunchProfileName.Value);
+ Assert.AreSequenceEqual(["--file", "Program.cs", "--launch-profile", "Dev", "--port", "8080"], options.CommandArguments);
}
- [Fact]
+ [TestMethod]
public void GetProjectOptions_NoLaunchProfile_WithApplicationArguments()
{
var launcher = CreateLauncher("myapp.csproj", launchProfileName: Optional.NoValue, applicationArguments: ["--urls", "http://localhost:5000"]);
@@ -147,7 +148,7 @@ public void GetProjectOptions_NoLaunchProfile_WithApplicationArguments()
var options = launcher.GetHostProjectOptions();
AssertCommonProperties(options, launcher);
- Assert.False(options.LaunchProfileName.HasValue);
- AssertEx.SequenceEqual(["--project", "myapp.csproj", "--no-launch-profile", "--urls", "http://localhost:5000"], options.CommandArguments);
+ Assert.IsFalse(options.LaunchProfileName.HasValue);
+ Assert.AreSequenceEqual(["--project", "myapp.csproj", "--no-launch-profile", "--urls", "http://localhost:5000"], options.CommandArguments);
}
-}
+}
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireResourceLauncherCliTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireResourceLauncherCliTests.cs
index d0151c2102fb..a4cb31a69526 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireResourceLauncherCliTests.cs
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireResourceLauncherCliTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CommandLine;
@@ -6,175 +6,176 @@
namespace Microsoft.DotNet.Watch.UnitTests;
+[TestClass]
public class AspireResourceLauncherCliTests
{
- [Fact]
+ [TestMethod]
public void RequiredServerOption()
{
// --server option is missing
var args = new[] { "resource", "--entrypoint", "proj" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void RequiredEntryPointOption()
{
// --entrypoint option is missing
var args = new[] { "resource", "--server", "pipe1" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void MinimalRequiredOptions()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj.csproj" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("pipe1", launcher.ServerPipeName);
- Assert.Equal("proj.csproj", launcher.EntryPoint);
- Assert.Empty(launcher.ApplicationArguments);
- Assert.Empty(launcher.EnvironmentVariables);
- Assert.True(launcher.LaunchProfileName.HasValue);
- Assert.Null(launcher.LaunchProfileName.Value);
- Assert.Equal(LogLevel.Information, launcher.GlobalOptions.LogLevel);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("pipe1", launcher.ServerPipeName);
+ Assert.AreEqual("proj.csproj", launcher.EntryPoint);
+ Assert.IsEmpty(launcher.ApplicationArguments);
+ Assert.IsEmpty(launcher.EnvironmentVariables);
+ Assert.IsTrue(launcher.LaunchProfileName.HasValue);
+ Assert.IsNull(launcher.LaunchProfileName.Value);
+ Assert.AreEqual(LogLevel.Information, launcher.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void ApplicationArguments()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "a", "b" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- AssertEx.SequenceEqual(["a", "b"], launcher.ApplicationArguments);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreSequenceEqual(["a", "b"], launcher.ApplicationArguments);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_SingleVariable()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-e", "KEY=value" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Single(launcher.EnvironmentVariables);
- Assert.Equal("value", launcher.EnvironmentVariables["KEY"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.ContainsSingle(launcher.EnvironmentVariables);
+ Assert.AreEqual("value", launcher.EnvironmentVariables["KEY"]);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_MultipleVariables()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-e", "KEY1=val1", "-e", "KEY2=val2" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal(2, launcher.EnvironmentVariables.Count);
- Assert.Equal("val1", launcher.EnvironmentVariables["KEY1"]);
- Assert.Equal("val2", launcher.EnvironmentVariables["KEY2"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual(2, launcher.EnvironmentVariables.Count);
+ Assert.AreEqual("val1", launcher.EnvironmentVariables["KEY1"]);
+ Assert.AreEqual("val2", launcher.EnvironmentVariables["KEY2"]);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_ValueWithEquals()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-e", "CONN=Server=localhost;Port=5432" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("Server=localhost;Port=5432", launcher.EnvironmentVariables["CONN"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("Server=localhost;Port=5432", launcher.EnvironmentVariables["CONN"]);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_EmptyValue()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-e", "KEY=" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("", launcher.EnvironmentVariables["KEY"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("", launcher.EnvironmentVariables["KEY"]);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_NoEquals()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-e", "KEY" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("", launcher.EnvironmentVariables["KEY"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("", launcher.EnvironmentVariables["KEY"]);
}
- [Fact]
+ [TestMethod]
public void NoLaunchProfileOption()
{
// With no-launch-profile flag
var argsNoProfile = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "--no-launch-profile" };
- var launcherNoProfile = Assert.IsType(AspireLauncher.TryCreate(argsNoProfile));
- Assert.False(launcherNoProfile.LaunchProfileName.HasValue);
+ var launcherNoProfile = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNoProfile));
+ Assert.IsFalse(launcherNoProfile.LaunchProfileName.HasValue);
// Without no-launch-profile flag
var argsDefault = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj" };
- var launcherDefault = Assert.IsType(AspireLauncher.TryCreate(argsDefault));
- Assert.True(launcherDefault.LaunchProfileName.HasValue);
- Assert.Null(launcherDefault.LaunchProfileName.Value);
+ var launcherDefault = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsDefault));
+ Assert.IsTrue(launcherDefault.LaunchProfileName.HasValue);
+ Assert.IsNull(launcherDefault.LaunchProfileName.Value);
}
- [Fact]
+ [TestMethod]
public void LaunchProfileOption()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "--launch-profile", "MyProfile" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.True(launcher.LaunchProfileName.HasValue);
- Assert.Equal("MyProfile", launcher.LaunchProfileName.Value);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.IsTrue(launcher.LaunchProfileName.HasValue);
+ Assert.AreEqual("MyProfile", launcher.LaunchProfileName.Value);
}
- [Fact]
+ [TestMethod]
public void LaunchProfileOption_ShortForm()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "-lp", "MyProfile" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.True(launcher.LaunchProfileName.HasValue);
- Assert.Equal("MyProfile", launcher.LaunchProfileName.Value);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.IsTrue(launcher.LaunchProfileName.HasValue);
+ Assert.AreEqual("MyProfile", launcher.LaunchProfileName.Value);
}
- [Fact]
+ [TestMethod]
public void VerboseOption()
{
var argsVerbose = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "--verbose" };
- var launcherVerbose = Assert.IsType(AspireLauncher.TryCreate(argsVerbose));
- Assert.Equal(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
+ var launcherVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsVerbose));
+ Assert.AreEqual(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
var argsNotVerbose = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj" };
- var launcherNotVerbose = Assert.IsType(AspireLauncher.TryCreate(argsNotVerbose));
- Assert.Equal(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
+ var launcherNotVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotVerbose));
+ Assert.AreEqual(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void QuietOption()
{
var argsQuiet = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "--quiet" };
- var launcherQuiet = Assert.IsType(AspireLauncher.TryCreate(argsQuiet));
- Assert.Equal(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
+ var launcherQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsQuiet));
+ Assert.AreEqual(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
var argsNotQuiet = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj" };
- var launcherNotQuiet = Assert.IsType(AspireLauncher.TryCreate(argsNotQuiet));
- Assert.Equal(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
+ var launcherNotQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotQuiet));
+ Assert.AreEqual(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void ConflictingOptions()
{
// Cannot specify both --quiet and --verbose
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "proj", "--quiet", "--verbose" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void AllOptionsSet()
{
var args = new[] { "resource", "--server", "pipe1", "--entrypoint", "myapp.csproj", "-e", "K1=V1", "-e", "K2=V2", "--launch-profile", "Dev", "--verbose", "arg1", "arg2" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
-
- Assert.Equal("pipe1", launcher.ServerPipeName);
- Assert.Equal("myapp.csproj", launcher.EntryPoint);
- Assert.Equal(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
- Assert.True(launcher.LaunchProfileName.HasValue);
- Assert.Equal("Dev", launcher.LaunchProfileName.Value);
- AssertEx.SequenceEqual(["arg1", "arg2"], launcher.ApplicationArguments);
- Assert.Equal(2, launcher.EnvironmentVariables.Count);
- Assert.Equal("V1", launcher.EnvironmentVariables["K1"]);
- Assert.Equal("V2", launcher.EnvironmentVariables["K2"]);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+
+ Assert.AreEqual("pipe1", launcher.ServerPipeName);
+ Assert.AreEqual("myapp.csproj", launcher.EntryPoint);
+ Assert.AreEqual(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
+ Assert.IsTrue(launcher.LaunchProfileName.HasValue);
+ Assert.AreEqual("Dev", launcher.LaunchProfileName.Value);
+ Assert.AreSequenceEqual(["arg1", "arg2"], launcher.ApplicationArguments);
+ Assert.AreEqual(2, launcher.EnvironmentVariables.Count);
+ Assert.AreEqual("V1", launcher.EnvironmentVariables["K1"]);
+ Assert.AreEqual("V2", launcher.EnvironmentVariables["K2"]);
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_Duplicates()
{
var command = new AspireResourceCommandDefinition();
@@ -187,7 +188,7 @@ public void EnvironmentOption_Duplicates()
result.Errors.Should().BeEmpty();
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_Duplicates_CasingDifference()
{
var command = new AspireResourceCommandDefinition();
@@ -212,7 +213,7 @@ public void EnvironmentOption_Duplicates_CasingDifference()
result.Errors.Should().BeEmpty();
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_MultiplePerToken()
{
var command = new AspireResourceCommandDefinition();
@@ -230,7 +231,7 @@ public void EnvironmentOption_MultiplePerToken()
result.Errors.Should().BeEmpty();
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_NoValue()
{
var command = new AspireResourceCommandDefinition();
@@ -243,7 +244,7 @@ public void EnvironmentOption_NoValue()
result.Errors.Should().BeEmpty();
}
- [Fact]
+ [TestMethod]
public void EnvironmentOption_WhitespaceTrimming()
{
var command = new AspireResourceCommandDefinition();
@@ -256,19 +257,19 @@ public void EnvironmentOption_WhitespaceTrimming()
result.Errors.Should().BeEmpty();
}
- [Theory]
- [InlineData("")]
- [InlineData("=")]
- [InlineData("= X")]
- [InlineData(" \u2002 = X")]
+ [TestMethod]
+ [DataRow("")]
+ [DataRow("=")]
+ [DataRow("= X")]
+ [DataRow(" \u2002 = X")]
public void EnvironmentOption_Errors(string token)
{
var command = new AspireResourceCommandDefinition();
var result = command.Parse(["--server", "S", "--entrypoint", "E", "-e", token]);
- AssertEx.SequenceEqual(
+ Assert.AreSequenceEqual(
[
$"Incorrectly formatted environment variables '{token}'"
], result.Errors.Select(e => e.Message));
}
-}
+}
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireServerLauncherCliTests.cs b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireServerLauncherCliTests.cs
index 39ba1fdff22b..127b20e9ca0f 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireServerLauncherCliTests.cs
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireServerLauncherCliTests.cs
@@ -1,129 +1,130 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Extensions.Logging;
namespace Microsoft.DotNet.Watch.UnitTests;
+[TestClass]
public class AspireServerLauncherCliTests
{
- [Fact]
+ [TestMethod]
public void RequiredServerOption()
{
// --server option is missing
var args = new[] { "server", "--sdk", "sdk" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void RequiredSdkOption()
{
// --sdk option is missing
var args = new[] { "server", "--server", "pipe1" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void MinimalRequiredOptions()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("pipe1", launcher.ServerPipeName);
- Assert.Equal(LogLevel.Information, launcher.GlobalOptions.LogLevel);
- Assert.Empty(launcher.ResourcePaths);
- Assert.Null(launcher.StatusPipeName);
- Assert.Null(launcher.ControlPipeName);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("pipe1", launcher.ServerPipeName);
+ Assert.AreEqual(LogLevel.Information, launcher.GlobalOptions.LogLevel);
+ Assert.IsEmpty(launcher.ResourcePaths);
+ Assert.IsNull(launcher.StatusPipeName);
+ Assert.IsNull(launcher.ControlPipeName);
}
- [Fact]
+ [TestMethod]
public void ResourceOption_SingleValue()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--resource", "proj1.csproj" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- AssertEx.SequenceEqual(["proj1.csproj"], launcher.ResourcePaths);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreSequenceEqual(["proj1.csproj"], launcher.ResourcePaths);
}
- [Fact]
+ [TestMethod]
public void ResourceOption_MultipleValues()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--resource", "proj1.csproj", "proj2.csproj", "file.cs" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- AssertEx.SequenceEqual(["proj1.csproj", "proj2.csproj", "file.cs"], launcher.ResourcePaths);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreSequenceEqual(["proj1.csproj", "proj2.csproj", "file.cs"], launcher.ResourcePaths);
}
- [Fact]
+ [TestMethod]
public void ResourceOption_MultipleFlags()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--resource", "proj1.csproj", "--resource", "proj2.csproj" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- AssertEx.SequenceEqual(["proj1.csproj", "proj2.csproj"], launcher.ResourcePaths);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreSequenceEqual(["proj1.csproj", "proj2.csproj"], launcher.ResourcePaths);
}
- [Fact]
+ [TestMethod]
public void StatusPipeOption()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--status-pipe", "status1" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("status1", launcher.StatusPipeName);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("status1", launcher.StatusPipeName);
}
- [Fact]
+ [TestMethod]
public void ControlPipeOption()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--control-pipe", "control1" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
- Assert.Equal("control1", launcher.ControlPipeName);
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
+ Assert.AreEqual("control1", launcher.ControlPipeName);
}
- [Fact]
+ [TestMethod]
public void VerboseOption()
{
// With verbose flag
var argsVerbose = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--verbose" };
- var launcherVerbose = Assert.IsType(AspireLauncher.TryCreate(argsVerbose));
- Assert.Equal(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
+ var launcherVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsVerbose));
+ Assert.AreEqual(LogLevel.Debug, launcherVerbose.GlobalOptions.LogLevel);
// Without verbose flag
var argsNotVerbose = new[] { "server", "--server", "pipe1", "--sdk", "sdk" };
- var launcherNotVerbose = Assert.IsType(AspireLauncher.TryCreate(argsNotVerbose));
- Assert.Equal(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
+ var launcherNotVerbose = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotVerbose));
+ Assert.AreEqual(LogLevel.Information, launcherNotVerbose.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void QuietOption()
{
// With quiet flag
var argsQuiet = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--quiet" };
- var launcherQuiet = Assert.IsType(AspireLauncher.TryCreate(argsQuiet));
- Assert.Equal(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
+ var launcherQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsQuiet));
+ Assert.AreEqual(LogLevel.Warning, launcherQuiet.GlobalOptions.LogLevel);
// Without quiet flag
var argsNotQuiet = new[] { "server", "--server", "pipe1", "--sdk", "sdk" };
- var launcherNotQuiet = Assert.IsType(AspireLauncher.TryCreate(argsNotQuiet));
- Assert.Equal(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
+ var launcherNotQuiet = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(argsNotQuiet));
+ Assert.AreEqual(LogLevel.Information, launcherNotQuiet.GlobalOptions.LogLevel);
}
- [Fact]
+ [TestMethod]
public void ConflictingOptions()
{
// Cannot specify both --quiet and --verbose
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--quiet", "--verbose" };
var launcher = AspireLauncher.TryCreate(args);
- Assert.Null(launcher);
+ Assert.IsNull(launcher);
}
- [Fact]
+ [TestMethod]
public void AllOptionsSet()
{
var args = new[] { "server", "--server", "pipe1", "--sdk", "sdk", "--resource", "proj1.csproj", "proj2.csproj", "--status-pipe", "status1", "--control-pipe", "control1", "--verbose" };
- var launcher = Assert.IsType(AspireLauncher.TryCreate(args));
+ var launcher = Assert.IsExactInstanceOfType(AspireLauncher.TryCreate(args));
- Assert.Equal("pipe1", launcher.ServerPipeName);
- Assert.Equal(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
- AssertEx.SequenceEqual(["proj1.csproj", "proj2.csproj"], launcher.ResourcePaths);
- Assert.Equal("status1", launcher.StatusPipeName);
- Assert.Equal("control1", launcher.ControlPipeName);
+ Assert.AreEqual("pipe1", launcher.ServerPipeName);
+ Assert.AreEqual(LogLevel.Debug, launcher.GlobalOptions.LogLevel);
+ Assert.AreSequenceEqual(["proj1.csproj", "proj2.csproj"], launcher.ResourcePaths);
+ Assert.AreEqual("status1", launcher.StatusPipeName);
+ Assert.AreEqual("control1", launcher.ControlPipeName);
}
-}
+}
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj
index e65ce1a88a56..0aec8ad4a1ee 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj
+++ b/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Microsoft.DotNet.HotReload.Watch.Aspire.Tests.csproj
@@ -1,19 +1,14 @@
-
+
+
$(SdkTargetFramework)
- Exe
Microsoft.DotNet.Watch.Aspire.UnitTests
MicrosoftAspNetCore
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.Test.MSTest.Utilities/InMemoryLoggerProvider.cs b/test/Microsoft.DotNet.Test.MSTest.Utilities/InMemoryLoggerProvider.cs
new file mode 100644
index 000000000000..3715dac3febe
--- /dev/null
+++ b/test/Microsoft.DotNet.Test.MSTest.Utilities/InMemoryLoggerProvider.cs
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.DotNet.Test.MSTest.Utilities;
+
+///
+/// An that appends every log entry to a caller-supplied list.
+/// Useful for tests that need to assert on the exact sequence of log entries produced by a
+/// component under test (without dragging in MSTest's TestContext sink).
+///
+public sealed class InMemoryLoggerProvider(List<(LogLevel, string)> messagesCollection) : ILoggerProvider
+{
+ public ILogger CreateLogger(string categoryName) => new InMemoryLogger(messagesCollection);
+
+ public void Dispose()
+ {
+ }
+
+ private sealed class InMemoryLogger(List<(LogLevel, string)> messagesCollection) : ILogger
+ {
+ public IDisposable? BeginScope(TState state) where TState : notnull => NullScope.Instance;
+
+ public bool IsEnabled(LogLevel logLevel) => true;
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
+ => messagesCollection.Add((logLevel, formatter(state, exception)));
+ }
+
+ private sealed class NullScope : IDisposable
+ {
+ public static readonly NullScope Instance = new();
+
+ public void Dispose()
+ {
+ }
+ }
+}
diff --git a/test/Microsoft.DotNet.Test.MSTest.Utilities/Microsoft.DotNet.Test.MSTest.Utilities.csproj b/test/Microsoft.DotNet.Test.MSTest.Utilities/Microsoft.DotNet.Test.MSTest.Utilities.csproj
new file mode 100644
index 000000000000..73adf7653621
--- /dev/null
+++ b/test/Microsoft.DotNet.Test.MSTest.Utilities/Microsoft.DotNet.Test.MSTest.Utilities.csproj
@@ -0,0 +1,42 @@
+
+
+
+
+
+ $(SdkTargetFramework);$(NetFrameworkToolCurrent)
+ Library
+ Microsoft.DotNet.Test.MSTest.Utilities
+ MicrosoftAspNetCore
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.DotNet.HotReload.Client.Tests/Utilities/TestLogger.cs b/test/Microsoft.DotNet.Test.MSTest.Utilities/TestLogger.cs
similarity index 70%
rename from test/Microsoft.DotNet.HotReload.Client.Tests/Utilities/TestLogger.cs
rename to test/Microsoft.DotNet.Test.MSTest.Utilities/TestLogger.cs
index 6bb15080c57d..87c8c1248f62 100644
--- a/test/Microsoft.DotNet.HotReload.Client.Tests/Utilities/TestLogger.cs
+++ b/test/Microsoft.DotNet.Test.MSTest.Utilities/TestLogger.cs
@@ -1,12 +1,18 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Immutable;
using Microsoft.Extensions.Logging;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace Microsoft.DotNet.Watch.UnitTests;
+namespace Microsoft.DotNet.Test.MSTest.Utilities;
-internal class TestLogger(TestContext? output = null) : ILogger
+///
+/// An that captures messages in memory and optionally echoes them to an
+/// MSTest . Designed to be shared across MSTest.Sdk test projects so
+/// the same pattern doesn't have to be duplicated per project.
+///
+public class TestLogger(TestContext? testContext = null) : ILogger
{
public readonly object Guard = new();
private readonly List _messages = [];
@@ -31,7 +37,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except
HasWarning |= logLevel is LogLevel.Warning;
_messages.Add(message);
- output?.WriteLine(message);
+ testContext?.WriteLine(message);
}
}
diff --git a/test/Microsoft.DotNet.Test.MSTest.Utilities/TestLoggerFactory.cs b/test/Microsoft.DotNet.Test.MSTest.Utilities/TestLoggerFactory.cs
new file mode 100644
index 000000000000..15485a93f137
--- /dev/null
+++ b/test/Microsoft.DotNet.Test.MSTest.Utilities/TestLoggerFactory.cs
@@ -0,0 +1,97 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Microsoft.DotNet.Test.MSTest.Utilities;
+
+///
+/// An that writes log messages to an MSTest
+/// (when provided) and a simple console sink. Useful for tests that
+/// need a real (e.g. for components that take one in their ctor).
+///
+public sealed class TestLoggerFactory : ILoggerFactory
+{
+ private readonly List _loggerProviders = new();
+ private readonly List _factories = new();
+
+ public TestLoggerFactory(TestContext? testContext = null)
+ {
+ if (testContext is not null)
+ {
+ _loggerProviders.Add(new TestContextLoggerProvider(testContext));
+ }
+ }
+
+ public void Dispose()
+ {
+ while (_factories.Count > 0)
+ {
+ ILoggerFactory factory = _factories[0];
+ _factories.RemoveAt(0);
+ factory.Dispose();
+ }
+ }
+
+ public ILogger CreateLogger(string categoryName)
+ {
+ ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
+ {
+ builder.SetMinimumLevel(LogLevel.Trace);
+
+ foreach (ILoggerProvider loggerProvider in _loggerProviders)
+ {
+ builder.AddProvider(loggerProvider);
+ }
+
+ builder.AddSimpleConsole(options =>
+ {
+ options.SingleLine = true;
+ options.TimestampFormat = "[yyyy-MM-dd HH:mm:ss.fff] ";
+ options.IncludeScopes = true;
+ });
+ });
+
+ _factories.Add(loggerFactory);
+ return loggerFactory.CreateLogger(categoryName);
+ }
+
+ public ILogger CreateLogger() => CreateLogger("Test Host");
+
+ public void AddProvider(ILoggerProvider provider) => _loggerProviders.Add(provider);
+
+ private sealed class TestContextLoggerProvider(TestContext testContext) : ILoggerProvider
+ {
+ public ILogger CreateLogger(string categoryName) => new TestContextLogger(testContext, categoryName);
+
+ public void Dispose()
+ {
+ }
+ }
+
+ private sealed class TestContextLogger(TestContext testContext, string categoryName) : ILogger
+ {
+ public IDisposable? BeginScope(TState state) where TState : notnull => NullScope.Instance;
+
+ public bool IsEnabled(LogLevel logLevel) => true;
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
+ {
+ testContext.WriteLine($"{logLevel}: {categoryName}: {formatter(state, exception)}");
+ if (exception is not null)
+ {
+ testContext.WriteLine(exception.ToString());
+ }
+ }
+ }
+
+ private sealed class NullScope : IDisposable
+ {
+ public static readonly NullScope Instance = new();
+
+ public void Dispose()
+ {
+ }
+ }
+}
diff --git a/test/containerize.UnitTests/ParserTests.cs b/test/containerize.UnitTests/ParserTests.cs
index 4240089eca13..d9273253b6ce 100644
--- a/test/containerize.UnitTests/ParserTests.cs
+++ b/test/containerize.UnitTests/ParserTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CommandLine;
@@ -6,9 +6,10 @@
namespace containerize.UnitTests;
+[TestClass]
public class ParserTests
{
- [Fact]
+ [TestMethod]
public void CanParseLabels()
{
ContainerizeCommand command = new();
@@ -41,17 +42,17 @@ public void CanParseLabels()
Dictionary? labels = parseResult.GetValue(command.LabelsOption);
- Assert.NotNull(labels);
- Assert.Equal(6, labels.Count);
- Assert.Empty(labels["NoValue"]);
- Assert.Equal("Val2", labels["Valid2"]);
- Assert.Equal("Val 3", labels["Valid3"]);
- Assert.Equal("\"Val4\"", labels["Valid4"]);
- Assert.Equal("\"Un1", labels["Unbalanced1"]);
- Assert.Equal("Un2\"", labels["Unbalanced2"]);
+ Assert.IsNotNull(labels);
+ Assert.AreEqual(6, labels.Count);
+ Assert.IsEmpty(labels["NoValue"]);
+ Assert.AreEqual("Val2", labels["Valid2"]);
+ Assert.AreEqual("Val 3", labels["Valid3"]);
+ Assert.AreEqual("\"Val4\"", labels["Valid4"]);
+ Assert.AreEqual("\"Un1", labels["Unbalanced1"]);
+ Assert.AreEqual("Un2\"", labels["Unbalanced2"]);
}
- [Fact]
+ [TestMethod]
public void CanParseLabels2()
{
ContainerizeCommand command = new();
@@ -79,15 +80,15 @@ public void CanParseLabels2()
Dictionary? labels = parseResult.GetValue(command.LabelsOption);
- Assert.NotNull(labels);
- Assert.Equal(2, labels.Count);
- Assert.Empty(labels["NoValue"]);
- Assert.Equal("Val2", labels["Valid2"]);
+ Assert.IsNotNull(labels);
+ Assert.AreEqual(2, labels.Count);
+ Assert.IsEmpty(labels["NoValue"]);
+ Assert.AreEqual("Val2", labels["Valid2"]);
}
- [Theory]
- [InlineData("not-a-label")]
- [InlineData("not", "a", "label")]
+ [TestMethod]
+ [DataRow("not-a-label")]
+ [DataRow("not", "a", "label")]
public void CanHandleInvalidLabels(params string[] labelStr)
{
ContainerizeCommand command = new();
@@ -114,12 +115,12 @@ public void CanHandleInvalidLabels(params string[] labelStr)
}
ParseResult parseResult = command.Parse(baseArgs.ToArray());
- Assert.Single(parseResult.Errors);
+ Assert.ContainsSingle(parseResult.Errors);
- Assert.Equal($"Incorrectly formatted labels: {string.Join(";", labelStr)}", parseResult.Errors[0].Message);
+ Assert.AreEqual($"Incorrectly formatted labels: {string.Join(";", labelStr)}", parseResult.Errors[0].Message);
}
- [Fact]
+ [TestMethod]
public void CanParseEnvironmentVariables()
{
ContainerizeCommand command = new();
@@ -149,21 +150,21 @@ public void CanParseEnvironmentVariables()
ParseResult parseResult = command.Parse(baseArgs.ToArray());
- Assert.Empty(parseResult.Errors);
+ Assert.IsEmpty(parseResult.Errors);
Dictionary? envVars = parseResult.GetValue(command.EnvVarsOption);
- Assert.NotNull(envVars);
- Assert.Equal(6, envVars.Count);
- Assert.Empty(envVars["NoValue"]);
- Assert.Equal("Val2", envVars["Valid2"]);
- Assert.Equal("Val 3", envVars["Valid3"]);
- Assert.Equal("\"Val4\"", envVars["Valid4"]);
- Assert.Equal("\"Un1", envVars["Unbalanced1"]);
- Assert.Equal("Un2\"", envVars["Unbalanced2"]);
+ Assert.IsNotNull(envVars);
+ Assert.AreEqual(6, envVars.Count);
+ Assert.IsEmpty(envVars["NoValue"]);
+ Assert.AreEqual("Val2", envVars["Valid2"]);
+ Assert.AreEqual("Val 3", envVars["Valid3"]);
+ Assert.AreEqual("\"Val4\"", envVars["Valid4"]);
+ Assert.AreEqual("\"Un1", envVars["Unbalanced1"]);
+ Assert.AreEqual("Un2\"", envVars["Unbalanced2"]);
}
- [Fact]
+ [TestMethod]
public void CanParsePorts()
{
ContainerizeCommand command = new();
@@ -191,22 +192,22 @@ public void CanParsePorts()
ParseResult parseResult = command.Parse(baseArgs.ToArray());
- Assert.Empty(parseResult.Errors);
+ Assert.IsEmpty(parseResult.Errors);
Port[]? ports = parseResult.GetValue(command.PortsOption);
- Assert.NotNull(ports);
- Assert.Equal(4, ports.Length);
+ Assert.IsNotNull(ports);
+ Assert.AreEqual(4, ports.Length);
Assert.Contains(new Port(1500, PortType.tcp), ports);
Assert.Contains(new Port(1501, PortType.udp), ports);
Assert.Contains(new Port(1501, PortType.tcp), ports);
Assert.Contains(new Port(1502, PortType.tcp), ports);
}
- [Theory]
- [InlineData("1501/smth", "(InvalidPortType)")]
- [InlineData("1501\\tcp", "(InvalidPortNumber)")]
- [InlineData("not-a-number", "(InvalidPortNumber)")]
+ [TestMethod]
+ [DataRow("1501/smth", "(InvalidPortType)")]
+ [DataRow("1501\\tcp", "(InvalidPortNumber)")]
+ [DataRow("not-a-number", "(InvalidPortNumber)")]
public void CanHandleInvalidPorts(string portStr, string reason)
{
string errorMessage = $"Incorrectly formatted ports:{Environment.NewLine}\t{portStr}:\t{reason}{Environment.NewLine}";
@@ -232,9 +233,9 @@ public void CanHandleInvalidPorts(string portStr, string reason)
baseArgs.Add(portStr);
ParseResult parseResult = command.Parse(baseArgs.ToArray());
- Assert.Single(parseResult.Errors);
+ Assert.ContainsSingle(parseResult.Errors);
- Assert.Equal(errorMessage, parseResult.Errors[0].Message);
+ Assert.AreEqual(errorMessage, parseResult.Errors[0].Message);
}
}
diff --git a/test/containerize.UnitTests/containerize.UnitTests.csproj b/test/containerize.UnitTests/containerize.UnitTests.csproj
index 215c72557027..3036a17b4558 100644
--- a/test/containerize.UnitTests/containerize.UnitTests.csproj
+++ b/test/containerize.UnitTests/containerize.UnitTests.csproj
@@ -1,17 +1,14 @@
-
+
$(SdkTargetFramework)
enable
- false
true
MicrosoftShared
- Exe
-
-
+
\ No newline at end of file
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireLauncherTests.cs b/test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs
similarity index 98%
rename from test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireLauncherTests.cs
rename to test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs
index ceab4de2f838..2255ed3aa721 100644
--- a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/AspireLauncherTests.cs
+++ b/test/dotnet-watch.Tests/Aspire/AspireLauncherIntegrationTests.cs
@@ -6,7 +6,7 @@
namespace Microsoft.DotNet.Watch.UnitTests;
-public class AspireLauncherTests(ITestOutputHelper logger) : WatchSdkTest(logger)
+public class AspireLauncherIntegrationTests(ITestOutputHelper logger) : WatchSdkTest(logger)
{
private WatchableApp CreateHostApp()
=> new(
diff --git a/test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Utilities/PipeUtilities.cs b/test/dotnet-watch.Tests/Aspire/PipeUtilities.cs
similarity index 100%
rename from test/Microsoft.DotNet.HotReload.Watch.Aspire.Tests/Utilities/PipeUtilities.cs
rename to test/dotnet-watch.Tests/Aspire/PipeUtilities.cs
diff --git a/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj b/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
index 72312ae26fb1..3b45b8eb3031 100644
--- a/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
+++ b/test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
@@ -1,4 +1,4 @@
-
+
Exe
$(SdkTargetFramework)
@@ -18,6 +18,8 @@
+
+