protected async Task TestActionsOnLinkedFiles(
            TestWorkspace workspace,
            string expectedText,
            int index,
            ImmutableArray <CodeAction> actions,
            string expectedPreviewContents = null,
            bool ignoreTrivia = true)
        {
            var operations = await VerifyInputsAndGetOperationsAsync(index, actions);

            await VerifyPreviewContents(workspace, expectedPreviewContents, operations);

            var applyChangesOperation = operations.OfType <ApplyChangesOperation>().First();

            applyChangesOperation.TryApply(workspace, new ProgressTracker(), CancellationToken.None);

            foreach (var document in workspace.Documents)
            {
                var fixedRoot = await workspace.CurrentSolution.GetDocument(document.Id).GetSyntaxRootAsync();

                var actualText = ignoreTrivia ? fixedRoot.ToString() : fixedRoot.ToFullString();

                if (ignoreTrivia)
                {
                    TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
                }
                else
                {
                    Assert.Equal(expectedText, actualText);
                }
            }
        }
Example #2
0
 public void Dispose()
 {
     try
     {
         if (!_ignoreResult)
         {
             this.Document = this.Result;
             if (_compareTokens)
             {
                 var actual = string.Join(" ", Simplifier.ReduceAsync(this.Document, Simplifier.Annotation).Result.GetSyntaxRootAsync().Result.DescendantTokens());
                 TokenUtilities.AssertTokensEqual(_expected, actual, _language);
             }
             else
             {
                 var actual = Formatter.FormatAsync(Simplifier.ReduceAsync(this.Document, Simplifier.Annotation).Result, Formatter.Annotation).Result
                              .GetSyntaxRootAsync().Result.ToFullString();
                 Assert.Equal(_expected, actual);
             }
         }
     }
     finally
     {
         _workspace.Dispose();
     }
 }
        internal void Test(
            Func <SyntaxGenerator, SyntaxNode> nodeCreator,
            string cs, string vb)
        {
            var hostServices = MefV1HostServices.Create(TestExportProvider.ExportProviderWithCSharpAndVisualBasic.AsExportProvider());
            var workspace    = new AdhocWorkspace(hostServices);

            if (cs != null)
            {
                var csharpCodeGenService = workspace.Services.GetLanguageServices(LanguageNames.CSharp).GetService <ICodeGenerationService>();
                var codeDefFactory       = workspace.Services.GetLanguageServices(LanguageNames.CSharp).GetService <SyntaxGenerator>();

                var node = nodeCreator(codeDefFactory);
                node = node.NormalizeWhitespace();
                TokenUtilities.AssertTokensEqual(cs, node.ToFullString(), LanguageNames.CSharp);
            }

            if (vb != null)
            {
                var visualBasicCodeGenService = workspace.Services.GetLanguageServices(LanguageNames.VisualBasic).GetService <ICodeGenerationService>();
                var codeDefFactory            = workspace.Services.GetLanguageServices(LanguageNames.VisualBasic).GetService <SyntaxGenerator>();

                var node = nodeCreator(codeDefFactory);
                node = node.NormalizeWhitespace();
                TokenUtilities.AssertTokensEqual(vb, node.ToString(), LanguageNames.VisualBasic);
            }
        }
        protected void TestActionsOnLinkedFiles(
            TestWorkspace workspace,
            string expectedText,
            int index,
            IList <CodeAction> actions,
            string expectedPreviewContents = null,
            bool compareTokens             = true)
        {
            var operations = VerifyInputsAndGetOperations(index, actions);

            VerifyPreviewContents(workspace, expectedPreviewContents, operations);

            var applyChangesOperation = operations.OfType <ApplyChangesOperation>().First();

            applyChangesOperation.Apply(workspace, CancellationToken.None);

            foreach (var document in workspace.Documents)
            {
                var fixedRoot  = workspace.CurrentSolution.GetDocument(document.Id).GetSyntaxRootAsync().Result;
                var actualText = compareTokens ? fixedRoot.ToString() : fixedRoot.ToFullString();

                if (compareTokens)
                {
                    TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
                }
                else
                {
                    Assert.Equal(expectedText, actualText);
                }
            }
        }
Example #5
0
        protected async Task TestMoveTypeToNewFileAsync(
            string originalCode,
            string expectedSourceTextAfterRefactoring,
            string expectedDocumentName,
            string destinationDocumentText,
            IList <string> destinationDocumentContainers = null,
            bool expectedCodeAction = true,
            int index         = 0,
            bool ignoreTrivia = true,
            Action <Workspace> onAfterWorkspaceCreated = null)
        {
            var testOptions = new TestParameters();

            if (expectedCodeAction)
            {
                using (var workspace = await CreateWorkspaceFromFileAsync(originalCode, testOptions))
                {
                    onAfterWorkspaceCreated?.Invoke(workspace);

                    // replace with default values on null.
                    if (destinationDocumentContainers == null)
                    {
                        destinationDocumentContainers = Array.Empty <string>();
                    }

                    var sourceDocumentId = workspace.Documents[0].Id;

                    // Verify the newly added document and its text
                    var oldSolutionAndNewSolution = await TestAddDocumentAsync(
                        testOptions, workspace,
                        destinationDocumentText, index, expectedDocumentName,
                        destinationDocumentContainers, ignoreTrivia);

                    // Verify source document's text after moving type.
                    var oldSolution        = oldSolutionAndNewSolution.Item1;
                    var newSolution        = oldSolutionAndNewSolution.Item2;
                    var changedDocumentIds = SolutionUtilities.GetChangedDocuments(oldSolution, newSolution);
                    Assert.True(changedDocumentIds.Contains(sourceDocumentId), "source document was not changed.");

                    var modifiedSourceDocument = newSolution.GetDocument(sourceDocumentId);

                    if (ignoreTrivia)
                    {
                        TokenUtilities.AssertTokensEqual(
                            expectedSourceTextAfterRefactoring, (await modifiedSourceDocument.GetTextAsync()).ToString(), GetLanguage());
                    }
                    else
                    {
                        Assert.Equal(expectedSourceTextAfterRefactoring, (await modifiedSourceDocument.GetTextAsync()).ToString());
                    }
                }
            }
            else
            {
                await TestMissingAsync(originalCode);
            }
        }
        protected void TestActions(
            TestWorkspace workspace,
            string expectedText,
            int index,
            IList <CodeAction> actions,
            IList <TextSpan> expectedConflictSpans = null,
            IList <TextSpan> expectedRenameSpans   = null,
            IList <TextSpan> expectedWarningSpans  = null,
            string expectedPreviewContents         = null,
            bool compareTokens = true,
            bool compareExpectedTextAfterApply = false)
        {
            var operations = VerifyInputsAndGetOperations(index, actions);

            VerifyPreviewContents(workspace, expectedPreviewContents, operations);

            // Test annotations from the operation's new solution

            var applyChangesOperation = operations.OfType <ApplyChangesOperation>().First();

            var oldSolution = workspace.CurrentSolution;

            var newSolutionFromOperation = applyChangesOperation.ChangedSolution;
            var documentFromOperation    = SolutionUtilities.GetSingleChangedDocument(oldSolution, newSolutionFromOperation);
            var fixedRootFromOperation   = documentFromOperation.GetSyntaxRootAsync().Result;

            TestAnnotations(expectedText, expectedConflictSpans, fixedRootFromOperation, ConflictAnnotation.Kind, compareTokens);
            TestAnnotations(expectedText, expectedRenameSpans, fixedRootFromOperation, RenameAnnotation.Kind, compareTokens);
            TestAnnotations(expectedText, expectedWarningSpans, fixedRootFromOperation, WarningAnnotation.Kind, compareTokens);

            // Test final text

            string actualText;

            if (compareExpectedTextAfterApply)
            {
                applyChangesOperation.Apply(workspace, CancellationToken.None);
                var newSolutionAfterApply = workspace.CurrentSolution;

                var documentFromAfterApply  = SolutionUtilities.GetSingleChangedDocument(oldSolution, newSolutionAfterApply);
                var fixedRootFromAfterApply = documentFromAfterApply.GetSyntaxRootAsync().Result;
                actualText = compareTokens ? fixedRootFromAfterApply.ToString() : fixedRootFromAfterApply.ToFullString();
            }
            else
            {
                actualText = compareTokens ? fixedRootFromOperation.ToString() : fixedRootFromOperation.ToFullString();
            }

            if (compareTokens)
            {
                TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
            }
            else
            {
                Assert.Equal(expectedText, actualText);
            }
        }
Example #7
0
        internal void Test(
            Func <SyntaxGenerator, SyntaxNode> nodeCreator,
            string cs, string csSimple,
            string vb, string vbSimple)
        {
            Assert.True(cs != null || csSimple != null || vb != null || vbSimple != null,
                        $"At least one of {nameof(cs)}, {nameof(csSimple)}, {nameof(vb)}, {nameof(vbSimple)} must be provided");

            var hostServices = VisualStudioMefHostServices.Create(TestExportProvider.ExportProviderWithCSharpAndVisualBasic);
            var workspace    = new AdhocWorkspace(hostServices);

            if (cs != null || csSimple != null)
            {
                var codeDefFactory = workspace.Services.GetLanguageServices(LanguageNames.CSharp).GetService <SyntaxGenerator>();

                var node = nodeCreator(codeDefFactory);
                node = node.NormalizeWhitespace();

                if (cs != null)
                {
                    TokenUtilities.AssertTokensEqual(cs, node.ToFullString(), LanguageNames.CSharp);
                }

                if (csSimple != null)
                {
                    var simplifiedRootNode = Simplify(workspace, WrapExpressionInBoilerplate(node, codeDefFactory), LanguageNames.CSharp);
                    var expression         = simplifiedRootNode.DescendantNodes().OfType <EqualsValueClauseSyntax>().First().Value;

                    TokenUtilities.AssertTokensEqual(csSimple, expression.NormalizeWhitespace().ToFullString(), LanguageNames.CSharp);
                }
            }

            if (vb != null || vbSimple != null)
            {
                var codeDefFactory = workspace.Services.GetLanguageServices(LanguageNames.VisualBasic).GetService <SyntaxGenerator>();

                var node = nodeCreator(codeDefFactory);
                node = node.NormalizeWhitespace();

                if (vb != null)
                {
                    TokenUtilities.AssertTokensEqual(vb, node.ToFullString(), LanguageNames.VisualBasic);
                }

                if (vbSimple != null)
                {
                    var simplifiedRootNode = Simplify(workspace, WrapExpressionInBoilerplate(node, codeDefFactory), LanguageNames.VisualBasic);
                    var expression         = simplifiedRootNode.DescendantNodes().OfType <EqualsValueSyntax>().First().Value;

                    TokenUtilities.AssertTokensEqual(vbSimple, expression.NormalizeWhitespace().ToFullString(), LanguageNames.VisualBasic);
                }
            }
        }
        protected async Task <Tuple <Solution, Solution> > TestOperationsAsync(
            TestWorkspace workspace,
            string expectedText,
            IList <CodeActionOperation> operations,
            IList <TextSpan> conflictSpans,
            IList <TextSpan> renameSpans,
            IList <TextSpan> warningSpans,
            bool compareTokens,
            DocumentId expectedChangedDocumentId,
            ParseOptions parseOptions = null)
        {
            var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations);
            var oldSolution    = appliedChanges.Item1;
            var newSolution    = appliedChanges.Item2;

            if (IsWorkspaceElement(expectedText))
            {
                await VerifyAgainstWorkspaceDefinitionAsync(expectedText, newSolution);

                return(Tuple.Create(oldSolution, newSolution));
            }

            var document = GetDocumentToVerify(expectedChangedDocumentId, oldSolution, newSolution);

            var fixedRoot = await document.GetSyntaxRootAsync();

            var actualText = compareTokens ? fixedRoot.ToString() : fixedRoot.ToFullString();

            if (compareTokens)
            {
                TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
            }
            else
            {
                Assert.Equal(expectedText, actualText);
            }

            TestAnnotations(expectedText, conflictSpans, fixedRoot, ConflictAnnotation.Kind, compareTokens, parseOptions);
            TestAnnotations(expectedText, renameSpans, fixedRoot, RenameAnnotation.Kind, compareTokens, parseOptions);
            TestAnnotations(expectedText, warningSpans, fixedRoot, WarningAnnotation.Kind, compareTokens, parseOptions);

            return(Tuple.Create(oldSolution, newSolution));
        }
        private void TestAddDocument(
            TestWorkspace workspace,
            string expected,
            int index,
            IList <string> expectedFolders,
            string expectedDocumentName,
            IList <CodeAction> fixes,
            bool compareTokens)
        {
            Assert.NotNull(fixes);
            Assert.InRange(index, 0, fixes.Count - 1);

            var operations            = fixes[index].GetOperationsAsync(CancellationToken.None).Result;
            var applyChangesOperation = operations.OfType <ApplyChangesOperation>().First();
            var oldSolution           = workspace.CurrentSolution;
            var newSolution           = applyChangesOperation.ChangedSolution;

            var addedDocument = SolutionUtilities.GetSingleAddedDocument(oldSolution, newSolution);

            Assert.NotNull(addedDocument);

            AssertEx.Equal(expectedFolders, addedDocument.Folders);
            Assert.Equal(expectedDocumentName, addedDocument.Name);
            if (compareTokens)
            {
                TokenUtilities.AssertTokensEqual(
                    expected, addedDocument.GetTextAsync().Result.ToString(), GetLanguage());
            }
            else
            {
                Assert.Equal(expected, addedDocument.GetTextAsync().Result.ToString());
            }

            var editHandler = workspace.ExportProvider.GetExportedValue <ICodeActionEditHandlerService>();
            var content     = editHandler.GetPreview(workspace, operations, CancellationToken.None);
            var textView    = content as IWpfTextView;

            Assert.NotNull(textView);

            textView.Close();
        }
        private async Task <Tuple <Solution, Solution> > TestAddDocument(
            TestWorkspace workspace,
            string expected,
            IEnumerable <CodeActionOperation> operations,
            bool hasProjectChange,
            ProjectId modifiedProjectId,
            IList <string> expectedFolders,
            string expectedDocumentName,
            bool compareTokens)
        {
            var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations);
            var oldSolution    = appliedChanges.Item1;
            var newSolution    = appliedChanges.Item2;

            Document addedDocument = null;

            if (!hasProjectChange)
            {
                addedDocument = SolutionUtilities.GetSingleAddedDocument(oldSolution, newSolution);
            }
            else
            {
                Assert.NotNull(modifiedProjectId);
                addedDocument = newSolution.GetProject(modifiedProjectId).Documents.SingleOrDefault(doc => doc.Name == expectedDocumentName);
            }

            Assert.NotNull(addedDocument);

            AssertEx.Equal(expectedFolders, addedDocument.Folders);
            Assert.Equal(expectedDocumentName, addedDocument.Name);
            if (compareTokens)
            {
                TokenUtilities.AssertTokensEqual(
                    expected, (await addedDocument.GetTextAsync()).ToString(), GetLanguage());
            }
            else
            {
                Assert.Equal(expected, (await addedDocument.GetTextAsync()).ToString());
            }

            var editHandler = workspace.ExportProvider.GetExportedValue <ICodeActionEditHandlerService>();

            if (!hasProjectChange)
            {
                // If there is just one document change then we expect the preview to be a WpfTextView
                var content  = (await editHandler.GetPreviews(workspace, operations, CancellationToken.None).GetPreviewsAsync())[0];
                var diffView = content as IWpfDifferenceViewer;
                Assert.NotNull(diffView);
                diffView.Close();
            }
            else
            {
                // If there are more changes than just the document we need to browse all the changes and get the document change
                var  contents   = editHandler.GetPreviews(workspace, operations, CancellationToken.None);
                bool hasPreview = false;
                var  previews   = await contents.GetPreviewsAsync();

                if (previews != null)
                {
                    foreach (var preview in previews)
                    {
                        if (preview != null)
                        {
                            var diffView = preview as IWpfDifferenceViewer;
                            if (diffView != null)
                            {
                                hasPreview = true;
                                diffView.Close();
                                break;
                            }
                        }
                    }
                }

                Assert.True(hasPreview);
            }

            return(Tuple.Create(oldSolution, newSolution));
        }
Example #11
0
        protected async Task <Tuple <Solution, Solution> > TestOperationsAsync(
            TestWorkspace workspace,
            string expectedText,
            ImmutableArray <CodeActionOperation> operations,
            ImmutableArray <TextSpan> conflictSpans,
            ImmutableArray <TextSpan> renameSpans,
            ImmutableArray <TextSpan> warningSpans,
            bool ignoreTrivia,
            DocumentId expectedChangedDocumentId,
            ParseOptions parseOptions = null)
        {
            var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations);
            var oldSolution    = appliedChanges.Item1;
            var newSolution    = appliedChanges.Item2;

            if (TestWorkspace.IsWorkspaceElement(expectedText))
            {
                await VerifyAgainstWorkspaceDefinitionAsync(expectedText, newSolution);

                return(Tuple.Create(oldSolution, newSolution));
            }

            var document = GetDocumentToVerify(expectedChangedDocumentId, oldSolution, newSolution);

            var fixedRoot = await document.GetSyntaxRootAsync();

            var actualText = ignoreTrivia ? fixedRoot.ToString() : fixedRoot.ToFullString();

            if (ignoreTrivia)
            {
                TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
            }
            else
            {
                Assert.Equal(expectedText, actualText);
            }

            TestAnnotations(conflictSpans, ConflictAnnotation.Kind);
            TestAnnotations(renameSpans, RenameAnnotation.Kind);
            TestAnnotations(warningSpans, WarningAnnotation.Kind);

            return(Tuple.Create(oldSolution, newSolution));

            void TestAnnotations(ImmutableArray <TextSpan> expectedSpans, string annotationKind)
            {
                var annotatedTokens = fixedRoot.GetAnnotatedNodesAndTokens(annotationKind).Select(n => (SyntaxToken)n).ToList();

                Assert.Equal(expectedSpans.Length, annotatedTokens.Count);

                if (expectedSpans.Length > 0)
                {
                    var expectedTokens = TokenUtilities.GetTokens(TokenUtilities.GetSyntaxRoot(expectedText, GetLanguage(), parseOptions));
                    var actualTokens   = TokenUtilities.GetTokens(fixedRoot);

                    for (var i = 0; i < Math.Min(expectedTokens.Count, actualTokens.Count); i++)
                    {
                        var expectedToken = expectedTokens[i];
                        var actualToken   = actualTokens[i];

                        var actualIsConflict   = annotatedTokens.Contains(actualToken);
                        var expectedIsConflict = expectedSpans.Contains(expectedToken.Span);
                        Assert.Equal(expectedIsConflict, actualIsConflict);
                    }
                }
            }
        }
        protected Tuple <Solution, Solution> TestActions(
            TestWorkspace workspace,
            string expectedText,
            IEnumerable <CodeActionOperation> operations,
            DocumentId expectedChangedDocumentId   = null,
            IList <TextSpan> expectedConflictSpans = null,
            IList <TextSpan> expectedRenameSpans   = null,
            IList <TextSpan> expectedWarningSpans  = null,
            bool compareTokens   = true,
            bool isAddedDocument = false)
        {
            var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations);
            var oldSolution    = appliedChanges.Item1;
            var newSolution    = appliedChanges.Item2;

            Document document = null;

            if (expectedText.TrimStart('\r', '\n', ' ').StartsWith(@"<Workspace>"))
            {
                using (var expectedWorkspace = TestWorkspaceFactory.CreateWorkspace(expectedText))
                {
                    var expectedSolution = expectedWorkspace.CurrentSolution;
                    Assert.Equal(expectedSolution.Projects.Count(), newSolution.Projects.Count());
                    foreach (var project in newSolution.Projects)
                    {
                        var expectedProject = expectedSolution.GetProjectsByName(project.Name).Single();
                        Assert.Equal(expectedProject.Documents.Count(), project.Documents.Count());

                        foreach (var doc in project.Documents)
                        {
                            var root             = doc.GetSyntaxRootAsync().Result;
                            var expectedDocument = expectedProject.Documents.Single(d => d.Name == doc.Name);
                            var expectedRoot     = expectedDocument.GetSyntaxRootAsync().Result;
                            Assert.Equal(expectedRoot.ToFullString(), root.ToFullString());
                        }
                    }
                }
            }
            else
            {
                // If the expectedChangedDocumentId is not mentioned then we expect only single document to be changed
                if (expectedChangedDocumentId == null)
                {
                    if (!isAddedDocument)
                    {
                        // This method assumes that only one document changed and rest(Project state) remains unchanged
                        document = SolutionUtilities.GetSingleChangedDocument(oldSolution, newSolution);
                    }
                    else
                    {
                        // This method assumes that only one document added and rest(Project state) remains unchanged
                        document = SolutionUtilities.GetSingleAddedDocument(oldSolution, newSolution);
                        Assert.Empty(SolutionUtilities.GetChangedDocuments(oldSolution, newSolution));
                    }
                }
                else
                {
                    // This method obtains only the document changed and does not check the project state.
                    document = newSolution.GetDocument(expectedChangedDocumentId);
                }

                var fixedRoot  = document.GetSyntaxRootAsync().Result;
                var actualText = compareTokens ? fixedRoot.ToString() : fixedRoot.ToFullString();

                if (compareTokens)
                {
                    TokenUtilities.AssertTokensEqual(expectedText, actualText, GetLanguage());
                }
                else
                {
                    Assert.Equal(expectedText, actualText);
                }

                TestAnnotations(expectedText, expectedConflictSpans, fixedRoot, ConflictAnnotation.Kind, compareTokens);
                TestAnnotations(expectedText, expectedRenameSpans, fixedRoot, RenameAnnotation.Kind, compareTokens);
                TestAnnotations(expectedText, expectedWarningSpans, fixedRoot, WarningAnnotation.Kind, compareTokens);
            }

            return(Tuple.Create(oldSolution, newSolution));
        }