From fa497e62cf3086cc8aa8d34612c1dea50afe956c Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Fri, 25 May 2012 19:51:12 +0100 Subject: [PATCH] Implement EnvDTE.CodeModel and CodeNamespace. --- .../Project/PackageManagement.csproj | 5 + .../Project/Src/EnvDTE/ChildCodeNamespaces.cs | 54 +++++++ .../Project/Src/EnvDTE/CodeClass.cs | 4 + .../Project/Src/EnvDTE/CodeElement.cs | 2 +- .../Project/Src/EnvDTE/CodeModel.cs | 8 +- .../Project/Src/EnvDTE/CodeNamespace.cs | 37 ++++- .../Src/EnvDTE/CodeNamespaceMembers.cs | 50 ++++++ .../Project/Src/EnvDTE/CodeType.cs | 4 + .../Src/EnvDTE/CodeTypesInNamespace.cs | 52 ++++++ .../Project/Src/EnvDTE/NamespaceName.cs | 61 ++++++++ .../Project/Src/EnvDTE/ProjectCodeElements.cs | 53 +++++++ .../Test/PackageManagement.Tests.csproj | 2 + .../Test/Src/EnvDTE/CodeModelTests.cs | 104 ++++++++++++ .../Test/Src/EnvDTE/CodeNamespaceTests.cs | 148 ++++++++++++++++++ .../Test/Src/Helpers/CodeElementsHelpers.cs | 27 ++++ .../Test/Src/Helpers/ProjectContentHelper.cs | 41 +++++ 16 files changed, 647 insertions(+), 5 deletions(-) create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildCodeNamespaces.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespaceMembers.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeTypesInNamespace.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectCodeElements.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeNamespaceTests.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsHelpers.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index 778ab534d4..15ae943328 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -74,6 +74,7 @@ + @@ -86,6 +87,7 @@ + @@ -97,10 +99,13 @@ + + + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildCodeNamespaces.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildCodeNamespaces.cs new file mode 100644 index 0000000000..145010e56e --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildCodeNamespaces.cs @@ -0,0 +1,54 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class ChildCodeNamespaces : List + { + IProjectContent projectContent; + CodeNamespace parentNamespace; + HashSet namespacesAdded = new HashSet(); + + public ChildCodeNamespaces(IProjectContent projectContent, CodeNamespace parentNamespace) + { + this.projectContent = projectContent; + this.parentNamespace = parentNamespace; + AddChildNamespaces(); + } + + void AddChildNamespaces() + { + foreach (string namespaceName in GetUniqueQualifiedChildNamespaceNames()) { + AddCodeNamespace(namespaceName); + } + } + + IEnumerable GetUniqueQualifiedChildNamespaceNames() + { + foreach (string namespaceName in projectContent.NamespaceNames) { + string qualifiedChildNamespaceName = parentNamespace.GetChildNamespaceName(namespaceName); + if (IsUniqueChildNamespaceName(qualifiedChildNamespaceName)) { + namespacesAdded.Add(qualifiedChildNamespaceName); + yield return qualifiedChildNamespaceName; + } + } + } + + bool IsUniqueChildNamespaceName(string name) + { + if (name != null) { + return !namespacesAdded.Contains(name); + } + return false; + } + + void AddCodeNamespace(string namespaceName) + { + Add(new CodeNamespace(projectContent, namespaceName)); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs index 122585390e..61ad9b8e6b 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs @@ -13,6 +13,10 @@ namespace ICSharpCode.PackageManagement.EnvDTE { } + public CodeClass() + { + } + public virtual CodeElements ImplementedInterfaces { get { throw new NotImplementedException(); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs index 43ee2615c5..081b04021e 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs @@ -42,7 +42,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE throw new NotImplementedException(); } - public virtual vsCMInfoLocation InfoLocation { get; private set; } + public virtual vsCMInfoLocation InfoLocation { get; protected set; } public virtual DTE DTE { get; private set; } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs index ba957ce9dd..c2450b50f9 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs @@ -9,6 +9,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE public class CodeModel : MarshalByRefObject { IProjectContent projectContent; + ProjectCodeElements codeElements; public CodeModel(IProjectContent projectContent) { @@ -16,7 +17,12 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public CodeElements CodeElements { - get { throw new NotImplementedException(); } + get { + if (codeElements == null) { + codeElements = new ProjectCodeElements(projectContent); + } + return codeElements; + } } public CodeType CodeTypeFromFullName(string name) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs index ee3cc83fe7..7020452a2c 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs @@ -2,21 +2,52 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.PackageManagement.EnvDTE { public class CodeNamespace : CodeElement { - public CodeNamespace() + NamespaceName namespaceName; + IProjectContent projectContent; + CodeNamespaceMembers members; + + public CodeNamespace(IProjectContent projectContent, string qualifiedName) + : base(null) { + this.projectContent = projectContent; + this.namespaceName = new NamespaceName(qualifiedName); + this.InfoLocation = vsCMInfoLocation.vsCMInfoLocationExternal; + } + + internal string QualifiedName { + get { return namespaceName.QualifiedName; } + } + + internal NamespaceName NamespaceName { + get { return namespaceName; } } public string FullName { - get { throw new NotImplementedException(); } + get { return this.Name; } + } + + public override string Name { + get { return namespaceName.LastPart; } } public CodeElements Members { - get { throw new NotImplementedException(); } + get { + if (members == null) { + members = new CodeNamespaceMembers(projectContent, this); + } + return members; + } + } + + internal string GetChildNamespaceName(string qualifiedName) + { + return namespaceName.GetChildNamespaceName(qualifiedName); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespaceMembers.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespaceMembers.cs new file mode 100644 index 0000000000..ab31c1b3e3 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespaceMembers.cs @@ -0,0 +1,50 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Collections.Generic; + +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class CodeNamespaceMembers : CodeElements + { + List elements = new List(); + IProjectContent projectContent; + CodeNamespace codeNamespace; + + public CodeNamespaceMembers(IProjectContent projectContent, CodeNamespace codeNamespace) + { + this.projectContent = projectContent; + this.codeNamespace = codeNamespace; + GetMembers(); + } + + void GetMembers() + { + AddNamespaceMembers(); + AddTypesInNamespace(); + } + + void AddNamespaceMembers() + { + elements.AddRange(new ChildCodeNamespaces(projectContent, codeNamespace)); + } + + void AddTypesInNamespace() + { + elements.AddRange(new CodeTypesInNamespace(projectContent, codeNamespace)); + } + + public int Count { + get { return elements.Count; } + } + + public IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs index 563de33a6a..6159391d98 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs @@ -14,6 +14,10 @@ namespace ICSharpCode.PackageManagement.EnvDTE this.Class = c; } + public CodeType() + { + } + protected IClass Class { get; private set; } public virtual vsCMAccess Access { get; set; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeTypesInNamespace.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeTypesInNamespace.cs new file mode 100644 index 0000000000..0a2cc9e23d --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeTypesInNamespace.cs @@ -0,0 +1,52 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class CodeTypesInNamespace : List + { + IProjectContent projectContent; + CodeNamespace codeNamespace; + + public CodeTypesInNamespace(IProjectContent projectContent, string namespaceName) + : this(projectContent, new CodeNamespace(projectContent, namespaceName)) + { + } + + public CodeTypesInNamespace(IProjectContent projectContent, CodeNamespace codeNamespace) + { + this.projectContent = projectContent; + this.codeNamespace = codeNamespace; + AddTypes(); + } + + void AddTypes() + { + foreach (ICompletionEntry completionEntry in GetTypesInNamespace()) { + AddMember(completionEntry); + } + } + + List GetTypesInNamespace() + { + return projectContent.GetNamespaceContents(codeNamespace.QualifiedName); + } + + void AddMember(ICompletionEntry completionEntry) + { + IClass classMember = completionEntry as IClass; + if (classMember != null) { + AddClassMember(classMember); + } + } + + void AddClassMember(IClass classMember) + { + Add(new CodeClass2(classMember)); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs new file mode 100644 index 0000000000..fed788e2c9 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs @@ -0,0 +1,61 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class NamespaceName + { + public NamespaceName(string qualifiedName) + { + this.QualifiedName = qualifiedName; + FirstPart = GetFirstPartOfNamespace(); + LastPart = GetLastPartOfNamespace(); + } + + string GetFirstPartOfNamespace() + { + int index = QualifiedName.IndexOf('.'); + if (index >= 0) { + return QualifiedName.Substring(0, index); + } + return QualifiedName; + } + + string GetLastPartOfNamespace() + { + int index = QualifiedName.LastIndexOf('.'); + return QualifiedName.Substring(index + 1); + } + + public string FirstPart { get; private set; } + public string LastPart { get; private set; } + public string QualifiedName { get; private set; } + + public string GetChildNamespaceName(string namespaceName) + { + if (QualifiedName == String.Empty) { + return GetChildNamespaceNameForRootNamespace(namespaceName); + } + + string dottedQualifiedName = QualifiedName + "."; + if (namespaceName.StartsWith(dottedQualifiedName)) { + int nextIndex = namespaceName.IndexOf('.', dottedQualifiedName.Length); + if (nextIndex >= 0) { + return namespaceName.Substring(0, nextIndex); + } + return namespaceName; + } + return null; + } + + string GetChildNamespaceNameForRootNamespace(string namespaceName) + { + if (!String.IsNullOrEmpty(namespaceName)) { + return new NamespaceName(namespaceName).FirstPart; + } + return null; + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectCodeElements.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectCodeElements.cs new file mode 100644 index 0000000000..cc90945864 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectCodeElements.cs @@ -0,0 +1,53 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class ProjectCodeElements : CodeElements + { + List codeElements = new List(); + IProjectContent projectContent; + + public ProjectCodeElements(IProjectContent projectContent) + { + this.projectContent = projectContent; + AddCodeElements(); + } + + void AddCodeElements() + { + AddNamespaceCodeElements(); + AddClassesWithNoNamespace(); + } + + void AddNamespaceCodeElements() + { + codeElements.AddRange(CreateChildNodeNamespaces()); + } + + ChildCodeNamespaces CreateChildNodeNamespaces() + { + return new ChildCodeNamespaces(projectContent, new CodeNamespace(projectContent, String.Empty)); + } + + void AddClassesWithNoNamespace() + { + codeElements.AddRange(new CodeTypesInNamespace(projectContent, String.Empty)); + } + + public int Count { + get { return codeElements.Count; } + } + + public IEnumerator GetEnumerator() + { + return codeElements.GetEnumerator(); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index a4713e2160..5f9de9bcae 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -73,7 +73,9 @@ Properties\GlobalAssemblyInfo.cs + + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs index 3fffbd7e51..9e0c9de528 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs @@ -2,6 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; +using System.Linq; using ICSharpCode.PackageManagement.EnvDTE; using ICSharpCode.SharpDevelop.Dom; using NUnit.Framework; @@ -27,11 +29,31 @@ namespace PackageManagement.Tests.EnvDTE helper.AddClassToProjectContent(className); } + void AddClassToProjectContent(string namespaceName, string className) + { + helper.AddClassToProjectContent(namespaceName, className); + } + void AddInterfaceToProjectContent(string interfaceName) { helper.AddInterfaceToProjectContent(interfaceName); } + void AddNamespaceToProjectContent(string name) + { + helper.AddNamespaceNameToProjectContent(name); + } + + void AddEmptyNamespaceContentsForRootNamespace() + { + helper.AddEmptyNamespaceContentsForRootNamespace(); + } + + void AddEmptyNamespaceContents(string namespaceName) + { + helper.AddEmptyNamespaceContents(namespaceName); + } + [Test] public void CodeTypeFromFullName_NoSuchTypeInProject_ReturnsNull() { @@ -75,5 +97,87 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual("Interface1", codeInterface.FullName); } + + [Test] + public void CodeElements_OneNamespaceInProject_ReturnsOneCodeNamespaceItem() + { + CreateCodeModel(); + AddNamespaceToProjectContent("Test"); + AddEmptyNamespaceContentsForRootNamespace(); + + CodeElements codeElements = codeModel.CodeElements; + CodeNamespace codeNamespace = codeElements.FirstOrDefault() as CodeNamespace; + + Assert.AreEqual(1, codeElements.Count); + Assert.AreEqual("Test", codeNamespace.FullName); + Assert.AreEqual("Test", codeNamespace.Name); + } + + [Test] + public void CodeElements_OneNamespaceInProjectWithTwoPartsToName_ReturnsOneCodeNamespaceItemWithFirstPartOfNamespaceAsName() + { + CreateCodeModel(); + AddNamespaceToProjectContent("First.Second"); + AddEmptyNamespaceContentsForRootNamespace(); + + CodeElements codeElements = codeModel.CodeElements; + CodeNamespace codeNamespace = codeElements.FirstOrDefault() as CodeNamespace; + + Assert.AreEqual(1, codeElements.Count); + Assert.AreEqual("First", codeNamespace.FullName); + Assert.AreEqual("First", codeNamespace.Name); + } + + [Test] + public void CodeElements_OneClassWithNoNamespaceInProject_ReturnsOneCodeClassItem() + { + CreateCodeModel(); + AddClassToProjectContent(String.Empty, "TestClass"); + + CodeElements codeElements = codeModel.CodeElements; + CodeClass2 codeClass = codeElements.FirstOrDefault() as CodeClass2; + + Assert.AreEqual(1, codeElements.Count); + Assert.AreEqual("TestClass", codeClass.FullName); + } + + [Test] + public void CodeElements_TwoNamespacesInProjectWithFirstPartsTheName_ReturnsOneParentNamespaceWithTwoChildNamespaces() + { + CreateCodeModel(); + AddNamespaceToProjectContent("First.A"); + AddNamespaceToProjectContent("First.B"); + AddEmptyNamespaceContentsForRootNamespace(); + AddEmptyNamespaceContents("First"); + + CodeElements codeElements = codeModel.CodeElements; + CodeNamespace codeNamespace = codeElements.FirstOrDefault() as CodeNamespace; + + List members = codeNamespace.Members.ToList(); + CodeNamespace firstChildNamespace = members.FirstOrDefault() as CodeNamespace; + CodeNamespace secondChildNamespace = members.LastOrDefault() as CodeNamespace; + + Assert.AreEqual(1, codeElements.Count); + Assert.AreEqual("First", codeNamespace.FullName); + Assert.AreEqual(2, codeNamespace.Members.Count); + Assert.AreEqual("A", firstChildNamespace.Name); + Assert.AreEqual("B", secondChildNamespace.Name); + } + + [Test] + public void CodeElements_ProjectHasEmptyNamespaceName_EmptyNamespaceNameNotIncludedInMembers() + { + CreateCodeModel(); + AddNamespaceToProjectContent(String.Empty); + AddNamespaceToProjectContent("Tests"); + AddEmptyNamespaceContentsForRootNamespace(); + AddEmptyNamespaceContents("Tests"); + + CodeElements members = codeModel.CodeElements; + CodeNamespace codeNamespace = members.ToList().FirstOrDefault() as CodeNamespace; + + Assert.AreEqual(1, members.Count); + Assert.AreEqual("Tests", codeNamespace.Name); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeNamespaceTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeNamespaceTests.cs new file mode 100644 index 0000000000..8852afa4c5 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeNamespaceTests.cs @@ -0,0 +1,148 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.SharpDevelop.Dom; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; + +namespace PackageManagement.Tests.EnvDTE +{ + [TestFixture] + public class CodeNamespaceTests + { + CodeNamespace codeNamespace; + ProjectContentHelper helper; + + void CreateCodeNamespace(string namespaceName) + { + codeNamespace = new CodeNamespace(helper.FakeProjectContent, namespaceName); + } + + void CreateProjectContent() + { + helper = new ProjectContentHelper(); + } + + void AddClassToProjectContent(string namespaceName, string className) + { + helper.AddClassToProjectContent(namespaceName, className); + } + + void AddNamespaceToProjectContent(string name) + { + helper.AddNamespaceNameToProjectContent(name); + } + + void NoClassesInNamespace(string name) + { + helper.AddEmptyNamespaceContents(name); + } + + void AddUnknownCompletionEntryToNamespace(string namespaceName) + { + helper.AddUnknownCompletionEntryTypeToNamespace(namespaceName); + } + + [Test] + public void Members_NamespaceHasOneClass_ReturnsOneClass() + { + CreateProjectContent(); + AddNamespaceToProjectContent("Tests"); + AddClassToProjectContent("Tests", "Tests.MyClass"); + CreateCodeNamespace("Tests"); + + CodeElements members = codeNamespace.Members; + CodeClass2 codeClass = members.FirstOrDefault() as CodeClass2; + + Assert.AreEqual(1, members.Count); + Assert.AreEqual("Tests.MyClass", codeClass.FullName); + } + + [Test] + public void Members_NamespaceHasOneChildNamespace_ReturnsOneChildNamespace() + { + CreateProjectContent(); + AddNamespaceToProjectContent("First.Second"); + NoClassesInNamespace("First"); + NoClassesInNamespace("First.Second"); + CreateCodeNamespace("First"); + + CodeElements members = codeNamespace.Members; + CodeNamespace childNamespace = members.FirstOrDefault() as CodeNamespace; + + Assert.AreEqual("First", codeNamespace.Name); + Assert.AreEqual(1, members.Count); + Assert.AreEqual("Second", childNamespace.Name); + Assert.AreEqual("Second", childNamespace.FullName); + } + + [Test] + public void InfoLocation_NamespaceHasNoClasses_ReturnsExternal() + { + CreateProjectContent(); + CreateCodeNamespace("Test"); + + Assert.AreEqual(vsCMInfoLocation.vsCMInfoLocationExternal, codeNamespace.InfoLocation); + } + + [Test] + public void Members_NamespaceHasOneChildNamespaceWithThreeNamespaceParts_ReturnsOneChildNamespaceWhichHasOneChildNamespace() + { + CreateProjectContent(); + AddNamespaceToProjectContent("First.Second.Third"); + NoClassesInNamespace("First"); + NoClassesInNamespace("First.Second"); + NoClassesInNamespace("First.Second.Third"); + CreateCodeNamespace("First"); + + CodeElements members = codeNamespace.Members; + CodeNamespace secondNamespace = members.FirstOrDefault() as CodeNamespace; + CodeNamespace thirdNamespace = secondNamespace.Members.FirstOrDefault() as CodeNamespace; + + Assert.AreEqual("First", codeNamespace.Name); + Assert.AreEqual(1, members.Count); + Assert.AreEqual("Second", secondNamespace.Name); + Assert.AreEqual("Second", secondNamespace.FullName); + Assert.AreEqual(1, secondNamespace.Members.Count); + Assert.AreEqual("Third", thirdNamespace.FullName); + Assert.AreEqual(0, thirdNamespace.Members.Count); + } + + [Test] + public void Members_ProjectHasTwoNamespacesWithCommonFirstAndSecondPartOfThreePartNamespace_ReturnsOneChildNamespaceWhichHasOneChildNamespace() + { + CreateProjectContent(); + AddNamespaceToProjectContent("First.Second.Third"); + AddNamespaceToProjectContent("First.Second.Different"); + NoClassesInNamespace("First"); + NoClassesInNamespace("First.Second"); + NoClassesInNamespace("First.Second.Third"); + NoClassesInNamespace("First.Second.Different"); + CreateCodeNamespace("First"); + + CodeElements members = codeNamespace.Members; + CodeNamespace secondNamespace = members.FirstOrDefault() as CodeNamespace; + + Assert.AreEqual("First", codeNamespace.Name); + Assert.AreEqual(1, members.Count); + Assert.AreEqual("Second", secondNamespace.Name); + Assert.AreEqual("Second", secondNamespace.FullName); + Assert.AreEqual(2, secondNamespace.Members.Count); + } + + [Test] + public void Members_NamespaceHasUnknownNamespaceEntryType_ReturnsNoItems() + { + CreateProjectContent(); + AddNamespaceToProjectContent("Tests"); + AddUnknownCompletionEntryToNamespace("Tests"); + CreateCodeNamespace("Tests"); + + CodeElements members = codeNamespace.Members; + + Assert.AreEqual(0, members.Count); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsHelpers.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsHelpers.cs new file mode 100644 index 0000000000..000537dfd6 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsHelpers.cs @@ -0,0 +1,27 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.PackageManagement.EnvDTE; + +namespace PackageManagement.Tests.Helpers +{ + public static class CodeElementsHelpers + { + public static CodeElement FirstOrDefault(this CodeElements codeElements) + { + return ToList(codeElements).FirstOrDefault(); + } + + public static List ToList(this CodeElements codeElements) + { + var list = new List(); + foreach (CodeElement codeElement in codeElements) { + list.Add(codeElement); + } + return list; + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs index 52f796b712..fc263ff622 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; using ICSharpCode.SharpDevelop.Dom; using Rhino.Mocks; @@ -10,10 +11,32 @@ namespace PackageManagement.Tests.Helpers public class ProjectContentHelper { public IProjectContent FakeProjectContent; + public List NamespaceNames = new List(); public ProjectContentHelper() { FakeProjectContent = MockRepository.GenerateStub(); + FakeProjectContent.Stub(pc => pc.NamespaceNames).Return(NamespaceNames); + } + + public IClass AddClassToProjectContent(string namespaceName, string className) + { + IClass fakeClass = AddClassToProjectContent(className); + var namespaceContents = new List(); + namespaceContents.Add(fakeClass); + AddNamespaceContents(namespaceName, namespaceContents); + + return fakeClass; + } + + public void AddNamespaceContents(string namespaceName, List namespaceContents) + { + FakeProjectContent.Stub(pc => pc.GetNamespaceContents(namespaceName)).Return(namespaceContents); + } + + public void AddEmptyNamespaceContents(string namespaceName) + { + AddNamespaceContents(namespaceName, new List()); } public IClass AddClassToProjectContent(string className) @@ -38,5 +61,23 @@ namespace PackageManagement.Tests.Helpers fakeClass.Stub(c => c.ClassType).Return(ClassType.Interface); return fakeClass; } + + public void AddNamespaceNameToProjectContent(string name) + { + NamespaceNames.Add(name); + } + + public void AddEmptyNamespaceContentsForRootNamespace() + { + AddEmptyNamespaceContents(String.Empty); + } + + public void AddUnknownCompletionEntryTypeToNamespace(string namespaceName) + { + var unknownEntry = MockRepository.GenerateStub(); + var namespaceContents = new List(); + namespaceContents.Add(unknownEntry); + AddNamespaceContents(namespaceName, namespaceContents); + } } }