PageRenderTime 52ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/EditorFeatures/Test/Diagnostics/AbstractSuppressionAllCodeTests.cs

https://gitlab.com/sharadag/TestProject2
C# | 162 lines | 134 code | 26 blank | 2 comment | 13 complexity | f7c6d0170b806a46b0bd769c4b37071b MD5 | raw file
  1. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.Immutable;
  5. using System.Linq;
  6. using System.Threading;
  7. using Microsoft.CodeAnalysis.CodeActions;
  8. using Microsoft.CodeAnalysis.CodeFixes.Suppression;
  9. using Microsoft.CodeAnalysis.Diagnostics;
  10. using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
  11. using Microsoft.CodeAnalysis.UnitTests.Diagnostics;
  12. using Roslyn.Utilities;
  13. using Xunit;
  14. namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
  15. {
  16. public abstract class AbstractSuppressionAllCodeTests : IEqualityComparer<Diagnostic>
  17. {
  18. protected abstract TestWorkspace CreateWorkspaceFromFile(string definition, ParseOptions parseOptions);
  19. internal abstract Tuple<Analyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace);
  20. protected void TestPragma(string code, ParseOptions options, Func<string, bool> verifier)
  21. {
  22. var set = new HashSet<ValueTuple<SyntaxToken, SyntaxToken>>();
  23. TestPragmaOrLocal(code, options, pragma: true, digInto: n => true, verifier: verifier, fixChecker: c =>
  24. {
  25. var fix = (AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction)c;
  26. var tuple = ValueTuple.Create(fix.StartToken_TestOnly, fix.EndToken_TestOnly);
  27. if (set.Contains(tuple))
  28. {
  29. return true;
  30. }
  31. set.Add(tuple);
  32. return false;
  33. });
  34. }
  35. protected void TestLocalSuppression(string code, ParseOptions options, Func<SyntaxNode, bool> digInto, Func<string, bool> verifier)
  36. {
  37. var set = new HashSet<SyntaxNode>();
  38. TestPragmaOrLocal(code, options, pragma: false, digInto: digInto, verifier: verifier, fixChecker: c =>
  39. {
  40. var fix = (AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction)c;
  41. if (set.Contains(fix.TargetNode_TestOnly))
  42. {
  43. return true;
  44. }
  45. set.Add(fix.TargetNode_TestOnly);
  46. return false;
  47. });
  48. }
  49. protected void TestPragmaOrLocal(
  50. string code, ParseOptions options, bool pragma, Func<SyntaxNode, bool> digInto, Func<string, bool> verifier, Func<CodeAction, bool> fixChecker)
  51. {
  52. using (var workspace = CreateWorkspaceFromFile(code, options))
  53. {
  54. var document = workspace.CurrentSolution.Projects.Single().Documents.Single();
  55. var root = document.GetSyntaxRootAsync().GetAwaiter().GetResult();
  56. var existingDiagnostics = root.GetDiagnostics().ToArray();
  57. var analyzerAndFixer = CreateDiagnosticProviderAndFixer(workspace);
  58. var analyzer = analyzerAndFixer.Item1;
  59. var fixer = analyzerAndFixer.Item2;
  60. foreach (var node in root.DescendantNodesAndSelf(digInto))
  61. {
  62. analyzer.Node = node;
  63. var span = node.Span;
  64. var diagnostics = DiagnosticProviderTestUtilities.GetAllDiagnostics(analyzer, document, span);
  65. foreach (var diagnostic in diagnostics)
  66. {
  67. if (!fixer.CanBeSuppressed(diagnostic))
  68. {
  69. continue;
  70. }
  71. var fixes = fixer.GetSuppressionsAsync(document, diagnostic.Location.SourceSpan, SpecializedCollections.SingletonEnumerable(diagnostic), CancellationToken.None).GetAwaiter().GetResult();
  72. if (fixes == null || fixes.Count() <= 0)
  73. {
  74. continue;
  75. }
  76. var fix = GetFix(fixes.Select(f => f.Action), pragma);
  77. if (fix == null)
  78. {
  79. continue;
  80. }
  81. // already same fix has been tested
  82. if (fixChecker(fix))
  83. {
  84. continue;
  85. }
  86. var operations = fix.GetOperationsAsync(CancellationToken.None).GetAwaiter().GetResult();
  87. var applyChangesOperation = operations.OfType<ApplyChangesOperation>().Single();
  88. var newDocument = applyChangesOperation.ChangedSolution.Projects.Single().Documents.Single();
  89. var newTree = newDocument.GetSyntaxTreeAsync().GetAwaiter().GetResult();
  90. var newText = newTree.GetText().ToString();
  91. Assert.True(verifier(newText));
  92. var newDiagnostics = newTree.GetDiagnostics();
  93. Assert.Equal(0, existingDiagnostics.Except(newDiagnostics, this).Count());
  94. }
  95. }
  96. }
  97. }
  98. private CodeAction GetFix(IEnumerable<CodeAction> fixes, bool pragma)
  99. {
  100. if (pragma)
  101. {
  102. return fixes.FirstOrDefault(f => f is AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction);
  103. }
  104. return fixes.FirstOrDefault(f => f is AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction);
  105. }
  106. public bool Equals(Diagnostic x, Diagnostic y)
  107. {
  108. return x.Id == y.Id && x.Descriptor.Category == y.Descriptor.Category;
  109. }
  110. public int GetHashCode(Diagnostic obj)
  111. {
  112. return Hash.Combine(obj.Id, obj.Descriptor.Category.GetHashCode());
  113. }
  114. internal class Analyzer : DiagnosticAnalyzer
  115. {
  116. private readonly DiagnosticDescriptor _descriptor =
  117. new DiagnosticDescriptor("TestId", "Test", "Test", "Test", DiagnosticSeverity.Warning, isEnabledByDefault: true);
  118. public SyntaxNode Node { get; set; }
  119. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
  120. {
  121. get
  122. {
  123. return ImmutableArray.Create(_descriptor);
  124. }
  125. }
  126. public override void Initialize(AnalysisContext analysisContext)
  127. {
  128. analysisContext.RegisterSyntaxTreeAction(
  129. (context) =>
  130. {
  131. context.ReportDiagnostic(Diagnostic.Create(_descriptor, Node.GetLocation()));
  132. });
  133. }
  134. }
  135. }
  136. }