Adding dotnet remove project tests

This commit is contained in:
Justin Goshi 2016-12-15 15:48:04 -08:00
parent 07ddddfa88
commit 20f2242947
15 changed files with 643 additions and 178 deletions

View file

@ -0,0 +1,38 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{7072A694-548F-4CAE-A58F-12D257D5F486}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{B38B1FA5-B4C9-456A-8B71-8FCD62ACF400}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{B38B1FA5-B4C9-456A-8B71-8FCD62ACF400}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.ActiveCfg = Debug|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.Build.0 = Debug|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.ActiveCfg = Debug|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.Build.0 = Debug|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.Build.0 = Release|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.ActiveCfg = Release|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.Build.0 = Release|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.ActiveCfg = Release|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lib\Lib.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,10 @@
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello from the main app");
Console.WriteLine(Lib.Library.GetMessage());
}
}

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="1.6" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
using System;
namespace Lib
{
public class Library
{
public static string GetMessage()
{
return "Message from Lib";
}
}
}

View file

@ -0,0 +1,62 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.DotNet.Tools.Add
{
public abstract class AddSubCommandBase
{
protected abstract string CommandName { get; }
protected abstract string LocalizedDisplayName { get; }
protected abstract string LocalizedDescription { get; }
protected abstract string LocalizedHelpText { get; }
internal abstract void AddCustomOptions(CommandLineApplication app);
protected abstract IAddSubCommand CreateIAddSubCommand(string fileOrDirectory);
internal CommandLineApplication Create(CommandLineApplication parentApp)
{
CommandLineApplication app = parentApp.Command(CommandName, throwOnUnexpectedArg: false);
app.FullName = LocalizedDisplayName;
app.Description = LocalizedDescription;
app.HandleRemainingArguments = true;
app.ArgumentSeparatorHelpText = LocalizedHelpText;
app.HelpOption("-h|--help");
AddCustomOptions(app);
app.OnExecute(() => {
try
{
if (!parentApp.Arguments.Any())
{
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
}
var projectOrDirectory = parentApp.Arguments.First().Value;
if (string.IsNullOrEmpty(projectOrDirectory))
{
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
}
var addSubCommand = CreateIAddSubCommand(projectOrDirectory);
return addSubCommand.Add(app.RemainingArguments);
}
catch (GracefulException e)
{
Reporter.Error.WriteLine(e.Message.Red());
app.ShowHelp();
return 1;
}
});
return app;
}
}
}

View file

@ -0,0 +1,12 @@
// 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.Collections.Generic;
namespace Microsoft.DotNet.Tools.Add
{
public interface IAddSubCommand
{
int Add(List<string> items);
}
}

View file

@ -4,6 +4,7 @@
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Add;
using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks;
using System.Collections.Generic;
@ -13,114 +14,86 @@ using System.Text;
namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
{
public class AddProjectToProjectReferenceCommand
public class AddProjectToProjectReference : IAddSubCommand
{
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
private CommandOption _frameworkOption;
private MsbuildProject _msbuildProj;
private ProjectCollection _projects;
internal AddProjectToProjectReference(string fileOrDirectory, CommandOption frameworkOption)
{
CommandLineApplication app = parentApp.Command("p2p", throwOnUnexpectedArg: false);
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.HandleRemainingArguments = true;
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
app.HelpOption("-h|--help");
CommandOption frameworkOption = app.Option(
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
app.OnExecute(() =>
{
try
{
if (!parentApp.Arguments.Any())
{
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
}
var projectOrDirectory = parentApp.Arguments.First().Value;
if (string.IsNullOrEmpty(projectOrDirectory))
{
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
}
var projects = new ProjectCollection();
var msbuildProj = MsbuildProject.FromFileOrDirectory(projects, projectOrDirectory);
if (app.RemainingArguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
}
string frameworkString = frameworkOption.Value();
List<string> references = app.RemainingArguments;
PathUtility.EnsureAllPathsExist(references, CommonLocalizableStrings.ReferenceDoesNotExist);
IEnumerable<MsbuildProject> refs = references.Select((r) => MsbuildProject.FromFile(projects, r));
if (frameworkString == null)
{
foreach (var tfm in msbuildProj.GetTargetFrameworks())
{
foreach (var @ref in refs)
{
if (!@ref.CanWorkOnFramework(tfm))
{
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
@ref,
msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName())));
return 1;
}
}
}
}
else
{
var framework = NuGetFramework.Parse(frameworkString);
if (!msbuildProj.IsTargettingFramework(framework))
{
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.ProjectDoesNotTargetFramework, msbuildProj.ProjectRootElement.FullPath, frameworkString));
return 1;
}
foreach (var @ref in refs)
{
if (!@ref.CanWorkOnFramework(framework))
{
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
@ref,
new string[] { frameworkString }));
return 1;
}
}
}
var relativePathReferences = references.Select((r) =>
PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList();
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
frameworkOption.Value(),
relativePathReferences);
if (numberOfAddedReferences != 0)
{
msbuildProj.ProjectRootElement.Save();
}
return 0;
}
catch (GracefulException e)
{
Reporter.Error.WriteLine(e.Message.Red());
app.ShowHelp();
return 1;
}
});
return app;
_projects = new ProjectCollection();
_msbuildProj = MsbuildProject.FromFileOrDirectory(_projects, fileOrDirectory);
_frameworkOption = frameworkOption;
}
private static string GetProjectNotCompatibleWithFrameworksDisplayString(MsbuildProject project, IEnumerable<string> frameworksDisplayStrings)
public int Add(List<string> references)
{
if (references.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
}
string frameworkString = _frameworkOption.Value();
PathUtility.EnsureAllPathsExist(references, CommonLocalizableStrings.ReferenceDoesNotExist);
IEnumerable<MsbuildProject> refs = references.Select((r) => MsbuildProject.FromFile(_projects, r));
if (frameworkString == null)
{
foreach (var tfm in _msbuildProj.GetTargetFrameworks())
{
foreach (var @ref in refs)
{
if (!@ref.CanWorkOnFramework(tfm))
{
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
@ref,
_msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName())));
return 1;
}
}
}
}
else
{
var framework = NuGetFramework.Parse(frameworkString);
if (!_msbuildProj.IsTargettingFramework(framework))
{
Reporter.Error.WriteLine(string.Format(
CommonLocalizableStrings.ProjectDoesNotTargetFramework,
_msbuildProj.ProjectRootElement.FullPath,
frameworkString));
return 1;
}
foreach (var @ref in refs)
{
if (!@ref.CanWorkOnFramework(framework))
{
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
@ref,
new string[] { frameworkString }));
return 1;
}
}
}
var relativePathReferences = references.Select((r) =>
PathUtility.GetRelativePath(_msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList();
int numberOfAddedReferences = _msbuildProj.AddProjectToProjectReferences(
_frameworkOption.Value(),
relativePathReferences);
if (numberOfAddedReferences != 0)
{
_msbuildProj.ProjectRootElement.Save();
}
return 0;
}
private string GetProjectNotCompatibleWithFrameworksDisplayString(MsbuildProject project, IEnumerable<string> frameworksDisplayStrings)
{
var sb = new StringBuilder();
sb.AppendLine(string.Format(CommonLocalizableStrings.ProjectNotCompatibleWithFrameworks, project.ProjectRootElement.FullPath));
@ -132,4 +105,33 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
return sb.ToString();
}
}
public class AddProjectToProjectReferenceCommand : AddSubCommandBase
{
private CommandOption _frameworkOption;
protected override string CommandName => "p2p";
protected override string LocalizedDisplayName => LocalizableStrings.AppFullName;
protected override string LocalizedDescription => LocalizableStrings.AppDescription;
protected override string LocalizedHelpText => LocalizableStrings.AppHelpText;
internal override void AddCustomOptions(CommandLineApplication app)
{
_frameworkOption = app.Option(
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
}
protected override IAddSubCommand CreateIAddSubCommand(string fileOrDirectory)
{
return new AddProjectToProjectReference(fileOrDirectory, _frameworkOption);
}
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
{
var addSubCommand = new AddProjectToProjectReferenceCommand();
return addSubCommand.Create(parentApp);
}
}
}

View file

@ -11,84 +11,56 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Tools.Add;
namespace Microsoft.DotNet.Tools.Add.ProjectToSolution
{
public class AddProjectToSolutionCommand
public class AddProjectToSolution : IAddSubCommand
{
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
private SlnFile _slnFile;
public AddProjectToSolution(string fileOrDirectory)
{
CommandLineApplication app = parentApp.Command("project", throwOnUnexpectedArg: false);
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.HandleRemainingArguments = true;
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
app.HelpOption("-h|--help");
app.OnExecute(() =>
{
try
{
if (!parentApp.Arguments.Any())
{
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
}
var projectOrDirectory = parentApp.Arguments.First().Value;
if (string.IsNullOrEmpty(projectOrDirectory))
{
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
}
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(projectOrDirectory);
if (app.RemainingArguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
}
List<string> projectPaths = app.RemainingArguments;
PathUtility.EnsureAllPathsExist(projectPaths, CommonLocalizableStrings.ProjectDoesNotExist);
var relativeProjectPaths = projectPaths.Select((p) =>
PathUtility.GetRelativePath(
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
Path.GetFullPath(p))).ToList();
int preAddProjectCount = slnFile.Projects.Count;
foreach (var project in relativeProjectPaths)
{
AddProject(slnFile, project);
}
if (slnFile.Projects.Count > preAddProjectCount)
{
slnFile.Write();
}
return 0;
}
catch (GracefulException e)
{
Reporter.Error.WriteLine(e.Message.Red());
app.ShowHelp();
return 1;
}
});
return app;
_slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
}
private static void AddProject(SlnFile slnFile, string projectPath)
public int Add(List<string> projectPaths)
{
if (projectPaths.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
}
PathUtility.EnsureAllPathsExist(projectPaths, CommonLocalizableStrings.ProjectDoesNotExist);
var relativeProjectPaths = projectPaths.Select((p) =>
PathUtility.GetRelativePath(
PathUtility.EnsureTrailingSlash(_slnFile.BaseDirectory),
Path.GetFullPath(p))).ToList();
int preAddProjectCount = _slnFile.Projects.Count;
foreach (var project in relativeProjectPaths)
{
AddProject(project);
}
if (_slnFile.Projects.Count > preAddProjectCount)
{
_slnFile.Write();
}
return 0;
}
private void AddProject(string projectPath)
{
var projectPathNormalized = PathUtility.GetPathWithBackSlashes(projectPath);
if (slnFile.Projects.Any((p) =>
if (_slnFile.Projects.Any((p) =>
string.Equals(p.FilePath, projectPathNormalized, StringComparison.OrdinalIgnoreCase)))
{
Reporter.Output.WriteLine(string.Format(
CommonLocalizableStrings.SolutionAlreadyContainsProject,
slnFile.FullPath,
_slnFile.FullPath,
projectPath));
}
else
@ -122,10 +94,33 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToSolution
FilePath = projectPathNormalized
};
slnFile.Projects.Add(slnProject);
_slnFile.Projects.Add(slnProject);
Reporter.Output.WriteLine(
string.Format(CommonLocalizableStrings.ProjectAddedToTheSolution, projectPath));
}
}
}
public class AddProjectToSolutionCommand : AddSubCommandBase
{
protected override string CommandName => "project";
protected override string LocalizedDisplayName => LocalizableStrings.AppFullName;
protected override string LocalizedDescription => LocalizableStrings.AppDescription;
protected override string LocalizedHelpText => LocalizableStrings.AppHelpText;
internal override void AddCustomOptions(CommandLineApplication app)
{
}
protected override IAddSubCommand CreateIAddSubCommand(string fileOrDirectory)
{
return new AddProjectToSolution(fileOrDirectory);
}
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
{
var addSubCommand = new AddProjectToSolutionCommand();
return addSubCommand.Create(parentApp);
}
}
}

View file

@ -37,7 +37,7 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectFromSolution
bool slnChanged = false;
foreach (var path in relativeProjectPaths)
{
slnChanged |= RemoveProject(_slnFile, path);
slnChanged |= RemoveProject(path);
}
if (slnChanged)
@ -46,11 +46,11 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectFromSolution
}
}
private static bool RemoveProject(SlnFile slnFile, string projectPath)
private bool RemoveProject(string projectPath)
{
var projectPathNormalized = PathUtility.GetPathWithBackSlashes(projectPath);
var projectsToRemove = slnFile.Projects.Where((p) =>
var projectsToRemove = _slnFile.Projects.Where((p) =>
string.Equals(p.FilePath, projectPathNormalized, StringComparison.OrdinalIgnoreCase)).ToList();
bool projectRemoved = false;
@ -64,7 +64,7 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectFromSolution
{
foreach (var slnProject in projectsToRemove)
{
slnFile.Projects.Remove(slnProject);
_slnFile.Projects.Remove(slnProject);
Reporter.Output.WriteLine(
string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, slnProject.FilePath));
}

View file

@ -7,7 +7,6 @@
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>dotnet-add-proj.Tests</AssemblyName>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
<DefineConstants>$(DefineConstants);DISABLE_TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
@ -21,10 +20,6 @@
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<Reference Include="System.Runtime" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk">
<Version>$(CLI_NETSDK_Version)</Version>

View file

@ -0,0 +1,259 @@
// 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 FluentAssertions;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Tools.Test.Utilities;
using System;
using System.IO;
using Xunit;
namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
{
public class GivenDotnetRemoveProj : TestBase
{
private const string HelpText = @".NET Remove Project from Solution Command
Usage: dotnet remove <PROJECT_OR_SOLUTION> project [options] [args]
Arguments:
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
Options:
-h|--help Show help information
Args:
Projects to remove from a solution
";
[Theory]
[InlineData("--help")]
[InlineData("-h")]
public void WhenHelpOptionIsPassedItPrintsUsage(string helpArg)
{
var cmd = new DotnetCommand()
.ExecuteWithCapturedOutput($"remove project {helpArg}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenTooManyArgumentsArePassedItPrintsError()
{
var cmd = new DotnetCommand()
.ExecuteWithCapturedOutput("remove one.sln two.sln three.sln project");
cmd.Should().Fail();
cmd.StdErr.Should().Contain("Unrecognized command or argument 'two.sln'");
cmd.StdOut.Should().Contain("Specify --help for a list of available options and commands.") ;
}
[Theory]
[InlineData("idontexist.sln")]
[InlineData("ihave?invalidcharacters")]
[InlineData("ihaveinv@lidcharacters")]
[InlineData("ihaveinvalid/characters")]
[InlineData("ihaveinvalidchar\\acters")]
public void WhenNonExistingSolutionIsPassedItPrintsErrorAndUsage(string solutionName)
{
var cmd = new DotnetCommand()
.ExecuteWithCapturedOutput($"remove {solutionName} project p.csproj");
cmd.Should().Fail();
cmd.StdErr.Should().Contain($"Could not find solution or directory `{solutionName}`.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenInvalidSolutionIsPassedItPrintsErrorAndUsage()
{
var projectDirectory = TestAssets
.Get("InvalidSolution")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove InvalidSolution.sln project {projectToRemove}");
cmd.Should().Fail();
cmd.StdErr.Should().Contain("Invalid solution `InvalidSolution.sln`.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenInvalidSolutionIsFoundItPrintsErrorAndUsage()
{
var projectDirectory = TestAssets
.Get("InvalidSolution")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "InvalidSolution.sln");
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
cmd.Should().Fail();
cmd.StdErr.Should().Contain($"Invalid solution `{solutionPath}`.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenNoProjectIsPassedItPrintsErrorAndUsage()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndCsprojFiles")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput(@"remove App.sln project");
cmd.Should().Fail();
cmd.StdErr.Should().Contain("You must specify at least one project to remove.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenNoSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndCsprojFiles")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "App");
var cmd = new DotnetCommand()
.WithWorkingDirectory(solutionPath)
.ExecuteWithCapturedOutput(@"remove project App.csproj");
cmd.Should().Fail();
cmd.StdErr.Should().Contain($"Specified solution file {solutionPath + Path.DirectorySeparatorChar} does not exist, or there is no solution file in the directory.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenMoreThanOneSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
{
var projectDirectory = TestAssets
.Get("TestAppWithMultipleSlnFiles")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
cmd.Should().Fail();
cmd.StdErr.Should().Contain($"Found more than one solution file in {projectDirectory + Path.DirectorySeparatorChar}. Please specify which one to use.");
cmd.StdOut.Should().Contain(HelpText);
}
[Fact]
public void WhenPassedAReferenceNotInSlnItPrintsStatus()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndExistingCsprojReferences")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "App.sln");
var contentBefore = File.ReadAllText(solutionPath);
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput("remove project referenceDoesNotExistInSln.csproj");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("Project reference `referenceDoesNotExistInSln.csproj` could not be found.");
File.ReadAllText(solutionPath)
.Should().Be(contentBefore);
}
[Fact]
public void WhenPassedAReferenceItRemovesTheReferenceButNotOtherReferences()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndExistingCsprojReferences")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "App.sln");
SlnFile slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(2);
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"Project reference `{projectToRemove}` removed.");
slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(1);
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
}
[Fact]
public void WhenDuplicateReferencesArePresentItRemovesThemAll()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndDuplicateProjectReferences")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "App.sln");
SlnFile slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(3);
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"Project reference `{projectToRemove}` removed.");
slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(1);
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
}
[Fact]
public void WhenPassedMultipleReferencesAndOneOfThemDoesNotExistItRemovesTheOneThatExists()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndExistingCsprojReferences")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var solutionPath = Path.Combine(projectDirectory, "App.sln");
SlnFile slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(2);
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"remove project idontexist.csproj {projectToRemove} idontexisteither.csproj");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"Project reference `{projectToRemove}` removed.");
slnFile = SlnFile.Read(solutionPath);
slnFile.Projects.Count.Should().Be(1);
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
}
}
}

View file

@ -0,0 +1 @@
https://github.com/Microsoft/msbuild/issues/927

View file

@ -0,0 +1 @@
https://github.com/Microsoft/msbuild/issues/927

View file

@ -0,0 +1,44 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>dotnet-remove-proj.Tests</AssemblyName>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk">
<Version>$(CLI_NETSDK_Version)</Version>
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>15.0.0-preview-20161024-02</Version>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio">
<Version>2.2.0-beta4-build1194</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.App">
<Version>1.0.1</Version>
</PackageReference>
<PackageReference Include="xunit">
<Version>2.2.0-beta4-build3444</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>