Fix using custom PHPUnit extension in older versions
This commit is contained in:
Родитель
632e4ccbe9
Коммит
835a97ac41
|
@ -34,5 +34,20 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
return assemblyDir;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a file name in the given directory with the given prefix which
|
||||
/// does not exists in it yet.
|
||||
/// </summary>
|
||||
public static string GetNonexistingFilePath(string dir, string prefix = "")
|
||||
{
|
||||
string filePath;
|
||||
do
|
||||
{
|
||||
filePath = Path.Combine(dir, prefix + Path.GetRandomFileName());
|
||||
} while (File.Exists(filePath));
|
||||
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using PHPUnit.Framework;
|
|||
using PHPUnit.TextUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
|
@ -14,6 +15,11 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
/// </summary>
|
||||
internal static class PhpUnitHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Current PHPUnit version.
|
||||
/// </summary>
|
||||
public static Version Version { get; } = typeof(TestCase).Assembly.GetName().Version;
|
||||
|
||||
private const string PharName = "phpunit.phar";
|
||||
|
||||
static PhpUnitHelper()
|
||||
|
@ -22,10 +28,30 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
Context.AddScriptReference(typeof(TestCase).Assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a PHPUnit configuration file in the given directory, return <c>null</c> if not present.
|
||||
/// </summary>
|
||||
public static string TryFindConfigFile(string dir)
|
||||
{
|
||||
string primaryConfig = Path.Combine(dir, "phpunit.xml");
|
||||
if (File.Exists(primaryConfig))
|
||||
{
|
||||
return primaryConfig;
|
||||
}
|
||||
|
||||
string secondaryConfig = Path.Combine(dir, "phpunit.xml.dist");
|
||||
if (File.Exists(secondaryConfig))
|
||||
{
|
||||
return secondaryConfig;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run PHPUnit on the given assembly and command line arguments.
|
||||
/// </summary>
|
||||
public static void Launch(string cwd, string testedAssembly, string[] args, Action<Context> initCalblack = null, Action<Context> finishCallback = null)
|
||||
public static void Launch(string cwd, string testedAssembly, string[] args, Action<Context> initCallback = null, Action<Context> finishCallback = null)
|
||||
{
|
||||
// Load assembly with tests (if not loaded yet)
|
||||
Context.AddScriptReference(Assembly.LoadFrom(testedAssembly));
|
||||
|
@ -39,7 +65,7 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
ctx.Server[CommonPhpArrayKeys.SCRIPT_NAME] = "__DUMMY_INVALID_FILE";
|
||||
|
||||
// Perform any custom operations on the context
|
||||
initCalblack?.Invoke(ctx);
|
||||
initCallback?.Invoke(ctx);
|
||||
|
||||
// Run the PHAR entry point so that all the classes are included
|
||||
var pharLoader = Context.TryGetDeclaredScript(PharName);
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
|
||||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
|
||||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
|
||||
using Pchp.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Peachpied.PhpUnit.TestAdapter
|
||||
{
|
||||
|
@ -44,8 +48,7 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
{
|
||||
try
|
||||
{
|
||||
// Inject our custom extension to report the test results
|
||||
var args = new[] { "--extensions", TestReporterExtension.PhpName };
|
||||
var args = Array.Empty<string>();
|
||||
|
||||
// Optionally filter the test cases by their names
|
||||
if (testCases != null)
|
||||
|
@ -62,7 +65,8 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
|
||||
string projectDir = EnvironmentHelper.TryFindProjectDirectory(Path.GetDirectoryName(source));
|
||||
|
||||
PhpUnitHelper.Launch(projectDir, source, args,
|
||||
// Inject our custom extension to report the test results
|
||||
RunPhpUnitWithExtension(projectDir, source, args,
|
||||
ctx =>
|
||||
{
|
||||
// Enable Peachpie to create an instance of our custom extension
|
||||
|
@ -79,6 +83,52 @@ namespace Peachpied.PhpUnit.TestAdapter
|
|||
}
|
||||
}
|
||||
|
||||
private void RunPhpUnitWithExtension(string projectDir, string source, string[] args, Action<Context> initCallback)
|
||||
{
|
||||
if (PhpUnitHelper.Version >= new Version(9, 1))
|
||||
{
|
||||
// The --extensions CLI argument is available from PHPUnit 9.1 (although it's documented only from 9.3)
|
||||
args = new[] { "--extensions", TestReporterExtension.PhpName }.Concat(args).ToArray();
|
||||
PhpUnitHelper.Launch(projectDir, source, args, initCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Older PHPUnit versions can receive extensions only in the configuration file,
|
||||
// so we need to create a modified version of the existing one and pass it to PHPUnit.
|
||||
// (or create one from scratch it if it doesn't exist at all)
|
||||
|
||||
// Create PHPUnit configuration with the extension added
|
||||
string origConfigFile = PhpUnitHelper.TryFindConfigFile(projectDir);
|
||||
var configXml = (origConfigFile != null) ? XElement.Load(origConfigFile) : new XElement("phpunit");
|
||||
var extensionsEl = configXml.GetOrCreateElement("extensions");
|
||||
extensionsEl.Add(new XElement("extension", new XAttribute("class", TestReporterExtension.PhpName)));
|
||||
|
||||
// Store the configuration in a temporary file to pass it to PHPUnit
|
||||
string tempConfigFile = null;
|
||||
try
|
||||
{
|
||||
// The configuration file must be in the same folder as the project in order to work (to load PHP classes properly etc.)
|
||||
tempConfigFile = EnvironmentHelper.GetNonexistingFilePath(projectDir, "phpunit.xml.");
|
||||
|
||||
// Save the config file without the BOM
|
||||
using (var xmlWriter = new XmlTextWriter(tempConfigFile, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)))
|
||||
{
|
||||
configXml.Save(xmlWriter);
|
||||
}
|
||||
|
||||
args = new[] { "--configuration", tempConfigFile }.Concat(args).ToArray();
|
||||
PhpUnitHelper.Launch(projectDir, source, args, initCallback);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(tempConfigFile))
|
||||
{
|
||||
File.Delete(tempConfigFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel test execution, currently ignored.
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Peachpied.PhpUnit.TestAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// LINQ to XML utility methods.
|
||||
/// </summary>
|
||||
internal static class XElementExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve the child element of the given name if it exists, or add an empty new one if it doesn't exist.
|
||||
/// </summary>
|
||||
public static XElement GetOrCreateElement(this XElement parent, XName elementName)
|
||||
{
|
||||
var element = parent.Element(elementName);
|
||||
if (element == null)
|
||||
{
|
||||
element = new XElement(elementName);
|
||||
parent.Add(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче