Improvements to test format.

- Allow class: File and class: Collection on file and collection test descriptions.
- Allow collection_type: <type> in collection test descriptions. Implement this.
- Update test workflows to reflect these two things as best practices.
This commit is contained in:
John Chilton
2024-09-25 11:35:20 -04:00
parent 813ed02d53
commit 389f3989a0
16 changed files with 57 additions and 8 deletions
+21 -2
View File
@@ -13,12 +13,16 @@ from typing import (
)
from pydantic import (
AfterValidator,
AnyUrl,
BaseModel,
ConfigDict,
Field,
RootModel,
)
from typing_extensions import (
Annotated,
Literal,
NotRequired,
TypedDict,
)
@@ -113,7 +117,7 @@ class BaseTestOutputModel(StrictModel):
class TestDataOutputAssertions(BaseTestOutputModel):
pass
class_: Optional[Literal["File"]] = Field("File", alias="class")
class TestCollectionCollectionElementAssertions(StrictModel):
@@ -131,14 +135,29 @@ TestCollectionElementAssertion = Union[
TestCollectionCollectionElementAssertions.model_rebuild()
def _check_collection_type(v: str) -> str:
if len(v) == 0:
raise ValueError("Invalid empty collection_type specified.")
collection_levels = v.split(":")
for collection_level in collection_levels:
if collection_level not in ["list", "paired"]:
raise ValueError(f"Invalid collection_type specified [{v}]")
return v
CollectionType = Annotated[Optional[str], AfterValidator(_check_collection_type)]
class CollectionAttributes(StrictModel):
collection_type: Optional[str] = None
collection_type: CollectionType = None
class TestCollectionOutputAssertions(StrictModel):
class_: Optional[Literal["Collection"]] = Field("Collection", alias="class")
elements: Optional[Dict[str, TestCollectionElementAssertion]] = None
element_tests: Optional[Dict[str, "TestCollectionElementAssertion"]] = None
attributes: Optional[CollectionAttributes] = None
collection_type: CollectionType = None
TestOutputLiteral = Union[bool, int, float, str]
+13
View File
@@ -870,6 +870,19 @@ class TestCollectionOutputDef:
element_tests=as_dict["element_tests"],
)
@staticmethod
def from_yaml_test_format(as_dict):
if "attributes" not in as_dict:
as_dict["attributes"] = {}
attributes = as_dict["attributes"]
# setup preferred name "elements" in accordance with work in https://github.com/galaxyproject/planemo/pull/1417
# TODO: test this works recursively...
if "elements" in as_dict and "element_tests" not in as_dict:
as_dict["element_tests"] = as_dict["elements"]
if "collection_type" in as_dict:
attributes["type"] = as_dict["collection_type"]
return TestCollectionOutputDef.from_dict(as_dict)
def to_dict(self):
return dict(name=self.name, attributes=self.attrib, element_tests=self.element_tests)
@@ -9,6 +9,8 @@
filter_file: i1
outputs:
output:
class: Collection
collection_type: list
elements:
i1:
asserts:
@@ -3,7 +3,8 @@
job: {}
outputs:
out:
attributes: {collection_type: 'list'}
class: Collection
collection_type: list
elements:
'oe1-ie1':
asserts:
@@ -8,6 +8,8 @@
content: "0 mycoolline\n1 mysecondline\n"
outputs:
out:
class: Collection
collection_type: list
elements:
'samp1-0':
asserts:
@@ -10,6 +10,7 @@
type: raw
outputs:
output:
class: File
asserts:
- that: has_line
line: "parameter: 2"
@@ -10,7 +10,8 @@
content: B
outputs:
out1:
attributes: { collection_type: list }
class: Collection
collection_type: list
elements:
A:
asserts:
@@ -16,6 +16,8 @@
ext: 'expression.json'
outputs:
output:
class: Collection
collection_type: list
elements:
the_example_2:
asserts:
@@ -10,6 +10,7 @@
type: raw
outputs:
output:
class: File
asserts:
- that: has_text
text: "col 1,2"
@@ -9,6 +9,7 @@
type: raw
outputs:
output:
class: File
asserts:
- that: has_line
line: '--ex1,ex2,--ex3'
@@ -6,12 +6,14 @@
type: raw
outputs:
output_1:
class: File
asserts:
- that: has_text
text: 'Version 0.1'
- that: not_has_text
text: 'Version 0.2'
output_2:
class: File
asserts:
- that: has_text
text: 'Version 0.2'
@@ -18,5 +18,6 @@
type: File
outputs:
output:
class: File
metadata:
name: 'the_dataset_pair suffix'
@@ -5,8 +5,10 @@
replaceme: moocow
outputs:
out1:
class: File
metadata:
name: 'moocow name'
out2:
class: File
metadata:
name: 'moocow name 2'
@@ -6,8 +6,10 @@
type: raw
outputs:
out1:
class: File
metadata:
name: 'moocow name'
out2:
class: File
metadata:
name: 'moocow name 2'
@@ -6,8 +6,10 @@
type: raw
outputs:
out1:
class: File
metadata:
name: 'moocow name'
out2:
class: File
metadata:
name: 'moocow name 2'
+1 -4
View File
@@ -96,10 +96,7 @@ class TestWorkflow(ApiTestCase):
if is_collection_test:
assert isinstance(test_properties, dict)
test_properties["name"] = output_name
# setup preferred name "elements" in accordance with work in https://github.com/galaxyproject/planemo/pull/1417
test_properties["element_tests"] = test_properties["elements"]
output_def = TestCollectionOutputDef.from_dict(test_properties)
output_def = TestCollectionOutputDef.from_yaml_test_format(test_properties)
invocation_details = self.workflow_populator.get_invocation(run_summary.invocation_id, step_details=True)
assert output_name in invocation_details["output_collections"]
test_output = invocation_details["output_collections"][output_name]