Added real-world tests and tests for conditional validation.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@601 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-05-06 13:38:46 +00:00
parent 4ac9e72739
commit bfd6dfe36c
3 changed files with 100 additions and 29 deletions

View File

@ -150,13 +150,13 @@ class ArgumentDefinitions {
/** /**
* Find all required definitions. * Find all required definitions.
*/ */
public static class RequiredDefinitionMatcher implements DefinitionMatcher { public static DefinitionMatcher RequiredDefinitionMatcher = new DefinitionMatcher() {
public boolean matches( ArgumentDefinition definition, Object key ) { public boolean matches( ArgumentDefinition definition, Object key ) {
if( !(key instanceof Boolean) ) if( !(key instanceof Boolean) )
throw new IllegalArgumentException("RequiredDefinitionMatcher requires boolean key"); throw new IllegalArgumentException("RequiredDefinitionMatcher requires boolean key");
return definition.required == (Boolean)key; return definition.required == (Boolean)key;
} }
} };
} }
/** /**

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Collection; import java.util.Collection;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.
@ -89,41 +90,67 @@ public class ParsingEngine {
return argumentMatches; return argumentMatches;
} }
public enum ValidationType { MissingRequiredArgument,
InvalidArgument,
ValueMissingArgument,
TooManyValuesForArgument };
/** /**
* Validates the list of command-line argument matches. On * Validates the list of command-line argument matches.
* failure throws an exception with detailed info about the particular failures. * @param argumentMatches Matches to validate.
*/ */
public void validate( ArgumentMatches argumentMatches ) { public void validate( ArgumentMatches argumentMatches ) {
// Find missing required arguments. validate( argumentMatches, EnumSet.noneOf(ValidationType.class) );
Collection<ArgumentDefinition> requiredArguments = argumentDefinitions.findArgumentDefinitions( true, new ArgumentDefinitions.RequiredDefinitionMatcher() ); }
Collection<ArgumentDefinition> missingArguments = new ArrayList<ArgumentDefinition>();
for( ArgumentDefinition requiredArgument: requiredArguments ) {
if( !argumentMatches.hasMatch(requiredArgument) )
missingArguments.add( requiredArgument );
}
if( missingArguments.size() > 0 ) /**
throw new MissingArgumentException( missingArguments ); * Validates the list of command-line argument matches. On failure throws an exception with detailed info about the
* particular failures. Takes an EnumSet indicating which validation checks to skip.
* @param argumentMatches Matches to validate.
* @param skipValidationOf List of validation checks to skip.
*/
public void validate( ArgumentMatches argumentMatches, EnumSet<ValidationType> skipValidationOf ) {
// Find missing required arguments.
if( !skipValidationOf.contains(ValidationType.MissingRequiredArgument) ) {
Collection<ArgumentDefinition> requiredArguments =
argumentDefinitions.findArgumentDefinitions( true, ArgumentDefinitions.RequiredDefinitionMatcher );
Collection<ArgumentDefinition> missingArguments = new ArrayList<ArgumentDefinition>();
for( ArgumentDefinition requiredArgument: requiredArguments ) {
if( !argumentMatches.hasMatch(requiredArgument) )
missingArguments.add( requiredArgument );
}
if( missingArguments.size() > 0 )
throw new MissingArgumentException( missingArguments );
}
// Find invalid arguments. Invalid arguments will have a null argument definition. // Find invalid arguments. Invalid arguments will have a null argument definition.
Collection<ArgumentMatch> invalidArguments = argumentMatches.findMatches(null); if( !skipValidationOf.contains(ValidationType.InvalidArgument) ) {
if( invalidArguments.size() > 0 ) Collection<ArgumentMatch> invalidArguments = argumentMatches.findMatches(null);
throw new InvalidArgumentException( invalidArguments ); if( invalidArguments.size() > 0 )
throw new InvalidArgumentException( invalidArguments );
// Find values without an associated mate.
if( argumentMatches.MissingArgument.values().size() > 0 )
throw new InvalidArgumentValueException( argumentMatches.MissingArgument );
// Find arguments with too many values.
Collection<ArgumentMatch> overvaluedArguments = new ArrayList<ArgumentMatch>();
for( ArgumentMatch argumentMatch: argumentMatches ) {
// Warning: assumes that definition is not null (asserted by checks above).
if( !argumentMatch.definition.isMultiValued() && argumentMatch.values().size() > 1 )
overvaluedArguments.add(argumentMatch);
} }
if( !overvaluedArguments.isEmpty() ) // Find values without an associated mate.
throw new TooManyValuesForArgumentException(overvaluedArguments); if( !skipValidationOf.contains(ValidationType.ValueMissingArgument) ) {
if( argumentMatches.MissingArgument.values().size() > 0 )
throw new InvalidArgumentValueException( argumentMatches.MissingArgument );
}
// Find arguments with too many values.
if( !skipValidationOf.contains(ValidationType.TooManyValuesForArgument)) {
Collection<ArgumentMatch> overvaluedArguments = new ArrayList<ArgumentMatch>();
for( ArgumentMatch argumentMatch: argumentMatches ) {
// Warning: assumes that definition is not null (asserted by checks above).
if( argumentMatch.definition != null &&
!argumentMatch.definition.isMultiValued() &&
argumentMatch.values().size() > 1 )
overvaluedArguments.add(argumentMatch);
}
if( !overvaluedArguments.isEmpty() )
throw new TooManyValuesForArgumentException(overvaluedArguments);
}
} }
/** /**

View File

@ -7,6 +7,7 @@ import org.junit.Before;
import org.junit.Assert; import org.junit.Assert;
import java.util.List; import java.util.List;
import java.util.EnumSet;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.
* User: mhanna * User: mhanna
@ -217,6 +218,20 @@ public class ParsingEngineTest extends BaseTest {
public Integer value; public Integer value;
} }
@Test
public void disableValidationOfRequiredArgTest() {
final String[] commandLine = new String[0];
parsingEngine.addArgumentSources( RequiredArgProvider.class );
ArgumentMatches argumentMatches = parsingEngine.parse( commandLine );
parsingEngine.validate( argumentMatches, EnumSet.of(ParsingEngine.ValidationType.MissingRequiredArgument) );
RequiredArgProvider argProvider = new RequiredArgProvider();
parsingEngine.loadArgumentsIntoObject(argProvider, argumentMatches);
Assert.assertNull("Value should have remain unset",argProvider.value);
}
@Test @Test
public void unrequiredArgTest() { public void unrequiredArgTest() {
final String[] commandLine = new String[0]; final String[] commandLine = new String[0];
@ -359,4 +374,33 @@ public class ParsingEngineTest extends BaseTest {
@Argument(doc="my bool") @Argument(doc="my bool")
boolean myBool; boolean myBool;
} }
@Test
public void testValidParseForAnalysisType() {
final String[] commandLine = new String[] {"--analysis_type", "Pileup" };
parsingEngine.addArgumentSources( AnalysisTypeArgProvider.class );
ArgumentMatches argumentMatches = parsingEngine.parse( commandLine );
parsingEngine.validate(argumentMatches, EnumSet.of(ParsingEngine.ValidationType.MissingRequiredArgument) );
AnalysisTypeArgProvider argProvider = new AnalysisTypeArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider, argumentMatches );
Assert.assertEquals("Argument is not correctly initialized", "Pileup", argProvider.Analysis_Name );
}
private class AnalysisTypeArgProvider {
@Argument(fullName="analysis_type", shortName="T", doc="Type of analysis to run")
public String Analysis_Name = null;
}
@Test(expected=TooManyValuesForArgumentException.class)
public void testInvalidParseForAnalysisType() {
final String[] commandLine = new String[] {"--analysis_type", "Pileup", "-TCountReads" };
parsingEngine.addArgumentSources( AnalysisTypeArgProvider.class );
ArgumentMatches argumentMatches = parsingEngine.parse( commandLine );
parsingEngine.validate(argumentMatches, EnumSet.of(ParsingEngine.ValidationType.MissingRequiredArgument) );
}
} }