From 4ff4cca51e96982fd28843b2bfade89ef99fea36 Mon Sep 17 00:00:00 2001
From: Alexander Schlemmer <alexander@mail-schlemmer.de>
Date: Thu, 10 Feb 2022 11:35:30 +0100
Subject: [PATCH] ENH: completed implementation of role keyword and added
 several tests

---
 src/caosadvancedtools/models/parser.py | 23 ++++++++-
 unittests/test_parser.py               | 67 +++++++++++++++++++++++++-
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/src/caosadvancedtools/models/parser.py b/src/caosadvancedtools/models/parser.py
index 90219508..f385a1a3 100644
--- a/src/caosadvancedtools/models/parser.py
+++ b/src/caosadvancedtools/models/parser.py
@@ -36,7 +36,8 @@ KEYWORDS = ["parent",  # TODO: can we remove that, see: #36
             "inherit_from_recommended",
             "inherit_from_suggested",
             "inherit_from_obligatory",
-            "role", ]
+            "role",
+            "value", ]
 
 # TODO: check whether it's really ignored
 # These KEYWORDS are not forbidden as properties, but merely ignored.
@@ -278,8 +279,11 @@ class Parser(object):
                 raise RuntimeError("Unknown role {} in definition of entity.".format(
                     definition["role"]))
 
-        # add other definitions recursively
+        # for setting values of properties directly:
+        if not isinstance(definition, dict):
+            return
 
+        # add other definitions recursively
         for prop_type in ["recommended_properties",
                           "suggested_properties", "obligatory_properties"]:
 
@@ -322,8 +326,12 @@ class Parser(object):
                     name=n,
                     importance=importance,
                     datatype=db.LIST(_get_listdatatype(e["datatype"])))
+            elif e is None:
+                self.model[ent_name].add_property(name=n,
+                                                  importance=importance)
             else:
                 self.model[ent_name].add_property(name=n,
+                                                  value=e,
                                                   importance=importance)
 
     def _inherit(self, name, prop, inheritance):
@@ -347,6 +355,10 @@ class Parser(object):
             if definition is None:
                 return
 
+            # for setting values of properties directly:
+            if not isinstance(definition, dict):
+                return
+
             if ("datatype" in definition
                     and definition["datatype"].startswith("LIST")):
 
@@ -363,6 +375,9 @@ class Parser(object):
                 if prop_name == "unit":
                     self.model[name].unit = prop
 
+                elif prop_name == "value":
+                    self.model[name].value = prop
+
                 elif prop_name == "description":
                     self.model[name].description = prop
 
@@ -391,6 +406,10 @@ class Parser(object):
                 elif prop_name == "datatype":
                     continue
 
+                # role has already been used
+                elif prop_name == "role":
+                    continue
+
                 elif prop_name == "inherit_from_obligatory":
                     self._inherit(name, prop, db.OBLIGATORY)
                 elif prop_name == "inherit_from_recommended":
diff --git a/unittests/test_parser.py b/unittests/test_parser.py
index 161e2873..6f3b81e6 100644
--- a/unittests/test_parser.py
+++ b/unittests/test_parser.py
@@ -15,7 +15,7 @@ def to_file(string):
 
     return f.name
 
-
+# TODO: check purpose of this function... add documentation
 def parse_str(string):
     parse_model_from_yaml(to_file(string))
 
@@ -328,3 +328,68 @@ A:
             with self.assertRaises(YamlDefinitionError) as yde:
                 parse_str(string)
             assert("line {}".format(line) in yde.exception.args[0])
+
+
+
+def test_define_role():
+    model = """
+A:
+  role: Record
+"""
+    entities = parse_model_from_string(model)
+    assert "A" in entities
+    assert isinstance(entities["A"], db.Record)
+    assert entities["A"].role == "Record"
+
+    model = """
+A:
+  role: Record
+  inherit_from_obligatory:
+  - C
+  obligatory_properties:
+    b:
+b:
+  datatype: INTEGER
+C:
+  obligatory_properties:
+    b:
+D:
+  role: RecordType
+"""
+    entities = parse_model_from_string(model)
+    for l, ent in (("A", "Record"), ("b", "Property"),
+                   ("C", "RecordType"), ("D", "RecordType")):
+        assert l in entities
+        assert isinstance(entities[l], getattr(db, ent))
+        assert entities[l].role == ent
+
+    assert entities["A"].parents[0].name == "C"
+    assert entities["A"].name == "A"
+
+    assert entities["A"].properties[0].name == "b"
+    assert entities["A"].properties[0].value is None
+
+    assert entities["C"].properties[0].name == "b"
+    assert entities["C"].properties[0].value is None
+
+    model = """
+A:
+  role: Record
+  obligatory_properties:
+    b: 42
+b:
+  datatype: INTEGER
+"""
+
+    entities = parse_model_from_string(model)
+    assert entities["A"].get_property("b").value == 42
+    assert entities["b"].value is None
+
+    
+    model = """
+b:
+  datatype: INTEGER
+  value: 18
+"""
+    entities = parse_model_from_string(model)
+    assert entities["b"].value == 18
-- 
GitLab