tests.java.org.python.indexer.TestBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import junit.framework.TestCase;
import org.python.indexer.types.NType;
import org.python.indexer.types.NUnknownType;
/**
* Test utilities for {@link IndexerTest}.
*/
public class TestBase extends TestCase {
// Set this to control logging to the console from the Indexer (mostly at FINER level).
static protected final Level LOGGING_LEVEL = Level.OFF;
static protected final String TEST_DATA_DIR;
static protected final String TEST_LIB_DIR;
static {
/*
* Locate cardinal directories in a way that insulates us from the vagueries of the
* environment, Ant, IDE and OS.
*/
String home = System.getProperty("python.home", "dist");
String test = System.getProperty("python.test.source.dir", "tests/java");
File source = new File(test, "org/python/indexer"); // corrects to \ where needed.
// Program actually uses strings, with a trailing slash
TEST_DATA_DIR = (new File(source, "data")).getAbsolutePath() + File.separator;
TEST_LIB_DIR = (new File(home, "Lib")).getAbsolutePath() + File.separator;
// Give the logger used by Indexer an outlet
setUpLogging();
}
// Define a handler for the logger to use
static private void setUpLogging() {
// Enable tracing of the operation of the Indexer onto the console
Logger indexerLogger = Logger.getLogger(Indexer.class.getCanonicalName());
Handler logHandler = new ConsoleHandler();
logHandler.setFormatter(new SimpleFormatter());
logHandler.setLevel(Level.FINEST);
indexerLogger.addHandler(logHandler);
}
protected Indexer idx;
public TestBase() {
}
@Override
protected void setUp() throws Exception {
idx = new Indexer();
idx.getLogger().setLevel(LOGGING_LEVEL);
idx.enableAggressiveAssertions(true);
idx.setProjectDir(TEST_DATA_DIR);
AstCache.get().clearDiskCache();
AstCache.get().clear();
}
/**
* Call this at the beginning of a test to permit the test code to import
* modules from the Python standard library.
*/
protected void includeStandardLibrary() throws Exception {
idx.addPath(TEST_LIB_DIR);
}
protected String abspath(String file) {
return getTestFilePath(file);
}
/**
* Return absolute path for {@code file}, a relative path under the
* data/ directory.
*/
protected String getTestFilePath(String file) {
return TEST_DATA_DIR + file;
}
protected String getSource(String file) throws Exception {
String path = getTestFilePath(file);
StringBuilder sb = new StringBuilder();
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
in.close(); // not overly worried about resource cleanup in unit tests
return sb.toString();
}
/**
* Construct python source by joining the specified lines.
*/
protected String makeModule(String... lines) {
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line).append("\n");
}
return sb.toString();
}
/**
* Build an index out of the specified file and content lines,
* and return the resulting module source.
*/
protected String index(String filename, String... lines) throws Exception {
String src = makeModule(lines);
idx.loadString(filename, src);
idx.ready();
return src;
}
/**
* Return offset in {@code s} of {@code n}th occurrence of {@code find}.
* {@code n} is 1-indexed.
* @throws IllegalArgumentException if the {@code n}th occurrence does not exist
*/
protected int nthIndexOf(String s, String find, int n) {
if (n <= 0) {
throw new IllegalArgumentException();
}
int index = -1;
for (int i = 0; i < n; i++) {
index = s.indexOf(find, index == -1 ? 0 : index + 1);
if (index == -1) {
throw new IllegalArgumentException();
}
}
return index;
}
// meta-tests
public void testHandleExceptionLoggingNulls() throws Exception {
try {
idx.enableAggressiveAssertions(false);
idx.getLogger().setLevel(java.util.logging.Level.OFF);
idx.handleException(null, new Exception());
idx.handleException("oops", null);
} catch (Throwable t) {
fail("should not have thrown: " + t);
}
}
public void testDataFileFindable() throws Exception {
assertTrue("Test file not found", new java.io.File(TEST_DATA_DIR).exists());
}
public void testLoadDataFile() throws Exception {
String path = abspath("test-load.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
assertEquals(in.readLine().trim(), "hello");
in.close();
}
public void testGetSource() throws Exception {
String src = getSource("testsrc.txt");
assertEquals("one\ntwo\n\nthree\n", src);
}
public void testStringModule() throws Exception {
idx.loadString("test-string-module.py", makeModule(
"def foo():",
" pass"));
idx.ready();
assertFunctionBinding("test-string-module.foo");
}
public void testNthIndexOf() throws Exception {
String s = "ab a b ab a\nb aab";
assertEquals(0, nthIndexOf(s, "ab", 1));
assertEquals(7, nthIndexOf(s, "ab", 2));
assertEquals(15, nthIndexOf(s, "ab", 3));
try {
assertEquals(-1, nthIndexOf(s, "ab", 0));
assertTrue(false);
} catch (IllegalArgumentException ix) {
assertTrue(true);
}
try {
assertEquals(-1, nthIndexOf(s, "ab", 4));
assertTrue(false);
} catch (IllegalArgumentException ix) {
assertTrue(true);
}
}
public void testIndexerDefaults() throws Exception {
includeStandardLibrary();
assertEquals("wrong project dir", TEST_DATA_DIR, idx.projDir);
assertEquals("unexpected load path entries", 1, idx.path.size());
assertEquals(TEST_LIB_DIR, idx.path.get(0));
}
// utilities
public String buildIndex(String... files) throws Exception {
for (String f : files) {
idx.loadFile(abspath(f));
}
idx.ready();
return getSource(files[0]);
}
public NBinding getBinding(String qname) throws Exception {
NBinding b = idx.lookupQname(qname);
assertNotNull("no binding found for " + qname, b);
return b;
}
public NBinding assertBinding(String qname, NBinding.Kind kind) throws Exception {
NBinding b = getBinding(qname);
assertEquals(kind, b.getKind());
return b;
}
public void assertNoBinding(String qname) throws Exception {
NBinding b = idx.lookupQname(qname);
assertNull("Should not have found binding for " + qname, b);
}
public NBinding assertAttributeBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.ATTRIBUTE);
}
public NBinding assertBuiltinBinding(String qname) throws Exception {
NBinding b = getBinding(qname);
assertTrue(b.isBuiltin());
return b;
}
public NBinding assertClassBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.CLASS);
}
public NBinding assertConstructorBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.CONSTRUCTOR);
}
public NBinding assertFunctionBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.FUNCTION);
}
public NBinding assertMethodBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.METHOD);
}
public NBinding assertModuleBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.MODULE);
}
public NBinding assertScopeBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.SCOPE);
}
public NBinding assertVariableBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.VARIABLE);
}
public NBinding assertParamBinding(String qname) throws Exception {
return assertBinding(qname, NBinding.Kind.PARAMETER);
}
public void assertStaticSynthetic(NBinding b) {
assertTrue(b.isStatic());
assertTrue(b.isSynthetic());
}
public Def getDefinition(String qname, int offset, int length) throws Exception {
NBinding b = getBinding(qname);
assertNotNull(b.getDefs());
for (Def def : b.getDefs()) {
if (offset == def.start() && length == def.end() - def.start()) {
return def;
}
}
return null;
}
public void assertDefinition(String qname, int offset, int length) throws Exception {
Def def = getDefinition(qname, offset, length);
if (def == null) {
fail("No definition for " + qname + " at " + offset + " of len " + length);
}
}
public void assertNoDefinition(String msg, String qname, int pos, int len) throws Exception {
Def def = getDefinition(qname, pos, len);
assertNull(msg, def);
}
public void assertDefinition(String qname, int offset) throws Exception {
String[] names = qname.split("[.&@]");
assertDefinition(qname, offset, names[names.length-1].length());
}
public void assertDefinition(String qname, String name, int offset) throws Exception {
assertDefinition(qname, offset, name.length());
}
public Ref getRefOrNull(String qname, int offset, int length) throws Exception {
NBinding b = getBinding(qname);
assertNotNull("Null refs list for " + qname, b.getRefs());
for (Ref ref : b.getRefs()) {
if (offset == ref.start() && length == ref.length()) {
return ref;
}
}
return null;
}
public Ref getRefOrFail(String qname, int offset, int length) throws Exception {
Ref ref = getRefOrNull(qname, offset, length);
assertNotNull("No reference to " + qname + " at offset " + offset + " of length " + length,
ref);
return ref;
}
public void assertReference(String qname, int offset, int length) throws Exception {
assertTrue(getRefOrFail(qname, offset, length).isRef());
}
public void assertReference(String qname, int offset, String refname) throws Exception {
assertReference(qname, offset, refname.length());
}
// assume reference to "a.b.c" is called "c" -- the normal case
public void assertReference(String qname, int offset) throws Exception {
String[] names = qname.split("[.&@]");
assertReference(qname, offset, names[names.length-1]);
}
public void assertNoReference(String msg, String qname, int pos, int len) throws Exception {
assertNull(msg, getRefOrNull(qname, pos, len));
}
public void assertCall(String qname, int offset, int length) throws Exception {
assertTrue(getRefOrFail(qname, offset, length).isCall());
}
public void assertCall(String qname, int offset, String refname) throws Exception {
assertCall(qname, offset, refname.length());
}
// "a.b.c()" => look for call reference at "c"
public void assertCall(String qname, int offset) throws Exception {
String[] names = qname.split("[.&@]");
assertCall(qname, offset, names[names.length-1]);
}
public void assertConstructed(String qname, int offset, int length) throws Exception {
assertTrue(getRefOrFail(qname, offset, length).isNew());
}
public void assertConstructed(String qname, int offset, String refname) throws Exception {
assertConstructed(qname, offset, refname.length());
}
// "a.b.c()" => look for call reference at "c"
public void assertConstructed(String qname, int offset) throws Exception {
String[] names = qname.split("[.&@]");
assertConstructed(qname, offset, names[names.length-1]);
}
public NType getTypeBinding(String typeQname) throws Exception {
NType type = idx.lookupQnameType(typeQname);
assertNotNull("No recorded type for " + typeQname, type);
return type;
}
// Assert that binding for qname has exactly one type (not a union),
// and that type has a binding with typeQname.
public NBinding assertBindingType(String bindingQname, String typeQname) throws Exception {
NBinding b = getBinding(bindingQname);
NType expected = getTypeBinding(typeQname);
assertEquals("Wrong binding type", expected, NUnknownType.follow(b.getType()));
return b;
}
public NBinding assertBindingType(String bindingQname, Class type) throws Exception {
NBinding b = getBinding(bindingQname);
NType btype = NUnknownType.follow(b.getType());
assertTrue("Wrong type: expected " + type + " but was " + btype,
type.isInstance(btype));
return b;
}
public void assertListType(String bindingQname) throws Exception {
assertListType(bindingQname, null);
}
/**
* Asserts that the binding named by {@code bindingQname} exists and
* its type is a List type. If {@code eltTypeQname} is non-{@code null},
* asserts that the List type's element type is an existing binding with
* {@code eltTypeQname}.
*/
public void assertListType(String bindingQname, String eltTypeQname) throws Exception {
NBinding b = getBinding(bindingQname);
NType btype = b.followType();
assertTrue(btype.isListType());
if (eltTypeQname != null) {
NType eltType = getTypeBinding(eltTypeQname);
assertEquals(eltType, NUnknownType.follow(btype.asListType().getElementType()));
}
}
public void assertStringType(String bindingQname) throws Exception {
assertBindingType(bindingQname, "__builtin__.str");
}
public void assertNumType(String bindingQname) throws Exception {
assertBindingType(bindingQname, "__builtin__.float");
}
public void assertInstanceType(String bindingQname, String classQname) throws Exception {
if (true) {
assertBindingType(bindingQname, classQname);
return;
}
// XXX: we've disabled support for NInstanceType for now
NBinding b = getBinding(bindingQname);
NType btype = b.followType();
assertTrue(btype.isInstanceType());
NType ctype = getTypeBinding(classQname);
assertEquals(btype.asInstanceType().getClassType(), ctype);
}
}