mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
JSON assertions.
This commit is contained in:
@@ -9,7 +9,7 @@ from galaxy.util import unicodify
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
assertion_module_names = ["text", "tabular", "xml", "hdf5", "archive", "size"]
|
||||
assertion_module_names = ["text", "tabular", "xml", "json", "hdf5", "archive", "size"]
|
||||
|
||||
# Code for loading modules containing assertion checking functions, to
|
||||
# create a new module of assertion functions, create the needed python
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import json
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
cast,
|
||||
)
|
||||
|
||||
PropertyVisitor = Callable[[str, Any], Any]
|
||||
|
||||
|
||||
def any_in_tree(f: PropertyVisitor, json_tree: Any):
|
||||
if isinstance(json_tree, list):
|
||||
for element in json_tree:
|
||||
if any_in_tree(f, element):
|
||||
return True
|
||||
|
||||
elif isinstance(json_tree, dict):
|
||||
for key, value in json_tree.items():
|
||||
if f(cast(str, key), value):
|
||||
return True
|
||||
elif any_in_tree(f, value):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def assert_has_json_property_with_value(
|
||||
output,
|
||||
property: str,
|
||||
value: str,
|
||||
):
|
||||
"""Assert JSON tree contains the specified property with specified JSON-ified value."""
|
||||
output_json = json.loads(output)
|
||||
expected_value = json.loads(value)
|
||||
|
||||
def is_property(key, value):
|
||||
return key == property and value == expected_value
|
||||
|
||||
assert any_in_tree(is_property, output_json), f"Failed to find property [{property}] with JSON value [{value}]"
|
||||
|
||||
|
||||
def assert_has_json_property_with_text(
|
||||
output,
|
||||
property: str,
|
||||
text: str,
|
||||
):
|
||||
"""Assert JSON tree contains the specified property with specified JSON-ified value."""
|
||||
output_json = json.loads(output)
|
||||
|
||||
def is_property(key, value):
|
||||
return key == property and value == text
|
||||
|
||||
assert any_in_tree(is_property, output_json), f"Failed to find property [{property}] with text [{text}]"
|
||||
@@ -2070,6 +2070,7 @@ module.
|
||||
<xs:group ref="TestAssertionsTabular" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsArchive" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsXml" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsJson" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsH5" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
@@ -2126,6 +2127,15 @@ module.
|
||||
<xs:element name="element_text" type="AssertElementText"/>
|
||||
</xs:choice>
|
||||
</xs:group>
|
||||
<xs:group name="TestAssertionsJson">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en"><![CDATA[Assertions for JSON data]]></xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:choice>
|
||||
<xs:element name="has_json_property_with_value" type="AssertHasJsonPropertyWithValue"/>
|
||||
<xs:element name="has_json_property_with_text" type="AssertHasJsonPropertyWithText"/>
|
||||
</xs:choice>
|
||||
</xs:group>
|
||||
<xs:group name="TestAssertionsH5">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en"><![CDATA[Assertions for H5 data]]></xs:documentation>
|
||||
@@ -2356,6 +2366,7 @@ $attribute_list::5
|
||||
<xs:group ref="TestAssertionsGeneral" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsText" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsTabular" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsJson" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsXml" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:group ref="TestAssertionsH5" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
@@ -2607,6 +2618,46 @@ $attribute_list::5
|
||||
<xs:attributeGroup ref="AssertAttributePath"/>
|
||||
<xs:attributeGroup ref="AssertAttributeNegate"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AssertHasJsonPropertyWithValue">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en"><![CDATA[
|
||||
Asserts the JSON document contains a property or key with the specified JSON value.
|
||||
|
||||
```xml
|
||||
<has_json_property_with_value property="skipped_columns" value="[1, 3, 5]" />
|
||||
```
|
||||
|
||||
$attribute_list::5
|
||||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:attributeGroup ref="AssertAttributeProperty"/>
|
||||
<xs:attribute name="value" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en">JSON-ified value to search for. This will be converted from an XML string to JSON with Python's json.loads function.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AssertHasJsonPropertyWithText">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en"><![CDATA[
|
||||
Asserts the JSON document contains a property or key with the specified text (i.e. string) value.
|
||||
|
||||
```xml
|
||||
<has_json_property_with_text property="color" text="red" />
|
||||
```
|
||||
|
||||
$attribute_list::5
|
||||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:attributeGroup ref="AssertAttributeProperty"/>
|
||||
<xs:attribute name="text" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en">Text value to search for.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AssertHasH5Keys">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en"><![CDATA[
|
||||
@@ -2659,6 +2710,14 @@ $attribute_list::5
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="AssertAttributeProperty">
|
||||
<xs:attribute name="property" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en">JSON property to search the target for.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="AssertAttributeNegate">
|
||||
<xs:attribute name="negate" type="PermissiveBoolean" default="false">
|
||||
<xs:annotation>
|
||||
|
||||
@@ -216,6 +216,18 @@ XML_XML_ELEMENT = """
|
||||
</assert_contents>
|
||||
"""
|
||||
|
||||
JSON_HAS_PROPERTY_WITH_VALUE = """
|
||||
<assert_contents>
|
||||
<has_json_property_with_value property="{property}" value="{value}" />
|
||||
</assert_contents>
|
||||
"""
|
||||
|
||||
JSON_HAS_PROPERTY_WITH_WITH = """
|
||||
<assert_contents>
|
||||
<has_json_property_with_text property="{property}" text="{text}" />
|
||||
</assert_contents>
|
||||
"""
|
||||
|
||||
VALID_XML = """<root>
|
||||
<elem name="foo">
|
||||
<more name="bar">BAR</more>
|
||||
@@ -227,6 +239,9 @@ VALID_XML = """<root>
|
||||
"""
|
||||
INVALID_XML = '<root><elem name="foo"></root>'
|
||||
|
||||
VALID_SIMPLE_JSON = """{"foo": 5, "list": [{"textprop": "right"}]}"""
|
||||
|
||||
|
||||
if h5py is not None:
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||
h5name = tmp.name
|
||||
@@ -693,6 +708,26 @@ TESTS = [
|
||||
lambda x: "Text of element with path './/more': Did not expect text matching expression '(BA[RZ]|QUX)$' in output ('BAR')"
|
||||
in x,
|
||||
),
|
||||
(
|
||||
JSON_HAS_PROPERTY_WITH_VALUE.format(property="foo", value="5"),
|
||||
VALID_SIMPLE_JSON,
|
||||
lambda x: len(x) == 0,
|
||||
),
|
||||
(
|
||||
JSON_HAS_PROPERTY_WITH_VALUE.format(property="foo", value="6"),
|
||||
VALID_SIMPLE_JSON,
|
||||
lambda x: "Failed to find property [foo] with JSON value [6]" in x,
|
||||
),
|
||||
(
|
||||
JSON_HAS_PROPERTY_WITH_WITH.format(property="textprop", text="right"),
|
||||
VALID_SIMPLE_JSON,
|
||||
lambda x: len(x) == 0,
|
||||
),
|
||||
(
|
||||
JSON_HAS_PROPERTY_WITH_WITH.format(property="textprop", text="wrong"),
|
||||
VALID_SIMPLE_JSON,
|
||||
lambda x: "Failed to find property [textprop] with text [wrong]" in x,
|
||||
),
|
||||
# test has_archive_member with zip
|
||||
(
|
||||
ARCHIVE_HAS_ARCHIVE_MEMBER.format(path="(\\./)?testdir/file1.txt", content_assert="", all="false"),
|
||||
@@ -988,6 +1023,10 @@ TEST_IDS = [
|
||||
"xml_element failure (due to n)",
|
||||
"xml_element failure (due to min/max in combination with negate)",
|
||||
"xml_element failure (due to subassertion)",
|
||||
"has_json_property_with_value success",
|
||||
"has_json_property_with_value failure",
|
||||
"has_json_property_with_text success",
|
||||
"has_json_property_with_text failure",
|
||||
"has_archive_member zip",
|
||||
"has_archive_member tar",
|
||||
"has_archive_member non-archive",
|
||||
|
||||
Reference in New Issue
Block a user