Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions terminusdb_client/schema/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ def __init__(cls, name, bases, nmspc):

# _abstract should not be inherited
cls._abstract = nmspc.get("_abstract")
# _unfoldable should not be inherited
cls._unfoldable = nmspc.get("_unfoldable")
# _shared should not be inherited
cls._shared = nmspc.get("_shared")
cls._instances = set()

def init(obj, *args, **kwargs):
Expand Down Expand Up @@ -288,6 +292,10 @@ def _to_dict(cls, skip_checking=False):
result["@key"] = {"@type": "Random"}
if hasattr(cls, "_abstract") and cls._abstract is not None:
result["@abstract"] = cls._abstract
if hasattr(cls, "_unfoldable") and cls._unfoldable is not None:
result["@unfoldable"] = cls._unfoldable
if hasattr(cls, "_shared") and cls._shared is not None:
result["@shared"] = cls._shared
if hasattr(cls, "_key") and not hasattr(cls, "_subdocument"):
if hasattr(cls._key, "_keys"):
result["@key"] = {
Expand Down Expand Up @@ -591,6 +599,10 @@ def _construct_class(self, class_obj_dict):
attributedict["_subdocument"] = value
elif key == "@abstract":
attributedict["_abstract"] = value
elif key == "@unfoldable":
attributedict["_unfoldable"] = value
elif key == "@shared":
attributedict["_shared"] = value
elif key == "@key":
key_type = value.get("@type")
if key_type and key_type == "Random":
Expand Down
10 changes: 10 additions & 0 deletions terminusdb_client/scripts/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ def add_subdoc(self):
def add_abstract(self):
self.script += " _abstract = []\n"

def add_unfoldable(self):
self.script += " _unfoldable = []\n"

def add_shared(self):
self.script += " _shared = []\n"

def add_docstring(self, obj_dict):
self.script += ' """'
if obj_dict["@documentation"].get("@comment"):
Expand Down Expand Up @@ -297,6 +303,10 @@ def add_docstring(self, obj_dict):

if obj.get("@abstract") is not None:
result_obj.add_abstract()
if obj.get("@unfoldable") is not None:
result_obj.add_unfoldable()
if obj.get("@shared") is not None:
result_obj.add_shared()
result_list.append(result_obj)

for key, value in obj.items():
Expand Down
88 changes: 88 additions & 0 deletions terminusdb_client/tests/test_Schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,34 @@ class ChildAbs(Abstract):
# _abstract = False


class Unfoldable(DocumentTemplate):
"""This is unfoldable class"""

_schema = Schema()
_unfoldable = []
name: str


class ChildUnf(Unfoldable):
"""Child of unfoldable class, should not be unfoldable by default"""

# _unfoldable = False


class Shared(DocumentTemplate):
"""This is shared class"""

_schema = Schema()
_shared = []
name: str


class ChildShared(Shared):
"""Child of shared class, should not be shared by default"""

# _shared = False


class TypeCheck(DocumentTemplate):
"""For checking instance types"""

Expand Down Expand Up @@ -112,6 +140,66 @@ def test_abstract_class_child():
assert "@abstract" not in ChildAbs._to_dict()


def test_unfoldable_class():
it_ok_to_create = Unfoldable(name="It's ok")
assert it_ok_to_create.name == "It's ok"
assert Unfoldable._unfoldable == []
assert Unfoldable._to_dict().get("@unfoldable") == []


def test_unfoldable_class_child():
it_ok_to_create = ChildUnf(name="It's ok")
assert it_ok_to_create.name == "It's ok"
assert ChildUnf._unfoldable is None
assert "@unfoldable" not in ChildUnf._to_dict()


def test_construct_class_with_unfoldable():
schema_json = {
"@id": "UnfoldableDoc",
"@type": "Class",
"@unfoldable": [],
"@key": {"@type": "Random"},
"name": "xsd:string",
}
schema = Schema()
test_result = schema._construct_class(schema_json)
assert test_result._unfoldable == []
assert test_result._to_dict() == schema_json


def test_shared_class():
it_ok_to_create = Shared(name="It's ok")
assert it_ok_to_create.name == "It's ok"
assert Shared._shared == []
class_dict = Shared._to_dict()
assert class_dict.get("@shared") == []
# shared documents are regular documents: they keep their key
assert class_dict.get("@key") == {"@type": "Random"}
assert "@subdocument" not in class_dict


def test_shared_class_child():
it_ok_to_create = ChildShared(name="It's ok")
assert it_ok_to_create.name == "It's ok"
assert ChildShared._shared is None
assert "@shared" not in ChildShared._to_dict()


def test_construct_class_with_shared():
schema_json = {
"@id": "SharedDoc",
"@type": "Class",
"@shared": [],
"@key": {"@type": "Random"},
"name": "xsd:string",
}
schema = Schema()
test_result = schema._construct_class(schema_json)
assert test_result._shared == []
assert test_result._to_dict() == schema_json


@pytest.mark.skip(reason="relaxing type checking")
def test_type_check():
test_obj = TypeCheck()
Expand Down
22 changes: 22 additions & 0 deletions terminusdb_client/tests/test_schema_overall.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,28 @@ class Doc(DocumentTemplate):

assert result.get("@abstract") is True

def test_to_dict_with_unfoldable(self):
"""Test _to_dict with _unfoldable list"""

class Doc(DocumentTemplate):
name: str
_unfoldable = []

result = Doc._to_dict()

assert result.get("@unfoldable") == []

def test_to_dict_with_shared(self):
"""Test _to_dict with _shared list"""

class Doc(DocumentTemplate):
name: str
_shared = []

result = Doc._to_dict()

assert result.get("@shared") == []

def test_to_dict_with_hashkey(self):
"""Test _to_dict with HashKey"""

Expand Down
24 changes: 24 additions & 0 deletions terminusdb_client/tests/test_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,30 @@ def test_create_script_parent_string():
assert "class Child2(Parent1):" in result


def test_create_script_unfoldable():
"""Test _create_script emitting _unfoldable for @unfoldable classes"""
obj_list = [
{"@documentation": {"@title": "Test Schema"}},
{"@id": "UnfoldableDoc", "@type": "Class", "@unfoldable": []},
]

result = scripts._create_script(obj_list)
assert "class UnfoldableDoc(DocumentTemplate):" in result
assert "_unfoldable = []" in result


def test_create_script_shared():
"""Test _create_script emitting _shared for @shared classes"""
obj_list = [
{"@documentation": {"@title": "Test Schema"}},
{"@id": "SharedDoc", "@type": "Class", "@shared": []},
]

result = scripts._create_script(obj_list)
assert "class SharedDoc(DocumentTemplate):" in result
assert "_shared = []" in result


def test_sync_empty_schema():
"""Test _sync with empty schema"""
mock_client = MagicMock()
Expand Down
Loading