Replace JSON test DSL with regular C# Xunit tests for consistency with other ASP.NET repos
This commit is contained in:
parent
58211f89c7
commit
1f9dd4db5d
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test
|
||||||
|
{
|
||||||
|
public class EmptyWebTemplateTest : TemplateTestBase
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("net461")]
|
||||||
|
public void EmptyWebTemplate_Works(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("web", targetFrameworkOverride);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test.Helpers
|
||||||
|
{
|
||||||
|
public class AspNetProcess : IDisposable
|
||||||
|
{
|
||||||
|
private const string DefaultFramework = "netcoreapp2.0";
|
||||||
|
private const string ListeningMessagePrefix = "Now listening on: ";
|
||||||
|
|
||||||
|
private static int NextKestrelPort = 5000;
|
||||||
|
|
||||||
|
private readonly ProcessEx _process;
|
||||||
|
private readonly Uri _listeningUri;
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
public AspNetProcess(string workingDirectory, string projectName, string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient();
|
||||||
|
|
||||||
|
var buildProcess = ProcessEx.Run(workingDirectory, "dotnet", "build --no-restore -c Debug");
|
||||||
|
buildProcess.WaitForExit(assertSuccess: true);
|
||||||
|
|
||||||
|
var port = Interlocked.Increment(ref NextKestrelPort);
|
||||||
|
var envVars = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "ASPNETCORE_URLS", "http://localhost:" + port }
|
||||||
|
};
|
||||||
|
|
||||||
|
var framework = string.IsNullOrEmpty(targetFrameworkOverride) ? DefaultFramework : targetFrameworkOverride;
|
||||||
|
if (framework.StartsWith("netcore"))
|
||||||
|
{
|
||||||
|
_process = ProcessEx.Run(workingDirectory, "dotnet", $"exec bin/Debug/{framework}/{projectName}.dll", envVars: envVars);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var exeFullPath = Path.Combine(workingDirectory, "bin", "Debug", framework, $"{projectName}.exe");
|
||||||
|
_process = ProcessEx.Run(workingDirectory, exeFullPath, envVars: envVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until the app is accepting HTTP requests
|
||||||
|
var listeningMessage = _process
|
||||||
|
.OutputLinesAsEnumerable
|
||||||
|
.Where(line => line != null)
|
||||||
|
.FirstOrDefault(line => line.StartsWith(ListeningMessagePrefix, StringComparison.Ordinal));
|
||||||
|
Assert.True(!string.IsNullOrEmpty(listeningMessage), $"ASP.NET process exited without listening for requests.\nOutput: { _process.Output }\nError: { _process.Error }");
|
||||||
|
|
||||||
|
// Verify we have a valid URL to make requests to
|
||||||
|
var listeningUrlString = listeningMessage.Substring(ListeningMessagePrefix.Length);
|
||||||
|
_listeningUri = new Uri(listeningUrlString, UriKind.Absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AssertOk(string requestUrl)
|
||||||
|
=> AssertStatusCode(requestUrl, HttpStatusCode.OK);
|
||||||
|
|
||||||
|
internal void AssertNotFound(string requestUrl)
|
||||||
|
=> AssertStatusCode(requestUrl, HttpStatusCode.NotFound);
|
||||||
|
|
||||||
|
internal void AssertStatusCode(string requestUrl, HttpStatusCode statusCode)
|
||||||
|
{
|
||||||
|
var request = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
new Uri(_listeningUri, requestUrl));
|
||||||
|
|
||||||
|
var response = _httpClient.SendAsync(request).Result;
|
||||||
|
Assert.Equal(statusCode, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_httpClient.Dispose();
|
||||||
|
_process.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test.Helpers
|
||||||
|
{
|
||||||
|
internal class ProcessEx : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Process _process;
|
||||||
|
private readonly StringBuilder _stderrCapture;
|
||||||
|
private readonly StringBuilder _stdoutCapture;
|
||||||
|
private BlockingCollection<string> _stdoutLines;
|
||||||
|
|
||||||
|
public static ProcessEx Run(string workingDirectory, string command, string args = null, IDictionary<string, string> envVars = null)
|
||||||
|
{
|
||||||
|
var startInfo = new ProcessStartInfo(command, args)
|
||||||
|
{
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
WorkingDirectory = workingDirectory
|
||||||
|
};
|
||||||
|
|
||||||
|
if (envVars != null)
|
||||||
|
{
|
||||||
|
foreach (var envVar in envVars)
|
||||||
|
{
|
||||||
|
startInfo.EnvironmentVariables.Add(envVar.Key, envVar.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var proc = Process.Start(startInfo);
|
||||||
|
|
||||||
|
return new ProcessEx(proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessEx(Process proc)
|
||||||
|
{
|
||||||
|
_stdoutCapture = new StringBuilder();
|
||||||
|
_stderrCapture = new StringBuilder();
|
||||||
|
_stdoutLines = new BlockingCollection<string>();
|
||||||
|
|
||||||
|
_process = proc;
|
||||||
|
proc.EnableRaisingEvents = true;
|
||||||
|
proc.OutputDataReceived += OnOutputData;
|
||||||
|
proc.ErrorDataReceived += OnErrorData;
|
||||||
|
proc.Exited += OnProcessExited;
|
||||||
|
proc.BeginOutputReadLine();
|
||||||
|
proc.BeginErrorReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Error => _stderrCapture.ToString();
|
||||||
|
|
||||||
|
public string Output => _stdoutCapture.ToString();
|
||||||
|
|
||||||
|
public int ExitCode => _process.ExitCode;
|
||||||
|
|
||||||
|
private void OnErrorData(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
_stderrCapture.AppendLine(e.Data);
|
||||||
|
Console.Error.WriteLine(e.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOutputData(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
_stdoutCapture.AppendLine(e.Data);
|
||||||
|
Console.WriteLine(e.Data);
|
||||||
|
|
||||||
|
if (_stdoutLines != null)
|
||||||
|
{
|
||||||
|
_stdoutLines.Add(e.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProcessExited(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_stdoutLines.CompleteAdding();
|
||||||
|
_stdoutLines = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WaitForExit(bool assertSuccess)
|
||||||
|
{
|
||||||
|
_process.WaitForExit();
|
||||||
|
|
||||||
|
if (assertSuccess && _process.ExitCode != 0)
|
||||||
|
{
|
||||||
|
throw new Exception($"Process exited with code {_process.ExitCode}\nStdErr: {Error}\nStdOut: {Output}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_process != null && !_process.HasExited)
|
||||||
|
{
|
||||||
|
_process.Kill();
|
||||||
|
_process.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> OutputLinesAsEnumerable => _stdoutLines.GetConsumingEnumerable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using Templates.Test.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test
|
||||||
|
{
|
||||||
|
public class TemplateTestBase : IDisposable
|
||||||
|
{
|
||||||
|
protected string ProjectName { get; set; }
|
||||||
|
protected string TemplateOutputDir { get; private set; }
|
||||||
|
|
||||||
|
public TemplateTestBase()
|
||||||
|
{
|
||||||
|
ProjectName = Guid.NewGuid().ToString().Replace("-", "");
|
||||||
|
|
||||||
|
var assemblyPath = GetType().GetTypeInfo().Assembly.CodeBase;
|
||||||
|
var assemblyUri = new Uri(assemblyPath, UriKind.Absolute);
|
||||||
|
var basePath = Path.GetDirectoryName(assemblyUri.LocalPath);
|
||||||
|
TemplateOutputDir = Path.Combine(basePath, "TestTemplates", ProjectName);
|
||||||
|
Directory.CreateDirectory(TemplateOutputDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InstallTemplatePackages()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RunDotNetNew(string templateName, string targetFrameworkOverride, string auth = null, string language = null)
|
||||||
|
{
|
||||||
|
var args = $"new {templateName}";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
args += $" --target-framework-override {targetFrameworkOverride}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(auth))
|
||||||
|
{
|
||||||
|
args += $" -au {auth}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(language))
|
||||||
|
{
|
||||||
|
args += $" -lang {language}";
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessEx.Run(TemplateOutputDir, "dotnet", args).WaitForExit(assertSuccess: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AssertDirectoryExists(string path, bool shouldExist)
|
||||||
|
{
|
||||||
|
var fullPath = Path.Combine(TemplateOutputDir, path);
|
||||||
|
var doesExist = Directory.Exists(fullPath);
|
||||||
|
|
||||||
|
if (shouldExist)
|
||||||
|
{
|
||||||
|
Assert.True(doesExist, "Expected directory to exist, but it doesn't: " + path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.False(doesExist, "Expected directory not to exist, but it does: " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AssertFileExists(string path, bool shouldExist)
|
||||||
|
{
|
||||||
|
var fullPath = Path.Combine(TemplateOutputDir, path);
|
||||||
|
var doesExist = File.Exists(fullPath);
|
||||||
|
|
||||||
|
if (shouldExist)
|
||||||
|
{
|
||||||
|
Assert.True(doesExist, "Expected file to exist, but it doesn't: " + path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.False(doesExist, "Expected file not to exist, but it does: " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string ReadFile(string path)
|
||||||
|
{
|
||||||
|
AssertFileExists(path, shouldExist: true);
|
||||||
|
return File.ReadAllText(Path.Combine(TemplateOutputDir, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AspNetProcess StartAspNetProcess(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
return new AspNetProcess(TemplateOutputDir, ProjectName, targetFrameworkOverride);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
DeleteOutputDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteOutputDirectory()
|
||||||
|
{
|
||||||
|
var numAttempts = 5;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(TemplateOutputDir, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
numAttempts--;
|
||||||
|
if (numAttempts > 0)
|
||||||
|
{
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test
|
||||||
|
{
|
||||||
|
public class MvcTemplateTest : TemplateTestBase
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(/* netcoreapp */ null, /* C# */ null)]
|
||||||
|
[InlineData("net461", /* C# */ null)]
|
||||||
|
[InlineData(/* netcoreapp */ null, "F#")]
|
||||||
|
[InlineData("net461", "F#")]
|
||||||
|
public void MvcTemplate_NoAuth_Works(string targetFrameworkOverride, string languageOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("mvc", targetFrameworkOverride, language: languageOverride);
|
||||||
|
|
||||||
|
AssertDirectoryExists("Areas", false);
|
||||||
|
AssertDirectoryExists("Extensions", false);
|
||||||
|
AssertFileExists("urlRewrite.config", false);
|
||||||
|
AssertFileExists("Controllers/AccountController.cs", false);
|
||||||
|
|
||||||
|
var projectExtension = languageOverride == "F#" ? "fsproj" : "csproj";
|
||||||
|
var projectFileContents = ReadFile($"{ProjectName}.{projectExtension}");
|
||||||
|
Assert.DoesNotContain(".db", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/");
|
||||||
|
aspNetProcess.AssertOk("/Home/About");
|
||||||
|
aspNetProcess.AssertOk("/Home/Contact");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("net461")]
|
||||||
|
public void MvcTemplate_IndividualAuth_Works(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("mvc", targetFrameworkOverride, auth: "Individual");
|
||||||
|
|
||||||
|
AssertDirectoryExists("Extensions", true);
|
||||||
|
AssertFileExists("urlRewrite.config", false);
|
||||||
|
AssertFileExists("Controllers/AccountController.cs", true);
|
||||||
|
|
||||||
|
var projectFileContents = ReadFile($"{ProjectName}.csproj");
|
||||||
|
Assert.Contains(".db", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.EntityFrameworkCore.Tools", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.Extensions.SecretManager.Tools", projectFileContents);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/");
|
||||||
|
aspNetProcess.AssertOk("/Home/About");
|
||||||
|
aspNetProcess.AssertOk("/Home/Contact");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test
|
||||||
|
{
|
||||||
|
public class RazorPagesTemplateTest : TemplateTestBase
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("net461")]
|
||||||
|
public void RazorPagesTemplate_NoAuth_Works(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("razor", targetFrameworkOverride);
|
||||||
|
|
||||||
|
AssertDirectoryExists("Extensions", false);
|
||||||
|
AssertFileExists("Controllers/AccountController.cs", false);
|
||||||
|
|
||||||
|
var projectFileContents = ReadFile($"{ProjectName}.csproj");
|
||||||
|
Assert.DoesNotContain(".db", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents);
|
||||||
|
Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/");
|
||||||
|
aspNetProcess.AssertOk("/About");
|
||||||
|
aspNetProcess.AssertOk("/Contact");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("net461")]
|
||||||
|
public void RazorPagesTemplate_IndividualAuth_Works(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("razor", targetFrameworkOverride, auth: "Individual");
|
||||||
|
|
||||||
|
AssertDirectoryExists("Extensions", true);
|
||||||
|
AssertFileExists("Controllers/AccountController.cs", true);
|
||||||
|
|
||||||
|
var projectFileContents = ReadFile($"{ProjectName}.csproj");
|
||||||
|
Assert.Contains(".db", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.EntityFrameworkCore.Tools", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents);
|
||||||
|
Assert.Contains("Microsoft.Extensions.SecretManager.Tools", projectFileContents);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/");
|
||||||
|
aspNetProcess.AssertOk("/About");
|
||||||
|
aspNetProcess.AssertOk("/Contact");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Templates.Test
|
||||||
|
{
|
||||||
|
public class WebApiTemplateTest : TemplateTestBase
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("net461")]
|
||||||
|
public void WebApiTemplate_Works(string targetFrameworkOverride)
|
||||||
|
{
|
||||||
|
RunDotNetNew("api", targetFrameworkOverride);
|
||||||
|
|
||||||
|
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
|
||||||
|
{
|
||||||
|
aspNetProcess.AssertOk("/api/values");
|
||||||
|
aspNetProcess.AssertNotFound("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Templates.Test
|
|
||||||
{
|
|
||||||
public class WebTemplateTest
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,304 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
using ProjectTestRunner.Handlers;
|
|
||||||
using ProjectTestRunner.Helpers;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
|
||||||
|
|
||||||
namespace ProjectTestRunner
|
|
||||||
{
|
|
||||||
public class Battery
|
|
||||||
{
|
|
||||||
private static readonly IReadOnlyDictionary<string, IHandler> HandlerLookup = new Dictionary<string, IHandler>
|
|
||||||
{
|
|
||||||
{ ExecuteHandler.Handler, new ExecuteHandler() },
|
|
||||||
{ TaskKillHandler.Handler, new TaskKillHandler() },
|
|
||||||
{ HttpRequestHandler.Handler, new HttpRequestHandler() },
|
|
||||||
{ FindProcessHandler.Handler, new FindProcessHandler() },
|
|
||||||
{ FileInspectHandler.Handler, new FileInspectHandler() },
|
|
||||||
{ DirectoryInspectHandler.Handler, new DirectoryInspectHandler() },
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly string Creator;
|
|
||||||
private static readonly string BasePath;
|
|
||||||
|
|
||||||
static Battery()
|
|
||||||
{
|
|
||||||
string assemblyPath = typeof(Battery).GetTypeInfo().Assembly.CodeBase;
|
|
||||||
Uri assemblyUri = new Uri(assemblyPath, UriKind.Absolute);
|
|
||||||
assemblyPath = assemblyUri.LocalPath;
|
|
||||||
BasePath = Path.GetDirectoryName(assemblyPath);
|
|
||||||
|
|
||||||
Creator = Environment.GetEnvironmentVariable("CREATION_TEST_RUNNER");
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(Creator))
|
|
||||||
{
|
|
||||||
Creator = "new";
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.Run("dotnet", $"--version").WaitForExit();
|
|
||||||
|
|
||||||
Proc.Run("dotnet", $"{Creator} --debug:reinit").WaitForExit();
|
|
||||||
Proc.Run("dotnet", $"{Creator}").WaitForExit();
|
|
||||||
|
|
||||||
string templateFeedDirectory = FindTemplateFeedDirectory(BasePath);
|
|
||||||
Proc.Run("dotnet", $"{Creator} -i \"{templateFeedDirectory}\"").WaitForExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Battery(ITestOutputHelper outputHelper)
|
|
||||||
{
|
|
||||||
Console.SetOut(new OutputHelperHelper(outputHelper));
|
|
||||||
Console.SetError(new OutputHelperHelper(outputHelper));
|
|
||||||
}
|
|
||||||
|
|
||||||
[PrettyTheory, MemberData(nameof(Discover))]
|
|
||||||
public void Run(TemplateTestData testData)
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
string[] allParts = new string[testData.Paths.Length + 2];
|
|
||||||
allParts[0] = BasePath;
|
|
||||||
allParts[1] = "TestCases";
|
|
||||||
|
|
||||||
for (int i = 0; i < testData.Paths.Length; ++i)
|
|
||||||
{
|
|
||||||
allParts[i + 2] = testData.Paths[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
string contents = File.ReadAllText(Path.Combine(allParts));
|
|
||||||
contents = Environment.ExpandEnvironmentVariables(contents);
|
|
||||||
|
|
||||||
JObject json = JObject.Parse(contents);
|
|
||||||
|
|
||||||
if (json["skip"]?.Value<bool>() ?? false)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Test Skipped");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string targetPath = Path.Combine(GetTemplatePath(), "_" + Guid.NewGuid().ToString().Replace("-", ""));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string install = json["install"]?.ToString();
|
|
||||||
string command = testData.CreateCommand;
|
|
||||||
|
|
||||||
Console.WriteLine("Testing: " + testData.Name);
|
|
||||||
Dictionary<string, string> dict = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "targetPath", targetPath},
|
|
||||||
{ "targetPathName", Path.GetFileName(targetPath)},
|
|
||||||
};
|
|
||||||
|
|
||||||
List<IHandlerResult> results = new List<IHandlerResult>();
|
|
||||||
IHandlerResult current;
|
|
||||||
string message;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(install))
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Executing step {(results.Count + 1)} (install)...");
|
|
||||||
current = Install(Creator, install);
|
|
||||||
|
|
||||||
message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}";
|
|
||||||
Console.WriteLine($" {message}");
|
|
||||||
Console.WriteLine(" ");
|
|
||||||
|
|
||||||
if (!current.VerificationSuccess)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
Assert.False(true, current.FailureMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($"Executing step {(results.Count + 1)} (create)...");
|
|
||||||
current = Create(Creator, install, testData.CreateCommand, targetPath);
|
|
||||||
|
|
||||||
message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}";
|
|
||||||
Console.WriteLine($" {message}");
|
|
||||||
Console.WriteLine(" ");
|
|
||||||
|
|
||||||
if (!current.VerificationSuccess)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
Assert.False(true, current.FailureMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
results.Add(current);
|
|
||||||
|
|
||||||
foreach (JObject entry in ((JArray)json["tasks"]).Children().OfType<JObject>())
|
|
||||||
{
|
|
||||||
string handlerKey = entry["handler"].ToString();
|
|
||||||
string variationKey = entry["variation"]?.ToString();
|
|
||||||
|
|
||||||
// running the right variation, or
|
|
||||||
if (string.Equals(testData.Variation, variationKey)
|
|
||||||
|| variationKey == null
|
|
||||||
|| (testData.Variation == null && variationKey.Equals(string.Empty)))
|
|
||||||
{
|
|
||||||
IHandler handler = HandlerLookup[handlerKey];
|
|
||||||
Console.WriteLine($"Executing step {(results.Count + 1)} ({handler.Summarize(dict, entry)})...");
|
|
||||||
current = handler.Execute(dict, results, entry);
|
|
||||||
message = current.VerificationSuccess ? $"PASS ({current.Duration})" : $"FAIL ({current.Duration}): {current.FailureMessage}";
|
|
||||||
Console.WriteLine($" {message}");
|
|
||||||
Console.WriteLine(" ");
|
|
||||||
results.Add(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (IHandlerResult result in results)
|
|
||||||
{
|
|
||||||
success = !success ? success : result.VerificationSuccess;
|
|
||||||
Assert.False(!result.VerificationSuccess, result.FailureMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 5; ++i)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DeleteDirectory(targetPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Thread.Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DeleteDirectory(string directory)
|
|
||||||
{
|
|
||||||
string[] files = Directory.GetFiles(directory);
|
|
||||||
string[] dirs = Directory.GetDirectories(directory);
|
|
||||||
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
|
||||||
File.SetAttributes(file, FileAttributes.Normal);
|
|
||||||
File.Delete(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string dir in dirs)
|
|
||||||
{
|
|
||||||
DeleteDirectory(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory.Delete(directory, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private IHandlerResult Install(string creator, string installPackage)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Process install = Proc.Run("dotnet", $"{creator} -i \"{installPackage}\"");
|
|
||||||
install.WaitForExit();
|
|
||||||
|
|
||||||
if (install.ExitCode != 0)
|
|
||||||
{
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, false, $"\"{installPackage}\" failed to install");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, true, null);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FindTemplateFeedDirectory(string batteryDirectory)
|
|
||||||
{
|
|
||||||
DirectoryInfo currentDirectory = new DirectoryInfo(batteryDirectory);
|
|
||||||
string templateFeed = Path.Combine(currentDirectory.FullName, "template_feed");
|
|
||||||
|
|
||||||
while (!Directory.Exists(templateFeed))
|
|
||||||
{
|
|
||||||
currentDirectory = currentDirectory.Parent;
|
|
||||||
templateFeed = Path.Combine(currentDirectory.FullName, "template_feed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return templateFeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IHandlerResult Create(string creator, string installPackage, string command, string targetPath)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(targetPath);
|
|
||||||
Process create = Proc.Run("dotnet", $"{creator} {command} -o \"{targetPath}\"");
|
|
||||||
create.WaitForExit();
|
|
||||||
|
|
||||||
if (create.ExitCode != 0)
|
|
||||||
{
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, false, $"\"{command}\" failed create");
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory.SetCurrentDirectory(targetPath);
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, true, null);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetTemplatePath()
|
|
||||||
{
|
|
||||||
return Path.Combine(BasePath, "TestTemplates");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<object[]> Discover()
|
|
||||||
{
|
|
||||||
string basePath = Path.Combine(BasePath, "TestCases");
|
|
||||||
|
|
||||||
foreach (string testCase in Directory.EnumerateFiles(basePath, "*.json", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
string contents = File.ReadAllText(Path.Combine(testCase));
|
|
||||||
contents = Environment.ExpandEnvironmentVariables(contents);
|
|
||||||
|
|
||||||
JObject json = JObject.Parse(contents);
|
|
||||||
|
|
||||||
string relPath = testCase.Substring(basePath.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
||||||
|
|
||||||
var data = new TemplateTestData()
|
|
||||||
{
|
|
||||||
Paths = relPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
|
|
||||||
Name = json["name"].ToString(),
|
|
||||||
CreateCommand = json["create"].ToString(),
|
|
||||||
Variation = null
|
|
||||||
};
|
|
||||||
|
|
||||||
yield return new object[] { data };
|
|
||||||
|
|
||||||
if (json["variations"] != null)
|
|
||||||
{
|
|
||||||
foreach (JObject entry in ((JArray)json["variations"]).Children().OfType<JObject>())
|
|
||||||
{
|
|
||||||
var variation = new TemplateTestData()
|
|
||||||
{
|
|
||||||
Paths = relPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
|
|
||||||
Name = entry["name"]?.ToString() ?? data.Name,
|
|
||||||
Variation = entry["id"].ToString(),
|
|
||||||
CreateCommand = entry["create"]?.ToString() ?? data.CreateCommand
|
|
||||||
};
|
|
||||||
yield return new object[] { variation };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.HandlerResults
|
|
||||||
{
|
|
||||||
internal class ExecuteHandlerResult : IHandlerResult
|
|
||||||
{
|
|
||||||
private readonly Process _process;
|
|
||||||
|
|
||||||
public ExecuteHandlerResult(TimeSpan duration, bool verificationSuccess, string failureMessage, Process process = null, string name = null)
|
|
||||||
{
|
|
||||||
Duration = duration;
|
|
||||||
_process = process;
|
|
||||||
Name = name;
|
|
||||||
VerificationSuccess = verificationSuccess;
|
|
||||||
FailureMessage = failureMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool VerificationSuccess { get; }
|
|
||||||
|
|
||||||
public string FailureMessage { get; }
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
public TimeSpan Duration { get; }
|
|
||||||
|
|
||||||
public void Kill()
|
|
||||||
{
|
|
||||||
_process?.Kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.HandlerResults
|
|
||||||
{
|
|
||||||
internal class GenericHandlerResult : IHandlerResult
|
|
||||||
{
|
|
||||||
public GenericHandlerResult(TimeSpan duration, bool verificationSuccess, string failureMessage, string name = null)
|
|
||||||
{
|
|
||||||
Duration = duration;
|
|
||||||
Name = name;
|
|
||||||
VerificationSuccess = verificationSuccess;
|
|
||||||
FailureMessage = failureMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
public bool VerificationSuccess { get; }
|
|
||||||
|
|
||||||
public string FailureMessage { get; }
|
|
||||||
|
|
||||||
public TimeSpan Duration { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.HandlerResults
|
|
||||||
{
|
|
||||||
public interface IHandlerResult
|
|
||||||
{
|
|
||||||
string Name { get; }
|
|
||||||
|
|
||||||
bool VerificationSuccess { get; }
|
|
||||||
|
|
||||||
string FailureMessage { get; }
|
|
||||||
|
|
||||||
TimeSpan Duration { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// directory: rel path to directory
|
|
||||||
// assertion: exists | does_not_exist
|
|
||||||
|
|
||||||
public class DirectoryInspectHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "directoryInspect";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string basePath = tokens["targetPath"];
|
|
||||||
|
|
||||||
string name = json["name"]?.ToString();
|
|
||||||
string directoryName = json["directory"].ToString();
|
|
||||||
string pathToDirectory = Path.Combine(basePath, directoryName);
|
|
||||||
string assertion = json["assertion"].ToString();
|
|
||||||
bool doesDirectoryExist = Directory.Exists(pathToDirectory);
|
|
||||||
|
|
||||||
if (string.Equals(assertion, "exists", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (!doesDirectoryExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected directory {directoryName} to exist, but it did not", name: name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(assertion, "does_not_exist", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (doesDirectoryExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected directory {directoryName} to not exist, but it did", name: name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, true, null);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, false, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
string directoryName = json["directory"].ToString();
|
|
||||||
string assertion = json["assertion"].ToString().ToLowerInvariant().Replace("_", " ");
|
|
||||||
|
|
||||||
return $"Directory inspection - checking if directory \"{directoryName}\" {assertion}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
using ProjectTestRunner.Helpers;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
public class ExecuteHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "execute";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string args = json["args"]?.ToString() ?? string.Empty;
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> entry in tokens)
|
|
||||||
{
|
|
||||||
args = args.Replace($"%{entry.Key}%", entry.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
string command = json["command"].ToString();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> entry in tokens)
|
|
||||||
{
|
|
||||||
command = command.Replace($"%{entry.Key}%", entry.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessEx p = Proc.Run(command, args);
|
|
||||||
string name = json["name"]?.ToString();
|
|
||||||
|
|
||||||
if (json["noExit"]?.Value<bool>() ?? false)
|
|
||||||
{
|
|
||||||
if (p.WaitForExit(json["exitTimeout"]?.Value<int>() ?? 1000))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, "Process exited unexpectedly", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, true, null, p, name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p.WaitForExit();
|
|
||||||
int expectedExitCode = json["exitCode"]?.Value<int>() ?? 0;
|
|
||||||
bool success = expectedExitCode == p.ExitCode;
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Process exited with code {p.ExitCode} instead of {expectedExitCode}", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
JArray expectations = json["expectations"]?.Value<JArray>();
|
|
||||||
|
|
||||||
if(expectations != null)
|
|
||||||
{
|
|
||||||
foreach(JObject expectation in expectations.Children().OfType<JObject>())
|
|
||||||
{
|
|
||||||
string assertion = expectation["assertion"]?.Value<string>()?.ToUpperInvariant();
|
|
||||||
string s;
|
|
||||||
StringComparison c;
|
|
||||||
|
|
||||||
switch (assertion)
|
|
||||||
{
|
|
||||||
case "OUTPUT_CONTAINS":
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if(!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p.Output.IndexOf(s, c) < 0)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to contain \"{s}\" ({c}), but it did not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "OUTPUT_DOES_NOT_CONTAIN":
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if (!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.Output.IndexOf(s, c) > -1)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to NOT contain \"{s}\" ({c}), but it did", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Unkown assertion: {assertion}", name: name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, true, null, name: name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
string args = json["args"]?.ToString() ?? string.Empty;
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> entry in tokens)
|
|
||||||
{
|
|
||||||
args = args.Replace($"%{entry.Key}%", entry.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
string command = json["command"].ToString();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> entry in tokens)
|
|
||||||
{
|
|
||||||
command = command.Replace($"%{entry.Key}%", entry.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"Execute {command} {args}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
// file: rel path to file
|
|
||||||
// Note: For filenames that get modified by the template creation name, use the literal "%targetPathName%".
|
|
||||||
// It gets replaced with the creation name.
|
|
||||||
// Example: "filename": "%targetPathName%.csproj"
|
|
||||||
// expectations:
|
|
||||||
// assertion: exists | does_not_exist | contains | does_not_contain
|
|
||||||
// text: text to check for when using (file_contains | file_does_not_contain)
|
|
||||||
// comparison: a StringComparison enum value
|
|
||||||
|
|
||||||
// Example:
|
|
||||||
// {
|
|
||||||
// "handler": "fileInspect",
|
|
||||||
// "file": "filename"
|
|
||||||
// "expectations": [
|
|
||||||
// {
|
|
||||||
// "assertion": "exists"
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "assertion": "contains",
|
|
||||||
// "text": "netcoreapp1.0",
|
|
||||||
// "comparison": "Ordinal",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "assertion": "does_not_contain",
|
|
||||||
// "text": "TargetFrameworkOverride",
|
|
||||||
// }
|
|
||||||
|
|
||||||
public class FileInspectHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "fileInspect";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string basePath = tokens["targetPath"];
|
|
||||||
string outputName = tokens["targetPathName"];
|
|
||||||
|
|
||||||
string name = json["name"]?.ToString();
|
|
||||||
string filename = json["file"].ToString();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> entry in tokens)
|
|
||||||
{
|
|
||||||
filename = filename.Replace($"%{entry.Key}%", entry.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
string pathToFile = Path.Combine(basePath, filename);
|
|
||||||
bool doesFileExist = File.Exists(pathToFile);
|
|
||||||
|
|
||||||
string fileContent = null;
|
|
||||||
|
|
||||||
JArray expectations = json["expectations"]?.Value<JArray>();
|
|
||||||
|
|
||||||
if (expectations != null)
|
|
||||||
{
|
|
||||||
foreach (JObject expectation in expectations.Children().OfType<JObject>())
|
|
||||||
{
|
|
||||||
string assertion = expectation["assertion"]?.Value<string>()?.ToUpperInvariant();
|
|
||||||
string text;
|
|
||||||
StringComparison comparison;
|
|
||||||
|
|
||||||
switch (assertion)
|
|
||||||
{
|
|
||||||
case "EXISTS":
|
|
||||||
if (!doesFileExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to exist, but it did not", name: name);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "DOES_NOT_EXIST":
|
|
||||||
if (doesFileExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not exist, but it did", name: name);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CONTAINS":
|
|
||||||
text = expectation["text"]?.Value<string>();
|
|
||||||
if (!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out comparison))
|
|
||||||
{
|
|
||||||
comparison = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doesFileExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to contain \"{text}\" ({comparison}), but file did not exist", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContent == null)
|
|
||||||
{
|
|
||||||
fileContent = File.ReadAllText(pathToFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContent.IndexOf(text, comparison) < 0)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to contain \"{text}\" ({comparison}), but it did not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "DOES_NOT_CONTAIN":
|
|
||||||
text = expectation["text"].Value<string>();
|
|
||||||
if (!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out comparison))
|
|
||||||
{
|
|
||||||
comparison = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doesFileExist)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not contain \"{text}\" ({comparison}), but file did not exist", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContent == null)
|
|
||||||
{
|
|
||||||
fileContent = File.ReadAllText(pathToFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContent.IndexOf(text, comparison) >= 0)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected file \"{filename}\" to not contain \"{text}\" ({comparison}), but it did", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, true, null);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, false, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
string filename = json["file"].ToString();
|
|
||||||
|
|
||||||
return $"File Inspection - inspecting file = \"{filename}\"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
public class FindProcessHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "find";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string[] args = json["args"].Values<string>().ToArray();
|
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; ++i)
|
|
||||||
{
|
|
||||||
if (tokens.TryGetValue(args[i].Trim('%'), out string val))
|
|
||||||
{
|
|
||||||
args[i] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string name = json["name"].ToString();
|
|
||||||
Process p = Process.GetProcesses().FirstOrDefault(x =>
|
|
||||||
{
|
|
||||||
ProcessStartInfo info = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
info = x.StartInfo;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return args.All(y => info.Arguments.Contains(y));
|
|
||||||
});
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, p != null, p != null ? null : "Unable to find process", p, name);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
string[] args = json["args"].Values<string>().ToArray();
|
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; ++i)
|
|
||||||
{
|
|
||||||
if (tokens.TryGetValue(args[i].Trim('%'), out string val))
|
|
||||||
{
|
|
||||||
args[i] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"Find process with args [{string.Join(", ", args)}]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
public class HttpRequestHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "httpRequest";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string name = json["name"]?.ToString();
|
|
||||||
string url = json["url"].ToString();
|
|
||||||
int status = json["statusCode"].Value<int>();
|
|
||||||
string verb = json["verb"].ToString();
|
|
||||||
string body = json["body"]?.ToString();
|
|
||||||
string requestMediaType = json["requestMediaType"]?.ToString();
|
|
||||||
string requestEncoding = json["requestEncoding"]?.ToString();
|
|
||||||
|
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
HttpRequestMessage message = new HttpRequestMessage(new HttpMethod(verb), url);
|
|
||||||
|
|
||||||
if (body != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(requestEncoding))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(requestMediaType))
|
|
||||||
{
|
|
||||||
message.Content = new StringContent(body, Encoding.GetEncoding(requestEncoding), requestMediaType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message.Content = new StringContent(body, Encoding.GetEncoding(requestEncoding));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message.Content = new StringContent(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HttpResponseMessage response = client.SendAsync(message).Result;
|
|
||||||
bool success = status == (int)response.StatusCode;
|
|
||||||
string responseText = response.Content.ReadAsStringAsync().Result;
|
|
||||||
|
|
||||||
JArray expectations = json["expectations"]?.Value<JArray>();
|
|
||||||
|
|
||||||
if(expectations != null)
|
|
||||||
{
|
|
||||||
foreach(JObject expectation in expectations.Children().OfType<JObject>())
|
|
||||||
{
|
|
||||||
string assertion = expectation["assertion"]?.Value<string>()?.ToUpperInvariant();
|
|
||||||
string s, key;
|
|
||||||
StringComparison c;
|
|
||||||
IEnumerable<string> values;
|
|
||||||
|
|
||||||
switch (assertion)
|
|
||||||
{
|
|
||||||
case "RESPONSE_CONTAINS":
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if(!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(responseText.IndexOf(s, c) < 0)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to contain \"{s}\" ({c}), but it did not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "RESPONSE_DOES_NOT_CONTAIN":
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if(!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(responseText.IndexOf(s, c) > -1)
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected output to NOT contain \"{s}\" ({c}), but it did", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "RESPONSE_HEADER_CONTAINS":
|
|
||||||
key = expectation["key"]?.Value<string>();
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if(!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!response.Headers.TryGetValues(key, out values))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!values.Any(x => x.IndexOf(s, c) > -1))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to have a value \"{s}\", but it did not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "HAS_HEADER":
|
|
||||||
key = expectation["key"]?.Value<string>();
|
|
||||||
|
|
||||||
if(!response.Headers.TryGetValues(key, out values))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "RESPONSE_HEADER_DOES_NOT_CONTAIN":
|
|
||||||
key = expectation["key"]?.Value<string>();
|
|
||||||
s = expectation["text"]?.Value<string>();
|
|
||||||
if(!Enum.TryParse(expectation["comparison"]?.Value<string>() ?? "OrdinalIgnoreCase", out c))
|
|
||||||
{
|
|
||||||
c = StringComparison.OrdinalIgnoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!response.Headers.TryGetValues(key, out values))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to be present, but it was not", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(values.Any(x => x.IndexOf(s, c) > -1))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to NOT have a value \"{s}\", but it did", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "DOES_NOT_HAVE_HEADER":
|
|
||||||
key = expectation["key"]?.Value<string>();
|
|
||||||
|
|
||||||
if(response.Headers.TryGetValues(key, out values))
|
|
||||||
{
|
|
||||||
return new ExecuteHandlerResult(watch.Elapsed, false, $"Expected a response header called \"{key}\" to NOT be present, but it was", name: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, success, success ? null : $"Expected {status} but got {response.StatusCode}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, false, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
string url = json["url"].ToString();
|
|
||||||
int status = json["statusCode"].Value<int>();
|
|
||||||
string verb = json["verb"].ToString();
|
|
||||||
string body = json["body"]?.ToString();
|
|
||||||
string requestMediaType = json["requestMediaType"]?.ToString();
|
|
||||||
string requestEncoding = json["requestEncoding"]?.ToString();
|
|
||||||
|
|
||||||
return $"Web Request - {verb} {url} (Body? {body != null}, Encoding? {requestEncoding}, MediaType? {requestMediaType}) -> Expect {status}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
public interface IHandler
|
|
||||||
{
|
|
||||||
string HandlerName { get; }
|
|
||||||
|
|
||||||
IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json);
|
|
||||||
|
|
||||||
string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using ProjectTestRunner.HandlerResults;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Handlers
|
|
||||||
{
|
|
||||||
public class TaskKillHandler : IHandler
|
|
||||||
{
|
|
||||||
public static string Handler => "taskkill";
|
|
||||||
|
|
||||||
public string HandlerName => Handler;
|
|
||||||
|
|
||||||
public IHandlerResult Execute(IReadOnlyDictionary<string, string> tokens, IReadOnlyList<IHandlerResult> results, JObject json)
|
|
||||||
{
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string targetName = json["name"].ToString();
|
|
||||||
IHandlerResult result = results.FirstOrDefault(x => x.Name == targetName);
|
|
||||||
if (result is ExecuteHandlerResult xr)
|
|
||||||
{
|
|
||||||
xr.Kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GenericHandlerResult(watch.Elapsed, true, null);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
watch.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Summarize(IReadOnlyDictionary<string, string> tokens, JObject json)
|
|
||||||
{
|
|
||||||
return "Kill process in named step " + json["name"].ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Helpers
|
|
||||||
{
|
|
||||||
internal class OutputHelperHelper : TextWriter
|
|
||||||
{
|
|
||||||
private ITestOutputHelper _outputHelper;
|
|
||||||
|
|
||||||
public OutputHelperHelper(ITestOutputHelper outputHelper)
|
|
||||||
{
|
|
||||||
_outputHelper = outputHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Encoding Encoding => Encoding.UTF8;
|
|
||||||
|
|
||||||
public override void Write(char value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteLine(string format, params object[] arg)
|
|
||||||
{
|
|
||||||
_outputHelper.WriteLine(format, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteLine(string message)
|
|
||||||
{
|
|
||||||
_outputHelper.WriteLine(message ?? "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Helpers
|
|
||||||
{
|
|
||||||
public class PrettyTheoryAttribute : TheoryAttribute
|
|
||||||
{
|
|
||||||
public PrettyTheoryAttribute([CallerMemberName] string memberName = null)
|
|
||||||
{
|
|
||||||
DisplayName = memberName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Helpers
|
|
||||||
{
|
|
||||||
public class Proc
|
|
||||||
{
|
|
||||||
public static ProcessEx Run(string command, string args)
|
|
||||||
{
|
|
||||||
ProcessStartInfo psi = new ProcessStartInfo(command, args)
|
|
||||||
{
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
Process p = Process.Start(psi);
|
|
||||||
ProcessEx wrapper = new ProcessEx(p);
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner.Helpers
|
|
||||||
{
|
|
||||||
public class ProcessEx
|
|
||||||
{
|
|
||||||
private readonly Process _process;
|
|
||||||
private readonly StringBuilder _stderr;
|
|
||||||
private readonly StringBuilder _stdout;
|
|
||||||
|
|
||||||
public ProcessEx(Process p)
|
|
||||||
{
|
|
||||||
_stdout = new StringBuilder();
|
|
||||||
_stderr = new StringBuilder();
|
|
||||||
|
|
||||||
_process = p;
|
|
||||||
p.OutputDataReceived += OnOutputData;
|
|
||||||
p.ErrorDataReceived += OnErrorData;
|
|
||||||
p.BeginOutputReadLine();
|
|
||||||
p.BeginErrorReadLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Error => _stderr.ToString();
|
|
||||||
|
|
||||||
public string Output => _stdout.ToString();
|
|
||||||
|
|
||||||
public int ExitCode => _process.ExitCode;
|
|
||||||
|
|
||||||
public static implicit operator Process(ProcessEx self)
|
|
||||||
{
|
|
||||||
return self._process;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnErrorData(object sender, DataReceivedEventArgs e)
|
|
||||||
{
|
|
||||||
_stderr.AppendLine(e.Data);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine(e.Data);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnOutputData(object sender, DataReceivedEventArgs e)
|
|
||||||
{
|
|
||||||
_stdout.AppendLine(e.Data);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Data);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool WaitForExit(int milliseconds)
|
|
||||||
{
|
|
||||||
return _process.WaitForExit(milliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WaitForExit()
|
|
||||||
{
|
|
||||||
_process.WaitForExit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<packageSources>
|
|
||||||
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
|
|
||||||
</packageSources>
|
|
||||||
</configuration>
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\Templates.Settings.Targets" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
|
||||||
<OutputPath>$(TestFolder)</OutputPath>
|
|
||||||
<IntermediatePath>$(IntermediateFolder)\Test</IntermediatePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170517-02" />
|
|
||||||
<PackageReference Include="xunit" Version="2.2.0" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="TestCases\**\*.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace ProjectTestRunner
|
|
||||||
{
|
|
||||||
public class TemplateTestData : IXunitSerializable
|
|
||||||
{
|
|
||||||
public TemplateTestData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Variation { get; set; }
|
|
||||||
public string CreateCommand { get; set; }
|
|
||||||
public string[] Paths { get; set; }
|
|
||||||
|
|
||||||
public void Deserialize(IXunitSerializationInfo info)
|
|
||||||
{
|
|
||||||
Name = info.GetValue<string>(nameof(Name));
|
|
||||||
Variation = info.GetValue<string>(nameof(Variation));
|
|
||||||
CreateCommand = info.GetValue<string>(nameof(CreateCommand));
|
|
||||||
Paths = info.GetValue<string[]>(nameof(Paths));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Serialize(IXunitSerializationInfo info)
|
|
||||||
{
|
|
||||||
info.AddValue(nameof(Name), Name, typeof(string));
|
|
||||||
info.AddValue(nameof(Variation), Variation, typeof(string));
|
|
||||||
info.AddValue(nameof(CreateCommand), CreateCommand, typeof(string));
|
|
||||||
info.AddValue(nameof(Paths), Paths, typeof(string[]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
{
|
|
||||||
"create": "mvc --no-restore",
|
|
||||||
"name": "MVC (C#, default framework, default auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "MVC (C#, net461 framework, default auth)",
|
|
||||||
"create": "mvc --target-framework-override net461 --no-restore "
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "directoryInspect",
|
|
||||||
"directory": "Areas",
|
|
||||||
"assertion": "does_not_exist"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "directoryInspect",
|
|
||||||
"directory": "Extensions",
|
|
||||||
"assertion": "does_not_exist"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "urlRewrite.config",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "does_not_exist"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "Controllers/AccountController.cs",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "does_not_exist"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "%targetPathName%.csproj",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "exists"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "does_not_contain",
|
|
||||||
"text": ".db"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "does_not_contain",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "does_not_contain",
|
|
||||||
"text": "Microsoft.VisualStudio.Web.CodeGeneration.Design"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "does_not_contain",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools.DotNet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "does_not_contain",
|
|
||||||
"text": "Microsoft.Extensions.SecretManager.Tools"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/About",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/Contact",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
{
|
|
||||||
"create": "mvc -au Individual --KestrelPort 5000 --no-restore",
|
|
||||||
"name": "MVC (C#, default framework, local individual auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "MVC (C#, net461 framework, local individual auth)",
|
|
||||||
"create": "mvc -au Individual --KestrelPort 5000 --target-framework-override net461 --no-restore"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "directoryInspect",
|
|
||||||
"directory": "Extensions",
|
|
||||||
"assertion": "exists"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "Controllers/AccountController.cs",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "exists"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "%targetPathName%.csproj",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "exists"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": ".db"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.VisualStudio.Web.CodeGeneration.Design"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools.DotNet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.Extensions.SecretManager.Tools"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/About",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/Contact",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
{
|
|
||||||
"create": "razor --no-restore",
|
|
||||||
"name": "Razor Pages (C#, default framework, default auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "Razor Pages (C#, net461 framework, default auth)",
|
|
||||||
"create": "razor --target-framework-override net461 --no-restore "
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/About",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Contact",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
{
|
|
||||||
"create": "razor -au Individual --KestrelPort 5000 --no-restore",
|
|
||||||
"name": "Razor Pages (C#, default framework, local individual auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "Razor Pages (C#, net461 framework, local individual auth)",
|
|
||||||
"create": "razor -au Individual --KestrelPort 5000 --target-framework-override net461 --no-restore"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "directoryInspect",
|
|
||||||
"directory": "Extensions",
|
|
||||||
"assertion": "exists"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "Controllers/AccountController.cs",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "exists"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "fileInspect",
|
|
||||||
"file": "%targetPathName%.csproj",
|
|
||||||
"expectations": [
|
|
||||||
{
|
|
||||||
"assertion": "exists"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": ".db"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.VisualStudio.Web.CodeGeneration.Design"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.EntityFrameworkCore.Tools.DotNet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assertion": "contains",
|
|
||||||
"text": "Microsoft.Extensions.SecretManager.Tools"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/About",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Contact",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
{
|
|
||||||
"create": "web --no-restore",
|
|
||||||
"name": "Empty Web (C#, default framework, default auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "Empty Web (C#, net461 framework, default auth)",
|
|
||||||
"create": "web --target-framework-override net461 --no-restore "
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
{
|
|
||||||
"create": "api --no-restore",
|
|
||||||
"name": "WebAPI (C#, default framework, default auth)",
|
|
||||||
"variations": [
|
|
||||||
{
|
|
||||||
"id": "fullFramework",
|
|
||||||
"name": "WebAPI (C#, net461 framework, default auth)",
|
|
||||||
"create": "api --target-framework-override net461 --no-restore"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"variation": "fullFramework",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "bin/Debug/net461/%targetPathName%.exe",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/api/values",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 404,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"create": "mvc --language F# --no-restore",
|
|
||||||
"name": "MVC (F#, default framework, default auth)",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "restore -s https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json -s https://dotnet.myget.org/F/msbuild/api/v3/index.json -s https://api.nuget.org/v3/index.json",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "build -c Debug",
|
|
||||||
"noExit": false,
|
|
||||||
"exitCode": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RunApp",
|
|
||||||
"handler": "execute",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": "exec bin/Debug/netcoreapp2.0/%targetPathName%.dll",
|
|
||||||
"noExit": true,
|
|
||||||
"exitTimeout": 5000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/About",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "httpRequest",
|
|
||||||
"url": "http://localhost:5000/Home/Contact",
|
|
||||||
"statusCode": 200,
|
|
||||||
"verb": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"handler": "taskkill",
|
|
||||||
"name": "RunApp"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue