/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.editor.codecompletion;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.python.pydev.core.ICompletionState;
import org.python.pydev.core.IToken;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.editor.codecompletion.revisited.CodeCompletionTestsBase;
import org.python.pydev.editor.codecompletion.revisited.modules.CompiledModule;
import com.aptana.shared_core.string.FastStringBuffer;
public class PythonCompletionCalltipsTest extends CodeCompletionTestsBase {
public static void main(String[] args) {
try {
//DEBUG_TESTS_BASE = true;
PythonCompletionCalltipsTest test = new PythonCompletionCalltipsTest();
test.setUp();
test.testCalltips3a();
test.tearDown();
System.out.println("Finished");
junit.textui.TestRunner.run(PythonCompletionCalltipsTest.class);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
}
/*
* @see TestCase#setUp()
*/
public void setUp() throws Exception {
super.setUp();
CompiledModule.COMPILED_MODULES_ENABLED = false;
this.restorePythonPath(false);
codeCompletion = new PyCodeCompletion();
}
/*
* @see TestCase#tearDown()
*/
public void tearDown() throws Exception {
CompiledModule.COMPILED_MODULES_ENABLED = true;
super.tearDown();
}
public void testCalltips1() throws Exception {
String s;
s = "" +
"GLOBAL_VAR = 10\n" + //this variable should not show in the return
"def m1(a, b):\n" +
" print a, b\n" +
"\n" +
"m1(a, b)"; //we'll request a completion inside the parentesis to check for calltips. For calltips, we
//should get the activation token as an empty string and the qualifier as "m1",
//so, the completion that should return is "m1(a, b)", with the information context
//as "a, b".
//
//
//
//The process of getting the completions actually starts at:
//org.python.pydev.editor.codecompletion.PyCodeCompletion#getCodeCompletionProposals
ICompletionProposal[] proposals = requestCompl(s, s.length() - 5, -1, new String[] {});
if (false) { //make true to see which proposals were returned.
for (ICompletionProposal proposal : proposals) {
System.out.println(proposal.getDisplayString());
}
}
assertEquals(1, proposals.length); //now, here's the first part of the failing test: we can only have one
//returned proposal: m1(a, b)
//check if the returned proposal is there
ICompletionProposal prop = proposals[0];
assertEquals("m1(a, b)", prop.getDisplayString());
PyCompletionProposal p4 = (PyCompletionProposal) prop;
assertTrue(p4.isAutoInsertable());
assertEquals(PyCompletionProposal.ON_APPLY_JUST_SHOW_CTX_INFO, p4.onApplyAction);
//the display string for the context 'context' and 'information' should be the same
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) prop.getContextInformation();
assertEquals("a, b", contextInformation.getContextDisplayString());
assertEquals("a, b", contextInformation.getInformationDisplayString());
//now, this proposal has one interesting thing about it: it should actually not change the document
//where it is applied (it is there just to show the calltip).
//
//To implement that, when we see that it is called inside some parenthesis, we should create a subclass of
//PyCompletionProposal that will have its apply method overriden, so that nothing happens here (the calltips will
//still be shown)
Document doc = new Document();
prop.apply(doc);
assertEquals("", doc.get());
}
public void testCalltips2() throws Exception {
String s;
s = "" +
"GLOBAL_VAR = 10\n" +
"def m1(a, b):\n" +
" print a, b\n" +
"def m1Other(a, b):\n" + //this one should not show, as we're returning it for calltip purposes only
" print a, b\n" +
"\n" +
"m1()";
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] { "m1(a, b)" });
assertEquals(1, proposals.length);
}
public void testCalltips3() throws Exception {
String s;
s = "" +
"def m1(a, b):\n" +
" print a, b\n" +
"m1()";
PyContextInformationValidator validator = new PyContextInformationValidator();
int requestOffset = s.length() - 1;
ICompletionProposal[] proposals = requestCompl(s, requestOffset, -1, new String[] {});
assertEquals(1, proposals.length);
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) proposals[0]
.getContextInformation();
validator.install(contextInformation, new Document(s), requestOffset);
assertFalse(validator.isContextInformationValid(0));
assertTrue(validator.isContextInformationValid(requestOffset));
assertFalse(validator.isContextInformationValid(requestOffset + 1));
assertEquals("a, b", contextInformation.getContextDisplayString());
}
public void testCalltips3a() throws Exception {
String s;
s = "" +
"def m1((a, b), c):\n" + //yes, this is no longer supported (and this construct is rarely used).
" print a, b, c\n" +
"m1()";
PyContextInformationValidator validator = new PyContextInformationValidator();
int requestOffset = s.length() - 1;
ICompletionProposal[] proposals = requestCompl(s, requestOffset, -1, new String[] {});
assertEquals(1, proposals.length);
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) proposals[0]
.getContextInformation();
validator.install(contextInformation, new Document(s), requestOffset);
assertFalse(validator.isContextInformationValid(0));
assertTrue(validator.isContextInformationValid(requestOffset));
assertFalse(validator.isContextInformationValid(requestOffset + 1));
assertEquals("(a, b), c", contextInformation.getContextDisplayString());
}
public void testCalltips4() throws Exception {
String s;
s = "" +
"def m1(a, b):\n" +
" print a, b\n" +
"m1(a,b)";
int requestOffset = s.length() - 4;
ICompletionProposal[] proposals = requestCompl(s, requestOffset, -1, new String[] {});
assertEquals(1, proposals.length);
PyContextInformationValidator validator = new PyContextInformationValidator();
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) proposals[0]
.getContextInformation();
validator.install(contextInformation, new Document(s), requestOffset);
assertFalse(validator.isContextInformationValid(requestOffset - 1));
assertTrue(validator.isContextInformationValid(requestOffset));
assertTrue(validator.isContextInformationValid(requestOffset + 3));
assertFalse(validator.isContextInformationValid(requestOffset + 4));
}
public void testCalltips5() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, a, b):\n" +
" pass\n" +
" \n"
+
"TestCase(%s)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] {});
assertEquals(1, proposals.length);
PyCompletionProposal p = (PyCompletionProposal) proposals[0];
assertEquals("TestCase(a, b)", p.getDisplayString());
Document document = new Document(s);
p.apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "a, b"), document.get());
}
public void testCalltips6() throws Exception {
String s = "from extendable import calltips\n" +
"calltips.";
requestCompl(s, s.length(), 5, new String[] { "__file__", "__dict__", "__name__", "method1(a, b)", "__path__" });
}
public void testCalltips7() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, param1, param2):\n" +
" pass\n"
+
" \n" +
"TestCase(para%s)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] {});
assertEquals(2, proposals.length);
PyCompletionProposal param1Proposal = (PyCompletionProposal) assertContains("param1=", proposals);
assertContains("param2=", proposals);
Document document = new Document(s);
param1Proposal.apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "m1="), document.get());
}
public void testCalltips8() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, param1, param2):\n" +
" pass\n"
+
" \n" +
"TestCase(param1=10, para%s)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] {});
assertEquals(2, proposals.length);
PyCompletionProposal paramProposal = (PyCompletionProposal) assertContains("param1=", proposals);
paramProposal = (PyCompletionProposal) assertContains("param2=", proposals);
Document document = new Document(s);
paramProposal.apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "m2="), document.get());
}
public void testCalltips8a() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, param1, param2):\n" +
" pass\n"
+
" \n" +
"TestCase(param1=10, para%s=20)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "m3");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 7, -1, new String[] {});
assertEquals(2, proposals.length);
PyLinkedModeCompletionProposal paramProposal = (PyLinkedModeCompletionProposal) assertContains("param1=",
proposals);
paramProposal = (PyLinkedModeCompletionProposal) assertContains("param2=", proposals);
Document document = new Document(s);
paramProposal.setLen(2); //only the 'm3'
paramProposal.applyOnDoc(paramProposal.getReplacementOffset() + 4, true, document, 4, '\0');
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "m2"), document.get());
}
public void testCalltips9() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, param1, param2, *args, **kwargs):\n"
+
" pass\n" +
" \n" +
"TestCase(%s)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] {});
assertEquals(1, proposals.length);
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) proposals[0]
.getContextInformation();
assertEquals("self, param1, param2, *args, **kwargs", contextInformation.getContextDisplayString());
assertEquals(108, contextInformation.getShowCalltipsOffset());
Document document = new Document(s);
proposals[0].apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "param1, param2"), document.get());
}
public void testCalltips10() throws Exception {
String s0 = "class TestCase(object):\n" +
" def __init__(self, param1, param2, *args, **kwargs):\n"
+
" pass\n" +
" \n" +
"TestCase(param1=10, p)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 2, -1, new String[] {});
assertEquals(1, proposals.length);
IPyCalltipsContextInformation contextInformation = (IPyCalltipsContextInformation) proposals[0]
.getContextInformation();
assertEquals("self, param1, param2, *args, **kwargs", contextInformation.getContextDisplayString());
assertEquals(108, contextInformation.getShowCalltipsOffset());
Document document = new Document(s);
proposals[0].apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "param1, param2"), document.get());
}
public void testCalltips11() throws Exception {
String s0 = "class TestCase(object):\n" +
" \n" +
" def M1(self, kkk, xxx):\n" +
" pass\n" +
"\n"
+
" def __init__(self):\n" +
" self.M1(k%s)";
String s = com.aptana.shared_core.string.StringUtils.format(s0, "");
ICompletionProposal[] proposals = requestCompl(s, s.length() - 1, -1, new String[] {});
assertEquals(1, proposals.length);
Document document = new Document(s);
proposals[0].apply(document);
assertEquals(com.aptana.shared_core.string.StringUtils.format(s0, "kk="), document.get());
}
public void testMakeArgsForDocumentReplacement() throws Exception {
FastStringBuffer temp = new FastStringBuffer();
FastStringBuffer result = new FastStringBuffer();
assertEquals("", AbstractPyCodeCompletion.makeArgsForDocumentReplacement("", result, temp));
assertEquals("()", AbstractPyCodeCompletion.makeArgsForDocumentReplacement("()", result, temp));
assertEquals("(a, b, c)", AbstractPyCodeCompletion.makeArgsForDocumentReplacement("(a, b, c)", result, temp));
assertEquals("((a, b), c)",
AbstractPyCodeCompletion.makeArgsForDocumentReplacement("((a, b), c)", result, temp));
assertEquals("(a, b)",
AbstractPyCodeCompletion.makeArgsForDocumentReplacement("(object a, object b)", result, temp));
assertEquals("(a, b)", AbstractPyCodeCompletion.makeArgsForDocumentReplacement("(o\ta,\to\tb)", result, temp));
assertEquals("(a, *b, **c)",
AbstractPyCodeCompletion.makeArgsForDocumentReplacement("(o\ta,\to\t* b, o ** c)", result, temp));
}
public void testCalltipsArgs() throws Exception {
assertEquals("()", AbstractPyCodeCompletion.getArgs("", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("()", AbstractPyCodeCompletion.getArgs("(", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("()", AbstractPyCodeCompletion.getArgs(")", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("(a, b)", AbstractPyCodeCompletion.getArgs("(a, b)", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("(a, b)", AbstractPyCodeCompletion.getArgs("(self, a, b)", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("(a, b)", AbstractPyCodeCompletion.getArgs("(cls, a, b)", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("(clsParam, a, b)", AbstractPyCodeCompletion.getArgs("(clsParam, a, b)", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
assertEquals("(selfParam, a, b)", AbstractPyCodeCompletion.getArgs("(selfParam, a, b)", IToken.TYPE_FUNCTION,
ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE));
}
}