jastrachan | 26 Mar 07:54 2004
Picon

Re: GroovyMarkup with Ant and JUnit

On 25 Mar 2004, at 20:56, Mike Clark wrote:
> On Mar 25, 2004, at 11:55 AM, jastrachan@... wrote:
>>
>> Just a thought - could it just be that ant-optional-${version}.jar  
>> isn't on your classpath? i.e. that Ant can't see the 'junit' task  
>> (which AFAIK is in the optional jar?
>
> Thanks.  Indeed, it does seem to be a CLASSPATH issue.  When all else  
> fails in Java...  :-)

:)

> So here's my test method:
>
>   void test() {
>
>     compileTests()
>
>     ant.junit(haltonfailure: true) {
>       test(name: "com.xyz.ExampleTest")
>       formatter(type: "plain", usefile: false)
>       classpath() {
>         pathelement(path: projectClasspath())
>       }
>     }
>   }
>
> Notice that I'm building dependencies into targets (methods) by just  
> calling dependent methods first.

Neat!

I guess the downside though is that methods will get re-evaluated if  
the same dependency is shared by multiple targets. Though we could use  
flags inside the methods for this if its a problem. I guess we can let  
the programmer figure this stuff out.

One alternative could be to use some kind of metadata to add  
dependencies so that the engine can know which order to call the  
targets and to avoid, say, compiling things twice.

build.targets {
     compileTests( depends:['clean', compile'], description:'Compiles  
unit tests' {
	...
     }
     compile(depends:'clean', description:'Compiles bytecode') {
	...	
     }
}

Though there is something nice about using real methods and so forth as  
in your example. Maybe, once we have metadata in Groovy we could use  
that?

 <at> depends "compile"
 <at> description "Compiles the unit test cases"
compileTests() {
     ...
}

> That is, each method is a build target that explicitly calls its  
> dependent targets first.  I'm still feeling this out.  The beauty, I  
> think, is that any of these targets can use the power of a full  
> scripting language: loops, conditionals, method overriding, etc.
>
> I'm not quite happy with my projectClasspath() method:
>
>   String projectClasspath() {
>
>     path = new StringBuffer()
>     path.append(buildDir).append(File.pathSeparator)
>
>     files = ant.fileScanner {
>       fileset(dir: libDir) {
>         include(name: "**/*.jar")
>       }
>     }
>
>     for (file in files.iterator()) {

FWIW the '.iterator()' is not needed

>       path.append(file).append(File.pathSeparator)
>     }
>
>     return path.toString()
>   }
>
> I'm open to any ideas for making this cleaner.  It seems like it  
> should be easier, like using an Ant pathelement or something.

Agreed. How about this...

path = ant.path {
     fileset(
       fileset(dir: libDir) {
         include(name: "**/*.jar")
       }
     }
}
return path.toString()

Which is quite neat. I was quite surprised this actually worked first  
time :) - I added a test method to the test case below. Note that path  
is-an Ant Path object, hence the reason for the toString() - though  
your code would probably work using path as a Path rather than String  
anyways.

>  Does anybody have other examples of Ant scripting they'd mind sharing?

So far all my examples (other than Jelly) have been the unit test case  
in CVS...

http://cvs.groovy.codehaus.org/viewcvs.cgi/groovy/groovy-core/src/test/ 
groovy/util/AntTest.groovy?rev=HEAD&view=auto

James
-------
http://radio.weblogs.com/0112098/

Gmane