Skip to content

Commit

Permalink
Progress on test case XML.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmchilton committed Jul 29, 2024
1 parent 055849f commit 71de93b
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 20 deletions.
3 changes: 2 additions & 1 deletion lib/galaxy/tool_util/parameters/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
List,
)

from galaxy.tool_util.parser.interface import ToolSourceTest
from .models import (
DataCollectionParameterModel,
DataParameterModel,
Expand Down Expand Up @@ -45,7 +46,7 @@ def legacy_from_string(parameter: ToolParameterT, value: str, warnings: List[str


def test_case_state(
test_dict: Dict[str, Any], tool_parameter_bundle: ToolParameterBundle, profile: str
test_dict: ToolSourceTest, tool_parameter_bundle: ToolParameterBundle, profile: str
) -> TestCaseStateAndWarnings:
warnings: List[str] = []
inputs = test_dict["inputs"]
Expand Down
18 changes: 11 additions & 7 deletions lib/galaxy/tool_util/parameters/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
# + request_internal: This is a pydantic model to validate what Galaxy expects to find in the database,
# in particular dataset and collection references should be decoded integers.
StateRepresentationT = Literal[
"request", "request_internal", "job_internal", "test_case", "workflow_step", "workflow_step_linked"
"request", "request_internal", "job_internal", "test_case_xml", "workflow_step", "workflow_step_linked"
]


Expand Down Expand Up @@ -310,9 +310,9 @@ def py_type_internal(self) -> Type:
def py_type_test_case(self) -> Type:
base_model: Type
if self.multiple:
base_model = MultiDataRequestInternal
base_model = str
else:
base_model = DataTestCaseValue
base_model = str
return optional_if_needed(base_model, self.optional)

def pydantic_template(self, state_representation: StateRepresentationT) -> DynamicModelInformation:
Expand All @@ -324,7 +324,7 @@ def pydantic_template(self, state_representation: StateRepresentationT) -> Dynam
)
elif state_representation == "job_internal":
return dynamic_model_information_from_py_type(self, self.py_type_internal)
elif state_representation == "test_case":
elif state_representation == "test_case_xml":
return dynamic_model_information_from_py_type(self, self.py_type_test_case)
elif state_representation == "workflow_step":
return dynamic_model_information_from_py_type(self, type(None), requires_value=False)
Expand Down Expand Up @@ -961,9 +961,13 @@ class ToolParameterBundleModel(BaseModel):
input_models: List[ToolParameterT]


def parameters_by_name(tool_parameter_bundle: ToolParameterBundle) -> Dict[str, ToolParameterT]:
def parameters_by_name(inputs: Union[Iterable[ToolParameterModel], Iterable[ToolParameterT], ToolParameterBundle]) -> Dict[str, ToolParameterT]:
as_dict = {}
for input_model in simple_input_models(tool_parameter_bundle.input_models):
if hasattr(inputs, "input_models"):
inputs_list = simple_input_models(cast(ToolParameterBundle, inputs.input_models))
else:
inputs_list = cast(Union[Iterable[ToolParameterModel], Iterable[ToolParameterT]], inputs)
for input_model in inputs_list:
as_dict[input_model.name] = input_model
return as_dict

Expand Down Expand Up @@ -1001,7 +1005,7 @@ def create_job_internal_model(tool: ToolParameterBundle, name: str = "DynamicMod


def create_test_case_model(tool: ToolParameterBundle, name: str = "DynamicModelForTool") -> Type[BaseModel]:
return create_field_model(tool.input_models, name, "test_case")
return create_field_model(tool.input_models, name, "test_case_xml")


def create_workflow_step_model(tool: ToolParameterBundle, name: str = "DynamicModelForTool") -> Type[BaseModel]:
Expand Down
5 changes: 3 additions & 2 deletions lib/galaxy/tool_util/parameters/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
create_job_internal_model,
create_request_internal_model,
create_request_model,
create_test_case_model,
create_workflow_step_linked_model,
create_workflow_step_model,
StateRepresentationT,
Expand Down Expand Up @@ -92,12 +93,12 @@ def _parameter_model_for(cls, input_models: ToolParameterBundle) -> Type[BaseMod


class TestCaseToolState(ToolState):
state_representation: Literal["test_case"] = "test_case"
state_representation: Literal["test_case_xml"] = "test_case_xml"

@classmethod
def _parameter_model_for(cls, input_models: ToolParameterBundle) -> Type[BaseModel]:
# implement a test case model...
return create_request_internal_model(input_models)
return create_test_case_model(input_models)


class WorkflowStepToolState(ToolState):
Expand Down
1 change: 1 addition & 0 deletions lib/galaxy/tool_util/verify/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Any,
Dict,
List,
Optional,
Tuple,
)

Expand Down
16 changes: 8 additions & 8 deletions test/unit/tool_util/parameter_specification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ gx_int:
- parameter: "None"
- parameter: { 5 }
- parameter: {__class__: 'ConnectedValue'}
test_case_valid:
test_case_xml_valid:
- parameter: 5
- {}
test_case_invalid:
test_case_xml_invalid:
- parameter: null
- parameter: "5"
workflow_step_valid:
Expand Down Expand Up @@ -189,11 +189,11 @@ gx_select:
- parameter: "ex2"
request_internal_invalid:
- parameter: {}
test_case_valid:
test_case_xml_valid:
- parameter: 'ex2'
- parameter: '--ex1'
- {}
test_case_invalid:
test_case_xml_invalid:
- parameter: {}
- parameter: null
workflow_step_valid:
Expand Down Expand Up @@ -357,11 +357,11 @@ gx_float:
- parameter: "5"
- parameter: "5.0"
- parameter: { "moo": "cow" }
test_case_valid:
test_case_xml_valid:
- parameter: 5
- parameter: 5.0
- {}
test_case_invalid:
test_case_xml_invalid:
- parameter: null
- parameter: "5.0"
- parameter: "5.1"
Expand Down Expand Up @@ -394,12 +394,12 @@ gx_float_optional:
- parameter: "5.0"
- parameter: {}
- parameter: { "moo": "cow" }
test_case_valid:
test_case_xml_valid:
- parameter: 5
- parameter: 5.0
- {}
- parameter: null
test_case_invalid:
test_case_xml_invalid:
- parameter: "5.0"
- parameter: "5.1"
workflow_step_valid:
Expand Down
33 changes: 31 additions & 2 deletions test/unit/tool_util/test_parameter_test_cases.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import List

from galaxy.tool_util.parser.interface import ToolSourceTest
from galaxy.tool_util.parameters.case import test_case_state as case_state
from galaxy.tool_util.unittest_utils.parameters import (
parameter_bundle_for_file,
parameter_tool_source,
)
from galaxy.tool_util.parser.factory import get_tool_source
from galaxy.tool_util.unittest_utils import functional_test_tool_path
from galaxy.tool_util.models import parse_tool


def test_parameter_test_cases_validate():
Expand All @@ -14,16 +18,41 @@ def test_parameter_test_cases_validate():
assert len(warnings[1]) == 1


def test_validate_framework_test_tools():
tool_names = [
"checksum.xml",
"all_output_types.xml",
"cheetah_casting.xml",
"collection_creates_dynamic_list_of_pairs.xml",
"collection_creates_dynamic_nested.xml",
"collection_mixed_param.xml",
# Doesn't validate because it uses legacy functionality of setting nested parameters
# as unqualified root parameters.
# "boolean_conditional.xml",
]
for tool_name in tool_names:
tool_path = functional_test_tool_path(tool_name)
tool_source = get_tool_source(tool_path)
parsed_tool = parse_tool(tool_source)
profile = tool_source.parse_profile()
test_cases: List[ToolSourceTest] = tool_source.parse_tests_to_dict()["tests"]
for test_case in test_cases:
test_case_state_and_warnings = case_state(test_case, parsed_tool.inputs, profile)
tool_state = test_case_state_and_warnings.tool_state
warnings = test_case_state_and_warnings.warnings
assert tool_state.state_representation == "test_case_xml"


def validate_test_cases_for(tool_name: str) -> List[List[str]]:
tool_parameter_bundle = parameter_bundle_for_file(tool_name)
tool_source = parameter_tool_source(tool_name)
profile = tool_source.parse_profile()
test_cases = tool_source.parse_tests_to_dict()["tests"]
test_cases: List[ToolSourceTest] = tool_source.parse_tests_to_dict()["tests"]
warnings_by_test = []
for test_case in test_cases:
test_case_state_and_warnings = case_state(test_case, tool_parameter_bundle, profile)
tool_state = test_case_state_and_warnings.tool_state
warnings = test_case_state_and_warnings.warnings
assert tool_state.state_representation == "test_case"
assert tool_state.state_representation == "test_case_xml"
warnings_by_test.append(warnings)
return warnings_by_test

0 comments on commit 71de93b

Please sign in to comment.