/**
* Copyright (c) 2005-2013 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.
*/
/*
* Created on Feb 1, 2005
*
* @author Fabio Zadrozny
*/
package org.python.pydev.editor.codecompletion.revisited;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.text.Document;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.ICodeCompletionASTManager;
import org.python.pydev.core.ICompletionState;
import org.python.pydev.core.IToken;
import org.python.pydev.core.TestDependent;
import org.python.pydev.core.structure.CompletionRecursionException;
import org.python.pydev.editor.codecompletion.IASTManagerObserver;
import org.python.pydev.editor.codecompletion.revisited.modules.CompiledModule;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.shared_core.string.FastStringBuffer;
/**
* Tests here have no dependency on the pythonpath.
*
* @author Fabio Zadrozny
*/
public class ASTManagerTest extends CodeCompletionTestsBase {
public static void main(String[] args) {
CompiledModule.COMPILED_MODULES_ENABLED = false;
try {
ASTManagerTest test = new ASTManagerTest();
test.setUp();
test.testCompletion();
test.tearDown();
junit.textui.TestRunner.run(ASTManagerTest.class);
} catch (Throwable e) {
e.printStackTrace();
}
}
private ICompletionState state;
private String token;
private int line;
private int col;
private String sDoc;
private Document doc;
private IToken[] comps = null;
/**
* @return Returns the manager.
*/
private ICodeCompletionASTManager getManager() {
return (ICodeCompletionASTManager) nature.getAstManager();
}
/*
* @see TestCase#setUp()
*/
@Override
public void setUp() throws Exception {
super.setUp();
CompiledModule.COMPILED_MODULES_ENABLED = false;
super.restorePythonPath(false);
}
/*
* @see TestCase#tearDown()
*/
@Override
public void tearDown() throws Exception {
super.tearDown();
CompiledModule.COMPILED_MODULES_ENABLED = true;
PydevPlugin.setBundleInfo(null);
}
public void testCompletion() {
token = "C";
line = 6;
col = 11;
sDoc = "" +
"class C: \n" +
" \n" +
" def makeit(self):\n"
+
" pass \n" +
" \n" +
"class D(C.: \n"
+
" \n" +
" def a(self): \n" +
" pass \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(1);
assertEquals("makeit", comps[0].getRepresentation());
sDoc = "" +
"import unittest \n" +
" \n" +
"class Classe1: \n"
+
" \n" +
" def makeit(self): \n" +
" self.makeit \n"
+
" \n" +
" \n" +
"class Test(unit \n";
line = 8;
col = 16;
token = "";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(6);
assertIsIn("__name__", comps);
assertIsIn("__file__", comps);
assertIsIn("__dict__", comps);
assertIsIn("unittest", comps);
assertIsIn("Classe1", comps);
assertIsIn("Test", comps);
sDoc = "" +
"import unittest \n" +
" \n" +
"class Classe1: \n"
+
" \n" +
" def makeit(self): \n" +
" self.makeit \n"
+
" \n" +
" \n" +
"class Test(unit \n"
+
" \n" +
"def meth1(): \n" +
" pass \n";
line = 8;
col = 16;
token = "";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(7);
assertIsIn("__name__", comps);
assertIsIn("__file__", comps);
assertIsIn("__dict__", comps);
assertIsIn("unittest", comps);
assertIsIn("Classe1", comps);
assertIsIn("Test", comps);
assertIsIn("meth1", comps);
sDoc = "" +
"import unittest \n" +
" \n" +
"class Classe1: \n"
+
" \n" +
" def makeit(self): \n" +
" self.makeit \n"
+
" \n" +
" \n" +
"class Test(unit \n"
+
" \n" +
" def meth1(): \n" +
" pass \n";
line = 8;
col = 16;
token = "";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(6);
assertIsIn("__name__", comps);
assertIsIn("__file__", comps);
assertIsIn("__dict__", comps);
assertIsIn("unittest", comps);
assertIsIn("Classe1", comps);
assertIsIn("Test", comps);
sDoc = "" +
"class Classe1: \n" +
" \n" +
" def foo(self): \n"
+
" ignoreThis=0 \n" +
" self.a = 1 \n" +
" self. \n"
+
" \n";
line = 6;
col = 13;
token = "Classe1";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(2);
assertIsIn("a", comps);
assertIsIn("foo", comps);
sDoc = "" +
"class Classe1: \n" +
" \n" +
" def foo(self): \n"
+
" self.a = 2 \n" +
" \n" +
" test = foo \n"
+
" \n" +
"Classe1. \n";
line = 8;
col = 9;
token = "Classe1";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(3);
assertIsIn("foo", comps);
assertIsIn("a", comps);
assertIsIn("test", comps);
sDoc = "" +
"class LinkedList: \n" +
" def __init__(self,content='Null'): \n"
+
" if not content: \n" +
" self.first=content \n"
+
" self.last=content \n" +
" else: \n"
+
" self.first='Null' \n" +
" self.last='Null' \n"
+
" self.content=content \n" +
" self. \n";
line = 9;
col = 9;
token = "LinkedList";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
assertIsIn("first", comps);
assertIsIn("last", comps);
assertIsIn("content", comps);
}
private void checkExpected(String... expected) {
for (String s : expected) {
assertIsIn(s, comps);
}
List<String> asList = Arrays.asList(expected);
for (IToken t : comps) {
assertContains(asList, t.getRepresentation());
}
checkExpected(expected.length);
}
private void checkExpected(int expected) {
FastStringBuffer buf = new FastStringBuffer(40 * comps.length);
for (IToken t : comps) {
buf.append(t.getRepresentation());
buf.append(", ");
}
String msg = "Expected " + expected +
". Found: " + buf.toString();
assertEquals(msg, expected, comps.length);
}
private IToken[] getComps() {
try {
IToken[] completionsForToken = getManager().getCompletionsForToken(doc, state);
HashMap<String, IToken> map = new HashMap<String, IToken>();
for (IToken iToken : completionsForToken) {
map.put(iToken.getRepresentation(), iToken);
}
return map.values().toArray(new IToken[map.size()]);
} catch (CompletionRecursionException e) {
throw new RuntimeException(e);
}
}
public void testRecursion() {
token = "B";
line = 0;
col = 0;
sDoc = "" +
"class A(B):pass \n" +
"class B(A):pass \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(0); //no tokens returned
}
public void testRelative() {
super.restorePythonPath(false);
token = "Test1";
line = 1;
col = 0;
sDoc = "" +
"from testlib.unittest.relative import Test1 \n" +
"\n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(1);
assertIsIn("test1", comps);
}
public void testLocals() {
token = "";
line = 2;
sDoc = "" +
"contentsCopy = applicationDb.getContentsCopy()\n"
+
"database.Database.fromContentsCopy(self, cont)";
col = sDoc.length() - 3;
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(4);
assertIsIn("contentsCopy", comps);
assertIsIn("__file__", comps);
assertIsIn("__dict__", comps);
assertIsIn("__name__", comps);
}
public void testLocals2() {
token = "";
line = 2;
col = 10;
sDoc = "" +
"def met(par1, par2): \n" +
" print \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(6);
assertIsIn("__file__", comps);
assertIsIn("__name__", comps);
assertIsIn("__dict__", comps);
assertIsIn("par1", comps);
assertIsIn("par2", comps);
assertIsIn("met", comps);
token = "";
line = 3;
col = 13;
sDoc = "" +
"class C: \n" +
" def met(self, par1, par2): \n"
+
" print \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected(7);
assertIsIn("__name__", comps);
assertIsIn("__dict__", comps);
assertIsIn("__file__", comps);
assertIsIn("par1", comps);
assertIsIn("par2", comps);
assertIsIn("self", comps);
assertIsIn("C", comps);
token = "";
line = 4;
col = 13;
sDoc = "" +
"class C: \n" +
" def met(self, par1, par2): \n"
+
" loc1 = 10 \n" +
" print \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected("__name__", "__file__", "__dict__", "par1", "loc1", "par2", "self", "C");
token = "";
line = 4;
col = 13;
sDoc = "" +
"class C: \n" +
" def met(self, par1, par2): \n"
+
" loc1 = 10 \n" +
" print \n"
+
" ignoreLineAfter = 5 \n";
doc = new Document(sDoc);
state = new CompletionState(line, col, token, nature, "");
comps = getComps();
checkExpected("__name__", "__file__", "__dict__", "par1", "loc1", "par2", "self", "C");
}
private static class ManagerObserver implements IASTManagerObserver {
boolean called;
@Override
public void notifyASTManagerAttached(ICodeCompletionASTManager manager) {
called = true;
}
}
/**
* Check that registered observers are called when ASTManager is
* associated with project.
*/
public void testManagerObserver() {
Map<String, List<Object>> oldExtensions = ExtensionHelper.testingParticipants;
try {
ManagerObserver trackingObserver = new ManagerObserver();
Map<String, List<Object>> extensions = new HashMap<String, List<Object>>();
extensions
.put(ExtensionHelper.PYDEV_MANAGER_OBSERVER, Collections.<Object> singletonList(trackingObserver));
ExtensionHelper.testingParticipants = extensions;
restoreProjectPythonPath(false, TestDependent.TEST_PYSRC_LOC, "TestProject");
assertTrue(trackingObserver.called);
} finally {
ExtensionHelper.testingParticipants = oldExtensions;
}
}
/**
* @param string
* @param comps
*/
public static void assertIsIn(String string, IToken[] comps) {
StringBuffer buffer = new StringBuffer("Available: \n");
boolean found = false;
for (int i = 0; i < comps.length; i++) {
String rep = comps[i].getRepresentation();
if (string.equals(rep)) {
found = true;
}
buffer.append(rep);
buffer.append("\n");
}
assertTrue("The searched token (" + string +
")was not found in the completions. " + buffer, found);
}
}