diff --git a/definitions/EiffelActivityCanceledEvent/5.0.0.yml b/definitions/EiffelActivityCanceledEvent/5.0.0.yml index 7618e0cf..eac55b69 100644 --- a/definitions/EiffelActivityCanceledEvent/5.0.0.yml +++ b/definitions/EiffelActivityCanceledEvent/5.0.0.yml @@ -38,6 +38,12 @@ properties: additionalProperties: false links: type: array + contains: + type: object + properties: + type: + enum: + - ACTIVITY_EXECUTION items: $ref: ../EiffelEventLink/2.0.0.yml required: diff --git a/schemas/EiffelActivityCanceledEvent/5.0.0.json b/schemas/EiffelActivityCanceledEvent/5.0.0.json index b38672f7..59fda088 100644 --- a/schemas/EiffelActivityCanceledEvent/5.0.0.json +++ b/schemas/EiffelActivityCanceledEvent/5.0.0.json @@ -157,6 +157,16 @@ }, "links": { "type": "array", + "contains": { + "type": "object", + "properties": { + "type": { + "enum": [ + "ACTIVITY_EXECUTION" + ] + } + } + }, "items": { "type": "object", "properties": { diff --git a/test_definitions.py b/test_definitions.py index 448002d7..ce8a8c34 100644 --- a/test_definitions.py +++ b/test_definitions.py @@ -14,7 +14,7 @@ # limitations under the License. import logging -import pathlib +from pathlib import Path import pytest @@ -32,73 +32,99 @@ logger.addHandler(console_handler) -manifest = generate_manifest.Manifest("event_manifest.yml") +class DefinitionFile: + """Helper class that loads a type definition and tracks its source + path and desired testcase id. + """ + def __init__(self, path: Path): + self.path = path + self.definition = definition_loader.load(path) + self.id = str(Path(path.parent.name) / path.stem) -def do_test_history_table_contains_current_version( - event_type, event_version, definition -): + +# Preloaded type definitions for reuse in each parametrized testcase. +EVENT_DEFINITIONS = [ + DefinitionFile(p) for p in Path(".").glob("definitions/Eiffel*Event/*.yml") +] +EVENT_DEFINITION_IDS = [d.id for d in EVENT_DEFINITIONS] + + +@pytest.fixture(scope="session") +def manifest(): + return generate_manifest.Manifest("event_manifest.yml") + + +@pytest.mark.parametrize( + "definition_file", + EVENT_DEFINITIONS, + ids=EVENT_DEFINITION_IDS, +) +def test_history_table_contains_current_version(definition_file): + event_version = definition_file.path.stem assert [ entry - for entry in definition.get("_history", []) + for entry in definition_file.definition.get("_history", []) if entry.get("version") == event_version - ], f"History table entry missing for {event_type} {event_version}" + ], "History table entry missing" -def do_test_history_table_contains_valid_release(event_type, event_version, definition): - for entry in definition.get("_history", []): +@pytest.mark.parametrize( + "definition_file", + EVENT_DEFINITIONS, + ids=EVENT_DEFINITION_IDS, +) +def test_history_table_contains_valid_release(definition_file, manifest): + for entry in definition_file.definition.get("_history", []): edition = entry.get("introduced_in", None) if edition is not None: assert manifest.is_edition_tag( edition - ), f"Nonexistent edition '{edition}' in history table for {event_type} {event_version}" + ), f"Nonexistent edition '{edition}' in history table" -def do_test_history_table_matches_manifest(event_type, event_version, definition): - for entry in definition.get("_history", []): +@pytest.mark.parametrize( + "definition_file", + EVENT_DEFINITIONS, + ids=EVENT_DEFINITION_IDS, +) +def test_history_table_matches_manifest(definition_file, manifest): + event_type = definition_file.path.parent.name + for entry in definition_file.definition.get("_history", []): edition = entry.get("introduced_in", None) event_version_of_edition = entry.get("version") if edition is not None: assert manifest.is_in_edition( edition, event_type, event_version_of_edition - ), f"{event_version_of_edition} not part of '{edition}' as described in history table for {event_type} {event_version}" + ), f"{event_version_of_edition} not part of '{edition}' as described in history table" -def do_test_links(event_type, event_version, definition): - schema_version = definition.get("$schema") +@pytest.mark.parametrize( + "definition_file", + EVENT_DEFINITIONS, + ids=EVENT_DEFINITION_IDS, +) +def test_links(definition_file, manifest): # Checking for required link is only valid for event types with recent meta schemas - if "draft-04" in schema_version: + if "draft-04" in definition_file.definition.get("$schema"): assert True else: contained_link_types = [] required_link_types = [] - schema_links = definition.get("properties").get("links") - if schema_links.get("contains"): + schema_links_contains = ( + definition_file.definition.get("properties").get("links").get("contains") + ) + if schema_links_contains: contained_link_types = ( - schema_links.get("contains").get("properties").get("type").get("enum") + schema_links_contains.get("properties").get("type").get("enum") ) - links = definition.get("_links", {}) + contained_link_types.sort() + links = definition_file.definition.get("_links", {}) for link in links: if links[link]["required"]: required_link_types.append(link) + required_link_types.sort() assert ( - contained_link_types.sort() == required_link_types.sort() + contained_link_types == required_link_types ), f"Required '{required_link_types}' and contained '{contained_link_types}' link types do not match" - - -@pytest.mark.parametrize( - "event_definition_path", - pathlib.Path(".").glob("definitions/Eiffel*Event/*.yml"), -) -def test_definition_file(event_definition_path): - logger.info("Definition check - %s", event_definition_path) - event_type = event_definition_path.parent.name - event_version = event_definition_path.stem - definition = definition_loader.load(event_definition_path) - do_test_history_table_contains_current_version( - event_type, event_version, definition - ) - do_test_history_table_contains_valid_release(event_type, event_version, definition) - do_test_history_table_matches_manifest(event_type, event_version, definition) - do_test_links(event_type, event_version, definition)