/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Test/Core/Metadata/MetadataSignatureUnitTestHelper.cs
175 строк
7 KB
Jason Malinowski
Switch code that was using Assert.True/False as a replacement for .Fail
21 апр 2026, 23:28
21 апр 2026, 23:28
3bf59ba
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Test.Utilities { internal class MetadataSignatureUnitTestHelper { /// <summary> /// Uses Reflection to verify that the specified member signatures are present in emitted metadata /// </summary> /// <param name="appDomainHost">Unit test AppDomain host</param> /// <param name="expectedSignatures">Baseline signatures - use the Signature() factory method to create instances of SignatureDescription</param> internal static void VerifyMemberSignatures( IRuntimeEnvironment appDomainHost, params SignatureDescription[] expectedSignatures) { Assert.NotNull(expectedSignatures); Assert.NotEmpty(expectedSignatures); var succeeded = true; var expected = new List<string>(); var actual = new List<string>(); foreach (var signature in expectedSignatures) { var expectedSignature = signature.ExpectedSignature; if (!VerifyMemberSignatureHelper( appDomainHost, signature.FullyQualifiedTypeName, signature.MemberName, ref expectedSignature, out var actualSignatures)) { succeeded = false; } expected.Add(expectedSignature); actual.AddRange(actualSignatures); } if (!succeeded) { TriggerSignatureMismatchFailure(expected, actual); } } /// <summary> /// Uses Reflection to verify that the specified member signature is present in emitted metadata /// </summary> /// <param name="appDomainHost">Unit test AppDomain host</param> /// <param name="fullyQualifiedTypeName"> /// Fully qualified type name for member /// Names must be in format recognized by reflection /// e.g. MyType<T>.MyNestedType<T, U> => MyType`1+MyNestedType`2 /// </param> /// <param name="memberName"> /// Name of member on specified type whose signature needs to be verified /// Names must be in format recognized by reflection /// e.g. For explicitly implemented member - I1<string>.Method => I1<System.String>.Method /// </param> /// <param name="expectedSignature"> /// Baseline string for signature of specified member /// Skip this argument to get an error message that shows all available signatures for specified member /// This argument is passed by reference and it will be updated with a formatted form of the baseline signature for error reporting purposes /// </param> /// <param name="actualSignatures">List of found signatures matching member name</param> /// <returns>True if a matching member signature was found, false otherwise</returns> private static bool VerifyMemberSignatureHelper( IRuntimeEnvironment appDomainHost, string fullyQualifiedTypeName, string memberName, ref string expectedSignature, out List<string> actualSignatures) { Assert.False(string.IsNullOrWhiteSpace(fullyQualifiedTypeName), "'fullyQualifiedTypeName' can't be null or empty"); Assert.False(string.IsNullOrWhiteSpace(memberName), "'memberName' can't be null or empty"); var retVal = true; actualSignatures = new List<string>(); var signatures = appDomainHost.GetMemberSignaturesFromMetadata(fullyQualifiedTypeName, memberName); var signatureAssertText = "Signature(\"" + fullyQualifiedTypeName + "\", \"" + memberName + "\", \"{0}\"),"; if (!string.IsNullOrWhiteSpace(expectedSignature)) { expectedSignature = expectedSignature.Replace("\"", "\\\""); } expectedSignature = string.Format(signatureAssertText, expectedSignature); if (signatures.Count > 1) { var found = false; foreach (var signature in signatures) { var actualSignature = signature.Replace("\"", "\\\""); actualSignature = string.Format(signatureAssertText, actualSignature); if (actualSignature == expectedSignature) { actualSignatures.Clear(); actualSignatures.Add(actualSignature); found = true; break; } else { actualSignatures.Add(actualSignature); } } if (!found) { retVal = false; } } else if (signatures.Count == 1) { var actualSignature = signatures.First().Replace("\"", "\\\""); actualSignature = string.Format(signatureAssertText, actualSignature); actualSignatures.Add(actualSignature); if (expectedSignature != actualSignature) { retVal = false; } } else { retVal = false; } return retVal; } /// <summary> /// Triggers assert when expected and actual signatures don't match /// </summary> /// <param name="expectedSignatures">List of baseline signature strings</param> /// <param name="actualSignatures">List of actually found signature strings</param> private static void TriggerSignatureMismatchFailure(List<string> expectedSignatures, List<string> actualSignatures) { var expectedText = string.Empty; var actualText = string.Empty; var distinctSignatures = new HashSet<string>(); foreach (var signature in expectedSignatures) { // We need to preserve the order as well as prevent duplicates if (!distinctSignatures.Contains(signature)) { expectedText += "\n\t" + signature; distinctSignatures.Add(signature); } } distinctSignatures.Clear(); foreach (var signature in actualSignatures) { // We need to preserve the order as well as prevent duplicates if (!distinctSignatures.Contains(signature)) { actualText += "\n\t" + signature; distinctSignatures.Add(signature); } } expectedText = expectedText.TrimEnd(','); actualText = actualText.TrimEnd(','); var diffText = DiffUtil.DiffReport(expectedText, actualText); Assert.Fail("\n\nExpected:" + expectedText + "\n\nActual:" + actualText + "\n\nDifferences:\n" + diffText); } } }