From 3515947870459150230233a961c2b180d62b4b09 Mon Sep 17 00:00:00 2001 From: RayPlante Date: Thu, 16 Nov 2023 06:34:00 -0500 Subject: [PATCH] move loosen_schema() to nerdm.utils --- python/nistoar/nerdm/utils.py | 34 ++++++++++++++++++++ python/tests/nistoar/nerdm/test_utils.py | 41 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/python/nistoar/nerdm/utils.py b/python/nistoar/nerdm/utils.py index 9ba2479..deeae27 100644 --- a/python/nistoar/nerdm/utils.py +++ b/python/nistoar/nerdm/utils.py @@ -204,6 +204,12 @@ def declutter_schema(schema: Mapping, post2020: bool=False): for defname in schema[deftag]: declutter_schema(schema[deftag][defname]) + for seq in "allOf anyOf oneOf".split(): + if seq in schema: + for itm in schema[seq]: + declutter_schema(itm) + + def unrequire_props_in(schema: Mapping, locations: Union[str, List[str]], post2020: bool=False): """ remove ``"required"`` fields at the specified locations from within the given JSON Schema. @@ -231,3 +237,31 @@ def unrequire_props_in(schema: Mapping, locations: Union[str, List[str]], post20 unrequire_props_in(itm, "$", post2020) +def loosen_schema(schema: Mapping, directives: Mapping, opts=None): + """ + apply the given loosening directive to the given JSON Schema. The directives is a + dictionary describes what to do with the following properties (the directives) supported: + + ``derequire`` + a list of type definitions within the schema from which the required property + should be removed (via :py:func:`~nistoar.nerdm.utils.unrequire_props_in`). Each + type name listed will be assumed to be an item under the "definitions" node in the + schema this directive is applied to. + ``dedocument`` + a boolean indicating whether the documentation annotations should be removed from + the schema. If not set, the default is determined by opts.dedoc if opts is given or + True, otherwise. + + :param dict schema: the schema document as a JSON Schema schema dictionary + :param dict directives: the dictionary of directives to apply + :param opt: an options object (containing scripts command-line options) + """ + if directives.get("dedocument", True): + declutter_schema(schema) + + p2020 = directives.get("post2020") + deftag = "$defs" if p2020 else "definitions" + + dereqtps = [ deftag+'.'+t for t in directives.get("derequire", []) ] + unrequire_props_in(schema, dereqtps, p2020) + diff --git a/python/tests/nistoar/nerdm/test_utils.py b/python/tests/nistoar/nerdm/test_utils.py index f3b9f84..037aa52 100644 --- a/python/tests/nistoar/nerdm/test_utils.py +++ b/python/tests/nistoar/nerdm/test_utils.py @@ -1,6 +1,7 @@ import os, sys, pdb, shutil, logging, json import unittest as test from pathlib import Path +from collections import OrderedDict from nistoar.nerdm import utils from nistoar.nerdm import constants as const @@ -189,6 +190,46 @@ def test_unrequire_props_in(self): self.assertTrue(not utils.hget(schema, "definitions.Topic.required")) self.assertTrue(not utils.hget(schema, "definitions.Organization.required")) + def test_loosen_schema(self): + with open(schemadir/"nerdm-schema.json") as fd: + schema = json.load(fd, object_pairs_hook=OrderedDict) + + self.assertTrue(utils.hget(schema, "title")) + self.assertTrue(utils.hget(schema, "description")) + self.assertTrue(utils.hget(schema, "definitions.Resource.required")) + self.assertTrue(utils.hget(schema, "definitions.Resource.description")) + self.assertTrue(utils.hget(schema, "definitions.Organization.required")) + self.assertTrue(utils.hget(schema, "definitions.Organization.description")) + + utils.loosen_schema(schema, {"derequire": ["Resource"], "dedocument": True}) + + self.assertTrue(not utils.hget(schema, "title")) + self.assertTrue(not utils.hget(schema, "description")) + self.assertTrue(not utils.hget(schema, "definitions.Resource.required")) + self.assertTrue(not utils.hget(schema, "definitions.Resource.description")) + self.assertTrue(utils.hget(schema, "definitions.Organization.required")) + self.assertTrue(not utils.hget(schema, "definitions.Organization.description")) + + def test_loosen_schema_no_dedoc(self): + with open(schemadir/"nerdm-schema.json") as fd: + schema = json.load(fd, object_pairs_hook=OrderedDict) + + self.assertTrue(utils.hget(schema, "title")) + self.assertTrue(utils.hget(schema, "description")) + self.assertTrue(utils.hget(schema, "definitions.Resource.required")) + self.assertTrue(utils.hget(schema, "definitions.Resource.description")) + self.assertTrue(utils.hget(schema, "definitions.Organization.required")) + self.assertTrue(utils.hget(schema, "definitions.Organization.description")) + + utils.loosen_schema(schema, {"derequire": ["Resource"], "dedocument": False}) + + self.assertTrue(utils.hget(schema, "title")) + self.assertTrue(utils.hget(schema, "description")) + self.assertTrue(not utils.hget(schema, "definitions.Resource.required")) + self.assertTrue(utils.hget(schema, "definitions.Resource.description")) + self.assertTrue(utils.hget(schema, "definitions.Organization.required")) + self.assertTrue(utils.hget(schema, "definitions.Organization.description")) + class TestVersion(test.TestCase):