Skip to content
This repository has been archived by the owner on Apr 20, 2023. It is now read-only.

Commit

Permalink
Lock on spec - all tests passing on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
krwq committed Nov 22, 2016
1 parent 80d4dae commit 7bb9a0b
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 77 deletions.
73 changes: 51 additions & 22 deletions src/dotnet/commands/dotnet-add-p2p/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Tools.Common;

namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
{
Expand Down Expand Up @@ -42,18 +43,29 @@ public static int Run(string[] args)

CommandOption forceOption = app.Option(
"--force",
"Add reference even if it does not exist",
"Add reference even if it does not exist, do not convert paths to relative",
CommandOptionType.NoValue);

app.OnExecute(() => {
if (projectArgument.Value == null)
if (string.IsNullOrEmpty(projectArgument.Value))
{
throw new GracefulException("Argument <Project> is required.");
}

ProjectRootElement project = File.Exists(projectArgument.Value) ?
GetProjectFromFileOrThrow(projectArgument.Value) :
GetProjectFromDirectoryOrThrow(projectArgument.Value);
ProjectRootElement project;
string projectDir;
if (File.Exists(projectArgument.Value))
{
project = GetProjectFromFileOrThrow(projectArgument.Value);
projectDir = new FileInfo(projectArgument.Value).DirectoryName;
}
else
{
project = GetProjectFromDirectoryOrThrow(projectArgument.Value);
projectDir = projectArgument.Value;
}

projectDir = PathUtility.EnsureTrailingSlash(projectDir);

if (app.RemainingArguments.Count == 0)
{
Expand All @@ -63,22 +75,8 @@ public static int Run(string[] args)
List<string> references = app.RemainingArguments;
if (!forceOption.HasValue())
{
var notExisting = new List<string>();
foreach (var r in references)
{
if (!File.Exists(r))
{
notExisting.Add(r);
}
}

if (notExisting.Count > 0)
{
throw new GracefulException(
string.Join(
Environment.NewLine,
notExisting.Select((ne) => $"Reference `{ne}` does not exist.")));
}
EnsureAllReferencesExist(references);
ConvertPathsToRelative(projectDir, ref references);
}

int numberOfAddedReferences = AddProjectToProjectReference(
Expand Down Expand Up @@ -106,6 +104,32 @@ public static int Run(string[] args)
}
}

internal static void EnsureAllReferencesExist(List<string> references)
{
var notExisting = new List<string>();
foreach (var r in references)
{
if (!File.Exists(r))
{
notExisting.Add(r);
}
}

if (notExisting.Count > 0)
{
throw new GracefulException(
string.Join(
Environment.NewLine,
notExisting.Select((ne) => $"Reference `{ne}` does not exist.")));
}
}

internal static void ConvertPathsToRelative(string root, ref List<string> references)
{
root = PathUtility.EnsureTrailingSlash(Path.GetFullPath(root));
references = references.Select((r) => PathUtility.GetRelativePath(root, Path.GetFullPath(r))).ToList();
}

// There is ProjectRootElement.TryOpen but it does not work as expected
// I.e. it returns null for some valid projects
internal static ProjectRootElement TryOpenProject(string filename)
Expand Down Expand Up @@ -181,13 +205,18 @@ internal static ProjectRootElement GetProjectFromDirectoryOrThrow(string directo
return ret;
}

private static string NormalizeSlashesForMsbuild(string path)
{
return path.Replace('/', '\\');
}

internal static int AddProjectToProjectReference(ProjectRootElement root, string framework, IEnumerable<string> refs)
{
int numberOfAddedReferences = 0;
const string ProjectItemElementType = "ProjectReference";

ProjectItemGroupElement ig = null;
foreach (var @ref in refs)
foreach (var @ref in refs.Select((r) => NormalizeSlashesForMsbuild(r)))
{
if (root.HasExistingItemWithCondition(framework, @ref))
{
Expand Down
37 changes: 0 additions & 37 deletions test/dotnet-add-p2p.Tests/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,6 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
{
internal static class Extensions
{
//public static int CountOccurrances(this string s, string pattern)
//{
// int ret = 0;
// for (int i = s.IndexOf(pattern); i != -1; i = s.IndexOf(pattern, i + 1))
// {
// ret++;
// }

// return ret;
//}

//public static int NumberOfLinesWith(this string s, params string[] patterns)
//{
// int ret = 0;
// string[] lines = s.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
// foreach (var line in lines)
// {
// bool shouldCount = true;

// foreach (var p in patterns)
// {
// if (!line.Contains(p))
// {
// shouldCount = false;
// break;
// }
// }

// if (shouldCount)
// {
// ret++;
// }
// }

// return ret;
//}

public static int NumberOfItemGroupsWithConditionContaining(this ProjectRootElement root, string patternInCondition)
{
return root.ItemGroups.Count((ig) => ig.Condition.Contains(patternInCondition));
Expand Down
75 changes: 63 additions & 12 deletions test/dotnet-add-p2p.Tests/GivenDotnetAddP2P.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public void WhenHelpOptionIsPassedItPrintsUsage(string helpArg)
[InlineData("ihave?inv@lid/char\\acters")]
public void WhenNonExistingProjectIsPassedItPrintsErrorAndUsage(string projName)
{
string testRoot = NewDir().Path;
var setup = Setup();

var cmd = new AddP2PCommand()
Expand Down Expand Up @@ -99,7 +98,7 @@ public void WhenMoreThanOneProjectExistsInTheDirectoryItPrintsErrorAndUsage()

var cmd = new AddP2PCommand()
.WithWorkingDirectory(Path.Combine(setup.TestRoot, "MoreThanOne"))
.Execute($"\"{setup.ValidRefCsprojRelPath}\"");
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
cmd.ExitCode.Should().NotBe(0);
cmd.StdErr.Should().Contain("more than one");
cmd.StdOut.Should().Contain("Usage");
Expand Down Expand Up @@ -550,28 +549,80 @@ public void WhenPassedMultipleRefsAndOneOfthemDoesNotExistItCancelsWholeOperatio
lib.CsProjContent().Should().BeEquivalentTo(contentBefore);
}

[Fact(Skip = "Not finished")]
[Fact]
public void WhenPassedReferenceDoesNotExistAndForceSwitchIsPassedItAddsIt()
{
throw new NotImplementedException();
var lib = NewLib();
const string nonExisting = "IDoNotExist.csproj";

int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
var cmd = new AddP2PCommand()
.WithWorkingDirectory(lib.Path)
.WithProject(lib.CsProjName)
.Execute($"--force \"{nonExisting}\"");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("added to the project");
cmd.StdErr.Should().BeEmpty();
var csproj = lib.CsProj();
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
csproj.NumberOfProjectReferencesWithIncludeContaining(nonExisting).Should().Be(1);
}

[Fact(Skip = "Not finished")]
[Fact]
public void WhenPassedReferenceIsUsingSlashesItNormalizesItToBackslashes()
{
throw new NotImplementedException();
var lib = NewLib();
var setup = Setup();

int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
var cmd = new AddP2PCommand()
.WithWorkingDirectory(lib.Path)
.WithProject(lib.CsProjName)
.Execute($"--force \"{setup.ValidRefCsprojPath.Replace('\\', '/')}\"");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("added to the project");
cmd.StdErr.Should().BeEmpty();
var csproj = lib.CsProj();
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojPath.Replace('/', '\\')).Should().Be(1);
}

[Fact(Skip = "Not finished")]
public void WhenPassedRefIsUsingBackslashesItDoesntNormalizeIt()
[Fact]
public void WhenReferenceIsRelativeAndProjectIsNotInCurrentDirectoryReferencePathIsFixed()
{
throw new NotImplementedException();
var setup = Setup();
var proj = new ProjDir(setup.LibDir);

int noCondBefore = proj.CsProj().NumberOfItemGroupsWithoutCondition();
var cmd = new AddP2PCommand()
.WithWorkingDirectory(setup.TestRoot)
.WithProject(setup.LibCsprojPath)
.Execute($"\"{setup.ValidRefCsprojRelPath}\"");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("added to the project");
cmd.StdErr.Should().BeEmpty();
var csproj = proj.CsProj();
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelToOtherProjPath).Should().Be(1);
}

[Fact(Skip = "Not finished")]
public void WhenReferenceIsRelativeAndProjectIsNotInCurrentDirectoryReferencePathIsFixed()
[Fact]
public void WhenReferenceIsRelativeAndProjectIsNotInCurrentDirectoryAndForceSwitchIsPassedItDoesNotChangeIt()
{
throw new NotImplementedException();
var setup = Setup();
var proj = new ProjDir(setup.LibDir);

int noCondBefore = proj.CsProj().NumberOfItemGroupsWithoutCondition();
var cmd = new AddP2PCommand()
.WithWorkingDirectory(setup.TestRoot)
.WithProject(setup.LibCsprojPath)
.Execute($"--force \"{setup.ValidRefCsprojRelPath}\"");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("added to the project");
cmd.StdErr.Should().BeEmpty();
var csproj = proj.CsProj();
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelPath).Should().Be(1);
}
}
}
10 changes: 4 additions & 6 deletions test/dotnet-add-p2p.Tests/TestSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ internal class TestSetup

public string TestRoot { get; private set; }


private const string ValidRef = "ValidRef";
public string ValidRefCsprojName => $"{ValidRef}.csproj";
public string ValidRefCsprojPath => Path.Combine(TestRoot, ValidRef, ValidRefCsprojName);
public string ValidRefCsprojRelPath => Path.Combine("..", ValidRef, ValidRefCsprojName);

public string ValidRefCsprojRelPath => Path.Combine(ValidRef, ValidRefCsprojName);
public string ValidRefCsprojPath => Path.Combine(TestRoot, ValidRefCsprojRelPath);
public string ValidRefCsprojRelToOtherProjPath => Path.Combine("..", ValidRefCsprojRelPath);

private const string Lib = "Lib";
public string LibDir => Path.Combine(TestRoot, Lib);
public string LibCsprojName => $"{Lib}.csproj";
public string LibCsprojPath => Path.Combine(TestRoot, Lib, LibCsprojName);
public string LibCsprojRelPath => Path.Combine("..", Lib, LibCsprojName);



public TestSetup(string testRoot)
{
TestRoot = testRoot;
Expand Down

0 comments on commit 7bb9a0b

Please sign in to comment.