Skip to content
This repository was archived by the owner on Dec 12, 2017. It is now read-only.

Commit 34b685e

Browse files
committed
Escape control chars in strings
Causes issues with xml serialisation of messages between ReSharper and the external test runner. This was already handled by xunit1, since it used xml to serialise between AppDomains. Serialises interfaces and raw strings now, so no longer needs to escape strings. Fixes #10
1 parent 3bd4d2b commit 34b685e

File tree

8 files changed

+109
-2
lines changed

8 files changed

+109
-2
lines changed

resharper/src/xunitcontrib.runner.resharper.provider/UnitTestElementFactory.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using JetBrains.ReSharper.UnitTestFramework.Elements;
88
using Xunit.Sdk;
99
using JetBrains.Util;
10+
using XunitContrib.Runner.ReSharper.RemoteRunner;
1011

1112
namespace XunitContrib.Runner.ReSharper.UnitTestProvider
1213
{
@@ -143,7 +144,8 @@ public XunitTestTheoryElement GetOrCreateTestTheory(IProject project, XunitTestM
143144
private static string GetTestTheoryShortName(string theoryName, XunitTestMethodElement methodElement)
144145
{
145146
var prefix = methodElement.TypeName.FullName + ".";
146-
return theoryName.StartsWith(prefix) ? theoryName.Substring(prefix.Length) : theoryName;
147+
var name = theoryName.StartsWith(prefix) ? theoryName.Substring(prefix.Length) : theoryName;
148+
return DisplayNameUtil.Escape(name);
147149
}
148150

149151
private static string GetTestTheoryId(XunitTestMethodElement methodElement, string shortName)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace XunitContrib.Runner.ReSharper.RemoteRunner
5+
{
6+
public class DisplayNameUtil
7+
{
8+
public static string Escape(string name)
9+
{
10+
var sb = new StringBuilder();
11+
foreach (var c in name)
12+
sb.Append(EscapeControlChar(c));
13+
14+
return sb.ToString();
15+
}
16+
17+
private static string EscapeControlChar(char c)
18+
{
19+
switch (c)
20+
{
21+
case '\0':
22+
return "\\0";
23+
case '\a':
24+
return "\\a";
25+
case '\b':
26+
return "\\b";
27+
case '\f':
28+
return "\\f";
29+
case '\n':
30+
return "\\n";
31+
case '\r':
32+
return "\\r";
33+
case '\t':
34+
return "\\t";
35+
case '\v':
36+
return "\\v";
37+
38+
case '\x0085':
39+
case '\x2028':
40+
case '\x2029':
41+
return string.Format("\\x{0:X4}", (ushort)c);
42+
43+
default:
44+
return char.IsControl(c) || (ushort)c > 128
45+
? String.Format("\\x{0:X4}", (ushort)c)
46+
: c.ToString();
47+
}
48+
}
49+
}
50+
}

resharper/src/xunitcontrib.runner.resharper.runner/TaskProvider.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ public TheoryTaskInfo GetTheoryTask(string name, string type, string method)
102102
private static string GetTheoryShortName(string name, string type)
103103
{
104104
var prefix = type + ".";
105-
return name.StartsWith(prefix) ? name.Substring(prefix.Length) : name;
105+
var shortName = name.StartsWith(prefix) ? name.Substring(prefix.Length) : name;
106+
return DisplayNameUtil.Escape(shortName);
106107
}
107108

108109
private static bool IsTheory(string name, string type, string method)

resharper/src/xunitcontrib.runner.resharper.runner/xunitcontrib.runner.resharper.runner.8.2.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<Link>Properties\ProductInfo.ReSharper.8.2.cs</Link>
5656
</Compile>
5757
<Compile Include="AttributeNames.cs" />
58+
<Compile Include="DisplayNameUtil.cs" />
5859
<Compile Include="ISetTempFolderPathStrategy.cs" />
5960
<Compile Include="ISimpleClientController.cs" />
6061
<Compile Include="ISimpleRemoteTaskServer.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Xunit;
2+
using Xunit.Extensions;
3+
4+
namespace Foo
5+
{
6+
public class PassingTheory
7+
{
8+
[Theory]
9+
[InlineData("$ \\ \b \f \n \r \t \v")]
10+
public void TestMethod(string value)
11+
{
12+
}
13+
}
14+
}
15+
16+
// xunit2 doesn't define Xunit.Extensions
17+
namespace Xunit.Extensions
18+
{
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<task-start />
2+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" /></task-start>
3+
<cache-folder />
4+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /></task-start>
5+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /></task-start>
6+
<task-create><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \x8 \xC \n \r \t \xB&quot;)" /></task-create>
7+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \x8 \xC \n \r \t \xB&quot;)" /></task-start>
8+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \x8 \xC \n \r \t \xB&quot;)" /></task-duration>
9+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \x8 \xC \n \r \t \xB&quot;)" /><message /></task-finish>
10+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /></task-duration>
11+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /><message /></task-finish>
12+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /></task-duration>
13+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /><message /></task-finish>
14+
<task-finish result="Success" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<task-start />
2+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" /></task-start>
3+
<cache-folder />
4+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /></task-start>
5+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /></task-start>
6+
<task-create><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \b \f \n \r \t \v&quot;)" /></task-create>
7+
<task-start><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \b \f \n \r \t \v&quot;)" /></task-start>
8+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \b \f \n \r \t \v&quot;)" /></task-duration>
9+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" TheoryName="TestMethod(value: &quot;$ \ \b \f \n \r \t \v&quot;)" /><message /></task-finish>
10+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /></task-duration>
11+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" MethodName="TestMethod" Explicitly="False" Dynamic="False" /><message /></task-finish>
12+
<task-duration><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /></task-duration>
13+
<task-finish result="Success"><task runnerID="xUnit" ProjectId="697F5F53-AEB2-4284-AA79-90E7368C55E6" TypeName="Foo.PassingTheory" Explicitly="False" /><message /></task-finish>
14+
<task-finish result="Success" />

resharper/test/src/tests/AcceptanceTests/Runner/OrderedFactGoldTests.cs

+6
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,11 @@ public void TestAmbiguouslyNamedTestMethods()
4646
// TODO: This misses a test to continue running next class. Ordering.
4747
DoOneTestWithStrictOrdering("AmbiguouslyNamedTestMethods");
4848
}
49+
50+
[Test]
51+
public void TestEscapedStringsInDataAttributes()
52+
{
53+
DoOneTestWithStrictOrdering("EscapedDataAttributeStrings");
54+
}
4955
}
5056
}

0 commit comments

Comments
 (0)