blob: 02882bf2420e26371655746ad60eef0fab4bf92b [file] [log] [blame]
/*
* Copyright 2000-2012 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.intellij.psi.formatter.java;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.util.IncorrectOperationException;
/**
* Is intended to hold java formatting indentation-specific tests.
*
* @author Denis Zhdanov
* @since Apr 27, 2010 6:29:25 PM
*/
public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
public void testClassInitializationBlockIndentation() throws Exception {
// Checking that initialization block body is correctly indented.
doMethodTest(
"checking(new Expectations() {{\n" +
"one(tabConfiguration).addFilter(with(equal(PROPERTY)), with(aListContaining(\"a-c\")));\n" +
"}});",
"checking(new Expectations() {{\n" +
" one(tabConfiguration).addFilter(with(equal(PROPERTY)), with(aListContaining(\"a-c\")));\n" +
"}});"
);
// Checking that closing curly brace of initialization block that is not the first block on a line is correctly indented.
doTextTest("class Class {\n" + " private Type field; {\n" + " }\n" + "}",
"class Class {\n" + " private Type field;\n\n {\n" + " }\n" + "}");
doTextTest(
"class T {\n" +
" private final DecimalFormat fmt = new DecimalFormat(); {\n" +
" fmt.setGroupingUsed(false);\n" +
" fmt.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));\n" +
" }\n" +
"}",
"class T {\n" +
" private final DecimalFormat fmt = new DecimalFormat();\n\n {\n" +
" fmt.setGroupingUsed(false);\n" +
" fmt.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));\n" +
" }\n" +
"}"
);
}
public void testNestedMethodsIndentation() throws Exception {
// Inspired by IDEA-43962
getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 4;
doMethodTest(
"BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
".add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE)))))))));",
"BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE)))))))));"
);
}
public void testShiftedChainedIfElse() throws Exception {
getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2;
getSettings().ELSE_ON_NEW_LINE = true;
getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).INDENT_SIZE = 4;
doMethodTest(
"long a = System.currentTimeMillis();\n" +
" if (a == 0){\n" +
" }else if (a > 1){\n" +
" }else if (a > 2){\n" +
" }else if (a > 3){\n" +
" }else if (a > 4){\n" +
" }else if (a > 5){\n" +
" }else{\n" +
" }",
"long a = System.currentTimeMillis();\n" +
"if (a == 0)\n" +
" {\n" +
" }\n" +
"else if (a > 1)\n" +
" {\n" +
" }\n" +
"else if (a > 2)\n" +
" {\n" +
" }\n" +
"else if (a > 3)\n" +
" {\n" +
" }\n" +
"else if (a > 4)\n" +
" {\n" +
" }\n" +
"else if (a > 5)\n" +
" {\n" +
" }\n" +
"else\n" +
" {\n" +
" }"
);
}
public void testAlignedSubBlockIndentation() {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 8;
// Inspired by IDEA-54671
doTextTest(
"class Test {\n" +
" public void foo() {\n" +
" test(11\n" +
" + 12\n" +
" + 13,\n" +
" 21\n" +
" + 22\n" +
" + 23\n" +
" )" +
" }\n" +
"}",
"class Test {\n" +
" public void foo() {\n" +
" test(11\n" +
" + 12\n" +
" + 13,\n" +
" 21\n" +
" + 22\n" +
" + 23\n" +
" )\n" +
" }\n" +
"}"
);
}
public void testEnumIndentation() throws IncorrectOperationException {
// Inspired by IDEADEV-2840
doTextTest("enum Xyz {\n" + "FOO,\n" + "BAR,\n" + "}", "enum Xyz {\n" + " FOO,\n" + " BAR,\n" + "}");
}
public void testFirstColumnComment() throws IncorrectOperationException {
// Inspired by IDEADEV-14116
getSettings().KEEP_FIRST_COLUMN_COMMENT = false;
doTextTest("class Foo{\n" + "private int foo; // this is a foo\n" + "}",
"class Foo {\n" + " private int foo; // this is a foo\n" + "}");
}
public void testCaseFromSwitch() throws IncorrectOperationException {
// Inspired by IDEADEV-22920
getSettings().INDENT_CASE_FROM_SWITCH = false;
doTextTest(
"class Foo{\n" +
"void foo () {\n" +
"switch(someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
"}\n" +
"}\n" +
"}",
"class Foo {\n" +
" void foo() {\n" +
" switch (someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
" }\n" +
" }\n" +
"}");
}
public void testBinaryExpressionsWithRelativeIndents() {
// Inspired by IDEA-21795
getIndentOptions().USE_RELATIVE_INDENTS = true;
getIndentOptions().CONTINUATION_INDENT_SIZE = 4;
doTextTest(
"public class FormattingTest {\n" +
"\n" +
" public boolean test1(int a, int b, int c, int d) {\n" +
" return a == 1 &&\n" +
" b == 2;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" +
" return a == 0 &&\n" +
" (b == 0 ||\n" +
" c == 0) &&\n" +
" d == 0;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"\n" +
" public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"}",
"public class FormattingTest {\n" +
"\n" +
" public boolean test1(int a, int b, int c, int d) {\n" +
" return a == 1 &&\n" +
" b == 2;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" +
" return a == 0 &&\n" +
" (b == 0 ||\n" +
" c == 0) &&\n" +
" d == 0;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"\n" +
" public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"}"
);
}
public void testBracesShiftedOnNextLineOnMethodWithJavadoc() throws Exception {
// Inspired by IDEA-62997
getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED;
String precededByJavadoc =
"/**\n" +
" * test\n" +
" */\n" +
"public int getFoo()\n" +
" {\n" +
" return foo;\n" +
" }";
String precededBySingleLineComment =
"// test\n" +
"public int getFoo()\n" +
" {\n" +
" return foo;\n" +
" }";
String precededByMultiLineComment =
"/*\n" +
"test\n" +
"*/\n" +
"public int getFoo()\n" +
" {\n" +
" return foo;\n" +
" }";
doClassTest(precededByJavadoc, precededByJavadoc);
doClassTest(precededBySingleLineComment, precededBySingleLineComment);
doClassTest(precededByMultiLineComment, precededByMultiLineComment);
}
public void testAnonymousClassInstancesAsMethodCallArguments() throws Exception {
// Inspired by IDEA-65987
doMethodTest(
"foo(\"long string as the first argument\", new Runnable() {\n" +
"public void run() { \n" +
"} \n" +
"}, \n" +
"new Runnable() { \n" +
"public void run() { \n" +
"} \n" +
"} \n" +
"); ",
"foo(\"long string as the first argument\", new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }\n" +
");"
);
doMethodTest(
"foo(1,\n" +
"2, new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"});",
"foo(1,\n" +
" 2, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" });"
);
doMethodTest(
"foo(new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"},\n" +
"new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"});",
"foo(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" });"
);
}
public void testAnonymousClassInstancesAsAlignedMethodCallArguments() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doMethodTest(
"foo(new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"},\n" +
"new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"});",
"foo(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" });"
);
doMethodTest(
"foo(123456789, new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"},\n" +
"new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}\n" +
"});",
"foo(123456789, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" });"
);
doMethodTest(
"foo(new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}" +
"}, 1, 2);",
"foo(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
"}, 1, 2);"
);
}
public void testAnonymousClassesOnSameLineAtMethodCallExpression() throws Exception {
doMethodTest(
"foo(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" });",
"foo(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"}, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"});"
);
}
public void testAlignMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception {
String text = "test(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"AAA!\");\n" +
" }\n" +
"}, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB!\");\n" +
" }\n" +
"});\n";
doMethodTest(text, text);
}
public void testAlignmentAdditionalParamsWithMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception {
String text = "foo(1221, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"A\");\n" +
" }\n" +
"}, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BB\");\n" +
" }\n" +
"});";
doMethodTest(text, text);
}
public void testAlignmentMultipleParamsWithAnonymousClass_PassedAsMethodParams() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(1000,\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" }\n" +
");";
doMethodTest(text, text);
}
public void testAlignmentMultipleAnonymousClassesOnNewLines() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(1000,\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" }\n" +
");";
doMethodTest(text, text);
}
public void testEnforceChildrenIndent_OfAnonymousClasses_IfAnyOfParamsIsLocatedOnNewLine() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(\"Suuuuuuuuuuuuuuuuuper loooooooooooong string\",\n" +
" \"Next loooooooooooooooooooooong striiiiiiiiiiing\", new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
"\n" +
" }\n" +
" }, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
"\n" +
" }\n" +
" }\n" +
");\n";
doMethodTest(text, text);
}
public void testPackagePrivateAnnotation() {
// Inspired by IDEA-67294
String text =
"@Retention(RUNTIME)\n" +
"@Target({FIELD, PARAMETER, METHOD})\n" +
"@interface MyAnnotation {\n" +
"\n" +
"}";
doTextTest(text, text);
}
public void testIncompleteMethodCall() throws Exception {
// Inspired by IDEA-79836.
doMethodTest(
"test(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }, )",
"test(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"}, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"}, )"
);
}
public void testCStyleCommentIsNotMoved() throws Exception {
// IDEA-87087
doClassTest(
" /*\n" +
" this is a c-style comment\n" +
" */\n" +
" // This is a line comment",
" /*\n" +
" this is a c-style comment\n" +
" */\n" +
"// This is a line comment"
);
}
public void testMultilineCommentAtFileStart() {
// IDEA-90860
String text =
"\n" +
"/*\n" +
" * comment\n" +
" */\n" +
"\n" +
"class Test {\n" +
"}";
doTextTest(text, text);
}
public void testMultilineCommentAndTabsIndent() {
// IDEA-91703
String initial =
"\t/*\n" +
"\t\t* comment\n" +
"\t */\n" +
"class Test {\n" +
"}";
String expected =
"/*\n" +
"\t* comment\n" +
" */\n" +
"class Test {\n" +
"}";
getIndentOptions().USE_TAB_CHARACTER = true;
doTextTest(initial, expected);
}
public void testLambdaIndentation() throws Exception {
String before = "Runnable r = () ->\n" +
"{\n" +
" System.out.println(\"olo\");\n" +
"};";
doMethodTest(before, before);
}
}