public async Task WorkspaceChanged_DocumentChanged_Razor_UpdatesProjectState_AfterDelay() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator) { EnqueueDelay = 1, BlockDelayedUpdateWorkEnqueue = new ManualResetEventSlim(initialState: false), }; Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); workspaceStateGenerator.ClearQueue(); var solution = SolutionWithTwoProjects.WithDocumentText(RazorDocumentId, SourceText.From("Hello World")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id, RazorDocumentId); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); detector.BlockDelayedUpdateWorkEnqueue.Set(); await detector._deferredUpdates.Single().Value.Task; var(workspaceProject, projectSnapshot) = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(workspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(projectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task ProjectOperations_EndBuild_ProjectWithoutWorkspaceProject_Noops() { // Arrange var expectedPath = "Path/To/Project.csproj"; var projectService = CreateProjectService(expectedPath); var args = new BuildEventArgs(monitor: null, success: true); var projectSnapshot = new DefaultProjectSnapshot( ProjectState.Create( Workspace.Services, new HostProject(expectedPath, RazorConfiguration.Default, "Project"))); var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Returns(Workspace); projectManager .Setup(p => p.GetLoadedProject(expectedPath)) .Returns(projectSnapshot); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new ProjectBuildChangeTrigger(Dispatcher, projectService, workspaceStateGenerator, projectManager.Object); // Act await trigger.HandleEndBuildAsync(args); // Assert Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public async Task WorkspaceChanged_DocumentChanged_CSHTML_UpdatesProjectState_AfterDelay() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator) { EnqueueDelay = 50, }; Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); workspaceStateGenerator.ClearQueue(); var solution = SolutionWithTwoProjects.WithDocumentText(CshtmlDocumentId, SourceText.From("Hello World")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id, CshtmlDocumentId); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); await detector._deferredUpdates.Single().Value; var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.workspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.projectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task SolutionClosing_StopsActiveWork() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); WorkQueueTestAccessor.NotifyBackgroundWorkStarting = new ManualResetEventSlim(initialState: false); Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => projectManager.ProjectAdded(HostProjectOne), CancellationToken.None).ConfigureAwait(false); workspaceStateGenerator.ClearQueue(); WorkQueueTestAccessor.NotifyBackgroundWorkStarting.Wait(); // Act await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.SolutionClosed(); // Trigger a project removed event while solution is closing to clear state. projectManager.ProjectRemoved(HostProjectOne); }, CancellationToken.None).ConfigureAwait(false); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public async Task IsPartialComponentClass_NonComponents_ReturnsFalse() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var sourceText = SourceText.From( $@" public partial class NonComponent1 {{}} public class NonComponent2 {{}} public partial class NonComponent3 {{}} public class NonComponent4 {{}} namespace Microsoft.AspNetCore.Components {{ public interface IComponent {{}} }} "); var syntaxTreeRoot = CSharpSyntaxTree.ParseText(sourceText).GetRoot(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // Initialize document await document.GetSyntaxRootAsync(); await document.GetSemanticModelAsync(); // Act var result = detector.IsPartialComponentClass(document); // Assert Assert.False(result); }
public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_AfterDelay(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator) { EnqueueDelay = 1, BlockDelayedUpdateWorkEnqueue = new ManualResetEventSlim(initialState: false), }; var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); var solution = SolutionWithTwoProjects.WithProjectAssemblyName(ProjectNumberOne.Id, "Changed"); var e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); detector.BlockDelayedUpdateWorkEnqueue.Set(); await detector._deferredUpdates.Single().Value; var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.workspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.projectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task IsPartialComponentClass_InitializedDocument_ReturnsTrue() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue); var sourceText = SourceText.From( $@" public partial class TestComponent : {ComponentsApi.IComponent.MetadataName} {{}} namespace Microsoft.AspNetCore.Components {{ public interface IComponent {{}} }} "); var syntaxTreeRoot = await CSharpSyntaxTree.ParseText(sourceText).GetRootAsync(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // Initialize document await document.GetSyntaxRootAsync(); await document.GetSemanticModelAsync(); // Act var result = detector.IsPartialComponentClass(document); // Assert Assert.True(result); }
public async Task SolutionClosing_CancelsActiveWork() { // Arrange var projectManager = new TestProjectSnapshotManager(Workspace) { AllowNotifyListeners = true, }; var expectedProjectPath = SomeProject.FilePath; var expectedProjectSnapshot = await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(SomeProject); projectManager.ProjectAdded(SomeOtherProject); return(projectManager.GetLoadedProject(SomeProject.FilePath)); }, CancellationToken.None); var projectService = new Mock <TextBufferProjectService>(MockBehavior.Strict); projectService.Setup(p => p.GetProjectPath(It.IsAny <IVsHierarchy>())).Returns(expectedProjectPath); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger(TestServiceProvider.Instance, projectService.Object, workspaceStateGenerator, Dispatcher, JoinableTaskFactory.Context); trigger.Initialize(projectManager); trigger.UpdateProjectCfg_Done(Mock.Of <IVsHierarchy>(MockBehavior.Strict), pCfgProj: default, pCfgSln: default, dwAction: default, fSuccess: default, fCancel: default);
public async Task ProjectOperations_EndBuild_EnqueuesProjectStateUpdate() { // Arrange var expectedProjectPath = SomeProject.FilePath; var projectService = CreateProjectService(expectedProjectPath); var args = new BuildEventArgs(monitor: null, success: true); var projectSnapshot = new DefaultProjectSnapshot(ProjectState.Create(Workspace.Services, SomeProject)); var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Returns(Workspace); projectManager .Setup(p => p.GetLoadedProject(SomeProject.FilePath)) .Returns(projectSnapshot); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new ProjectBuildChangeTrigger(Dispatcher, projectService, workspaceStateGenerator, projectManager.Object); // Act await trigger.HandleEndBuildAsync(args); Thread.Sleep(500); // Assert var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(SomeWorkspaceProject, update.workspaceProject); }
public async Task WorkspaceChanged_DocumentChanged_Razor_UpdatesProjectState_AfterDelay() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => projectManager.ProjectAdded(HostProjectOne), CancellationToken.None).ConfigureAwait(false); workspaceStateGenerator.ClearQueue(); var solution = SolutionWithTwoProjects.WithDocumentText(RazorDocumentId, SourceText.From("Hello World")); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id, RazorDocumentId); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.WorkspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.ProjectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task WorkspaceChanged_ProjectRemovedEvent_QueuesProjectStateRemoval() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue) { NotifyWorkspaceChangedEventComplete = new ManualResetEventSlim(initialState: false), }; var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); }, CancellationToken.None).ConfigureAwait(false); var solution = SolutionWithTwoProjects.RemoveProject(ProjectNumberOne.Id); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.ProjectRemoved, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Null(p.WorkspaceProject)); }
public async Task WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSolution(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue) { NotifyWorkspaceChangedEventComplete = new ManualResetEventSlim(initialState: false), }; var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); }, CancellationToken.None).ConfigureAwait(false); var e = new WorkspaceChangeEventArgs(kind, oldSolution: EmptySolution, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberOne.Id, p.WorkspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.WorkspaceProject.Id)); }
public void IsPartialComponentClass_Uninitialized_ReturnsFalse() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var sourceText = SourceText.From( $@" public partial class TestComponent : {ComponentsApi.IComponent.MetadataName} {{}} namespace Microsoft.AspNetCore.Components {{ public interface IComponent {{}} }} "); var syntaxTreeRoot = CSharpSyntaxTree.ParseText(sourceText).GetRoot(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // Act var result = detector.IsPartialComponentClass(document); // Assert Assert.False(result); }
public void WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSolutionProjectUpdates(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); projectManager.ProjectAdded(HostProjectThree); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); detector.Workspace_WorkspaceChanged(Workspace, e); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithOneProject, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberThree.Id, p.workspaceProject.Id), p => Assert.Null(p.workspaceProject), p => Assert.Equal(ProjectNumberOne.Id, p.workspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.workspaceProject.Id)); }
public async Task WorkspaceChanged_DocumentChanged_PartialComponent_UpdatesProjectState_AfterDelay() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator) { EnqueueDelay = 1, BlockDelayedUpdateWorkEnqueue = new ManualResetEventSlim(initialState: false), }; Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); workspaceStateGenerator.ClearQueue(); var sourceText = SourceText.From( $@" public partial class TestComponent : {ComponentsApi.IComponent.MetadataName} {{}} namespace Microsoft.AspNetCore.Components {{ public interface IComponent {{}} }} "); var syntaxTreeRoot = CSharpSyntaxTree.ParseText(sourceText).GetRoot(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // The change detector only operates when a semantic model / syntax tree is available. await document.GetSyntaxRootAsync(); await document.GetSemanticModelAsync(); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: solution, newSolution: solution, projectId: ProjectNumberOne.Id, PartialComponentClassDocumentId); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); detector.BlockDelayedUpdateWorkEnqueue.Set(); await detector._deferredUpdates.Single().Value; var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.workspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.projectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task WorkspaceChanged_DocumentChanged_PartialComponent_UpdatesProjectState_AfterDelay() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); Workspace.TryApplyChanges(SolutionWithTwoProjects); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => projectManager.ProjectAdded(HostProjectOne), CancellationToken.None).ConfigureAwait(false); workspaceStateGenerator.ClearQueue(); var sourceText = SourceText.From( $@" public partial class TestComponent : {ComponentsApi.IComponent.MetadataName} {{}} namespace Microsoft.AspNetCore.Components {{ public interface IComponent {{}} }} "); var syntaxTreeRoot = await CSharpSyntaxTree.ParseText(sourceText).GetRootAsync(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // The change detector only operates when a semantic model / syntax tree is available. await document.GetSyntaxRootAsync(); await document.GetSemanticModelAsync(); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.DocumentChanged, oldSolution: solution, newSolution: solution, projectId: ProjectNumberOne.Id, PartialComponentClassDocumentId); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.WorkspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.ProjectSnapshot.FilePath, HostProjectOne.FilePath); }
public void UpdateProjectCfg_Done_KnownProject_EnqueuesProjectStateUpdate() { // Arrange var expectedProjectPath = SomeProject.FilePath; uint cookie; var buildManager = new Mock <IVsSolutionBuildManager>(MockBehavior.Strict); buildManager .Setup(b => b.AdviseUpdateSolutionEvents(It.IsAny <VsSolutionUpdatesProjectSnapshotChangeTrigger>(), out cookie)) .Returns(VSConstants.S_OK); var services = new Mock <IServiceProvider>(MockBehavior.Strict); services.Setup(s => s.GetService(It.Is <Type>(f => f == typeof(SVsSolutionBuildManager)))).Returns(buildManager.Object); var projectService = new Mock <TextBufferProjectService>(MockBehavior.Strict); projectService.Setup(p => p.GetProjectPath(It.IsAny <IVsHierarchy>())).Returns(expectedProjectPath); var projectSnapshots = new[] { new DefaultProjectSnapshot(ProjectState.Create(Workspace.Services, SomeProject)), new DefaultProjectSnapshot(ProjectState.Create(Workspace.Services, SomeOtherProject)), }; var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Returns(Workspace); projectManager .Setup(p => p.GetLoadedProject(expectedProjectPath)) .Returns(projectSnapshots[0]); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger(services.Object, projectService.Object, workspaceStateGenerator); trigger.Initialize(projectManager.Object); // Act trigger.UpdateProjectCfg_Done(Mock.Of <IVsHierarchy>(MockBehavior.Strict), Mock.Of <IVsCfg>(MockBehavior.Strict), Mock.Of <IVsCfg>(MockBehavior.Strict), 0, 0, 0); // Assert var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.workspaceProject.Id, SomeWorkspaceProject.Id); Assert.Same(update.projectSnapshot, projectSnapshots[0]); }
public async Task WorkspaceChanged_ProjectEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue) { NotifyWorkspaceChangedEventComplete = new ManualResetEventSlim(initialState: false), }; WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); projectManager.ProjectAdded(HostProjectThree); }, CancellationToken.None).ConfigureAwait(false); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); detector.NotifyWorkspaceChangedEventComplete.Reset(); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithOneProject, newSolution: SolutionWithDependentProject); var solution = SolutionWithDependentProject.WithProjectAssemblyName(ProjectNumberThree.Id, "Changed"); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithDependentProject, newSolution: solution, projectId: ProjectNumberThree.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); // Assert Assert.Equal(3, WorkQueueTestAccessor.Work.Count); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberOne.FilePath); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberTwo.FilePath); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberThree.FilePath); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); Assert.Empty(WorkQueueTestAccessor.Work); }
public void ProjectOperations_EndBuild_BuildFailed_Noops() { // Arrange var args = new BuildEventArgs(monitor: null, success: false); var projectService = new Mock <TextBufferProjectService>(); projectService.Setup(p => p.IsSupportedProject(null)).Throws <InvalidOperationException>(); var projectManager = new Mock <ProjectSnapshotManagerBase>(); projectManager.SetupGet(p => p.Workspace).Throws <InvalidOperationException>(); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new ProjectBuildChangeTrigger(Dispatcher, projectService.Object, workspaceStateGenerator, projectManager.Object); // Act trigger.ProjectOperations_EndBuild(null, args); // Assert Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public async Task ProjectOperations_EndBuild_UnsupportedProject_Noops() { // Arrange var args = new BuildEventArgs(monitor: null, success: true); var projectService = new Mock <TextBufferProjectService>(MockBehavior.Strict); projectService.Setup(p => p.IsSupportedProject(null)).Returns(false); var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Throws <InvalidOperationException>(); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new ProjectBuildChangeTrigger(Dispatcher, projectService.Object, workspaceStateGenerator, projectManager.Object); // Act await trigger.HandleEndBuildAsync(args); // Assert Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public void WorkspaceChanged_ProjectAddedEvent_AddsProject() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectThree); var solution = SolutionWithOneProject; var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.ProjectAdded, oldSolution: EmptySolution, newSolution: solution, projectId: ProjectNumberThree.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberThree.Id, p.workspaceProject.Id)); }
public void UpdateProjectCfg_Done_WithoutWorkspaceProject_DoesNotEnqueueUpdate() { // Arrange uint cookie; var buildManager = new Mock <IVsSolutionBuildManager>(MockBehavior.Strict); buildManager .Setup(b => b.AdviseUpdateSolutionEvents(It.IsAny <VsSolutionUpdatesProjectSnapshotChangeTrigger>(), out cookie)) .Returns(VSConstants.S_OK); var services = new Mock <IServiceProvider>(MockBehavior.Strict); services.Setup(s => s.GetService(It.Is <Type>(f => f == typeof(SVsSolutionBuildManager)))).Returns(buildManager.Object); var projectSnapshot = new DefaultProjectSnapshot( ProjectState.Create( Workspace.Services, new HostProject("/Some/Unknown/Path.csproj", RazorConfiguration.Default, "Path"))); var expectedProjectPath = projectSnapshot.FilePath; var projectService = new Mock <TextBufferProjectService>(MockBehavior.Strict); projectService.Setup(p => p.GetProjectPath(It.IsAny <IVsHierarchy>())).Returns(expectedProjectPath); var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Returns(Workspace); projectManager .Setup(p => p.GetLoadedProject(expectedProjectPath)) .Returns(projectSnapshot); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new VsSolutionUpdatesProjectSnapshotChangeTrigger(services.Object, projectService.Object, workspaceStateGenerator); trigger.Initialize(projectManager.Object); // Act trigger.UpdateProjectCfg_Done(Mock.Of <IVsHierarchy>(MockBehavior.Strict), Mock.Of <IVsCfg>(MockBehavior.Strict), Mock.Of <IVsCfg>(MockBehavior.Strict), 0, 0, 0); // Assert Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public void WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSolution(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); var e = new WorkspaceChangeEventArgs(kind, oldSolution: EmptySolution, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberOne.Id, p.workspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.workspaceProject.Id)); }
public void WorkspaceChanged_ProjectRemovedEvent_QueuesProjectStateRemoval() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); var solution = SolutionWithTwoProjects.RemoveProject(ProjectNumberOne.Id); var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.ProjectRemoved, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Null(p.workspaceProject)); }
public async Task ProjectOperations_EndBuild_UntrackedProject_NoopsAsync() { // Arrange var projectService = CreateProjectService(SomeProject.FilePath); var args = new BuildEventArgs(monitor: null, success: true); var projectManager = new Mock <ProjectSnapshotManagerBase>(MockBehavior.Strict); projectManager.SetupGet(p => p.Workspace).Returns(Workspace); projectManager .Setup(p => p.GetLoadedProject(SomeProject.FilePath)) .Returns <ProjectSnapshot>(null); var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var trigger = new ProjectBuildChangeTrigger(Dispatcher, projectService, workspaceStateGenerator, projectManager.Object); // Act await trigger.HandleEndBuildAsync(args); // Assert Assert.Empty(workspaceStateGenerator.UpdateQueue); }
public async Task IsPartialComponentClass_NonClass_ReturnsFalse() { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var sourceText = SourceText.From(string.Empty); var syntaxTreeRoot = CSharpSyntaxTree.ParseText(sourceText).GetRoot(); var solution = SolutionWithTwoProjects .WithDocumentText(PartialComponentClassDocumentId, sourceText) .WithDocumentSyntaxRoot(PartialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity); var document = solution.GetDocument(PartialComponentClassDocumentId); // Initialize document await document.GetSyntaxRootAsync(); await document.GetSemanticModelAsync(); // Act var result = detector.IsPartialComponentClass(document); // Assert Assert.False(result); }