From f7c7a4f19724f0767f10f2ce88e0f2c09d67873f Mon Sep 17 00:00:00 2001 From: Daniel <d.hornung@indiscale.com> Date: Thu, 4 Apr 2024 16:51:19 +0200 Subject: [PATCH] FIX: Json schema exporter is more relaxed now. --- src/caosadvancedtools/json_schema_exporter.py | 36 +++++++++++++------ unittests/test_json_schema_exporter.py | 16 ++++----- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py index 5d18ad06..11e74369 100644 --- a/src/caosadvancedtools/json_schema_exporter.py +++ b/src/caosadvancedtools/json_schema_exporter.py @@ -147,16 +147,25 @@ class JsonSchemaExporter: def _make_segment_from_prop(self, prop: db.Property) -> Tuple[OrderedDict, dict]: """Return the JSON Schema and ui schema segments for the given property. - The result may either be a simple json schema segment, such as a `string - <https://json-schema.org/understanding-json-schema/reference/string>`_ element (or another - simple type), a combination such as `anyOf - <https://json-schema.org/understanding-json-schema/reference/combining#anyof>`_ or an `array - <https://json-schema.org/understanding-json-schema/reference/array>`_ element +The result may either be a simple json schema segment, such as a `string +<https://json-schema.org/understanding-json-schema/reference/string>`_ element (or another +simple type), a combination such as `anyOf +<https://json-schema.org/understanding-json-schema/reference/combining#anyof>`_ or an `array +<https://json-schema.org/understanding-json-schema/reference/array>`_ element - Parameters - ---------- - prop : db.Property - The property to be transformed. +Parameters +---------- +prop : db.Property + The property to be transformed. + +Returns +------- + +json_schema : OrderedDict + The Json schema. + +ui_schema : dict + An appropriate UI schema. """ json_prop = OrderedDict() ui_schema: dict = {} @@ -202,6 +211,11 @@ class JsonSchemaExporter: list_element_prop = db.Property( name=prop.name, datatype=get_list_datatype(prop.datatype, strict=True)) json_prop["items"], inner_ui_schema = self._make_segment_from_prop(list_element_prop) + if "type" in json_prop["items"] and ( + json_prop["items"]["type"] in ["boolean", "integer", "number", "string"] + ): + json_prop["items"]["type"] = [json_prop["items"]["type"], "null"] + if prop.name in self._multiple_choice and prop.name in self._do_not_create: # TODO: if not multiple_choice, but do_not_create: # "ui:widget" = "radio" & "ui:inline" = true @@ -235,8 +249,10 @@ class JsonSchemaExporter: json_prop["items"] = { "type": "object", "title": "Next file", + # TODO Why can't it be empty? # The wrapper object must wrap a file and can't be empty. - "required": ["file"], + "required": [ # "file" + ], # Wrapper objects must only contain the wrapped file. "additionalProperties": False, "properties": { diff --git a/unittests/test_json_schema_exporter.py b/unittests/test_json_schema_exporter.py index b8c1ddd1..1cea2f58 100644 --- a/unittests/test_json_schema_exporter.py +++ b/unittests/test_json_schema_exporter.py @@ -268,7 +268,7 @@ def test_units(): assert "ListWithUnit" in props assert props["ListWithUnit"]["type"] == "array" assert "items" in props["ListWithUnit"] - assert props["ListWithUnit"]["items"]["type"] == "number" + assert props["ListWithUnit"]["items"]["type"] == ["number", "null"] assert "description" in props["ListWithUnit"] assert props["ListWithUnit"]["description"] == "This is a list. Unit is m." assert "unit" not in props["ListWithUnit"] @@ -285,7 +285,7 @@ def test_units(): assert "ListWithUnit" in props assert props["ListWithUnit"]["type"] == "array" assert "items" in props["ListWithUnit"] - assert props["ListWithUnit"]["items"]["type"] == "number" + assert props["ListWithUnit"]["items"]["type"] == ["number", "null"] assert "description" in props["ListWithUnit"] assert props["ListWithUnit"]["description"] == "This is a list." assert "unit" in props["ListWithUnit"] @@ -306,14 +306,14 @@ def test_rt_with_list_props(): assert "ListOfIntegers" in props assert props["ListOfIntegers"]["type"] == "array" assert "items" in props["ListOfIntegers"] - assert props["ListOfIntegers"]["items"]["type"] == "integer" + assert props["ListOfIntegers"]["items"]["type"] == ["integer", "null"] assert "description" not in props["ListOfIntegers"]["items"] assert props["ListOfIntegers"]["description"] == "List of integers" assert "ListOfPatterns" in props assert props["ListOfPatterns"]["type"] == "array" assert "items" in props["ListOfPatterns"] - assert props["ListOfPatterns"]["items"]["type"] == "string" + assert props["ListOfPatterns"]["items"]["type"] == ["string", "null"] assert props["ListOfPatterns"]["items"]["pattern"] == "[A-Z]+" # Validation @@ -575,8 +575,7 @@ def test_rt_with_references(): assert "items" in schema["properties"]["FileProp"] items = schema["properties"]["FileProp"]["items"] assert items["type"] == "object" - assert len(items["required"]) == 1 - assert "file" in items["required"] + assert len(items["required"]) == 0 assert items["additionalProperties"] is False assert len(items["properties"]) == 1 assert "file" in items["properties"] @@ -588,7 +587,7 @@ def test_rt_with_references(): schema = rtjs(rt) assert schema["properties"]["FileProp"]["type"] == "array" - assert schema["properties"]["FileProp"]["items"]["type"] == "string" + assert schema["properties"]["FileProp"]["items"]["type"] == ["string", "null"] assert schema["properties"]["FileProp"]["items"]["format"] == "data-url" # wrap in array (cf. https://github.com/rjsf-team/react-jsonschema-form/issues/3957) @@ -599,8 +598,7 @@ def test_rt_with_references(): assert "items" in schema["properties"]["FileProp"] items = schema["properties"]["FileProp"]["items"] assert items["type"] == "object" - assert len(items["required"]) == 1 - assert "file" in items["required"] + assert len(items["required"]) == 0 assert items["additionalProperties"] is False assert len(items["properties"]) == 1 assert "file" in items["properties"] -- GitLab