diff --git a/docs/RFCs/0017-Managed-TestCase-Properties.md b/docs/RFCs/0017-Managed-TestCase-Properties.md index e6953c038f..dfc4fb0139 100644 --- a/docs/RFCs/0017-Managed-TestCase-Properties.md +++ b/docs/RFCs/0017-Managed-TestCase-Properties.md @@ -20,7 +20,7 @@ The `ManagedType` test case property represents the fully specified type name in * The type name must be fully qualified (in the CLR sense), including its namespace. Any generic classes must also include an arity value using backtick notation (`# where # is the number of type arguments that the class requires). * Nested classes are appended with a '+' and must also include an arity if generic. -* `ManagedType` name must be escaped if it doesn't conform to identifier naming rules. +* `ManagedType` name must not be escaped. ### `ManagedMethod` Property @@ -131,7 +131,8 @@ The combination of `ManagedType` and `ManagedMethod` will be unique to a particu 3. It can contain formatting characters. (Unicode categories: `Mn`, `Mc`, `Pc`, and `Cf`.) ## Escaping -If an identifier does not conform to identifier naming rules, it gets escaped. An escaped identifier always start and end with a `'`. +If an identifier does not conform to identifier naming rules, it gets escaped. An escaped identifier always start and end with a `'`. Note that `ManagedType` is never escaped. + ```console Type: CleanNamespaceName.SecondLevel.𝐌𝐲 𝘤𝘭𝘢𝘴𝘴 with 𝘢𝘯 𝒊𝒏𝒂𝒄𝒄𝒆𝒔𝒔𝒊𝒃𝒍𝒆 𝙣𝙖𝙢𝙚 🤷‍♀️ Method: int Sum(int x, int y) diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs index a1eb37da9c..eeeb3660ad 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs @@ -160,6 +160,8 @@ private static void GetManagedNameAndHierarchy(MethodBase method, bool useClosed method = MethodBase.GetMethodFromHandle(methodHandle, semanticType.TypeHandle)!; } + managedTypeName = semanticType.FullName!; + if (method.IsGenericMethod && !useClosedTypes) { // If this method is generic, then convert to the generic method definition @@ -210,20 +212,20 @@ private static void GetManagedNameAndHierarchy(MethodBase method, bool useClosed } var methodNameEndIndex = methodBuilder.Length; - managedTypeName = typeBuilder.ToString(); + var escapedManagedTypeName = typeBuilder.ToString(); managedMethodName = methodBuilder.ToString(); hierarchyValues = new string[HierarchyConstants.Levels.TotalLevelCount]; hierarchyValues[HierarchyConstants.Levels.TestGroupIndex] = managedMethodName.Substring(0, methodNameEndIndex); if (hierarchyPos[1] == hierarchyPos[0]) // No namespace { - hierarchyValues[HierarchyConstants.Levels.ClassIndex] = managedTypeName.Substring(0, hierarchyPos[2]); + hierarchyValues[HierarchyConstants.Levels.ClassIndex] = escapedManagedTypeName.Substring(0, hierarchyPos[2]); hierarchyValues[HierarchyConstants.Levels.NamespaceIndex] = null; } else { - hierarchyValues[HierarchyConstants.Levels.ClassIndex] = managedTypeName.Substring(hierarchyPos[1] + 1, hierarchyPos[2] - hierarchyPos[1] - 1); - hierarchyValues[HierarchyConstants.Levels.NamespaceIndex] = managedTypeName.Substring(hierarchyPos[0], hierarchyPos[1] - hierarchyPos[0]); + hierarchyValues[HierarchyConstants.Levels.ClassIndex] = escapedManagedTypeName.Substring(hierarchyPos[1] + 1, hierarchyPos[2] - hierarchyPos[1] - 1); + hierarchyValues[HierarchyConstants.Levels.NamespaceIndex] = escapedManagedTypeName.Substring(hierarchyPos[0], hierarchyPos[1] - hierarchyPos[0]); } var assembly = method.DeclaringType?.Assembly; @@ -268,12 +270,11 @@ private static void GetManagedNameAndHierarchy(MethodBase method, bool useClosed /// public static MethodBase GetMethod(Assembly assembly, string managedTypeName, string managedMethodName) { - var parsedManagedTypeName = ReflectionHelpers.ParseEscapedString(managedTypeName); - var type = assembly.GetType(parsedManagedTypeName, throwOnError: false, ignoreCase: false); + var type = assembly.GetType(managedTypeName, throwOnError: false, ignoreCase: false); if (type == null) { - string message = string.Format(CultureInfo.CurrentCulture, Resources.Resources.ErrorTypeNotFound, parsedManagedTypeName); + string message = string.Format(CultureInfo.CurrentCulture, Resources.Resources.ErrorTypeNotFound, managedTypeName); throw new InvalidManagedNameException(message); }