From 34b685ea8d9dc2a10c2ab2a00349c81376d821ca Mon Sep 17 00:00:00 2001 From: Matt Ellis Date: Wed, 23 Jul 2014 16:00:17 +0100 Subject: [PATCH] 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 --- .../UnitTestElementFactory.cs | 4 +- .../DisplayNameUtil.cs | 50 +++++++++++++++++++ .../TaskProvider.cs | 3 +- ...contrib.runner.resharper.runner.8.2.csproj | 1 + .../Gold/EscapedDataAttributeStrings.cs | 19 +++++++ ...scapedDataAttributeStrings.xunit1.dll.gold | 14 ++++++ ...scapedDataAttributeStrings.xunit2.dll.gold | 14 ++++++ .../Runner/OrderedFactGoldTests.cs | 6 +++ 8 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 resharper/src/xunitcontrib.runner.resharper.runner/DisplayNameUtil.cs create mode 100644 resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.cs create mode 100644 resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit1.dll.gold create mode 100644 resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit2.dll.gold diff --git a/resharper/src/xunitcontrib.runner.resharper.provider/UnitTestElementFactory.cs b/resharper/src/xunitcontrib.runner.resharper.provider/UnitTestElementFactory.cs index 0e90ad9..66f51cf 100644 --- a/resharper/src/xunitcontrib.runner.resharper.provider/UnitTestElementFactory.cs +++ b/resharper/src/xunitcontrib.runner.resharper.provider/UnitTestElementFactory.cs @@ -7,6 +7,7 @@ using JetBrains.ReSharper.UnitTestFramework.Elements; using Xunit.Sdk; using JetBrains.Util; +using XunitContrib.Runner.ReSharper.RemoteRunner; namespace XunitContrib.Runner.ReSharper.UnitTestProvider { @@ -143,7 +144,8 @@ public XunitTestTheoryElement GetOrCreateTestTheory(IProject project, XunitTestM private static string GetTestTheoryShortName(string theoryName, XunitTestMethodElement methodElement) { var prefix = methodElement.TypeName.FullName + "."; - return theoryName.StartsWith(prefix) ? theoryName.Substring(prefix.Length) : theoryName; + var name = theoryName.StartsWith(prefix) ? theoryName.Substring(prefix.Length) : theoryName; + return DisplayNameUtil.Escape(name); } private static string GetTestTheoryId(XunitTestMethodElement methodElement, string shortName) diff --git a/resharper/src/xunitcontrib.runner.resharper.runner/DisplayNameUtil.cs b/resharper/src/xunitcontrib.runner.resharper.runner/DisplayNameUtil.cs new file mode 100644 index 0000000..fe5aba4 --- /dev/null +++ b/resharper/src/xunitcontrib.runner.resharper.runner/DisplayNameUtil.cs @@ -0,0 +1,50 @@ +using System; +using System.Text; + +namespace XunitContrib.Runner.ReSharper.RemoteRunner +{ + public class DisplayNameUtil + { + public static string Escape(string name) + { + var sb = new StringBuilder(); + foreach (var c in name) + sb.Append(EscapeControlChar(c)); + + return sb.ToString(); + } + + private static string EscapeControlChar(char c) + { + switch (c) + { + case '\0': + return "\\0"; + case '\a': + return "\\a"; + case '\b': + return "\\b"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + case '\v': + return "\\v"; + + case '\x0085': + case '\x2028': + case '\x2029': + return string.Format("\\x{0:X4}", (ushort)c); + + default: + return char.IsControl(c) || (ushort)c > 128 + ? String.Format("\\x{0:X4}", (ushort)c) + : c.ToString(); + } + } + } +} \ No newline at end of file diff --git a/resharper/src/xunitcontrib.runner.resharper.runner/TaskProvider.cs b/resharper/src/xunitcontrib.runner.resharper.runner/TaskProvider.cs index 8a3e9ca..141a89d 100644 --- a/resharper/src/xunitcontrib.runner.resharper.runner/TaskProvider.cs +++ b/resharper/src/xunitcontrib.runner.resharper.runner/TaskProvider.cs @@ -102,7 +102,8 @@ public TheoryTaskInfo GetTheoryTask(string name, string type, string method) private static string GetTheoryShortName(string name, string type) { var prefix = type + "."; - return name.StartsWith(prefix) ? name.Substring(prefix.Length) : name; + var shortName = name.StartsWith(prefix) ? name.Substring(prefix.Length) : name; + return DisplayNameUtil.Escape(shortName); } private static bool IsTheory(string name, string type, string method) diff --git a/resharper/src/xunitcontrib.runner.resharper.runner/xunitcontrib.runner.resharper.runner.8.2.csproj b/resharper/src/xunitcontrib.runner.resharper.runner/xunitcontrib.runner.resharper.runner.8.2.csproj index a0e89d0..34f7a82 100644 --- a/resharper/src/xunitcontrib.runner.resharper.runner/xunitcontrib.runner.resharper.runner.8.2.csproj +++ b/resharper/src/xunitcontrib.runner.resharper.runner/xunitcontrib.runner.resharper.runner.8.2.csproj @@ -55,6 +55,7 @@ Properties\ProductInfo.ReSharper.8.2.cs + diff --git a/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.cs b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.cs new file mode 100644 index 0000000..3563465 --- /dev/null +++ b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.cs @@ -0,0 +1,19 @@ +using Xunit; +using Xunit.Extensions; + +namespace Foo +{ + public class PassingTheory + { + [Theory] + [InlineData("$ \\ \b \f \n \r \t \v")] + public void TestMethod(string value) + { + } + } +} + +// xunit2 doesn't define Xunit.Extensions +namespace Xunit.Extensions +{ +} diff --git a/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit1.dll.gold b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit1.dll.gold new file mode 100644 index 0000000..dcfb1dd --- /dev/null +++ b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit1.dll.gold @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit2.dll.gold b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit2.dll.gold new file mode 100644 index 0000000..c625ac0 --- /dev/null +++ b/resharper/test/data/Runner/Gold/EscapedDataAttributeStrings.xunit2.dll.gold @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resharper/test/src/tests/AcceptanceTests/Runner/OrderedFactGoldTests.cs b/resharper/test/src/tests/AcceptanceTests/Runner/OrderedFactGoldTests.cs index 6896d01..34ec409 100644 --- a/resharper/test/src/tests/AcceptanceTests/Runner/OrderedFactGoldTests.cs +++ b/resharper/test/src/tests/AcceptanceTests/Runner/OrderedFactGoldTests.cs @@ -46,5 +46,11 @@ public void TestAmbiguouslyNamedTestMethods() // TODO: This misses a test to continue running next class. Ordering. DoOneTestWithStrictOrdering("AmbiguouslyNamedTestMethods"); } + + [Test] + public void TestEscapedStringsInDataAttributes() + { + DoOneTestWithStrictOrdering("EscapedDataAttributeStrings"); + } } } \ No newline at end of file