| /* | |
| * Copyright 2000-2014 JetBrains s.r.o. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.jetbrains.python; | |
| import com.intellij.codeInsight.intention.IntentionAction; | |
| import com.intellij.testFramework.LightProjectDescriptor; | |
| import com.intellij.testFramework.TestDataFile; | |
| import com.intellij.testFramework.TestDataPath; | |
| import com.jetbrains.python.fixtures.PyTestCase; | |
| import com.jetbrains.python.inspections.PyAbstractClassInspection; | |
| import com.jetbrains.python.inspections.PyMissingConstructorInspection; | |
| import com.jetbrains.python.inspections.PyStatementEffectInspection; | |
| import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection; | |
| import com.jetbrains.python.psi.LanguageLevel; | |
| import org.jetbrains.annotations.NonNls; | |
| import org.jetbrains.annotations.NotNull; | |
| import java.util.List; | |
| @TestDataPath("$CONTENT_ROOT/../testData/inspections/") | |
| public class Py3QuickFixTest extends PyTestCase { | |
| @Override | |
| protected LightProjectDescriptor getProjectDescriptor() { | |
| return PyTestCase.ourPy3Descriptor; | |
| } | |
| // PY-13685 | |
| public void testReplacePrintEnd() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true)); | |
| } | |
| // PY-13685 | |
| public void testReplacePrintComment() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true)); | |
| } | |
| // PY-13685 | |
| public void testReplaceExecComment() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true)); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperKeywordOnlyParamInSuperInit() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperKeywordOnlyParamInInit() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperSingleStarParamInSuperInit() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperSingleStarParamInSuperInitAndVarargInInit() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-11561 | |
| public void testAddCallSuperTypeAnnotationsPreserved() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-16036, PY-11561 | |
| public void testAddCallSuperSelfNameAndAnnotationPreserved() { | |
| doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperNoRequiredKeywordOnlyParamAfterSingleStarInSuperInit() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-16421 | |
| public void testAddCallSuperSingleStarParamPreserved() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-15867 | |
| public void testAddCallSuperRequiredKeywordOnlyParamAfterSingleStarInSuperInitIsMerged() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, | |
| () -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true)); | |
| } | |
| // PY-16428 | |
| public void testAddParameterNotAvailableInsideAnnotation() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, () -> doInspectionTest(PyUnresolvedReferencesInspection.class, | |
| PyBundle.message("QFIX.unresolved.reference.add.param.$0", "unresolved"), false, false)); | |
| } | |
| // PY-8991 | |
| public void testRemoveUnsupportedPrefixFromGluedStringNodesWithSlash() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, () -> { | |
| myFixture.configureByFile(getTestName(false) + ".py"); | |
| myFixture.checkHighlighting(true, false, false); | |
| final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "F")); | |
| assertNotNull(intentionAction); | |
| myFixture.launchAction(intentionAction); | |
| myFixture.checkResultByFile(getTestName(false) + "_after.py"); | |
| }); | |
| } | |
| // PY-8990 | |
| public void testRemoveUnsupportedPrefixFromGluedStringNodesInParenthesis() { | |
| runWithLanguageLevel(LanguageLevel.PYTHON34, () -> { | |
| myFixture.configureByFile(getTestName(false) + ".py"); | |
| myFixture.checkHighlighting(true, false, false); | |
| final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "F")); | |
| assertNotNull(intentionAction); | |
| myFixture.launchAction(intentionAction); | |
| myFixture.checkResultByFile(getTestName(false) + "_after.py"); | |
| }); | |
| } | |
| // PY-30789 | |
| public void testAddABCToSuperclasses() { | |
| final String[] testFiles = { | |
| "PyAbstractClassInspection/quickFix/AddABCToSuperclasses/main.py", | |
| "PyAbstractClassInspection/quickFix/AddABCToSuperclasses/main_import.py" | |
| }; | |
| doInspectionTest(testFiles, | |
| PyAbstractClassInspection.class, | |
| "Add '" + PyNames.ABC + "' to superclasses", | |
| true, | |
| true); | |
| } | |
| // PY-30789 | |
| public void testAddImportedABCToSuperclasses() { | |
| doInspectionTest("PyAbstractClassInspection/quickFix/AddImportedABCToSuperclasses/main.py", | |
| PyAbstractClassInspection.class, | |
| "Add '" + PyNames.ABC + "' to superclasses", | |
| true, | |
| true); | |
| } | |
| // PY-30789 | |
| public void testSetABCMetaAsMetaclassPy3() { | |
| final String[] testFiles = { | |
| "PyAbstractClassInspection/quickFix/SetABCMetaAsMetaclassPy3/main.py", | |
| "PyAbstractClassInspection/quickFix/SetABCMetaAsMetaclassPy3/main_import.py" | |
| }; | |
| doInspectionTest(testFiles, | |
| PyAbstractClassInspection.class, | |
| "Set '" + PyNames.ABC_META + "' as metaclass", | |
| true, | |
| true); | |
| } | |
| // PY-30789 | |
| public void testSetImportedABCMetaAsMetaclassPy3() { | |
| doInspectionTest("PyAbstractClassInspection/quickFix/SetImportedABCMetaAsMetaclassPy3/main.py", | |
| PyAbstractClassInspection.class, | |
| "Set '" + PyNames.ABC_META + "' as metaclass", | |
| true, | |
| true); | |
| } | |
| @Override | |
| @NonNls | |
| protected String getTestDataPath() { | |
| return PythonTestUtil.getTestDataPath() + "/inspections/"; | |
| } | |
| private void doInspectionTest(@NotNull Class inspectionClass, | |
| @NotNull String quickFixName, | |
| boolean applyFix, | |
| boolean available) { | |
| doInspectionTest(getTestName(false) + ".py", inspectionClass, quickFixName, applyFix, available); | |
| } | |
| protected void doInspectionTest(@TestDataFile @NonNls @NotNull String testFileName, | |
| @NotNull Class inspectionClass, | |
| @NonNls @NotNull String quickFixName, | |
| boolean applyFix, | |
| boolean available) { | |
| doInspectionTest(new String[]{testFileName}, inspectionClass, quickFixName, applyFix, available); | |
| } | |
| /** | |
| * Runs daemon passes and looks for given fix within infos. | |
| * | |
| * @param testFiles names of files to participate; first is used for inspection and then for check by "_after". | |
| * @param inspectionClass what inspection to run | |
| * @param quickFixName how the resulting fix should be named (the human-readable name users see) | |
| * @param applyFix true if the fix needs to be applied | |
| * @param available true if the fix should be available, false if it should be explicitly not available. | |
| * @throws Exception | |
| */ | |
| protected void doInspectionTest(@NonNls String @NotNull [] testFiles, | |
| @NotNull Class inspectionClass, | |
| @NonNls @NotNull String quickFixName, | |
| boolean applyFix, | |
| boolean available) { | |
| myFixture.enableInspections(inspectionClass); | |
| myFixture.configureByFiles(testFiles); | |
| myFixture.checkHighlighting(true, false, false); | |
| final List<IntentionAction> intentionActions = myFixture.filterAvailableIntentions(quickFixName); | |
| if (available) { | |
| if (intentionActions.isEmpty()) { | |
| throw new AssertionError("Quickfix \"" + quickFixName + "\" is not available"); | |
| } | |
| if (intentionActions.size() > 1) { | |
| throw new AssertionError("There are more than one quickfix with the name \"" + quickFixName + "\""); | |
| } | |
| if (applyFix) { | |
| myFixture.launchAction(intentionActions.get(0)); | |
| myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after")); | |
| } | |
| } | |
| else { | |
| assertEmpty("Quick fix \"" + quickFixName + "\" should not be available", intentionActions); | |
| } | |
| } | |
| // Turns "name.ext" to "name_insertion.ext" | |
| @NonNls | |
| private static String graftBeforeExt(String name, String insertion) { | |
| int dotpos = name.indexOf('.'); | |
| if (dotpos < 0) dotpos = name.length(); | |
| return name.substring(0, dotpos) + insertion + name.substring(dotpos); | |
| } | |
| } |