diff --git a/.github/workflows/run_test.yml b/.github/workflows/run_test.yml new file mode 100644 index 0000000..7c49c5d --- /dev/null +++ b/.github/workflows/run_test.yml @@ -0,0 +1,27 @@ +name: Run Unit Test via Pytest + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi + - name: Test with pytest + run: | + coverage run -m pytest -v -s + - name: Generate Coverage Report + run: | + coverage report -m diff --git a/main.py b/main.py new file mode 100644 index 0000000..987cd09 --- /dev/null +++ b/main.py @@ -0,0 +1,32 @@ +import argparse +import os +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def main(): + """Main function to execute""" + parser = argparse.ArgumentParser( + description="Translate JSON Schema to SHACL") + parser.add_argument("json_file", type=str, + help="Path to JSON Schema file") + args = parser.parse_args() + + file_path = args.json_file + schema = parse_json_schema(file_path) + + json_converter = JsonSchemaToShacl() + + if schema is not None: + json_converter.translate(schema) + # Remove the last component of the path + base_path = os.path.dirname(file_path) + base_name = os.path.splitext(os.path.basename(file_path))[ + 0] # Remove the .json extension + # Construct the new file name with .shape.ttl extension + file_name = os.path.join(base_path, base_name + "_shape.ttl") + json_converter.shacl.serialize(format="turtle", destination=file_name) + + +if __name__ == "__main__": + main() diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..03f586d --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +pythonpath = . \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3aa57e2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +jsonpath-ng==1.6.1 +owlrl==6.0.2 +pyshacl==0.26.0 +rdflib==7.0.0 diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/constants.py b/src/constants.py index cba2167..b900b7c 100644 --- a/src/constants.py +++ b/src/constants.py @@ -11,7 +11,7 @@ def build_in_types(json_type): def format_types(format_type): format_type_map = { - "date-time": "dateTime ", + "date-time": "dateTime", "date": "date", "time": "time", "duration": "duration" diff --git a/src/json_schema_to_shacl.py b/src/json_schema_to_shacl.py index 6fe82bd..fa61142 100644 --- a/src/json_schema_to_shacl.py +++ b/src/json_schema_to_shacl.py @@ -1,10 +1,8 @@ -import argparse from rdflib import Graph, Namespace, Literal, URIRef, BNode from jsonpath_ng import parse # from pyshacl import validate -from file_parser import parse_json_schema -from constants import build_in_types, format_types -from utils import check_type, check_if_object_has_properties_or_restrictions +from .constants import build_in_types, format_types +from .utils import check_type, check_if_object_has_properties_or_restrictions class JsonSchemaToShacl: @@ -968,7 +966,7 @@ def trans_complex(self, element: dict, ref_name: str = None) -> URIRef: return subject - def translate(self, element: dict) -> None: + def translate(self, element: dict) -> Graph: """Function to translate JSON Schema to SHACL""" self.schema = element type_element = check_type(element) @@ -979,25 +977,4 @@ def translate(self, element: dict) -> None: elif type_element == "SimpleType": self.trans_simple(element) - -def main(): - """Main function to execute""" - parser = argparse.ArgumentParser( - description="Translate JSON Schema to SHACL") - parser.add_argument("json_file", type=str, - help="Path to JSON Schema file") - args = parser.parse_args() - - file_path = args.json_file - schema = parse_json_schema(file_path) - - json_converter = JsonSchemaToShacl() - - if schema is not None: - json_converter.translate(schema) - file_name = f"{file_path}.shape.ttl" - json_converter.shacl.serialize(format="turtle", destination=file_name) - - -if __name__ == "__main__": - main() + return self.shacl diff --git a/test/1-SimpleType/mapping.json b/test/1-SimpleType/mapping.json new file mode 100644 index 0000000..0e8d4ef --- /dev/null +++ b/test/1-SimpleType/mapping.json @@ -0,0 +1,4 @@ +{ + "type": "number", + "name": "credit_card" +} \ No newline at end of file diff --git a/test/1-SimpleType/test_1simpletype.py b/test/1-SimpleType/test_1simpletype.py new file mode 100644 index 0000000..d2f97a8 --- /dev/null +++ b/test/1-SimpleType/test_1simpletype.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_1simpletype(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/1-SimpleType/test_shape.ttl b/test/1-SimpleType/test_shape.ttl new file mode 100644 index 0000000..401426a --- /dev/null +++ b/test/1-SimpleType/test_shape.ttl @@ -0,0 +1,8 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "credit_card" ; + sh:path . + diff --git a/test/10-item/mapping.json b/test/10-item/mapping.json new file mode 100644 index 0000000..e99e18c --- /dev/null +++ b/test/10-item/mapping.json @@ -0,0 +1,8 @@ +{ + "type": "array", + "name" :"test", + "items": { + "type": "number" + } + } + \ No newline at end of file diff --git a/test/10-item/test_10item.py b/test/10-item/test_10item.py new file mode 100644 index 0000000..1f287ef --- /dev/null +++ b/test/10-item/test_10item.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_10item(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/10-item/test_shape.ttl b/test/10-item/test_shape.ttl new file mode 100644 index 0000000..9ba8a5e --- /dev/null +++ b/test/10-item/test_shape.ttl @@ -0,0 +1,10 @@ +@prefix sh: . +@prefix xsd: . + + sh:property . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "test" ; + sh:path . + diff --git a/test/11-prefixItems/mapping.json b/test/11-prefixItems/mapping.json new file mode 100644 index 0000000..dcc7fcc --- /dev/null +++ b/test/11-prefixItems/mapping.json @@ -0,0 +1,11 @@ +{ + "type": "array", + "name" :"test", + "prefixItems": [ + { "type": "number" }, + { "type": "string" }, + { "enum": ["Street", "Avenue", "Boulevard"] }, + { "enum": ["NW", "NE", "SW", "SE"] } + ] + } + \ No newline at end of file diff --git a/test/11-prefixItems/test_11prefixitems.py b/test/11-prefixItems/test_11prefixitems.py new file mode 100644 index 0000000..d2b199b --- /dev/null +++ b/test/11-prefixItems/test_11prefixitems.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_11prefixitems(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/11-prefixItems/test_shape.ttl b/test/11-prefixItems/test_shape.ttl new file mode 100644 index 0000000..cd09f90 --- /dev/null +++ b/test/11-prefixItems/test_shape.ttl @@ -0,0 +1,35 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "test" ; + sh:property , + , + , + . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP0" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "testP1" ; + sh:path . + + a sh:PropertyShape ; + sh:in_ "Avenue", + "Boulevard", + "Street" ; + sh:name "testP2" ; + sh:path . + + a sh:PropertyShape ; + sh:in_ "NE", + "NW", + "SE", + "SW" ; + sh:name "testP3" ; + sh:path . + diff --git a/test/12-unevaluatedItems/mapping.json b/test/12-unevaluatedItems/mapping.json new file mode 100644 index 0000000..5d149f9 --- /dev/null +++ b/test/12-unevaluatedItems/mapping.json @@ -0,0 +1,13 @@ +{ + "type": "array", + "name": "test", + "prefixItems": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "unevaluatedItems": false +} \ No newline at end of file diff --git a/test/12-unevaluatedItems/test_12unevaluateditems.py b/test/12-unevaluatedItems/test_12unevaluateditems.py new file mode 100644 index 0000000..a341d17 --- /dev/null +++ b/test/12-unevaluatedItems/test_12unevaluateditems.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_12unevaluateditems(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/12-unevaluatedItems/test_shape.ttl b/test/12-unevaluatedItems/test_shape.ttl new file mode 100644 index 0000000..ff29c72 --- /dev/null +++ b/test/12-unevaluatedItems/test_shape.ttl @@ -0,0 +1,18 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "test" ; + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "testP0" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP1" ; + sh:path . + diff --git a/test/13-contains/mapping.json b/test/13-contains/mapping.json new file mode 100644 index 0000000..6513349 --- /dev/null +++ b/test/13-contains/mapping.json @@ -0,0 +1,11 @@ +{ + "type": "array", + "name": "test", + "items": { + "type": "number" + }, + "contains": { + "type": "number" + } +} + \ No newline at end of file diff --git a/test/13-contains/test_13contains.py b/test/13-contains/test_13contains.py new file mode 100644 index 0000000..9a9c54c --- /dev/null +++ b/test/13-contains/test_13contains.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_13contains(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/13-contains/test_shape.ttl b/test/13-contains/test_shape.ttl new file mode 100644 index 0000000..fe589a6 --- /dev/null +++ b/test/13-contains/test_shape.ttl @@ -0,0 +1,16 @@ +@prefix sh: . +@prefix xsd: . + + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP0" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP1" ; + sh:path . + diff --git a/test/14-uniqueItems/mapping.json b/test/14-uniqueItems/mapping.json new file mode 100644 index 0000000..b626748 --- /dev/null +++ b/test/14-uniqueItems/mapping.json @@ -0,0 +1,8 @@ +{ + "type": "array", + "name": "test", + "items": { + "type": "number" + }, + "uniqueItems": true +} \ No newline at end of file diff --git a/test/14-uniqueItems/test_14uniqueitems.py b/test/14-uniqueItems/test_14uniqueitems.py new file mode 100644 index 0000000..a07c2b3 --- /dev/null +++ b/test/14-uniqueItems/test_14uniqueitems.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_14uniqueitems(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/14-uniqueItems/test_shape.ttl b/test/14-uniqueItems/test_shape.ttl new file mode 100644 index 0000000..57c85ae --- /dev/null +++ b/test/14-uniqueItems/test_shape.ttl @@ -0,0 +1,11 @@ +@prefix sh: . +@prefix xsd: . + + sh:property ; + sh:uniqueLang true . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "test" ; + sh:path . + diff --git a/test/15-boolean/mapping.json b/test/15-boolean/mapping.json new file mode 100644 index 0000000..bc45dfd --- /dev/null +++ b/test/15-boolean/mapping.json @@ -0,0 +1,4 @@ +{ + "type": "boolean", + "name": "bool" +} \ No newline at end of file diff --git a/test/15-boolean/test_15boolean.py b/test/15-boolean/test_15boolean.py new file mode 100644 index 0000000..b3f0969 --- /dev/null +++ b/test/15-boolean/test_15boolean.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_15boolean(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/15-boolean/test_shape.ttl b/test/15-boolean/test_shape.ttl new file mode 100644 index 0000000..e5eb369 --- /dev/null +++ b/test/15-boolean/test_shape.ttl @@ -0,0 +1,8 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:boolean ; + sh:name "bool" ; + sh:path . + diff --git a/test/16-null/mapping.json b/test/16-null/mapping.json new file mode 100644 index 0000000..5eac4f8 --- /dev/null +++ b/test/16-null/mapping.json @@ -0,0 +1,4 @@ +{ + "type": "null", + "name": "nullType" +} \ No newline at end of file diff --git a/test/16-null/test_16null.py b/test/16-null/test_16null.py new file mode 100644 index 0000000..f82a1fb --- /dev/null +++ b/test/16-null/test_16null.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_16null(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/16-null/test_shape.ttl b/test/16-null/test_shape.ttl new file mode 100644 index 0000000..55b8049 --- /dev/null +++ b/test/16-null/test_shape.ttl @@ -0,0 +1,8 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:nil ; + sh:name "nullType" ; + sh:path . + diff --git a/test/17-dependentRequired/mapping.json b/test/17-dependentRequired/mapping.json new file mode 100644 index 0000000..dde0b4c --- /dev/null +++ b/test/17-dependentRequired/mapping.json @@ -0,0 +1,23 @@ +{ + "type": "object", + "name": "customer", + "properties": { + "name": { + "type": "string" + }, + "credit_card": { + "type": "number" + }, + "billing_address": { + "type": "string" + } + }, + "required": [ + "name" + ], + "dependentRequired": { + "credit_card": [ + "billing_address" + ] + } +} \ No newline at end of file diff --git a/test/17-dependentRequired/test_17dependentrequired.py b/test/17-dependentRequired/test_17dependentrequired.py new file mode 100644 index 0000000..5e8349f --- /dev/null +++ b/test/17-dependentRequired/test_17dependentrequired.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_17dependentrequired(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/17-dependentRequired/test_shape.ttl b/test/17-dependentRequired/test_shape.ttl new file mode 100644 index 0000000..0a9d132 --- /dev/null +++ b/test/17-dependentRequired/test_shape.ttl @@ -0,0 +1,32 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "customer" ; + sh:property , + , + ; + sh:qualifiedMinCount 1 ; + sh:targetClass . + + a sh:NodeShape ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "billing_address" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "credit_card" ; + sh:path ; + sh:qualifiedValueShape . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "name" ; + sh:path . + diff --git a/test/18-refs/mapping.json b/test/18-refs/mapping.json new file mode 100644 index 0000000..84e3315 --- /dev/null +++ b/test/18-refs/mapping.json @@ -0,0 +1,19 @@ +{ + "type": "object", + "name" : "client", + "properties": { + "first_name": { "$ref": "#/$defs/name" }, + "last_name": { "$ref": "#/$defs/name" } + }, + "required": ["first_name", "last_name"], + + "$defs": { + "name": { "type": "object", + "properties": { + "manolito": { "type": "string" }, + "pepito": { "type": "string" } + } + } + } +} + \ No newline at end of file diff --git a/test/18-refs/test_18refs.py b/test/18-refs/test_18refs.py new file mode 100644 index 0000000..db34636 --- /dev/null +++ b/test/18-refs/test_18refs.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_18refs(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/18-refs/test_shape.ttl b/test/18-refs/test_shape.ttl new file mode 100644 index 0000000..99e97c7 --- /dev/null +++ b/test/18-refs/test_shape.ttl @@ -0,0 +1,37 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "client" ; + sh:property , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:node ; + sh:path . + + a sh:PropertyShape ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:node ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "manolito" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "pepito" ; + sh:path . + + a sh:NodeShape ; + sh:name "name" ; + sh:property , + ; + sh:targetClass . + diff --git a/test/19-if/mapping.json b/test/19-if/mapping.json new file mode 100644 index 0000000..1769da8 --- /dev/null +++ b/test/19-if/mapping.json @@ -0,0 +1,37 @@ +{ + "type": "object", + "name": "office", + "properties": { + "street_address": { + "type": "string" + }, + "country": { + "default": "United States of America", + "enum": [ + "United States of America", + "Canada" + ] + } + }, + "if": { + "properties": { + "country": { + "const": "United States of America" + } + } + }, + "then": { + "properties": { + "postal_code": { + "pattern": "[0-9]{5}(-[0-9]{4})?" + } + } + }, + "else": { + "properties": { + "postal_code": { + "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" + } + } + } +} \ No newline at end of file diff --git a/test/19-if/test_19if.py b/test/19-if/test_19if.py new file mode 100644 index 0000000..b450bd8 --- /dev/null +++ b/test/19-if/test_19if.py @@ -0,0 +1,20 @@ +import os +from rdflib import compare, Graph +import pytest +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +@pytest.mark.skip(reason="Not implemented yet") +def test_19if(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/19-if/test_shape.ttl b/test/19-if/test_shape.ttl new file mode 100644 index 0000000..625b2fc --- /dev/null +++ b/test/19-if/test_shape.ttl @@ -0,0 +1,29 @@ +@prefix rdf: . +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "office" ; + sh:or_ ( [ sh:and_ ( [ sh:hasValue "United States of America" ; + sh:path ] ) ] ) ; + sh:property , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:in_ "Canada", + "United States of America" ; + sh:name "country" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "street_address" ; + sh:path . + +_:N4a812d942a1e4f74b9bae1cf1181a91f sh:path ; + sh:pattern "[0-9]{5}(-[0-9]{4})?" . + +_:Na2be0e5910a14480b96e7fe3bcc8c6d7 sh:path ; + sh:pattern "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" . + diff --git a/test/2-CompleType/mapping.json b/test/2-CompleType/mapping.json new file mode 100644 index 0000000..79bc439 --- /dev/null +++ b/test/2-CompleType/mapping.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "name": "persona", + "properties": { + "first_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "birthday": { + "type": "string", + "format": "date" + } + } +} \ No newline at end of file diff --git a/test/2-CompleType/test_2completype.py b/test/2-CompleType/test_2completype.py new file mode 100644 index 0000000..2399488 --- /dev/null +++ b/test/2-CompleType/test_2completype.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_2completype(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/2-CompleType/test_shape.ttl b/test/2-CompleType/test_shape.ttl new file mode 100644 index 0000000..95f68b3 --- /dev/null +++ b/test/2-CompleType/test_shape.ttl @@ -0,0 +1,26 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "persona" ; + sh:property , + , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:datatype xsd:date, + xsd:string ; + sh:name "birthday" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "first_name" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "last_name" ; + sh:path . + diff --git a/test/20-logicalOperators/mapping.json b/test/20-logicalOperators/mapping.json new file mode 100644 index 0000000..7db4335 --- /dev/null +++ b/test/20-logicalOperators/mapping.json @@ -0,0 +1,22 @@ +{ + "type": "object", + "name": "office", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "credit_card": { + "type": "number" + }, + "billing_address": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/test/20-logicalOperators/test_20logicaloperators.py b/test/20-logicalOperators/test_20logicaloperators.py new file mode 100644 index 0000000..4e438b2 --- /dev/null +++ b/test/20-logicalOperators/test_20logicaloperators.py @@ -0,0 +1,20 @@ +import os +from rdflib import compare, Graph +import pytest +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +@pytest.mark.skip(reason="Not implemented yet") +def test_20logicaloperators(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/21-const/mapping.json b/test/21-const/mapping.json new file mode 100644 index 0000000..9548cd5 --- /dev/null +++ b/test/21-const/mapping.json @@ -0,0 +1,10 @@ +{ + "type": "object", + "name": "office", + "properties": { + "country": { + "const": "United States of America" + } + } + } + \ No newline at end of file diff --git a/test/21-const/mapping.ttl b/test/21-const/mapping.ttl new file mode 100644 index 0000000..a49ceb3 --- /dev/null +++ b/test/21-const/mapping.ttl @@ -0,0 +1,12 @@ +@prefix sh: . + + a sh:NodeShape ; + sh:name "office" ; + sh:property ; + sh:targetClass . + + a sh:PropertyShape ; + sh:hasValue "United States of America" ; + sh:name "country" ; + sh:path . + diff --git a/test/21-const/test_21const.py b/test/21-const/test_21const.py new file mode 100644 index 0000000..1812a9e --- /dev/null +++ b/test/21-const/test_21const.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_21const(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/21-const/test_shape.ttl b/test/21-const/test_shape.ttl new file mode 100644 index 0000000..a49ceb3 --- /dev/null +++ b/test/21-const/test_shape.ttl @@ -0,0 +1,12 @@ +@prefix sh: . + + a sh:NodeShape ; + sh:name "office" ; + sh:property ; + sh:targetClass . + + a sh:PropertyShape ; + sh:hasValue "United States of America" ; + sh:name "country" ; + sh:path . + diff --git a/test/22-maximum/mapping.json b/test/22-maximum/mapping.json new file mode 100644 index 0000000..31e81ad --- /dev/null +++ b/test/22-maximum/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "number", + "name": "credit_card", + "maximum": 2 +} \ No newline at end of file diff --git a/test/22-maximum/test_22maximum.py b/test/22-maximum/test_22maximum.py new file mode 100644 index 0000000..d697ce3 --- /dev/null +++ b/test/22-maximum/test_22maximum.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_22maximum(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/22-maximum/test_shape.ttl b/test/22-maximum/test_shape.ttl new file mode 100644 index 0000000..2f660ba --- /dev/null +++ b/test/22-maximum/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:minExclusive 2 ; + sh:name "credit_card" ; + sh:path . + diff --git a/test/23-minimum/mapping.json b/test/23-minimum/mapping.json new file mode 100644 index 0000000..393ca45 --- /dev/null +++ b/test/23-minimum/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "number", + "name": "credit_card", + "minimum": 2 +} \ No newline at end of file diff --git a/test/23-minimum/test_23minimum.py b/test/23-minimum/test_23minimum.py new file mode 100644 index 0000000..9f603cf --- /dev/null +++ b/test/23-minimum/test_23minimum.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_23minimum(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/23-minimum/test_shape.ttl b/test/23-minimum/test_shape.ttl new file mode 100644 index 0000000..b8084b0 --- /dev/null +++ b/test/23-minimum/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:minInclusive 2 ; + sh:name "credit_card" ; + sh:path . + diff --git a/test/24-exclusiveMaximum/mapping.json b/test/24-exclusiveMaximum/mapping.json new file mode 100644 index 0000000..d82abf6 --- /dev/null +++ b/test/24-exclusiveMaximum/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "number", + "name": "credit_card", + "exclusiveMaximum": 100 +} \ No newline at end of file diff --git a/test/24-exclusiveMaximum/test_24exclusivemaximum.py b/test/24-exclusiveMaximum/test_24exclusivemaximum.py new file mode 100644 index 0000000..8187c6c --- /dev/null +++ b/test/24-exclusiveMaximum/test_24exclusivemaximum.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_24exclusivemaximum(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/24-exclusiveMaximum/test_shape.ttl b/test/24-exclusiveMaximum/test_shape.ttl new file mode 100644 index 0000000..657e390 --- /dev/null +++ b/test/24-exclusiveMaximum/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:maxExclusive 100 ; + sh:name "credit_card" ; + sh:path . + diff --git a/test/25-exclusiveMinimum/mapping.json b/test/25-exclusiveMinimum/mapping.json new file mode 100644 index 0000000..764b3d6 --- /dev/null +++ b/test/25-exclusiveMinimum/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "number", + "name": "credit_card", + "exclusiveMinimum": 100 +} \ No newline at end of file diff --git a/test/25-exclusiveMinimum/test_25exclusiveminimum.py b/test/25-exclusiveMinimum/test_25exclusiveminimum.py new file mode 100644 index 0000000..dfaa3dc --- /dev/null +++ b/test/25-exclusiveMinimum/test_25exclusiveminimum.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_25exclusiveminimum(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/25-exclusiveMinimum/test_shape.ttl b/test/25-exclusiveMinimum/test_shape.ttl new file mode 100644 index 0000000..0b178d6 --- /dev/null +++ b/test/25-exclusiveMinimum/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:minExclusive 100 ; + sh:name "credit_card" ; + sh:path . + diff --git a/test/26-maxLength/mapping.json b/test/26-maxLength/mapping.json new file mode 100644 index 0000000..494de67 --- /dev/null +++ b/test/26-maxLength/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "string", + "name": "test", + "maxLength": 3 +} \ No newline at end of file diff --git a/test/26-maxLength/test_26maxlength.py b/test/26-maxLength/test_26maxlength.py new file mode 100644 index 0000000..b92026d --- /dev/null +++ b/test/26-maxLength/test_26maxlength.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_26maxlength(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/26-maxLength/test_shape.ttl b/test/26-maxLength/test_shape.ttl new file mode 100644 index 0000000..914cd45 --- /dev/null +++ b/test/26-maxLength/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:maxLength 3 ; + sh:name "test" ; + sh:path . + diff --git a/test/27-minLength/mapping.json b/test/27-minLength/mapping.json new file mode 100644 index 0000000..be0d92d --- /dev/null +++ b/test/27-minLength/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "string", + "name": "test", + "minLength": 2 +} \ No newline at end of file diff --git a/test/27-minLength/test_27minlength.py b/test/27-minLength/test_27minlength.py new file mode 100644 index 0000000..cbdd086 --- /dev/null +++ b/test/27-minLength/test_27minlength.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_27minlength(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/27-minLength/test_shape.ttl b/test/27-minLength/test_shape.ttl new file mode 100644 index 0000000..547f88f --- /dev/null +++ b/test/27-minLength/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:minLength 2 ; + sh:name "test" ; + sh:path . + diff --git a/test/28-maxItems/mapping.json b/test/28-maxItems/mapping.json new file mode 100644 index 0000000..0f9bfa2 --- /dev/null +++ b/test/28-maxItems/mapping.json @@ -0,0 +1,16 @@ +{ + "type": "array", + "name": "fruits", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "flavor": { + "type": "string" + } + } + }, + "maxItems": 2 +} \ No newline at end of file diff --git a/test/28-maxItems/test_28maxitems.py b/test/28-maxItems/test_28maxitems.py new file mode 100644 index 0000000..2aea805 --- /dev/null +++ b/test/28-maxItems/test_28maxitems.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_28maxitems(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/28-maxItems/test_shape.ttl b/test/28-maxItems/test_shape.ttl new file mode 100644 index 0000000..e8dc8e0 --- /dev/null +++ b/test/28-maxItems/test_shape.ttl @@ -0,0 +1,20 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:maxInclusive 2 ; + sh:name "fruits" ; + sh:node ; + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "color" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "flavor" ; + sh:path . + diff --git a/test/29-minItems/mapping.json b/test/29-minItems/mapping.json new file mode 100644 index 0000000..c732a12 --- /dev/null +++ b/test/29-minItems/mapping.json @@ -0,0 +1,16 @@ +{ + "type": "array", + "name": "fruits", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "flavor": { + "type": "string" + } + } + }, + "minItems": 2 +} \ No newline at end of file diff --git a/test/29-minItems/test_29minitems.py b/test/29-minItems/test_29minitems.py new file mode 100644 index 0000000..3097af3 --- /dev/null +++ b/test/29-minItems/test_29minitems.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_29minitems(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/29-minItems/test_shape.ttl b/test/29-minItems/test_shape.ttl new file mode 100644 index 0000000..ab6a65b --- /dev/null +++ b/test/29-minItems/test_shape.ttl @@ -0,0 +1,20 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:minInclusive 2 ; + sh:name "fruits" ; + sh:node ; + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "color" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "flavor" ; + sh:path . + diff --git a/test/3-ArrayType/mapping.json b/test/3-ArrayType/mapping.json new file mode 100644 index 0000000..f06942b --- /dev/null +++ b/test/3-ArrayType/mapping.json @@ -0,0 +1,15 @@ +{ + "type": "array", + "name": "fruits", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "flavor": { + "type": "string" + } + } + } +} \ No newline at end of file diff --git a/test/3-ArrayType/test_3arraytype.py b/test/3-ArrayType/test_3arraytype.py new file mode 100644 index 0000000..5a4b36c --- /dev/null +++ b/test/3-ArrayType/test_3arraytype.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_3arraytype(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/3-ArrayType/test_shape.ttl b/test/3-ArrayType/test_shape.ttl new file mode 100644 index 0000000..500a4ee --- /dev/null +++ b/test/3-ArrayType/test_shape.ttl @@ -0,0 +1,19 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "fruits" ; + sh:node ; + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "color" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "flavor" ; + sh:path . + diff --git a/test/30-maxContains/mapping.json b/test/30-maxContains/mapping.json new file mode 100644 index 0000000..7072a93 --- /dev/null +++ b/test/30-maxContains/mapping.json @@ -0,0 +1,12 @@ +{ + "type": "array", + "name": "test", + "items": { + "type": "number" + }, + "contains": { + "type": "number" + }, + "maxContains": 3 +} + \ No newline at end of file diff --git a/test/30-maxContains/test_30maxcontains.py b/test/30-maxContains/test_30maxcontains.py new file mode 100644 index 0000000..334a63c --- /dev/null +++ b/test/30-maxContains/test_30maxcontains.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_30maxcontains(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/30-maxContains/test_shape.ttl b/test/30-maxContains/test_shape.ttl new file mode 100644 index 0000000..7e6db0c --- /dev/null +++ b/test/30-maxContains/test_shape.ttl @@ -0,0 +1,17 @@ +@prefix sh: . +@prefix xsd: . + + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP0" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:maxCount 3 ; + sh:name "testP1" ; + sh:path . + diff --git a/test/31-minContains/mapping.json b/test/31-minContains/mapping.json new file mode 100644 index 0000000..284392a --- /dev/null +++ b/test/31-minContains/mapping.json @@ -0,0 +1,12 @@ +{ + "type": "array", + "name": "test", + "items": { + "type": "number" + }, + "contains": { + "type": "number" + }, + "minContains": 3 +} + \ No newline at end of file diff --git a/test/31-minContains/test_31mincontains.py b/test/31-minContains/test_31mincontains.py new file mode 100644 index 0000000..a748366 --- /dev/null +++ b/test/31-minContains/test_31mincontains.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_31mincontains(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/31-minContains/test_shape.ttl b/test/31-minContains/test_shape.ttl new file mode 100644 index 0000000..a01abb3 --- /dev/null +++ b/test/31-minContains/test_shape.ttl @@ -0,0 +1,17 @@ +@prefix sh: . +@prefix xsd: . + + sh:property , + . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "testP0" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:minCount 3 ; + sh:name "testP1" ; + sh:path . + diff --git a/test/32-format/mapping.json b/test/32-format/mapping.json new file mode 100644 index 0000000..25f87ab --- /dev/null +++ b/test/32-format/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "string", + "name": "test", + "format": "date-time" +} \ No newline at end of file diff --git a/test/32-format/test_32format.py b/test/32-format/test_32format.py new file mode 100644 index 0000000..b975792 --- /dev/null +++ b/test/32-format/test_32format.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_32format(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/32-format/test_shape.ttl b/test/32-format/test_shape.ttl new file mode 100644 index 0000000..7d7b374 --- /dev/null +++ b/test/32-format/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:dateTime, + xsd:string ; + sh:name "test" ; + sh:path . + diff --git a/test/4-Enum/mapping.json b/test/4-Enum/mapping.json new file mode 100644 index 0000000..f9c380c --- /dev/null +++ b/test/4-Enum/mapping.json @@ -0,0 +1,12 @@ +{ + "type": "object", + "name": "office", + "properties": { + "country": { + "enum": [ + "United States of America", + "Canada" + ] + } + } +} \ No newline at end of file diff --git a/test/4-Enum/test_4enum.py b/test/4-Enum/test_4enum.py new file mode 100644 index 0000000..b747581 --- /dev/null +++ b/test/4-Enum/test_4enum.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_4enum(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/4-Enum/test_shape.ttl b/test/4-Enum/test_shape.ttl new file mode 100644 index 0000000..b4454af --- /dev/null +++ b/test/4-Enum/test_shape.ttl @@ -0,0 +1,13 @@ +@prefix sh: . + + a sh:NodeShape ; + sh:name "office" ; + sh:property ; + sh:targetClass . + + a sh:PropertyShape ; + sh:in_ "Canada", + "United States of America" ; + sh:name "country" ; + sh:path . + diff --git a/test/5-pattern/mapping.json b/test/5-pattern/mapping.json new file mode 100644 index 0000000..aed69da --- /dev/null +++ b/test/5-pattern/mapping.json @@ -0,0 +1,5 @@ +{ + "type": "string", + "name": "test", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" +} \ No newline at end of file diff --git a/test/5-pattern/test_5pattern.py b/test/5-pattern/test_5pattern.py new file mode 100644 index 0000000..8efb332 --- /dev/null +++ b/test/5-pattern/test_5pattern.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_5pattern(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/5-pattern/test_shape.ttl b/test/5-pattern/test_shape.ttl new file mode 100644 index 0000000..bd8812d --- /dev/null +++ b/test/5-pattern/test_shape.ttl @@ -0,0 +1,9 @@ +@prefix sh: . +@prefix xsd: . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "test" ; + sh:path ; + sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" . + diff --git a/test/6-additionalProperties/mapping.json b/test/6-additionalProperties/mapping.json new file mode 100644 index 0000000..430b953 --- /dev/null +++ b/test/6-additionalProperties/mapping.json @@ -0,0 +1,9 @@ +{ + "type": "object", + "name": "address", + "properties": { + "number": { "type": "number" }, + "street_name": { "type": "string" } + }, + "additionalProperties": false + } \ No newline at end of file diff --git a/test/6-additionalProperties/test_6additionalproperties.py b/test/6-additionalProperties/test_6additionalproperties.py new file mode 100644 index 0000000..73090ab --- /dev/null +++ b/test/6-additionalProperties/test_6additionalproperties.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_6additionalproperties(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/6-additionalProperties/test_shape.ttl b/test/6-additionalProperties/test_shape.ttl new file mode 100644 index 0000000..eaf71df --- /dev/null +++ b/test/6-additionalProperties/test_shape.ttl @@ -0,0 +1,19 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "address" ; + sh:property , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:datatype xsd:decimal ; + sh:name "number" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "street_name" ; + sh:path . + diff --git a/test/7-required/mapping.json b/test/7-required/mapping.json new file mode 100644 index 0000000..c9073ad --- /dev/null +++ b/test/7-required/mapping.json @@ -0,0 +1,22 @@ +{ + "type": "object", + "name": "address", + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "address": { + "type": "string" + }, + "telephone": { + "type": "string" + } + }, + "required": [ + "name", + "email" + ] +} \ No newline at end of file diff --git a/test/7-required/test_7required.py b/test/7-required/test_7required.py new file mode 100644 index 0000000..c31189f --- /dev/null +++ b/test/7-required/test_7required.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_7required(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/7-required/test_shape.ttl b/test/7-required/test_shape.ttl new file mode 100644 index 0000000..f51a2a2 --- /dev/null +++ b/test/7-required/test_shape.ttl @@ -0,0 +1,30 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "address" ; + sh:property , + , + , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "email" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "name" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "telephone" ; + sh:path . + diff --git a/test/8-unevaluatedProperties/mapping.json b/test/8-unevaluatedProperties/mapping.json new file mode 100644 index 0000000..0cb3a81 --- /dev/null +++ b/test/8-unevaluatedProperties/mapping.json @@ -0,0 +1,22 @@ +{ + "type": "object", + "name": "address", + "properties": { + "street_address": { + "type": "string" + }, + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "type": { + "enum": [ + "residential", + "business" + ] + } + }, + "unevaluatedProperties": false +} \ No newline at end of file diff --git a/test/8-unevaluatedProperties/test_8unevaluatedproperties.py b/test/8-unevaluatedProperties/test_8unevaluatedproperties.py new file mode 100644 index 0000000..02e501a --- /dev/null +++ b/test/8-unevaluatedProperties/test_8unevaluatedproperties.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_8unevaluatedproperties(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/8-unevaluatedProperties/test_shape.ttl b/test/8-unevaluatedProperties/test_shape.ttl new file mode 100644 index 0000000..74bdf05 --- /dev/null +++ b/test/8-unevaluatedProperties/test_shape.ttl @@ -0,0 +1,32 @@ +@prefix sh: . +@prefix xsd: . + + a sh:NodeShape ; + sh:name "address" ; + sh:property , + , + , + ; + sh:targetClass . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "city" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "state" ; + sh:path . + + a sh:PropertyShape ; + sh:datatype xsd:string ; + sh:name "street_address" ; + sh:path . + + a sh:PropertyShape ; + sh:in_ "business", + "residential" ; + sh:name "type" ; + sh:path . + diff --git a/test/9-propertyNames/mapping.json b/test/9-propertyNames/mapping.json new file mode 100644 index 0000000..4d2e099 --- /dev/null +++ b/test/9-propertyNames/mapping.json @@ -0,0 +1,7 @@ +{ + "type": "object", + "name": "propertyNames", + "propertyNames": { + "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" + } +} \ No newline at end of file diff --git a/test/9-propertyNames/test_9propertynames.py b/test/9-propertyNames/test_9propertynames.py new file mode 100644 index 0000000..a169ad9 --- /dev/null +++ b/test/9-propertyNames/test_9propertynames.py @@ -0,0 +1,18 @@ +import os +from rdflib import compare, Graph +from src.file_parser import parse_json_schema +from src.json_schema_to_shacl import JsonSchemaToShacl + + +def test_9propertynames(): + expected_graph = Graph() + expected_graph.parse(os.path.join(os.path.dirname( + os.path.realpath(__file__)), 'test_shape.ttl'), format="turtle") + + result_graph = Graph() + json_schema = parse_json_schema( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mapping.json')) + result_graph = JsonSchemaToShacl().translate( + json_schema) + + assert compare.isomorphic(expected_graph, result_graph) diff --git a/test/9-propertyNames/test_shape.ttl b/test/9-propertyNames/test_shape.ttl new file mode 100644 index 0000000..0e0bfde --- /dev/null +++ b/test/9-propertyNames/test_shape.ttl @@ -0,0 +1,12 @@ +@prefix sh: . + + a sh:NodeShape ; + sh:name "propertyNames" ; + sh:property ; + sh:targetClass . + + a sh:PropertyShape ; + sh:name "propertyNamesPropertyNames" ; + sh:path ; + sh:pattern "^[A-Za-z_][A-Za-z0-9_]*$" . +