Skip to content

Commit

Permalink
ManagedNames impl. refactored.
Browse files Browse the repository at this point in the history
 - ManagedNames support in TestCase is updated to support the latest preview.
 - Updated TP to `16.10.0-preview-20210204-01`.
  • Loading branch information
Haplois committed Feb 4, 2021
1 parent f55f5f2 commit aafb275
Show file tree
Hide file tree
Showing 27 changed files with 299 additions and 84 deletions.
2 changes: 1 addition & 1 deletion scripts/build/TestFx.Versions.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TestPlatformVersion Condition=" '$(TestPlatformVersion)' == '' ">16.9.0-preview-20210129-05</TestPlatformVersion>
<TestPlatformVersion Condition=" '$(TestPlatformVersion)' == '' ">16.10.0-preview-20210204-01</TestPlatformVersion>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
</PropertyGroup>
</Project>
1 change: 1 addition & 0 deletions src/Adapter/MSTest.CoreAdapter/Discovery/TypeEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ internal Collection<UnitTestElement> GetTests(ICollection<string> warnings)
/// <returns> Returns a UnitTestElement.</returns>
internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInTestTypeAssembly, ICollection<string> warnings)
{
// null if the current instance represents a generic type parameter.
Debug.Assert(this.type.AssemblyQualifiedName != null, "AssemblyQualifiedName for method is null.");

// This allows void returning async test method to be valid test method. Though they will be executed similar to non-async test method.
Expand Down
52 changes: 43 additions & 9 deletions src/Adapter/MSTest.CoreAdapter/Execution/TypeCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution
using System.Reflection;
using System.Security;

using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities;
using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery;
using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions;
using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers;
Expand Down Expand Up @@ -635,9 +636,50 @@ private TestMethodAttribute GetTestMethodAttribute(MethodInfo methodInfo, TestCl
/// <returns> The <see cref="MethodInfo"/>. </returns>
private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassInfo testClassInfo)
{
var methodsInClass = testClassInfo.ClassType.GetRuntimeMethods().ToArray();
var testMethodInfo = testMethod.HasManagedMethodAndTypeProperties
? this.GetMethodInfoUsingManagedNameHelper(testMethod, testClassInfo)
: this.GetMethodInfoUsingRuntimeMethods(testMethod, testClassInfo);

// if correct method is not found, throw appropriate
// exception about what is wrong.
if (testMethodInfo == null)
{
var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
throw new TypeInspectionException(errorMessage);
}

return testMethodInfo;
}

private MethodInfo GetMethodInfoUsingManagedNameHelper(TestMethod testMethod, TestClassInfo testClassInfo)
{
MethodInfo testMethodInfo = null;
var assembly = testClassInfo.ClassType.GetTypeInfo().Assembly;
var methodBase = ManagedNameHelper.GetMethod(assembly, testMethod.ManagedTypeName, testMethod.ManagedMethodName);

if (methodBase is MethodInfo mi)
{
testMethodInfo = mi;
}
else if (methodBase != null)
{
var parameters = methodBase.GetParameters().Select(i => i.ParameterType).ToArray();
testMethodInfo = methodBase.DeclaringType.GetRuntimeMethod(methodBase.Name, parameters);
}

testMethodInfo = testMethodInfo?.HasCorrectTestMethodSignature(true) ?? false
? testMethodInfo
: null;

return testMethodInfo;
}

private MethodInfo GetMethodInfoUsingRuntimeMethods(TestMethod testMethod, TestClassInfo testClassInfo)
{
MethodInfo testMethodInfo;

var methodsInClass = testClassInfo.ClassType.GetRuntimeMethods().ToArray();

if (testMethod.DeclaringClassFullName != null)
{
// Only find methods that match the given declaring name.
Expand All @@ -657,14 +699,6 @@ private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassIn
.OrderByDescending(method => method.DeclaringType.FullName.Equals(className)).FirstOrDefault();
}

// if correct method is not found, throw appropriate
// exception about what is wrong.
if (testMethodInfo == null)
{
var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
throw new TypeInspectionException(errorMessage);
}

return testMethodInfo;
}

Expand Down
20 changes: 14 additions & 6 deletions src/Adapter/MSTest.CoreAdapter/Extensions/TestCaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@

namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions
{
using Microsoft.TestPlatform.AdapterUtilities;
using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;

using Constants = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Constants;
using ManagedNameUtilities = Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities;

/// <summary>
/// Extension Methods for TestCase Class
/// </summary>
internal static class TestCaseExtensions
{
internal static readonly TestProperty ManagedTypeProperty = TestProperty.Register(
id: ManagedNameUtilities.Contants.ManagedTypePropertyId,
label: ManagedNameUtilities.Contants.ManagedTypeLabel,
id: ManagedNameConstants.ManagedTypePropertyId,
label: ManagedNameConstants.ManagedTypeLabel,
category: string.Empty,
description: string.Empty,
valueType: typeof(string),
Expand All @@ -25,8 +25,8 @@ internal static class TestCaseExtensions
owner: typeof(TestCase));

internal static readonly TestProperty ManagedMethodProperty = TestProperty.Register(
id: ManagedNameUtilities.Contants.ManagedMethodPropertyId,
label: ManagedNameUtilities.Contants.ManagedMethodLabel,
id: ManagedNameConstants.ManagedMethodPropertyId,
label: ManagedNameConstants.ManagedMethodLabel,
category: string.Empty,
description: string.Empty,
valueType: typeof(string),
Expand All @@ -53,7 +53,15 @@ internal static UnitTestElement ToUnitTestElement(this TestCase testCase, string
? fullyQualifiedName.Remove(0, $"{testClassName}.".Length)
: fullyQualifiedName;

TestMethod testMethod = new TestMethod(name, testClassName, source, isAsync);
TestMethod testMethod;
if (testCase.ContainsManagedMethodAndType())
{
testMethod = new TestMethod(testCase.GetManagedType(), testCase.GetManagedMethod(), name, testClassName, source, isAsync);
}
else
{
testMethod = new TestMethod(name, testClassName, source, isAsync);
}

if (declaringClassName != null && declaringClassName != testClassName)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Adapter/MSTest.CoreAdapter/Friends.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("MSTestAdapter.Smoke.E2ETests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
1 change: 1 addition & 0 deletions src/Adapter/MSTest.CoreAdapter/Helpers/ReflectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers
using System.Linq;
using System.Reflection;
using System.Security;

using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution;
using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
Expand Down
30 changes: 21 additions & 9 deletions src/Adapter/MSTest.CoreAdapter/ObjectModel/TestMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public TestMethod(string name, string fullClassName, string assemblyName, bool i
this.IsAsync = isAsync;
}

public TestMethod(MethodBase method, string name, string fullClassName, string assemblyName, bool isAsync)
internal TestMethod(MethodBase method, string name, string fullClassName, string assemblyName, bool isAsync)
: this(name, fullClassName, assemblyName, isAsync)
{
if (method == null)
Expand All @@ -57,8 +57,20 @@ public TestMethod(MethodBase method, string name, string fullClassName, string a

ManagedNameHelper.GetManagedName(method, out var managedType, out var managedMethod);

this.ManagedType = managedType;
this.ManagedMethod = managedMethod;
// ManagedNameHelpers currently does not support spaces in method names.
// If there are spaces in the method name, we'll use the legacy way to find the method.
if (!managedMethod.Contains(" "))
{
this.ManagedTypeName = managedType;
this.ManagedMethodName = managedMethod;
}
}

internal TestMethod(string managedTypeName, string managedMethodName, string name, string fullClassName, string assemblyName, bool isAsync)
: this(name, fullClassName, assemblyName, isAsync)
{
this.ManagedTypeName = managedTypeName;
this.ManagedMethodName = managedMethodName;
}

/// <summary>
Expand Down Expand Up @@ -120,13 +132,13 @@ public string DeclaringClassFullName
/// </summary>
public bool IsAsync { get; private set; }

public string ManagedType { get; }
/// <inheritdoc />
public string ManagedTypeName { get; }

public string ManagedMethod { get; }
/// <inheritdoc />
public string ManagedMethodName { get; }

/// <summary>
/// Gets a value indicating whether both <see cref="ManagedType"/> and <see cref="ManagedMethod"/> are not null or whitespace.
/// </summary>
public bool HasManagedMethodAndType => !string.IsNullOrWhiteSpace(this.ManagedType) && !string.IsNullOrWhiteSpace(this.ManagedMethod);
/// <inheritdoc />
public bool HasManagedMethodAndTypeProperties => !string.IsNullOrWhiteSpace(this.ManagedTypeName) && !string.IsNullOrWhiteSpace(this.ManagedMethodName);
}
}
40 changes: 27 additions & 13 deletions src/Adapter/MSTest.CoreAdapter/ObjectModel/UnitTestElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,22 @@ public UnitTestElement(TestMethod testMethod)
/// <returns> An instance of <see cref="TestCase"/>. </returns>
internal TestCase ToTestCase()
{
var fullName = string.Format(
CultureInfo.InvariantCulture,
"{0}.{1}",
this.TestMethod.FullClassName,
this.TestMethod.Name);
string fullName = this.TestMethod.HasManagedMethodAndTypeProperties
? string.Format(CultureInfo.InvariantCulture, "{0}.{1}", this.TestMethod.ManagedTypeName, this.TestMethod.ManagedMethodName)
: string.Format(CultureInfo.InvariantCulture, "{0}.{1}", this.TestMethod.FullClassName, this.TestMethod.Name);

TestCase testCase = new TestCase(fullName, TestAdapter.Constants.ExecutorUri, this.TestMethod.AssemblyName);
testCase.DisplayName = this.GetDisplayName();

testCase.DisplayName = string.IsNullOrEmpty(this.DisplayName) ? this.TestMethod.Name : this.DisplayName;
testCase.SetPropertyValue(TestAdapter.Constants.TestClassNameProperty, this.TestMethod.FullClassName);
if (this.TestMethod.HasManagedMethodAndType)
if (this.TestMethod.HasManagedMethodAndTypeProperties)
{
testCase.SetPropertyValue(TestCaseExtensions.ManagedTypeProperty, this.TestMethod.ManagedType);
testCase.SetPropertyValue(TestCaseExtensions.ManagedMethodProperty, this.TestMethod.ManagedMethod);
testCase.SetPropertyValue(TestCaseExtensions.ManagedTypeProperty, this.TestMethod.ManagedTypeName);
testCase.SetPropertyValue(TestCaseExtensions.ManagedMethodProperty, this.TestMethod.ManagedMethodName);
testCase.SetPropertyValue(TestAdapter.Constants.TestClassNameProperty, this.TestMethod.ManagedTypeName);
}
else
{
testCase.SetPropertyValue(TestAdapter.Constants.TestClassNameProperty, this.TestMethod.FullClassName);
}

// Set declaring type if present so the correct method info can be retrieved
Expand Down Expand Up @@ -183,12 +185,24 @@ internal TestCase ToTestCase()
// Set the Do not parallelize state if present
if (this.DoNotParallelize)
{
testCase.SetPropertyValue(
TestAdapter.Constants.DoNotParallelizeProperty,
this.DoNotParallelize);
testCase.SetPropertyValue(TestAdapter.Constants.DoNotParallelizeProperty, this.DoNotParallelize);
}

return testCase;
}

private string GetDisplayName()
{
if (string.IsNullOrWhiteSpace(this.DisplayName))
{
return string.IsNullOrWhiteSpace(this.TestMethod.ManagedMethodName)
? this.TestMethod.Name
: this.TestMethod.ManagedMethodName;
}
else
{
return this.DisplayName;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,8 @@ private string GetStringPropertyValue(string propertyName)
private void InitializeProperties()
{
this.properties[TestContextPropertyStrings.FullyQualifiedTestClassName] = this.testMethod.FullClassName;
this.properties[TestContextPropertyStrings.ManagedType] = this.testMethod.ManagedType;
this.properties[TestContextPropertyStrings.ManagedMethod] = this.testMethod.ManagedMethod;
this.properties[TestContextPropertyStrings.ManagedType] = this.testMethod.ManagedTypeName;
this.properties[TestContextPropertyStrings.ManagedMethod] = this.testMethod.ManagedMethodName;
this.properties[TestContextPropertyStrings.TestName] = this.testMethod.Name;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/PlatformServices.Desktop/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MicroBuild.Core" version="0.2.0" targetFramework="net451" developmentDependency="true" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.9.0-preview-20210129-05" targetFramework="net45" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.10.0-preview-20210204-01" targetFramework="net45" />
<package id="NuGet.Frameworks" version="5.0.0" targetFramework="net45" />
<package id="StyleCop.Analyzers" version="1.0.0" targetFramework="net45" developmentDependency="true" />
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net45" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,19 @@ public interface ITestMethod
/// <example>
/// <code>NamespaceA.NamespaceB.ClassName`1+InnerClass`2</code>
/// </example>
string ManagedType { get; }
string ManagedTypeName { get; }

/// <summary>
/// Gets the fully specified method name metadata format.
/// </summary>
/// <example>
/// <code>MethodName`2(ParamTypeA,ParamTypeB,…)</code>
/// </example>
string ManagedMethod { get; }
string ManagedMethodName { get; }

/// <summary>
/// Gets a value indicating whether both <see cref="ManagedTypeName"/> and <see cref="ManagedMethodName"/> are not null or whitespace.
/// </summary>
bool HasManagedMethodAndTypeProperties { get; }
}
}
2 changes: 1 addition & 1 deletion src/Adapter/PlatformServices.Interface/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MicroBuild.Core" version="0.2.0" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.9.0-preview-20210129-05" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.10.0-preview-20210204-01" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="StyleCop.Analyzers" version="1.0.0" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
<package id="System.Collections" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="System.ComponentModel" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,8 @@ private string GetStringPropertyValue(string propertyName)
private void InitializeProperties()
{
this.properties[FullyQualifiedTestClassNameLabel] = this.testMethod.FullClassName;
this.properties[ManagedTypeLabel] = this.testMethod.ManagedType;
this.properties[ManagedMethodLabel] = this.testMethod.ManagedMethod;
this.properties[ManagedTypeLabel] = this.testMethod.ManagedTypeName;
this.properties[ManagedMethodLabel] = this.testMethod.ManagedMethodName;
this.properties[TestNameLabel] = this.testMethod.Name;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/PlatformServices.Portable/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MicroBuild.Core" version="0.2.0" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.9.0-preview-20210129-05" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="Microsoft.TestPlatform.ObjectModel" version="16.10.0-preview-20210204-01" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="StyleCop.Analyzers" version="1.0.0" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
<package id="System.Collections" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
<package id="System.ComponentModel" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ private object GetPropertyValue(string propertyName)
private void InitializeProperties()
{
this.properties[FullyQualifiedTestClassNameLabel] = this.testMethod.FullClassName;
this.properties[ManagedTypeLabel] = this.testMethod.ManagedType;
this.properties[ManagedMethodLabel] = this.testMethod.ManagedMethod;
this.properties[ManagedTypeLabel] = this.testMethod.ManagedTypeName;
this.properties[ManagedMethodLabel] = this.testMethod.ManagedMethodName;
this.properties[TestNameLabel] = this.testMethod.Name;
}
}
Expand Down
Loading

0 comments on commit aafb275

Please sign in to comment.