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.
*/
public static class RequiredDefinitionMatcher implements DefinitionMatcher {
public static DefinitionMatcher RequiredDefinitionMatcher = new DefinitionMatcher() {
public boolean matches( ArgumentDefinition definition, Object key ) {
if( !(key instanceof Boolean) )
throw new IllegalArgumentException("RequiredDefinitionMatcher requires boolean key");
return definition.required == (Boolean)key;
}
}
};
}
/**

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.Arrays;
import java.util.EnumSet;
/**
* Created by IntelliJ IDEA.
@ -89,41 +90,67 @@ public class ParsingEngine {
return argumentMatches;
}
public enum ValidationType { MissingRequiredArgument,
InvalidArgument,
ValueMissingArgument,
TooManyValuesForArgument };
/**
* Validates the list of command-line argument matches. On
* failure throws an exception with detailed info about the particular failures.
* Validates the list of command-line argument matches.
* @param argumentMatches Matches to validate.
*/
public void validate( ArgumentMatches argumentMatches ) {
// Find missing required arguments.
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 );
}
validate( argumentMatches, EnumSet.noneOf(ValidationType.class) );
}
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.
Collection<ArgumentMatch> invalidArguments = argumentMatches.findMatches(null);
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( !skipValidationOf.contains(ValidationType.InvalidArgument) ) {
Collection<ArgumentMatch> invalidArguments = argumentMatches.findMatches(null);
if( invalidArguments.size() > 0 )
throw new InvalidArgumentException( invalidArguments );
}
if( !overvaluedArguments.isEmpty() )
throw new TooManyValuesForArgumentException(overvaluedArguments);
// Find values without an associated mate.
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 java.util.List;
import java.util.EnumSet;
/**
* Created by IntelliJ IDEA.
* User: mhanna
@ -217,6 +218,20 @@ public class ParsingEngineTest extends BaseTest {
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
public void unrequiredArgTest() {
final String[] commandLine = new String[0];
@ -359,4 +374,33 @@ public class ParsingEngineTest extends BaseTest {
@Argument(doc="my bool")
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) );
}
}