Skip to content

Commit 00b8d3a

Browse files
committed
Add unit tests for Code Explorer references and folders.
1 parent 1eb76a6 commit 00b8d3a

7 files changed

+785
-11
lines changed

RubberduckTests/AddRemoveReferences/AddRemoveReferencesSetup.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public static class AddRemoveReferencesSetup
4040
new ReferenceInfo(Guid.Empty, $"VBProject{info}", $@"C:\Users\Rubberduck\Documents\Book{info}.xlsm", 0, 0))
4141
.ToList();
4242

43+
public static List<ReferenceModel> DummyProjectsList => ProjectReferenceInfoList
44+
.Select(proj => new ReferenceModel(proj, ReferenceKind.Project)).ToList();
45+
4346
public static List<ReferenceInfo> RecentProjectReferenceInfoList =>
4447
Enumerable.Range(1, 3)
4548
.Select(info =>

RubberduckTests/CodeExplorer/CodeExplorerCustomFolderViewModelTests.cs

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.Diagnostics.CodeAnalysis;
43
using System.Linq;
5-
using System.Text;
6-
using System.Threading.Tasks;
74
using NUnit.Framework;
85
using Rubberduck.Navigation.CodeExplorer;
96
using Rubberduck.Navigation.Folders;
10-
using Rubberduck.Parsing.Symbols;
117

128
namespace RubberduckTests.CodeExplorer
139
{
@@ -246,6 +242,104 @@ public void Constructor_CreatesCorrectSubFolderStructure(params object[] paramet
246242
AssertFolderStructureIsCorrect(folder, structure);
247243
}
248244

245+
[Test]
246+
[Category("Code Explorer")]
247+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Modules",
248+
CodeExplorerTestSetup.TestClassName, "Foo.Classes",
249+
CodeExplorerTestSetup.TestDocumentName, "Foo.Docs",
250+
CodeExplorerTestSetup.TestUserFormName, "Foo.Forms")]
251+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo",
252+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar",
253+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar",
254+
CodeExplorerTestSetup.TestClassName, "Foo.Bar")]
255+
[TestCase(CodeExplorerTestSetup.TestClassName, "Foo.Bar",
256+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz",
257+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar",
258+
CodeExplorerTestSetup.TestModuleName, "Foo")]
259+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Bar.Baz",
260+
CodeExplorerTestSetup.TestClassName, "Foo.Bar.Baz",
261+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar.Baz",
262+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz")]
263+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Baz",
264+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar",
265+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar",
266+
CodeExplorerTestSetup.TestClassName, "Foo.Baz")]
267+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo",
268+
CodeExplorerTestSetup.TestClassName, "Foo.Bar.Baz",
269+
CodeExplorerTestSetup.TestUserFormName, "Foo.Foo.Foo",
270+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz")]
271+
[TestCase(CodeExplorerTestSetup.TestClassName, "Foo Bar.Baz Baz",
272+
CodeExplorerTestSetup.TestDocumentName, "Foo Bar.Baz",
273+
CodeExplorerTestSetup.TestUserFormName, "Foo Bar.Foo Foo",
274+
CodeExplorerTestSetup.TestModuleName, "Foo Bar")]
275+
public void Synchronize_AddedComponent_HasCorrectSubFolderStructure(params object[] parameters)
276+
{
277+
var structure = ToFolderStructure(parameters.Cast<string>());
278+
var root = structure.First().Folder;
279+
var path = root.Split(FolderExtensions.FolderDelimiter);
280+
281+
var declarations = CodeExplorerTestSetup.TestProjectWithFolderStructure(structure, out var projectDeclaration);
282+
var synchronizing = CodeExplorerProjectViewModel.ExtractTrackedDeclarationsForProject(projectDeclaration, ref declarations);
283+
var component = synchronizing.TestComponentDeclarations(structure.Last().Name);
284+
var contents = synchronizing.Except(component).ToList();
285+
286+
var project = new CodeExplorerProjectViewModel(projectDeclaration, ref contents, null, null);
287+
var folder = project.Children.OfType<CodeExplorerCustomFolderViewModel>().Single(item => item.Name.Equals(path.First()));
288+
289+
project.Synchronize(ref synchronizing);
290+
291+
AssertFolderStructureIsCorrect(folder, structure);
292+
}
293+
294+
[Test]
295+
[Category("Code Explorer")]
296+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Modules",
297+
CodeExplorerTestSetup.TestClassName, "Foo.Classes",
298+
CodeExplorerTestSetup.TestDocumentName, "Foo.Docs",
299+
CodeExplorerTestSetup.TestUserFormName, "Foo.Forms")]
300+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo",
301+
CodeExplorerTestSetup.TestClassName, "Foo.Bar",
302+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar",
303+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar")]
304+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo",
305+
CodeExplorerTestSetup.TestClassName, "Foo.Bar",
306+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz",
307+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar")]
308+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Bar.Baz",
309+
CodeExplorerTestSetup.TestClassName, "Foo.Bar.Baz",
310+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz",
311+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar.Baz")]
312+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo.Baz",
313+
CodeExplorerTestSetup.TestClassName, "Foo.Baz",
314+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar",
315+
CodeExplorerTestSetup.TestUserFormName, "Foo.Bar")]
316+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo",
317+
CodeExplorerTestSetup.TestClassName, "Foo.Bar.Baz",
318+
CodeExplorerTestSetup.TestDocumentName, "Foo.Bar.Baz",
319+
CodeExplorerTestSetup.TestUserFormName, "Foo.Foo.Foo")]
320+
[TestCase(CodeExplorerTestSetup.TestModuleName, "Foo Bar",
321+
CodeExplorerTestSetup.TestClassName, "Foo Bar.Baz Baz",
322+
CodeExplorerTestSetup.TestDocumentName, "Foo Bar.Baz",
323+
CodeExplorerTestSetup.TestUserFormName, "Foo Bar.Foo Foo")]
324+
public void Synchronize_RemovedComponent_HasCorrectSubFolderStructure(params object[] parameters)
325+
{
326+
var structure = ToFolderStructure(parameters.Cast<string>());
327+
var root = structure.First().Folder;
328+
var path = root.Split(FolderExtensions.FolderDelimiter);
329+
330+
var declarations = CodeExplorerTestSetup.TestProjectWithFolderStructure(structure, out var projectDeclaration);
331+
var contents = CodeExplorerProjectViewModel.ExtractTrackedDeclarationsForProject(projectDeclaration, ref declarations);
332+
var component = contents.TestComponentDeclarations(structure.Last().Name);
333+
var synchronizing = contents.Except(component).ToList();
334+
335+
var project = new CodeExplorerProjectViewModel(projectDeclaration, ref contents, null, null);
336+
var folder = project.Children.OfType<CodeExplorerCustomFolderViewModel>().Single(item => item.Name.Equals(path.First()));
337+
338+
project.Synchronize(ref synchronizing);
339+
340+
AssertFolderStructureIsCorrect(folder, structure.Take(structure.Count - 1).ToList());
341+
}
342+
249343
private static void AssertFolderStructureIsCorrect(CodeExplorerCustomFolderViewModel underTest, List<(string Name, string Folder)> structure)
250344
{
251345
foreach (var (name, fullPath) in structure)
@@ -262,17 +356,17 @@ private static void AssertFolderStructureIsCorrect(CodeExplorerCustomFolderViewM
262356
path.Take(folder.FolderDepth + 1))));
263357
}
264358

265-
Assert.IsNotNull(folder);
359+
Assert.IsNotNull(folder, $"Folder {fullPath} was not found.");
266360

267361
var components = folder.Children.OfType<CodeExplorerComponentViewModel>().ToList();
268362
var component = components.SingleOrDefault(subFolder => subFolder.Name.Equals(name));
269363

270-
Assert.IsNotNull(component);
364+
Assert.IsNotNull(component, $"Component {name} was not found in folder {fullPath}.");
271365

272366
var expected = structure.Where(item => item.Folder.Equals(fullPath)).Select(item => item.Name).OrderBy(_ => _);
273367
var actual = components.Select(item => item.Declaration.IdentifierName).OrderBy(_ => _);
274368

275-
Assert.IsTrue(expected.SequenceEqual(actual));
369+
Assert.IsTrue(expected.SequenceEqual(actual), $"Folder {fullPath} does not contain expected components.");
276370
}
277371
}
278372

RubberduckTests/CodeExplorer/CodeExplorerProjectViewModelTests.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using System.Collections.Generic;
22
using NUnit.Framework;
33
using System.Linq;
4+
using Rubberduck.AddRemoveReferences;
45
using Rubberduck.Parsing.Symbols;
56
using Rubberduck.Navigation.CodeExplorer;
7+
using Rubberduck.VBEditor.SafeComWrappers;
8+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
69

710
namespace RubberduckTests.CodeExplorer
811
{
@@ -407,5 +410,95 @@ public void Synchronize_SetsDeclarationNull_DeclarationsForDifferentProject()
407410

408411
Assert.IsNull(project.Declaration);
409412
}
413+
414+
[Test]
415+
[Category("Code Explorer")]
416+
[TestCase(true, false, TestName = "Constructor_CreatesReferenceFolders_LibrariesOnly")]
417+
[TestCase(true, true, TestName = "Constructor_CreatesReferenceFolders_LibrariesAndProjects")]
418+
[TestCase(false, false, TestName = "Constructor_CreatesReferenceFolders_NoReferences")]
419+
[TestCase(false, true, TestName = "Constructor_CreatesReferenceFolders_ProjectsOnly")]
420+
public void Constructor_CreatesReferenceFolders(bool libraries, bool projects)
421+
{
422+
var declarations = CodeExplorerTestSetup.GetProjectDeclarationsWithReferences(libraries, projects);
423+
var projectDeclaration = declarations.First(declaration => declaration.DeclarationType == DeclarationType.Project);
424+
425+
var project = new CodeExplorerProjectViewModel(projectDeclaration, ref declarations, null, null);
426+
427+
var libraryFolder = project.Children.OfType<CodeExplorerReferenceFolderViewModel>()
428+
.SingleOrDefault(folder => folder.ReferenceKind == ReferenceKind.TypeLibrary);
429+
var projectFolder = project.Children.OfType<CodeExplorerReferenceFolderViewModel>()
430+
.SingleOrDefault(folder => folder.ReferenceKind == ReferenceKind.Project);
431+
432+
Assert.AreEqual(libraries, libraryFolder != null);
433+
Assert.AreEqual(projects, projectFolder != null);
434+
}
435+
436+
[Test]
437+
[Category("Code Explorer")]
438+
[TestCase(true, false, TestName = "Synchronize_ReferenceFolders_NoChanges_LibrariesOnly")]
439+
[TestCase(true, true, TestName = "Synchronize_ReferenceFolders_NoChanges_LibrariesAndProjects")]
440+
[TestCase(false, false, TestName = "Synchronize_ReferenceFolders_NoChanges_NoReferences")]
441+
[TestCase(false, true, TestName = "Synchronize_ReferenceFolders_NoChanges_ProjectsOnly")]
442+
public void Synchronize_ReferenceFolders_NoChanges(bool libraries, bool projects)
443+
{
444+
var declarations = CodeExplorerTestSetup.GetProjectDeclarationsWithReferences(libraries, projects);
445+
var updates = declarations.ToList();
446+
var projectDeclaration = declarations.First(declaration => declaration.DeclarationType == DeclarationType.Project);
447+
448+
var expected = GetReferencesFromProjectDeclaration(projectDeclaration).Select(reference => reference.Name).ToList();
449+
450+
var project = new CodeExplorerProjectViewModel(projectDeclaration, ref declarations, null, null);
451+
project.Synchronize(ref updates);
452+
453+
var actual = GetReferencesFromProjectViewModel(project).OrderBy(reference => reference.Priority).Select(reference => reference.Name);
454+
455+
Assert.IsTrue(expected.SequenceEqual(actual));
456+
}
457+
458+
[Test]
459+
[Ignore("References.Remove is not mocked yet. Remove this annotation when it is working.")]
460+
[Category("Code Explorer")]
461+
[TestCase(true, false, TestName = "Synchronize_ReferenceFolderRemoved_Libraries")]
462+
[TestCase(false, true, TestName = "Synchronize_ReferenceFolderRemoved_Projects")]
463+
[TestCase(true, true, TestName = "Synchronize_ReferenceFolderRemoved_Both")]
464+
public void Synchronize_ReferenceFolderRemoved(bool libraries, bool projects)
465+
{
466+
var declarations = CodeExplorerTestSetup.GetProjectDeclarationsWithReferences(libraries, projects);
467+
var updates = declarations.ToList();
468+
var projectDeclaration = declarations.First(declaration => declaration.DeclarationType == DeclarationType.Project);
469+
470+
var project = new CodeExplorerProjectViewModel(projectDeclaration, ref declarations, null, null);
471+
472+
var references = projectDeclaration.Project.References;
473+
foreach (var reference in references.ToList())
474+
{
475+
references.Remove(reference);
476+
}
477+
478+
project.Synchronize(ref updates);
479+
480+
var libraryFolder = project.Children.OfType<CodeExplorerReferenceFolderViewModel>()
481+
.SingleOrDefault(folder => folder.ReferenceKind == ReferenceKind.TypeLibrary);
482+
var projectFolder = project.Children.OfType<CodeExplorerReferenceFolderViewModel>()
483+
.SingleOrDefault(folder => folder.ReferenceKind == ReferenceKind.Project);
484+
485+
Assert.IsNull(libraryFolder);
486+
Assert.IsNull(projectFolder);
487+
}
488+
489+
private static List<ReferenceModel> GetReferencesFromProjectViewModel(ICodeExplorerNode viewModel)
490+
{
491+
return viewModel.Children
492+
.OfType<CodeExplorerReferenceFolderViewModel>()
493+
.SelectMany(folder => folder.Children
494+
.OfType<CodeExplorerReferenceViewModel>()
495+
.Select(vm => vm.Reference))
496+
.ToList();
497+
}
498+
499+
private static List<IReference> GetReferencesFromProjectDeclaration(Declaration project)
500+
{
501+
return project.Project.References.ToList();
502+
}
410503
}
411504
}

0 commit comments

Comments
 (0)