/*******************************************************************************
* Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package com.w4t;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import junit.framework.TestCase;
/** <p>the superclass for TestCases that rewrite their own source files in
* order to integrate their comparation resources. When set to generation
* mode, a subclass of SelfGeneratingTestCase will append package private
* classes that provide comparation resources like strings etc.</p>
*
* How to create a self-generating TestCase:
* =========================================
*
* - extend this class
* - call <code>setGenerateResources( false );</code> in the constructor
* whenever resources are generated, switch 'false' to true, after
* generating set it back to false
* - in the testing code, do sth. like this:
*
* <code>
* String[] tokens = ... // collect whatever you want to compare
* String resourceClassName = ... // assign a name for the resource class
*
* if( isGenerateResources() ) {
* addResource( resourceClassName, tokens );
* } else {
* Class resourceClass = Class.forName( resourceClassName );
* Method getRes
* = resourceClass.getDeclaredMethod( "getRes", new Class[ 0 ] );
* getRes.setAccessible( true );
* String[] tokensRes = ( String[] )getRes.invoke( null, new Object[ 0 ] );
* compare( tokens, tokensRes );
* </code>
*/
public abstract class SelfGeneratingTestCase extends TestCase {
private boolean generateResources;
private final static String MARKER = "//$endOfPublicClass";
/** contains the resource classes (key: name, element: content as String[])
* that are rewritten after the test has been run (only when in generation
* mode). */
private Hashtable htResources;
public SelfGeneratingTestCase( final String name ) {
super( name );
htResources = new Hashtable();
}
protected void setUp() throws Exception {
W4TFixture.setUp();
W4TFixture.createContext();
}
public void tearDown() throws Exception {
W4TFixture.removeContext();
W4TFixture.tearDown();
if( isGenerateResources() ) {
StringBuffer sbContent = readPublicClass();
Enumeration keys = htResources.keys();
while( keys.hasMoreElements() ) {
String key = ( String )keys.nextElement();
Object[] resource = ( Object[] )htResources.get( key );
appendResource( key, resource, sbContent );
}
writeFile( sbContent );
}
}
protected void addResource( final String key, final Object[] resource ) {
htResources.put( key, resource );
}
protected void setGenerateResources( final boolean generateResources ) {
this.generateResources = generateResources;
}
protected boolean isGenerateResources() {
return generateResources;
}
protected void compare( final Object[] names, final String[] namesRes ) {
StringBuffer namesBuffer = new StringBuffer();
for( int i = 0; i < names.length; i++ ) {
namesBuffer.append( names[ i ] );
}
StringBuffer namesResBuffer = new StringBuffer();
for( int i = 0; i < namesRes.length; i++ ) {
namesResBuffer.append( namesRes[ i ] );
}
assertEquals( namesResBuffer.toString(), namesBuffer.toString() );
}
// helping methods
//////////////////
private String getSourceFileName() {
String userDir = System.getProperty( "user.dir" );
return userDir + "/INTERNAL/java/test/"
+ this.getClass().getName().replace( '.', '/' )
+ ".java";
}
private StringBuffer readPublicClass() throws Exception {
StringBuffer result = new StringBuffer();
File sourceFile = new File( getSourceFileName() );
BufferedReader br = null;
try {
br = new BufferedReader( new FileReader( sourceFile ) );
} catch( FileNotFoundException e ) {
throw new Exception( "You have probably set generateResources true;\n"
+ "but you are not on drive T:\\ actually.\n"
+ "so what had to happen happened:\n"
+ e.toString() );
}
String line = br.readLine();
while( line != null
&& line.indexOf( MARKER ) == -1 ) {
result.append( line );
result.append( "\r\n" );
line = br.readLine();
}
result.append( MARKER );
result.append( "\r\n" );
br.close();
return result;
}
private void writeFile( final StringBuffer sbContent ) throws Exception {
FileWriter fr = new FileWriter( getSourceFileName() );
fr.write( sbContent.toString() );
fr.close();
}
private void appendResource( final String className,
final Object[] resource,
final StringBuffer sb ) {
String nl = "\r\n";
sb.append( "class " + className + " {" );
sb.append( nl );
sb.append( nl );
sb.append( " private static String[] res = new String[] {" );
sb.append( nl );
sb.append( createStringList( resource ) );
sb.append( " };" );
sb.append( nl );
sb.append( nl );
sb.append( " static String[] getRes() {" );
sb.append( nl );
sb.append( " return res;" );
sb.append( nl );
sb.append( " }" );
sb.append( nl );
sb.append( "}" );
sb.append( nl );
sb.append( nl );
}
private StringBuffer createStringList( final Object[] resource ) {
StringBuffer result = new StringBuffer();
for( int i = 0; i < resource.length; i++ ) {
result.append( " \"" );
result.append( resource[ i ].toString() );
result.append( "\"" );
if( i < resource.length - 1 ) {
result.append( "," );
}
result.append( "\r\n" );
}
return result;
}
}