// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.CodeAnalysis.Interactive; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; using System; using System.IO; using System.Text; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.Interactive { public class NuGetPackageResolverTests : TestBase { /// /// Valid reference. /// [ConditionalFact(typeof(WindowsOnly))] public void ResolveReference() { var expectedProjectJson = @"{ ""dependencies"": { ""A.B.C"": ""1.2"" }, ""frameworks"": { ""net46"": {} } }"; var expectedConfig = @" "; var actualProjectLockJson = @"{ ""locked"": false, ""version"": 1, ""targets"": { "".NETFramework,Version=v4.5"": { }, "".NETFramework,Version=v4.6"": { ""System.Collections/4.0.10"": { ""dependencies"": { ""System.Runtime"": """" }, ""compile"": { ""ref/dotnet/System.Runtime.dll"": {} }, ""runtime"": { ""ref/dotnet/System.Collections.dll"": {} } }, ""System.Diagnostics.Debug/4.0.10"": { ""dependencies"": { ""System.Runtime"": """" }, }, ""System.Runtime/4.0.0"": { ""runtime"": { ""ref/dotnet/_._"": {} } }, ""System.IO/4.0.10"": { ""dependencies"": {}, ""runtime"": { ""ref/dotnet/System.Runtime.dll"": {}, ""ref/dotnet/System.IO.dll"": {} } } } } }"; using (var directory = new DisposableDirectory(Temp)) { var packagesDirectory = directory.Path; var resolver = new NuGetPackageResolverImpl( packagesDirectory, startInfo => { // Verify arguments. var arguments = startInfo.Arguments.Split('"'); Assert.Equal(7, arguments.Length); Assert.Equal("restore ", arguments[0]); Assert.Equal("project.json", PathUtilities.GetFileName(arguments[1])); Assert.Equal(" -ConfigFile ", arguments[2]); Assert.Equal("nuget.config", PathUtilities.GetFileName(arguments[3])); Assert.Equal(" -PackagesDirectory ", arguments[4]); Assert.Equal(packagesDirectory, arguments[5]); Assert.Equal("", arguments[6]); // Verify project.json contents. var projectJsonPath = arguments[1]; var actualProjectJson = File.ReadAllText(projectJsonPath); Assert.Equal(expectedProjectJson, actualProjectJson); // Verify config file contents. var configPath = arguments[3]; var actualConfig = File.ReadAllText(configPath); Assert.Equal(expectedConfig, actualConfig); // Generate project.lock.json. var projectLockJsonPath = PathUtilities.CombineAbsoluteAndRelativePaths(PathUtilities.GetDirectoryName(projectJsonPath), "project.lock.json"); using (var writer = new StreamWriter(projectLockJsonPath)) { writer.Write(actualProjectLockJson); } }); var actualPaths = resolver.ResolveNuGetPackage("A.B.C", "1.2"); AssertEx.SetEqual(actualPaths, PathUtilities.CombineAbsoluteAndRelativePaths(packagesDirectory, PathUtilities.CombinePossiblyRelativeAndRelativePaths("System.Collections/4.0.10", "ref/dotnet/System.Collections.dll")), PathUtilities.CombineAbsoluteAndRelativePaths(packagesDirectory, PathUtilities.CombinePossiblyRelativeAndRelativePaths("System.IO/4.0.10", "ref/dotnet/System.Runtime.dll")), PathUtilities.CombineAbsoluteAndRelativePaths(packagesDirectory, PathUtilities.CombinePossiblyRelativeAndRelativePaths("System.IO/4.0.10", "ref/dotnet/System.IO.dll"))); } } /// /// Expected exception thrown during restore. /// [ConditionalFact(typeof(WindowsOnly))] public void HandledException() { using (var directory = new DisposableDirectory(Temp)) { bool restored = false; var resolver = new NuGetPackageResolverImpl(directory.Path, startInfo => { restored = true; throw new IOException(); }); var actualPaths = resolver.ResolveNuGetPackage("A.B.C", "1.2"); Assert.True(actualPaths.IsEmpty); Assert.True(restored); } } /// /// Unexpected exception thrown during restore. /// [ConditionalFact(typeof(WindowsOnly))] public void UnhandledException() { using (var directory = new DisposableDirectory(Temp)) { bool restored = false; var resolver = new NuGetPackageResolverImpl(directory.Path, startInfo => { restored = true; throw new InvalidOperationException(); }); Assert.Throws(() => resolver.ResolveNuGetPackage("A.B.C", "1.2")); Assert.True(restored); } } [ConditionalFact(typeof(WindowsOnly))] public void ParsePackageNameAndVersion() { ParseInvalidPackageReference("A"); ParseInvalidPackageReference("A/1"); ParseInvalidPackageReference("nuget"); ParseInvalidPackageReference("nuget:"); ParseInvalidPackageReference("NUGET:"); ParseInvalidPackageReference("nugetA/1"); ParseValidPackageReference("nuget:A", "A", ""); ParseValidPackageReference("nuget:A.B", "A.B", ""); ParseValidPackageReference("nuget: ", " ", ""); ParseInvalidPackageReference("nuget:A/"); ParseInvalidPackageReference("nuget:A//1.0"); ParseInvalidPackageReference("nuget:/1.0.0"); ParseInvalidPackageReference("nuget:A/B/2.0.0"); ParseValidPackageReference("nuget::nuget/1", ":nuget", "1"); ParseValidPackageReference("nuget:A/1", "A", "1"); ParseValidPackageReference("nuget:A.B/1.0.0", "A.B", "1.0.0"); ParseValidPackageReference("nuget:A/B.C", "A", "B.C"); ParseValidPackageReference("nuget: /1", " ", "1"); ParseValidPackageReference("nuget:A\t/\n1.0\r ", "A\t", "\n1.0\r "); } private static void ParseValidPackageReference(string reference, string expectedName, string expectedVersion) { string name; string version; Assert.True(NuGetPackageResolverImpl.TryParsePackageReference(reference, out name, out version)); Assert.Equal(expectedName, name); Assert.Equal(expectedVersion, version); } private static void ParseInvalidPackageReference(string reference) { string name; string version; Assert.False(NuGetPackageResolverImpl.TryParsePackageReference(reference, out name, out version)); Assert.Null(name); Assert.Null(version); } [ConditionalFact(typeof(WindowsOnly))] public void WriteProjectJson() { WriteProjectJsonPackageReference("A.B", "4.0.1", @"{ ""dependencies"": { ""A.B"": ""4.0.1"" }, ""frameworks"": { ""net46"": {} } }"); WriteProjectJsonPackageReference("A", "", @"{ ""dependencies"": { ""A"": """" }, ""frameworks"": { ""net46"": {} } }"); WriteProjectJsonPackageReference("\n\t", "\"'", @"{ ""dependencies"": { ""\n\t"": ""\""'"" }, ""frameworks"": { ""net46"": {} } }"); } private static void WriteProjectJsonPackageReference(string packageName, string packageVersion, string expectedJson) { var builder = new StringBuilder(); using (var writer = new StringWriter(builder)) { NuGetPackageResolverImpl.WriteProjectJson(writer, packageName, packageVersion); } var actualJson = builder.ToString(); Assert.Equal(expectedJson, actualJson); } } }