    1   /***
    2    *
    3    * Copyright 2005 Jeremy Rayner
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18  package org.codehaus.groovy.antlr.treewalker;
    19
    20  import groovy.util.GroovyTestCase;
    21
    22  import java.io.ByteArrayOutputStream;
    23  import java.io.PrintStream;
    24  import java.io.StringReader;
    25
    26  import org.codehaus.groovy.antlr.AntlrASTProcessor;
    27  import org.codehaus.groovy.antlr.SourceBuffer;
    28  import org.codehaus.groovy.antlr.UnicodeEscapingReader;
    29  import org.codehaus.groovy.antlr.parser.GroovyLexer;
    30  import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
    31
    32  import antlr.collections.AST;
    33
    34  /***
    35   * Testcases for the antlr AST visitor that prints groovy source code.
    36   *
    37   * @author <a href="mailto:groovy@ross-rayner.com">Jeremy Rayner</a>
    38   * @version $Revision: 1.15 $
    39   */
    40  public class SourcePrinterTest extends GroovyTestCase {
    41
    42
    43      public void testAnnotations() throws Exception{
    44          assertEquals("@Property foo", pretty("@Property foo"));
    45      }
    46
    47      public void testAssign() throws Exception {
    48          assertEquals("a = 12", pretty("a=12"));
    49      }
    50
    51      public void testClassDef() throws Exception {
    52          assertEquals("class Foo {def bar}", pretty("class Foo{def bar}"));
    53      }
    54
    55      public void testClosedBlock_FAILS() throws Exception{ if (notYetImplemented()) return;
    56          assertEquals("[1, 2, 3].each {println(it)}", pretty("[1,2,3].each{println it}"));
    57          assertEquals("def x = foo.bar(mooky) {x ->wibble(x)}", pretty("def x = foo.bar(mooky) {x-> wibble(x)}"));
    58      }
    59      public void testCtorIdent() throws Exception {
    60          assertEquals("class Foo {private Foo() {}}", pretty("class Foo {private Foo() {}}"));
    61      }
    62
    63      public void testDot() throws Exception {
    64          assertEquals("foo.bar.mooky()", pretty("foo.bar.mooky()"));
    65      }
    66
    67      public void testElist() throws Exception {
    68          assertEquals("foo(bar, mooky)", pretty("foo( bar , mooky )"));
    69      }
    70
    71      public void testEqual() throws Exception {
    72          assertEquals("a == b", pretty("a==b"));
    73      }
    74
    75      public void testExpr_FAILS() throws Exception { if (notYetImplemented()) return;
    76          assertEquals("foo(bar);mooky(bar)", pretty("foo(bar);mooky(bar)"));
    77      }
    78
    79      public void testExtendsClause() throws Exception {
    80          assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
    81      }
    82      public void testForInIterable() throws Exception {
    83          assertEquals("for (i in [1, 2]) {}", pretty("for (i in [1,2]) {}"));
    84      }
    85      public void testGt() throws Exception {
    86          assertEquals("if (2070 > 354) {}", pretty("if (2070 > 354) {}"));
    87      }
    88
    89      public void testIdent() throws Exception {
    90          assertEquals("foo.bar", pretty("foo.bar"));
    91      }
    92
    93      public void testImplementsClause() throws Exception {
    94          assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
    95      }
    96
    97      public void testImport() throws Exception {
    98          assertEquals("import foo.bar.Wibble", pretty("import foo.bar.Wibble"));
    99      }
    100
    101     public void testIndexOp() throws Exception {
    102         assertEquals("foo.bar()[fred.wilma()]", pretty("foo.bar()[fred.wilma()]"));
    103     }
    104
    105     public void testLabeledArg() throws Exception {
    106         assertEquals("myMethod(argOne:123, argTwo:123)", pretty("myMethod(argOne:123,argTwo:123)"));
    107     }
    108     public void testLand() throws Exception {
    109         assertEquals("true && false", pretty("true && false"));
    110     }
    111     public void testListConstructor() throws Exception {
    112         assertEquals("[a, b]", pretty("[a,b]"));
    113     }
    114
    115     public void testLiteralAssert() throws Exception {
    116         assertEquals("assert a == true", pretty("assert a== true"));
    117     }
    118
    119     public void testLiteralBoolean() throws Exception {
    120         assertEquals("boolean b = true", pretty("boolean b =true"));
    121     }
    122
    123     public void testLiteralCatch() throws Exception {
    124         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
    125     }
    126
    127     public void testLiteralFalse() throws Exception {
    128         assertEquals("if (false) {}", pretty("if (false) {}"));
    129     }
    130
    131     public void testLiteralFloat() throws Exception {
    132         assertEquals("float x", pretty("float x"));
    133     }
    134
    135     public void testLiteralFor() throws Exception {
    136         assertEquals("for (i in [1, 2, 3]) {}", pretty("for (i in [1,2,3]) {}"));
    137     }
    138
    139     public void testLiteralIf() throws Exception {
    140         assertEquals("if (a == b) return false", pretty("if (a==b) return false"));
    141         assertEquals("if (a == b) {}", pretty("if (a==b) {}"));
    142     }
    143
    144     public void testLiteralInstanceOf() throws Exception {
    145         assertEquals("if (a instanceof String) {}", pretty("if (a instanceof String) {}"));
    146     }
    147     public void testLiteralInt() throws Exception {
    148         assertEquals("int a", pretty("int a"));
    149     }
    150
    151     public void testLiteralNew() throws Exception {
    152         assertEquals("new Foo()", pretty("new Foo()"));
    153     }
    154
    155     public void testLiteralNull() throws Exception {
    156         assertEquals("def foo = null", pretty("def foo=null"));
    157     }
    158
    159     public void testLiteralPrivate() throws Exception{
    160         assertEquals("private bar", pretty("private bar"));
    161     }
    162
    163     public void testLiteralProtected() throws Exception{
    164         assertEquals("protected mooky", pretty("protected mooky"));
    165     }
    166
    167     public void testLiteralPublic() throws Exception{
    168         assertEquals("public foo", pretty("public foo"));
    169     }
    170
    171     public void testLiteralReturn() throws Exception {
    172         assertEquals("def foo() {return false}", pretty("def  foo() { return false }"));
    173     }
    174
    175     public void testLiteralStatic() throws Exception {
    176         assertEquals("static void foo() {}", pretty("static void foo() {}"));
    177     }
    178
    179     public void testLiteralThis() throws Exception {
    180         assertEquals("this.x = this.y", pretty("this.x=this.y"));
    181     }
    182     public void testLiteralThrow() throws Exception {
    183         assertEquals("def foo() {if (false) throw new RuntimeException()}", pretty("def foo() {if (false) throw new RuntimeException()}"));
    184     }
    185     public void testLiteralTrue() throws Exception {
    186         assertEquals("foo = true", pretty("foo = true"));
    187     }
    188
    189     public void testLiteralTry() throws Exception {
    190         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
    191     }
    192
    193     public void testLiteralVoid_FAILS() throws Exception { if (notYetImplemented()) return;
    194         assertEquals("void foo() {}", pretty("void foo(){}"));
    195     }
    196
    197     public void testLiteralWhile() throws Exception {
    198         assertEquals("while (true) {}", pretty("while(true){}"));
    199     }
    200
    201     public void testLnot() throws Exception {
    202             assertEquals("if (!isRaining) {}", pretty("if (!isRaining) {}"));
    203         }
    204
    205     public void testLt() throws Exception {
    206         assertEquals("if (3.4f < 12f) {}", pretty("if (3.4f < 12f) {}"));
    207     }
    208     public void testMapConstructor() throws Exception{
    209         assertEquals("Map foo = [:]", pretty("Map foo = [:]"));
    210         assertEquals("[a:1, b:2]", pretty("[a:1,b:2]"));
    211     }
    212
    213     public void testMemberPointer() throws Exception {
    214         assertEquals("def x = foo.&bar()", pretty("def x=foo.&bar()"));
    215     }
    216     public void testMethodCall() throws Exception {
    217         assertEquals("foo(bar)", pretty("foo(bar)"));
    218         assertEquals("[1, 2, 3].each {println(it)}", pretty("[1,2,3].each{println it}"));
    219         assertEquals("foo(bar){mooky()}", pretty("foo(bar){mooky()}"));
    220     }
    221
    222     public void testMethodDef_FAILS() throws Exception{ if (notYetImplemented()) return;
    223         assertEquals("def foo(int bar, boolean boo) {}", pretty("def foo(int bar,boolean boo) {}"));
    224         assertEquals("void foo(){} void bar(){}", pretty("void foo(){} void bar(){}"));
    225     }
    226
    227     public void testMinus() throws Exception {
    228         assertEquals("def bar = 4 - foo", pretty("def bar=4-foo"));
    229     }
    230
    231     public void testModifiers() throws Exception {
    232         assertEquals("", pretty(""));
    233     }
    234     public void testNotEqual() throws Exception {
    235         assertEquals("a != b", pretty("a!=b"));
    236     }
    237     public void testNumInt() throws Exception {
    238         assertEquals("a = 12", pretty("a=12"));
    239     }
    240
    241     public void testNumFloat() throws Exception {
    242         assertEquals("b = 34.4f", pretty("b=34.4f"));
    243     }
    244
    245     public void testObjblock() throws Exception {
    246         assertEquals("class Foo {def bar}", pretty("class Foo {def bar}"));
    247     }
    248
    249     public void testPackageDef() throws Exception {
    250         assertEquals("package foo.bar", pretty("package foo.bar"));
    251     }
    252
    253     public void testParameterDef() throws Exception {
    254         assertEquals("", pretty(""));
    255     }
    256
    257     public void testParameters() throws Exception {
    258         assertEquals("", pretty(""));
    259     }
    260     public void testPlus() throws Exception {
    261         assertEquals("a + b", pretty("a+b"));
    262     }
    263     public void testQuestion() throws Exception {
    264         assertEquals("foo == bar?10:20", pretty("foo==bar?10:20"));
    265     }
    266     public void testRangeExclusive() throws Exception {
    267         assertEquals("foo[45..<89]", pretty("foo[45 ..< 89]"));
    268     }
    269     public void testRangeInclusive() throws Exception {
    270         assertEquals("foo[bar..12]", pretty("foo[bar .. 12]"));
    271     }
    272     public void testSlist() throws Exception {
    273         assertEquals("if (true) {foo}", pretty("if (true) {foo}"));
    274     }
    275
    276     public void testStar() throws Exception {
    277         assertEquals("import foo.*", pretty("import foo.*"));
    278         assertEquals("a*b", pretty("a*b"));
    279     }
    280
    281     public void testStringConstructor() throws Exception{
    282         assertEquals("\"foo$bar\"", pretty("\"foo$bar\""));
    283     }
    284
    285     public void testStringLiteral_FAILS() throws Exception{ if (notYetImplemented()) return;
    286         assertEquals("\"mooky\"", pretty("\"mooky\""));
    287         assertEquals("'mooky'", pretty("'mooky'"));
    288     }
    289
    290     public void testType() throws Exception {
    291         assertEquals("String bar", pretty("String bar"));
    292     }
    293
    294     public void testTypecast() throws Exception {
    295         assertEquals("foo = (String)bar", pretty("foo = (String)bar"));
    296     }
    297
    298     public void testVariableDef() throws Exception {
    299         assertEquals("def x = 1", pretty("def x = 1"));
    300     }
    301
    302     public String pretty(String input) throws Exception{
    303         GroovyRecognizer parser = null;
    304         SourceBuffer sourceBuffer = new SourceBuffer();
    305         UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
    306         GroovyLexer lexer = new GroovyLexer(unicodeReader);
    307         unicodeReader.setLexer(lexer);
    308         parser = GroovyRecognizer.make(lexer);
    309         parser.setSourceBuffer(sourceBuffer);
    310
    311         String[] tokenNames;
    312         tokenNames = parser.getTokenNames();
    313         parser.compilationUnit();
    314         AST ast = parser.getAST();
    315
    316         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    317         Visitor visitor = new SourcePrinter(new PrintStream(baos),tokenNames,false);
    318         AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
    319
    320         traverser.process(ast);
    321
    322         return new String(baos.toByteArray());
    323     }
    324
    325 }