From 72b0a52bcfd40cde2bc4b6510451749deff3c841 Mon Sep 17 00:00:00 2001 From: mrward Date: Thu, 16 Sep 2010 22:38:22 +0100 Subject: [PATCH] Asterisk character treated as a normal key character when completing IronPython code. --- .../BackendBindings/Python/PythonBinding.sln | 2 +- .../Project/PythonBinding.csproj | 2 + .../Src/PythonCodeCompletionBinding.cs | 29 +++-- .../Src/PythonCodeCompletionItemProvider.cs | 16 +++ .../Project/Src/PythonCompletionItemList.cs | 25 +++++ .../Project/Src/PythonImportCompletion.cs | 14 ++- .../Src/PythonImportExpressionContext.cs | 7 ++ ...nBindingFromImportCompletionTestFixture.cs | 42 -------- ...pletionBindingFromImportCompletionTests.cs | 70 ++++++++++++ ...etionBindingImportCompletionTestFixture.cs | 89 --------------- ...eCompletionBindingImportCompletionTests.cs | 101 ++++++++++++++++++ ...omImportDotNetNamespaceCompletionTests.cs} | 10 +- ... FromImportPythonModuleCompletionTests.cs} | 20 +++- .../PythonCodeCompletionItemProviderTests.cs | 23 ++++ .../PythonCompletionItemListTests.cs | 41 +++++++ ... => PythonImportExpressionContextTests.cs} | 53 ++++++--- .../Test/PythonBinding.Tests.csproj | 16 +-- .../ImportModuleResolveResultTests.cs | 20 ++-- .../DerivedPythonCodeCompletionBinding.cs | 94 ---------------- .../Test/Utils/FakeCompletionItemProvider.cs | 24 +++++ .../TestablePythonCodeCompletionBinding.cs | 51 +++++++++ ...establePythonCodeCompletionItemProvider.cs | 17 +++ 22 files changed, 485 insertions(+), 281 deletions(-) create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionItemProvider.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs delete mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTests.cs delete mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTests.cs rename src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/{FromImportDotNetNamespaceCompletionTestFixture.cs => FromImportDotNetNamespaceCompletionTests.cs} (74%) rename src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/{FromImportPythonModuleCompletionTestFixture.cs => FromImportPythonModuleCompletionTests.cs} (58%) create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCodeCompletionItemProviderTests.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCompletionItemListTests.cs rename src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/{PythonImportExpressionContextTestFixture.cs => PythonImportExpressionContextTests.cs} (57%) delete mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedPythonCodeCompletionBinding.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/FakeCompletionItemProvider.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionBinding.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionItemProvider.cs diff --git a/src/AddIns/BackendBindings/Python/PythonBinding.sln b/src/AddIns/BackendBindings/Python/PythonBinding.sln index 9e95cf6c2e..fb15eb87e0 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding.sln +++ b/src/AddIns/BackendBindings/Python/PythonBinding.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.0.0.6569 +# SharpDevelop 4.0.0.6611 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonBinding", "PythonBinding\Project\PythonBinding.csproj", "{8D732610-8FC6-43BA-94C9-7126FD7FE361}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonBinding.Tests", "PythonBinding\Test\PythonBinding.Tests.csproj", "{23B517C9-1ECC-4419-A13F-0B7136D085CB}" diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj index 2becd4bdb9..6e4f0eb411 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj @@ -92,6 +92,8 @@ + + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionBinding.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionBinding.cs index e2bd66fc14..55dd92c2ac 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionBinding.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionBinding.cs @@ -10,43 +10,38 @@ using System.Collections.Generic; namespace ICSharpCode.PythonBinding { - /// - /// Python code completion binding. - /// public class PythonCodeCompletionBinding : DefaultCodeCompletionBinding { - public PythonCodeCompletionBinding() - { - } - /// /// Shows the code completion window if the keyword is handled. /// /// The keyword string. /// true if the keyword is handled; otherwise false. - public override bool HandleKeyword(ICSharpCode.SharpDevelop.Editor.ITextEditor editor, string word) + public override bool HandleKeyword(ITextEditor editor, string word) { if (word != null) { switch (word.ToLowerInvariant()) { case "import": case "from": - AbstractCompletionItemProvider dataProvider = CreateCompletionDataProvider(); - ShowCodeCompletionWindow(editor, dataProvider, ' '); - return true; + return HandleImportKeyword(editor); } } return false; } - protected virtual AbstractCompletionItemProvider CreateCompletionDataProvider() + bool HandleImportKeyword(ITextEditor editor) { - return new CodeCompletionItemProvider(); + AbstractCompletionItemProvider provider = CreateKeywordCompletionItemProvider(); + ShowCodeCompletionWindow(provider, editor); + return true; } - /// - /// Shows the code completion window. - /// - protected virtual void ShowCodeCompletionWindow(ICSharpCode.SharpDevelop.Editor.ITextEditor editor, AbstractCompletionItemProvider completionItemProvider, char ch) + protected virtual AbstractCompletionItemProvider CreateKeywordCompletionItemProvider() + { + return new PythonCodeCompletionItemProvider(); + } + + protected virtual void ShowCodeCompletionWindow(AbstractCompletionItemProvider completionItemProvider, ITextEditor editor) { completionItemProvider.ShowCompletion(editor); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionItemProvider.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionItemProvider.cs new file mode 100644 index 0000000000..a300cca621 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeCompletionItemProvider.cs @@ -0,0 +1,16 @@ +// 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.SharpDevelop.Editor.CodeCompletion; + +namespace ICSharpCode.PythonBinding +{ + public class PythonCodeCompletionItemProvider : CodeCompletionItemProvider + { + protected override DefaultCompletionItemList CreateCompletionItemList() + { + return new PythonCompletionItemList(); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs new file mode 100644 index 0000000000..96bcbb202b --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompletionItemList.cs @@ -0,0 +1,25 @@ +// 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.SharpDevelop.Editor.CodeCompletion; + +namespace ICSharpCode.PythonBinding +{ + public class PythonCompletionItemList : DefaultCompletionItemList + { + public override CompletionItemListKeyResult ProcessInput(char key) + { + if (key == '*') { + return ProcessAsterisk(); + } + return base.ProcessInput(key); + } + + CompletionItemListKeyResult ProcessAsterisk() + { + InsertSpace = false; + return CompletionItemListKeyResult.NormalKey; + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportCompletion.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportCompletion.cs index c8308a5cea..59bf5e0d43 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportCompletion.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportCompletion.cs @@ -12,6 +12,8 @@ namespace ICSharpCode.PythonBinding { public class PythonImportCompletion { + public static readonly NamespaceEntry ImportAll = new NamespaceEntry("*"); + IProjectContent projectContent; static readonly PythonStandardModules standardPythonModules = new PythonStandardModules(); @@ -41,12 +43,22 @@ namespace ICSharpCode.PythonBinding } public List GetCompletionItemsFromModule(string module) + { + List items = GetCompletionItemsFromStandardPythonModules(module); + if (items == null) { + items = projectContent.GetNamespaceContents(module); + } + items.Add(ImportAll); + return items; + } + + List GetCompletionItemsFromStandardPythonModules(string module) { PythonStandardModuleType type = standardPythonModules.GetModuleType(module); if (type != null) { return GetCompletionItemsFromModule(type); } - return projectContent.GetNamespaceContents(module); + return null; } List GetCompletionItemsFromModule(PythonStandardModuleType type) diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportExpressionContext.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportExpressionContext.cs index 8bd2fa99f9..b798686330 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportExpressionContext.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonImportExpressionContext.cs @@ -31,8 +31,15 @@ namespace ICSharpCode.PythonBinding return true; } else if (entry is IClass) { return true; + } else if (entry is NamespaceEntry) { + return IsImportAll(entry); } return false; } + + bool IsImportAll(ICompletionEntry entry) + { + return PythonImportCompletion.ImportAll.Equals(entry); + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTestFixture.cs deleted file mode 100644 index 9de7c2a42c..0000000000 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTestFixture.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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.Core; -using ICSharpCode.PythonBinding; -using ICSharpCode.SharpDevelop.Editor.AvalonEdit; -using ICSharpCode.SharpDevelop.Dom; -using NUnit.Framework; -using PythonBinding.Tests.Utils; - -namespace PythonBinding.Tests.Completion -{ - /// - /// Tests that the From keyword is correctly identified as a - /// importable code completion keyword. - /// - [TestFixture] - public class FromImportCompletionTestFixture - { - DerivedPythonCodeCompletionBinding codeCompletionBinding; - bool handlesImportKeyword; - AvalonEditTextEditorAdapter textEditor; - - [TestFixtureSetUp] - public void SetUpFixture() - { - if (!PropertyService.Initialized) { - PropertyService.InitializeService(String.Empty, String.Empty, String.Empty); - } - textEditor = new AvalonEditTextEditorAdapter(new ICSharpCode.AvalonEdit.TextEditor()); - codeCompletionBinding = new DerivedPythonCodeCompletionBinding(); - handlesImportKeyword = codeCompletionBinding.HandleKeyword(textEditor, "from"); - } - - [Test] - public void HandlesImportKeyWord() - { - Assert.IsTrue(handlesImportKeyword); - } - } -} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTests.cs new file mode 100644 index 0000000000..fb78f0fac4 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingFromImportCompletionTests.cs @@ -0,0 +1,70 @@ +// 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.PythonBinding; +using ICSharpCode.Scripting.Tests.Utils; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Completion +{ + /// + /// Tests that the From keyword is correctly identified as a + /// importable code completion keyword. + /// + [TestFixture] + public class CodeCompletionBindingFromImportCompletionTests + { + MockTextEditor fakeTextEditor; + TestablePythonCodeCompletionBinding codeCompletionBinding; + + void CreatePythonCodeCompletionBinding() + { + fakeTextEditor = new MockTextEditor(); + codeCompletionBinding = new TestablePythonCodeCompletionBinding(); + } + + [Test] + public void HandleKeyword_KeywordIsFrom_ReturnsTrue() + { + CreatePythonCodeCompletionBinding(); + bool handled = codeCompletionBinding.HandleKeyword(fakeTextEditor, "from"); + Assert.IsTrue(handled); + } + + [Test] + public void HandleKeyword_KeywordIsFrom_PythonDotCodeCompletionItemProviderUsedToShowCompletionWindow() + { + CreatePythonCodeCompletionBinding(); + codeCompletionBinding.HandleKeyword(fakeTextEditor, "from"); + ITextEditor textEditor = codeCompletionBinding.TextEditorPassedToShowCompletionWindow; + + Assert.AreEqual(fakeTextEditor, textEditor); + } + + [Test] + public void HandleKeyword_KeywordIsFrom_PythonCodeCompletionItemProviderCreated() + { + CreatePythonCodeCompletionBinding(); + codeCompletionBinding.HandleKeyword(fakeTextEditor, "from"); + + PythonCodeCompletionItemProvider provider = codeCompletionBinding.KeywordCompletionItemProviderCreated as PythonCodeCompletionItemProvider; + + Assert.IsNotNull(provider); + } + + [Test] + public void HandleKeyword_KeywordIsFrom_PythonCodeCompletionItemProviderPassedToShowCompletionWindow() + { + CreatePythonCodeCompletionBinding(); + codeCompletionBinding.HandleKeyword(fakeTextEditor, "from"); + + AbstractCompletionItemProvider provider = codeCompletionBinding.CompletionItemProviderUsedWhenDisplayingCodeCompletionWindow; + + Assert.AreSame(codeCompletionBinding.KeywordCompletionItemProviderCreated, provider); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTestFixture.cs deleted file mode 100644 index 78f0173e40..0000000000 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTestFixture.cs +++ /dev/null @@ -1,89 +0,0 @@ -// 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.Core; -using ICSharpCode.PythonBinding; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor.AvalonEdit; -using NUnit.Framework; -using PythonBinding.Tests.Utils; - -namespace PythonBinding.Tests.Completion -{ - /// - /// Tests the code completion after an "import" statement. - /// - [TestFixture] - public class CodeCompletionBindingImportCompletionTestFixture - { - DerivedPythonCodeCompletionBinding codeCompletionBinding; - bool handlesImportKeyword; - AvalonEditTextEditorAdapter textEditor; - - [TestFixtureSetUp] - public void SetUpFixture() - { - if (!PropertyService.Initialized) { - PropertyService.InitializeService(String.Empty, String.Empty, String.Empty); - } - textEditor = new AvalonEditTextEditorAdapter(new ICSharpCode.AvalonEdit.TextEditor()); - codeCompletionBinding = new DerivedPythonCodeCompletionBinding(); - handlesImportKeyword = codeCompletionBinding.HandleKeyword(textEditor, "import"); - } - - [Test] - public void HandlesImportKeyWord() - { - Assert.IsTrue(handlesImportKeyword); - } - - [Test] - public void UnknownKeywordNotHandled() - { - Assert.IsFalse(codeCompletionBinding.HandleKeyword(textEditor, "Unknown")); - } - - [Test] - public void HandlesUppercaseImportKeyword() - { - Assert.IsTrue(codeCompletionBinding.HandleKeyword(textEditor, "IMPORT")); - } - - [Test] - public void NullKeyword() - { - Assert.IsFalse(codeCompletionBinding.HandleKeyword(textEditor, null)); - } - - [Test] - public void CompletionDataProviderCreated() - { - Assert.IsTrue(codeCompletionBinding.IsCompletionDataProviderCreated); - } - - [Test] - public void CodeCompletionWindowDisplayed() - { - Assert.IsTrue(codeCompletionBinding.IsCodeCompletionWindowDisplayed); - } - - [Test] - public void TextAreaControlUsedToDisplayCodeCompletionWindow() - { - Assert.AreSame(textEditor, codeCompletionBinding.TextEditorUsedToShowCompletionWindow); - } - - [Test] - public void CompletionProviderUsedWhenDisplayingCodeCompletionWindow() - { - Assert.AreSame(codeCompletionBinding.CompletionDataProvider, codeCompletionBinding.CompletionProviderUsedWhenDisplayingCodeCompletionWindow); - } - - [Test] - public void CompletionCharacterIsSpace() - { - Assert.AreEqual(' ', codeCompletionBinding.CompletionCharacter); - } - } -} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTests.cs new file mode 100644 index 0000000000..55053eff1e --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/CodeCompletionBindingImportCompletionTests.cs @@ -0,0 +1,101 @@ +// 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.Scripting.Tests.Utils; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Completion +{ + /// + /// Tests the code completion after an "import" statement. + /// + [TestFixture] + public class CodeCompletionBindingImportCompletionTests + { + TestablePythonCodeCompletionBinding codeCompletionBinding; + MockTextEditor textEditor; + bool handled; + + public void CreateCompletionBinding() + { + textEditor = new MockTextEditor(); + codeCompletionBinding = new TestablePythonCodeCompletionBinding(); + } + + public void HandlesImportKeyword() + { + CreateCompletionBinding(); + handled = codeCompletionBinding.HandleKeyword(textEditor, "import"); + } + + [Test] + public void HandleKeyword_KeywordIsImport_ReturnsTrue() + { + HandlesImportKeyword(); + Assert.IsTrue(handled); + } + + [Test] + public void HandleKeyword_UnknownKeyword_ReturnsFalse() + { + bool handled = codeCompletionBinding.HandleKeyword(textEditor, "Unknown"); + Assert.IsFalse(handled); + } + + [Test] + public void HandleKeyword_KeywordIsImportInUpperCase_ReturnsTrue() + { + bool handled = codeCompletionBinding.HandleKeyword(textEditor, "IMPORT"); + Assert.IsTrue(handled); + } + + [Test] + public void HandleKeyword_KeywordIsNull_ReturnsFalse() + { + bool handled = codeCompletionBinding.HandleKeyword(textEditor, null); + Assert.IsFalse(handled); + } + + [Test] + public void HandleKeyword_KeywordIsImport_CodeCompletionWindowDisplayed() + { + HandlesImportKeyword(); + Assert.IsTrue(codeCompletionBinding.IsCodeCompletionWindowDisplayed); + } + + [Test] + public void HandleKeyword_KeywordIsImport_TextEditorPassedToShowCompletionWindowMethod() + { + HandlesImportKeyword(); + Assert.AreSame(textEditor, codeCompletionBinding.TextEditorPassedToShowCompletionWindow); + } + + [Test] + public void HandleKeyword_KeywordIsImport_CompletionProviderUsedWhenDisplayingCodeCompletionWindow() + { + HandlesImportKeyword(); + Assert.AreSame(codeCompletionBinding.KeywordCompletionItemProviderCreated, codeCompletionBinding.CompletionItemProviderUsedWhenDisplayingCodeCompletionWindow); + } + + [Test] + public void HandleKeyword_KeywordIsImport_KeywordCompletionDataProviderIsCodeCompletionItemProvider() + { + HandlesImportKeyword(); + CodeCompletionItemProvider provider = codeCompletionBinding.KeywordCompletionItemProviderCreated as CodeCompletionItemProvider; + Assert.IsNotNull(provider); + } + + [Test] + public void ShowCompletionWindow_FakeCompletionItemProviderAndTextEditorPassed_asdf() + { + CreateCompletionBinding(); + FakeCompletionItemProvider provider = new FakeCompletionItemProvider(); + codeCompletionBinding.CallBaseShowCodeCompletionWindow(provider, textEditor); + + Assert.AreEqual(textEditor, provider.TextEditorPassedToShowCompletion); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTests.cs similarity index 74% rename from src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTestFixture.cs rename to src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTests.cs index e1dd76aac9..88234a939a 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportDotNetNamespaceCompletionTests.cs @@ -12,7 +12,7 @@ using PythonBinding.Tests.Utils; namespace PythonBinding.Tests.Completion { [TestFixture] - public class FromImportDotNetNamespaceCompletionTestFixture + public class FromImportDotNetNamespaceCompletionTes { PythonImportCompletion completion; MockProjectContent projectContent; @@ -33,20 +33,22 @@ namespace PythonBinding.Tests.Completion } [Test] - public void FromDotNetSystemLibraryGetCompletionItemsReturnsAllClassesFromSystemNamespace() + public void GetCompletionItemsFromModule_DotNetSystemLibrary_ReturnsAllClassesFromSystemNamespaceAndAsteriskForImportAll() { List items = completion.GetCompletionItemsFromModule("System"); List expectedItems = new List(); expectedItems.Add(c); + expectedItems.Add(new NamespaceEntry("*")); Assert.AreEqual(expectedItems, items); } [Test] - public void SystemNamespaceSearchedForWhenGetCompletionItemsMethodCalled() + public void GetCompletionItems_DotNetSystemLibrary_SystemNamespaceSearchedForWhenGetCompletionItemsMethodCalled() { completion.GetCompletionItemsFromModule("System"); - Assert.AreEqual("System", projectContent.NamespacePassedToGetNamespaceContentsMethod); + string expectedNamespace = "System"; + Assert.AreEqual(expectedNamespace, projectContent.NamespacePassedToGetNamespaceContentsMethod); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTests.cs similarity index 58% rename from src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTestFixture.cs rename to src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTests.cs index fdb6a7dbcf..a2d4f6407a 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/FromImportPythonModuleCompletionTests.cs @@ -12,7 +12,7 @@ using PythonBinding.Tests.Utils; namespace PythonBinding.Tests.Completion { [TestFixture] - public class FromImportPythonModuleCompletionTestFixture + public class FromImportPythonModuleCompletionTests { PythonImportCompletion completion; MockProjectContent projectContent; @@ -26,18 +26,30 @@ namespace PythonBinding.Tests.Completion } [Test] - public void FromUnknownLibraryNoCompletionItemsReturned() + public void GetCompletionItemsFromModule_UnknownModule_OnlyImportAllItemsCompletionItemReturned() { List items = completion.GetCompletionItemsFromModule("unknown"); - Assert.AreEqual(0, items.Count); + List expectedItems = new List(); + expectedItems.Add(new NamespaceEntry("*")); + Assert.AreEqual(expectedItems, items); } [Test] - public void FromMathLibraryGetCompletionItemsReturnsPiField() + public void GetCompletionItemsFromModule_MathModule_ReturnsPiField() { List items = completion.GetCompletionItemsFromModule("math"); IField field = PythonCompletionItemsHelper.FindFieldFromCollection("pi", items); Assert.IsNotNull(field); } + + [Test] + public void GetCompletionItemsFromModule_MathModule_LastCompletionItemIsAsterisk() + { + List items = completion.GetCompletionItemsFromModule("math"); + int lastItem = items.Count - 1; + ICompletionEntry lastCompletionItem = items[lastItem]; + NamespaceEntry expectedCompletionItem = new NamespaceEntry("*"); + Assert.AreEqual(expectedCompletionItem, lastCompletionItem); + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCodeCompletionItemProviderTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCodeCompletionItemProviderTests.cs new file mode 100644 index 0000000000..9fa863c94c --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCodeCompletionItemProviderTests.cs @@ -0,0 +1,23 @@ +// 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.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Completion +{ + [TestFixture] + public class PythonCodeCompletionItemProviderTests + { + [Test] + public void CreateCompletionItemList_OverriddenInPythonCodeCompletionItemProvider_ReturnsPythonCompletionItemList() + { + TestablePythonCodeCompletionItemProvider provider = new TestablePythonCodeCompletionItemProvider(); + PythonCompletionItemList list = provider.CallBaseCreateCompletionItemList() as PythonCompletionItemList; + + Assert.IsNotNull(list); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCompletionItemListTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCompletionItemListTests.cs new file mode 100644 index 0000000000..d20773df60 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonCompletionItemListTests.cs @@ -0,0 +1,41 @@ +// 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.PythonBinding; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using NUnit.Framework; + +namespace PythonBinding.Tests.Completion +{ + [TestFixture] + public class PythonCompletionItemListTests + { + PythonCompletionItemList completionItemList; + + void CreatePythonCompletionItemList() + { + completionItemList = new PythonCompletionItemList(); + } + + [Test] + public void ProcessInput_KeyIsAsterisk_ReturnsNormalKey() + { + CreatePythonCompletionItemList(); + CompletionItemListKeyResult result = completionItemList.ProcessInput('*'); + CompletionItemListKeyResult expectedResult = CompletionItemListKeyResult.NormalKey; + + Assert.AreEqual(expectedResult, result); + } + + [Test] + public void ProcessInput_KeyIsAsterisk_InsertSpaceSetToFalseAfterMethodCalled() + { + CreatePythonCompletionItemList(); + completionItemList.InsertSpace = true; + completionItemList.ProcessInput('*'); + + Assert.IsFalse(completionItemList.InsertSpace); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTests.cs similarity index 57% rename from src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTestFixture.cs rename to src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTests.cs index 77dfa5deff..ef6d93d663 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Completion/PythonImportExpressionContextTests.cs @@ -11,17 +11,18 @@ using PythonBinding.Tests.Utils; namespace PythonBinding.Tests.Completion { [TestFixture] - public class PythonImportExpressionContextTestFixture + public class PythonImportExpressionContextTests { [Test] - public void ShowEntryReturnsTrueForIMethod() + public void ShowEntry_IMethodPassed_ReturnsTrue() { PythonImportExpressionContext context = new PythonImportExpressionContext(); context.HasFromAndImport = true; IMethod method = CreateMethod(); + bool result = context.ShowEntry(method); - Assert.IsTrue(context.ShowEntry(method)); + Assert.IsTrue(result); } IMethod CreateMethod() @@ -37,36 +38,40 @@ namespace PythonBinding.Tests.Completion } [Test] - public void ShowEntryReturnsFalseForNull() + public void ShowEntry_PassedNull_ReturnsFalse() { PythonImportExpressionContext context = new PythonImportExpressionContext(); context.HasFromAndImport = true; - Assert.IsFalse(context.ShowEntry(null)); + bool result = context.ShowEntry(null); + Assert.IsFalse(result); } [Test] - public void ShowEntryReturnsFalseForIMethodWhenHasFromAndImportIsFalse() + public void ShowEntry_PassedIMethodWhenHasFromAndImportIsFalse_ReturnsFalse() { PythonImportExpressionContext context = new PythonImportExpressionContext(); IMethod method = CreateMethod(); - Assert.IsFalse(context.ShowEntry(method)); + bool result = context.ShowEntry(method); + Assert.IsFalse(result); } [Test] - public void PythonImportExpressionContextHasFromAndImportIsFalseByDefault() + public void HasFromAndImport_NewPythonImportExpressionContextInstance_IsFalseByDefault() { PythonImportExpressionContext context = new PythonImportExpressionContext(); - Assert.IsFalse(context.HasFromAndImport); + bool result = context.HasFromAndImport; + Assert.IsFalse(result); } [Test] - public void ShowEntryReturnsTrueForIField() + public void ShowEntry_PassedIField_ReturnsTrue() { PythonImportExpressionContext context = new PythonImportExpressionContext(); context.HasFromAndImport = true; IField field = CreateField(); + bool result = context.ShowEntry(field); - Assert.IsTrue(context.ShowEntry(field)); + Assert.IsTrue(result); } IField CreateField() @@ -76,31 +81,45 @@ namespace PythonBinding.Tests.Completion } [Test] - public void ShowEntryReturnsFalseForIFieldWhenHasFromAndImportIsFalse() + public void ShowEntry_PassedIFieldWhenHasFromAndImportIsFalse_ReturnsFalse() { PythonImportExpressionContext context = new PythonImportExpressionContext(); IField field = CreateField(); + bool result = context.ShowEntry(field); - Assert.IsFalse(context.ShowEntry(field)); + Assert.IsFalse(result); } [Test] - public void ShowEntryReturnsTrueForIClass() + public void ShowEntry_PassedIClass_ReturnsTrue() { PythonImportExpressionContext context = new PythonImportExpressionContext(); context.HasFromAndImport = true; IClass c = CreateClass(); + bool result = context.ShowEntry(c); - Assert.IsTrue(context.ShowEntry(c)); + Assert.IsTrue(result); } [Test] - public void ShowEntryReturnsFalseForIClassWhenHasFromAndImportIsFalse() + public void ShowEntry_PassedIClassWhenHasFromAndImportIsFalse_ReturnsFalse() { PythonImportExpressionContext context = new PythonImportExpressionContext(); IClass c = CreateClass(); + bool result = context.ShowEntry(c); - Assert.IsFalse(context.ShowEntry(c)); + Assert.IsFalse(result); + } + + [Test] + public void ShowEntry_PassedImportAllNamespaceEntryWhenHasFromAndImportIsTrue_ReturnsTrue() + { + PythonImportExpressionContext context = new PythonImportExpressionContext(); + context.HasFromAndImport = true; + NamespaceEntry entry = new NamespaceEntry("*"); + bool result = context.ShowEntry(entry); + + Assert.IsTrue(result); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index 0ba42c5416..1729a491c5 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -80,11 +80,11 @@ - - + + - - + + @@ -97,7 +97,9 @@ - + + + @@ -405,10 +407,10 @@ - + @@ -420,6 +422,8 @@ + + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ImportModuleResolveResultTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ImportModuleResolveResultTests.cs index ffd8730ea9..8a1f1130a6 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ImportModuleResolveResultTests.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ImportModuleResolveResultTests.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.PythonBinding; using ICSharpCode.Scripting.Tests.Utils; using ICSharpCode.SharpDevelop.Dom; @@ -14,30 +15,37 @@ namespace PythonBinding.Tests.Resolver public class ImportModuleResolveResultTests { [Test] - public void NamePropertyMatchesTextPassedToConstructor() + public void Name_ExpressionIsImportFollowedByName_MatchesNameAfterImport() { PythonImportExpression expression = new PythonImportExpression("import abc"); PythonImportModuleResolveResult result = new PythonImportModuleResolveResult(expression); - Assert.AreEqual("abc", result.Name); + string expectedName = "abc"; + Assert.AreEqual(expectedName, result.Name); } [Test] - public void GetCompletionDataReturnsStandardMathPythonModuleWhenImportNameIsEmptyString() + public void GetCompletionData_WhenImportNameIsEmptyString_ReturnsStandardMathPythonModule() { PythonImportExpression expression = new PythonImportExpression(String.Empty); PythonImportModuleResolveResult result = new PythonImportModuleResolveResult(expression); MockProjectContent projectContent = new MockProjectContent(); - Assert.Contains(new NamespaceEntry("math"), result.GetCompletionData(projectContent)); + + List completionItems = result.GetCompletionData(projectContent); + NamespaceEntry mathNamespaceCompletionItem = new NamespaceEntry("math"); + Assert.Contains(mathNamespaceCompletionItem, completionItems); } [Test] - public void ClonedPythonModuleResultReturnsSameCompletionItems() + public void GetCompletionData_ClonedPythonModuleResult_ReturnsSameCompletionItems() { PythonImportExpression expression = new PythonImportExpression(String.Empty); PythonImportModuleResolveResult result = new PythonImportModuleResolveResult(expression); ResolveResult clonedResult = result.Clone(); MockProjectContent projectContent = new MockProjectContent(); - Assert.Contains(new NamespaceEntry("math"), clonedResult.GetCompletionData(projectContent)); + + List completionItems = clonedResult.GetCompletionData(projectContent); + NamespaceEntry mathNamespaceCompletionItem = new NamespaceEntry("math"); + Assert.Contains(mathNamespaceCompletionItem, completionItems); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedPythonCodeCompletionBinding.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedPythonCodeCompletionBinding.cs deleted file mode 100644 index 5a2f6e9e5a..0000000000 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedPythonCodeCompletionBinding.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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 ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using System; -using ICSharpCode.PythonBinding; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; - -namespace PythonBinding.Tests.Utils -{ - /// - /// Derived PythonCodeCompletion class that gives us access to - /// various protected methods for testing. - /// - public class DerivedPythonCodeCompletionBinding : PythonCodeCompletionBinding - { - bool completionDataProviderCreated; - bool codeCompletionWindowDisplayed; - ICSharpCode.SharpDevelop.Editor.ITextEditor textEditorUsedToShowCompletionWindow; - AbstractCompletionItemProvider completionProviderUsedWhenDisplayingCodeCompletionWindow; - AbstractCompletionItemProvider completionDataProvider; - char completionCharacter = '\0'; - - public DerivedPythonCodeCompletionBinding() - { - } - - /// - /// Gets whether the data provider was created by the - /// base class PythonCodeCompletionBinding. - /// - public bool IsCompletionDataProviderCreated { - get { return completionDataProviderCreated; } - } - - /// - /// Gets whether the base class PythonCodeCompletionBinding - /// displayed the code completion window. - /// - public bool IsCodeCompletionWindowDisplayed { - get { return codeCompletionWindowDisplayed; } - } - - public ICSharpCode.SharpDevelop.Editor.ITextEditor TextEditorUsedToShowCompletionWindow { - get { return textEditorUsedToShowCompletionWindow; } - } - - public AbstractCompletionItemProvider CompletionProviderUsedWhenDisplayingCodeCompletionWindow { - get { return completionProviderUsedWhenDisplayingCodeCompletionWindow; } - } - - /// - /// Gets the CompletionDataProvider created via the - /// CreateCompletionDataProvider method. - /// - public AbstractCompletionItemProvider CompletionDataProvider { - get { return completionDataProvider; } - } - - /// - /// Gets the character used when calling the TextAreaControl's - /// ShowCompletionWindow method. - /// - public char CompletionCharacter { - get { return completionCharacter; } - } - - /// - /// Overrides the completion data provider creation to make sure - /// it is called at the correct time. - /// - protected override AbstractCompletionItemProvider CreateCompletionDataProvider() - { - completionDataProviderCreated = true; - completionDataProvider = base.CreateCompletionDataProvider(); - return completionDataProvider; - } - - /// - /// Overrides the base class method so a code completion window is - /// not displayed but the fact that this method is called is - /// recorded. - /// - protected override void ShowCodeCompletionWindow(ICSharpCode.SharpDevelop.Editor.ITextEditor textEditor, AbstractCompletionItemProvider completionDataProvider, char ch) - { - textEditorUsedToShowCompletionWindow = textEditor; - codeCompletionWindowDisplayed = true; - completionCharacter = ch; - completionProviderUsedWhenDisplayingCodeCompletionWindow = completionDataProvider; - } - } -} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/FakeCompletionItemProvider.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/FakeCompletionItemProvider.cs new file mode 100644 index 0000000000..95cc1e989f --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/FakeCompletionItemProvider.cs @@ -0,0 +1,24 @@ +// 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.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace PythonBinding.Tests.Utils +{ + public class FakeCompletionItemProvider : AbstractCompletionItemProvider + { + public ITextEditor TextEditorPassedToShowCompletion; + + public override void ShowCompletion(ITextEditor editor) + { + TextEditorPassedToShowCompletion = editor; + } + + public override ICompletionItemList GenerateCompletionList(ITextEditor editor) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionBinding.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionBinding.cs new file mode 100644 index 0000000000..db0e56fb4a --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionBinding.cs @@ -0,0 +1,51 @@ +// 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 ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using System; +using ICSharpCode.PythonBinding; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Editor; + +namespace PythonBinding.Tests.Utils +{ + /// + /// Derived PythonCodeCompletion class that gives us access to + /// various protected methods for testing. + /// + public class TestablePythonCodeCompletionBinding : PythonCodeCompletionBinding + { + public bool IsCodeCompletionWindowDisplayed; + public ITextEditor TextEditorPassedToShowCompletionWindow; + public AbstractCompletionItemProvider CompletionItemProviderUsedWhenDisplayingCodeCompletionWindow; + public AbstractCompletionItemProvider KeywordCompletionItemProviderCreated; + + /// + /// Overrides the completion data provider creation to make sure + /// it is called at the correct time. + /// + protected override AbstractCompletionItemProvider CreateKeywordCompletionItemProvider() + { + KeywordCompletionItemProviderCreated = base.CreateKeywordCompletionItemProvider(); + return KeywordCompletionItemProviderCreated; + } + + public void CallBaseShowCodeCompletionWindow(AbstractCompletionItemProvider completionItemProvider, ITextEditor textEditor) + { + base.ShowCodeCompletionWindow(completionItemProvider, textEditor); + } + + /// + /// Overrides the base class method so a code completion window is + /// not displayed but the fact that this method is called is + /// recorded. + /// + protected override void ShowCodeCompletionWindow(AbstractCompletionItemProvider completionItemProvider, ITextEditor textEditor) + { + TextEditorPassedToShowCompletionWindow = textEditor; + IsCodeCompletionWindowDisplayed = true; + CompletionItemProviderUsedWhenDisplayingCodeCompletionWindow = completionItemProvider; + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionItemProvider.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionItemProvider.cs new file mode 100644 index 0000000000..8663a59faa --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/TestablePythonCodeCompletionItemProvider.cs @@ -0,0 +1,17 @@ +// 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.PythonBinding; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace PythonBinding.Tests.Utils +{ + public class TestablePythonCodeCompletionItemProvider : PythonCodeCompletionItemProvider + { + public DefaultCompletionItemList CallBaseCreateCompletionItemList() + { + return base.CreateCompletionItemList(); + } + } +}