Implement min/max for multiple data input parameters.

This commit is contained in:
John Chilton
2015-09-21 15:51:58 +01:00
parent 2bfc12d666
commit 87d5063a0d
3 changed files with 53 additions and 6 deletions
+39 -5
View File
@@ -1764,6 +1764,22 @@ class DataToolParameter( BaseDataToolParameter ):
self.validators.append( validation.MetadataValidator() )
self._parse_formats( trans, tool, input_source )
self.multiple = input_source.get_bool('multiple', False)
self.min = input_source.get( 'min' )
self.max = input_source.get( 'max' )
if self.min:
try:
self.min = int( self.min )
except:
raise ValueError( "An integer is required for min property." )
if self.max:
try:
self.max = int( self.max )
except:
raise ValueError( "An integer is required for max property." )
if not self.multiple and (self.min is not None):
raise ValueError( "Cannot specify min property on single data parameter '%s'. Set multiple=\"true\" to enable this option." % self.name )
if not self.multiple and (self.max is not None):
raise ValueError( "Cannot specify max property on single data parameter '%s'. Set multiple=\"true\" to enable this option." % self.name )
self.is_dynamic = True
self._parse_options( input_source )
# Load conversions required for the dataset input
@@ -2052,17 +2068,31 @@ class DataToolParameter( BaseDataToolParameter ):
return "No dataset"
def validate( self, value, history=None ):
dataset_count = 0
for validator in self.validators:
if value and self.multiple:
if isinstance(value, list):
for v in value:
validator.validate( v, history )
elif isinstance(value, galaxy.model.HistoryDatasetCollectionAssociation):
for v in value.collection.dataset_instances:
if not isinstance( value, list ):
value = [ value ]
for v in value:
if isinstance(v, galaxy.model.HistoryDatasetCollectionAssociation):
for dataset_instance in v.collection.dataset_instances:
dataset_count += 1
validator.validate( dataset_instance, history )
else:
dataset_count += 1
validator.validate( v, history )
else:
if value:
dataset_count += 1
validator.validate( value, history )
if self.min is not None:
if self.min > dataset_count:
raise ValueError( "At least %d datasets are required." % self.min )
if self.max is not None:
if self.max < dataset_count:
raise ValueError( "At most %d datasets are required." % self.max )
def get_dependencies( self ):
"""
Get the *names* of the other params this param depends on.
@@ -2124,6 +2154,10 @@ class DataToolParameter( BaseDataToolParameter ):
d['extensions'] = extensions
d['edam_formats'] = edam_formats
d['multiple'] = self.multiple
if self.multiple:
# For consistency, should these just always be in the dict?
d['min'] = self.min
d['max'] = self.max
d['options'] = {'hda': [], 'hdca': []}
# return default content if context is not available
+13
View File
@@ -62,6 +62,19 @@ class ToolsTestCase( api.ApiTestCase ):
self._assert_has_keys( case2_inputs[ 0 ], 'name', 'type', 'label', 'help', 'argument' )
assert case2_inputs[ 0 ][ "name" ] == "seed"
@skip_without_tool( "multi_data_param" )
def test_show_multi_data( self ):
tool_info = self._show_valid_tool( "multi_data_param" )
f1_info, f2_info = tool_info[ "inputs" ][ 0 ], tool_info[ "inputs" ][ 1 ]
self._assert_has_keys( f1_info, "min", "max" )
assert f1_info["min"] == 1
assert f1_info["max"] == 1235
self._assert_has_keys( f2_info, "min", "max" )
assert f2_info["min"] is None
assert f2_info["max"] is None
def _show_valid_tool( self, tool_id ):
tool_show_response = self._get( "tools/%s" % tool_id, data=dict( io_details=True ) )
self._assert_status_code_is( tool_show_response, 200 )
+1 -1
View File
@@ -6,7 +6,7 @@
cat ${" ".join(map(str, $f2))} >> $out2
</command>
<inputs>
<param name="f1" type="data" format="txt" multiple="true" label="Data 1" />
<param name="f1" type="data" format="txt" multiple="true" label="Data 1" min="1" max="1235" />
<param name="f2" type="data" format="txt" multiple="true" label="Data 2" />
<conditional name="advanced">
<param name="full" type="select" label="Parameter Settings">