Command line tools

* Added base classes for all importable data. These new classes should
be used for all future loaders; all existing loaders that are modified
should be updated.

* I18N loader rewritten to make use of the new base classes. External
strings are now read using the XML data file's path as the base
directory.

* Updated all external I18N definitions and moved the existing files
around in an attempt to make the data directory somewhat more livable.

* Added dependency management entry for the server's main package to the
root project, updated server distribution package accordingly. Added
dependency on the server's main package to the server's testing package.
This commit is contained in:
Emmanuel BENOîT 2011-12-17 12:37:01 +01:00
parent be3106c463
commit 631f49fb86
57 changed files with 2295 additions and 200 deletions

View file

@ -0,0 +1 @@
This is a test.

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<lw-text-data>
<does-not-exist />
</lw-text-data>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<lw-text-data xmlns="http://www.deepclone.com/lw/b6/m1/i18n-text"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.deepclone.com/lw/b6/m1/i18n-text ../../../legacyworlds-server-main/data/i18n-text.xsd">
<language name="test" id="test">
<inline-string id="test">
<value />
</inline-string>
</language>
</lw-text-data>

View file

@ -0,0 +1,2 @@
This is not an XML file, obviously.
We'll make that even more confusing: <<<<<< & >>!!!

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<lw-text-data xmlns="http://www.deepclone.com/lw/b6/m1/i18n-text"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.deepclone.com/lw/b6/m1/i18n-text ../../../legacyworlds-server-main/data/i18n-text.xsd">
<language name="test" id="test">
<from-file id="test" source="test.txt" />
</language>
</lw-text-data>

View file

@ -0,0 +1 @@
test

View file

@ -50,6 +50,10 @@
<artifactId>legacyworlds-server-beans-user</artifactId>
<groupId>com.deepclone.lw</groupId>
</dependency>
<dependency>
<artifactId>legacyworlds-server-main</artifactId>
<groupId>com.deepclone.lw</groupId>
</dependency>
<dependency>
<groupId>junit</groupId>

View file

@ -0,0 +1,152 @@
package com.deepclone.lw.cli.xmlimport;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import org.junit.Test;
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
import com.deepclone.lw.cli.xmlimport.data.i18n.I18NText;
import com.deepclone.lw.cli.xmlimport.data.i18n.LanguageDefinition;
import com.deepclone.lw.cli.xmlimport.data.i18n.StringDefinition;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
/**
* Unit tests for the {@link I18NLoader} class.
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*
*/
public class TestI18NLoader
{
/**
* Try initialising the loader with a <code>null</code> file instance.
*
* @throws NullPointerException
* when the constructor is executed
*/
@Test( expected = NullPointerException.class )
public void testNullFile( )
throws NullPointerException
{
new I18NLoader( null );
}
/**
* Try loading a file that does not exist
*/
@Test
public void testMissingFile( )
{
I18NLoader loader = new I18NLoader( new File( "does-not-exist" ) );
try {
loader.load( );
} catch ( DataImportException e ) {
assertTrue( "cause is a " + e.getCause( ).getClass( ).getName( ) , e.getCause( ) instanceof IOException );
return;
}
fail( "no exception after trying to load a missing file" );
}
/**
* Try loading a file that contains something that definitely isn't XML.
*/
@Test
public void testBadXML( )
{
I18NLoader loader = new I18NLoader( new File( "TestFiles/i18n-loader/bad-xml.xml" ) );
try {
loader.load( );
} catch ( DataImportException e ) {
assertTrue( "cause is a " + e.getCause( ).getClass( ).getName( ) , e.getCause( ) instanceof StreamException );
return;
}
fail( "no exception after loading stuff that isn't XML" );
}
/**
* Try loading a file that contains XML but which cannot be desertialised to an {@link I18NText}
* instance.
*/
@Test
public void testBadContents( )
{
I18NLoader loader = new I18NLoader( new File( "TestFiles/i18n-loader/bad-contents.xml" ) );
try {
loader.load( );
} catch ( DataImportException e ) {
assertTrue( "cause is a " + e.getCause( ).getClass( ).getName( ) ,
e.getCause( ) instanceof ConversionException );
return;
}
fail( "no exception after loading bad XML" );
}
/**
* Try loading a file that contains valid XML for an {@link I18NText} instance with semantic
* errors.
*/
@Test
public void testBadData( )
{
I18NLoader loader = new I18NLoader( new File( "TestFiles/i18n-loader/bad-data.xml" ) );
try {
loader.load( );
} catch ( DataImportException e ) {
assertNull( e.getCause( ) );
return;
}
fail( "no exception after loading bad data" );
}
/**
* Try loading valid data, make sure that it contains exactly what is expected, and that it
* loads external strings from the appropriate directory.
*/
@Test
public void testGoodData( )
{
I18NLoader loader = new I18NLoader( new File( "TestFiles/i18n-loader/good.xml" ) );
I18NText text;
try {
text = loader.load( );
} catch ( DataImportException e ) {
fail( "could not load valid file" );
return;
}
assertNotNull( text );
int lCount = 0;
for ( LanguageDefinition ld : text ) {
assertEquals( "test" , ld.getId( ) );
assertEquals( "test" , ld.getName( ) );
int tCount = 0;
for ( StringDefinition sd : ld ) {
assertEquals( "test" , sd.getId( ) );
try {
assertEquals( "test" , sd.getString( ).trim( ) );
} catch ( DataImportException e ) {
fail( "could not load string: " + e.getMessage( ) );
}
tCount++;
}
assertEquals( 1 , tCount );
lCount++;
}
assertEquals( 1 , lCount );
}
}

View file

@ -0,0 +1,73 @@
package com.deepclone.lw.cli.xmlimport.data;
import java.io.File;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Unit tests for the {@link ImportableData} class
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class TestImportableData
{
/**
* Dummy importable data
*
* <p>
* This class is used in the test to have access to an importable data instance that corresponds
* exactly to the base class.
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
@SuppressWarnings( "serial" )
private static class DummyData
extends ImportableData
{
// EMPTY
}
/** Make sure that {@link ImportableData#getReadFrom()} returns <code>null</code> by default */
@Test
public void testUninitialisedReadFrom( )
{
DummyData data = new DummyData( );
assertNull( data.getReadFrom( ) );
}
/** Checks the default implementation of {@link ImportableData#setReadFrom(File)} */
@Test
public void testSetReadFrom( )
{
DummyData data = new DummyData( );
File file = new File( "test" );
data.setReadFrom( file );
assertNotNull( data.getReadFrom( ) );
assertEquals( "test" , data.getReadFrom( ).getPath( ) );
}
/**
* Make sure that the default implementation of {@link ImportableData#verifyData()} always
* succeeds
*
* @throws DataImportException
* if the default implementation fails somehow
*/
@Test
public void testDefaultVerify( )
throws DataImportException
{
DummyData data = new DummyData( );
data.verifyData( );
}
}

View file

@ -0,0 +1,205 @@
package com.deepclone.lw.cli.xmlimport.data.i18n;
import com.deepclone.lw.cli.xmlimport.I18NLoader;
import com.deepclone.lw.cli.xmlimport.data.ImportableData;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
/**
* Base class for I18N import structures
*
* <p>
* This class is used as a parent by tests of the I18N import structures. It includes the code
* required to actually create such resources, as this can normally only be done through XStream.
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*
*/
abstract class BaseTest
{
/**
* Escape &amp;, &lt; and &gt; in XML strings
*
* @param string
* the string to escape
*
* @return the escaped string
*/
private String xmlString( String string )
{
return string.replace( "&" , "&amp;" ).replace( "<" , "&lt;" ).replace( ">" , "&gt;" );
}
/**
* Escape &amp;, &lt; and &gt;, ' and " in XML strings
*
* @param string
* the string to escape
*
* @return the escaped string
*/
private String quoteString( String string )
{
return "\"" + this.xmlString( string ).replace( "\"" , "&quot;" ).replace( "'" , "&apos;" ) + "\"";
}
/**
* Create an in-line string definition
*
* <p>
* Generate the XML code that corresponds to an in-line string definition.
*
* @param identifier
* the string's identifier, or <code>null</code> to omit the identifier
* @param contents
* the string's contents, or <code>null</code> to omit the contents.
*
* @return the XML code corresponding to the string definition
*/
protected String createInlineStringDefinition( String identifier , String contents )
{
StringBuilder str = new StringBuilder( );
str.append( "<inline-string" );
if ( identifier != null ) {
str.append( " id=" ).append( this.quoteString( identifier ) );
}
str.append( '>' );
if ( contents != null ) {
str.append( "<value>" ).append( this.xmlString( contents ) ).append( "</value>" );
}
str.append( "</inline-string>" );
return str.toString( );
}
/**
* Create an external string definition
*
* <p>
* Generate the XML code that corresponds to an external string definition.
*
* @param identifier
* the string's identifier, or <code>null</code> to omit the identifier
* @param source
* the string's source file, or <code>null</code> to omit the source.
*
* @return the XML code corresponding to the string definition
*/
protected String createExternalStringDefinition( String identifier , String source )
{
StringBuilder str = new StringBuilder( );
str.append( "<from-file" );
if ( identifier != null ) {
str.append( " id=" ).append( this.quoteString( identifier ) );
}
if ( source != null ) {
str.append( " source=" ).append( this.quoteString( source ) );
}
str.append( " />" );
return str.toString( );
}
/**
* Create a language definition
*
* @param identifier
* the language's identifier, or <code>null</code> if the identifier is to be omitted
* @param name
* the language's name, or <code>null</code> if the name is to be omitted
* @param stringDefinitions
* XML definitions returned by {@link #createInlineStringDefinition(String, String)}
* or {@link #createExternalStringDefinition(String, String)}
*
* @return the XML code corresponding to the language definition
*/
protected String createLanguageDefinition( String identifier , String name , String... stringDefinitions )
{
StringBuilder str = new StringBuilder( );
str.append( "<language" );
if ( identifier != null ) {
str.append( " id=" ).append( this.quoteString( identifier ) );
}
if ( name != null ) {
str.append( " name=" ).append( this.quoteString( name ) );
}
str.append( ">" );
for ( String definition : stringDefinitions ) {
str.append( definition );
}
str.append( "</language>" );
return str.toString( );
}
/**
* Create the XML code for a top-level I18N definition element
*
* @param languages
* XML definitions of languages, as returned by
* {@link #createLanguageDefinition(String, String, String...)}
*
* @return the top-level element's XML code
*/
protected String createTopLevel( String... languages )
{
StringBuilder str = new StringBuilder( );
str.append( "<lw-text-data>" );
for ( String language : languages ) {
str.append( language );
}
str.append( "</lw-text-data>" );
return str.toString( );
}
/**
* Create the necessary XStream instance
*
* <p>
* Initialise an XStream instance and set it up so it can process I18N data definitions. Unlike
* the XStream instance generated by {@link I18NLoader}, this version also registers the alias
* for language definitions.
*
* @return the initialised XStream instance.
*/
private XStream createXStreamInstance( )
{
XStream xstream = new XStream( );
xstream.processAnnotations( I18NText.class );
xstream.processAnnotations( InlineString.class );
xstream.processAnnotations( FileString.class );
xstream.alias( "language" , LanguageDefinition.class );
return xstream;
}
/**
* Create an I18N definition object from its XML code
*
* @param xml
* the XML code
* @param cls
* the class of the object
*
* @return the object that was created from the code
*
* @throws ClassCastException
* if the code corresponds to some other type of object
* @throws XStreamException
* if some error occurred while unserialising the object
*/
protected < T extends ImportableData > T createObject( String xml , Class< T > cls )
throws ClassCastException , XStreamException
{
return cls.cast( this.createXStreamInstance( ).fromXML( xml ) );
}
}

View file

@ -0,0 +1,307 @@
package com.deepclone.lw.cli.xmlimport.data.i18n;
import static org.junit.Assert.*;
import java.io.File;
import org.junit.Test;
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
/**
* Unit tests for the {@link FileString} class
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class TestExternalString
extends BaseTest
{
/**
* Test loading a valid external string record and the corresponding contents
*
* @throws DataImportException
* if a failure occurs while reading the source file.
*/
@Test
public void testLoadStringOK( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "TestFiles/i18n-external-file/file" ) );
assertEquals( "test" , instance.getId( ) );
assertEquals( "This is a test." , instance.getString( ).trim( ) );
}
/**
* Test loading an external string record with no identifier
*
* @throws DataImportException
* if a failure occurs while reading the source file.
*/
@Test
public void testLoadStringNullIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( null , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "TestFiles/i18n-external-file/file" ) );
assertNull( instance.getId( ) );
assertEquals( "This is a test." , instance.getString( ).trim( ) );
}
/**
* Test loading an external string record with no source file
*
* @throws DataImportException
* if a failure occurs while reading the source file
* @throws NullPointerException
* when {@link FileString#getString()} is called while its source is
* <code>null</code>
*/
@Test( expected = NullPointerException.class )
public void testLoadStringNullSource( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , null );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "TestFiles/i18n-external-file/file" ) );
assertEquals( "test" , instance.getId( ) );
instance.getString( );
}
/**
* Test loading a valid external string record and obtaining the contents without setting the
* path to the data file first.
*
* @throws DataImportException
* if a failure occurs while reading the source file.
* @throws NullPointerException
* when {@link FileString#getString()} is called while its original path is
* <code>null</code>
*/
@Test( expected = NullPointerException.class )
public void testLoadStringNoPath( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.getString( );
}
/**
* Test loading a valid external string record and obtaining the contents when the source file
* does not exist.
*
* @throws DataImportException
* when a failure occurs while reading the source file.
*/
@Test( expected = DataImportException.class )
public void testLoadStringBadSource( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , "does-not-exist.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "TestFiles/i18n-external-file/file" ) );
instance.getString( );
}
/**
* Test loading a valid external string record and obtaining the contents when the source file
* is a directory.
*
* @throws DataImportException
* when a failure occurs while reading the source file.
*/
@Test( expected = DataImportException.class )
public void testLoadStringSourceIsDirectory( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , "." );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "TestFiles/i18n-external-file/file" ) );
instance.getString( );
}
/**
* Test loading a valid external string record and obtaining the contents when the original
* file's path is incorrect.
*
* @throws DataImportException
* when a failure occurs while reading the source file.
*/
@Test( expected = DataImportException.class )
public void testLoadStringBadParent( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "does-not-exist/does-not-exist" ) );
instance.getString( );
}
/**
* Test loading a valid external string record and obtaining the contents when the original
* file's path is a single file name.
*
* @throws DataImportException
* if a failure occurs while reading the source file.
*/
@Test
public void testLoadStringParentIsCurrentDirectory( )
throws DataImportException , NullPointerException
{
String definition = this.createExternalStringDefinition( "test" , "TestFiles/i18n-external-file/test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.setReadFrom( new File( "does-not-exist" ) );
instance.getString( );
}
/** Test validating a file string record with a short identifier and a source */
@Test
public void testValidateSimple( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/** Test validating an external string record with a camel case identifier and a source */
@Test
public void testValidateCamelCaseIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "testCamelCase" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/**
* Test validating an external string record with an identifier that includes a sequence of
* upper-case letters and a source
*/
@Test
public void testValidateCapsIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "testCAPSIdentifier" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/**
* Test validating an external string record with an identifier that includes numbers and some
* contents
*/
@Test
public void testValidateNumbersIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test123Numbers123" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/**
* Test rejecting an external string record with a <code>null</code> identifier and a source
*/
@Test( expected = DataImportException.class )
public void testValidateNullIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( null , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/** Test rejecting an external string record with an identifier that starts with a bad character */
@Test( expected = DataImportException.class )
public void testValidateBadFirstCharacterIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( " test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/**
* Test rejecting an external string record with an identifier that starts with an upper-case
* letter
*/
@Test( expected = DataImportException.class )
public void testValidateFirstCharacterWrongCaseIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "Test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/** Test rejecting an external string record with an identifier that includes "bad" characters */
@Test( expected = DataImportException.class )
public void testValidateBadMiddleCharacterIdentifier( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test Test" , "test.txt" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/** Test rejecting an external record with <code>null</code> contents */
@Test( expected = DataImportException.class )
public void testValidateNullSource( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test" , null );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/** Test rejecting an external record with empty contents */
@Test( expected = DataImportException.class )
public void testValidateEmptySource( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test" , "" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
/**
* Test rejecting an external record with contents the include only white space (spaces, tabs,
* new line, line feed)
*/
@Test( expected = DataImportException.class )
public void testValidateSpacesOnlySource( )
throws DataImportException
{
String definition = this.createExternalStringDefinition( "test" , " \t\r\n" );
FileString instance = this.createObject( definition , FileString.class );
instance.verifyData( );
}
}

View file

@ -0,0 +1,134 @@
package com.deepclone.lw.cli.xmlimport.data.i18n;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
/**
* Unit tests for the {@link I18NText} class
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class TestI18NText
extends BaseTest
{
/** The language definition that will be used in most tests */
private String languageDefinition;
/** Initialise a language definition to use while testing */
@Before
public void setUp( )
{
String xml = this.createInlineStringDefinition( "test" , "test" );
this.languageDefinition = this.createLanguageDefinition( "test" , "test" , xml );
}
/**
* Try loading a valid top-level I18N definition and make sure its contents are correct
*
* @throws DataImportException
* if the language definition check fails for some unknown reason
*/
@Test
public void testLoadValidDefinitions( )
throws DataImportException
{
String xml = this.createTopLevel( this.languageDefinition );
I18NText text = this.createObject( xml , I18NText.class );
int count = 0;
for ( LanguageDefinition definition : text ) {
definition.verifyData( );
count++;
}
assertEquals( 1 , count );
}
/**
* Try loading an empty top-level element
*
* @throws NullPointerException
* when the iterator is accessed
*/
@Test( expected = NullPointerException.class )
public void testLoadEmpty( )
throws NullPointerException
{
String xml = this.createTopLevel( );
I18NText text = this.createObject( xml , I18NText.class );
text.iterator( );
}
/**
* Try validating a correct top-level element
*
* @throws DataImportException
* if the check fails
*/
@Test
public void testValidateOK( )
throws DataImportException
{
String xml = this.createTopLevel( this.languageDefinition );
I18NText text = this.createObject( xml , I18NText.class );
text.verifyData( );
}
/**
* Try rejecting a top-level element that does not contain any language definition
*
* @throws DataImportException
* when the check fails
*/
@Test( expected = DataImportException.class )
public void testValidateEmpty( )
throws DataImportException
{
String xml = this.createTopLevel( );
I18NText text = this.createObject( xml , I18NText.class );
text.verifyData( );
}
/**
* Try rejecting a top-level element that contains an invalid language definition
*
* @throws DataImportException
* when the check fails
*/
@Test( expected = DataImportException.class )
public void testValidateBadDefinition( )
throws DataImportException
{
String xml = this.createTopLevel( this.createLanguageDefinition( null , null ) );
I18NText text = this.createObject( xml , I18NText.class );
text.verifyData( );
}
/**
* Try rejecting a top-level element that contains two valid but duplicate language definitions
*
* @throws DataImportException
* when the check fails
*/
@Test( expected = DataImportException.class )
public void testValidateDuplicateDefinition( )
throws DataImportException
{
String xml = this.createTopLevel( this.languageDefinition , this.languageDefinition );
I18NText text = this.createObject( xml , I18NText.class );
text.verifyData( );
}
}

View file

@ -0,0 +1,210 @@
package com.deepclone.lw.cli.xmlimport.data.i18n;
import java.io.File;
import java.lang.reflect.Method;
import org.junit.Test;
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
import com.deepclone.lw.cli.xmlimport.data.ImportableData;
import static org.junit.Assert.*;
/**
* Tests for the {@link InlineString} class
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class TestInlineString
extends BaseTest
{
/** Test loading a valid in-line string record */
@Test
public void testLoadStringOK( )
{
String definition = this.createInlineStringDefinition( "test" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
assertEquals( "test" , instance.getId( ) );
assertEquals( "Test" , instance.getString( ) );
}
/** Test loading an in-line string record without identifier */
@Test
public void testLoadStringNoIdentifier( )
{
String definition = this.createInlineStringDefinition( null , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
assertNull( instance.getId( ) );
assertEquals( "Test" , instance.getString( ) );
}
/** Test loading an in-line string record without contents */
@Test
public void testLoadStringNoContents( )
{
String definition = this.createInlineStringDefinition( "test" , null );
InlineString instance = this.createObject( definition , InlineString.class );
assertEquals( "test" , instance.getId( ) );
assertNull( instance.getString( ) );
}
/** Test validating an in-line string record with a short identifier and some contents */
@Test
public void testValidateSimple( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/** Test validating an in-line string record with a camel case identifier and some contents */
@Test
public void testValidateCamelCaseIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "testCamelCase" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Test validating an in-line string record with an identifier that includes a sequence of
* upper-case letters and some contents
*/
@Test
public void testValidateCapsIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "testCAPSIdentifier" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Test validating an in-line string record with an identifier that includes numbers and some
* contents
*/
@Test
public void testValidateNumbersIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test123Numbers123" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Test rejecting an in-line string record with a <code>null</code> identifier and some contents
*/
@Test( expected = DataImportException.class )
public void testValidateNullIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( null , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/** Test rejecting an in-line string record with an identifier that starts with a bad character */
@Test( expected = DataImportException.class )
public void testValidateBadFirstCharacterIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( " test" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Test rejecting an in-line string record with an identifier that starts with an upper-case
* letter
*/
@Test( expected = DataImportException.class )
public void testValidateFirstCharacterWrongCaseIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "Test" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/** Test rejecting an in-line string record with an identifier that includes "bad" characters */
@Test( expected = DataImportException.class )
public void testValidateBadMiddleCharacterIdentifier( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test Test" , "Test" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/** Test rejecting an in-line record with <code>null</code> contents */
@Test( expected = DataImportException.class )
public void testValidateNullContents( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test" , null );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/** Test rejecting an in-line record with empty contents */
@Test( expected = DataImportException.class )
public void testValidateEmptyContents( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test" , "" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Test rejecting an in-line record with contents the include only white space (spaces, tabs,
* new line, line feed)
*/
@Test( expected = DataImportException.class )
public void testValidateSpacesOnlyContents( )
throws DataImportException
{
String definition = this.createInlineStringDefinition( "test" , " \t\r\n" );
InlineString instance = this.createObject( definition , InlineString.class );
instance.verifyData( );
}
/**
* Make sure the class does not override {@link ImportableData#setReadFrom(java.io.File)}; if it
* does, new tests <strong>must</strong> be written.
*
* @throws NoSuchMethodException
* if the method has been deleted
* @throws SecurityException
* if the JVM set-up is getting in the wayy
*/
@Test
public void testNoSetReadFromOverride( )
throws SecurityException , NoSuchMethodException
{
Class< InlineString > cls = InlineString.class;
Method method = cls.getMethod( "setReadFrom" , File.class );
assertEquals( ImportableData.class , method.getDeclaringClass( ) );
}
}

View file

@ -0,0 +1,264 @@
package com.deepclone.lw.cli.xmlimport.data.i18n;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
/**
* Unit tests for the {@link LanguageDefinition} class
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class TestLanguageDefinition
extends BaseTest
{
/** The in-line string definition that will be used in most tests */
private String inlineDefinition;
/**
* Create a valid in-line string definition to be appended to language definitions.
*/
@Before
public void setUp( )
{
this.inlineDefinition = this.createInlineStringDefinition( "test" , "test" );
}
/**
* Test loading a valid language definition and make sure that all fields were set
* appropriately.
*
* @throws DataImportException
* if accessing the test string fails.
*/
@Test
public void testLoadValidDefinition( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
assertEquals( "t" , language.getId( ) );
assertEquals( "Test" , language.getName( ) );
int count = 0;
for ( StringDefinition stringDefinition : language ) {
assertEquals( InlineString.class , stringDefinition.getClass( ) );
assertEquals( "test" , stringDefinition.getId( ) );
assertEquals( "test" , stringDefinition.getString( ) );
count++;
}
assertEquals( 1 , count );
}
/**
* Test loading a language definition that has no identifier.
*/
@Test
public void testLoadNullIdentifier( )
{
String xml = this.createLanguageDefinition( null , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
assertNull( language.getId( ) );
}
/**
* Test loading a language definition that has no name
*/
@Test
public void testLoadNullName( )
{
String xml = this.createLanguageDefinition( "test" , null , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
assertNull( language.getName( ) );
}
/**
* Test loading a language definition that has no contents
*
* @throws NullPointerException
* when the language definition's iterator is accessed, as its contents will be
* <code>null</code>
*/
@Test( expected = NullPointerException.class )
public void testLoadNullContents( )
throws NullPointerException
{
String xml = this.createLanguageDefinition( "test" , "test" );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.iterator( );
}
/**
* Test validating a correct language definition.
*
* @throws DataImportException
* if validating the definition fails
*/
@Test
public void testValidateOK( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with a <code>null</code> identifier.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateNullIdentifier( )
throws DataImportException
{
String xml = this.createLanguageDefinition( null , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with an empty identifier.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateEmptyIdentifier( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "" , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with an identifier that contains white space only.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateWhiteSpaceIdentifier( )
throws DataImportException
{
String xml = this.createLanguageDefinition( " \t\n\r" , "Test" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with a <code>null</code> name.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateNullName( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , null , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with an empty name.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateEmptyName( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , "" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with a name that contains white space only.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateWhiteSpaceName( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , " \t\n\r" , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with no contents.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateNoContents( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , "Test" );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with invalid contents.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateBadContents( )
throws DataImportException
{
String strXML = this.createInlineStringDefinition( null , "test" );
String xml = this.createLanguageDefinition( "t" , "Test" , strXML );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
/**
* Test validating a language definition with duplicate contents.
*
* @throws DataImportException
* when validation fails
*/
@Test( expected = DataImportException.class )
public void testValidateDuplicateContents( )
throws DataImportException
{
String xml = this.createLanguageDefinition( "t" , "Test" , this.inlineDefinition , this.inlineDefinition );
LanguageDefinition language = this.createObject( xml , LanguageDefinition.class );
language.verifyData( );
}
}