summaryrefslogtreecommitdiff
path: root/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java')
-rw-r--r--python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java202
1 files changed, 202 insertions, 0 deletions
diff --git a/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java b/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java
new file mode 100644
index 000000000000..c6b150f31359
--- /dev/null
+++ b/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java
@@ -0,0 +1,202 @@
+package com.jetbrains.env.python;
+
+import com.google.common.collect.ImmutableSet;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.env.PyEnvTestCase;
+import com.jetbrains.env.PyExecutionFixtureTestTask;
+import com.jetbrains.env.PyTestTask;
+import com.jetbrains.python.PythonFileType;
+import com.jetbrains.python.PythonTestUtil;
+import com.jetbrains.python.documentation.PythonDocumentationProvider;
+import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyBuiltinCache;
+import com.jetbrains.python.psi.resolve.PythonSdkPathCache;
+import com.jetbrains.python.psi.types.PyType;
+import com.jetbrains.python.psi.types.TypeEvalContext;
+import com.jetbrains.python.sdk.PythonSdkType;
+import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher;
+import com.jetbrains.python.sdk.skeletons.SkeletonVersionChecker;
+import com.jetbrains.python.sdkTools.SdkCreationType;
+import com.jetbrains.python.toolbox.Maybe;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.Set;
+
+/**
+ * Heavyweight integration tests of skeletons of Python binary modules.
+ * <p/>
+ * An environment test environment must have a 'skeletons' tag in order to be compatible with this test case. No specific packages are
+ * required currently. Both Python 2 and Python 3 are OK. All platforms are OK. At least one Python 2.6+ environment is required.
+ *
+ * @author vlan
+ */
+public class PythonSkeletonsTest extends PyEnvTestCase {
+ public static final ImmutableSet<String> TAGS = ImmutableSet.of("skeletons");
+
+ public void testBuiltins() {
+ runTest(new SkeletonsTask() {
+ @Override
+ public void runTestOn(@NotNull Sdk sdk) {
+ // Check the builtin skeleton header
+ final Project project = myFixture.getProject();
+ final PyFile builtins = PyBuiltinCache.getBuiltinsForSdk(project, sdk);
+ assertNotNull(builtins);
+ final VirtualFile virtualFile = builtins.getVirtualFile();
+ assertNotNull(virtualFile);
+ assertTrue(virtualFile.isInLocalFileSystem());
+ final String path = virtualFile.getPath();
+ final PySkeletonRefresher.SkeletonHeader header = PySkeletonRefresher.readSkeletonHeader(new File(path));
+ assertNotNull(header);
+ final int version = header.getVersion();
+ assertTrue("Header version must be > 0, currently it is " + version, version > 0);
+ assertEquals(SkeletonVersionChecker.BUILTIN_NAME, header.getBinaryFile());
+
+ // Run inspections on a file that uses builtins
+ myFixture.configureByFile(getTestName(false) + ".py");
+
+
+ PsiFile expr = myFixture.getFile();
+
+ final Module module = ModuleUtil.findModuleForPsiElement(expr);
+
+ final Sdk sdkFromModule = PythonSdkType.findPythonSdk(module);
+ assertNotNull(sdkFromModule);
+
+ final Sdk sdkFromPsi = PyBuiltinCache.findSdkForFile(expr.getContainingFile());
+ final PyFile builtinsFromSdkCache = PythonSdkPathCache.getInstance(project, sdkFromPsi).getBuiltins().getBuiltinsFile();
+ assertNotNull(builtinsFromSdkCache);
+ assertEquals(builtins, builtinsFromSdkCache);
+
+ final PyFile builtinsFromPsi = PyBuiltinCache.getInstance(expr).getBuiltinsFile();
+ assertNotNull(builtinsFromPsi);
+ assertEquals(builtins, builtinsFromPsi);
+
+ myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
+ edt(new Runnable() {
+ @Override
+ public void run() {
+ myFixture.checkHighlighting(true, false, false);
+ }
+ });
+ }
+ });
+ }
+
+ // PY-4349
+ public void testFakeNamedTuple() {
+ runTest(new SkeletonsTask() {
+ @Override
+ protected void runTestOn(@NotNull Sdk sdk) {
+ final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
+ // Named tuples have been introduced in Python 2.6
+ if (languageLevel.isOlderThan(LanguageLevel.PYTHON26)) {
+ return;
+ }
+
+ // XXX: A workaround for invalidating VFS cache with the test file copied to our temp directory
+ LocalFileSystem.getInstance().refresh(false);
+
+ // Run inspections on code that uses named tuples
+ myFixture.configureByFile(getTestName(false) + ".py");
+ myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
+
+ edt(new Runnable() {
+ @Override
+ public void run() {
+ myFixture.checkHighlighting(true, false, false);
+ }
+ });
+ }
+ });
+ }
+
+ public void testKnownPropertiesTypes() {
+ runTest(new SkeletonsTask() {
+ @Override
+ protected void runTestOn(@NotNull Sdk sdk) {
+ myFixture.configureByText(PythonFileType.INSTANCE,
+ "expr = slice(1, 2).start\n");
+ final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class);
+ final TypeEvalContext context = TypeEvalContext.codeAnalysis(myFixture.getFile());
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ final PyType type = context.getType(expr);
+ final String actualType = PythonDocumentationProvider.getTypeName(type, context);
+ assertEquals("int", actualType);
+ }
+ });
+ }
+ });
+ }
+
+ // PY-9797
+ public void testReadWriteDeletePropertyDefault() {
+ runTest(new SkeletonsTask() {
+ @Override
+ protected void runTestOn(@NotNull Sdk sdk) {
+ final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
+ // We rely on int.real property that is not explicitly annotated in the skeletons generator
+ if (languageLevel.isOlderThan(LanguageLevel.PYTHON26)) {
+ return;
+ }
+ final Project project = myFixture.getProject();
+ final PyFile builtins = PyBuiltinCache.getBuiltinsForSdk(project, sdk);
+ assertNotNull(builtins);
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ final PyClass cls = builtins.findTopLevelClass("int");
+ assertNotNull(cls);
+ final Property prop = cls.findProperty("real", true);
+ assertNotNull(prop);
+ assertIsNotNull(prop.getGetter());
+ assertIsNotNull(prop.getSetter());
+ assertIsNotNull(prop.getDeleter());
+ }
+ });
+ }
+
+ private void assertIsNotNull(Maybe<Callable> accessor) {
+ if (accessor.isDefined()) {
+ assertNotNull(accessor.valueOrNull());
+ }
+ }
+ });
+ }
+
+
+ private void runTest(@NotNull PyTestTask task) {
+ runPythonTest(task);
+ }
+
+
+ private abstract class SkeletonsTask extends PyExecutionFixtureTestTask {
+ @Override
+ protected String getTestDataPath() {
+ return PythonTestUtil.getTestDataPath() + "/skeletons/";
+ }
+
+ @Override
+ public void runTestOn(String sdkHome) throws Exception {
+ final Sdk sdk = createTempSdk(sdkHome, SdkCreationType.SDK_PACKAGES_AND_SKELETONS);
+ runTestOn(sdk);
+ }
+
+ @Override
+ public Set<String> getTags() {
+ return TAGS;
+ }
+
+ protected abstract void runTestOn(@NotNull Sdk sdk);
+ }
+}