예제 #1
0
        public async Task TestGetFixesAsyncForDocumentDiagnosticAnalyzerAsync()
        {
            // TS has special DocumentDiagnosticAnalyzer that report 0 SupportedDiagnostics.
            // We need to ensure that we don't skip these document analyzers
            // when computing the diagnostics/code fixes for "Normal" priority bucket, which
            // normally only execute those analyzers which report at least one fixable supported diagnostic.
            var documentDiagnosticAnalyzer = new MockAnalyzerReference.MockDocumentDiagnosticAnalyzer(reportedDiagnosticIds: ImmutableArray <string> .Empty);

            Assert.Empty(documentDiagnosticAnalyzer.SupportedDiagnostics);

            var analyzers         = ImmutableArray.Create <DiagnosticAnalyzer>(documentDiagnosticAnalyzer);
            var codeFix           = new MockFixer();
            var analyzerReference = new MockAnalyzerReference(codeFix, analyzers);

            // Verify no callbacks received at initialization.
            Assert.False(documentDiagnosticAnalyzer.ReceivedCallback);

            var tuple = ServiceSetup(codeFix, includeConfigurationFixProviders: false);

            using var workspace = tuple.workspace;
            GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager, analyzerReference);

            // Verify both analyzers are executed when GetFixesAsync is invoked with 'CodeActionRequestPriority.Normal'.
            _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0),
                                                         priority : CodeActionRequestPriority.Normal, CodeActionOptions.DefaultProvider, isBlocking : false,
                                                         addOperationScope : _ => null, cancellationToken : CancellationToken.None);

            Assert.True(documentDiagnosticAnalyzer.ReceivedCallback);
        }
예제 #2
0
        public async Task TestGetFixesAsyncWithDuplicateDiagnostics()
        {
            var codeFix = new MockFixer();

            // Add duplicate analyzers to get duplicate diagnostics.
            var analyzerReference = new MockAnalyzerReference(
                codeFix,
                ImmutableArray.Create <DiagnosticAnalyzer>(
                    new MockAnalyzerReference.MockDiagnosticAnalyzer(),
                    new MockAnalyzerReference.MockDiagnosticAnalyzer()));

            var tuple = ServiceSetup(codeFix);

            using var workspace = tuple.workspace;
            GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager, analyzerReference);

            // Verify that we do not crash when computing fixes.
            var options = CodeActionOptions.Default;

            _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0), options, CancellationToken.None);

            // Verify that code fix is invoked with both the diagnostics in the context,
            // i.e. duplicate diagnostics are not silently discarded by the CodeFixService.
            Assert.Equal(2, codeFix.ContextDiagnosticsCount);
        }
예제 #3
0
        public async Task TestGetFixesAsyncHasNoDuplicateConfigurationActions()
        {
            var codeFix = new MockFixer();

            // Add analyzers with duplicate ID and/or category to get duplicate diagnostics.
            var analyzerReference = new MockAnalyzerReference(
                codeFix,
                ImmutableArray.Create <DiagnosticAnalyzer>(
                    new MockAnalyzerReference.MockDiagnosticAnalyzer("ID1", "Category1"),
                    new MockAnalyzerReference.MockDiagnosticAnalyzer("ID1", "Category1"),
                    new MockAnalyzerReference.MockDiagnosticAnalyzer("ID1", "Category2"),
                    new MockAnalyzerReference.MockDiagnosticAnalyzer("ID2", "Category2")));

            var tuple = ServiceSetup(codeFix, includeConfigurationFixProviders: true);

            using var workspace = tuple.workspace;
            GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager, analyzerReference);

            // Verify registered configuration code actions do not have duplicates.
            var fixCollections = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0), CodeActionOptions.DefaultProvider, isBlocking : false, CancellationToken.None);

            var codeActions = fixCollections.SelectMany(c => c.Fixes.Select(f => f.Action)).ToImmutableArray();

            Assert.Equal(7, codeActions.Length);
            var uniqueTitles = new HashSet <string>();

            foreach (var codeAction in codeActions)
            {
                Assert.True(codeAction is AbstractConfigurationActionWithNestedActions);
                Assert.True(uniqueTitles.Add(codeAction.Title));
            }
        }
예제 #4
0
        public async Task TestGetFixesAsyncForFixableAndNonFixableAnalyzersAsync()
        {
            var codeFix         = new MockFixer();
            var analyzerWithFix = new MockAnalyzerReference.MockDiagnosticAnalyzer();

            Assert.Equal(codeFix.FixableDiagnosticIds.Single(), analyzerWithFix.SupportedDiagnostics.Single().Id);

            var analyzerWithoutFix = new MockAnalyzerReference.MockDiagnosticAnalyzer("AnalyzerWithoutFixId", "Category");
            var analyzers          = ImmutableArray.Create <DiagnosticAnalyzer>(analyzerWithFix, analyzerWithoutFix);
            var analyzerReference  = new MockAnalyzerReference(codeFix, analyzers);

            // Verify no callbacks received at initialization.
            Assert.False(analyzerWithFix.ReceivedCallback);
            Assert.False(analyzerWithoutFix.ReceivedCallback);

            var tuple = ServiceSetup(codeFix, includeConfigurationFixProviders: true);

            using var workspace = tuple.workspace;
            GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager, analyzerReference);

            var options = CodeActionOptions.Default;

            // Verify only analyzerWithFix is executed when GetFixesAsync is invoked with 'CodeActionRequestPriority.Normal'.
            _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0),
                                                         priority : CodeActionRequestPriority.Normal, options,
                                                         addOperationScope : _ => null, cancellationToken : CancellationToken.None);

            Assert.True(analyzerWithFix.ReceivedCallback);
            Assert.False(analyzerWithoutFix.ReceivedCallback);

            // Verify both analyzerWithFix and analyzerWithoutFix are executed when GetFixesAsync is invoked with 'CodeActionRequestPriority.Lowest'.
            _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0),
                                                         priority : CodeActionRequestPriority.Lowest, options,
                                                         addOperationScope : _ => null, cancellationToken : CancellationToken.None);

            Assert.True(analyzerWithFix.ReceivedCallback);
            Assert.True(analyzerWithoutFix.ReceivedCallback);
        }