Repository: ResearchObject/ro-crate-py
Pull request #53 (2021-03-08 11:46:11)

Support for context extension
Adds support for context extension via extra terms and uses it to write the appropriate context for testing metadata.

https://www.researchobject.org/ro-crate/1.1/appendix/jsonld.html#extending-ro-crate



Patch:
diff --git a/rocrate/model/metadata.py b/rocrate/model/metadata.py
index 11d37aa..beb6da8 100644
--- a/rocrate/model/metadata.py
+++ b/rocrate/model/metadata.py
@@ -36,6 +36,8 @@ class Metadata(File):
 
     def __init__(self, crate):
         super().__init__(crate, None, self.BASENAME, False, None)
+        # https://www.researchobject.org/ro-crate/1.1/appendix/jsonld.html#extending-ro-crate
+        self.extra_terms = {}
 
     def _empty(self):
         # default properties of the metadata entry
@@ -51,7 +53,10 @@ class Metadata(File):
         graph = []
         for entity in self.crate.get_entities():
             graph.append(entity.properties())
-        return {'@context': f'{self.PROFILE}/context', '@graph': graph}
+        context = f'{self.PROFILE}/context'
+        if self.extra_terms:
+            context = [context, self.extra_terms]
+        return {'@context': context, '@graph': graph}
 
     def write(self, base_path):
         # writes itself in
@@ -81,3 +86,20 @@ class LegacyMetadata(Metadata):
 
     BASENAME = "ro-crate-metadata.jsonld"
     PROFILE = "https://w3id.org/ro/crate/1.0"
+
+
+# https://github.com/ResearchObject/ro-terms/tree/master/test
+TESTING_EXTRA_TERMS = {
+    "TestSuite": "https://w3id.org/ro/terms/test#TestSuite",
+    "TestInstance": "https://w3id.org/ro/terms/test#TestInstance",
+    "TestService": "https://w3id.org/ro/terms/test#TestService",
+    "TestDefinition": "https://w3id.org/ro/terms/test#TestDefinition",
+    "PlanemoEngine": "https://w3id.org/ro/terms/test#PlanemoEngine",
+    "JenkinsService": "https://w3id.org/ro/terms/test#JenkinsService",
+    "TravisService": "https://w3id.org/ro/terms/test#TravisService",
+    "instance": "https://w3id.org/ro/terms/test#instance",
+    "runsOn": "https://w3id.org/ro/terms/test#runsOn",
+    "resource": "https://w3id.org/ro/terms/test#resource",
+    "definition": "https://w3id.org/ro/terms/test#definition",
+    "engineVersion": "https://w3id.org/ro/terms/test#engineVersion"
+}
diff --git a/rocrate/rocrate.py b/rocrate/rocrate.py
index 74e0ab6..4470650 100644
--- a/rocrate/rocrate.py
+++ b/rocrate/rocrate.py
@@ -34,7 +34,7 @@ from .model import contextentity
 from .model.root_dataset import RootDataset
 from .model.file import File
 from .model.dataset import Dataset
-from .model.metadata import Metadata, LegacyMetadata
+from .model.metadata import Metadata, LegacyMetadata, TESTING_EXTRA_TERMS
 from .model.preview import Preview
 from .model.testdefinition import TestDefinition
 from .model.computationalworkflow import ComputationalWorkflow, galaxy_to_abstract_cwl
@@ -517,6 +517,7 @@ class ROCrate():
         suite_set = set(test_dir["about"] or [])
         suite_set.add(suite)
         test_dir["about"] = list(suite_set)
+        self.metadata.extra_terms.update(TESTING_EXTRA_TERMS)
         return suite
 
     def add_test_instance(self, suite, url, resource="", service="jenkins", identifier=None, name=None):
@@ -534,6 +535,7 @@ class ROCrate():
         instance_set = set(suite.instance or [])
         instance_set.add(instance)
         suite.instance = list(instance_set)
+        self.metadata.extra_terms.update(TESTING_EXTRA_TERMS)
         return instance
 
     def add_test_definition(
@@ -556,6 +558,7 @@ class ROCrate():
         definition.engine = engine
         definition.engineVersion = engine_version
         suite.definition = definition
+        self.metadata.extra_terms.update(TESTING_EXTRA_TERMS)
         return definition
 
     def __validate_suite(self, suite):


Test patch:
diff --git a/test/test_cli.py b/test/test_cli.py
index 0d7fd46..9c43ff9 100644
--- a/test/test_cli.py
+++ b/test/test_cli.py
@@ -15,10 +15,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
 import pytest
 from click.testing import CliRunner
 
 from rocrate.cli import cli
+from rocrate.model.metadata import TESTING_EXTRA_TERMS
 
 
 @pytest.mark.parametrize("cwd", [False, True])
@@ -111,3 +113,13 @@ def test_cli_add_test_metadata(test_data_dir, helpers, monkeypatch, cwd):
     json_entities = helpers.read_json_entities(crate_dir)
     assert def_id in json_entities
     assert set(json_entities[def_id]["@type"]) == {"File", "TestDefinition"}
+    # check extra terms
+    metadata_path = crate_dir / helpers.METADATA_FILE_NAME
+    with open(metadata_path, "rt") as f:
+        json_data = json.load(f)
+    assert "@context" in json_data
+    context = json_data["@context"]
+    assert isinstance(context, list)
+    assert len(context) > 1
+    extra_terms = context[1]
+    assert set(TESTING_EXTRA_TERMS.items()).issubset(extra_terms.items())