Ejemplo n.º 1
0
        /// <summary>
        /// Verifies that specified source will not produce diagnostic described with see <see cref="Descriptor"/>
        /// </summary>
        /// <param name="source">Source text that contains placeholder [||] to be replaced with <paramref name="sourceData"/>.</param>
        /// <param name="sourceData"></param>
        /// <param name="options"></param>
        /// <param name="cancellationToken"></param>
        public async Task VerifyNoDiagnosticAsync(
            string source,
            string sourceData,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            (_, string text) = TextParser.ReplaceEmptySpan(source, sourceData);

            await VerifyNoDiagnosticAsync(
                source : text,
                additionalSources : null,
                options : options,
                cancellationToken);
        }
Ejemplo n.º 2
0
 public async Task VerifyNoRefactoringAsync(
     string source,
     TextSpan span,
     string equivalenceKey               = null,
     CodeVerificationOptions options     = null,
     CancellationToken cancellationToken = default)
 {
     await VerifyNoRefactoringAsync(
         source,
         ImmutableArray.Create(span),
         equivalenceKey,
         options,
         cancellationToken).ConfigureAwait(false);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Verifies that specified source will produce diagnostic described with see <see cref="Descriptor"/>
        /// </summary>
        /// <param name="source">A source code that should be tested. Tokens [| and |] represents start and end of selection respectively.</param>
        /// <param name="options"></param>
        /// <param name="cancellationToken"></param>
        public async Task VerifyDiagnosticAsync(
            string source,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source);

            await VerifyDiagnosticAsync(
                result.Text,
                result.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)),
                additionalSources : null,
                options : options,
                cancellationToken);
        }
Ejemplo n.º 4
0
        internal async Task VerifyNoRefactoringAsync(
            string source,
            IEnumerable <TextSpan> spans,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            options ??= Options;

            using (Workspace workspace = new AdhocWorkspace())
            {
                Document document = WorkspaceFactory.CreateDocument(workspace.CurrentSolution, source, options);

                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken);

                ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);

                VerifyCompilerDiagnostics(compilerDiagnostics, options);

                using (IEnumerator <TextSpan> en = spans.GetEnumerator())
                {
                    if (!en.MoveNext())
                    {
                        Assert.True(false, "Span on which a refactoring should be invoked was not found.");
                    }

                    do
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        var context = new CodeRefactoringContext(
                            document,
                            en.Current,
                            a =>
                        {
                            if (equivalenceKey == null ||
                                string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                            {
                                Assert.True(false, "No code refactoring expected.");
                            }
                        },
                            CancellationToken.None);

                        await RefactoringProvider.ComputeRefactoringsAsync(context);
                    } while (en.MoveNext());
                }
            }
        }
Ejemplo n.º 5
0
        public async Task VerifyNoRefactoringAsync(
            string source,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source, LinePositionSpanInfoComparer.IndexDescending);

            await VerifyNoRefactoringAsync(
                source : result.Text,
                spans : result.Spans.Select(f => f.Span),
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
Ejemplo n.º 6
0
        public async Task VerifyFixAsync(
            string source,
            string inlineSource,
            string inlineExpected,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            (_, string source2, string expected) = TextParser.ReplaceEmptySpan(source, inlineSource, inlineExpected);

            await VerifyFixAsync(
                source : source2,
                expected : expected,
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken);
        }
Ejemplo n.º 7
0
        public async Task VerifyRefactoringAsync(
            string source,
            string expected,
            IEnumerable <string> additionalSources = null,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            TextParserResult result = TextParser.GetSpans(source, LinePositionSpanInfoComparer.IndexDescending);

            await VerifyRefactoringAsync(
                source : result.Text,
                expected : expected,
                spans : result.Spans.Select(f => f.Span),
                additionalSources : additionalSources,
                equivalenceKey : equivalenceKey,
                options : options,
                cancellationToken : cancellationToken);
        }
Ejemplo n.º 8
0
        public async Task VerifyNoDiagnosticAsync(
            string source,
            IEnumerable <string> additionalSources = null,
            CodeVerificationOptions options        = null,
            CancellationToken cancellationToken    = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            options ??= Options;

            if (SupportedDiagnostics.IndexOf(Descriptor, DiagnosticDescriptorComparer.Id) == -1)
            {
                Assert.True(false, $"Diagnostic \"{Descriptor.Id}\" is not supported by analyzer \"{Analyzer.GetType().Name}\".");
            }

            using (Workspace workspace = new AdhocWorkspace())
            {
                Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options);

                Document document = WorkspaceFactory.AddDocument(project, source, additionalSources);

                Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                VerifyCompilerDiagnostics(compilerDiagnostics, options);

                if (!Descriptor.IsEnabledByDefault)
                {
                    compilation = compilation.EnsureEnabled(Descriptor);
                }

                ImmutableArray <Diagnostic> analyzerDiagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false);

                foreach (Diagnostic diagnostic in analyzerDiagnostics)
                {
                    if (string.Equals(diagnostic.Id, Descriptor.Id, StringComparison.Ordinal))
                    {
                        Assert.True(false, $"No diagnostic expected{analyzerDiagnostics.Where(f => string.Equals(f.Id, Descriptor.Id, StringComparison.Ordinal)).ToDebugString()}");
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public async Task VerifyDiagnosticAsync(
            string source,
            string inlineSource,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            (TextSpan span, string text) = TextParser.ReplaceEmptySpan(source, inlineSource);

            TextParserResult result = TextParser.GetSpans(text);

            if (result.Spans.Any())
            {
                await VerifyDiagnosticAsync(result.Text, result.Spans.Select(f => f.Span), options, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await VerifyDiagnosticAsync(text, span, options, cancellationToken).ConfigureAwait(false);
            }
        }
Ejemplo n.º 10
0
        internal void VerifyCompilerDiagnostics(
            ImmutableArray <Diagnostic> diagnostics,
            CodeVerificationOptions options)
        {
            DiagnosticSeverity maxAllowedSeverity = options.AllowedCompilerDiagnosticSeverity;

            ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds;

            if (IsAny())
            {
                IEnumerable <Diagnostic> notAllowed = diagnostics
                                                      .Where(f => f.Severity > maxAllowedSeverity && !allowedDiagnosticIds.Any(id => id == f.Id));

                Assert.True(false, $"No compiler diagnostics with severity higher than '{maxAllowedSeverity}' expected{notAllowed.ToDebugString()}");
            }

            bool IsAny()
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (diagnostic.Severity > maxAllowedSeverity &&
                        !IsAllowed(diagnostic))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            bool IsAllowed(Diagnostic diagnostic)
            {
                foreach (string diagnosticId in allowedDiagnosticIds)
                {
                    if (diagnostic.Id == diagnosticId)
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Verifies that a refactoring can be applied on a specified source code.
        /// </summary>
        /// <param name="source">Source text that contains placeholder [||] to be replaced with <paramref name="sourceData"/> and <paramref name="expectedData"/>.</param>
        /// <param name="sourceData"></param>
        /// <param name="expectedData"></param>
        /// <param name="title">Code action's title.</param>
        /// <param name="equivalenceKey">Code action's equivalence key.</param>
        /// <param name="options"></param>
        /// <param name="cancellationToken"></param>
        public async Task VerifyRefactoringAsync(
            string source,
            string sourceData,
            string expectedData,
            string title                        = null,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            (TextSpan span, string source2, string expected) = TextParser.ReplaceEmptySpan(source, sourceData, expectedData);

            TextParserResult result = TextParser.GetSpans(source2, LinePositionSpanInfoComparer.IndexDescending);

            if (result.Spans.Any())
            {
                await VerifyRefactoringAsync(
                    source : result.Text,
                    expected : expected,
                    spans : result.Spans.Select(f => f.Span),
                    title : title,
                    equivalenceKey : equivalenceKey,
                    options : options,
                    cancellationToken : cancellationToken);
            }
            else
            {
                await VerifyRefactoringAsync(
                    source : source2,
                    expected : expected,
                    span : span,
                    title : title,
                    equivalenceKey : equivalenceKey,
                    options : options,
                    cancellationToken : cancellationToken);
            }
        }
Ejemplo n.º 12
0
        public async Task VerifyDiagnosticAsync(
            string source,
            IEnumerable <Diagnostic> expectedDiagnostics,
            IEnumerable <string> additionalSources = null,
            CodeVerificationOptions options        = null,
            CancellationToken cancellationToken    = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            options ??= Options;

            using (Workspace workspace = new AdhocWorkspace())
            {
                Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options);

                Document document = WorkspaceFactory.AddDocument(project, source, additionalSources);

                Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                VerifyCompilerDiagnostics(compilerDiagnostics, options);

                if (!Descriptor.IsEnabledByDefault)
                {
                    compilation = compilation.EnsureEnabled(Descriptor);
                }

                ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false);

                if (diagnostics.Length > 0 &&
                    SupportedDiagnostics.Length > 1)
                {
                    VerifyDiagnostics(FilterDiagnostics(diagnostics), expectedDiagnostics, cancellationToken);
                }
                else
                {
                    VerifyDiagnostics(diagnostics, expectedDiagnostics, cancellationToken);
                }
            }

            IEnumerable <Diagnostic> FilterDiagnostics(ImmutableArray <Diagnostic> diagnostics)
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    bool success = false;
                    foreach (Diagnostic expectedDiagnostic in expectedDiagnostics)
                    {
                        if (DiagnosticComparer.Id.Equals(diagnostic, expectedDiagnostic))
                        {
                            success = true;
                            break;
                        }
                    }

                    if (success)
                    {
                        yield return(diagnostic);
                    }
                }
            }
        }
Ejemplo n.º 13
0
 public Document CreateDocument(Solution solution, string source, CodeVerificationOptions options)
 {
     return(CreateDocument(solution, source, additionalSource: null, options));
 }
Ejemplo n.º 14
0
        public Document CreateDocument(Solution solution, string source, IEnumerable <string> additionalSource, CodeVerificationOptions options)
        {
            Project project = AddProject(solution, options);

            return(AddDocument(project, source, additionalSource));
        }
Ejemplo n.º 15
0
        public async Task VerifyRefactoringAsync(
            string source,
            string expected,
            TextSpan span,
            IEnumerable <string> additionalSources = null,
            string equivalenceKey               = null,
            CodeVerificationOptions options     = null,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            options ??= Options;

            using (Workspace workspace = new AdhocWorkspace())
            {
                Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options);

                Document document = WorkspaceFactory.AddDocument(project, source, additionalSources);

                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);

                VerifyCompilerDiagnostics(compilerDiagnostics, options);
                CodeAction action = null;

                var context = new CodeRefactoringContext(
                    document,
                    span,
                    a =>
                {
                    if (equivalenceKey == null ||
                        string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                    {
                        if (action == null)
                        {
                            action = a;
                        }
                    }
                },
                    CancellationToken.None);

                await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false);

                Assert.True(action != null, "No code refactoring has been registered.");

                document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false);

                semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);

                VerifyCompilerDiagnostics(newCompilerDiagnostics, options);

                VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options);

                string actual = await document.ToFullStringAsync(simplify : true, format : true, cancellationToken).ConfigureAwait(false);

                Assert.Equal(expected, actual);
            }
        }
Ejemplo n.º 16
0
 public virtual Project AddProject(Solution solution, CodeVerificationOptions options)
 {
     return(solution
            .AddProject(DefaultProjectName, DefaultProjectName, Language)
            .WithMetadataReferences(options.MetadataReferences));
 }
Ejemplo n.º 17
0
        internal void VerifyNoNewCompilerDiagnostics(
            ImmutableArray <Diagnostic> diagnostics,
            ImmutableArray <Diagnostic> newDiagnostics,
            CodeVerificationOptions options)
        {
            ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds;

            if (allowedDiagnosticIds.IsDefault)
            {
                allowedDiagnosticIds = ImmutableArray <string> .Empty;
            }

            if (IsAnyNewCompilerDiagnostic())
            {
                IEnumerable <Diagnostic> diff = newDiagnostics
                                                .Where(diagnostic => !allowedDiagnosticIds.Any(id => id == diagnostic.Id))
                                                .Except(diagnostics, DiagnosticDeepEqualityComparer.Instance);

                Assert.True(false, $"Code fix introduced new compiler diagnostics.{diff.ToDebugString()}");
            }

            bool IsAnyNewCompilerDiagnostic()
            {
                foreach (Diagnostic newDiagnostic in newDiagnostics)
                {
                    if (!IsAllowed(newDiagnostic) &&
                        !EqualsAny(newDiagnostic))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            bool IsAllowed(Diagnostic diagnostic)
            {
                foreach (string diagnosticId in allowedDiagnosticIds)
                {
                    if (diagnostic.Id == diagnosticId)
                    {
                        return(true);
                    }
                }

                return(false);
            }

            bool EqualsAny(Diagnostic newDiagnostic)
            {
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (DiagnosticDeepEqualityComparer.Instance.Equals(diagnostic, newDiagnostic))
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }