diff --git a/lib/galaxy/tools/parameters/validation.py b/lib/galaxy/tools/parameters/validation.py index 4df3364011ec..e89b4bed574a 100644 --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -14,12 +14,6 @@ log = logging.getLogger(__name__) -def get_test_fname(fname): - """Returns test data filename""" - path, name = os.path.split(__file__) - full_path = os.path.join(path, "test", fname) - return full_path - class Validator(abc.ABC): """ @@ -86,45 +80,6 @@ def validate(self, value, trans=None, message=None, value_to_show=None): class RegexValidator(Validator): """ Validator that evaluates a regular expression - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... [Ff]oo - ... - ... ''')) - >>> t = p.validate("Foo") - >>> t = p.validate("foo") - >>> t = p.validate("Fop") - Traceback (most recent call last): - ... - ValueError: Value 'Fop' does not match regular expression '[Ff]oo' - >>> t = p.validate(["Foo", "foo"]) - >>> t = p.validate(["Foo", "Fop"]) - Traceback (most recent call last): - ... - ValueError: Value 'Fop' does not match regular expression '[Ff]oo' - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... [Ff]oo - ... - ... ''')) - >>> t = p.validate("Foo") - Traceback (most recent call last): - ... - ValueError: Value 'Foo' does match regular expression '[Ff]oo' - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Value 'foo' does match regular expression '[Ff]oo' - >>> t = p.validate("Fop") - >>> t = p.validate(["Fop", "foo"]) - Traceback (most recent call last): - ... - ValueError: Value 'foo' does match regular expression '[Ff]oo' - >>> t = p.validate(["Fop", "Fop"]) """ @classmethod @@ -175,40 +130,6 @@ def validate(self, value, trans=None): class InRangeValidator(ExpressionValidator): """ Validator that ensures a number is in a specified range - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(10) - Traceback (most recent call last): - ... - ValueError: Doh!! 10 not in range - >>> t = p.validate(15) - >>> t = p.validate(20) - >>> t = p.validate(21) - Traceback (most recent call last): - ... - ValueError: Doh!! 21 not in range - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(10) - >>> t = p.validate(15) - Traceback (most recent call last): - ... - ValueError: Value ('15') must not fulfill float('10') < value <= float('20') - >>> t = p.validate(20) - Traceback (most recent call last): - ... - ValueError: Value ('20') must not fulfill float('10') < value <= float('20') - >>> t = p.validate(21) """ @classmethod @@ -251,40 +172,6 @@ def __init__(self, message, range_min, range_max, exclude_min=False, exclude_max class LengthValidator(InRangeValidator): """ Validator that ensures the length of the provided string (value) is in a specific range - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - >>> t = p.validate("bar") - >>> t = p.validate("f") - Traceback (most recent call last): - ... - ValueError: Must have length of at least 2 and at most 8 - >>> t = p.validate("foobarbaz") - Traceback (most recent call last): - ... - ValueError: Must have length of at least 2 and at most 8 - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Must not have length of at least 2 and at most 8 - >>> t = p.validate("bar") - Traceback (most recent call last): - ... - ValueError: Must not have length of at least 2 and at most 8 - >>> t = p.validate("f") - >>> t = p.validate("foobarbaz") """ @classmethod @@ -303,44 +190,6 @@ def validate(self, value, trans=None): class DatasetOkValidator(Validator): """ Validator that checks if a dataset is in an 'ok' state - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> ok_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> ok_hda.set_dataset_state(model.Dataset.states.OK) - >>> notok_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> notok_hda.set_dataset_state(model.Dataset.states.EMPTY) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(ok_hda) - >>> t = p.validate(notok_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is still being generated, select another dataset or wait until it is completed - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(ok_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset must not be in state OK - >>> t = p.validate(notok_hda) """ @classmethod @@ -362,44 +211,6 @@ def validate(self, value, trans=None): class DatasetEmptyValidator(Validator): """ Validator that checks if a dataset has a positive file size. - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import Dataset, History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> empty_dataset = Dataset(external_filename=get_test_fname("empty.txt")) - >>> empty_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', dataset=empty_dataset, sa_session=sa_session)) - >>> full_dataset = Dataset(external_filename=get_test_fname("1.tabular")) - >>> full_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', dataset=full_dataset, sa_session=sa_session)) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(full_hda) - >>> t = p.validate(empty_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is empty, this tool expects non-empty files. - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(full_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is non-empty, this tool expects empty files. - >>> t = p.validate(empty_hda) """ @classmethod @@ -411,6 +222,8 @@ def from_element(cls, param, elem): return cls(message, negate) def validate(self, value, trans=None): + print(f"value {value}") + print(f"value {value.get_size()}") if value: super().validate(value.get_size() != 0) @@ -418,46 +231,6 @@ def validate(self, value, trans=None): class DatasetExtraFilesPathEmptyValidator(Validator): """ Validator that checks if a dataset's extra_files_path exists and is not empty. - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> has_extra_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_extra_hda.dataset.file_size = 10 - >>> has_extra_hda.dataset.total_size = 15 - >>> has_no_extra_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_no_extra_hda.dataset.file_size = 10 - >>> has_no_extra_hda.dataset.total_size = 10 - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_extra_hda) - >>> t = p.validate(has_no_extra_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset's extra_files_path directory is empty or does not exist, this tool expects non-empty extra_files_path directories associated with the selected input. - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_extra_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset's extra_files_path directory is non-empty or does exist, this tool expects empty extra_files_path directories associated with the selected input. - >>> t = p.validate(has_no_extra_hda) """ @classmethod @@ -476,58 +249,6 @@ def validate(self, value, trans=None): class MetadataValidator(Validator): """ Validator that checks for missing metadata - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import Dataset, History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> fname = get_test_fname('1.bed') - >>> bedds = Dataset(external_filename=fname) - >>> hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='bed', create_dataset=True, sa_session=sa_session, dataset=bedds)) - >>> hda.set_dataset_state(model.Dataset.states.OK) - >>> hda.set_meta() - >>> hda.metadata.strandCol = hda.metadata.spec["strandCol"].no_value - >>> param_xml = ''' - ... - ... ''' - >>> p = ToolParameter.build(None, XML(param_xml.format(check="nameCol", skip=""))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml.format(check="strandCol", skip=""))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes - >>> p = ToolParameter.build(None, XML(param_xml.format(check="", skip="dbkey,comment_lines,column_names,strandCol"))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml.format(check="", skip="dbkey,comment_lines,column_names,nameCol"))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes - >>> param_xml_negate = ''' - ... - ... ''' - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="strandCol", skip=""))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="nameCol", skip=""))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: At least one of the checked metadata 'nameCol' is set, click the pencil icon in the history item to edit / save the metadata attributes - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,nameCol"))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,strandCol"))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: At least one of the non skipped metadata 'dbkey,comment_lines,column_names,strandCol' is set, click the pencil icon in the history item to edit / save the metadata attributes """ requires_dataset_metadata = True @@ -562,45 +283,6 @@ def validate(self, value, trans=None): class UnspecifiedBuildValidator(Validator): """ Validator that checks for dbkey not equal to '?' - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> has_dbkey_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_dbkey_hda.set_dataset_state(model.Dataset.states.OK) - >>> has_dbkey_hda.metadata.dbkey = 'hg19' - >>> has_no_dbkey_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_no_dbkey_hda.set_dataset_state(model.Dataset.states.OK) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_dbkey_hda) - >>> t = p.validate(has_no_dbkey_hda) - Traceback (most recent call last): - ... - ValueError: Unspecified genome build, click the pencil icon in the history item to set the genome build - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_dbkey_hda) - Traceback (most recent call last): - ... - ValueError: Specified genome build, click the pencil icon in the history item to remove the genome build - >>> t = p.validate(has_no_dbkey_hda) """ requires_dataset_metadata = True @@ -626,31 +308,6 @@ def validate(self, value, trans=None): class NoOptionsValidator(Validator): """ Validator that checks for empty select list - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate('foo') - >>> t = p.validate(None) - Traceback (most recent call last): - ... - ValueError: No options available for selection - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... - ... ''')) - >>> t = p.validate('foo') - Traceback (most recent call last): - ... - ValueError: Options available for selection - >>> t = p.validate(None) """ @classmethod @@ -668,28 +325,6 @@ def validate(self, value, trans=None): class EmptyTextfieldValidator(Validator): """ Validator that checks for empty text field - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("") - Traceback (most recent call last): - ... - ValueError: Field requires a value - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Field must not set a value - >>> t = p.validate("") """ @classmethod diff --git a/test/unit/app/tools/test_parameter_validation.py b/test/unit/app/tools/test_parameter_validation.py index 77fcfee7030d..9a7ac9608e1c 100644 --- a/test/unit/app/tools/test_parameter_validation.py +++ b/test/unit/app/tools/test_parameter_validation.py @@ -1,6 +1,15 @@ +from galaxy.datatypes.sniff import get_test_fname +from galaxy.model import Dataset, History, HistoryDatasetAssociation from .util import BaseParameterTestCase +# def get_test_fname(fname): +# """Returns test data filename""" +# path, name = os.path.split(__file__) +# full_path = os.path.join(path, "test", fname) +# return full_path + + class TestParameterValidation(BaseParameterTestCase): def test_simple_ExpressionValidator(self): p = self._parameter_for( @@ -62,3 +71,371 @@ def test_ExpressionValidator_message(self): ValueError, r"Validator 'value.lower\(\) == \"foo\"' could not be evaluated on '1'" ): p.validate(1) + + def test_NoOptionsValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter index: No options available for selection"): + p.validate(None) + + p = self._parameter_for( + xml=""" + + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter index: Options available for selection"): + p.validate("foo") + p.validate(None) + + def test_EmptyTextfieldValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter blah: Field requires a value"): + p.validate("") + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Field must not set a value"): + p.validate("foo") + p.validate("") + + def test_RegexValidator(self): + p = self._parameter_for( + xml=""" + + [Ff]oo +""" + ) + p.validate("Foo") + p.validate("foo") + with self.assertRaisesRegex( + ValueError, "Parameter blah: Value 'Fop' does not match regular expression '\[Ff\]oo'" + ): + p.validate("Fop") + + # test also valitation of lists (for select parameters) + p.validate(["Foo", "foo"]) + with self.assertRaisesRegex( + ValueError, "Parameter blah: Value 'Fop' does not match regular expression '\[Ff\]oo'" + ): + p.validate(["Foo", "Fop"]) + + p = self._parameter_for( + xml=""" + + [Ff]oo +""" + ) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'Foo' does match regular expression '\[Ff\]oo'" + ): + p.validate("Foo") + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'foo' does match regular expression '\[Ff\]oo'" + ): + p.validate("foo") + p.validate("Fop") + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'foo' does match regular expression '\[Ff\]oo'" + ): + p.validate(["Fop", "foo"]) + p.validate(["Fop", "fop"]) + + def test_LengthValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + p.validate("bar") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must have length of at least 2 and at most 8"): + p.validate("f") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must have length of at least 2 and at most 8"): + p.validate("foobarbaz") + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Must not have length of at least 2 and at most 8"): + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must not have length of at least 2 and at most 8"): + p.validate("bar") + p.validate("f") + p.validate("foobarbaz") + + def test_InRangeValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Doh!! 10 not in range"): + p.validate(10) + p.validate(15) + p.validate(20) + with self.assertRaisesRegex(ValueError, "Parameter blah: Doh!! 21 not in range"): + p.validate(21) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(10) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value \('15'\) must not fulfill float\('10'\) < value <= float\('20'\)" + ): + p.validate(15) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value \('20'\) must not fulfill float\('10'\) < value <= float\('20'\)" + ): + p.validate(20) + p.validate(21) + + def test_DatasetOkValidator(self): + + sa_session = self.app.model.context + hisHistory() + with sa_session.begin(): + sa_session.add(hist) + ok_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + ok_hda.set_dataset_state(Dataset.states.OK) + notok_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + notok_hda.set_dataset_state(Dataset.states.EMPTY) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(ok_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset is still being generated, select another dataset or wait until it is completed", + ): + p.validate(notok_hda) + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: The selected dataset must not be in state OK"): + p.validate(ok_hda) + p.validate(notok_hda) + + def test_DatasetEmptyValidator(self): + sa_session = self.app.model.context + hisHistory() + with sa_session.begin(): + sa_session.add(hist) + empty_dataseDataset(external_filename=get_test_fname("empty.txt")) + empty_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", dataset=empty_dataset, sa_session=sa_session) + ) + full_dataseDataset(external_filename=get_test_fname("1.json")) + full_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", dataset=full_dataset, sa_session=sa_session) + ) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(full_hda) + with self.assertRaisesRegex( + ValueError, "Parameter blah: The selected dataset is empty, this tool expects non-empty files." + ): + p.validate(empty_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex( + ValueError, "Parameter blah: The selected dataset is non-empty, this tool expects empty files." + ): + p.validate(full_hda) + p.validate(empty_hda) + + def test_DatasetExtraFilesPathEmptyValidator(self): + sa_session = self.app.model.context + hisHistory() + with sa_session.begin(): + sa_session.add(hist) + has_extra_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_extra_hda.dataset.file_size = 10 + has_extra_hda.dataset.total_size = 15 + has_no_extra_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_no_extra_hda.dataset.file_size = 10 + has_no_extra_hda.dataset.total_size = 10 + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(has_extra_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset's extra_files_path directory is empty or does not exist, this tool expects non-empty extra_files_path directories associated with the selected input.", + ): + p.validate(has_no_extra_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset's extra_files_path directory is non-empty or does exist, this tool expects empty extra_files_path directories associated with the selected input.", + ): + p.validate(has_extra_hda) + p.validate(has_no_extra_hda) + + def test_MetadataValidator(self): + sa_session = self.app.model.context + hisHistory() + with sa_session.begin(): + sa_session.add(hist) + hda = hist.add_dataset( + HistoryDatasetAssociation( + id=1, + extension="bed", + create_dataset=True, + sa_session=sa_session, + dataset=Dataset(external_filename=get_test_fname("1.bed")), + ) + ) + hda.set_dataset_state(Dataset.states.OK) + hda.set_meta() + hda.metadata.strandCol = hda.metadata.spec["strandCol"].no_value + + param_xml = """ + + +""" + + p = self._parameter_for(xml=param_xml.format(check="nameCol", skip="")) + p.validate(hda) + + p = self._parameter_for(xml=param_xml.format(check="strandCol", skip="")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + p = self._parameter_for(xml=param_xml.format(check="", skip="dbkey,comment_lines,column_names,strandCol")) + p.validate(hda) + p = self._parameter_for(xml=param_xml.format(check="", skip="dbkey,comment_lines,column_names,nameCol")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + param_xml_negate = """ + + +""" + p = self._parameter_for(xml=param_xml_negate.format(check="strandCol", skip="")) + p.validate(hda) + p = self._parameter_for(xml=param_xml_negate.format(check="nameCol", skip="")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: At least one of the checked metadata 'nameCol' is set, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + p = self._parameter_for(xml=param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,nameCol")) + p.validate(hda) + p = self._parameter_for( + xml=param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,strandCol") + ) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: At least one of the non skipped metadata 'dbkey,comment_lines,column_names,strandCol' is set, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + def test_UnspecifiedBuildValidator(self): + sa_session = self.app.model.context + hisHistory() + with sa_session.begin(): + sa_session.add(hist) + has_dbkey_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_dbkey_hda.set_dataset_state(Dataset.states.OK) + has_dbkey_hda.metadata.dbkey = "hg19" + has_no_dbkey_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_no_dbkey_hda.set_dataset_state(Dataset.states.OK) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(has_dbkey_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Unspecified genome build, click the pencil icon in the history item to set the genome build", + ): + p.validate(has_no_dbkey_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Specified genome build, click the pencil icon in the history item to remove the genome build", + ): + p.validate(has_dbkey_hda) + p.validate(has_no_dbkey_hda)