コード例 #1
0
            /// <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());
                }
            }
コード例 #2
0
            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);
                }
            }
コード例 #3
0
        /// <summary>
        /// Verifies that <paramref name="code"/> produces no diagnostics when analyzed with <typeparamref name="TAnalyzer"/>.
        /// </summary>
        /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam>
        /// <param name="code">The code to analyze.</param>
        public static void Valid <TAnalyzer>(params string[] code)
            where TAnalyzer : DiagnosticAnalyzer, new()
        {
            var analyzer = new TAnalyzer();

            ValidAsync(
                analyzer,
                code,
                CodeFactory.DefaultCompilationOptions(analyzer, SuppressedDiagnostics),
                MetadataReferences)
            .GetAwaiter()
            .GetResult();
        }
コード例 #4
0
            private Diagnostic[] GetSortedDiagnosticsFromDocument(TAnalyzer analyzer, Document document)
            {
                var diagnostics = new List <Diagnostic>();
                var compilation = document.Project.GetCompilationAsync().Result;
                var options     = new AnalyzerOptions(AdditionalFiles.ToImmutableArray <AdditionalText>());
                var compilationWithAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer), options);
                var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result;

                diagnostics.AddRange(diags.Concat(compilation.GetDiagnostics().Where(x => x.Severity == DiagnosticSeverity.Error)));
                var results = SortDiagnostics(diagnostics);

                diagnostics.Clear();
                return(results);
            }
コード例 #5
0
        /// <summary>
        /// Verifies that <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics.
        /// </summary>
        /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam>
        /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param>
        public static void Diagnostics <TAnalyzer>(params string[] codeWithErrorsIndicated)
            where TAnalyzer : DiagnosticAnalyzer, new()
        {
            var analyzer = new TAnalyzer();

            DiagnosticsWithMetadataAsync(
                analyzer,
                DiagnosticsAndSources.CreateFromCodeWithErrorsIndicated(analyzer, codeWithErrorsIndicated),
                CodeFactory.DefaultCompilationOptions(analyzer, SuppressedDiagnostics),
                MetadataReferences,
                null)
            .GetAwaiter()
            .GetResult();
        }
コード例 #6
0
        /// <summary>
        /// Verifies that
        /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics
        /// 2. The code fix does not change the code.
        /// </summary>
        /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam>
        /// <typeparam name="TCodeFix">The type of the code fix.</typeparam>
        /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param>
        public static void NoFix <TAnalyzer, TCodeFix>(params string[] codeWithErrorsIndicated)
            where TAnalyzer : DiagnosticAnalyzer, new()
            where TCodeFix : CodeFixProvider, new()
        {
            var analyzer = new TAnalyzer();

            NoFixAsync(
                analyzer,
                new TCodeFix(),
                DiagnosticsAndSources.CreateFromCodeWithErrorsIndicated(analyzer, codeWithErrorsIndicated),
                CodeFactory.DefaultCompilationOptions(analyzer, SuppressedDiagnostics),
                MetadataReferences)
            .GetAwaiter()
            .GetResult();
        }
コード例 #7
0
 /// <summary>
 /// Given classes in the form of strings, their language, and an IDiagnosticAnalyzer to apply to it, return the diagnostics found in the string after converting it to a document.
 /// </summary>
 /// <param name="analyzer">The analyzer to be run on the sources</param>
 /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location</returns>
 private Diagnostic[] GetSortedDiagnostics(TAnalyzer analyzer)
 {
     return(GetSortedDiagnosticsFromDocument(analyzer, GetDocument()));
 }