diff --git a/src/JUnit.Xml.TestLogger/TestCaseNameParser.cs b/src/JUnit.Xml.TestLogger/TestCaseNameParser.cs index 77072a5..9cf126b 100644 --- a/src/JUnit.Xml.TestLogger/TestCaseNameParser.cs +++ b/src/JUnit.Xml.TestLogger/TestCaseNameParser.cs @@ -56,6 +56,7 @@ public static ParsedName Parse(string fullyQualifedName) var step = NameParseStep.FindMethod; var state = NameParseState.Default; + var parenthesisCount = 0; var output = new List(); @@ -71,13 +72,18 @@ public static ParsedName Parse(string fullyQualifedName) } else if (state == NameParseState.Default) { - if (thisChar == '(' || thisChar == '"' || thisChar == '\\') + if (thisChar == '(') + { + parenthesisCount--; + } + + if (thisChar == '"' || thisChar == '\\') { throw new Exception("Found invalid characters"); } else if (thisChar == ')') { - if (output.Count > 0) + if ((output.Count > 0) && (parenthesisCount == 0)) { throw new Exception("The closing parenthesis we detected wouldn't be the last character in the output string. This isn't acceptable because we aren't in a string"); } @@ -123,9 +129,9 @@ public static ParsedName Parse(string fullyQualifedName) } else if (state == NameParseState.Parenthesis) { - if (thisChar == ')' || thisChar == '\\') + if (thisChar == ')') { - throw new Exception("Found invalid characters"); + parenthesisCount++; } if (thisChar == '(') @@ -157,6 +163,11 @@ public static ParsedName Parse(string fullyQualifedName) } } + if (parenthesisCount != 0) + { + throw new Exception($"Unbalanced count of parentheses found ({parenthesisCount})"); + } + // We are done. If we are finding type, set that variable. // Otherwise, ther was some issue, so leave the type blank. if (step == NameParseStep.FindNamespace) @@ -211,4 +222,4 @@ public ParsedName(string namespaceName, string typeName, string methodName) public string MethodName { get; } } } -} +} \ No newline at end of file diff --git a/test/JUnit.Xml.TestLogger.UnitTests/TestCaseNameParserTests.cs b/test/JUnit.Xml.TestLogger.UnitTests/TestCaseNameParserTests.cs index 8f94457..f2d8f18 100644 --- a/test/JUnit.Xml.TestLogger.UnitTests/TestCaseNameParserTests.cs +++ b/test/JUnit.Xml.TestLogger.UnitTests/TestCaseNameParserTests.cs @@ -27,10 +27,17 @@ public class TestCaseNameParserTests // Tests with longer type and method names [DataRow("z.y.x.ape.bar(\"ar.g\",\"\\\"\")", "z.y.x", "ape", "bar(\"ar.g\",\"\\\"\")")] [DataRow("z.y.x.ape.bar(\"ar.g\",\")(\")", "z.y.x", "ape", "bar(\"ar.g\",\")(\")")] + + // See nunit.testlogger #66. + [DataRow("z.y.x.ape.bar(a\\b)", "z.y.x", "ape", "bar(a\\b)")] + + // Test with tuple arguments + [DataRow("z.a.b((0,1))", "z", "a", "b((0,1))")] + [DataRow("z.a.b((\"arg\",1))", "z", "a", "b((\"arg\",1))")] + [DataRow("z.a.b((0,1),(2,3))", "z", "a", "b((0,1),(2,3))")] + [DataRow("z.a.b((0,(0,1)),(0,1))", "z", "a", "b((0,(0,1)),(0,1))")] public void Parse_ParsesAllParsableInputs_WithoutConsoleOutput(string testCaseName, string expectedNamespace, string expectedType, string expectedMethod) { - var expected = new Tuple(expectedType, expectedMethod); - using (var sw = new StringWriter()) { Console.SetOut(sw); @@ -91,6 +98,10 @@ public void Parse_ParsesAllParsableInputsWithoutNamespace_WithoutConsoleOutput(s [DataRow("z.y.x.")] [DataRow("z.y.x.)")] [DataRow("z.y.x.\"\")")] + [DataRow("z.a.b((0,1)")] + [DataRow("z.a.b((0,1)))")] + [DataRow("z.a.b((0,(0,1))")] + [DataRow("z.a.b((0,(0,1))))")] public void Parse_FailsGracefullyOnNonParsableInputs_WithConsoleOutput(string testCaseName) { var expectedConsole = string.Format(