From dcc0cc2b2d20c9f8748ced1a9a0ac86abe046d35 Mon Sep 17 00:00:00 2001 From: Tobias Klockau Date: Fri, 20 Oct 2023 12:14:01 +0200 Subject: [PATCH] feat: onthology schema --- .../onthology_schema_v1.yaml | 87 ++++++++ .../test_onthology_schema_v1.py | 196 ++++++++++++++++++ 2 files changed, 283 insertions(+) create mode 100644 raillabel_providerkit/validation/validate_onthology/onthology_schema_v1.yaml create mode 100644 tests/test_raillabel_providerkit/validation/validate_onthology/test_onthology_schema_v1.py diff --git a/raillabel_providerkit/validation/validate_onthology/onthology_schema_v1.yaml b/raillabel_providerkit/validation/validate_onthology/onthology_schema_v1.yaml new file mode 100644 index 0000000..8b3db11 --- /dev/null +++ b/raillabel_providerkit/validation/validate_onthology/onthology_schema_v1.yaml @@ -0,0 +1,87 @@ +# Copyright DB Netz AG and contributors +# SPDX-License-Identifier: Apache-2.0 + +"$schema": http://json-schema.org/draft-07/schema# +version: 1.0.0 + +definitions: + + attribute: + oneOf: + [ + "$ref": "#/definitions/boolean_attribute", + "$ref": "#/definitions/integer_attribute", + "$ref": "#/definitions/multi_select_attribute", + "$ref": "#/definitions/single_select_attribute", + "$ref": "#/definitions/string_attribute", + "$ref": "#/definitions/vector_attribute", + ] + + boolean_attribute: + const: boolean + + class: + additionalProperties: false + properties: + attributes: + additionalProperties: false + patternProperties: + "^": + "$ref": "#/definitions/attribute" + type: object + sensor_types: + additionalProperties: false + patternProperties: + "^(camera|lidar|radar)$": + "$ref": "#/definitions/sensor_type" + type: object + type: object + + integer_attribute: + const: integer + + single_select_attribute: + additionalProperties: false + properties: + type: + const: single-select + options: + type: array + items: + type: string + type: object + + multi_select_attribute: + additionalProperties: false + properties: + type: + const: multi-select + options: + type: array + items: + type: string + type: object + + sensor_type: + additionalProperties: false + properties: + attributes: + additionalProperties: false + patternProperties: + "^": + "$ref": "#/definitions/attribute" + type: object + type: object + + string_attribute: + const: string + + vector_attribute: + const: vector + +additionalProperties: false +patternProperties: + "^": + "$ref": "#/definitions/class" + +type: object diff --git a/tests/test_raillabel_providerkit/validation/validate_onthology/test_onthology_schema_v1.py b/tests/test_raillabel_providerkit/validation/validate_onthology/test_onthology_schema_v1.py new file mode 100644 index 0000000..85685b4 --- /dev/null +++ b/tests/test_raillabel_providerkit/validation/validate_onthology/test_onthology_schema_v1.py @@ -0,0 +1,196 @@ +# Copyright DB Netz AG and contributors +# SPDX-License-Identifier: Apache-2.0 + +import os +from pathlib import Path + +import jsonschema +import pytest +import yaml + +# == Fixtures ========================= + +@pytest.fixture +def schema_path() -> Path: + return ( + Path(__file__).parent.parent.parent.parent.parent + / "raillabel_providerkit" + / "validation" + / "validate_onthology" + / "onthology_schema_v1.yaml" + ) + +@pytest.fixture +def schema(schema_path) -> dict: + with schema_path.open() as f: + schema_data = yaml.safe_load(f) + return schema_data + +@pytest.fixture +def validator(schema) -> jsonschema.Draft7Validator: + return jsonschema.Draft7Validator(schema) + +def schema_errors(data: dict, validator: jsonschema.Draft7Validator) -> list[str]: + errors = [] + + for error in validator.iter_errors(data): + errors.append("$" + error.json_path[1:] + ": " + str(error.message)) + + return errors + +# == Tests ========================= + +def test_classes(validator): + data = { + "person": {}, + "train": {}, + } + + assert schema_errors(data, validator) == [] + +def test_class_unsupported_field(validator): + data = { + "person": { + "UNSUPPORTED_FIELD": {} + } + } + + assert schema_errors(data, validator) == [ + "$.person: Additional properties are not allowed ('UNSUPPORTED_FIELD' was unexpected)", + ] + + +def test_attributes_field(validator): + data = { + "person": { + "attributes": {} + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_string(validator): + data = { + "person": { + "attributes": { + "name": "string" + } + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_integer(validator): + data = { + "person": { + "attributes": { + "number_of_fingers": "integer" + } + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_boolean(validator): + data = { + "person": { + "attributes": { + "number_of_fingers": "boolean" + } + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_single_select(validator): + data = { + "person": { + "attributes": { + "carrying": { + "type": "single-select", + "options": [ + "groceries", + "a baby", + "the new Slicer-Dicer 3000 (WOW!)" + ] + } + } + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_multi_select(validator): + data = { + "person": { + "attributes": { + "carrying": { + "type": "multi-select", + "options": [ + "groceries", + "a baby", + "the new Slicer-Dicer 3000 (WOW!)" + ] + } + } + } + } + + assert schema_errors(data, validator) == [] + +def test_attribute_vector(validator): + data = { + "person": { + "attributes": { + "carrying": "vector" + } + } + } + + assert schema_errors(data, validator) == [] + + +def test_sensor_types(validator): + data = { + "person": { + "sensor_types": { + "camera": {}, + "lidar": {}, + "radar": {}, + } + } + } + + assert schema_errors(data, validator) == [] + +def test_sensor_types_unsupported_type(validator): + data = { + "person": { + "sensor_types": { + "UNSUPPORTED_SENSOR_TYPE": {}, + "lidar": {}, + } + } + } + + assert len(schema_errors(data, validator)) == 1 + +def test_sensor_type_attributes(validator): + data = { + "person": { + "sensor_types": { + "lidar": { + "attributes": { + "name": "string" + } + }, + } + } + } + + assert schema_errors(data, validator) == [] + + +if __name__ == "__main__": + os.system("clear") + pytest.main([__file__, "--disable-pytest-warnings", "--cache-clear", "-v"])