| 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); |
| } |
| } |