Merge pull request #6698 from mlorbetske/dev/mlorbe/AddSupportForLaunchSettings

Add support for launch settings
This commit is contained in:
Livar 2017-06-01 11:24:42 -07:00 committed by GitHub
commit 7d6b188a53
17 changed files with 726 additions and 0 deletions

View file

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<RuntimeIdentifiers>win7-x64;win7-x86;osx.10.12-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;ubuntu.16.10-x64;centos.7-x64;rhel.7-x64;debian.8-x64;fedora.24-x64;opensuse.42.1-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace MSBuildTestApp
{
public class Program
{
public static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine("echo args:" + string.Join(";", args));
}
string message = Environment.GetEnvironmentVariable("Message");
if (string.IsNullOrEmpty(message))
{
message = "(NO MESSAGE)";
}
Console.WriteLine(message);
}
}
}

View file

@ -0,0 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49850/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"First": {
"commandName": "Project",
"environmentVariables": [ ]
},
"Second": {
"commandName": "Project",
"environmentVariables": {
"Message": "Second"
}
}
}
}

View file

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<RuntimeIdentifiers>win7-x64;win7-x86;osx.10.12-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;ubuntu.16.10-x64;centos.7-x64;rhel.7-x64;debian.8-x64;fedora.24-x64;opensuse.42.1-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace MSBuildTestApp
{
public class Program
{
public static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine("echo args:" + string.Join(";", args));
}
string message = Environment.GetEnvironmentVariable("Message");
if (string.IsNullOrEmpty(message))
{
message = "(NO MESSAGE)";
}
Console.WriteLine(message);
}
}
}

View file

@ -0,0 +1,31 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49850/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"First": {
"commandName": "Project",
"environmentVariables": {
"Message": "First"
}
},
"Second": {
"commandName": "Project",
"environmentVariables": {
"Message": "Second"
}
}
}
}

View file

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<RuntimeIdentifiers>win7-x64;win7-x86;osx.10.12-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;ubuntu.16.10-x64;centos.7-x64;rhel.7-x64;debian.8-x64;fedora.24-x64;opensuse.42.1-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace MSBuildTestApp
{
public class Program
{
public static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine("echo args:" + string.Join(";", args));
}
string message = Environment.GetEnvironmentVariable("Message");
if (string.IsNullOrEmpty(message))
{
message = "(NO MESSAGE)";
}
Console.WriteLine(message);
}
}
}

View file

@ -0,0 +1,19 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49850/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View file

@ -0,0 +1,13 @@
using Microsoft.DotNet.Cli.Utils;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.Tools.Run.LaunchSettings
{
public interface ILaunchSettingsProvider
{
string CommandName { get; }
LaunchSettingsApplyResult TryApplySettings(JObject document, JObject model, ref ICommand command);
}
}

View file

@ -0,0 +1,18 @@
namespace Microsoft.DotNet.Tools.Run.LaunchSettings
{
public class LaunchSettingsApplyResult
{
public LaunchSettingsApplyResult(bool success, string failureReason, string runAfterLaunch = null)
{
Success = success;
FailureReason = failureReason;
RunAfterLaunch = runAfterLaunch;
}
public bool Success { get; }
public string FailureReason { get; }
public string RunAfterLaunch { get; }
}
}

View file

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.Tools.Run.LaunchSettings
{
internal class LaunchSettingsManager
{
private const string ProfilesKey = "profiles";
private const string CommandNameKey = "commandName";
private const string DefaultProfileCommandName = "Project";
private static IReadOnlyDictionary<string, ILaunchSettingsProvider> _providers;
static LaunchSettingsManager()
{
_providers = new Dictionary<string, ILaunchSettingsProvider>
{
{ ProjectLaunchSettingsProvider.CommandNameValue, new ProjectLaunchSettingsProvider() }
};
}
public static LaunchSettingsApplyResult TryApplyLaunchSettings(string launchSettingsJsonContents, ref ICommand command, string profileName = null)
{
try
{
var model = JObject.Parse(launchSettingsJsonContents);
var profilesObject = model[ProfilesKey] as JObject;
if (profilesObject == null)
{
return new LaunchSettingsApplyResult(false, LocalizableStrings.LaunchProfilesCollectionIsNotAJsonObject);
}
JObject profileObject;
if (profileName == null)
{
profileObject = profilesObject
.Properties()
.FirstOrDefault(IsDefaultProfileType)?.Value as JObject;
}
else
{
profileObject = profilesObject[profileName] as JObject;
if (profileObject == null)
{
return new LaunchSettingsApplyResult(false, LocalizableStrings.LaunchProfileIsNotAJsonObject);
}
}
if (profileObject == null)
{
foreach (var prop in profilesObject.Properties())
{
var profile = prop.Value as JObject;
if (profile != null)
{
var cmdName = profile[CommandNameKey]?.Value<string>();
if (_providers.ContainsKey(cmdName))
{
profileObject = profile;
break;
}
}
}
}
var commandName = profileObject?[CommandNameKey]?.Value<string>();
if (profileObject == null)
{
return new LaunchSettingsApplyResult(false, LocalizableStrings.UsableLaunchProfileCannotBeLocated);
}
if (!TryLocateHandler(commandName, out ILaunchSettingsProvider provider))
{
return new LaunchSettingsApplyResult(false, string.Format(LocalizableStrings.LaunchProfileHandlerCannotBeLocated, commandName));
}
return provider.TryApplySettings(model, profileObject, ref command);
}
catch (JsonException ex)
{
return new LaunchSettingsApplyResult(false, string.Format(LocalizableStrings.DeserializationExceptionMessage, ex.Message));
}
}
private static bool TryLocateHandler(string commandName, out ILaunchSettingsProvider provider)
{
return _providers.TryGetValue(commandName, out provider);
}
private static bool IsDefaultProfileType(JProperty profileProperty)
{
JObject profile = profileProperty.Value as JObject;
var commandName = profile?[CommandNameKey]?.Value<string>();
return string.Equals(commandName, DefaultProfileCommandName, StringComparison.Ordinal);
}
}
}

View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Microsoft.DotNet.Cli.Utils;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.Tools.Run.LaunchSettings
{
public class ProjectLaunchSettingsProvider : ILaunchSettingsProvider
{
public static readonly string CommandNameValue = "Project";
public string CommandName => CommandNameValue;
public LaunchSettingsApplyResult TryApplySettings(JObject document, JObject model, ref ICommand command)
{
var config = model.ToObject<ProjectLaunchSettingsModel>();
//For now, ignore everything but the environment variables section
foreach (var entry in config.EnvironmentVariables)
{
string value = Environment.ExpandEnvironmentVariables(entry.Value);
//NOTE: MSBuild variables are not expanded like they are in VS
command.EnvironmentVariable(entry.Key, value);
}
if (!string.IsNullOrEmpty(config.ApplicationUrl))
{
command.EnvironmentVariable("ASPNETCORE_URLS", config.ApplicationUrl);
}
return new LaunchSettingsApplyResult(true, null, config.LaunchUrl);
}
private class ProjectLaunchSettingsModel
{
public ProjectLaunchSettingsModel()
{
EnvironmentVariables = new Dictionary<string, string>();
}
public string CommandLineArgs { get; set; }
public bool LaunchBrowser { get; set; }
public string LaunchUrl { get; set; }
public string ApplicationUrl { get; set; }
public Dictionary<string, string> EnvironmentVariables { get; }
}
}
}

View file

@ -17,6 +17,10 @@ namespace Microsoft.DotNet.Tools.Run
public const string CommandOptionProjectDescription = "The path to the project file to run (defaults to the current directory if there is only one project).";
public const string CommandOptionLaunchProfileDescription = "The name of the launch profile (if any) to use when launching the application.";
public const string CommandOptionNoLaunchProfileDescription = "Do not attempt to use launchSettings.json to configure the application.";
public const string RunCommandException = "The build failed. Please fix the build errors and run again.";
public const string RunCommandExceptionUnableToRunSpecifyFramework = "Unable to run your project\nYour project targets multiple frameworks. Please specify which framework to run using '{0}'.";
@ -28,5 +32,25 @@ namespace Microsoft.DotNet.Tools.Run
public const string RunCommandExceptionMultipleProjects = "Specify which project file to use because {0} contains more than one project file.";
public const string RunCommandAdditionalArgsHelpText = "Arguments passed to the application that is being run.";
public const string RunCommandExceptionCouldNotLocateALaunchSettingsFile = "The specified launch profile could not be located.";
public const string RunCommandExceptionCouldNotApplyLaunchSettings = "The launch profile \"{0}\" could not be applied.\n{1}";
public const string DefaultLaunchProfileDisplayName = "(Default)";
public const string UsingLaunchSettingsFromMessage = "Using launch settings from {0}...";
public const string LaunchProfileIsNotAJsonObject = "Launch profile is not a JSON object.";
public const string LaunchProfileHandlerCannotBeLocated = "The launch profile type '{0}' is not supported.";
public const string UsableLaunchProfileCannotBeLocated = "A usable launch profile could not be located.";
public const string UnexpectedExceptionProcessingLaunchSettings = "An unexpected exception occurred while processing launch settings:\n{0}";
public const string LaunchProfilesCollectionIsNotAJsonObject = "The 'profiles' property of the launch settings document is not a JSON object.";
public const string DeserializationExceptionMessage = "An error was encountered when reading launchSettings.json.\n{0}";
}
}

View file

@ -8,6 +8,7 @@ using System.Linq;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Tools.Run.LaunchSettings;
namespace Microsoft.DotNet.Tools.Run
{
@ -22,6 +23,10 @@ namespace Microsoft.DotNet.Tools.Run
private List<string> _args;
private bool ShouldBuild => !NoBuild;
public string LaunchProfile { get; private set; }
public bool NoLaunchProfile { get; private set; }
private bool UseLaunchProfile => !NoLaunchProfile;
public int Start()
{
Initialize();
@ -32,6 +37,12 @@ namespace Microsoft.DotNet.Tools.Run
}
ICommand runCommand = GetRunCommand();
int launchSettingsApplicationResult = ApplyLaunchProfileSettingsIfNeeded(ref runCommand);
if (launchSettingsApplicationResult != 0)
{
return launchSettingsApplicationResult;
}
return runCommand
.Execute()
@ -42,12 +53,16 @@ namespace Microsoft.DotNet.Tools.Run
string framework,
bool noBuild,
string project,
string launchProfile,
bool noLaunchProfile,
IReadOnlyCollection<string> args)
{
Configuration = configuration;
Framework = framework;
NoBuild = noBuild;
Project = project;
LaunchProfile = launchProfile;
NoLaunchProfile = noLaunchProfile;
Args = args;
}
@ -55,6 +70,8 @@ namespace Microsoft.DotNet.Tools.Run
string framework = null,
bool? noBuild = null,
string project = null,
string launchProfile = null,
bool? noLaunchProfile = null,
IReadOnlyCollection<string> args = null)
{
return new RunCommand(
@ -62,10 +79,50 @@ namespace Microsoft.DotNet.Tools.Run
framework ?? this.Framework,
noBuild ?? this.NoBuild,
project ?? this.Project,
launchProfile ?? this.LaunchProfile,
noLaunchProfile ?? this.NoLaunchProfile,
args ?? this.Args
);
}
private int ApplyLaunchProfileSettingsIfNeeded(ref ICommand runCommand)
{
if (UseLaunchProfile)
{
var buildPathContainer = File.Exists(Project) ? Path.GetDirectoryName(Project) : Project;
var launchSettingsPath = Path.Combine(buildPathContainer, "Properties", "launchSettings.json");
if (File.Exists(launchSettingsPath))
{
Reporter.Output.WriteLine(string.Format(LocalizableStrings.UsingLaunchSettingsFromMessage, launchSettingsPath));
string profileName = string.IsNullOrEmpty(LaunchProfile) ? LocalizableStrings.DefaultLaunchProfileDisplayName : LaunchProfile;
try
{
var launchSettingsFileContents = File.ReadAllText(launchSettingsPath);
var applyResult = LaunchSettingsManager.TryApplyLaunchSettings(launchSettingsFileContents, ref runCommand, LaunchProfile);
if (!applyResult.Success)
{
//Error that the launch profile couldn't be applied
Reporter.Error.WriteLine(string.Format(LocalizableStrings.RunCommandExceptionCouldNotApplyLaunchSettings, profileName, applyResult.FailureReason).Bold().Red());
}
}
catch (IOException ex)
{
Reporter.Error.WriteLine(string.Format(LocalizableStrings.RunCommandExceptionCouldNotApplyLaunchSettings, profileName).Bold().Red());
Reporter.Error.WriteLine(ex.Message.Bold().Red());
return -1;
}
}
else if (!string.IsNullOrEmpty(LaunchProfile))
{
//Error that the launch profile couldn't be found
Reporter.Error.WriteLine(LocalizableStrings.RunCommandExceptionCouldNotLocateALaunchSettingsFile.Bold().Red());
}
}
return 0;
}
private void EnsureProjectIsBuilt()
{
List<string> buildArgs = new List<string>();

View file

@ -21,6 +21,8 @@ namespace Microsoft.DotNet.Cli
framework: o.SingleArgumentOrDefault("--framework"),
noBuild: o.HasOption("--no-build"),
project: o.SingleArgumentOrDefault("--project"),
launchProfile: o.SingleArgumentOrDefault("--launch-profile"),
noLaunchProfile: o.HasOption("--no-launch-profile"),
args: o.Arguments
)),
options: new[]
@ -32,6 +34,14 @@ namespace Microsoft.DotNet.Cli
"-p|--project",
LocalizableStrings.CommandOptionProjectDescription,
Accept.ExactlyOneArgument()),
Create.Option(
"--launch-profile",
LocalizableStrings.CommandOptionLaunchProfileDescription,
Accept.ExactlyOneArgument()),
Create.Option(
"--no-launch-profile",
LocalizableStrings.CommandOptionNoLaunchProfileDescription,
Accept.NoArguments()),
Create.Option(
"--no-build",
LocalizableStrings.CommandOptionNoBuildDescription,

View file

@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.IO;
using FluentAssertions;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
@ -200,5 +201,267 @@ namespace Microsoft.DotNet.Cli.Run.Tests
.Pass()
.And.HaveStdOutContaining("echo args:foo;bar;baz");
}
[Fact]
public void ItGivesAnErrorWhenAttemptingToUseALaunchProfileThatDoesNotExistWhenThereIsNoLaunchSettingsFile()
{
var testAppName = "MSBuildTestApp";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--launch-profile test")
.Should().Pass()
.And.HaveStdOutContaining("Hello World!")
.And.HaveStdErrContaining("The specified launch profile could not be located.");
}
[Fact]
public void ItUsesLaunchProfileOfTheSpecifiedName()
{
var testAppName = "AppWithLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--launch-profile Second");
cmd.Should().Pass()
.And.HaveStdOutContaining("Second");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void ItDefaultsToTheFirstUsableLaunchProfile()
{
var testAppName = "AppWithLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput();
cmd.Should().Pass()
.And.HaveStdOutContaining("First");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void ItGivesAnErrorWhenTheLaunchProfileNotFound()
{
var testAppName = "AppWithLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--launch-profile Third")
.Should().Pass()
.And.HaveStdOutContaining("(NO MESSAGE)")
.And.HaveStdErrContaining("The launch profile \"Third\" could not be applied.");
}
[Fact]
public void ItGivesAnErrorWhenTheLaunchProfileCanNotBeHandled()
{
var testAppName = "AppWithLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--launch-profile \"IIS Express\"")
.Should().Pass()
.And.HaveStdOutContaining("(NO MESSAGE)")
.And.HaveStdErrContaining("The launch profile \"IIS Express\" could not be applied.");
}
[Fact]
public void ItSkipsLaunchProfilesWhenTheSwitchIsSupplied()
{
var testAppName = "AppWithLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--no-launch-profile");
cmd.Should().Pass()
.And.HaveStdOutContaining("(NO MESSAGE)");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void ItSkipsLaunchProfilesWhenTheSwitchIsSuppliedWithoutErrorWhenThereAreNoLaunchSettings()
{
var testAppName = "MSBuildTestApp";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput("--no-launch-profile");
cmd.Should().Pass()
.And.HaveStdOutContaining("Hello World!");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void ItSkipsLaunchProfilesWhenThereIsNoUsableDefault()
{
var testAppName = "AppWithLaunchSettingsNoDefault";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput();
cmd.Should().Pass()
.And.HaveStdOutContaining("(NO MESSAGE)")
.And.HaveStdErrContaining("The launch profile \"(Default)\" could not be applied.");
}
[Fact]
public void ItPrintsAnErrorWhenLaunchSettingsAreCorrupted()
{
var testAppName = "AppWithCorruptedLaunchSettings";
var testInstance = TestAssets.Get(testAppName)
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
new BuildCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should().Pass();
var cmd = new RunCommand()
.WithWorkingDirectory(testProjectDirectory)
.ExecuteWithCapturedOutput();
cmd.Should().Pass()
.And.HaveStdOutContaining("(NO MESSAGE)")
.And.HaveStdErrContaining("The launch profile \"(Default)\" could not be applied.");
}
}
}