/// <summary> /// General verifier for codefixes. /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes. /// Then gets the string after the codefix is applied and compares it with the expected result. /// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true. /// </summary> /// <param name="analyzer">The analyzer to be applied to the source code</param> /// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param> /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param> /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param> private void VerifyFix(TAnalyzer analyzer, TCodeFix codeFixProvider, string oldSource, string newSource) { var document = GetDocument(); var analyzerDiagnostics = GetSortedDiagnosticsFromDocument(analyzer, document); var compilerDiagnostics = GetCompilerDiagnostics(document); var attempts = analyzerDiagnostics.Length; for (int i = 0; i < attempts; ++i) { var actions = new List <CodeAction>(); var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); codeFixProvider.RegisterCodeFixesAsync(context).Wait(); if (!actions.Any()) { break; } document = ApplyFix(document, actions.ElementAt(0)); analyzerDiagnostics = GetSortedDiagnosticsFromDocument(analyzer, document); //check if there are analyzer diagnostics left after the code fix if (!analyzerDiagnostics.Any()) { break; } } //after applying all of the code fixes, compare the resulting string to the inputted one var actual = GetStringFromDocument(document); Assert.Equal(newSource, actual); Document ApplyFix(Document document, CodeAction codeAction) { var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result; var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); } string GetStringFromDocument(Document document) { var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result; var root = simplifiedDoc.GetSyntaxRootAsync().Result; root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace); return(root.GetText().ToString()); } IEnumerable <Diagnostic> GetCompilerDiagnostics(Document document) { return(document.GetSemanticModelAsync().Result.GetDiagnostics()); } }
public void Run() { var analyzer = new TAnalyzer(); var fix = new TCodeFix(); var actualResults = GetSortedDiagnostics(analyzer); VerifyDiagnosticResults(actualResults, analyzer, ExpectedDiagnostics.ToArray()); if (FixedCode != null) { VerifyFix(analyzer, fix, TestCode, FixedCode); } }