1/*
2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21
22package com.github.javaparser.printer;
23
24import com.github.javaparser.JavaParser;
25import com.github.javaparser.ast.CompilationUnit;
26import com.github.javaparser.ast.Node;
27import com.github.javaparser.ast.body.MethodDeclaration;
28import com.github.javaparser.ast.comments.LineComment;
29import com.github.javaparser.ast.expr.CastExpr;
30import com.github.javaparser.ast.expr.ClassExpr;
31import com.github.javaparser.ast.expr.Expression;
32import com.github.javaparser.ast.expr.VariableDeclarationExpr;
33import com.github.javaparser.ast.type.Type;
34import org.junit.Test;
35
36import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
37import static com.github.javaparser.utils.Utils.EOL;
38import static org.junit.Assert.assertEquals;
39
40public class PrettyPrintVisitorTest {
41
42    @Test
43    public void getMaximumCommonTypeWithoutAnnotations() {
44        VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a[], b[]");
45        assertEquals("int[]", vde1.getMaximumCommonType().get().toString());
46
47        VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[][] a[], b[]");
48        assertEquals("int[][][]", vde2.getMaximumCommonType().get().toString());
49
50        VariableDeclarationExpr vde3 = JavaParser.parseVariableDeclarationExpr("int[][] a, b[]");
51        assertEquals("int[][]", vde3.getMaximumCommonType().get().toString());
52    }
53
54    @Test
55    public void getMaximumCommonTypeWithAnnotations() {
56        VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a @Foo [], b[]");
57        assertEquals("int", vde1.getMaximumCommonType().get().toString());
58
59        VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[]@Foo [] a[], b[]");
60        assertEquals("int[] @Foo [][]", vde2.getMaximumCommonType().get().toString());
61    }
62
63    private String print(Node node) {
64        return new PrettyPrinter().print(node);
65    }
66
67    @Test
68    public void printSimpleClassExpr() {
69        ClassExpr expr = JavaParser.parseExpression("Foo.class");
70        assertEquals("Foo.class", print(expr));
71    }
72
73    @Test
74    public void printArrayClassExpr() {
75        ClassExpr expr = JavaParser.parseExpression("Foo[].class");
76        assertEquals("Foo[].class", print(expr));
77    }
78
79    @Test
80    public void printGenericClassExpr() {
81        ClassExpr expr = JavaParser.parseExpression("Foo<String>.class");
82        assertEquals("Foo<String>.class", print(expr));
83    }
84
85    @Test
86    public void printSimplestClass() {
87        Node node = JavaParser.parse("class A {}");
88        assertEquals("class A {" + EOL +
89                "}" + EOL, print(node));
90    }
91
92    @Test
93    public void printAClassWithField() {
94        Node node = JavaParser.parse("class A { int a; }");
95        assertEquals("class A {" + EOL
96                + EOL +
97                "    int a;" + EOL +
98                "}" + EOL, print(node));
99    }
100
101    @Test
102    public void printAReceiverParameter() {
103        Node node = JavaParser.parseBodyDeclaration("int x(@O X A.B.this, int y) { }");
104        assertEquals("int x(@O X A.B.this, int y) {" + EOL + "}", print(node));
105    }
106
107    @Test
108    public void printLambdaIntersectionTypeAssignment() {
109        String code = "class A {" + EOL +
110                "  void f() {" + EOL +
111                "    Runnable r = (Runnable & Serializable) (() -> {});" + EOL +
112                "    r = (Runnable & Serializable)() -> {};" + EOL +
113                "    r = (Runnable & I)() -> {};" + EOL +
114                "  }}";
115        CompilationUnit cu = JavaParser.parse(code);
116        MethodDeclaration methodDeclaration = (MethodDeclaration) cu.getType(0).getMember(0);
117
118        assertEquals("Runnable r = (Runnable & Serializable) (() -> {" + EOL + "});", print(methodDeclaration.getBody().get().getStatements().get(0)));
119    }
120
121    @Test
122    public void printIntersectionType() {
123        String code = "(Runnable & Serializable) (() -> {})";
124        Expression expression = JavaParser.parseExpression(code);
125        Type type = ((CastExpr) expression).getType();
126
127        assertEquals("Runnable & Serializable", print(type));
128    }
129
130    @Test
131    public void printLambdaIntersectionTypeReturn() {
132        String code = "class A {" + EOL
133                + "  Object f() {" + EOL
134                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
135                + "}}";
136        CompilationUnit cu = JavaParser.parse(code);
137        MethodDeclaration methodDeclaration = (MethodDeclaration) cu.getType(0).getMember(0);
138
139        assertEquals("return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey());", print(methodDeclaration.getBody().get().getStatements().get(0)));
140    }
141
142    @Test
143    public void printClassWithoutJavaDocButWithComment() {
144        String code = String.format("/** javadoc */ public class A { %s// stuff%s}", EOL, EOL);
145        CompilationUnit cu = JavaParser.parse(code);
146        PrettyPrinterConfiguration ignoreJavaDoc = new PrettyPrinterConfiguration().setPrintJavadoc(false);
147        String content = cu.toString(ignoreJavaDoc);
148        assertEquals(String.format("public class A {%s    // stuff%s}%s", EOL, EOL, EOL), content);
149    }
150
151    @Test
152    public void printImportsDefaultOrder() {
153        String code = "import x.y.z;import a.b.c;import static b.c.d;class c {}";
154        CompilationUnit cu = JavaParser.parse(code);
155        String content = cu.toString();
156        assertEqualsNoEol("import x.y.z;\n" +
157                "import a.b.c;\n" +
158                "import static b.c.d;\n" +
159                "\n" +
160                "class c {\n" +
161                "}\n", content);
162    }
163
164    @Test
165    public void printImportsOrdered() {
166        String code = "import x.y.z;import a.b.c;import static b.c.d;class c {}";
167        CompilationUnit cu = JavaParser.parse(code);
168        PrettyPrinterConfiguration orderImports = new PrettyPrinterConfiguration().setOrderImports(true);
169        String content = cu.toString(orderImports);
170        assertEqualsNoEol("import static b.c.d;\n" +
171                "import a.b.c;\n" +
172                "import x.y.z;\n" +
173                "\n" +
174                "class c {\n" +
175                "}\n", content);
176    }
177
178    @Test
179    public void multilineJavadocGetsFormatted() {
180        CompilationUnit cu = new CompilationUnit();
181        cu.addClass("X").addMethod("abc").setJavadocComment("line1\n   line2 *\n * line3");
182
183        assertEqualsNoEol("public class X {\n" +
184                "\n" +
185                "    /**\n" +
186                "     * line1\n" +
187                "     *   line2 *\n" +
188                "     * line3\n" +
189                "     */\n" +
190                "    void abc() {\n" +
191                "    }\n" +
192                "}\n", cu.toString());
193    }
194
195    @Test
196    public void emptyJavadocGetsFormatted() {
197        CompilationUnit cu = new CompilationUnit();
198        cu.addClass("X").addMethod("abc").setJavadocComment("");
199
200        assertEqualsNoEol("public class X {\n" +
201                "\n" +
202                "    /**\n" +
203                "     */\n" +
204                "    void abc() {\n" +
205                "    }\n" +
206                "}\n", cu.toString());
207    }
208
209    @Test
210    public void multilineJavadocWithLotsOfEmptyLinesGetsFormattedNeatly() {
211        CompilationUnit cu = new CompilationUnit();
212        cu.addClass("X").addMethod("abc").setJavadocComment("\n\n\n ab\n\n\n cd\n\n\n");
213
214        assertEqualsNoEol("public class X {\n" +
215                "\n" +
216                "    /**\n" +
217                "     * ab\n" +
218                "     *\n" +
219                "     * cd\n" +
220                "     */\n" +
221                "    void abc() {\n" +
222                "    }\n" +
223                "}\n", cu.toString());
224    }
225
226    @Test
227    public void singlelineJavadocGetsFormatted() {
228        CompilationUnit cu = new CompilationUnit();
229        cu.addClass("X").addMethod("abc").setJavadocComment("line1");
230
231        assertEqualsNoEol("public class X {\n" +
232                "\n" +
233                "    /**\n" +
234                "     * line1\n" +
235                "     */\n" +
236                "    void abc() {\n" +
237                "    }\n" +
238                "}\n", cu.toString());
239    }
240
241    @Test
242    public void singlelineCommentGetsFormatted() {
243        CompilationUnit cu = new CompilationUnit();
244        cu.addClass("X").addMethod("abc").setComment(new LineComment("   line1  \n "));
245
246        assertEqualsNoEol("public class X {\n" +
247                "\n" +
248                "    // line1\n" +
249                "    void abc() {\n" +
250                "    }\n" +
251                "}\n", cu.toString());
252    }
253
254    @Test
255    public void blockcommentGetsNoFormatting() {
256        CompilationUnit cu = JavaParser.parse("class A {\n" +
257                "    public void helloWorld(String greeting, String name) {\n" +
258                "        //sdfsdfsdf\n" +
259                "            //sdfds\n" +
260                "        /*\n" +
261                "                            dgfdgfdgfdgfdgfd\n" +
262                "         */\n" +
263                "    }\n" +
264                "}\n");
265
266        assertEqualsNoEol("class A {\n" +
267                "\n" +
268                "    public void helloWorld(String greeting, String name) {\n" +
269                "    // sdfsdfsdf\n" +
270                "    // sdfds\n" +
271                "    /*\n" +
272                "                            dgfdgfdgfdgfdgfd\n" +
273                "         */\n" +
274                "    }\n" +
275                "}\n", cu.toString());
276    }
277}
278