From f1cc87ea224a7266082400ca019e59174acb7572 Mon Sep 17 00:00:00 2001 From: David Federman Date: Wed, 7 Aug 2024 14:03:07 -0700 Subject: [PATCH] Add e2e tests --- .../E2ETests.cs | 229 ++++++++++++++++++ .../PackagesConfigConverter.UnitTests.csproj | 5 + .../TestData/E2ETests/MSTest/after.csproj | 56 +++++ .../TestData/E2ETests/MSTest/before.csproj | 73 ++++++ .../TestData/E2ETests/MSTest/packages.config | 6 + .../TestData/E2ETests/NuGet.config | 20 ++ .../E2ETests/ReferenceOnly/after.csproj | 54 +++++ .../E2ETests/ReferenceOnly/before.csproj | 57 +++++ .../E2ETests/ReferenceOnly/packages.config | 4 + .../ProjectConverter.cs | 4 +- 10 files changed, 505 insertions(+), 3 deletions(-) create mode 100644 src/PackagesConfigConverter.UnitTests/E2ETests.cs create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/after.csproj create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/before.csproj create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/packages.config create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/NuGet.config create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/after.csproj create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/before.csproj create mode 100644 src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/packages.config diff --git a/src/PackagesConfigConverter.UnitTests/E2ETests.cs b/src/PackagesConfigConverter.UnitTests/E2ETests.cs new file mode 100644 index 0000000..de1ba10 --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/E2ETests.cs @@ -0,0 +1,229 @@ +// Copyright (c) Jeff Kluge. All rights reserved. +// +// Licensed under the MIT license. + +using log4net; +using log4net.Core; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading; +using Xunit; +using Xunit.Abstractions; + +namespace PackagesConfigConverter.UnitTests +{ + public class E2ETests : TestBase + { + private const string BaseTestCaseDir = @"TestData\E2ETests"; + private const string BaseWorkingDir = @"_work"; + private const string NuGetConfigFile = "NuGet.config"; + private const string PackagesConfigFileName = "packages.config"; + private const string BeforeProjectName = "before.csproj"; + private const string AfterProjectName = "after.csproj"; + + private static readonly Regex ConverterInclude = new Regex($"{BeforeProjectName}$", RegexOptions.Compiled); + + public E2ETests(ITestOutputHelper testOutputHelper) + : base(testOutputHelper) + { + } + + public static IEnumerable TestCases() + { + foreach (string dir in Directory.EnumerateDirectories(BaseTestCaseDir)) + { + string testCase = Path.GetFileName(dir); + yield return new object[] { testCase }; + } + } + + [Theory] + [MemberData(nameof(TestCases))] + public void E2ETest(string testCase) + { + // Copy test files to a working dir + string testCaseDir = Path.Combine(BaseTestCaseDir, testCase); + string workingDir = Path.Combine(BaseWorkingDir, testCase); + + if (Directory.Exists(workingDir)) + { + Directory.Delete(workingDir, recursive: true); + } + + Directory.CreateDirectory(workingDir); + foreach (string file in Directory.EnumerateFiles(testCaseDir, "*", SearchOption.AllDirectories)) + { + string relativePath = file.Substring(testCaseDir.Length + 1); + string destintion = Path.Combine(workingDir, relativePath); + File.Copy(file, destintion); + } + + File.Copy(Path.Combine(BaseTestCaseDir, NuGetConfigFile), Path.Combine(workingDir, NuGetConfigFile)); + + string packagesConfigFile = Path.Combine(workingDir, PackagesConfigFileName); + Assert.True(File.Exists(packagesConfigFile)); + + // Restore the project + var process = new Process() + { + StartInfo = new ProcessStartInfo() + { + FileName = "nuget.exe", + Arguments = "restore", + WorkingDirectory = workingDir, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + }, + EnableRaisingEvents = true, + }; + + process.OutputDataReceived += (sender, eventArgs) => + { + if (eventArgs.Data != null) + { + TestOutputHelper.WriteLine(eventArgs.Data); + } + }; + + process.ErrorDataReceived += (sender, eventArgs) => + { + if (eventArgs.Data != null) + { + TestOutputHelper.WriteLine(eventArgs.Data); + } + }; + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + Assert.Equal(0, process.ExitCode); + + // Run the conversion + var converterSettings = new ProjectConverterSettings() + { + Include = ConverterInclude, + Log = new TestLog(TestOutputHelper), + RepositoryRoot = workingDir, + }; + var converter = new ProjectConverter(converterSettings); + converter.ConvertRepository(CancellationToken.None); + + // File was deleted + Assert.False(File.Exists(packagesConfigFile)); + + string expectedProjectContent = File.ReadAllText(Path.Combine(testCaseDir, AfterProjectName)); + string actualProjectContent = File.ReadAllText(Path.Combine(workingDir, BeforeProjectName)); + Assert.Equal(expectedProjectContent, actualProjectContent); + } + + private sealed class TestLog : ILog + { + private const string DebugLevel = "Debug"; + private const string ErrorLevel = "Error"; + private const string FatalLevel = "Fatal"; + private const string InfoLevel = "Info"; + private const string WarnLevel = "Warn"; + + private readonly ITestOutputHelper _testOutputHelper; + + public TestLog(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + + public bool IsDebugEnabled => true; + + public bool IsInfoEnabled => true; + + public bool IsWarnEnabled => true; + + public bool IsErrorEnabled => true; + + public bool IsFatalEnabled => true; + + public ILogger Logger => throw new NotImplementedException(); + + public void Debug(object message) => Log(DebugLevel, message); + + public void Debug(object message, Exception exception) => Log(DebugLevel, message, exception); + + public void DebugFormat(string format, params object[] args) => Log(DebugLevel, format, args); + + public void DebugFormat(string format, object arg0) => Log(DebugLevel, string.Format(format, arg0)); + + public void DebugFormat(string format, object arg0, object arg1) => Log(DebugLevel, string.Format(format, arg0, arg1)); + + public void DebugFormat(string format, object arg0, object arg1, object arg2) => Log(DebugLevel, string.Format(format, arg0, arg2)); + + public void DebugFormat(IFormatProvider provider, string format, params object[] args) => Log(DebugLevel, string.Format(provider, format, args)); + + public void Error(object message) => Log(ErrorLevel, message); + + public void Error(object message, Exception exception) => Log(ErrorLevel, message, exception); + + public void ErrorFormat(string format, params object[] args) => Log(ErrorLevel, format, args); + + public void ErrorFormat(string format, object arg0) => Log(ErrorLevel, string.Format(format, arg0)); + + public void ErrorFormat(string format, object arg0, object arg1) => Log(ErrorLevel, string.Format(format, arg0, arg1)); + + public void ErrorFormat(string format, object arg0, object arg1, object arg2) => Log(ErrorLevel, string.Format(format, arg0, arg2)); + + public void ErrorFormat(IFormatProvider provider, string format, params object[] args) => Log(ErrorLevel, string.Format(provider, format, args)); + + public void Fatal(object message) => Log(FatalLevel, message); + + public void Fatal(object message, Exception exception) => Log(FatalLevel, message, exception); + + public void FatalFormat(string format, params object[] args) => Log(FatalLevel, format, args); + + public void FatalFormat(string format, object arg0) => Log(FatalLevel, string.Format(format, arg0)); + + public void FatalFormat(string format, object arg0, object arg1) => Log(FatalLevel, string.Format(format, arg0, arg1)); + + public void FatalFormat(string format, object arg0, object arg1, object arg2) => Log(FatalLevel, string.Format(format, arg0, arg2)); + + public void FatalFormat(IFormatProvider provider, string format, params object[] args) => Log(FatalLevel, string.Format(provider, format, args)); + + public void Info(object message) => Log(InfoLevel, message); + + public void Info(object message, Exception exception) => Log(InfoLevel, message, exception); + + public void InfoFormat(string format, params object[] args) => Log(InfoLevel, format, args); + + public void InfoFormat(string format, object arg0) => Log(InfoLevel, string.Format(format, arg0)); + + public void InfoFormat(string format, object arg0, object arg1) => Log(InfoLevel, string.Format(format, arg0, arg1)); + + public void InfoFormat(string format, object arg0, object arg1, object arg2) => Log(InfoLevel, string.Format(format, arg0, arg2)); + + public void InfoFormat(IFormatProvider provider, string format, params object[] args) => Log(InfoLevel, string.Format(provider, format, args)); + + public void Warn(object message) => Log(WarnLevel, message); + + public void Warn(object message, Exception exception) => Log(WarnLevel, message, exception); + + public void WarnFormat(string format, params object[] args) => Log(WarnLevel, format, args); + + public void WarnFormat(string format, object arg0) => Log(WarnLevel, string.Format(format, arg0)); + + public void WarnFormat(string format, object arg0, object arg1) => Log(WarnLevel, string.Format(format, arg0, arg1)); + + public void WarnFormat(string format, object arg0, object arg1, object arg2) => Log(WarnLevel, string.Format(format, arg0, arg2)); + + public void WarnFormat(IFormatProvider provider, string format, params object[] args) => Log(WarnLevel, string.Format(provider, format, args)); + + private void Log(string level, object message) => _testOutputHelper.WriteLine($"[{level}] {message}"); + + private void Log(string level, object message, Exception exception) => _testOutputHelper.WriteLine($"[{level}] {message}. Exception: {exception}"); + + private void Log(string level, string format, params object[] args) => _testOutputHelper.WriteLine($"[{level}] {format}", args); + } + } +} diff --git a/src/PackagesConfigConverter.UnitTests/PackagesConfigConverter.UnitTests.csproj b/src/PackagesConfigConverter.UnitTests/PackagesConfigConverter.UnitTests.csproj index b6c359b..8e134a0 100644 --- a/src/PackagesConfigConverter.UnitTests/PackagesConfigConverter.UnitTests.csproj +++ b/src/PackagesConfigConverter.UnitTests/PackagesConfigConverter.UnitTests.csproj @@ -12,4 +12,9 @@ + + + PreserveNewest + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/after.csproj b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/after.csproj new file mode 100644 index 0000000..e36bd1b --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/after.csproj @@ -0,0 +1,56 @@ + + + + + Debug + AnyCPU + {526743F1-40C3-4E9D-A23B-927EE3FC8583} + Library + Properties + SomeProject + SomeProject + v4.7.2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/before.csproj b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/before.csproj new file mode 100644 index 0000000..c4ff576 --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/before.csproj @@ -0,0 +1,73 @@ + + + + + + + Debug + AnyCPU + {526743F1-40C3-4E9D-A23B-927EE3FC8583} + Library + Properties + SomeProject + SomeProject + v4.7.2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.3.1.1\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.3.1.1\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/packages.config b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/packages.config new file mode 100644 index 0000000..391995a --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/MSTest/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/NuGet.config b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/NuGet.config new file mode 100644 index 0000000..c942c0c --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/NuGet.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/after.csproj b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/after.csproj new file mode 100644 index 0000000..4bdfdda --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/after.csproj @@ -0,0 +1,54 @@ + + + + + Debug + AnyCPU + {526743F1-40C3-4E9D-A23B-927EE3FC8583} + Library + Properties + SomeProject + SomeProject + v4.7.2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/before.csproj b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/before.csproj new file mode 100644 index 0000000..9d2e464 --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/before.csproj @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {526743F1-40C3-4E9D-A23B-927EE3FC8583} + Library + Properties + SomeProject + SomeProject + v4.7.2 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/packages.config b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/packages.config new file mode 100644 index 0000000..d24fb34 --- /dev/null +++ b/src/PackagesConfigConverter.UnitTests/TestData/E2ETests/ReferenceOnly/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/PackagesConfigConverter/ProjectConverter.cs b/src/PackagesConfigConverter/ProjectConverter.cs index 899b1e4..0fd0cec 100644 --- a/src/PackagesConfigConverter/ProjectConverter.cs +++ b/src/PackagesConfigConverter/ProjectConverter.cs @@ -75,9 +75,7 @@ public void ConvertRepository(CancellationToken cancellationToken) Log.Info($" NuGet configuration file : \"{_converterSettings.NuGetConfigPath}\""); foreach (string file in Directory.EnumerateFiles(_converterSettings.RepositoryRoot, "*.csproj", SearchOption.AllDirectories) - .TakeWhile(_ => !cancellationToken.IsCancellationRequested) - .Where(f => _converterSettings.Exclude == null || !_converterSettings.Exclude.IsMatch(f)) - .Where(f => _converterSettings.Include == null || _converterSettings.Include.IsMatch(f))) + .TakeWhile(_ => !cancellationToken.IsCancellationRequested)) { if (_converterSettings.Exclude != null && _converterSettings.Exclude.IsMatch(file)) {