File: SolutionExplorer\SourceGeneratorItemTests.vb
Web Access
Project: ..\..\..\src\VisualStudio\Core\Test\Microsoft.VisualStudio.LanguageServices.UnitTests.vbproj (Microsoft.VisualStudio.LanguageServices.UnitTests)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
 
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.Internal.VisualStudio.PlatformUI
Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
Imports Roslyn.Test.Utilities
 
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
    <UseExportProvider>
    <Trait(Traits.Feature, Traits.Features.Diagnostics)>
    Public Class SourceGeneratorItemTests
        <WpfFact>
        Public Sub SourceGeneratorsListed()
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
 
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
 
                Assert.True(source.HasItems)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
 
                Assert.Equal(GetType(GenerateFileForEachAdditionalFileWithContentsCommented).FullName, generatorItem.Text)
            End Using
        End Sub
 
        <WpfFact>
        Public Async Function PlaceholderItemCreateIfGeneratorProducesNoFiles() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                ' We have items even before we expand, but then must expand to get real items
                Assert.True(generatorFilesItemSource.HasItems)
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
            End Using
        End Function
 
        <WpfFact>
        Public Async Function SingleSourceGeneratedFileProducesItem() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                        <AdditionalDocument FilePath="Test.txt"></AdditionalDocument>
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                ' We have items even before we expand, but then must expand to get real items
                Assert.True(generatorFilesItemSource.HasItems)
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Dim fileItem = Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
                Dim sourceGeneratedDocument = Assert.Single(Await workspace.CurrentSolution.GetProject(projectId).GetSourceGeneratedDocumentsAsync())
 
                Assert.Equal(sourceGeneratedDocument.Name, fileItem.Text)
                Assert.Equal(sourceGeneratedDocument.Id, fileItem.DocumentId)
            End Using
        End Function
 
        <WpfFact>
        Public Async Function MultipleSourceGeneratedFilesProducesSortedItem() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                        <AdditionalDocument FilePath="Test1.txt"></AdditionalDocument>
                        <AdditionalDocument FilePath="Test2.txt"></AdditionalDocument>
                        <AdditionalDocument FilePath="Test3.txt"></AdditionalDocument>
                        <AdditionalDocument FilePath="Test4.txt"></AdditionalDocument>
                        <AdditionalDocument FilePath="Test5.txt"></AdditionalDocument>
                        <AdditionalDocument FilePath="Test6.txt"></AdditionalDocument>
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Dim expectedNames = Aggregate document In workspace.CurrentSolution.GetProject(projectId).AdditionalDocuments
                                    Select document.Name.Replace(".txt", ".generated.cs")
                                    Into ToList()
 
                Assert.Equal(expectedNames, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem).Select(Function(i) i.Text))
            End Using
        End Function
 
        <WpfFact>
        Public Async Function ChangeToRemoveAllGeneratedDocumentsUpdatesListCorrectly() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                        <AdditionalDocument FilePath="Test1.txt"></AdditionalDocument>
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
 
                workspace.OnAdditionalDocumentRemoved(workspace.CurrentSolution.GetProject(projectId).AdditionalDocumentIds.Single())
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
            End Using
        End Function
 
        <WpfFact>
        Public Async Function AddingAGeneratedDocumentUpdatesListCorrectly() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
 
                ' Add a first item and see if it updates correctly
                workspace.OnAdditionalDocumentAdded(
                    DocumentInfo.Create(
                        DocumentId.CreateNewId(projectId),
                        "Test.txt"))
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
 
                ' Add a second item and see if it updates correctly again
                workspace.OnAdditionalDocumentAdded(
                    DocumentInfo.Create(
                        DocumentId.CreateNewId(projectId),
                        "Test2.txt"))
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
                Assert.Equal(2, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem)().Count())
            End Using
        End Function
 
        <WpfFact>
        Public Async Function GeneratedDocumentsStayingTheSameWorksCorrectly() As Task
            Dim workspaceXml =
                <Workspace>
                    <Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
                        <AdditionalDocument FilePath="Test1.txt"></AdditionalDocument>
                    </Project>
                </Workspace>
 
            Using workspace = TestWorkspace.Create(workspaceXml)
                Dim projectId = workspace.Projects.Single().Id
                Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
                Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
                Dim generatorFilesItemSource = CreateSourceGeneratedFilesItemSource(workspace, generatorItem)
 
                Assert.IsAssignableFrom(Of ISupportExpansionEvents)(generatorFilesItemSource).BeforeExpand()
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Dim itemBeforeUpdate = Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
 
                ' Change a document; this will produce updated documents but no new hint path is being introduced or removed
                workspace.OnAdditionalDocumentTextChanged(workspace.CurrentSolution.Projects.Single().AdditionalDocumentIds.Single(),
                    SourceText.From("Changed"),
                    PreservationMode.PreserveValue)
 
                Await WaitForGeneratorsAndItemSourcesAsync(workspace)
 
                Dim itemAfterUpdate = Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
 
                Assert.Same(itemBeforeUpdate, itemAfterUpdate)
            End Using
        End Function
 
        Private Shared Function CreateItemSourceForAnalyzerReference(workspace As TestWorkspace, projectId As ProjectId) As BaseDiagnosticAndGeneratorItemSource
            Dim analyzerReference = New TestGeneratorReference(New GenerateFileForEachAdditionalFileWithContentsCommented())
            workspace.OnAnalyzerReferenceAdded(projectId, analyzerReference)
 
            Return New LegacyDiagnosticItemSource(
                New AnalyzerItem(New AnalyzersFolderItem(workspace, projectId, Nothing, Nothing), analyzerReference, Nothing),
                New FakeAnalyzersCommandHandler,
                workspace.GetService(Of IDiagnosticAnalyzerService))
        End Function
 
        Private Shared Function CreateSourceGeneratedFilesItemSource(workspace As TestWorkspace, generatorItem As SourceGeneratorItem) As Shell.IAttachedCollectionSource
            Dim asyncListener = workspace.GetService(Of IAsynchronousOperationListenerProvider).GetListener(FeatureAttribute.SourceGenerators)
 
            Return New SourceGeneratedFileItemSource(generatorItem, workspace, asyncListener, workspace.GetService(Of IThreadingContext)())
        End Function
 
        Private Shared Function WaitForGeneratorsAndItemSourcesAsync(workspace As TestWorkspace) As Task
            Dim service = workspace.GetService(Of AsynchronousOperationListenerProvider)
 
            ' We wait for the Workspace to ensure that any WorkspaceChanged events have been raised; we wait for SourceGenerators
            ' as that is what refreshes of the list are registered against.
            Return service.WaitAllAsync(workspace, (New String() {FeatureAttribute.Workspace, FeatureAttribute.SourceGenerators}))
        End Function
    End Class
End Namespace