/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/CSharpTest2/EmbeddedLanguages/RegularExpressions/CSharpRegexParserTests_TestGeneration.cs
177 строк
6 KB
Cyrus Najmabadi
Move embedded language tests to unittests2 project
03 фев 2022, 07:00
03 фев 2022, 07:00
4fcc465
Код
Авторство
О чём код?
// 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 #if false // This file is entirely disabled, but serves a useful purpose and is thus kept in the source tree. // Specifically, it provides a test scaffolding that allows us to easily run and regenerate tests // when appropriate. For example, if/when we decide to add/change information in the baselines, we // can easily just regenerate all the tests instead of having to manually fix up the baselines // themselves. // // The main logic is in CSharpRegexParserTests.GenerateTests. Basically, all tests will funnel // through to that, passing along all the appropriate test arguments. That helper will then // generate the new baseline. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.EmbeddedLanguages.RegularExpressions { // used so we can keep tests sorted numerically. i.e. test9 then test10 (even though 1 is // before 9 in ascii). internal class LogicalStringComparer : IComparer<string> { [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] private static extern int StrCmpLogicalW(string psz1, string psz2); public static readonly IComparer<string> Instance = new LogicalStringComparer(); private LogicalStringComparer() { } public int Compare(string x, string y) { return StrCmpLogicalW(x, y); } } public class Fixture : IDisposable { public void Dispose() { var other = new Dictionary<string, string>(); var tree = SyntaxFactory.ParseSyntaxTree( File.ReadAllText(@"C:\GitHub\roslyn\src\Workspaces\CSharpTest\EmbeddedLanguages\RegularExpressions\CSharpRegexParserTests_BasicTests.cs")); var methodNames = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Select(m => m.Identifier.ValueText); var nameToIndex = new Dictionary<string, int>(); var index = 0; foreach (var name in methodNames) { nameToIndex[name] = index; index++; } #if false var tests = CSharpRegexParserTests.nameToTest.Where(kvp => !kvp.Key.StartsWith("NegativeTest") && !kvp.Key.StartsWith("Reference")) .OrderBy(kvp => nameToIndex[kvp.Key]) .Select(kvp => kvp.Value); #elif false var tests = CSharpRegexParserTests.nameToTest.Where(kvp => kvp.Key.StartsWith("NegativeTest")) .OrderBy(kvp => kvp.Key, LogicalStringComparer.Instance) .Select(kvp => kvp.Value); #else var tests = CSharpRegexParserTests.nameToTest.Where(kvp => kvp.Key.StartsWith("Reference")) .OrderBy(kvp => kvp.Key, LogicalStringComparer.Instance) .Select(kvp => kvp.Value); #endif var val = string.Join("\r\n", tests); } } [CollectionDefinition(nameof(MyCollection))] public class MyCollection : ICollectionFixture<Fixture> { } [Collection(nameof(MyCollection))] public partial class CSharpRegexParserTests { private readonly Fixture _fixture; public CSharpRegexParserTests(Fixture fixture) { _fixture = fixture; } public static Dictionary<string, string> nameToTest = new Dictionary<string, string>(); private void Test( string stringText, string expected, RegexOptions options, bool runSubTreeTests = true, [CallerMemberName]string name = "", bool allowIndexOutOfRange = false, bool allowNullReference = false, bool allowOutOfMemory = false) { var test = GenerateTests(stringText, options, runSubTreeTests, name, allowIndexOutOfRange, allowNullReference, allowOutOfMemory); nameToTest.Add(name, test); } public string GenerateTests( string val, RegexOptions options, bool runSubTreeTests, string testName, bool allowIndexOutOfRange, bool allowNullReference, bool allowOutOfMemory) { // Actually call into our regex APIs to produce figure out the tree produced. // Then spit out a test that does the same, encoding the tree as the expected var builder = new StringBuilder(); builder.AppendLine("[Fact]"); builder.AppendLine("public void " + testName + "()"); builder.AppendLine("{"); builder.Append(@" Test("); var escaped = val.Replace("\"", "\"\""); var quoted = "" + '@' + '"' + escaped + '"'; builder.Append(quoted); var token = GetStringToken(val); var allChars = _service.TryConvertToVirtualChars(token); var tree = RegexParser.TryParse(allChars, options); var actual = TreeToText(token.SyntaxTree.GetText(), tree).Replace("\"", "\"\""); builder.Append(", " + '@' + '"'); builder.Append(actual); builder.Append('"'); builder.Append(", RegexOptions." + options.ToString()); if (!runSubTreeTests) { builder.Append(", runSubTreeTests: false"); } if (allowIndexOutOfRange) { builder.Append(", allowIndexOutOfRange: true"); } if (allowNullReference) { builder.Append(", allowNullReference: true"); } if (allowOutOfMemory) { builder.Append(", allowOutOfMemory: true"); } builder.AppendLine(");"); builder.AppendLine("}"); return builder.ToString(); } } } #endif