Skip to content

Commit 7cfb0cf

Browse files
Allow tests to specify delay for WorkspaceProjectStateChangeDetector (#10297)
Fixes #10295 `WorkspaceProjectStateChangeDetector` tests were taking an extra long time to run because they didn't specify a faster delay `TimeSpan` to the detector's `AsyncBatchingWorkQueue`.
2 parents 77b30be + 6f8c5bd commit 7cfb0cf

File tree

2 files changed

+55
-37
lines changed

2 files changed

+55
-37
lines changed

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/WorkspaceProjectStateChangeDetector.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,24 @@ public WorkspaceProjectStateChangeDetector(
4040
IProjectSnapshotManager projectManager,
4141
LanguageServerFeatureOptions options,
4242
IWorkspaceProvider workspaceProvider)
43+
: this(generator, projectManager, options, workspaceProvider, s_delay)
44+
{
45+
}
46+
47+
public WorkspaceProjectStateChangeDetector(
48+
IProjectWorkspaceStateGenerator generator,
49+
IProjectSnapshotManager projectManager,
50+
LanguageServerFeatureOptions options,
51+
IWorkspaceProvider workspaceProvider,
52+
TimeSpan delay)
4353
{
4454
_generator = generator;
4555
_projectManager = projectManager;
4656
_options = options;
4757

4858
_disposeTokenSource = new();
4959
_workQueue = new AsyncBatchingWorkQueue<(Project?, IProjectSnapshot)>(
50-
s_delay,
60+
delay,
5161
ProcessBatchAsync,
5262
_disposeTokenSource.Token);
5363

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ProjectSystem/WorkspaceProjectStateChangeDetectorTest.cs

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4-
#nullable disable
5-
4+
using System;
65
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Razor;
77
using Microsoft.AspNetCore.Razor.Language.Components;
88
using Microsoft.AspNetCore.Razor.Test.Common.VisualStudio;
99
using Microsoft.AspNetCore.Razor.Test.Common.Workspaces;
1010
using Microsoft.CodeAnalysis;
1111
using Microsoft.CodeAnalysis.CSharp;
1212
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
1313
using Microsoft.CodeAnalysis.Text;
14-
using Microsoft.VisualStudio.LanguageServices.Razor;
1514
using Microsoft.VisualStudio.Shell;
1615
using Microsoft.VisualStudio.Threading;
1716
using Xunit;
@@ -110,9 +109,9 @@ public WorkspaceProjectStateChangeDetectorTest(ITestOutputHelper testOutput)
110109
filePath: "Three.csproj",
111110
documents: [razorDocumentInfo]).WithCompilationOutputInfo(new CompilationOutputInfo().WithAssemblyPath("obj3\\Three.dll")));
112111

113-
_projectNumberOne = _solutionWithTwoProjects.GetProject(projectId1);
114-
_projectNumberTwo = _solutionWithTwoProjects.GetProject(projectId2);
115-
_projectNumberThree = _solutionWithOneProject.GetProject(projectId3);
112+
_projectNumberOne = _solutionWithTwoProjects.GetProject(projectId1).AssumeNotNull();
113+
_projectNumberTwo = _solutionWithTwoProjects.GetProject(projectId2).AssumeNotNull();
114+
_projectNumberThree = _solutionWithOneProject.GetProject(projectId3).AssumeNotNull();
116115

117116
_hostProjectOne = new HostProject("One.csproj", "obj1", FallbackRazorConfiguration.MVC_1_1, "One");
118117
_hostProjectTwo = new HostProject("Two.csproj", "obj2", FallbackRazorConfiguration.MVC_1_1, "Two");
@@ -125,7 +124,7 @@ public async Task SolutionClosing_StopsActiveWork()
125124
// Arrange
126125
var generator = new TestProjectWorkspaceStateGenerator();
127126
var projectManager = CreateProjectSnapshotManager();
128-
using var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
127+
using var detector = CreateDetector(generator, projectManager);
129128
var detectorAccessor = detector.GetTestAccessor();
130129

131130
var workspaceChangedTask = detectorAccessor.ListenForWorkspaceChangesAsync(
@@ -167,7 +166,7 @@ public async Task WorkspaceChanged_DocumentEvents_EnqueuesUpdatesForDependentPro
167166
// Arrange
168167
var generator = new TestProjectWorkspaceStateGenerator();
169168
var projectManager = CreateProjectSnapshotManager();
170-
using var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
169+
using var detector = CreateDetector(generator, projectManager);
171170
var detectorAccessor = detector.GetTestAccessor();
172171

173172
await projectManager.UpdateAsync(updater =>
@@ -208,7 +207,7 @@ public async Task WorkspaceChanged_ProjectEvents_EnqueuesUpdatesForDependentProj
208207
// Arrange
209208
var generator = new TestProjectWorkspaceStateGenerator();
210209
var projectManager = CreateProjectSnapshotManager();
211-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
210+
using var detector = CreateDetector(generator, projectManager);
212211
var detectorAccessor = detector.GetTestAccessor();
213212

214213
await projectManager.UpdateAsync(updater =>
@@ -251,7 +250,7 @@ public async Task WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSo
251250
// Arrange
252251
var generator = new TestProjectWorkspaceStateGenerator();
253252
var projectManager = CreateProjectSnapshotManager();
254-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
253+
using var detector = CreateDetector(generator, projectManager);
255254
var detectorAccessor = detector.GetTestAccessor();
256255

257256
await projectManager.UpdateAsync(updater =>
@@ -270,8 +269,8 @@ await projectManager.UpdateAsync(updater =>
270269
// Assert
271270
Assert.Collection(
272271
generator.Updates,
273-
p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject.Id),
274-
p => Assert.Equal(_projectNumberTwo.Id, p.WorkspaceProject.Id));
272+
p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject?.Id),
273+
p => Assert.Equal(_projectNumberTwo.Id, p.WorkspaceProject?.Id));
275274
}
276275

277276
[UITheory]
@@ -285,7 +284,7 @@ public async Task WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSol
285284
// Arrange
286285
var generator = new TestProjectWorkspaceStateGenerator();
287286
var projectManager = CreateProjectSnapshotManager();
288-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
287+
using var detector = CreateDetector(generator, projectManager);
289288
var detectorAccessor = detector.GetTestAccessor();
290289

291290
await projectManager.UpdateAsync(updater =>
@@ -311,10 +310,10 @@ await projectManager.UpdateAsync(updater =>
311310
// Assert
312311
Assert.Collection(
313312
generator.Updates,
314-
p => Assert.Equal(_projectNumberThree.Id, p.WorkspaceProject.Id),
313+
p => Assert.Equal(_projectNumberThree.Id, p.WorkspaceProject?.Id),
315314
p => Assert.Null(p.WorkspaceProject),
316-
p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject.Id),
317-
p => Assert.Equal(_projectNumberTwo.Id, p.WorkspaceProject.Id));
315+
p => Assert.Equal(_projectNumberOne.Id, p.WorkspaceProject?.Id),
316+
p => Assert.Equal(_projectNumberTwo.Id, p.WorkspaceProject?.Id));
318317
}
319318

320319
[UITheory]
@@ -325,7 +324,7 @@ public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_After
325324
// Arrange
326325
var generator = new TestProjectWorkspaceStateGenerator();
327326
var projectManager = CreateProjectSnapshotManager();
328-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
327+
using var detector = CreateDetector(generator, projectManager);
329328
var detectorAccessor = detector.GetTestAccessor();
330329

331330
await projectManager.UpdateAsync(updater =>
@@ -351,8 +350,8 @@ await projectManager.UpdateAsync(updater =>
351350

352351
// Assert
353352
var update = Assert.Single(generator.Updates);
354-
Assert.Equal(update.WorkspaceProject.Id, _projectNumberOne.Id);
355-
Assert.Equal(update.ProjectSnapshot.FilePath, _hostProjectOne.FilePath);
353+
Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id);
354+
Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath);
356355
}
357356

358357
[UIFact]
@@ -361,7 +360,7 @@ public async Task WorkspaceChanged_DocumentChanged_BackgroundVirtualCS_UpdatesPr
361360
// Arrange
362361
var generator = new TestProjectWorkspaceStateGenerator();
363362
var projectManager = CreateProjectSnapshotManager();
364-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
363+
using var detector = CreateDetector(generator, projectManager);
365364
var detectorAccessor = detector.GetTestAccessor();
366365

367366
Workspace.TryApplyChanges(_solutionWithTwoProjects);
@@ -383,8 +382,8 @@ await projectManager.UpdateAsync(updater =>
383382

384383
// Assert
385384
var update = Assert.Single(generator.Updates);
386-
Assert.Equal(update.WorkspaceProject.Id, _projectNumberOne.Id);
387-
Assert.Equal(update.ProjectSnapshot.FilePath, _hostProjectOne.FilePath);
385+
Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id);
386+
Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath);
388387
}
389388

390389
[UIFact]
@@ -393,7 +392,7 @@ public async Task WorkspaceChanged_DocumentChanged_CSHTML_UpdatesProjectState_Af
393392
// Arrange
394393
var generator = new TestProjectWorkspaceStateGenerator();
395394
var projectManager = CreateProjectSnapshotManager();
396-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
395+
using var detector = CreateDetector(generator, projectManager);
397396
var detectorAccessor = detector.GetTestAccessor();
398397

399398
Workspace.TryApplyChanges(_solutionWithTwoProjects);
@@ -415,8 +414,8 @@ await projectManager.UpdateAsync(updater =>
415414

416415
// Assert
417416
var update = Assert.Single(generator.Updates);
418-
Assert.Equal(update.WorkspaceProject.Id, _projectNumberOne.Id);
419-
Assert.Equal(update.ProjectSnapshot.FilePath, _hostProjectOne.FilePath);
417+
Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id);
418+
Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath);
420419
}
421420

422421
[UIFact]
@@ -425,7 +424,7 @@ public async Task WorkspaceChanged_DocumentChanged_Razor_UpdatesProjectState_Aft
425424
// Arrange
426425
var generator = new TestProjectWorkspaceStateGenerator();
427426
var projectManager = CreateProjectSnapshotManager();
428-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
427+
using var detector = CreateDetector(generator, projectManager);
429428
var detectorAccessor = detector.GetTestAccessor();
430429

431430
Workspace.TryApplyChanges(_solutionWithTwoProjects);
@@ -447,8 +446,8 @@ await projectManager.UpdateAsync(updater =>
447446

448447
// Assert
449448
var update = Assert.Single(generator.Updates);
450-
Assert.Equal(update.WorkspaceProject.Id, _projectNumberOne.Id);
451-
Assert.Equal(update.ProjectSnapshot.FilePath, _hostProjectOne.FilePath);
449+
Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id);
450+
Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath);
452451
}
453452

454453
[UIFact]
@@ -457,7 +456,7 @@ public async Task WorkspaceChanged_DocumentChanged_PartialComponent_UpdatesProje
457456
// Arrange
458457
var generator = new TestProjectWorkspaceStateGenerator();
459458
var projectManager = CreateProjectSnapshotManager();
460-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
459+
using var detector = CreateDetector(generator, projectManager);
461460
var detectorAccessor = detector.GetTestAccessor();
462461

463462
Workspace.TryApplyChanges(_solutionWithTwoProjects);
@@ -482,6 +481,7 @@ public interface IComponent {}
482481
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
483482
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
484483
var document = solution.GetDocument(_partialComponentClassDocumentId);
484+
Assert.NotNull(document);
485485

486486
// The change detector only operates when a semantic model / syntax tree is available.
487487
await document.GetSyntaxRootAsync();
@@ -496,8 +496,8 @@ public interface IComponent {}
496496

497497
// Assert
498498
var update = Assert.Single(generator.Updates);
499-
Assert.Equal(update.WorkspaceProject.Id, _projectNumberOne.Id);
500-
Assert.Equal(update.ProjectSnapshot.FilePath, _hostProjectOne.FilePath);
499+
Assert.Equal(_projectNumberOne.Id, update.WorkspaceProject?.Id);
500+
Assert.Equal(_hostProjectOne.FilePath, update.ProjectSnapshot.FilePath);
501501
}
502502

503503
[UIFact]
@@ -506,7 +506,7 @@ public async Task WorkspaceChanged_ProjectRemovedEvent_QueuesProjectStateRemoval
506506
// Arrange
507507
var generator = new TestProjectWorkspaceStateGenerator();
508508
var projectManager = CreateProjectSnapshotManager();
509-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
509+
using var detector = CreateDetector(generator, projectManager);
510510
var detectorAccessor = detector.GetTestAccessor();
511511

512512
await projectManager.UpdateAsync(updater =>
@@ -534,7 +534,7 @@ public async Task WorkspaceChanged_ProjectAddedEvent_AddsProject()
534534
// Arrange
535535
var generator = new TestProjectWorkspaceStateGenerator();
536536
var projectManager = CreateProjectSnapshotManager();
537-
var detector = new WorkspaceProjectStateChangeDetector(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider);
537+
using var detector = CreateDetector(generator, projectManager);
538538
var detectorAccessor = detector.GetTestAccessor();
539539

540540
await projectManager.UpdateAsync(updater =>
@@ -554,7 +554,7 @@ await projectManager.UpdateAsync(updater =>
554554
// Assert
555555
Assert.Single(
556556
generator.Updates,
557-
p => p.WorkspaceProject.Id == _projectNumberThree.Id);
557+
p => p.WorkspaceProject?.Id == _projectNumberThree.Id);
558558
}
559559

560560
[Fact]
@@ -569,6 +569,7 @@ public partial class TestComponent{}
569569
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
570570
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
571571
var document = solution.GetDocument(_partialComponentClassDocumentId);
572+
Assert.NotNull(document);
572573

573574
// Initialize document
574575
await document.GetSyntaxRootAsync();
@@ -597,6 +598,7 @@ public interface IComponent {}
597598
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
598599
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
599600
var document = solution.GetDocument(_partialComponentClassDocumentId);
601+
Assert.NotNull(document);
600602

601603
// Initialize document
602604
await document.GetSyntaxRootAsync();
@@ -625,6 +627,7 @@ public interface IComponent {}
625627
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
626628
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
627629
var document = solution.GetDocument(_partialComponentClassDocumentId);
630+
Assert.NotNull(document);
628631

629632
// Act
630633
var result = WorkspaceProjectStateChangeDetector.IsPartialComponentClass(document);
@@ -649,6 +652,7 @@ public interface IComponent {}
649652
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
650653
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
651654
var document = solution.GetDocument(_partialComponentClassDocumentId);
655+
Assert.NotNull(document);
652656

653657
await document.GetSyntaxRootAsync();
654658

@@ -669,6 +673,7 @@ public async Task IsPartialComponentClass_NonClass_ReturnsFalse()
669673
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
670674
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
671675
var document = solution.GetDocument(_partialComponentClassDocumentId);
676+
Assert.NotNull(document);
672677

673678
// Initialize document
674679
await document.GetSyntaxRootAsync();
@@ -684,7 +689,6 @@ public async Task IsPartialComponentClass_NonClass_ReturnsFalse()
684689
[Fact]
685690
public async Task IsPartialComponentClass_MultipleClassesOneComponentPartial_ReturnsTrue()
686691
{
687-
688692
// Arrange
689693
var sourceText = SourceText.From($$"""
690694
public partial class NonComponent1 {}
@@ -702,6 +706,7 @@ public interface IComponent {}
702706
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
703707
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
704708
var document = solution.GetDocument(_partialComponentClassDocumentId);
709+
Assert.NotNull(document);
705710

706711
// Initialize document
707712
await document.GetSyntaxRootAsync();
@@ -717,7 +722,6 @@ public interface IComponent {}
717722
[Fact]
718723
public async Task IsPartialComponentClass_NonComponents_ReturnsFalse()
719724
{
720-
721725
// Arrange
722726
var sourceText = SourceText.From("""
723727
public partial class NonComponent1 {}
@@ -734,6 +738,7 @@ public interface IComponent {}
734738
.WithDocumentText(_partialComponentClassDocumentId, sourceText)
735739
.WithDocumentSyntaxRoot(_partialComponentClassDocumentId, syntaxTreeRoot, PreservationMode.PreserveIdentity);
736740
var document = solution.GetDocument(_partialComponentClassDocumentId);
741+
Assert.NotNull(document);
737742

738743
// Initialize document
739744
await document.GetSyntaxRootAsync();
@@ -745,4 +750,7 @@ public interface IComponent {}
745750
// Assert
746751
Assert.False(result);
747752
}
753+
754+
private WorkspaceProjectStateChangeDetector CreateDetector(IProjectWorkspaceStateGenerator generator, IProjectSnapshotManager projectManager)
755+
=> new(generator, projectManager, TestLanguageServerFeatureOptions.Instance, WorkspaceProvider, TimeSpan.FromMilliseconds(10));
748756
}

0 commit comments

Comments
 (0)