public async Task WhenBaseIntermediateOutputPathNotSet_DoesNotAttemptToAdviseFileChange() { var spMock = new IAsyncServiceProviderMoq(); var fileChangeService = IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(100); spMock.AddService(typeof(SVsFileChangeEx), fileChangeService); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); var watcher = new ProjectAssetFileWatcher(spMock, IProjectTreeProviderFactory.Create(), IUnconfiguredProjectCommonServicesFactory.Create(threadingService: new IProjectThreadingServiceMock()), tasksService, IActiveConfiguredProjectSubscriptionServiceFactory.Create()); var tree = ProjectTreeParser.Parse(@"Root (flags: {ProjectRoot}), FilePath: ""C:\Foo\foo.proj"""); var projectUpdate = IProjectSubscriptionUpdateFactory.FromJson(@"{ ""CurrentState"": { ""ConfigurationGeneral"": { ""Properties"": { ""MSBuildProjectFullPath"": ""C:\\Foo\\foo.proj"" } } } }"); watcher.Load(); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory <Tuple <IProjectTreeSnapshot, IProjectSubscriptionUpdate> > .Create((Tuple.Create(IProjectTreeSnapshotFactory.Create(tree), projectUpdate)))); var fileChangeServiceMock = Mock.Get(fileChangeService); uint cookie; fileChangeServiceMock.Verify(s => s.AdviseFileChange(It.IsAny <string>(), It.IsAny <uint>(), watcher, out cookie), Times.Never()); }
public async Task VerifyFileWatcherRegistrationOnTreeChange(string inputTree, string changedTree, int numRegisterCalls, int numUnregisterCalls) { uint adviseCookie = 100; var fileChangeService = IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(adviseCookie); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); using var watcher = new ProjectAssetFileWatcherInstance( IVsServiceFactory.Create <SVsFileChangeEx, IVsAsyncFileChangeEx>(fileChangeService), IProjectTreeProviderFactory.Create(), IUnconfiguredProjectCommonServicesFactory.Create(threadingService: IProjectThreadingServiceFactory.Create()), tasksService, IActiveConfiguredProjectSubscriptionServiceFactory.Create()); await watcher.InitializeAsync(); var projectUpdate = IProjectSubscriptionUpdateFactory.FromJson(ProjectCurrentStateJson); var firstTree = ProjectTreeParser.Parse(inputTree); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory.Create(Tuple.Create(IProjectTreeSnapshotFactory.Create(firstTree), projectUpdate))); var secondTree = ProjectTreeParser.Parse(changedTree); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory.Create(Tuple.Create(IProjectTreeSnapshotFactory.Create(secondTree), projectUpdate))); // If fileToWatch is null then we expect to not register any filewatcher. var fileChangeServiceMock = Mock.Get(fileChangeService); fileChangeServiceMock.Verify(s => s.AdviseFileChangeAsync(It.IsAny <string>(), It.IsAny <_VSFILECHANGEFLAGS>(), watcher, CancellationToken.None), Times.Exactly(numRegisterCalls)); fileChangeServiceMock.Verify(s => s.UnadviseFileChangeAsync(adviseCookie, CancellationToken.None), Times.Exactly(numUnregisterCalls)); }
internal async Task OnProjectChangedAsync_WhenProjectUnloaded_TriggersCancellation(WorkspaceContextHandlerType handlerType) { var unloadSource = new CancellationTokenSource(); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(unloadSource.Token); void ApplyProjectBuild(IProjectVersionedValue <IProjectSubscriptionUpdate> _, IProjectBuildSnapshot projectBuildSnapshot, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } void ApplyProjectEvaluation(IProjectVersionedValue <IProjectSubscriptionUpdate> _, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } var applyChangesToWorkspaceContext = handlerType switch { WorkspaceContextHandlerType.Evaluation => IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectEvaluationAsync(ApplyProjectEvaluation), WorkspaceContextHandlerType.ProjectBuild => IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectBuildAsync(ApplyProjectBuild), WorkspaceContextHandlerType.SourceItems => IApplyChangesToWorkspaceContextFactory.ImplementApplySourceItemsAsync(ApplyProjectEvaluation), // ApplyProjectEvaluation works for source items as they share a signature _ => throw new NotImplementedException() }; var instance = await CreateInitializedInstanceAsync(tasksService : tasksService, applyChangesToWorkspaceContext : applyChangesToWorkspaceContext); var update = IProjectVersionedValueFactory.Create <(ConfiguredProject, IProjectSubscriptionUpdate, IProjectBuildSnapshot)>((default !, default !, Mock.Of <IProjectBuildSnapshot>()));
internal async Task OnProjectChangedAsync_WhenProjectUnloaded_TriggersCancellation() { var unloadSource = new CancellationTokenSource(); var instance = await CreateInitializedInstanceAsync( tasksService : IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(unloadSource.Token)); var registration = IDataProgressTrackerServiceRegistrationFactory.Create(); var activeConfiguredProject = ConfiguredProjectFactory.Create(); var update = IProjectVersionedValueFactory.CreateEmpty(); await Assert.ThrowsAsync <OperationCanceledException>(() => { return(instance.OnProjectChangedAsync( registration, activeConfiguredProject, update, hasChange: _ => true, applyFunc: (_, _, _, token) => { // Simulate project unload during callback unloadSource.Cancel(); token.ThrowIfCancellationRequested(); })); }); }
public async Task WhenBaseIntermediateOutputPathNotSet_DoesNotAttemptToAdviseFileChange() { var fileChangeService = IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(100); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); using var watcher = new ProjectAssetFileWatcherInstance( IVsServiceFactory.Create <SVsFileChangeEx, IVsAsyncFileChangeEx>(fileChangeService), IProjectTreeProviderFactory.Create(), IUnconfiguredProjectCommonServicesFactory.Create(threadingService: IProjectThreadingServiceFactory.Create()), tasksService, IActiveConfiguredProjectSubscriptionServiceFactory.Create()); var tree = ProjectTreeParser.Parse(@"Root (flags: {ProjectRoot}), FilePath: ""C:\Foo\foo.proj"""); var projectUpdate = IProjectSubscriptionUpdateFactory.FromJson(@"{ ""CurrentState"": { ""ConfigurationGeneral"": { ""Properties"": { ""MSBuildProjectFullPath"": ""C:\\Foo\\foo.proj"" } } } }"); await watcher.InitializeAsync(); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory.Create(Tuple.Create(IProjectTreeSnapshotFactory.Create(tree), projectUpdate))); var fileChangeServiceMock = Mock.Get(fileChangeService); fileChangeServiceMock.Verify(s => s.AdviseFileChangeAsync(It.IsAny <string>(), It.IsAny <_VSFILECHANGEFLAGS>(), watcher, CancellationToken.None), Times.Never()); }
[InlineData(false)] // Project Build public async Task OnProjectChangedAsync_WhenProjectUnloaded_TriggersCancellation(bool evaluation) { var unloadSource = new CancellationTokenSource(); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(unloadSource.Token); void ApplyProjectBuild(IProjectVersionedValue <IProjectSubscriptionUpdate> _, IProjectBuildSnapshot projectBuildSnapshot, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } void ApplyProjectEvaluation(IProjectVersionedValue <IProjectSubscriptionUpdate> _, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } var applyChangesToWorkspaceContext = evaluation ? IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectEvaluationAsync(ApplyProjectEvaluation) : IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectBuildAsync(ApplyProjectBuild); var instance = await CreateInitializedInstanceAsync(tasksService : tasksService, applyChangesToWorkspaceContext : applyChangesToWorkspaceContext); var update = IProjectVersionedValueFactory.Create <(ConfiguredProject, IProjectSubscriptionUpdate, IProjectBuildSnapshot)>(default);
public async Task VerifyFileWatcherRegistrationOnTreeChange(string inputTree, string changedTree, int numRegisterCalls, int numUnregisterCalls) { var spMock = new IAsyncServiceProviderMoq(); uint adviseCookie = 100; var fileChangeService = IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(adviseCookie); spMock.AddService(typeof(SVsFileChangeEx), fileChangeService); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); var watcher = new ProjectAssetFileWatcher(spMock, IProjectTreeProviderFactory.Create(), IUnconfiguredProjectCommonServicesFactory.Create(threadingService: new IProjectThreadingServiceMock()), tasksService, IActiveConfiguredProjectSubscriptionServiceFactory.Create()); watcher.Load(); var projectUpdate = IProjectSubscriptionUpdateFactory.FromJson(ProjectCurrentStateJson); var firstTree = ProjectTreeParser.Parse(inputTree); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory <Tuple <IProjectTreeSnapshot, IProjectSubscriptionUpdate> > .Create((Tuple.Create(IProjectTreeSnapshotFactory.Create(firstTree), projectUpdate)))); var secondTree = ProjectTreeParser.Parse(changedTree); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory <Tuple <IProjectTreeSnapshot, IProjectSubscriptionUpdate> > .Create((Tuple.Create(IProjectTreeSnapshotFactory.Create(secondTree), projectUpdate)))); // If fileToWatch is null then we expect to not register any filewatcher. var fileChangeServiceMock = Mock.Get(fileChangeService); fileChangeServiceMock.Verify(s => s.AdviseFileChange(It.IsAny <string>(), It.IsAny <uint>(), watcher, out adviseCookie), Times.Exactly(numRegisterCalls)); fileChangeServiceMock.Verify(s => s.UnadviseFileChange(adviseCookie), Times.Exactly(numUnregisterCalls)); }
private static VsSafeProjectGuidService CreateInstance(IUnconfiguredProjectTasksService tasksService = null) { var project = UnconfiguredProjectFactory.Create(); tasksService = tasksService ?? IUnconfiguredProjectTasksServiceFactory.ImplementPrioritizedProjectLoadedInHost(() => Task.CompletedTask); return(new VsSafeProjectGuidService(project, tasksService)); }
public void GetProjectGuidAsync_WhenProjectAlreadyUnloaded_ReturnsCancelledTask() { var tasksService = IUnconfiguredProjectTasksServiceFactory.CreateWithUnloadedProject <string>(); var accessor = CreateInstance(tasksService); var result = accessor.GetProjectGuidAsync(); Assert.True(result.IsCanceled); }
private static SDKVersionTelemetryServiceComponent CreateComponent(Guid guid, Action <TelemetryParameters> onTelemetryLogged, string?version) { var projectVsServices = CreateProjectServices(version); var projectGuidService = CreateISafeProjectGuidService(guid); var telemetryService = CreateITelemetryService(onTelemetryLogged); var unconfiguredProjectTasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync(async t => await t()); return(new SDKVersionTelemetryServiceComponent( projectVsServices, projectGuidService, telemetryService, unconfiguredProjectTasksService)); }
public async Task OpenContextForWriteAsync_WhenProjectUnloaded_ThrowsOperationCanceled() { var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(new CancellationToken(canceled: true)); var accessor = IWorkspaceProjectContextAccessorFactory.Create(); var workspaceProjectContextProvider = IWorkspaceProjectContextProviderFactory.ImplementCreateProjectContextAsync(accessor); var instance = await CreateInitializedInstanceAsync(workspaceProjectContextProvider : workspaceProjectContextProvider, tasksService : tasksService); int callCount = 0; await Assert.ThrowsAnyAsync <OperationCanceledException>(() => { return(instance.OpenContextForWriteAsync(c => { callCount++; return Task.CompletedTask; })); }); Assert.Equal(0, callCount); }
private WorkspaceProjectContextHostInstance CreateInstance(ConfiguredProject project = null, IProjectThreadingService threadingService = null, IUnconfiguredProjectTasksService tasksService = null, IProjectSubscriptionService projectSubscriptionService = null, IActiveEditorContextTracker activeWorkspaceProjectContextTracker = null, IWorkspaceProjectContextProvider workspaceProjectContextProvider = null, IApplyChangesToWorkspaceContext applyChangesToWorkspaceContext = null) { project = project ?? ConfiguredProjectFactory.Create(); threadingService = threadingService ?? IProjectThreadingServiceFactory.Create(); tasksService = tasksService ?? IUnconfiguredProjectTasksServiceFactory.Create(); projectSubscriptionService = projectSubscriptionService ?? IProjectSubscriptionServiceFactory.Create(); activeWorkspaceProjectContextTracker = activeWorkspaceProjectContextTracker ?? IActiveEditorContextTrackerFactory.Create(); workspaceProjectContextProvider = workspaceProjectContextProvider ?? IWorkspaceProjectContextProviderFactory.ImplementCreateProjectContextAsync(IWorkspaceProjectContextAccessorFactory.Create()); applyChangesToWorkspaceContext = applyChangesToWorkspaceContext ?? IApplyChangesToWorkspaceContextFactory.Create(); return(new WorkspaceProjectContextHostInstance(project, threadingService, tasksService, projectSubscriptionService, workspaceProjectContextProvider, activeWorkspaceProjectContextTracker, ExportFactoryFactory.ImplementCreateValueWithAutoDispose(() => applyChangesToWorkspaceContext))); }
public async Task GetProjectGuidAsync_WhenProjectUnloads_CancelsTask() { var projectUnloaded = new TaskCompletionSource <object>(); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementPrioritizedProjectLoadedInHost(() => projectUnloaded.Task); var accessor = CreateInstance(tasksService); var result = accessor.GetProjectGuidAsync(); Assert.False(result.IsCanceled); // Now "unload" the project projectUnloaded.SetCanceled(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => { return(result); }); }
private static StartupProjectRegistrar CreateInstance( IVsStartupProjectsListService?vsStartupProjectsListService = null, IProjectThreadingService?threadingService = null, ISafeProjectGuidService?projectGuidService = null, IActiveConfiguredProjectSubscriptionService?projectSubscriptionService = null, IActiveConfiguredValues <IDebugLaunchProvider>?launchProviders = null) { var project = UnconfiguredProjectFactory.Create(); var instance = new StartupProjectRegistrar( project, IUnconfiguredProjectTasksServiceFactory.Create(), IVsServiceFactory.Create <SVsStartupProjectsListService, IVsStartupProjectsListService?>(vsStartupProjectsListService !), threadingService ?? IProjectThreadingServiceFactory.Create(), projectGuidService ?? ISafeProjectGuidServiceFactory.ImplementGetProjectGuidAsync(Guid.NewGuid()), projectSubscriptionService ?? IActiveConfiguredProjectSubscriptionServiceFactory.Create(), launchProviders !); return(instance); }
public async Task VerifyFileWatcherRegistration(string inputTree, string fileToWatch) { uint adviseCookie = 100; var fileChangeService = IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(adviseCookie); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); using (var watcher = new ProjectAssetFileWatcher(IVsServiceFactory.Create <SVsFileChangeEx, Shell.IVsAsyncFileChangeEx>(fileChangeService), IProjectTreeProviderFactory.Create(), IUnconfiguredProjectCommonServicesFactory.Create(threadingService: IProjectThreadingServiceFactory.Create()), tasksService, IActiveConfiguredProjectSubscriptionServiceFactory.Create())) { var tree = ProjectTreeParser.Parse(inputTree); var projectUpdate = IProjectSubscriptionUpdateFactory.FromJson(ProjectCurrentStateJson); watcher.Load(); await watcher.DataFlow_ChangedAsync(IProjectVersionedValueFactory.Create(Tuple.Create(IProjectTreeSnapshotFactory.Create(tree), projectUpdate))); // If fileToWatch is null then we expect to not register any filewatcher. var times = fileToWatch == null?Times.Never() : Times.Once(); Mock.Get(fileChangeService).Verify(s => s.AdviseFileChangeAsync(fileToWatch ?? It.IsAny <string>(), It.IsAny <_VSFILECHANGEFLAGS>(), watcher, CancellationToken.None), times); } }
internal async Task RenameAsync(string sourceCode, string oldFilePath, string newFilePath, IUserNotificationServices userNotificationServices, IRoslynServices roslynServices, IVsOnlineServices vsOnlineServices, string language) { using var ws = new AdhocWorkspace(); ws.AddSolution(InitializeWorkspace(ProjectId.CreateNewId(), newFilePath, sourceCode, language)); var unconfiguredProject = UnconfiguredProjectFactory.Create(filePath: $@"C:\project1.{ProjectFileExtension}"); var projectServices = IUnconfiguredProjectVsServicesFactory.Implement( threadingServiceCreator: () => IProjectThreadingServiceFactory.Create(), unconfiguredProjectCreator: () => unconfiguredProject); var unconfiguredProjectTasksService = IUnconfiguredProjectTasksServiceFactory.Create(); var environmentOptionsFactory = IEnvironmentOptionsFactory.Implement((string category, string page, string property, bool defaultValue) => { return(true); }); var waitIndicator = (new Mock <IWaitIndicator>()).Object; var refactorNotifyService = (new Mock <IRefactorNotifyService>()).Object; var dte = IVsUIServiceFactory.Create <Shell.Interop.SDTE, EnvDTE.DTE>(null !); var renamer = new Renamer(projectServices, unconfiguredProjectTasksService, ws, dte, environmentOptionsFactory, userNotificationServices, roslynServices, waitIndicator, refactorNotifyService, vsOnlineServices); await renamer.HandleRenameAsync(oldFilePath, newFilePath) .TimeoutAfter(TimeSpan.FromSeconds(1)); }
private static WorkspaceProjectContextHostInstance CreateInstance(ConfiguredProject?project = null, IProjectThreadingService?threadingService = null, IUnconfiguredProjectTasksService?tasksService = null, IProjectSubscriptionService?projectSubscriptionService = null, IActiveEditorContextTracker?activeWorkspaceProjectContextTracker = null, IWorkspaceProjectContextProvider?workspaceProjectContextProvider = null, IApplyChangesToWorkspaceContext?applyChangesToWorkspaceContext = null) { project ??= ConfiguredProjectFactory.Create(); threadingService ??= IProjectThreadingServiceFactory.Create(); tasksService ??= IUnconfiguredProjectTasksServiceFactory.Create(); projectSubscriptionService ??= IProjectSubscriptionServiceFactory.Create(); activeWorkspaceProjectContextTracker ??= IActiveEditorContextTrackerFactory.Create(); workspaceProjectContextProvider ??= IWorkspaceProjectContextProviderFactory.ImplementCreateProjectContextAsync(IWorkspaceProjectContextAccessorFactory.Create()); applyChangesToWorkspaceContext ??= IApplyChangesToWorkspaceContextFactory.Create(); IDataProgressTrackerService dataProgressTrackerService = IDataProgressTrackerServiceFactory.Create(); return(new WorkspaceProjectContextHostInstance(project, threadingService, tasksService, projectSubscriptionService, workspaceProjectContextProvider, activeWorkspaceProjectContextTracker, ExportFactoryFactory.ImplementCreateValueWithAutoDispose(() => applyChangesToWorkspaceContext), dataProgressTrackerService)); }
[InlineData(false)] // Project Build public async Task OnProjectChangedAsync_WhenProjectUnloaded_TriggersCancellation(bool evaluation) { var unloadSource = new CancellationTokenSource(); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(unloadSource.Token); void applyChanges(IProjectVersionedValue <IProjectSubscriptionUpdate> _, bool __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } var applyChangesToWorkspaceContext = evaluation ? IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectEvaluationAsync(applyChanges) : IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectBuildAsync(applyChanges); var instance = await CreateInitializedInstanceAsync(tasksService : tasksService, applyChangesToWorkspaceContext : applyChangesToWorkspaceContext); var update = IProjectVersionedValueFactory.CreateEmpty(); await Assert.ThrowsAsync <OperationCanceledException>(() => { return(instance.OnProjectChangedAsync(update, evaluation)); }); }
public async Task WhenProjectUnloading_DoesNotLoadConfiguredProject() { var tasksService = IUnconfiguredProjectTasksServiceFactory.CreateWithUnloadedProject <ConfiguredProject>(); var configuredProject = ConfiguredProjectFactory.Create(); int callCount = 0; UnconfiguredProject project = UnconfiguredProjectFactory.ImplementLoadConfiguredProjectAsync(configuration => { callCount++; return(Task.FromResult(configuredProject)); }); var loader = CreateInstance(project, tasksService, out ProjectValueDataSource <IConfigurationGroup <ProjectConfiguration> > source); await loader.InitializeAsync(); var configurationGroups = IConfigurationGroupFactory.CreateFromConfigurationNames("Debug|AnyCPU"); // Change the active configurations await source.SendAndCompleteAsync(configurationGroups, loader.TargetBlock); // Should not be listening Assert.Equal(0, callCount); }
private static ActiveConfiguredProjectsLoader CreateInstance(UnconfiguredProject project, IActiveConfigurationGroupService activeConfigurationGroupService, IUnconfiguredProjectTasksService?tasksService) { tasksService ??= IUnconfiguredProjectTasksServiceFactory.ImplementLoadedProjectAsync <ConfiguredProject>(t => t()); return(new ActiveConfiguredProjectsLoader(project, activeConfigurationGroupService, tasksService)); }