Skip to content

Commit fb3e398

Browse files
committed
Postponed loading od the ProjectsRepository to the first refresh to avoid race conditions with the VBE loading.
1 parent c33ffa3 commit fb3e398

File tree

2 files changed

+214
-3
lines changed

2 files changed

+214
-3
lines changed

Rubberduck.VBEEditor/ComManagement/ProjectsRepository.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public class ProjectsRepository : IProjectsRepository
2121
public ProjectsRepository(IVBE vbe)
2222
{
2323
_projectsCollection = vbe.VBProjects;
24-
LoadCollections();
2524
}
2625

2726
private void LoadCollections()
@@ -207,11 +206,21 @@ private T EvaluateWithinReadLock<T>(Func<T> function) where T: class
207206

208207
public IVBProject Project(string projectId)
209208
{
209+
if (projectId == null)
210+
{
211+
return null;
212+
}
213+
210214
return EvaluateWithinReadLock(() => _projects.TryGetValue(projectId, out var project) ? project : null);
211215
}
212216

213217
public IVBComponents ComponentsCollection(string projectId)
214218
{
219+
if (projectId == null)
220+
{
221+
return null;
222+
}
223+
215224
return EvaluateWithinReadLock(() => _componentsCollections.TryGetValue(projectId, out var componenstCollection) ? componenstCollection : null);
216225
}
217226

RubberduckTests/VBEditor/ProjectsRepositoryTests.cs

Lines changed: 204 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@ namespace RubberduckTests.VBEditor
1414
[TestFixture()]
1515
public class ProjectsRepositoryTests
1616
{
17-
private IProjectsRepository TestRepository(IVBE vbe)
17+
private IProjectsRepository TestRepository(IVBE vbe, bool initialRefresh = true)
1818
{
19-
return new ProjectsRepository(vbe);
19+
var repository = new ProjectsRepository(vbe);
20+
if (initialRefresh)
21+
{
22+
repository.Refresh();
23+
}
24+
return repository;
2025
}
2126

2227
[Test()]
@@ -118,6 +123,25 @@ public void ProjectsReturnsEmptyCollectionAfterDisposal()
118123
Assert.IsEmpty(projects);
119124
}
120125

126+
[Test()]
127+
public void ProjectsReturnsEmptyCollectionBeforeFirstRefresh()
128+
{
129+
var vbeBuilder = new MockVbeBuilder();
130+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
131+
var projectMock = projectBuilder.Build();
132+
vbeBuilder.AddProject(projectMock);
133+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
134+
var otherProjectMock = otherProjectBuilder.Build();
135+
vbeBuilder.AddProject(otherProjectMock);
136+
137+
var vbe = vbeBuilder.Build().Object;
138+
139+
var repository = TestRepository(vbe, initialRefresh: false);
140+
var projects = repository.Projects().ToList();
141+
142+
Assert.IsEmpty(projects);
143+
}
144+
121145
[Test()]
122146
public void ProjectsDoesNotReturnProjectsAddedToVbeWithoutRefresh()
123147
{
@@ -303,6 +327,26 @@ public void ProjectReturnsNullAfterDisposal()
303327
Assert.IsNull(returnedProject);
304328
}
305329

330+
[Test()]
331+
public void ProjectReturnsNullBeforeFirstRefresh()
332+
{
333+
var vbeBuilder = new MockVbeBuilder();
334+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
335+
var projectMock = projectBuilder.Build();
336+
vbeBuilder.AddProject(projectMock);
337+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
338+
var otherProjectMock = otherProjectBuilder.Build();
339+
vbeBuilder.AddProject(otherProjectMock);
340+
341+
var vbe = vbeBuilder.Build().Object;
342+
var otherProject = otherProjectMock.Object;
343+
344+
var repository = TestRepository(vbe, initialRefresh: false);
345+
var returnedProject = repository.Project(otherProject.ProjectId);
346+
347+
Assert.IsNull(returnedProject);
348+
}
349+
306350
[Test()]
307351
public void ProjectReturnsNullForProjectIdOfAddedProjectBeforeRefresh()
308352
{
@@ -507,6 +551,26 @@ public void ComponentsCollectionReturnsNullAfterDisposal()
507551
Assert.IsNull(returnedCollection);
508552
}
509553

554+
[Test()]
555+
public void ComponentsCollectionReturnsNullBeforeFirstRefresh()
556+
{
557+
var vbeBuilder = new MockVbeBuilder();
558+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
559+
var projectMock = projectBuilder.Build();
560+
vbeBuilder.AddProject(projectMock);
561+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
562+
var otherProjectMock = otherProjectBuilder.Build();
563+
vbeBuilder.AddProject(otherProjectMock);
564+
565+
var vbe = vbeBuilder.Build().Object;
566+
var project = projectMock.Object;
567+
568+
var repository = TestRepository(vbe, initialRefresh: false); ;
569+
var returnedCollection = repository.ComponentsCollection(project.ProjectId);
570+
571+
Assert.IsNull(returnedCollection);
572+
}
573+
510574
[Test()]
511575
public void ComponentsCollectionReturnsNullForProjectIdOfAddedProjectBeforeRefresh()
512576
{
@@ -707,6 +771,28 @@ public void ComponentsReturnsEmptyCollectionAfterDisposal()
707771
Assert.IsEmpty(components);
708772
}
709773

774+
[Test()]
775+
public void ComponentsReturnsEmptyCollectionBeforeFirstRefresh()
776+
{
777+
var vbeBuilder = new MockVbeBuilder();
778+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
779+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
780+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
781+
var projectMock = projectBuilder.Build();
782+
vbeBuilder.AddProject(projectMock);
783+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
784+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
785+
var otherProjectMock = otherProjectBuilder.Build();
786+
vbeBuilder.AddProject(otherProjectMock);
787+
788+
var vbe = vbeBuilder.Build().Object;
789+
790+
var repository = TestRepository(vbe, initialRefresh: false);
791+
var components = repository.Components().ToList();
792+
793+
Assert.IsEmpty(components);
794+
}
795+
710796
[Test()]
711797
public void ComponentsDoesNotReturnComponentsAddedToVbeBeforeRefresh()
712798
{
@@ -1128,6 +1214,29 @@ public void ComponentsForProjectIdReturnsEmptyCollectionAfterDisposal()
11281214
Assert.IsEmpty(components);
11291215
}
11301216

1217+
[Test()]
1218+
public void ComponentsForProjectIdReturnsEmptyCollectionBeforeFirstRefresh()
1219+
{
1220+
var vbeBuilder = new MockVbeBuilder();
1221+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
1222+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
1223+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
1224+
var projectMock = projectBuilder.Build();
1225+
vbeBuilder.AddProject(projectMock);
1226+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
1227+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
1228+
var otherProjectMock = otherProjectBuilder.Build();
1229+
vbeBuilder.AddProject(otherProjectMock);
1230+
1231+
var vbe = vbeBuilder.Build().Object;
1232+
var project = projectMock.Object;
1233+
1234+
var repository = TestRepository(vbe, initialRefresh: false);
1235+
var components = repository.Components(project.ProjectId).ToList();
1236+
1237+
Assert.IsEmpty(components);
1238+
}
1239+
11311240
[Test()]
11321241
public void ComponentsFroProjectIdDoesNotReturnComponentsAddedToVbeBeforeRefresh()
11331242
{
@@ -1406,6 +1515,30 @@ public void ComponentReturnsNullAfterDisposal()
14061515
Assert.IsNull(returnedComponent);
14071516
}
14081517

1518+
[Test()]
1519+
public void ComponentReturnsNullBeforeFirstRefresh()
1520+
{
1521+
var vbeBuilder = new MockVbeBuilder();
1522+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
1523+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
1524+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
1525+
var projectMock = projectBuilder.Build();
1526+
var mockComponents = projectBuilder.MockComponents;
1527+
vbeBuilder.AddProject(projectMock);
1528+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
1529+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
1530+
var otherProjectMock = otherProjectBuilder.Build();
1531+
vbeBuilder.AddProject(otherProjectMock);
1532+
1533+
var vbe = vbeBuilder.Build().Object;
1534+
var component2 = mockComponents[1].Object;
1535+
1536+
var repository = TestRepository(vbe, initialRefresh: false);
1537+
var returnedComponent = repository.Component(component2.QualifiedModuleName);
1538+
1539+
Assert.IsNull(returnedComponent);
1540+
}
1541+
14091542
[Test()]
14101543
public void ComponentReturnsNullForQmnOfAddedComponentBeforeRefresh()
14111544
{
@@ -1690,6 +1823,28 @@ public void CodeModulesReturnsEmptyCollectionAfterDisposal()
16901823
Assert.IsEmpty(codeModules);
16911824
}
16921825

1826+
[Test()]
1827+
public void CodeModulesReturnsEmptyCollectionBeforeFirstRefresh()
1828+
{
1829+
var vbeBuilder = new MockVbeBuilder();
1830+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
1831+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
1832+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
1833+
var projectMock = projectBuilder.Build();
1834+
vbeBuilder.AddProject(projectMock);
1835+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
1836+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
1837+
var otherProjectMock = otherProjectBuilder.Build();
1838+
vbeBuilder.AddProject(otherProjectMock);
1839+
1840+
var vbe = vbeBuilder.Build().Object;
1841+
1842+
var repository = TestRepository(vbe, initialRefresh: false);
1843+
var codeModules = repository.CodeModules().ToList();
1844+
1845+
Assert.IsEmpty(codeModules);
1846+
}
1847+
16931848
[Test()]
16941849
public void CodeModulesDoesNotReturnCodeModulesAddedToVbeBeforeRefresh()
16951850
{
@@ -2112,6 +2267,29 @@ public void CodeModulesForProjectIdReturnsEmptyCollectionAfterDisposal()
21122267
Assert.IsEmpty(codeModules);
21132268
}
21142269

2270+
[Test()]
2271+
public void CodeModulesForProjectIdReturnsEmptyCollectionBeforeFirstRefresh()
2272+
{
2273+
var vbeBuilder = new MockVbeBuilder();
2274+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
2275+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
2276+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
2277+
var projectMock = projectBuilder.Build();
2278+
vbeBuilder.AddProject(projectMock);
2279+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
2280+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
2281+
var otherProjectMock = otherProjectBuilder.Build();
2282+
vbeBuilder.AddProject(otherProjectMock);
2283+
2284+
var vbe = vbeBuilder.Build().Object;
2285+
var project = projectMock.Object;
2286+
2287+
var repository = TestRepository(vbe, initialRefresh: false);
2288+
var codeModules = repository.CodeModules(project.ProjectId).ToList();
2289+
2290+
Assert.IsEmpty(codeModules);
2291+
}
2292+
21152293
[Test()]
21162294
public void CodeModulesFroProjectIdDoesNotReturnCodeModulesAddedToVbeBeforeRefresh()
21172295
{
@@ -2390,6 +2568,30 @@ public void CodeModuleReturnsNullAfterDisposal()
23902568
Assert.IsNull(returnedCodeModule);
23912569
}
23922570

2571+
[Test()]
2572+
public void CodeModuleReturnsNullBeforeFirstRefresh()
2573+
{
2574+
var vbeBuilder = new MockVbeBuilder();
2575+
var projectBuilder = vbeBuilder.ProjectBuilder("project", ProjectProtection.Unprotected);
2576+
projectBuilder.AddComponent("component1", ComponentType.ClassModule, String.Empty);
2577+
projectBuilder.AddComponent("component2", ComponentType.ClassModule, String.Empty);
2578+
var projectMock = projectBuilder.Build();
2579+
var mockComponents = projectBuilder.MockComponents;
2580+
vbeBuilder.AddProject(projectMock);
2581+
var otherProjectBuilder = vbeBuilder.ProjectBuilder("otherProject", ProjectProtection.Unprotected);
2582+
otherProjectBuilder.AddComponent("otherComponent", ComponentType.ClassModule, String.Empty);
2583+
var otherProjectMock = otherProjectBuilder.Build();
2584+
vbeBuilder.AddProject(otherProjectMock);
2585+
2586+
var vbe = vbeBuilder.Build().Object;
2587+
var component2 = mockComponents[1].Object;
2588+
2589+
var repository = TestRepository(vbe, initialRefresh: false);
2590+
var returnedCodeModule = repository.CodeModule(component2.QualifiedModuleName);
2591+
2592+
Assert.IsNull(returnedCodeModule);
2593+
}
2594+
23932595
[Test()]
23942596
public void CodeModuleReturnsNullForQmnOfAddedCodeModuleBeforeRefresh()
23952597
{

0 commit comments

Comments
 (0)