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: 4653 $
39   */
40  public class SourcePrinterTest extends GroovyTestCase {
41  
42  	public void testAbstract() throws Exception {
43  		assertEquals("public abstract class Foo {}", pretty("public abstract class Foo{}"));
44  	}
45  	
46      public void testAnnotation() throws Exception{
47          assertEquals("@Crimson foo", pretty("@Crimson foo"));
48          assertEquals("@Override int hashCode() {return 0}", pretty("@Override int hashCode() {return 0}"));
49      }
50      
51      public void testAnnotations() throws Exception{
52      	assertEquals("@Important @Blue package foo.bar",pretty("@Important @Blue package foo.bar"));
53      }
54  
55      public void testAnnotationArrayInit() throws Exception{
56      	// obsolete java syntax
57      }
58      
59      public void testAnnotationDef() throws Exception{
60      	// todo - 17 July 2006 - test fine, however this parses but causes error in AntlrParserPlugin
61          assertEquals("public @interface Foo{}", pretty("public @interface Foo{}"));
62      }
63      
64      public void testAnnotationFieldDef() throws Exception{
65      	assertEquals("public @interface Foo{int bar() default 123}", pretty("public @interface Foo{int bar() default 123}"));
66      }
67      
68      public void testAnnotationMemberValuePair() throws Exception{
69      	assertEquals("@Prime(value = 17) int foo",pretty("@Prime(value=17) int foo"));
70      	assertEquals("@Blue(v = 3, v = 5) int bar",pretty("@Blue(v = 3, v = 5) int bar"));
71      }
72      
73      public void testArrayDeclarator() throws Exception {
74      	assertEquals("int[] primes = new int[5]", pretty("int[] primes = new int[5]"));
75      }
76      
77      public void testAssign() throws Exception {
78          assertEquals("a = 12", pretty("a=12"));
79      }
80      
81      public void testBand() throws Exception {
82      	assertEquals("def x = 1 & 2", pretty("def x=1&2"));
83      }
84  
85      public void testBandAssign() throws Exception {
86      	assertEquals("x &= 2", pretty("x&=2"));
87      }
88      
89      public void testBnot() throws Exception {
90      	assertEquals("def z = ~123", pretty("def z = ~123"));
91      }
92      
93      public void testBor() throws Exception {
94      	assertEquals("def y = 1 | 2", pretty("def y = 1 | 2"));
95      }
96      
97      public void testBorAssign() throws Exception {
98      	assertEquals("y |= 2", pretty("y|=2"));
99      }
100 
101     public void testBsr() throws Exception {
102     	// unsigned right shift
103     	assertEquals("def q = 1 >>> 2", pretty("def q = 1 >>> 2"));
104     }
105 
106     public void testBsrAssign() throws Exception {
107     	assertEquals("y >>>= 2", pretty("y>>>=2"));
108     }
109     
110     public void testBxor() throws Exception {
111     	assertEquals("def y = true ^ false", pretty("def y = true ^ false"));
112     }
113     
114     public void testBxorAssign() throws Exception {
115     	assertEquals("y ^= false", pretty("y^=false"));
116     }
117 
118     public void testCaseGroup() throws Exception {
119         assertEquals("switch (foo) {case bar:x = 1}", pretty("switch(foo){case bar:x=1}"));
120     }
121     
122     public void testClassDef() throws Exception {
123         assertEquals("class Foo {def bar}", pretty("class Foo{def bar}"));
124     }
125 
126     public void testClosedBlock() throws Exception{
127         assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
128         assertEquals("def x = foo.bar(mooky){ x, y -> wibble(y, x)}", pretty("def x = foo.bar(mooky) {x,y-> wibble(y,x)}"));
129         // todo: above is not quite the spacing I would expect, but good enough for now...
130     }
131     
132     public void testCompareTo() throws Exception{
133     	assertEquals("1 <=> 2", pretty("1<=>2"));
134     }
135     
136     public void testCtorCall() throws Exception{
137     	assertEquals("class Foo {Foo(int x) {this()}}",pretty("class Foo{Foo(int x) {this()}}"));
138     	assertEquals("class Foo {Foo( x) {this()}}",pretty("class Foo{Foo(x) {this()}}"));
139         // todo: above is not quite the spacing I would expect, but good enough for now...
140     }
141     
142     public void testCtorIdent() throws Exception {
143         assertEquals("class Foo {private Foo() {}}", pretty("class Foo {private Foo() {}}"));
144     }
145     
146     public void testDec() throws Exception {
147     	assertEquals("--b", pretty("--b"));
148     }
149 
150     public void testDiv() throws Exception {
151     	assertEquals("1 / 2", pretty("1/2"));
152     }
153     
154     public void testDivAssign() throws Exception {
155     	assertEquals("x /= 2", pretty("x/=2"));
156     }
157     
158     public void testDot() throws Exception {
159     	assertEquals("java.util.Date d = new java.util.Date()", pretty("java.util.Date d = new java.util.Date()"));
160     	assertEquals("class Foo extends java.util.Date {}", pretty("class Foo extends java.util.Date {}"));
161     	assertEquals("foo.bar.mooky()", pretty("foo.bar.mooky()"));
162     	assertEquals("package foo.bar", pretty("package foo.bar"));
163     	assertEquals("import java.util.Date", pretty("import java.util.Date"));
164     	assertEquals("import java.io.*", pretty("import java.io.*"));
165     	assertEquals("@foo.Bar mooky", pretty("@foo.Bar mooky"));
166     	assertEquals("def foo() throws bar.MookyException{}", pretty("def foo() throws bar.MookyException{}"));
167     	assertEquals("def x = \"${foo.bar}\"", pretty("def x = \"${foo.bar}\""));
168     }
169     
170     public void testDynamicMember() throws Exception{
171     	assertEquals("foo.(bar)", pretty("foo.(bar)"));
172     	assertEquals("foo.\"${bar}\"", pretty("foo.\"${bar}\""));
173     }
174     
175     public void testElist() throws Exception {
176     	assertEquals("println 2 + 2", pretty("println 2 + 2"));
177     	assertEquals("for (i = 0, j = 2 ; i < 10 ; i++, j--){print i}", pretty("for (i = 0,j = 2;i < 10; i++, j--) {print i}"));
178     	assertEquals("foo()", pretty("foo()")); // empty ELIST
179     	assertEquals("foo(bar, mooky)", pretty("foo( bar , mooky )"));
180     }
181 
182     public void testEnumConstantDef() throws Exception {
183     	assertEquals("enum Coin {PENNY(1), DIME(10), QUARTER(25)}", pretty("enum Coin {PENNY(1), DIME(10), QUARTER(25)}"));
184     }
185 
186     public void testEnumDef() throws Exception {
187     	assertEquals("enum Season {WINTER, SPRING, SUMMER, AUTUMN}", pretty("enum Season{WINTER,SPRING,SUMMER,AUTUMN}"));
188     	//todo: more strange spacing in following line
189     	assertEquals("enum Operation {ADDITION{double eval( x,  y) {return x + y}}}",pretty("enum Operation {ADDITION {double eval(x,y) {return x + y}}}"));    	
190     }
191     
192     public void testEqual() throws Exception {
193         assertEquals("a == b", pretty("a==b"));
194     }
195 
196     public void testEsc_FAILS() throws Exception { if (notYetImplemented()) return;
197     	// dquote-tab-dquote
198     	assertEquals("println \"//\"\t//\"\"", pretty("println \"//\"\t//\"\""));
199     }
200     
201     public void testExponent() throws Exception {
202     	assertEquals("println 1.2e-10", pretty("println 1.2e-10"));
203     }
204     
205     public void testExpr_FAILS() throws Exception { if (notYetImplemented()) return;
206     	assertEquals("System.out.println(x)", pretty("System.out.println(x)"));
207     	assertEquals("return f", pretty("return f"));
208         assertEquals("foo(bar);mooky(bar)", pretty("foo(bar);mooky(bar)"));
209     }
210 
211     public void testExtendsClause() throws Exception {
212         assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
213         assertEquals("interface Wibble extends Mooky{}", pretty("interface Wibble extends Mooky {}"));
214         //todo spacing is odd, c.f. last space in class vs interface above
215     }
216     
217     public void testFinal() throws Exception {
218     	assertEquals("public final int getX() {return 0}", pretty("public final int getX() {return 0}"));
219     }
220     public void testForCondition() throws Exception {
221     	assertEquals("for (i = 0 ; i < 10 ; i++){println i}", pretty("for (i=0;i<10;i++) {println i}"));
222     }
223     
224     // testForInit() covered by testForCondition()
225     
226     public void testForInIterable() throws Exception {
227         assertEquals("for (i in [1, 2]) {}", pretty("for (i in [1,2]) {}"));
228     }
229 
230     // testForIterator() covered by testForCondition()
231     
232     public void testGe() throws Exception {
233     	assertEquals("if (60 >= 70) {}", pretty("if (60>=70) {}"));
234     }
235     
236     public void testGt() throws Exception {
237         assertEquals("if (2070 > 354) {}", pretty("if (2070 > 354) {}"));
238     }
239 
240     public void testHexDigit() throws Exception {
241         assertEquals("def bar = 0xCaFe", pretty("def bar = 0xCaFe"));    	
242     }
243     public void testHexDigitInUnicodeEscape_FAILS() throws Exception { if (notYetImplemented()) return;
244       assertEquals("def foo = '//ubabe'", pretty("def foo = '//ubabe'"));
245     }
246     
247     public void testIdent() throws Exception {
248     	// used _everywhere_ , lets assume that the other specific 
249     	// testcases include enough ident usage for now.
250         assertEquals("foo.bar", pretty("foo.bar"));
251     }
252 
253     public void testImplementsClause() throws Exception {
254         assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
255     }
256 
257     public void testImplicitParameters() throws Exception {
258     	assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
259     }
260     
261     public void testImport() throws Exception {
262         assertEquals("import foo.bar.Wibble", pretty("import foo.bar.Wibble"));
263     }
264     
265     public void testInc() throws Exception {
266     	assertEquals("++x",pretty("++x"));
267     }
268 
269     public void testIndexOp() throws Exception {
270         assertEquals("foo.bar()[fred.wilma()]", pretty("foo.bar()[fred.wilma()]"));
271     }
272     
273     public void testInterfaceDef() throws Exception {
274     	//todo, the spacing here is... unusual
275     	assertEquals("interface Foo{void blah() }", pretty("interface Foo{void blah()}"));
276     }
277 
278     public void testInstanceInit() throws Exception {
279     	assertEquals("class Foo {{x = 1}}", pretty("class Foo {{x=1}}"));
280     }
281 
282     public void testLabeledArg() throws Exception {
283         assertEquals("myMethod(argOne:123, argTwo:123)", pretty("myMethod(argOne:123,argTwo:123)"));
284         assertEquals("myMap = [keyOne:123, keyTwo:234]", pretty("myMap = [keyOne:123,keyTwo:234]"));
285     }
286 
287     public void testLabeledStat() throws Exception {
288      	assertEquals("foo:x = 1", pretty("foo:x = 1"));
289     }
290     
291     public void testLand() throws Exception {
292         assertEquals("true && false", pretty("true && false"));
293     }
294     
295     public void testLe() throws Exception {
296     	assertEquals("if (60 <= 70) {}", pretty("if (60<=70) {}"));
297     }    
298 
299     public void testListConstructor() throws Exception {
300         assertEquals("[a, b]", pretty("[a,b]"));
301     }
302 
303     public void testLiteralAny() throws Exception {
304         assertEquals("any x = 2", pretty("any x = 2"));
305     }
306 
307     public void testLiteralAs() throws Exception {
308         assertEquals("import java.util.Date as MyDate", pretty("import java.util.Date as MyDate"));
309         // todo suspicious spacing in the following assertion
310         assertEquals("x = 12 as Long ", pretty("x = 12 as Long"));
311     }
312 
313     public void testLiteralAssert() throws Exception {
314         assertEquals("assert a == true", pretty("assert a== true"));
315         assertEquals("assert b == true : 99", pretty("assert b==true:99"));
316         // todo is ',' deprecated now?
317         //assertEquals("assert b == true , 99", pretty("assert b==true,99"));
318     }
319 
320     public void testLiteralBoolean() throws Exception {
321         assertEquals("boolean b = true", pretty("boolean b =true"));
322     }
323     
324     public void testLiteralBreak() throws Exception {
325     	assertEquals("for (i in 1..100) {break }", pretty("for (i in 1..100) {break}"));
326         assertEquals("switch (foo) {default:break }", pretty("switch(foo){default:break}"));
327         assertEquals("def myMethod() {break }", pretty("def myMethod(){break}"));
328     	assertEquals("for (i in 1..100) {break 2}", pretty("for (i in 1..100) {break 2}"));
329     	//todo should the colon be postfixed to the label?
330     	assertEquals("for (i in 1..100) {break label1:}", pretty("for (i in 1..100) {break label1:}"));
331     }
332 
333     public void testLiteralByte() throws Exception {
334         assertEquals("byte b = 1", pretty("byte b=1"));
335     }
336 
337     public void testLiteralCase() throws Exception {
338         assertEquals("switch (foo) {case 1:x = 3}", pretty("switch(foo){case 1:x=3}"));
339     }
340     
341     public void testLiteralCatch() throws Exception {
342         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
343         assertEquals("try {} catch (Exception e1) {} catch (Exception2 e2) {}", pretty("try {} catch (Exception e1) {} catch (Exception2 e2) {}"));
344     }
345 
346     public void testLiteralChar() throws Exception {
347         assertEquals("char c = \"a\"", pretty("char c = \"a\""));
348     }
349 
350     public void testLiteralClass() throws Exception {
351     	assertEquals("public class Foo {int bar}", pretty("public class Foo{int bar}"));
352     }
353     
354     public void testLiteralContinue() throws Exception {
355     	assertEquals("for (i in 1..100) {continue }", pretty("for (i in 1..100) {continue}"));
356     	assertEquals("for (i in 1..100) {continue 2}", pretty("for (i in 1..100) {continue 2}"));
357     	//todo should the colon be postfixed to the label?
358     	assertEquals("for (i in 1..100) {continue label1:}", pretty("for (i in 1..100) {continue label1:}"));
359     	assertEquals("[1, 2, 3].each {continue }", pretty("[1,2,3].each{continue}"));
360     }
361 
362     public void testLiteralDef() throws Exception {
363     	assertEquals("def x = 123", pretty("def x=123"));
364     	assertEquals("def myMethod() {return 0}", pretty("def myMethod(){return 0}"));
365     	// note: def not needed in parameter declarations, but it is valid
366     	//todo: is it ok to strip out 'def' from parameter declarations?
367     	assertEquals("def foo( bar) {}", pretty("def foo(def bar){}"));
368     }
369     
370     public void testLiteralDefault() throws Exception {
371         assertEquals("switch (foo) {default:x = 2}", pretty("switch(foo){default:x=2}"));
372     	assertEquals("public @interface Foo{int bar() default 123}", pretty("public @interface Foo{int bar() default 123}"));
373     }
374     
375     public void testLiteralDouble() throws Exception {
376     	assertEquals("double d = 1.0", pretty("double d = 1.0"));
377     }
378     
379     public void testLiteralElse() throws Exception {
380     	assertEquals("if (false) {a = 1} else {a = 2}", pretty("if (false) {a=1} else {a=2}"));
381     }
382 
383     public void testLiteralEnum() throws Exception {
384     	assertEquals("enum Season {WINTER, SPRING, SUMMER, AUTUMN}", pretty("enum Season{WINTER,SPRING,SUMMER,AUTUMN}"));
385     }
386     
387     public void testLiteralExtends() throws Exception {
388     	assertEquals("class Foo extends java.util.Date {}", pretty("class Foo extends java.util.Date {}"));
389         assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
390         assertEquals("interface Wibble extends Mooky{}", pretty("interface Wibble extends Mooky {}"));
391         //todo spacing is odd, c.f. last space in class vs interface above
392     	assertEquals("public boolean process(Set<? extends TypeElement> annotations) {println annotations}", pretty("public boolean process(Set<? extends TypeElement> annotations) {println annotations}"));
393     }
394     
395     public void testLiteralFalse() throws Exception {
396         assertEquals("if (false) {}", pretty("if (false) {}"));
397     }
398 
399     public void testLiteralFinally() throws Exception {
400         assertEquals("try {}finally {}", pretty("try {}finally {}"));
401     }
402 
403     public void testLiteralFloat() throws Exception {
404         assertEquals("float x", pretty("float x"));
405     }
406 
407     public void testLiteralFor() throws Exception {
408         assertEquals("for (i in [1, 2, 3]) {}", pretty("for (i in [1,2,3]) {}"));
409         // check non-braced single statement
410         assertEquals("for (i in 1..100) rotateAntiClockwise()", pretty("for (i in 1..100) rotateAntiClockwise()"));
411     }
412 
413     public void testLiteralIf() throws Exception {
414         assertEquals("if (a == b) return false", pretty("if (a==b) return false"));
415         assertEquals("if (a == b) {}", pretty("if (a==b) {}"));
416     }
417 
418     public void testLiteralImplements() throws Exception {
419         assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
420         //todo the following is legal Java, but pretty strange...?
421         assertEquals("enum EarthSeason implements Season {SPRING}", pretty("enum EarthSeason implements Season{SPRING}"));
422     }
423     
424     public void testLiteralImport() throws Exception {
425     	assertEquals("import foo.Bar", pretty("import foo.Bar"));
426     	assertEquals("import mooky.*", pretty("import mooky.*"));
427     }
428     
429     public void testLiteralIn() throws Exception {
430     	assertEquals("for (i in 1..10) {}", pretty("for (i in 1..10) {}"));
431     	assertEquals("if (i in myList) {}", pretty("if (i in myList) {}"));
432     }
433 
434     public void testLiteralInstanceOf() throws Exception {
435         assertEquals("if (a instanceof String) {}", pretty("if (a instanceof String) {}"));
436     }
437     public void testLiteralInt() throws Exception {
438         assertEquals("int a", pretty("int a"));
439     }
440     
441     public void testLiteralInterface() throws Exception {
442     	assertEquals("interface Foo{}", pretty("interface Foo{}"));
443     }
444     public void testLiteralLong() throws Exception {
445         assertEquals("long a = 1", pretty("long a = 1"));
446     }
447     public void testLiteralNative() throws Exception {
448         assertEquals("public class R {public native void seek(long pos) }", pretty("public class R{public native void seek(long pos)}"));
449         assertEquals("native foo() ", pretty("native foo()"));
450     }
451     public void testLiteralNew() throws Exception {
452         assertEquals("new Foo()", pretty("new Foo()"));
453         assertEquals("def x = new int[5]", pretty("def x = new int[5]"));
454     }
455 
456     public void testLiteralNull() throws Exception {
457         assertEquals("def foo = null", pretty("def foo=null"));
458     }
459 
460     public void testLiteralPackage() throws Exception {
461     	assertEquals("package foo.bar", pretty("package foo.bar"));
462     }
463     public void testLiteralPrivate() throws Exception{
464         assertEquals("private bar", pretty("private bar"));
465     }
466 
467     public void testLiteralProtected() throws Exception{
468         assertEquals("protected mooky", pretty("protected mooky"));
469     }
470 
471     public void testLiteralPublic() throws Exception{
472         assertEquals("public foo", pretty("public foo"));
473     }
474 
475     public void testLiteralReturn() throws Exception {
476         assertEquals("def foo() {return false}", pretty("def  foo() { return false }"));
477         assertEquals("void bar() {return }", pretty("void bar() {return}"));
478     }
479 
480     public void testLiteralShort() throws Exception {
481         assertEquals("short a = 1", pretty("short a = 1"));
482     }
483 
484     public void testLiteralStatic() throws Exception {
485         assertEquals("static void foo() {}", pretty("static void foo() {}"));
486         //classes, interfaces, class/instance vars and methods
487         assertEquals("static int bar = 1", pretty("static int bar = 1"));
488         //todo: this should parse... assertEquals("private static <T> void foo(List<T> list){}", pretty("private static <T> void foo(List<T> list){}"));
489         assertEquals("class Foo {static {bar = 1}}", pretty("class Foo{static {bar=1}}"));
490     }
491 
492     public void testLiteralSuper() throws Exception {
493     	assertEquals("class Foo {public Foo() {super()}}", pretty("class Foo{public Foo(){super()}}"));
494     	// todo will 'super' be allowed in non-parentheses method call styles?
495     	assertEquals("class Bar {public Bar() {super 99}}", pretty("class Bar{public Bar(){super 99}}"));
496     	assertEquals("class Bar {public Bar() {super(1, 2, 3)}}", pretty("class Bar{public Bar(){super(1,2,3)}}"));
497     	assertEquals("println(super.toString())", pretty("println(super.toString())"));
498     	//todo: doesn't parse correctly...   assertEquals("class Foo<T super C> {T t}",pretty("class Foo<T super C> {T t}"));
499     }
500     public void testLiteralSwitch() throws Exception {
501         assertEquals("switch (foo) {case bar:x = 2}", pretty("switch(foo){case bar:x=2}"));
502     }
503         
504     public void testLiteralSynchronized() throws Exception {
505     	assertEquals("synchronized foo() {}", pretty("synchronized foo(){}"));
506     	assertEquals("synchronized (t) {doStuff(t)}", pretty("synchronized (t) {doStuff(t)}"));
507     }
508 
509     public void testLiteralThis() throws Exception {
510     	assertEquals("this",pretty("this"));
511     	assertEquals("this 2",pretty("this 2"));
512     	assertEquals("this()",pretty("this()"));
513     	assertEquals("this(1, 2, 3)",pretty("this(1,2,3)"));
514         assertEquals("this.x = this.y", pretty("this.x=this.y"));
515     }
516     
517     public void testLiteralThreadsafe() throws Exception {
518     	assertEquals("threadsafe foo() {}", pretty("threadsafe foo() {}"));
519     }
520     
521     public void testLiteralThrow() throws Exception {
522         assertEquals("def foo() {if (false) throw new RuntimeException()}", pretty("def foo() {if (false) throw new RuntimeException()}"));
523     }
524     public void testLiteralThrows() throws Exception {
525     	//todo AntlrParserPlugin: Unexpected node type: '.' found when expecting type: an identifier
526     	assertEquals("def foo() throws java.io.IOException{}", pretty("def foo() throws java.io.IOException{}"));
527     }
528     public void testLiteralTransient() throws Exception {
529     	assertEquals("transient bar", pretty("transient bar"));
530     }
531     
532     public void testLiteralTrue() throws Exception {
533         assertEquals("foo = true", pretty("foo = true"));
534     }
535 
536     public void testLiteralTry() throws Exception {
537         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
538     }
539 
540     public void testLiteralVoid() throws Exception {
541         assertEquals("void foo() {}", pretty("void foo(){}"));
542     }
543     public void testLiteralVolatile() throws Exception {
544     	assertEquals("volatile mooky", pretty("volatile mooky"));
545     }
546 
547     public void testLiteralWhile() throws Exception {
548         assertEquals("while (true) {}", pretty("while(true){}"));
549     }
550 
551     public void testLiteralWith() throws Exception {
552         assertEquals("with (myObject) {x = 1}", pretty("with(myObject) {x = 1}"));
553     }
554     public void testLnot() throws Exception {
555         assertEquals("if (!isRaining) {}", pretty("if (!isRaining) {}"));
556     }
557 
558     public void testLor() throws Exception {
559         assertEquals("true || false", pretty("true || false"));
560     }
561     public void testLparen_FAILS() throws Exception { if (notYetImplemented()) return;
562     	assertEquals("for (i in (history.size() - 1)..0) {}", pretty("for (i in (history.size() - 1)..0) {}"));
563     }
564     public void testLt() throws Exception {
565         assertEquals("if (3.4f < 12f) {}", pretty("if (3.4f < 12f) {}"));
566     }
567     public void testMapConstructor() throws Exception{
568         assertEquals("Map foo = [:]", pretty("Map foo = [:]"));
569         assertEquals("[a:1, b:2]", pretty("[a:1,b:2]"));
570     }
571 
572     public void testMemberPointer() throws Exception {
573         assertEquals("def x = foo.&bar()", pretty("def x=foo.&bar()"));
574     }
575     public void testMethodCall() throws Exception {
576         assertEquals("foo(bar)", pretty("foo(bar)"));
577         assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
578         assertEquals("foo(bar){mooky()}", pretty("foo(bar){mooky()}"));
579     }
580 
581     public void testMethodDef() throws Exception{
582         assertEquals("def foo(int bar, boolean boo) {}", pretty("def foo(int bar,boolean boo) {}"));
583     }
584 
585     public void testMinus() throws Exception {
586         assertEquals("def bar = 4 - foo", pretty("def bar=4-foo"));
587     }
588 
589     public void testMinusAssign() throws Exception {
590         assertEquals("x -= 23", pretty("x -= 23"));
591     }
592 
593     public void testMod() throws Exception {
594         assertEquals("x = 4 % 3", pretty("x = 4 % 3"));
595     }
596 
597     public void testModifiers() throws Exception {
598     	assertEquals("public static transient final native threadsafe synchronized volatile strictfp foo() {}", pretty("public static transient final native threadsafe synchronized volatile strictfp foo() {}"));
599     }
600     
601     public void testModAssign() throws Exception {
602         assertEquals("x %= 23", pretty("x %= 23"));
603     }
604 
605     public void testNotEqual() throws Exception {
606         assertEquals("a != b", pretty("a!=b"));
607     }
608 
609     public void testNumBigDecimal() throws Exception {
610     	assertEquals("a = 9.8g", pretty("a  =9.8g"));
611     }
612     public void testNumBigInt() throws Exception {
613     	assertEquals("a = 12g", pretty("a=   12g"));
614     }
615     
616     public void testNumDouble() throws Exception {
617         assertEquals("b = 34.4d", pretty("b=34.4d"));
618         assertEquals("b = 34.4D", pretty("b=34.4D"));
619     }
620     public void testNumFloat() throws Exception {
621         assertEquals("b = 34.4f", pretty("b=34.4f"));
622         assertEquals("b = 34.4F", pretty("b=34.4F"));
623     }
624     public void testNumInt() throws Exception {
625         assertEquals("a = 12", pretty("a=12"));
626     }
627 
628     public void testNumLong() throws Exception {
629     	assertEquals("a = 12l", pretty("a=12l"));    	
630     }
631     public void testObjblock() throws Exception {
632         assertEquals("class Foo {def bar}", pretty("class Foo {def bar}"));
633     }
634     public void testOptionalDot() throws Exception {
635         assertEquals("foo = england.london.kings?.head", pretty("foo = england.london.kings?.head"));
636     }
637 
638     public void testPackageDef() throws Exception {
639         assertEquals("package foo.bar", pretty("package foo.bar"));
640     }
641 
642     public void testParameterDef() throws Exception {
643     	//todo spacing slightly suspect with "foo( bar)"
644     	assertEquals("def foo( bar) {}", pretty("def foo(bar){}"));
645         assertEquals("def foo(String bar, String mooky) {}", pretty("def foo(String bar, String mooky){}"));
646         assertEquals("def c = { x -> println x}", pretty("def c = {x->println x}"));
647         assertEquals("def c = { x, y -> println(x + y)}", pretty("def c={x,y->println(x+y)}"));
648         assertEquals("def c = {int x,int y -> println(x + y)}", pretty("def c={int x, int y->println(x+y)}"));
649     }
650 
651     public void testParameters() throws Exception {
652         assertEquals("def foo(String bar, String mooky) {}", pretty("def foo(String bar, String mooky){}"));
653     }
654     public void testPlus() throws Exception {
655         assertEquals("a + b", pretty("a+b"));
656     }
657     
658     public void testPlusAssign() throws Exception {
659         assertEquals("x += 23", pretty("x += 23"));
660     }
661 
662     public void testPostDec() throws Exception {
663     	assertEquals("a--", pretty("a--"));
664     }
665     public void testPostInc() throws Exception {
666     	assertEquals("a++", pretty("a++"));
667     }
668     public void testQuestion() throws Exception {
669         assertEquals("foo == bar?10:20", pretty("foo==bar?10:20"));
670     	assertEquals("public boolean process(Set<? extends B> a) {println a}", pretty("public boolean process(Set<? extends B> a) {println a}"));
671     	assertEquals("public boolean process(Set<? extends B, ? super C> a) {println a}", pretty("public boolean process(Set<? extends B, ? super C> a) {println a}"));
672     }
673     public void testRangeExclusive() throws Exception {
674         assertEquals("foo[45..<89]", pretty("foo[45 ..< 89]"));
675     }
676     public void testRangeInclusive() throws Exception {
677         assertEquals("foo[bar..12]", pretty("foo[bar .. 12]"));
678     }
679     public void testRegexpLiteral() throws Exception {
680     	assertEquals("println", pretty("println //")); // empty regexp_literal should be treated as single line comment
681     }
682 
683     public void testRegexpLiteral_FAILS() throws Exception { if (notYetImplemented()) return;
684 		//todo: these fail because regexp_literals are converted into string_literals on the antlr AST
685 		assertEquals("def x = /./", pretty("def x = /./"));
686 		assertEquals("def z = /blah//s/", pretty("def z = /blah//s/")); // actually: def z = /blah\s/
687     }
688     
689     public void testRegexFind() throws Exception {
690     	assertEquals("def m = foo =~ \"bar\"", pretty("def m = foo =~ \"bar\""));
691     	assertEquals("if (foo =~ \"bar\") {}", pretty("if (foo=~\"bar\"){}"));
692     }
693     
694     public void testRegexMatch() throws Exception {
695     	assertEquals("if (foo ==~ \"bar\") {}", pretty("if (foo==~\"bar\"){}"));
696     }
697     
698     public void testScopeEscape() throws Exception {
699     	// todo - 31 July + 14 Dec 2006 - test fine, however this parses but causes error in AntlrParserPlugin
700     	assertEquals("println([$x, x, y])", pretty("println([$x, x, y])"));
701     }
702     
703     public void testSelectSlot() throws Exception {
704     	assertEquals("def x = foo.@bar", pretty("def x = foo . @ bar"));
705     }
706     
707     public void testSl() throws Exception {
708     	assertEquals("foo << 123", pretty("foo << 123"));
709     }
710     
711     public void testSlAssign() throws Exception {
712     	assertEquals("foo <<= 123", pretty("foo <<= 123")); // does this operator make any sense?
713     }
714 
715     public void testSlist() throws Exception {
716     	assertEquals("class Foo {private Foo() {println bar}}",pretty("class Foo {private Foo() {println bar}}"));
717     	assertEquals("if (true) {foo}", pretty("if (true) {foo}"));
718     	assertEquals("def x = foo.{bar}", pretty("def x = foo.{bar}")); // todo - inline open block is great, but it doesn't work as one would expect (yet). (c.f. with)
719     	assertEquals("def foo() {l:{x = 2}}", pretty("def foo(){l:{x=2}}")); // slist inside a method body (needed label to distinguish from a closure)
720     	assertEquals("switch (f) {case 1:break }", pretty("switch(f){case 1:break}")); // slist inside each case body...
721     } 
722     
723     public void testSpreadArg() throws Exception {
724     	assertEquals("myList {*name}", pretty("myList{*name}"));
725         assertEquals("\"foo$*bar\"", pretty("\"foo$*bar\"")); // this doesn't work beyond parser (AntlrParserPlugin)
726         assertEquals("\"foo${*bar}\"", pretty("\"foo${*bar}\"")); // this doesn't work beyond parser (AntlrParserPlugin)
727         assertEquals("f(*[a, b, c])", pretty("f(*[a,b,c])"));
728         assertEquals("f(*null)", pretty("f(*null)")); // equiv to f()
729     }
730     public void testSpreadMapArg() throws Exception {
731     	assertEquals("f(*:myMap)", pretty("f(*:myMap)"));
732     }
733     public void testSr() throws Exception {
734     	assertEquals("foo >> 123", pretty("foo >> 123"));
735     }
736     
737     public void testSrAssign() throws Exception {
738     	assertEquals("foo >>= 123", pretty("foo >>= 123")); // does this operator make any sense?
739     }
740 
741     public void testStar() throws Exception {
742         assertEquals("import foo.*", pretty("import foo.*"));
743         assertEquals("a*b", pretty("a*b"));
744     }
745     
746     public void testStarAssign() throws Exception {
747     	assertEquals("foo *= 123", pretty("foo *= 123"));
748     }
749 
750     public void testStarStar() throws Exception {
751         assertEquals("def square = +5**2", pretty("def square=+5**2"));
752         assertEquals("def cube = 5**3", pretty("def cube = 5**3"));
753     } 
754     
755     public void testStarStarAssign() throws Exception {
756     	assertEquals("cubeMe **= 3", pretty("cubeMe **= 3"));
757     }
758 
759     public void testStaticImport() throws Exception {
760     	assertEquals("import static foo.Bar.mooky", pretty("import static foo.Bar.mooky"));
761     	assertEquals("import static foo.Bar.*", pretty("import static foo.Bar.*"));
762     }
763 
764     public void testStaticInit() throws Exception {
765     	assertEquals("class Foo {static {println(1 + 1)}}", pretty("class Foo{static{println(1+1)}}"));
766     }
767     
768     public void testStrictFp() throws Exception {
769     	assertEquals("private strictfp flibble = 1.2", pretty("private strictfp flibble = 1.2"));
770     }
771     
772     public void testStringConstructor() throws Exception{
773         assertEquals("def x = \"foo$bar\"", pretty("def x=\"foo$bar\""));
774         assertEquals("def y = \"foo${mooky}\"", pretty("def y = \"foo${mooky}\""));
775     }
776 
777     public void testStringLiteral_FAILS() throws Exception{ if (notYetImplemented()) return;
778         assertEquals("\"mooky\"", pretty("\"mooky\""));
779         assertEquals("'mooky'", pretty("'mooky'"));
780     	assertEquals("def x = '''can go over newline'''", pretty("def x = '''can go over newline'''"));
781     	assertEquals("def x = \"\"\"can go over newline\"\"\"", pretty("def x = \"\"\"can go over newline\"\"\""));
782     	//todo test newlines inside strings somehow...
783     }
784 
785     public void testSuperCtorCall() throws Exception{
786     	assertEquals("class Foo {Foo(int x) {super(12, 3)}}",pretty("class Foo{Foo(int x) {super(12, 3)}}"));
787     	assertEquals("class Foo {Foo( x) {super()}}",pretty("class Foo{Foo(x) {super()}}"));
788         // todo: above is not quite the spacing I would expect, but good enough for now...
789     	// todo not yet implemented in parser: assertEquals("(new Outer()).super()", pretty("(new Outer()).super()"));
790     }
791     
792     public void testType() throws Exception {
793     	assertEquals("def bar", pretty("def bar"));
794         assertEquals("public bar", pretty("public bar"));
795         assertEquals("public String bar", pretty("public String bar"));
796         assertEquals("String bar", pretty("String bar"));
797     }
798 
799     public void testTypecast() throws Exception {
800         assertEquals("foo = (int)bar", pretty("foo = (int)bar"));
801         assertEquals("foo = (int[])bar", pretty("foo = (int[])bar"));
802         assertEquals("foo = (String)bar", pretty("foo = (String)bar"));
803         assertEquals("foo = (String[])bar", pretty("foo = (String[])bar"));
804     }
805 
806     public void testTypeArguments() throws Exception {
807     	assertEquals("void printCollection(Collection<?> c) {}", pretty("void printCollection(Collection<?> c) {}"));
808     }
809     public void testTypeLowerBounds() throws Exception {
810     	assertEquals("void printCollection(Collection<? super X> c) {}", pretty("void printCollection(Collection<? super X> c) {}"));
811     }
812     public void testTypeUpperBounds() throws Exception {
813     	assertEquals("void printCollection(Collection<? extends X> c) {}", pretty("void printCollection(Collection<? extends X> c) {}"));
814     }
815 
816     public void testTypeParameters() throws Exception {
817     	assertEquals("class Foo<T extends C & I> {T t}",pretty("class Foo<T extends C & I> {T t}"));
818     }
819     public void testUnaryMinus() throws Exception {
820         assertEquals("def x = -3", pretty("def x= -3"));
821     }
822     public void testUnaryPlus() throws Exception {
823         assertEquals("def x = +2", pretty("def x= +2"));
824     }
825 
826     public void testVariableDef() throws Exception {
827         assertEquals("def x = 1", pretty("def x = 1"));
828         assertEquals("int y = 2", pretty("int y = 2"));
829         assertEquals("String y", pretty("String y"));
830         assertEquals("def foo() {int b = 9}", pretty("def foo(){int b = 9}"));
831     }
832     public void testVariableDef_FAILS() throws Exception { if (notYetImplemented()) return;
833     	assertEquals("boolean x, y, z = false", pretty("boolean x,y,z = false"));       
834     }
835     
836     public void testVaribleParameterDef() throws Exception {
837     	assertEquals("void myMethod(String param1, String ... others) {}", pretty("void myMethod(String param1, String ... others) {}"));
838     	assertEquals("void myMethod(final int ... others) {}", pretty("void myMethod(final int ... others) {}"));
839     	assertEquals("void myMethod(def ... others) {}", pretty("void myMethod(def ... others) {}"));
840     }
841     
842     public void testWildcardType() throws Exception {
843     	assertEquals("public boolean process(Set<? extends TypeElement> annotations) {println annotations}", pretty("public boolean process(Set<? extends TypeElement> annotations) {println annotations}"));
844     }
845 
846     public String pretty(String input) throws Exception{
847         GroovyRecognizer parser = null;
848         SourceBuffer sourceBuffer = new SourceBuffer();
849         UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
850         GroovyLexer lexer = new GroovyLexer(unicodeReader);
851         unicodeReader.setLexer(lexer);
852         parser = GroovyRecognizer.make(lexer);
853         parser.setSourceBuffer(sourceBuffer);
854 
855         String[] tokenNames;
856         tokenNames = parser.getTokenNames();
857         parser.compilationUnit();
858         AST ast = parser.getAST();
859 
860         ByteArrayOutputStream baos = new ByteArrayOutputStream();
861         Visitor visitor = new SourcePrinter(new PrintStream(baos),tokenNames,false);
862         AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
863 
864         traverser.process(ast);
865 
866         return new String(baos.toByteArray());
867     }
868 
869 }