/*
 [The "BSD licence"]
 Copyright (c) 2007-2008 Leon, Jen-Yuan Su
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
group junit;

classHeader(header,junitFileName,hasTreeAdaptor,treeAdaptorPath,
    hasPackage,packagePath,lexerPath,parserPath,treeParserPath,isTreeGrammar) ::= <<
<header>

import org.antlr.gunit.gUnitBaseTest;

public class <junitFileName> extends gUnitBaseTest {
	
	public void setUp() {
		<if(hasTreeAdaptor)><\t><\t>this.treeAdaptorPath = "<treeAdaptorPath>";<endif>
		<if(hasPackage)><\t><\t>this.packagePath = "<packagePath>";<endif>
		this.lexerPath = "<lexerPath>";
		this.parserPath = "<parserPath>";
		<if(isTreeGrammar)><\t><\t>this.treeParserPath = "<treeParserPath>";<endif>
	}<\n><\n>
>>

testTreeRuleMethod(methodName,testTreeRuleName,testRuleName,test,tokenType,expecting) ::= <<
	public void <methodName>() throws Exception {
		// gunit test on line <test.line>
		Object retval = execTreeParser(<testTreeRuleName>, <testRuleName>, "<test.inputEscaped>", <test.isFile>);
		Object actual = examineExecResult(<tokenType>, retval);
		Object expecting = <expecting>;
		
		assertEquals("testing rule "+<testTreeRuleName>, expecting, actual);
	}<\n><\n>
>>

testTreeRuleMethod2(methodName,testTreeRuleName,testRuleName,test,returnType,expecting) ::= <<
	public void <methodName>() throws Exception {
		// gunit test on line <test.line>
		<returnType> retval = (<returnType>)execTreeParser(<testTreeRuleName>, <testRuleName>, "<test.inputEscaped>", <test.isFile>);
		
		assertTrue("testing rule "+<testTreeRuleName>, <expecting>);
	}<\n><\n>
>>

testRuleMethod(isLexicalRule,methodName,testRuleName,test,tokenType,expecting) ::= <<
	public void <methodName>() throws Exception {
		// gunit test on line <test.line>
		Object retval = <if(isLexicalRule)>execLexer<else>execParser<endif>(<testRuleName>, <test.line>, "<test.inputEscaped>", <test.isFile>);
		Object actual = examineExecResult(<tokenType>, retval);
		Object expecting = <expecting>;

		assertEquals("testing rule "+<testRuleName>, expecting, actual);
	}<\n><\n>
>>

testRuleMethod2(methodName,testRuleName,test,returnType,expecting) ::= <<
	public void <methodName>() throws Exception {
		// gunit test on line <test.line>
		<returnType> retval = (<returnType>)execParser(<testRuleName>, <test.line>, "<test.inputEscaped>", <test.isFile>);

		assertTrue("testing rule "+<testRuleName>, <expecting>);
	}<\n><\n>
>>
