Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only un-escape unicode character encoding color codes Fix #1124 #1147

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs
Expand Up @@ -127,7 +127,7 @@ protected NUnitTestEvent(XmlNode node) : base(node)

public string MethodName => Node.GetAttribute("methodname");
public string ClassName => Node.GetAttribute("classname");
public string Output => Node.SelectSingleNode("output")?.InnerText.UnEscapeUnicodeCharacters();
public string Output => Node.SelectSingleNode("output")?.InnerText.UnEscapeUnicodeColorCodesCharacters();


public CheckedTime StartTime()
Expand Down Expand Up @@ -165,7 +165,7 @@ public IEnumerable<NUnitAttachment> NUnitAttachments
foreach (XmlNode attachment in Node.SelectNodes("attachments/attachment"))
{
var path = attachment.SelectSingleNode("filePath")?.InnerText ?? string.Empty;
var description = attachment.SelectSingleNode("description")?.InnerText.UnEscapeUnicodeCharacters();
var description = attachment.SelectSingleNode("description")?.InnerText.UnEscapeUnicodeColorCodesCharacters();
nUnitAttachments.Add(new NUnitAttachment(path, description));
}
return nUnitAttachments;
Expand Down
Expand Up @@ -28,10 +28,10 @@ public NUnitTestEventSuiteFinished(XmlNode node) : base(node)
var failureNode = Node.SelectSingleNode("failure");
if (failureNode != null)
{
FailureMessage = failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeCharacters();
StackTrace = failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeCharacters();
FailureMessage = failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeColorCodesCharacters();
StackTrace = failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeColorCodesCharacters();
}
ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeCharacters();
ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeColorCodesCharacters();
}

public string ReasonMessage { get; }
Expand Down
8 changes: 4 additions & 4 deletions src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestCase.cs
Expand Up @@ -48,11 +48,11 @@ public NUnitTestEventTestCase(XmlNode node)
if (failureNode != null)
{
Failure = new NUnitFailure(
failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeCharacters(),
failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeCharacters());
failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeColorCodesCharacters(),
failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeColorCodesCharacters());
}

ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeCharacters();
ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeColorCodesCharacters();
}
public string ReasonMessage { get; }

Expand All @@ -73,7 +73,7 @@ public string StackTrace
int i = 1;
foreach (XmlNode assertionStacktraceNode in Node.SelectNodes("assertions/assertion/stack-trace"))
{
stackTrace += $"{i++}) " + assertionStacktraceNode.InnerText.UnEscapeUnicodeCharacters();
stackTrace += $"{i++}) " + assertionStacktraceNode.InnerText.UnEscapeUnicodeColorCodesCharacters();
stackTrace += "\n";
}

Expand Down
44 changes: 42 additions & 2 deletions src/NUnitTestAdapter/NUnitEngine/UnicodeEscapeHelper.cs
Expand Up @@ -6,7 +6,9 @@ namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
{
internal static class UnicodeEscapeHelper
{
public static string UnEscapeUnicodeCharacters(this string text)
private const int EscapeAsciiValue = 0x1B;

public static string UnEscapeUnicodeColorCodesCharacters(this string text)
{
if (text == null)
return null;
Expand Down Expand Up @@ -43,14 +45,52 @@ private static bool TryUnEscapeOneCharacter(string text, int position, out char
if (position + unicodeEscapeSample.Length >= text.Length)
return false;


extraCharacterRead = unicodeEscapeSample.Length;
if (!int.TryParse(text.Substring(position + 2, unicodeEscapeSample.Length - 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var escapeValue))
return false;

// Here we only want to escape color escape character when used in a context of a ANSI color code
// See https://github.com/nunit/nunit3-vs-adapter/issues/1124 for more information.
if (escapeValue != EscapeAsciiValue)
return false;

if (!IsAnsiColorCodeSequence(text, position + extraCharacterRead + 1))
return false;

escapedChar = (char)escapeValue;

return true;
}

private static bool IsAnsiColorCodeSequence(string text, int position)
{
var start = false;
while (position < text.Length)
{
var c = text[position++];
// Look for the begining [
if (c == '[' && !start)
{
start = true;
continue;
}

// Found the 'm' at the end
if (c == 'm' && start)
return true;

// [ was not found
if (!start)
return false;

// Ignore all number and ;
var isDigit = c is >= '0' and <= '9';
if (!isDigit && c != ';')
return false;
}

// At the end without the ending 'm'
return false;
}
}
}
Expand Up @@ -5,15 +5,18 @@ namespace NUnit.VisualStudio.TestAdapter.Tests.NUnitEngineTests
{
public class UnicodeEscapeHelperTests
{
[TestCase("\\u001b", "\u001b")]
[TestCase("\\u001b", "\\u001b")]
[TestCase("\\u001", "\\u001")]
[TestCase("\\u01", "\\u01")]
[TestCase("\\u1", "\\u1")]
[TestCase("\\u001b6", "\u001b6")]
[TestCase("\\u001b6", "\\u001b6")]
[TestCase("\\u001b[0m", "\u001b[0m")]
[TestCase("\\u001b[36m", "\u001b[36m")]
[TestCase("\\u001b[48;5;122mTest", "\u001b[48;5;122mTest")]
[TestCase("some-text", "some-text")]
public void UnEscapeUnicodeCharacters_ShouldReplaceBackslashU(string value, string expected)
public void UnEscapeUnicodeColorCodesCharactersShouldReplaceBackslashU(string value, string expected)
{
Assert.That(value.UnEscapeUnicodeCharacters(), Is.EqualTo(expected));
Assert.That(value.UnEscapeUnicodeColorCodesCharacters(), Is.EqualTo(expected));
}
}
}