Skip to content
Snippets Groups Projects
Verified Commit d97c5426 authored by Daniel Hornung's avatar Daniel Hornung
Browse files

FIX: Fixed get_deep a bit, added more tests.

parent 94f6222f
Branches
Tags
2 merge requests!89ENH: JsonSchemaExporter accepts do_not_create parameter.,!82ENH: JsonSchemaExporter accepts do_not_create parameter.
Pipeline #43064 canceled
...@@ -75,8 +75,16 @@ class JsonSchemaExporter: ...@@ -75,8 +75,16 @@ class JsonSchemaExporter:
@staticmethod @staticmethod
def _make_required_list(rt: db.RecordType): def _make_required_list(rt: db.RecordType):
"""Return the list of names of properties with importance db.OBLIGATORY.""" """Return the list of names of properties with importance db.OBLIGATORY."""
return [prop.name for prop in rt.properties required_list = []
if rt.get_importance(prop.name) == db.OBLIGATORY] for prop in rt.properties:
if rt.get_importance(prop.name) != db.OBLIGATORY:
continue
prop_name = prop.name
if isinstance(prop.datatype, db.Entity):
prop_name = prop.datatype.name
required_list.append(prop_name)
return required_list
def _make_segment_from_prop(self, prop: db.Property): def _make_segment_from_prop(self, prop: db.Property):
"""Return the JSON Schema segment for the given property """Return the JSON Schema segment for the given property
......
...@@ -268,6 +268,9 @@ class DataModel(dict): ...@@ -268,6 +268,9 @@ class DataModel(dict):
This methods only uses data which is available in this datamodel, which acts kind of like a This methods only uses data which is available in this datamodel, which acts kind of like a
cache pool. cache pool.
Note that this may change this data model (subsequent "get" like calls may also return deep
content.)
""" """
entity = self.get(name) entity = self.get(name)
if not entity: if not entity:
...@@ -281,8 +284,15 @@ class DataModel(dict): ...@@ -281,8 +284,15 @@ class DataModel(dict):
continue continue
visited.add(prop.name) visited.add(prop.name)
if prop.name in self: if prop.name in self:
entity.remove_property(prop).add_property(self.get_deep(prop.name, deep_prop = self.get_deep(prop.name, visited=visited)
visited=visited)) linked_prop = entity.get_property(prop)
if not linked_prop.datatype:
if deep_prop.role == "Property":
linked_prop.datatype = deep_prop.datatype
elif deep_prop.role == "RecordType":
linked_prop.datatype = deep_prop
if deep_prop.description:
linked_prop.description = deep_prop.description
else: else:
print(f"Referenced property \"{prop.name}\" not found in data model.") print(f"Referenced property \"{prop.name}\" not found in data model.")
return entity return entity
...@@ -2,6 +2,7 @@ import unittest ...@@ -2,6 +2,7 @@ import unittest
import caosdb as db import caosdb as db
from caosadvancedtools.models.data_model import DataModel from caosadvancedtools.models.data_model import DataModel
from caosadvancedtools.models.parser import parse_model_from_string
class DataModelTest(unittest.TestCase): class DataModelTest(unittest.TestCase):
...@@ -33,3 +34,31 @@ class DataModelTest(unittest.TestCase): ...@@ -33,3 +34,31 @@ class DataModelTest(unittest.TestCase):
DataModel.sync_ids_by_name(l1, l2) DataModel.sync_ids_by_name(l1, l2)
assert l1["TestRecord"].id == rt.id assert l1["TestRecord"].id == rt.id
assert l1["TestRecord2"].id < 0 assert l1["TestRecord2"].id < 0
def test_get_deep(self):
model_recursive_str = """
RT1:
description: some description
obligatory_properties:
RT1:
"""
model_recursive = parse_model_from_string(model_recursive_str)
prop1 = model_recursive["RT1"].get_property("RT1")
assert prop1.datatype is None
# TODO The next line actually changes model_recursive in place, is this OK?
RT1 = model_recursive.get_deep("RT1")
assert model_recursive["RT1"] == RT1
model_unresolved_str = """
RT1:
description: some description
obligatory_properties:
unresolved:
"""
model_unresolved = parse_model_from_string(model_unresolved_str)
rt1_unresolved = model_unresolved["RT1"]
prop_unresolved = model_unresolved.get_deep("unresolved")
assert prop_unresolved.datatype is None
rt1_deep = model_unresolved.get_deep("RT1")
assert rt1_deep == rt1_unresolved
assert rt1_deep is rt1_unresolved
...@@ -83,6 +83,7 @@ def _mock_execute_query(query_string, unique=False, **kwargs): ...@@ -83,6 +83,7 @@ def _mock_execute_query(query_string, unique=False, **kwargs):
elif query_string == "SELECT name, id FROM FILE": elif query_string == "SELECT name, id FROM FILE":
return all_files return all_files
else: else:
print(f"Query string: {query_string}")
return db.Container() return db.Container()
...@@ -587,7 +588,9 @@ RT2: ...@@ -587,7 +588,9 @@ RT2:
rt1_dict = rtjs(model.get_deep("RT1")) rt1_dict = rtjs(model.get_deep("RT1"))
assert json.dumps(rt1_dict, indent=2) == """{ assert json.dumps(rt1_dict, indent=2) == """{
"type": "object", "type": "object",
"required": [], "required": [
"some_date"
],
"additionalProperties": true, "additionalProperties": true,
"properties": { "properties": {
"some_date": { "some_date": {
...@@ -609,13 +612,13 @@ RT2: ...@@ -609,13 +612,13 @@ RT2:
"description": "some description" "description": "some description"
}""" }"""
# Second test: with reference # Second test: with reference
rt2_deep = model.get_deep("RT2")
# from IPython import embed rt2_dict = rtjs(rt2_deep)
# embed()
rt2_dict = rtjs(model.get_deep("RT2"))
assert json.dumps(rt2_dict, indent=2) == """{ assert json.dumps(rt2_dict, indent=2) == """{
"type": "object", "type": "object",
"required": [], "required": [
"RT1"
],
"additionalProperties": true, "additionalProperties": true,
"properties": { "properties": {
"RT1": { "RT1": {
...@@ -630,7 +633,9 @@ RT2: ...@@ -630,7 +633,9 @@ RT2:
}, },
{ {
"type": "object", "type": "object",
"required": [], "required": [
"some_date"
],
"additionalProperties": true, "additionalProperties": true,
"properties": { "properties": {
"some_date": { "some_date": {
...@@ -660,7 +665,9 @@ RT2: ...@@ -660,7 +665,9 @@ RT2:
rt2_dict = rtjs(model.get_deep("RT2"), do_not_create=["RT1"]) rt2_dict = rtjs(model.get_deep("RT2"), do_not_create=["RT1"])
assert json.dumps(rt2_dict, indent=2) == """{ assert json.dumps(rt2_dict, indent=2) == """{
"type": "object", "type": "object",
"required": [], "required": [
"RT1"
],
"additionalProperties": true, "additionalProperties": true,
"properties": { "properties": {
"RT1": { "RT1": {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment