public void AutoListIdentifierCompletions() { using (var view = new PythonEditor()) { view.AdvancedOptions.AutoListIdentifiers = true; view.Type("a = "); foreach (var c in "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ") { // x<space> should bring up a completion session Console.WriteLine("Typing {0}", c); view.Type(c.ToString()); using (var sh = view.View.WaitForSession<ICompletionSession>()) { sh.Session.Dismiss(); } view.Backspace(); } view.View.AssertNoIntellisenseSession(); // x<space> should not bring up a completion session // Don't check too many items, since asserting that no session // starts is slow. foreach (var c in "1234567890([{") { Console.WriteLine("Typing {0}", c); view.Type(c.ToString()); view.View.AssertNoIntellisenseSession(); view.Backspace(); } } }
public void UnresolvedImportSquiggle() { List<string> squiggles; using (var view = new PythonEditor("import fob, oar\r\nfrom baz import *\r\nfrom .spam import eggs")) { var errorProvider = view.VS.ServiceProvider.GetComponentModel().GetService<IErrorProviderFactory>(); var tagger = errorProvider.GetErrorTagger(view.View.TextView.TextBuffer); // Ensure all tasks have been updated var taskProvider = (ErrorTaskProvider)view.VS.ServiceProvider.GetService(typeof(ErrorTaskProvider)); var time = taskProvider.FlushAsync().GetAwaiter().GetResult(); Console.WriteLine("TaskProvider.FlushAsync took {0}ms", time.TotalMilliseconds); squiggles = tagger.GetTaggedSpans(new SnapshotSpan(view.CurrentSnapshot, 0, view.CurrentSnapshot.Length)) .Select(FormatErrorTag) .ToList(); } Console.WriteLine(" Squiggles found:"); foreach (var actual in squiggles) { Console.WriteLine(actual); } Console.WriteLine(" Found {0} squiggle(s)", squiggles.Count); int i = 0; foreach (var expected in new[] { // Ensure that the warning includes the module name @".*warning:.*fob.*\(7-10\)", @".*warning:.*oar.*\(12-15\)", @".*warning:.*baz.*\(22-25\)", @".*warning:.*\.spam.*\(41-46\)" }) { Assert.IsTrue(i < squiggles.Count, "Not enough squiggles"); AssertUtil.AreEqual(new Regex(expected, RegexOptions.IgnoreCase | RegexOptions.Singleline), squiggles[i]); i += 1; } }
public void GetApplicableSpanTest() { var text = "if fob.oar(eggs, spam<=ham) :"; using (var view = new PythonEditor(text)) { var snapshot = view.CurrentSnapshot; // We check the applicable span at every index in the string. var expected = new[] { "if", "if", "if", "fob", "fob", "fob", "fob", "oar", "oar", "oar", "oar", "eggs", "eggs", "eggs", "eggs", "eggs", "", // between ',' and ' ' "spam", "spam", "spam", "spam", "spam", "", // between '<' and '=' "ham", "ham", "ham", "ham", "", // between ')' and ' ' "", // between ' ' and ':' "", // between ':' and EOL }; for (int i = 0; i < text.Length; ++i) { var span = snapshot.GetApplicableSpan(i); if (span == null) { Assert.AreEqual(expected[i], "", text.Substring(0, i) + "|" + text.Substring(i)); } else { Assert.AreEqual(expected[i], span.GetText(snapshot), text.Substring(0, i) + "|" + text.Substring(i)); } } } }
public void CtrlSpaceCompletions() { using (var view = new PythonEditor()) { view.Text = @"def f(param1, param2): g()"; AssertUtil.ContainsAtLeast(view.GetCompletionsAfter("g("), "param1", "param2"); view.Text = @"def f(param1, param2): g(param1, )"; AssertUtil.ContainsAtLeast(view.GetCompletionsAfter("g(param1, "), "param1", "param2"); // verify Ctrl-Space inside of a function gives proper completions foreach (var codeSnippet in new[] { @"def f(): pass", @"def f(): x = (2 + 3) pass ", @"def f(): yield (2 + 3) pass" }) { Debug.WriteLine(String.Format("Testing {0}", codeSnippet)); view.Text = codeSnippet; AssertUtil.ContainsAtLeast(view.GetCompletions(codeSnippet.IndexOf("\r\n pass")), "min", "assert"); } } }
public void BuiltinFunctionCompletions() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); } } }
public void SigHelpInClass() { using (var view = new PythonEditor()) { view.Type("class C(): pass"); view.MoveCaret(1, 9); view.ParamInfo(); view.View.AssertNoIntellisenseSession(); } }
public void FilterCompletions() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("class"); AssertUtil.DoesntContain(sh.Session.Completions(), "__call__"); } } }
public void LambdaCompletions() { // https://github.com/Microsoft/PTVS/issues/1000 string code = @" l = (lambda b:b) l(42) "; using (var view = new PythonEditor(code)) { var completionList = view.GetCompletionsAfter(":"); AssertUtil.Contains(completionList, "b"); } }
public void FilterCompletions() { using (var view = new PythonEditor()) { view.TypeAndWaitForAnalysis("min"); view.Type("."); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("class"); AssertUtil.DoesntContain(sh.Session.Completions(), "__call__"); } } }
public void MethodArgumentNameCompletion() { const string code = @" class MyClass: def f(self, param1 = 123, param2 : int = 234): pass m = MyClass() x = m.f("; using (var view = new PythonEditor(code)) { AssertUtil.ContainsAtLeast(view.GetCompletions(-1), "param1", "param2"); AssertUtil.DoesntContain(view.GetCompletions(0), "param1"); } }
public void DotCompletes() { using (var view = new PythonEditor()) { view.TypeAndWaitForAnalysis("min"); view.Type("."); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("class."); Assert.AreEqual("min.__class__.", view.Text); } } }
private static ExpressionAnalysis AnalyzeExpression(MockVs vs, int location, string code, PythonLanguageVersion version = PythonLanguageVersion.V27) { if (location < 0) { location += code.Length + 1; } using (var view = new PythonEditor(code, version, vs)) { var snapshot = view.CurrentSnapshot; return(vs.InvokeTask(() => view.Analyzer.AnalyzeExpressionAsync( (AnalysisEntry)view.GetAnalysisEntry(), new SnapshotPoint(snapshot, location) ))); } }
private static SignatureAnalysis GetSignatureAnalysis(PythonEditor view, int index) { var snapshot = view.CurrentSnapshot; Task <SignatureAnalysis> task = null; view.VS.InvokeSync(() => { task = view.Analyzer.GetSignaturesAsync( (AnalysisEntry)view.GetAnalysisEntry(), view.View.TextView, snapshot, snapshot.CreateTrackingSpan(index, 1, SpanTrackingMode.EdgeInclusive) ); }); return(task.Wait(10000) ? task.Result : null); }
private static ExpressionAnalysis AnalyzeExpression(MockVs vs, int location, string code, PythonLanguageVersion version = PythonLanguageVersion.V27) { if (location < 0) { location += code.Length + 1; } using (var view = new PythonEditor(code, version, vs)) { var snapshot = view.CurrentSnapshot; return(snapshot.AnalyzeExpression( vs.ServiceProvider, snapshot.CreateTrackingSpan(location, location < snapshot.Length ? 1 : 0, SpanTrackingMode.EdgeInclusive), false )); } }
public void CtrlSpaceAfterKeyword() { // http://pytools.codeplex.com/workitem/560 string code = @" def h(): return print "; using (var editor = new PythonEditor(code)) { AssertUtil.ContainsAtLeast(editor.GetCompletions(code.IndexOfEnd("return ")), "any"); AssertUtil.ContainsAtLeast(editor.GetCompletions(code.IndexOfEnd("print ")), "any"); } }
public void NonIdentifierDismisses() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("#"); Assert.IsTrue(sh.Session.IsDismissed); } view.View.AssertNoIntellisenseSession(); Assert.AreEqual("min.#", view.Text); } }
public void EnterDismisses() { using (var view = new PythonEditor()) { view.AdvancedOptions.EnterCommitsIntellisense = false; view.AdvancedOptions.AutoListMembers = true; view.Type("min."); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "__class__"); view.Type("class\r"); } Assert.AreEqual("min.class\r\n", view.Text); } }
public void DisableAutoCompletions() { using (var view = new PythonEditor()) { view.AdvancedOptions.AutoListMembers = false; view.AdvancedOptions.AutoListIdentifiers = false; foreach (var t in new[] { "a", "a.", "import " }) { Console.WriteLine("Typed " + t); view.Type(t); view.View.AssertNoIntellisenseSession(); view.Clear(); } } }
public void BuiltinFunctionSigHelp() { using (var view = new PythonEditor()) { view.Type("min("); for (int retries = 10; retries > 0; --retries) { using (var sh = view.View.WaitForSession<ISignatureHelpSession>()) { var doc = sh.Session.Signatures[0].Documentation; if (doc.Contains("still being calculated")) { view.VS.Sleep(100); continue; } AssertUtil.AreEqual(new Regex(@"^min\(x\: object\).+?"), doc); break; } } } }
public ClassifierHelper(string code, PythonLanguageVersion version) { _view = new PythonEditor("", version); var providers = _view.VS.ComponentModel.GetExtensions <IClassifierProvider>().ToArray(); _provider1 = providers.OfType <PythonClassifierProvider>().Single(); _provider2 = providers.OfType <PythonAnalysisClassifierProvider>().Single(); _classificationsReady1 = new ManualResetEventSlim(); _classificationsReady2 = new ManualResetEventSlim(); AstClassifier.ClassificationChanged += (s, e) => _classificationsReady1.SetIfNotDisposed(); AnalysisClassifier.ClassificationChanged += (s, e) => _classificationsReady2.SetIfNotDisposed(); _view.Text = code; }
public void EnterCommitsCompleteNoNewLine() { using (var view = new PythonEditor()) { view.AdvancedOptions.AddNewLineAtEndOfFullyTypedWord = true; view.AdvancedOptions.AutoListMembers = true; view.AdvancedOptions.AutoListIdentifiers = false; view.AdvancedOptions.HideAdvancedMembers = false; view.Type("min.__"); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "__class__"); view.Type("class__\r"); } Assert.AreEqual("min.__class__\r\n", view.Text); } }
private IEnumerable <string> HideAdvancedMembersHelper(PythonEditor view, string text, params string[] completions) { view.Text = text; var snapshot = view.CurrentSnapshot; var set = new FuzzyCompletionSet( "Test Completions", "Test Completions", snapshot.CreateTrackingSpan(0, snapshot.Length, SpanTrackingMode.EdgeInclusive), completions.Select(c => new DynamicallyVisibleCompletion(c)), new CompletionOptions { HideAdvancedMembers = true, IntersectMembers = false }, CompletionComparer.UnderscoresLast ); set.Filter(); return(set.Completions.Select(c => c.DisplayText).ToList()); }
private void AutoListTest(string code, PythonLanguageVersion version, params int[] triggerAtIndex) { using (var view = new PythonEditor(version: version)) { view.AdvancedOptions.AutoListIdentifiers = true; view.AdvancedOptions.AutoListMembers = true; int lastStart = 0; string text; foreach (var _i in triggerAtIndex) { bool expectCompletions = _i >= 0; int expected = _i > 0 ? _i : -_i; text = code.Substring(lastStart, expected - lastStart); Console.WriteLine("Typing '{0}' [{1}, {2})", text, lastStart, expected); view.Type(text); view.View.AssertNoIntellisenseSession(); lastStart = expected; if (expectCompletions) { text = code.Substring(expected, 1); Console.WriteLine("Typing '{0}' [{1}, {2}) and expect completions", text, expected, expected + 1); view.Type(text); using (var sh = view.View.WaitForSession <ICompletionSession>()) { sh.Session.Dismiss(); } lastStart = expected + 1; } } text = code.Substring(lastStart); if (!string.IsNullOrEmpty(text)) { Console.WriteLine("Typing '{0}' [{1}, {2})", text, lastStart, code.Length); view.Type(text); view.View.AssertNoIntellisenseSession(); } } }
public void CompletionsAtEndOfLastChildScope() { using (var view = new PythonEditor(@"class A: def f(param1, param2): y = 234 class B: pass ")) { view.MoveCaret(5, 9); view.TypeAndWaitForAnalysis("p"); view.MemberList(); using (var sh = view.View.WaitForSession <ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "param1", "param2"); } } }
public void Scenario_CompletionInTripleQuotedString() { string code = @" ''' import from except @ sys. ''' "; using (var view = new PythonEditor(code)) { for (int i = code.IndexOfEnd("'''"); i < code.LastIndexOf("'''"); ++i) { AssertUtil.ContainsExactly(view.GetCompletions(i)); } } }
public void FromImportMultilineCompletions() { using (var editor = new PythonEditor()) { editor.Text = "from sys import ("; var completions = editor.GetCompletions(-1); AssertUtil.ContainsAtLeast(completions, "settrace", "api_version"); editor.Text = "from nt import (\r\n "; completions = editor.GetCompletions(-1); AssertUtil.ContainsAtLeast(completions, "abort", "W_OK"); editor.Text = "from nt import (getfilesystemencoding,\r\n "; completions = editor.GetCompletions(-1); AssertUtil.ContainsAtLeast(completions, "abort", "W_OK"); // Need a comma for more completions editor.Text = "from sys import (settrace\r\n "; AssertUtil.ContainsExactly(editor.GetCompletions(-1), "as"); } }
public void CompletionInTripleQuotedString() { string code = @" ''' import from except @ sys. ''' "; using (var view = new PythonEditor(code)) { for (int i = code.IndexOfEnd("'''"); i < code.LastIndexOf("'''"); ++i) { Console.WriteLine(code.Substring(0, i).Replace("\r", "\\r").Replace("\n", "\\n")); AssertUtil.ContainsExactly(view.GetCompletions(i)); } } }
public void BuiltinFunctionSigHelp() { using (var view = new PythonEditor()) { view.Type("min("); for (int retries = 10; retries > 0; --retries) { using (var sh = view.View.WaitForSession <ISignatureHelpSession>()) { var doc = sh.Session.Signatures[0].Documentation; if (doc.Contains("still being calculated")) { view.VS.Sleep(100); continue; } AssertUtil.AreEqual(new Regex(@"^min\(x\: object\).+?"), doc); break; } } } }
public async Task UnresolvedImportSquiggle() { List <string> squiggles; using (PythonEditor view = new PythonEditor("import fob, oar\r\nfrom baz import *\r\nfrom spam import eggs")) { var errorProvider = view.VS.ServiceProvider.GetComponentModel().GetService <IErrorProviderFactory>(); var tagger = errorProvider.GetErrorTagger(view.View.TextView.TextBuffer); // Ensure all tasks have been updated var taskProvider = (ErrorTaskProvider)view.VS.ServiceProvider.GetService(typeof(ErrorTaskProvider)); var time = await taskProvider.FlushAsync(); Console.WriteLine("TaskProvider.FlushAsync took {0}ms", time.TotalMilliseconds); squiggles = tagger.GetTaggedSpans(new SnapshotSpan(view.CurrentSnapshot, 0, view.CurrentSnapshot.Length)) .Select(FormatErrorTag) .ToList(); } Console.WriteLine(" Squiggles found:"); foreach (var actual in squiggles) { Console.WriteLine(actual); } Console.WriteLine(" Found {0} squiggle(s)", squiggles.Count); int i = 0; foreach (global::System.String expected in new[] { // Ensure that the warning includes the module name @".*warning:.*fob.*\(Python.+:7-10\)", @".*warning:.*oar.*\(Python.+:12-15\)", @".*warning:.*baz.*\(Python.+:22-25\)", @".*warning:.*spam.*\(Python.+:41-45\)" }) { Assert.IsTrue(i < squiggles.Count, "Not enough squiggles"); AssertUtil.AreEqual(new Regex(expected, RegexOptions.IgnoreCase | RegexOptions.Singleline), squiggles[i]); i += 1; } }
private static IEnumerable <string> EditAndGetCompletions( MockVs vs, string code, string editText, int editInsert, string completeAfter, PythonLanguageVersion version = PythonLanguageVersion.V27 ) { using (var view = new PythonEditor(code, version, vs)) { view.AdvancedOptions.HideAdvancedMembers = false; var snapshot = view.CurrentSnapshot; view.View.MoveCaret(new SnapshotPoint(snapshot, editInsert)); view.Type(editText); var newSnapshot = view.CurrentSnapshot; Assert.AreNotSame(snapshot, newSnapshot); return(view.GetCompletionsAfter(completeAfter)); } }
public void SignatureHelpStarArgs() { SignatureAnalysis sigResult = null; using (var view = new PythonEditor(@"def f(a, *b, c=None): pass f(1, 2, 3, 4,")) { for (int retries = 3; retries >= 0; --retries) { TestSignature(view, -1, "f", 4, out sigResult); if (retries == 0) { Assert.IsTrue(sigResult.Signatures.Count >= 1, "No signature analysis results"); } else if (sigResult.Signatures.Count >= 1) { break; } Console.WriteLine("Retry {0}", retries); view.Text = view.Text; } Assert.AreEqual("*b", sigResult.Signatures[0].CurrentParameter.Name); } }
private static void TestQuickInfo(PythonEditor view, int start, int end, params string[] expected) { var snapshot = view.CurrentSnapshot; for (int i = start; i < end; i++) { List <object> quickInfo = new List <object>(); ITrackingSpan span; QuickInfoSource.AugmentQuickInfoWorker( quickInfo, VsProjectAnalyzer.GetQuickInfoAsync( new SnapshotPoint(snapshot, start) ).Result, out span ); Assert.AreEqual(expected.Length, quickInfo.Count); for (int j = 0; j < expected.Length; j++) { Assert.AreEqual(expected[j], quickInfo[j]); } } }
private static void TestQuickInfo(PythonEditor view, int start, int end, string expected = null) { var snapshot = view.CurrentSnapshot; for (var i = start; i < end; i++) { var quickInfo = view.Analyzer.GetQuickInfoAsync( (AnalysisEntry)view.GetAnalysisEntry(), view.View.TextView, new SnapshotPoint(snapshot, start) ).Result; if (expected != null) { Assert.IsNotNull(quickInfo); Assert.AreEqual(expected, quickInfo.Text); } else { Assert.IsNull(quickInfo); } } }
public void TrueFalseNoneCompletions() { // http://pytools.codeplex.com/workitem/1905 foreach (var version in new[] { PythonLanguageVersion.V27, PythonLanguageVersion.V33 }) { using (var view = new PythonEditor(version: version)) { var completionList = view.GetCompletionList(0); foreach (var c in completionList) { Console.WriteLine(c.DisplayText); } var trueItems = completionList.Where(t => t.DisplayText == "True").ToArray(); var falseItems = completionList.Where(t => t.DisplayText == "False").ToArray(); var noneItems = completionList.Where(t => t.DisplayText == "None").ToArray(); Assert.AreEqual(1, trueItems.Count()); Assert.AreEqual(1, falseItems.Count()); Assert.AreEqual(1, noneItems.Count()); Assert.AreEqual("Keyword", trueItems[0].IconAutomationText); Assert.AreEqual("Keyword", falseItems[0].IconAutomationText); Assert.AreEqual("Keyword", noneItems[0].IconAutomationText); } } }
public void AutoListIdentifierCompletions() { using (var view = new PythonEditor()) { view.AdvancedOptions.AutoListIdentifiers = true; view.Type("a = "); foreach (var c in "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ") { // x<space> should bring up a completion session Console.WriteLine("Typing {0}", c); view.Type(c.ToString()); using (var sh = view.View.WaitForSession <ICompletionSession>()) { sh.Session.Dismiss(); } view.Backspace(); } view.View.AssertNoIntellisenseSession(); // x<space> should not bring up a completion session // Don't check too many items, since asserting that no session // starts is slow. foreach (var c in "1234567890([{") { Console.WriteLine("Typing {0}", c); view.Type(c.ToString()); view.View.AssertNoIntellisenseSession(); view.Backspace(); } } }
private static void OSPathImportTest(MockVs vs, Microsoft.PythonTools.Interpreter.IPythonInterpreterFactory factory) { using (var editor = new PythonEditor(vs: vs, factory: factory)) { editor.Text = "from "; AssertUtil.ContainsAtLeast(editor.GetCompletions(-1), "os", "sys"); editor.Text = "from o"; var completions = editor.GetCompletions(-1); AssertUtil.ContainsAtLeast(completions, "os"); AssertUtil.DoesntContain(completions, "sys"); editor.Text = "from os "; AssertUtil.ContainsExactly(editor.GetCompletions(-1), "import"); editor.Text = "from os import"; AssertUtil.ContainsExactly(editor.GetCompletions(-1), "import"); editor.Text = "from os import "; AssertUtil.ContainsAtLeast(editor.GetCompletions(-1), "path"); editor.Text = "from os."; AssertUtil.ContainsExactly(editor.GetCompletions(-1), "path"); editor.Text = "from os.path import "; AssertUtil.ContainsAtLeast(editor.GetCompletions(-1), "abspath", "relpath"); var allNames = new HashSet <string>(); editor.Text = "from ntpath import "; allNames.UnionWith(editor.GetCompletions(-1)); editor.Text = "from posixpath import "; allNames.UnionWith(editor.GetCompletions(-1)); editor.Text = "from os.path import "; AssertUtil.ContainsAtLeast(editor.GetCompletions(-1), allNames); } }
private static IEnumerable <string> EditAndGetCompletions( MockVs vs, string code, string editText, int editInsert, string completeAfter, PythonLanguageVersion version = PythonLanguageVersion.V27 ) { using (var view = new PythonEditor(code, version, vs)) { view.AdvancedOptions.HideAdvancedMembers = false; var snapshot = view.CurrentSnapshot; ITextVersion afterEditVersion = null; ManualResetEvent mre = new ManualResetEvent(false); view.View.TextView.TextBuffer.RegisterForNewAnalysis(entry => { if (afterEditVersion != null && entry.BufferParser.GetAnalysisVersion(snapshot.TextBuffer).VersionNumber >= afterEditVersion.VersionNumber) { mre.Set(); } }); view.View.MoveCaret(new SnapshotPoint(snapshot, editInsert)); view.Type(editText); afterEditVersion = view.CurrentSnapshot.Version; if (!mre.WaitOne(10000)) { Assert.Fail("Failed to wait for new analysis"); } var newSnapshot = view.CurrentSnapshot; Assert.AreNotSame(snapshot, newSnapshot); return(view.GetCompletionsAfter(completeAfter)); } }
public void QuickInfo() { string code = @" x = ""ABCDEFGHIJKLMNOPQRSTUVWYXZ"" cls._parse_block(ast.expr) f(a, (b, c, d), e) def f(): """"""helpful information """""" while True: pass lambda larg1, larg2: None"; using (var view = new PythonEditor(code)) { // we get the appropriate subexpression TestQuickInfo(view, code.IndexOf("cls."), code.IndexOf("cls.") + 4, "cls: <unknown type>"); TestQuickInfo(view, code.IndexOf("cls.") + 4 + 1, code.IndexOf("cls.") + 4 + 1 + 11, "cls._parse_block: <unknown type>"); TestQuickInfo(view, code.IndexOf("cls.") + 4 + 1 + 11 + 1, code.IndexOf("cls.") + 4 + 1 + 11 + 1 + 4, "ast: <unknown type>"); TestQuickInfo(view, code.IndexOf("cls.") + 4 + 1 + 11 + 1 + 4 + 1, code.IndexOf("cls.") + 4 + 1 + 11 + 1 + 4 + 1 + 3, "ast.expr: <unknown type>"); TestQuickInfo(view, code.IndexOf("cls.") + 4 + 1 + 11 + 1 + 4 + 1 + 3 + 1, code.IndexOf("cls.") + 4 + 1 + 11 + 1 + 5 + 3 + 1 + 1, "cls._parse_block(ast.expr): <unknown type>"); // the whole string shows up in quick info TestQuickInfo(view, code.IndexOf("x = ") + 4, code.IndexOf("x = ") + 4 + 28, "\"ABCDEFGHIJKLMNOPQRSTUVWYXZ\": str"); // trailing new lines don't show up in quick info TestQuickInfo(view, code.IndexOf("def f") + 4, code.IndexOf("def f") + 5, "f: def f()\r\nhelpful information"); // keywords don't show up in quick info TestQuickInfo(view, code.IndexOf("while True:"), code.IndexOf("while True:") + 5); // 'lambda' keyword doesn't show up in quick info TestQuickInfo(view, code.IndexOf("lambda"), code.IndexOf("lambda") + 6); // but its arguments do TestQuickInfo(view, code.IndexOf("larg1"), code.IndexOf("larg1") + 5, "larg1: <unknown type>"); TestQuickInfo(view, code.IndexOf("larg2"), code.IndexOf("larg2") + 5, "larg2: <unknown type>"); // multiline function, hover at the close paren TestQuickInfo(view, code.IndexOf("e)") + 1, code.IndexOf("e)") + 2, @"f(a, (b, c, d), e): <unknown type>"); } }
public void DecoratorNonCompletions() { using (var view = new PythonEditor()) { view.Type("a = b @"); view.View.AssertNoIntellisenseSession(); } }
public void DisableAutoCompletions() { using (var view = new PythonEditor()) { view.AdvancedOptions.AutoListMembers = false; view.AdvancedOptions.AutoListIdentifiers = false; foreach (var t in new[] { "a", "a.", "import " }) { Console.WriteLine("Typed " + t); view.Type(t); view.View.AssertNoIntellisenseSession(); view.View.Clear(); } } }
public void NormalOverrideCompletions() { using (var view2 = new PythonEditor(version: PythonLanguageVersion.V27)) using (var view3 = new PythonEditor(version: PythonLanguageVersion.V33)) { foreach (var code in new[] { @"class Fob(object): def func_a(self, a=100): pass def func_b(self, b, *p, **kw): pass class Baz(Fob): def None ", @"class Fob(object): def func_a(self, a=100): pass class Oar(Fob): def func_b(self, b, *p, **kw): pass class Baz(Oar): def None ", @"class Fob(object): def func_a(self, a=100): pass class Oar(object): def func_b(self, b, *p, **kw): pass class Baz(Fob, Oar): def None ", @"class Fob(object): def func_a(self, a=100): pass def func_b(self, b, *p, **kw): pass def func_c(self): pass class Baz(Fob): def func_c(self): pass def None ", @"class Fob(object): def func_a(self, a=100): pass def func_c(self): pass class Oar(Fob): def func_b(self, b, *p, **kw): pass class Baz(Oar): def func_c(self): pass def None ", @"class Fob(object): def func_a(self, a=100): pass class Oar(object): def func_b(self, b, *p, **kw): pass def func_c(self): pass class Baz(Fob, Oar): def func_c(self): pass def None "}) { view2.Text = code; Console.WriteLine(code); AssertUtil.ContainsAtLeast( view2.GetCompletionList(code.IndexOf("None")).Select(c => c.InsertionText), @"func_a(self, a = 100): return super(Baz, self).func_a(a)", @"func_b(self, b, *p, **kw): return super(Baz, self).func_b(b, *p, **kw)" ); view3.Text = code; AssertUtil.ContainsAtLeast( view3.GetCompletionList(code.IndexOf("None")).Select(c => c.InsertionText), @"func_a(self, a = 100): return super().func_a(a)", @"func_b(self, b, *p, **kw): return super().func_b(b, *p, **kw)" ); } } }
public void BuiltinOverrideCompletions() { using (var view2 = new PythonEditor(version: PythonLanguageVersion.V27)) using (var view3 = new PythonEditor(version: PythonLanguageVersion.V33)) { view2.Text = view3.Text = @"class Fob(str): def "; AssertUtil.ContainsAtLeast( view2.GetCompletionListAfter("def ").Select(c => c.InsertionText), @"capitalize(self): return super(Fob, self).capitalize()", @"index(self, sub, start, end): return super(Fob, self).index(sub, start, end)" ); AssertUtil.ContainsAtLeast( view3.GetCompletionListAfter("def ").Select(x => x.InsertionText), @"capitalize(self): return super().capitalize()", @"index(self, sub, start, end): return super().index(sub, start, end)" ); view2.Text = view3.Text = @"class Fob(str, list): def "; AssertUtil.Contains( view2.GetCompletionListAfter("def ").Select(c => c.InsertionText), @"index(self, sub, start, end): return super(Fob, self).index(sub, start, end)" ); AssertUtil.Contains( view3.GetCompletionListAfter("def ").Select(c => c.InsertionText), @"index(self, sub, start, end): return super().index(sub, start, end)" ); view2.Text = view3.Text = @"class Fob(list, str): def "; AssertUtil.Contains( view2.GetCompletionListAfter("def ").Select(c => c.InsertionText), @"index(self, item, start, stop): return super(Fob, self).index(item, start, stop)" ); AssertUtil.Contains( view3.GetCompletionListAfter("def ").Select(c => c.InsertionText), @"index(self, item, start, stop): return super().index(item, start, stop)" ); } }
public void DotCompletes() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("class."); Assert.AreEqual("min.__class__.", view.Text); } } }
public void EnterCommitsCompleteNoNewLine() { using (var view = new PythonEditor()) { view.AdvancedOptions.AddNewLineAtEndOfFullyTypedWord = true; view.AdvancedOptions.AutoListMembers = true; view.AdvancedOptions.AutoListIdentifiers = false; view.AdvancedOptions.HideAdvancedMembers = false; view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "__class__"); view.Type("__class__\r"); } Assert.AreEqual("min.__class__\r\n", view.Text); } }
public void TabCommits() { using (var view = new PythonEditor()) { view.AdvancedOptions.EnterCommitsIntellisense = false; view.AdvancedOptions.AutoListMembers = true; view.AdvancedOptions.AutoListIdentifiers = false; view.AdvancedOptions.HideAdvancedMembers = false; view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "__class__"); view.Type("class\t"); } Assert.AreEqual("min.__class__", view.Text); } }
public void DecoratorCompletions() { using (var view = new PythonEditor()) { view.Type("@"); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "property", "staticmethod"); } } }
public void EnterCommits() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "__class__"); view.Type("class\r"); } Assert.AreEqual("min.__class__", view.Text); } }
private IEnumerable<string> HideAdvancedMembersHelper(PythonEditor view, string text, params string[] completions) { view.Text = text; var snapshot = view.CurrentSnapshot; var set = new FuzzyCompletionSet( "Test Completions", "Test Completions", snapshot.CreateTrackingSpan(0, snapshot.Length, SpanTrackingMode.EdgeInclusive), completions.Select(c => new DynamicallyVisibleCompletion(c)), new CompletionOptions { HideAdvancedMembers = true, IntersectMembers = false }, CompletionComparer.UnderscoresLast ); set.Filter(); return set.Completions.Select(c => c.DisplayText).ToList(); }
public void CompletionWithLongDocString() { using (var vs = new MockVs()) { var docString = GenerateText(100, 72, " ").ToArray(); string code = @" def func(a): '''" + string.Join(Environment.NewLine, docString) + @"''' pass "; // Because there is an extra line added for the Quick Info we only // want the first 29 lines of the docstring. For signature docs, // we'll cut to 15 lines. var expected1 = string.Join(Environment.NewLine, docString.Take(29)) + Environment.NewLine + "..."; var expected2 = string.Join(Environment.NewLine, docString.Take(15)).TrimStart() + Environment.NewLine + "..."; using (var view = new PythonEditor(code)) { TestQuickInfo(view, code.IndexOf("func"), code.IndexOf("func") + 4, "func: def func(a)\r\n" + expected1); SignatureAnalysis sigs; view.Text += "func("; TestSignature(view, -1, "func", 0, out sigs); Assert.AreEqual(1, sigs.Signatures.Count); Assert.AreEqual(1, sigs.Signatures[0].Parameters.Count); Assert.AreEqual(expected2, sigs.Signatures[0].Documentation); } docString = GenerateText(100, 250, " ").ToArray(); code = @" def func(a): '''" + string.Join(Environment.NewLine, docString) + @"''' pass "; using (var view = new PythonEditor(code)) { // The long lines cause us to truncate sooner. expected1 = string.Join(Environment.NewLine, docString.Take(15)) + Environment.NewLine + "..."; expected2 = string.Join(Environment.NewLine, docString.Take(8)).TrimStart() + Environment.NewLine + "..."; TestQuickInfo(view, code.IndexOf("func"), code.IndexOf("func") + 4, "func: def func(a)\r\n" + expected1); SignatureAnalysis sigs; view.Text += "func("; TestSignature(view, -1, "func", 0, out sigs); Assert.AreEqual(1, sigs.Signatures.Count); Assert.AreEqual(1, sigs.Signatures[0].Parameters.Count); Assert.AreEqual(expected2, sigs.Signatures[0].Documentation); } } }
public void ClassCompletionOutsideFunction() { // Note that "eggs_and_spam" is longer than the indentation of each // scope. string code = @" eggs_and_spam = 'abc' class Spam(object): eggs_and_spam = 123 def f(self, eggs_and_spam = 3.14): #1 pass #2 #3 "; using (var view = new PythonEditor()) { view.Text = code.Replace("#1", "eggs_and_spam."); var completionList = view.GetCompletionsAfter("eggs_and_spam."); AssertUtil.ContainsAtLeast(completionList, "real", "imag"); AssertUtil.DoesntContain(completionList, "lower"); view.Text = code.Replace("#2", "eggs_and_spam."); AssertUtil.ContainsAtLeast(view.GetCompletionsAfter("eggs_and_spam."), "bit_length"); view.Text = code.Replace("#3", "eggs_and_spam."); AssertUtil.ContainsAtLeast(view.GetCompletionsAfter("eggs_and_spam."), "lower", "center"); } }
public void HandledImportSquiggle() { var testCases = new List<Tuple<string, string[]>>(); testCases.AddRange( new[] { "", " BaseException", " Exception", " ImportError", " (ValueError, ImportError)" } .Select(ex => Tuple.Create( string.Format("try:\r\n import spam\r\nexcept{0}:\r\n pass\r\n", ex), new string[0] )) ); testCases.Add(Tuple.Create( "try:\r\n import spam\r\nexcept ValueError:\r\n pass\r\n", new[] { @".*warning:.*spam.*\(17-21\)" } )); using (var view = new PythonEditor()) { var errorProvider = view.VS.ServiceProvider.GetComponentModel().GetService<IErrorProviderFactory>(); var tagger = errorProvider.GetErrorTagger(view.View.TextView.TextBuffer); // Ensure all tasks have been updated var taskProvider = (ErrorTaskProvider)view.VS.ServiceProvider.GetService(typeof(ErrorTaskProvider)); foreach (var testCase in testCases) { view.Text = testCase.Item1; var time = taskProvider.FlushAsync().GetAwaiter().GetResult(); Console.WriteLine("TaskProvider.FlushAsync took {0}ms", time.TotalMilliseconds); var squiggles = tagger.GetTaggedSpans(new SnapshotSpan(view.CurrentSnapshot, 0, view.CurrentSnapshot.Length)) .Select(FormatErrorTag) .ToList(); Console.WriteLine(testCase.Item1); Console.WriteLine(" Squiggles found:"); foreach (var actual in squiggles) { Console.WriteLine(actual); } Console.WriteLine(" Found {0} squiggle(s)", squiggles.Count); Console.WriteLine(); int i = 0; foreach (var expected in testCase.Item2) { Assert.IsTrue(i < squiggles.Count, "Not enough squiggles"); AssertUtil.AreEqual(new Regex(expected, RegexOptions.IgnoreCase | RegexOptions.Singleline), squiggles[i]); i += 1; } } } }
public ClassifierHelper(string code, PythonLanguageVersion version) { _view = new PythonEditor("", version); var providers = _view.VS.ComponentModel.GetExtensions<IClassifierProvider>().ToArray(); _provider1 = providers.OfType<PythonClassifierProvider>().Single(); _provider2 = providers.OfType<PythonAnalysisClassifierProvider>().Single(); _classificationsReady1 = new ManualResetEventSlim(); _classificationsReady2 = new ManualResetEventSlim(); AstClassifier.ClassificationChanged += (s, e) => SafeSetEvent(_classificationsReady1); AnalysisClassifier.ClassificationChanged += (s, e) => SafeSetEvent(_classificationsReady2); _view.Text = code; }
public void CompletionsAtEndOfLastChildScope() { using (var view = new PythonEditor(@"class A: def f(param1, param2): y = 234 class B: pass ")) { view.View.MoveCaret(5, 9); view.Type("p"); view.View.MemberList(); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.ContainsAtLeast(sh.Session.Completions(), "param1", "param2"); } } }
private void OneRefactorTest(string newName, string caretText, FileInput[] inputs, Version version, bool preview, string error, ExpectedPreviewItem[] expected = null) { Console.WriteLine("Replacing {0} with {1}", caretText, newName); version = version ?? new Version(2, 7); for (int loops = 0; loops < 2; loops++) { var views = new List<PythonEditor>(); try { var mainView = new PythonEditor(inputs[0].Input, version.ToLanguageVersion(), _vs, filename: inputs[0].Filename); var analyzer = mainView.Analyzer; views.Add(mainView); var bufferTable = new Dictionary<string, ITextBuffer> { { inputs[0].Filename, mainView.CurrentSnapshot.TextBuffer } }; foreach (var i in inputs.Skip(1)) { var editor = new PythonEditor(i.Input, version.ToLanguageVersion(), _vs, mainView.Factory, analyzer, i.Filename); views.Add(editor); bufferTable[i.Filename] = editor.CurrentSnapshot.TextBuffer; } // test runs twice, one w/ original buffer, once w/ re-analyzed buffers. if (loops == 1) { // do it again w/ a changed buffer mainView.Text = mainView.Text; } var caretPos = inputs[0].Input.IndexOf(caretText); mainView.View.MoveCaret(new SnapshotPoint(mainView.CurrentSnapshot, caretPos)); var extractInput = new RenameVariableTestInput(newName, bufferTable, preview); var previewChangesService = new TestPreviewChanges(expected); new VariableRenamer(views[0].View.View, _vs.ServiceProvider).RenameVariable(extractInput, previewChangesService); if (error != null) { Assert.AreEqual(error, extractInput.Failure); return; } Assert.IsNull(extractInput.Failure, "Unexpected error message: " + (extractInput.Failure ?? "")); Assert.AreEqual(preview, previewChangesService.Previewed, preview ? "Changes were not previewed" : "Changes were previewed"); AssertUtil.ArrayEquals(inputs.Select(i => i.Output).ToList(), views.Select(v => v.Text).ToList()); } finally { views.Reverse(); foreach (var v in views) { v.Dispose(); } } } }
public void HideAdvancedMembers() { using (var view = new PythonEditor()) { // No text - expect all non-advanced members AssertUtil.ContainsExactly(HideAdvancedMembersHelper(view, "", "a", "b", "__c__", "__d_e__", "_f_"), "a", "b", "_f_" ); // Matches one item, so we should only see that AssertUtil.ContainsExactly(HideAdvancedMembersHelper(view, "a", "a", "b", "__c__", "__d_e__", "_f_"), "a" ); // Matches one hidden item - expect all non-advanced members AssertUtil.ContainsExactly(HideAdvancedMembersHelper(view, "c", "a", "b", "__c__", "__d_e__", "_f_"), "a", "b", "_f_" ); // Matches one item and advanced members AssertUtil.ContainsExactly(HideAdvancedMembersHelper(view, "__", "a", "b", "__c__", "__d_e__", "_f_"), "_f_", "__c__", "__d_e__" ); } }
public void ArgumentNameCompletion() { const string code = @" def f(param1 = 123, param2 : int = 234): pass x = f("; using (var view = new PythonEditor(code)) { view.Text = view.Text; AssertUtil.ContainsAtLeast(view.GetCompletions(-1), "param1", "param2"); AssertUtil.DoesntContain(view.GetCompletions(0), "param1"); } }
private void AutoListTest(string code, PythonLanguageVersion version, params int[] triggerAtIndex) { using (var view = new PythonEditor(version: version)) { view.AdvancedOptions.AutoListIdentifiers = true; view.AdvancedOptions.AutoListMembers = true; int lastStart = 0; string text; foreach (var _i in triggerAtIndex) { bool expectCompletions = _i >= 0; int expected = _i > 0 ? _i : -_i; text = code.Substring(lastStart, expected - lastStart); Console.WriteLine("Typing '{0}' [{1}, {2})", text, lastStart, expected); view.Type(text); view.View.AssertNoIntellisenseSession(); lastStart = expected; if (expectCompletions) { text = code.Substring(expected, 1); Console.WriteLine("Typing '{0}' [{1}, {2}) and expect completions", text, expected, expected + 1); view.Type(text); using (var sh = view.View.WaitForSession<ICompletionSession>()) { sh.Session.Dismiss(); } lastStart = expected + 1; } } text = code.Substring(lastStart); if (!string.IsNullOrEmpty(text)) { Console.WriteLine("Typing '{0}' [{1}, {2})", text, lastStart, code.Length); view.Type(text); view.View.AssertNoIntellisenseSession(); } } }
public void NonIdentifierDismisses() { using (var view = new PythonEditor()) { view.Type("min."); using (var sh = view.View.WaitForSession<ICompletionSession>()) { AssertUtil.Contains(sh.Session.Completions(), "__call__"); view.Type("#"); Assert.IsTrue(sh.Session.IsDismissed); } view.View.AssertNoIntellisenseSession(); Assert.AreEqual("min.#", view.Text); } }