2016-12-15 15:48:04 -08:00
// 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 ;
2017-06-13 20:22:27 -07:00
using Microsoft.DotNet.Tools ;
2016-12-15 15:48:04 -08:00
using Microsoft.DotNet.Tools.Test.Utilities ;
using System ;
using System.IO ;
2017-01-03 07:18:45 -10:00
using System.Linq ;
2017-12-08 13:52:56 -08:00
using System.Text ;
2016-12-15 15:48:04 -08:00
using Xunit ;
2017-01-06 10:58:23 -10:00
namespace Microsoft.DotNet.Cli.Sln.Remove.Tests
2016-12-15 15:48:04 -08:00
{
2017-01-06 10:58:23 -10:00
public class GivenDotnetSlnRemove : TestBase
2016-12-15 15:48:04 -08:00
{
2017-06-26 17:17:51 -07:00
private const string HelpText = @ "Usage: dotnet sln <SLN_FILE> remove [options] <args>
2016-12-15 15:48:04 -08:00
Arguments :
2017-03-22 15:26:58 -07:00
< SLN_FILE > Solution file to operate on . If not specified , the command will search the current directory for one .
< args > Remove the specified project ( s ) from the solution . The project is not impacted .
2016-12-15 15:48:04 -08:00
Options :
2017-05-09 21:05:09 -07:00
- h , - - help Show help information .
2016-12-15 15:48:04 -08:00
";
2017-06-26 17:17:51 -07:00
private const string SlnCommandHelpText = @ "Usage: dotnet sln [options] <SLN_FILE> [command]
2017-05-04 01:01:35 +02:00
Arguments :
< SLN_FILE > Solution file to operate on . If not specified , the command will search the current directory for one .
Options :
2017-05-09 21:05:09 -07:00
- h , - - help Show help information .
2017-05-04 01:01:35 +02:00
Commands :
add < args > . NET Add project ( s ) to a solution file Command
list . NET List project ( s ) in a solution file Command
remove < args > . NET Remove project ( s ) from a solution file Command
";
2017-01-03 07:18:45 -10:00
private const string ExpectedSlnContentsAfterRemove = @ "
Microsoft Visual Studio Solution File , Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0 . 26006.2
MinimumVisualStudioVersion = 10.0 . 40219.1
Project ( "" { 9 A19103F - 16F 7 - 4668 - BE54 - 9 A1E7A4F7556 } "" ) = "" App "" , "" App \ App . csproj "" , "" { 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } ""
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
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . ActiveCfg = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . Build . 0 = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . ActiveCfg = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . Build . 0 = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . Build . 0 = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . ActiveCfg = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . Build . 0 = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . ActiveCfg = Release | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . Build . 0 = Release | x86
EndGlobalSection
EndGlobal
";
private const string ExpectedSlnContentsAfterRemoveAllProjects = @ "
Microsoft Visual Studio Solution File , Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0 . 26006.2
MinimumVisualStudioVersion = 10.0 . 40219.1
Global
EndGlobal
2017-01-04 18:32:09 -10:00
";
private const string ExpectedSlnContentsAfterRemoveNestedProj = @ "
Microsoft Visual Studio Solution File , Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0 . 26006.2
MinimumVisualStudioVersion = 10.0 . 40219.1
Project ( "" { 9 A19103F - 16F 7 - 4668 - BE54 - 9 A1E7A4F7556 } "" ) = "" App "" , "" App . csproj "" , "" { 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } ""
EndProject
Project ( "" { 2150E333 - 8F DC - 42 A3 - 9474 - 1 A3956D46DE8 } "" ) = "" src "" , "" src "" , "" { 7 B86CE74 - F620 - 4 B32 - 99F E - 82D 40F 8D 6 BF2 } ""
EndProject
Project ( "" { 2150E333 - 8F DC - 42 A3 - 9474 - 1 A3956D46DE8 } "" ) = "" Lib "" , "" Lib "" , "" { EAB71280 - AF32 - 4531 - 8703 - 43 CDBA261AA3 } ""
EndProject
Project ( "" { 9 A19103F - 16F 7 - 4668 - BE54 - 9 A1E7A4F7556 } "" ) = "" Lib "" , "" src \ Lib \ Lib . csproj "" , "" { 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } ""
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
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . ActiveCfg = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . Build . 0 = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . ActiveCfg = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . Build . 0 = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . Build . 0 = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . ActiveCfg = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . Build . 0 = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . ActiveCfg = Release | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . Build . 0 = Release | x86
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | x64 . ActiveCfg = Debug | x64
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | x64 . Build . 0 = Debug | x64
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | x86 . ActiveCfg = Debug | x86
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Debug | x86 . Build . 0 = Debug | x86
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | Any CPU . Build . 0 = Release | Any CPU
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | x64 . ActiveCfg = Release | x64
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | x64 . Build . 0 = Release | x64
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | x86 . ActiveCfg = Release | x86
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } . Release | x86 . Build . 0 = Release | x86
EndGlobalSection
GlobalSection ( SolutionProperties ) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection ( NestedProjects ) = preSolution
{ EAB71280 - AF32 - 4531 - 8703 - 43 CDBA261AA3 } = { 7 B86CE74 - F620 - 4 B32 - 99F E - 82D 40F 8D 6 BF2 }
{ 84 A45D44 - B677 - 492D - A6DA - B3A71135AB8E } = { EAB71280 - AF32 - 4531 - 8703 - 43 CDBA261AA3 }
EndGlobalSection
EndGlobal
";
private const string ExpectedSlnContentsAfterRemoveLastNestedProj = @ "
Microsoft Visual Studio Solution File , Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0 . 26006.2
MinimumVisualStudioVersion = 10.0 . 40219.1
Project ( "" { 9 A19103F - 16F 7 - 4668 - BE54 - 9 A1E7A4F7556 } "" ) = "" App "" , "" App . csproj "" , "" { 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } ""
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
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . ActiveCfg = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x64 . Build . 0 = Debug | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . ActiveCfg = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Debug | x86 . Build . 0 = Debug | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | Any CPU . Build . 0 = Release | Any CPU
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . ActiveCfg = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x64 . Build . 0 = Release | x64
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . ActiveCfg = Release | x86
{ 7072 A694 - 548F - 4 CAE - A58F - 12D 257D 5F 486 } . Release | x86 . Build . 0 = Release | x86
EndGlobalSection
EndGlobal
2017-11-21 15:46:21 -08:00
";
private const string ExpectedSlnContentsAfterRemoveProjectWithDependencies = @ "
Microsoft Visual Studio Solution File , Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0 . 27110.0
MinimumVisualStudioVersion = 10.0 . 40219.1
Project ( "" { FAE04EC0 - 301F - 11D 3 - BF4B - 00 C04F79EFBC } "" ) = "" App "" , "" App \ App . csproj "" , "" { BB02B949 - F6BD - 4872 - 95 CB - 96 A05B1FE026 } ""
ProjectSection ( ProjectDependencies ) = postProject
{ D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } = { D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 }
EndProjectSection
EndProject
Project ( "" { FAE04EC0 - 301F - 11D 3 - BF4B - 00 C04F79EFBC } "" ) = "" First "" , "" First \ First . csproj "" , "" { D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } ""
EndProject
Global
GlobalSection ( SolutionConfigurationPlatforms ) = preSolution
Debug | Any CPU = Debug | Any CPU
Release | Any CPU = Release | Any CPU
EndGlobalSection
GlobalSection ( ProjectConfigurationPlatforms ) = postSolution
{ BB02B949 - F6BD - 4872 - 95 CB - 96 A05B1FE026 } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ BB02B949 - F6BD - 4872 - 95 CB - 96 A05B1FE026 } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ BB02B949 - F6BD - 4872 - 95 CB - 96 A05B1FE026 } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ BB02B949 - F6BD - 4872 - 95 CB - 96 A05B1FE026 } . Release | Any CPU . Build . 0 = Release | Any CPU
{ D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } . Debug | Any CPU . ActiveCfg = Debug | Any CPU
{ D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } . Debug | Any CPU . Build . 0 = Debug | Any CPU
{ D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } . Release | Any CPU . ActiveCfg = Release | Any CPU
{ D53E177A - 8 ECF - 43D 5 - A01E - 98 B884D53CA6 } . Release | Any CPU . Build . 0 = Release | Any CPU
EndGlobalSection
GlobalSection ( SolutionProperties ) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection ( ExtensibilityGlobals ) = postSolution
SolutionGuid = { F6D9A973 - 1 CFD - 41 C9 - 84F 2 - 1471 C0FE67DF }
EndGlobalSection
EndGlobal
2017-01-03 07:18:45 -10:00
";
2016-12-15 15:48:04 -08:00
[Theory]
[InlineData("--help")]
[InlineData("-h")]
public void WhenHelpOptionIsPassedItPrintsUsage ( string helpArg )
{
var cmd = new DotnetCommand ( )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {helpArg}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Pass ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[Fact]
public void WhenTooManyArgumentsArePassedItPrintsError ( )
{
var cmd = new DotnetCommand ( )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( "sln one.sln two.sln three.sln remove" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-27 13:26:14 -07:00
cmd . StdErr . Should ( ) . BeVisuallyEquivalentTo ( $@"{string.Format(CommandLine.LocalizableStrings.UnrecognizedCommandOrArgument, " two . sln ")}
{ string . Format ( CommandLine . LocalizableStrings . UnrecognizedCommandOrArgument , "three.sln" ) }
{ CommonLocalizableStrings . SpecifyAtLeastOneProjectToRemove } ");
2016-12-15 15:48:04 -08:00
}
2016-12-16 10:23:26 -08:00
[Theory]
[InlineData("")]
[InlineData("unknownCommandName")]
public void WhenNoCommandIsPassedItPrintsError ( string commandName )
{
var cmd = new DotnetCommand ( )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln {commandName}" ) ;
2016-12-16 10:23:26 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( CommonLocalizableStrings . RequiredCommandNotPassed ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( SlnCommandHelpText ) ;
2016-12-16 10:23:26 -08:00
}
2016-12-15 15:48:04 -08:00
[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 ( )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln {solutionName} remove p.csproj" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . CouldNotFindSolutionOrDirectory , solutionName ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln InvalidSolution.sln remove {projectToRemove}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . InvalidSolutionFormatString , "InvalidSolution.sln" , LocalizableStrings . FileHeaderMissingError ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . InvalidSolutionFormatString , solutionPath , LocalizableStrings . FileHeaderMissingError ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[Fact]
public void WhenNoProjectIsPassedItPrintsErrorAndUsage ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojFiles" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( @"sln App.sln remove" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( CommonLocalizableStrings . SpecifyAtLeastOneProjectToRemove ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( @"sln remove App.csproj" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . SolutionDoesNotExist , solutionPath + Path . DirectorySeparatorChar ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Fail ( ) ;
2017-06-13 20:22:27 -07:00
cmd . StdErr . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . MoreThanOneSolutionInDirectory , projectDirectory + Path . DirectorySeparatorChar ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( "sln remove referenceDoesNotExistInSln.csproj" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Pass ( ) ;
2017-12-07 17:22:29 -08:00
cmd . StdOut . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . ProjectNotFoundInTheSolution , "referenceDoesNotExistInSln.csproj" ) ) ;
2016-12-15 15:48:04 -08:00
File . ReadAllText ( solutionPath )
2017-01-03 07:18:45 -10:00
. Should ( ) . BeVisuallyEquivalentTo ( contentBefore ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Pass ( ) ;
2017-12-07 17:22:29 -08:00
cmd . StdOut . Should ( ) . Be ( string . Format ( CommonLocalizableStrings . ProjectRemovedFromTheSolution , projectToRemove ) ) ;
2016-12-15 15:48:04 -08:00
slnFile = SlnFile . Read ( solutionPath ) ;
slnFile . Projects . Count . Should ( ) . Be ( 1 ) ;
2016-12-20 13:04:01 -10:00
slnFile . Projects [ 0 ] . FilePath . Should ( ) . Be ( Path . Combine ( "App" , "App.csproj" ) ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Pass ( ) ;
2016-12-16 01:04:09 -08:00
2017-12-07 17:22:29 -08:00
string outputText = string . Format ( CommonLocalizableStrings . ProjectRemovedFromTheSolution , projectToRemove ) ;
2017-06-13 20:22:27 -07:00
outputText + = Environment . NewLine + outputText ;
2016-12-28 14:50:34 -08:00
cmd . StdOut . Should ( ) . BeVisuallyEquivalentTo ( outputText ) ;
2016-12-15 15:48:04 -08:00
slnFile = SlnFile . Read ( solutionPath ) ;
slnFile . Projects . Count . Should ( ) . Be ( 1 ) ;
2016-12-20 13:04:01 -10:00
slnFile . Projects [ 0 ] . FilePath . Should ( ) . Be ( Path . Combine ( "App" , "App.csproj" ) ) ;
2016-12-15 15:48:04 -08:00
}
[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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove idontexist.csproj {projectToRemove} idontexisteither.csproj" ) ;
2016-12-15 15:48:04 -08:00
cmd . Should ( ) . Pass ( ) ;
2016-12-16 01:04:09 -08:00
2017-12-07 17:22:29 -08:00
string outputText = $@"{string.Format(CommonLocalizableStrings.ProjectNotFoundInTheSolution, " idontexist . csproj ")}
{ string . Format ( CommonLocalizableStrings . ProjectRemovedFromTheSolution , projectToRemove ) }
{ string . Format ( CommonLocalizableStrings . ProjectNotFoundInTheSolution , "idontexisteither.csproj" ) } ";
2017-06-13 20:22:27 -07:00
2016-12-28 14:50:34 -08:00
cmd . StdOut . Should ( ) . BeVisuallyEquivalentTo ( outputText ) ;
2016-12-15 15:48:04 -08:00
slnFile = SlnFile . Read ( solutionPath ) ;
slnFile . Projects . Count . Should ( ) . Be ( 1 ) ;
2016-12-20 13:04:01 -10:00
slnFile . Projects [ 0 ] . FilePath . Should ( ) . Be ( Path . Combine ( "App" , "App.csproj" ) ) ;
2016-12-15 15:48:04 -08:00
}
2017-01-03 07:18:45 -10:00
[Fact]
public void WhenReferenceIsRemovedBuildConfigsAreAlsoRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. 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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2017-01-03 07:18:45 -10:00
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemove ) ;
}
2017-12-07 17:22:29 -08:00
[Fact]
public void WhenDirectoryContainingProjectIsGivenProjectIsRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var solutionPath = Path . Combine ( projectDirectory , "App.sln" ) ;
SlnFile slnFile = SlnFile . Read ( solutionPath ) ;
slnFile . Projects . Count . Should ( ) . Be ( 2 ) ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. ExecuteWithCapturedOutput ( "sln remove Lib" ) ;
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemove ) ;
}
[Fact]
public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var directoryToRemove = "Empty" ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. ExecuteWithCapturedOutput ( $"sln remove {directoryToRemove}" ) ;
cmd . Should ( ) . Fail ( ) ;
cmd . StdErr . Should ( ) . Be (
string . Format (
CommonLocalizableStrings . CouldNotFindAnyProjectInDirectory ,
Path . Combine ( projectDirectory , directoryToRemove ) ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
}
[Fact]
public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var directoryToRemove = "Multiple" ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. ExecuteWithCapturedOutput ( $"sln remove {directoryToRemove}" ) ;
cmd . Should ( ) . Fail ( ) ;
cmd . StdErr . Should ( ) . Be (
string . Format (
CommonLocalizableStrings . MoreThanOneProjectInDirectory ,
Path . Combine ( projectDirectory , directoryToRemove ) ) ) ;
cmd . StdOut . Should ( ) . BeVisuallyEquivalentToIfNotLocalized ( HelpText ) ;
}
2017-01-04 18:32:09 -10:00
[Fact]
2017-01-03 07:18:45 -10:00
public void WhenReferenceIsRemovedSlnBuilds ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. 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 )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2017-01-03 07:18:45 -10:00
cmd . Should ( ) . Pass ( ) ;
new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. Execute ( $"restore App.sln" )
. Should ( ) . Pass ( ) ;
new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. Execute ( "build App.sln --configuration Release" )
. Should ( ) . Pass ( ) ;
var reasonString = "should be built in release mode, otherwise it means build configurations are missing from the sln file" ;
var releaseDirectory = Directory . EnumerateDirectories (
Path . Combine ( projectDirectory , "App" , "bin" ) ,
"Release" ,
SearchOption . AllDirectories ) ;
releaseDirectory . Count ( ) . Should ( ) . Be ( 1 , $"App {reasonString}" ) ;
Directory . EnumerateFiles ( releaseDirectory . Single ( ) , "App.dll" , SearchOption . AllDirectories )
. Count ( ) . Should ( ) . Be ( 1 , $"App {reasonString}" ) ;
}
2017-12-08 13:52:56 -08:00
[Fact]
public void WhenProjectIsRemovedSolutionHasUTF8BOM ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var projectToRemove = Path . Combine ( "Lib" , "Lib.csproj" ) ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. ExecuteWithCapturedOutput ( $"sln App.sln remove {projectToRemove}" ) ;
cmd . Should ( ) . Pass ( ) ;
var preamble = Encoding . UTF8 . GetPreamble ( ) ;
preamble . Length . Should ( ) . Be ( 3 ) ;
using ( var stream = new FileStream ( Path . Combine ( projectDirectory , "App.sln" ) , FileMode . Open ) )
{
var bytes = new byte [ preamble . Length ] ;
stream . Read ( bytes , 0 , bytes . Length ) ;
bytes . Should ( ) . BeEquivalentTo ( preamble ) ;
}
}
2017-01-03 07:18:45 -10:00
[Fact]
public void WhenFinalReferenceIsRemovedEmptySectionsAreRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var solutionPath = Path . Combine ( projectDirectory , "App.sln" ) ;
SlnFile slnFile = SlnFile . Read ( solutionPath ) ;
slnFile . Projects . Count . Should ( ) . Be ( 2 ) ;
var appPath = Path . Combine ( "App" , "App.csproj" ) ;
var libPath = Path . Combine ( "Lib" , "Lib.csproj" ) ;
var projectsToRemove = $"{libPath} {appPath}" ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectsToRemove}" ) ;
2017-01-03 07:18:45 -10:00
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemoveAllProjects ) ;
}
2017-01-04 18:32:09 -10:00
[Fact]
public void WhenNestedProjectIsRemovedItsSolutionFoldersAreRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndCsprojInSubDirToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var solutionPath = Path . Combine ( projectDirectory , "App.sln" ) ;
var projectToRemove = Path . Combine ( "src" , "NotLastProjInSrc" , "NotLastProjInSrc.csproj" ) ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2017-01-04 18:32:09 -10:00
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemoveNestedProj ) ;
}
[Fact]
public void WhenFinalNestedProjectIsRemovedSolutionFoldersAreRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnAndLastCsprojInSubDirToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var solutionPath = Path . Combine ( projectDirectory , "App.sln" ) ;
var projectToRemove = Path . Combine ( "src" , "Lib" , "Lib.csproj" ) ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
2017-01-06 10:58:23 -10:00
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
2017-01-04 18:32:09 -10:00
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemoveLastNestedProj ) ;
}
2017-11-21 15:46:21 -08:00
[Fact]
public void WhenProjectIsRemovedThenDependenciesOnProjectAreAlsoRemoved ( )
{
var projectDirectory = TestAssets
. Get ( "TestAppWithSlnProjectDependencyToRemove" )
. CreateInstance ( )
. WithSourceFiles ( )
. Root
. FullName ;
var solutionPath = Path . Combine ( projectDirectory , "App.sln" ) ;
var projectToRemove = Path . Combine ( "Second" , "Second.csproj" ) ;
var cmd = new DotnetCommand ( )
. WithWorkingDirectory ( projectDirectory )
. ExecuteWithCapturedOutput ( $"sln remove {projectToRemove}" ) ;
cmd . Should ( ) . Pass ( ) ;
File . ReadAllText ( solutionPath )
. Should ( ) . BeVisuallyEquivalentTo ( ExpectedSlnContentsAfterRemoveProjectWithDependencies ) ;
}
2016-12-15 15:48:04 -08:00
}
}