Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,618 changes: 930 additions & 688 deletions client/src/api/schema/schema.ts

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions lib/galaxy/tool_util/cwl/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,7 @@ def replacement_directory(value: Dict[str, Any]) -> Dict[str, Any]:
file_path = value.get("location", None) or value.get("path", None)
if file_path is None:
return value
if not os.path.isabs(file_path):
file_path = os.path.join(test_data_directory, file_path)
file_path = abs_path_or_uri(file_path, test_data_directory, resolve_data=resolve_data)

file_type = value.get("filetype", None) or value.get("format", None) or "directory"

Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/tool_util/verify/asserts/tabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def assert_has_n_columns(

For instance, ``<has_n_columns n="3"/>``. The assertion tests only the first line.
Number of columns can optionally also be specified with ``delta``. Alternatively the
range of expected occurences can be specified by ``min`` and/or ``max``.
range of expected occurrences can be specified by ``min`` and/or ``max``.

Optionally a column separator (``sep``, default is ``\t``) `and comment character(s)
can be specified (``comment``, default is empty string). The first non-comment
Expand Down
10 changes: 5 additions & 5 deletions lib/galaxy/tool_util/verify/asserts/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def assert_has_text(
lambda o, t: o.find(t) >= 0,
lambda o, t: len(re.findall(re.escape(t), o)),
"{expected} text '{text}' in output ('{output}')",
"{expected} {n}+-{delta} occurences of '{text}' in output ('{output}')",
"{expected} that the number of occurences of '{text}' in output is in [{min}:{max}] ('{output}')",
"{expected} {n}+-{delta} occurrences of '{text}' in output ('{output}')",
"{expected} that the number of occurrences of '{text}' in output is in [{min}:{max}] ('{output}')",
)


Expand Down Expand Up @@ -123,8 +123,8 @@ def assert_has_text_matching(
) -> None:
"""Asserts the specified output contains text matching the
regular expression specified by the argument expression.
If n is given the assertion checks for exacly n (nonoverlapping)
occurences.
If n is given the assertion checks for exactly n (nonoverlapping)
occurrences.
"""
_assert_presence_number(
output,
Expand Down Expand Up @@ -153,7 +153,7 @@ def assert_has_line_matching(
) -> None:
"""Asserts the specified output contains a line matching the
regular expression specified by the argument expression. If n is given
the assertion checks for exactly n occurences."""
the assertion checks for exactly n occurrences."""
_assert_presence_number(
output,
expression,
Expand Down
10 changes: 5 additions & 5 deletions lib/galaxy/tool_util/verify/asserts/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def assert_has_n_elements_with_path(
```

Alternatively to ``n`` and ``delta`` also the ``min`` and ``max`` attributes
can be used to specify the range of the expected number of occurences.
can be used to specify the range of the expected number of occurrences.
With ``negate`` the result of the assertion can be inverted.
"""
assert_xml_element(output, path, n=n, delta=delta, min=min, max=max, negate=negate)
Expand Down Expand Up @@ -222,7 +222,7 @@ def assert_xml_element(
) -> None:
"""Assert if the XML file contains element(s) or tag(s) with the specified
[XPath-like ``path``](https://lxml.de/xpathxslt.html). If ``n`` and ``delta``
or ``min`` and ``max`` are given also the number of occurences is checked.
or ``min`` and ``max`` are given also the number of occurrences is checked.

```xml
<assert_contents>
Expand All @@ -232,7 +232,7 @@ def assert_xml_element(
</assert_contents>
```

With ``negate="true"`` the outcome of the assertions wrt the precence and number
With ``negate="true"`` the outcome of the assertions wrt the presence and number
of ``path`` can be negated. If there are any sub assertions then check them against

- the content of the attribute ``attribute``
Expand All @@ -247,7 +247,7 @@ def assert_xml_element(
```

Sub-assertions are not subject to the ``negate`` attribute of ``xml_element``.
If ``all`` is ``true`` then the sub assertions are checked for all occurences.
If ``all`` is ``true`` then the sub assertions are checked for all occurrences.

Note that all other XML assertions can be expressed by this assertion (Galaxy
also implements the other assertions by calling this one).
Expand All @@ -269,7 +269,7 @@ def assert_xml_element(
lambda x, p: len(x.findall(p)),
"{expected} path '{text}' in xml",
"{expected} {n}+-{delta} occurrences of path '{text}' in xml",
"{expected} that the number of occurences of path '{text}' in xml is in [{min}:{max}]",
"{expected} that the number of occurrences of path '{text}' in xml is in [{min}:{max}]",
)

# check sub-assertions
Expand Down
41 changes: 30 additions & 11 deletions lib/galaxy/tool_util/verify/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from galaxy.tool_util.verify.asserts._types import AssertionParameter as AssertionParameterAnnotation
from galaxy.util.commands import shell

models_path = os.path.join(os.path.dirname(__file__), "assertion_models.py")
models_path = os.path.join(os.path.dirname(__file__), "..", "..", "tool_util_models", "assertions.py")
galaxy_xsd_path = os.path.join(os.path.dirname(__file__), "..", "xsd", "galaxy.xsd")

Children = Literal["allowed", "required", "forbidden"]
Expand Down Expand Up @@ -114,17 +114,19 @@ def check_non_negative_if_int(v: typing.Any):

class base_{{assertion.name}}_model(AssertionModel):
'''base model for {{assertion.name}} describing attributes.'''
model_config = ConfigDict(extra="forbid", title="base_{{assertion.name}}_model")
{% for parameter in assertion.parameters %}
{% if not parameter.is_deprecated %}
{{ parameter.name }}: {{ parameter.type_str }} = Field(
{{ parameter.field_default_str }},
title="{{ parameter.title }}",
description={{ assertion.name }}_{{ parameter.name }}_description,
)
{% endif %}
{% endfor %}
{% if assertion.children in ["required", "allowed"] %}
children: typing.Optional["assertion_list"] = None
asserts: typing.Optional["assertion_list"] = None
children: typing.Optional["assertion_list"] = Field(None, title="Children")
asserts: typing.Optional["assertion_list"] = Field(None, title="Asserts")

{% if assertion.children == "required" %}
@model_validator(mode='before')
Expand All @@ -139,17 +141,19 @@ def validate_children(self, data: typing.Any):

class base_{{assertion.name}}_model_relaxed(AssertionModel):
'''base model for {{assertion.name}} describing attributes.'''
model_config = ConfigDict(extra="forbid", title="base_{{assertion.name}}_model_relaxed")
{% for parameter in assertion.parameters %}
{% if not parameter.is_deprecated %}
{{ parameter.name }}: {{ parameter.lax_type_str }} = Field(
{{ parameter.field_default_str }},
title="{{ parameter.title }}",
description={{ assertion.name }}_{{ parameter.name }}_description,
)
{% endif %}
{% endfor %}
{% if assertion.children in ["required", "allowed"] %}
children: typing.Optional["assertion_list"] = None
asserts: typing.Optional["assertion_list"] = None
children: typing.Optional["assertion_list"] = Field(None, title="Children")
asserts: typing.Optional["assertion_list"] = Field(None, title="Asserts")

{% if assertion.children == "required" %}
@model_validator(mode='before')
Expand All @@ -164,15 +168,18 @@ def validate_children(self, data: typing.Any):

class {{assertion.name}}_model(base_{{assertion.name}}_model):
r\"\"\"{{ assertion.docstring }}\"\"\"
that: Literal["{{assertion.name}}"] = "{{assertion.name}}"
model_config = ConfigDict(extra="forbid", title="{{ assertion.title }}")
that: Literal["{{assertion.name}}"] = Field("{{assertion.name}}", title="That")

class {{assertion.name}}_model_nested(AssertionModel):
r\"\"\"Nested version of this assertion model.\"\"\"
{{assertion.name}}: base_{{assertion.name}}_model
model_config = ConfigDict(extra="forbid", title="{{ assertion.title }} (Nested)")
{{assertion.name}}: base_{{assertion.name}}_model = Field(..., title="{{ assertion.title }}")

class {{assertion.name}}_model_relaxed(base_{{assertion.name}}_model_relaxed):
r\"\"\"{{ assertion.docstring }}\"\"\"
that: Literal["{{assertion.name}}"] = "{{assertion.name}}"
model_config = ConfigDict(extra="forbid", title="{{ assertion.title }} (Relaxed)")
that: Literal["{{assertion.name}}"] = Field("{{assertion.name}}", title="That")
{% endfor %}

any_assertion_model_flat = Annotated[typing.Union[
Expand All @@ -193,15 +200,19 @@ class {{assertion.name}}_model_relaxed(base_{{assertion.name}}_model_relaxed):
{% endfor %}
], Field(discriminator="that")]

assertion_list = RootModel[typing.List[typing.Union[any_assertion_model_flat, any_assertion_model_nested]]]
class assertion_list(RootModel[typing.List[typing.Union[any_assertion_model_flat, any_assertion_model_nested]]]):
model_config = ConfigDict(title="assertion_list")


# used to model what the XML conversion should look like - not meant to be consumed outside of
# of Galaxy internals / linting.
relaxed_assertion_list = RootModel[typing.List[any_assertion_model_flat_relaxed]]
class relaxed_assertion_list(RootModel[typing.List[any_assertion_model_flat_relaxed]]):
model_config = ConfigDict(title="relaxed_assertion_list")

class assertion_dict(AssertionModel):
model_config = ConfigDict(extra="forbid", title="assertion_dict")
{% for assertion in assertions %}
{{assertion.name}}: typing.Optional[base_{{assertion.name}}_model] = None
{{assertion.name}}: typing.Optional[base_{{assertion.name}}_model] = Field(None, title="{{ assertion.title }}")
{% endfor %}


Expand Down Expand Up @@ -338,6 +349,10 @@ def __init__(self, name: str, type: str, default_value):
self.type = type
self.default_value = default_value

@property
def title(self) -> str:
return " ".join(w.capitalize() for w in self.name.split("_"))

@property
def description(self) -> str:
type = self.type
Expand Down Expand Up @@ -490,6 +505,10 @@ def __init__(
self.children = children
self.module_and_function = module_and_function

@property
def title(self) -> str:
return "Assert " + " ".join(w.capitalize() for w in self.name.split("_"))


def arg_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=DESCRIPTION)
Expand Down
16 changes: 8 additions & 8 deletions lib/galaxy/tool_util/xsd/galaxy.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -2532,7 +2532,7 @@ $attribute_list::5]]></xs:documentation>
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[Asserts the specified output contains a line matching the
regular expression specified by the argument expression. If n is given
the assertion checks for exactly n occurences.
the assertion checks for exactly n occurrences.

$attribute_list::5]]></xs:documentation>
</xs:annotation>
Expand Down Expand Up @@ -2653,8 +2653,8 @@ $attribute_list::5]]></xs:documentation>
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[Asserts the specified output contains text matching the
regular expression specified by the argument expression.
If n is given the assertion checks for exacly n (nonoverlapping)
occurences.
If n is given the assertion checks for exactly n (nonoverlapping)
occurrences.

$attribute_list::5]]></xs:documentation>
</xs:annotation>
Expand Down Expand Up @@ -2715,7 +2715,7 @@ number (``n``) of columns.

For instance, ``<has_n_columns n="3"/>``. The assertion tests only the first line.
Number of columns can optionally also be specified with ``delta``. Alternatively the
range of expected occurences can be specified by ``min`` and/or ``max``.
range of expected occurrences can be specified by ``min`` and/or ``max``.

Optionally a column separator (``sep``, default is `` ``) `and comment character(s)
can be specified (``comment``, default is empty string). The first non-comment
Expand Down Expand Up @@ -2991,7 +2991,7 @@ For example:
```

Alternatively to ``n`` and ``delta`` also the ``min`` and ``max`` attributes
can be used to specify the range of the expected number of occurences.
can be used to specify the range of the expected number of occurrences.
With ``negate`` the result of the assertion can be inverted.

$attribute_list::5]]></xs:documentation>
Expand Down Expand Up @@ -3043,7 +3043,7 @@ $attribute_list::5]]></xs:documentation>
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[Assert if the XML file contains element(s) or tag(s) with the specified
[XPath-like ``path``](https://lxml.de/xpathxslt.html). If ``n`` and ``delta``
or ``min`` and ``max`` are given also the number of occurences is checked.
or ``min`` and ``max`` are given also the number of occurrences is checked.

```xml
<assert_contents>
Expand All @@ -3053,7 +3053,7 @@ or ``min`` and ``max`` are given also the number of occurences is checked.
</assert_contents>
```

With ``negate="true"`` the outcome of the assertions wrt the precence and number
With ``negate="true"`` the outcome of the assertions wrt the presence and number
of ``path`` can be negated. If there are any sub assertions then check them against

- the content of the attribute ``attribute``
Expand All @@ -3068,7 +3068,7 @@ of ``path`` can be negated. If there are any sub assertions then check them agai
```

Sub-assertions are not subject to the ``negate`` attribute of ``xml_element``.
If ``all`` is ``true`` then the sub assertions are checked for all occurences.
If ``all`` is ``true`` then the sub assertions are checked for all occurrences.

Note that all other XML assertions can be expressed by this assertion (Galaxy
also implements the other assertions by calling this one).
Expand Down
Loading
Loading