/* * Copyright 2000-2013 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.openapi.command.WriteCommandAction; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.formatter.PyCodeStyleSettings; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyStatement; import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher; /** * @author yole */ public class PyFormatterTest extends PyTestCase { public void testBlankLineBetweenMethods() { doTest(); } public void testBlankLineAroundClasses() { CodeStyleSettingsManager.getSettings(myFixture.getProject()).BLANK_LINES_AROUND_CLASS = 2; doTest(); } public void testSpaceAfterComma() { doTest(); } public void testPep8ExtraneousWhitespace() { doTest(); } public void testPep8Operators() { doTest(); } public void testPep8KeywordArguments() { doTest(); } public void testUnaryMinus() { doTest(); } public void testBlankLineAfterImports() { doTest(); } public void testBlankLineBeforeFunction() { doTest(); } public void testStarArgument() { // PY-1395 doTest(); } public void testDictLiteral() { // PY-1461 doTest(); } public void testListAssignment() { // PY-1522 doTest(); } public void testStarExpression() { // PY-1523 doTestPy3(); } private void doTestPy3() { PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON30); try { doTest(); } finally { PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null); } } public void testWrapTuple() { // PY-1792 doTest(); } public void testSpaceAfterCommaWrappedLine() { // PY-1065 doTest(); } public void testAlignInBinaryExpression() { doTest(); } public void testAlignInStringLiteral() { doTest(); } public void testComment() { // PY-2108 doTest(); } public void testCommentBetweenClasses() { // PY-1598 doTest(); } public void testCommentInEmptyTuple() { //PY-11904 doTest(); } public void testTwoLinesBetweenTopLevelClasses() { // PY-2765 doTest(); } public void testTwoLinesBetweenTopLevelFunctions() { // PY-2765 doTest(); } public void testTwoLinesBetweenTopLevelDeclarationsWithComment() { // PY-9923 doTest(); } public void testSpecialSlice() { // PY-1928 doTest(); } public void testNoWrapBeforeParen() { // PY-3172 doTest(); } public void testTupleAssignment() { // PY-4034 comment doTest(); } public void testSpaceInMethodDeclaration() { // PY-4241 settings().SPACE_BEFORE_METHOD_PARENTHESES = true; doTest(); } public void testOptionalAlignForMethodParameters() { // PY-3995 settings().ALIGN_MULTILINE_PARAMETERS = false; doTest(); } public void testNoAlignForMethodArguments() { // PY-3995 settings().getCommonSettings(PythonLanguage.getInstance()).ALIGN_MULTILINE_PARAMETERS_IN_CALLS = false; doTest(); } public void testAlignForMethodArguments() { // PY-3995 doTest(); } public void testLambdaColon() { doTest(); } public void testInGenerator() { // PY-5379 doTest(); } public void testIndentInGenerator() { // PY-6219 doTest(); } public void testSpaceAroundDot() { // PY-6908 doTest(); } public void testSetLiteralInArgList() { // PY-6672 settings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest(); } public void testLiterals() { // PY-6751 doTest(); } public void testTupleInArgList() { settings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest(); } public void testAlignInBinaryExpressions() { doTest(); } public void testFromImportRelative() { doTest(); } public void testContinuationIndent() { doTest(); } public void testContinuationIndentInIndentingStatement() { // PY-9573 doTest(); } public void testContinuationIndentInIndentingStatement2() { // PY-11868 doTest(); } public void testBlankLineAfterDecorator() { doTest(); } public void testSpaceAroundKeywords() { doTest(); } public void testSpaceAfterReturn() { doTest(); } public void testSpaceAfterRelativeImport() { // PY-8112 doTest(); } public void testSpaceWithinBraces() { // PY-8069 settings().getCustomSettings(PyCodeStyleSettings.class).SPACE_WITHIN_BRACES = true; doTest(); } public void testTupleClosingParen() { // PY-7946 doTest(); } public void testBeforeTopLevelClass() { // PY-7743 doTest(); } public void testPsiFormatting() { // IDEA-69724 String initial = "def method_name(\n" + " desired_impulse_response,\n" + " desired_response_parameters,\n" + " inverse_filter_length, \n" + " observed_impulse_response):\n" + " # Extract from here to ...\n" + " desired_impulse_response = {'dirac, 'gaussian', logistic_derivative'}\n" + "return desired, o"; final PsiFile file = PyElementGenerator.getInstance(myFixture.getProject()).createDummyFile(LanguageLevel.PYTHON30, initial); final PsiElement reformatted = CodeStyleManager.getInstance(myFixture.getProject()).reformat(file); String expected = "def method_name(\n" + " desired_impulse_response,\n" + " desired_response_parameters,\n" + " inverse_filter_length,\n" + " observed_impulse_response):\n" + " # Extract from here to ...\n" + " desired_impulse_response = {'dirac, '\n" + " gaussian\n" + " ', logistic_derivative'}\n" + " return desired, o"; assertEquals(expected, reformatted.getText()); } public void testWrapDefinitionWithLongLine() { // IDEA-92081 settings().setRightMargin(PythonLanguage.getInstance(), 30); settings().WRAP_LONG_LINES = true; doTest(); } public void testWrapAssignment() { // PY-8572 settings().setRightMargin(PythonLanguage.getInstance(), 120); settings().WRAP_LONG_LINES = false; doTest(); } public void testIndentInSlice() { // PY-8572 settings().setRightMargin(PythonLanguage.getInstance(), 120); settings().WRAP_LONG_LINES = false; doTest(); } public void testIndentInComprehensions() { // PY-8516 settings().getCustomSettings(PyCodeStyleSettings.class).ALIGN_COLLECTIONS_AND_COMPREHENSIONS = false; doTest(); } public void testAlignInGenerators() { // PY-8822 doTest(); } public void testAlignInCallExpression() { doTest(); } public void _testAlignInNestedCallInWith() { //PY-11337 TODO: doTest(); } public void testContinuationIndentForCallInStatementPart() { // PY-8577 doTest(); } public void testIfConditionContinuation() { // PY-8195 doTest(); } public void _testIndentInNestedCall() { // PY-11919 TODO: required changes in formatter to be able to make indent relative to block or alignment doTest(); } public void testIndentAfterBackslash() { doTest(); } public void testSpaceBeforeBackslash() { settings().getCustomSettings(PyCodeStyleSettings.class).SPACE_BEFORE_BACKSLASH = false; doTest(); } public void testNewLineAfterColon() { settings().getCustomSettings(PyCodeStyleSettings.class).NEW_LINE_AFTER_COLON = true; doTest(); } public void testNewLineAfterColonMultiClause() { doTest(); } public void testLongWith() { // PY-8743 PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON27); try { doTest(); } finally { PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null); } } public void testSpaceInAnnotations() { // PY-8961 doTestPy3(); } public void testWrapInBinaryExpression() { // PY-9032 settings().setRightMargin(PythonLanguage.getInstance(), 80); doTest(true); } public void testSpaceWithinDeclarationParentheses() { // PY-8818 settings().SPACE_WITHIN_METHOD_PARENTHESES = true; doTest(); } public void testWrapBeforeElse() { // PY-10319 doTest(true); } public void testSpacesInImportParentheses() { // PY-11359 doTest(); } public void testWrapImports() { // PY-9163 settings().setRightMargin(PythonLanguage.getInstance(), 80); doTest(); } public void testCommentAfterBlock() { // PY-9542 doTest(); } public void testWrapOnDot() { // PY-6359 doTest(); } public void testIndentParensInImport() { // PY-9075 doTest(); } public void testAlignInParenthesizedExpression() { doTest(); } public void testAlignInParameterList() { doTest(); } public void testAlignListComprehensionInDict() { //PY-10076 doTest(); } public void testShebang() { //PY-12775 doTest(); } private void doTest() { doTest(false); } private void doTest(final boolean reformatText) { myFixture.configureByFile("formatter/" + getTestName(true) + ".py"); WriteCommandAction.runWriteCommandAction(null, new Runnable() { @Override public void run() { CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myFixture.getProject()); PsiFile file = myFixture.getFile(); if (reformatText) { codeStyleManager.reformatText(file, 0, file.getTextLength()); } else { codeStyleManager.reformat(file); } } }); myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.py"); } /** * This test merely checks that call to {@link com.intellij.psi.codeStyle.CodeStyleManager#reformat(com.intellij.psi.PsiElement)} * is possible for Python sources. */ public void testReformatOfSingleElementPossible() { myFixture.configureByFile("formatter/" + getTestName(true) + ".py"); WriteCommandAction.runWriteCommandAction(myFixture.getProject(), new Runnable() { @Override public void run() { final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); assertNotNull(elementAtCaret); final PyStatement statement = PsiTreeUtil.getParentOfType(elementAtCaret, PyStatement.class, false); assertNotNull(statement); final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myFixture.getProject()); codeStyleManager.reformat(statement); } }); myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.py"); } private CodeStyleSettings settings() { return CodeStyleSettingsManager.getInstance().getSettings(myFixture.getProject()); } }