From 2c3ed2c6b99a0e53c0d06915d19dee2accb713b3 Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Thu, 29 Jan 2026 10:23:29 -0700 Subject: [PATCH 1/6] feat: Adds uv with dependencies --- .gitignore | 2 + pyproject.toml | 15 ++++ uv.lock | 182 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 .gitignore create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f227f00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +*swp diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..84289d7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "big-dctap" +version = "0.2.0" +description = "BIBFRAME Interoperability Group DCTap TSV files used to generate SHACL graphs for validation" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "dctap2shacl>=0.1.1", + "pyshacl>=0.31.0", +] + +[dependency-groups] +dev = [ + "pytest>=9.0.2", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..6b3a52d --- /dev/null +++ b/uv.lock @@ -0,0 +1,182 @@ +version = 1 +revision = 2 +requires-python = ">=3.12" + +[[package]] +name = "big-dctap" +version = "0.2.0" +source = { virtual = "." } +dependencies = [ + { name = "dctap2shacl" }, + { name = "pyshacl" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "dctap2shacl", specifier = ">=0.1.1" }, + { name = "pyshacl", specifier = ">=0.31.0" }, +] + +[package.metadata.requires-dev] +dev = [{ name = "pytest", specifier = ">=9.0.2" }] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dctap2shacl" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "rdflib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/f3/f6b1833a0d56b0d2d90409a76df77a5b3bbed92544769fed2e2095898bc0/dctap2shacl-0.1.1.tar.gz", hash = "sha256:4d7a22d48177a8d814bc120a79724ae7bcf5291f3d3ebd7b210d25b5d93a185a", size = 4251, upload-time = "2026-01-16T15:50:45.364Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/f7/7e600e0db17739d399c5c428e40765e0f1e9f338983d3d0241f9288bf759/dctap2shacl-0.1.1-py3-none-any.whl", hash = "sha256:98428fdb50f691b94c9916221b1ff1affb762d7ed6f44e3b1361e316616656bc", size = 4200, upload-time = "2026-01-16T15:50:46.071Z" }, +] + +[[package]] +name = "html5rdf" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/55/1b839c43f5ed8207e17a9a02d8b395179520b8b4f00c00a41e113bc205ca/html5rdf-1.2.1.tar.gz", hash = "sha256:ace9b420ce52995bb4f05e7425eedf19e433c981dfe7a831ab391e2fa2e1a195", size = 287899, upload-time = "2024-10-30T05:06:56.384Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/c9/f6e1e8567660bc5b0aba281f2b0017b2a7665fcad6bf3ed67286a0c72cd4/html5rdf-1.2.1-py2.py3-none-any.whl", hash = "sha256:1f519121bc366af3e485310dc8041d2e86e5173c1a320fac3dc9d2604069b83e", size = 109765, upload-time = "2024-10-30T05:06:52.507Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "owlrl" +version = "7.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "rdflib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/fc/ce12482d096d65fff01af58f555a6f25e9dbf416fad5d99f91eaab0e11ca/owlrl-7.1.4.tar.gz", hash = "sha256:60bd4067e346b9111f0a2924565afe97ac6595b98b2bbe953928b5113971daf7", size = 44420, upload-time = "2025-07-29T00:17:27.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/78/f857ff1a7207e967dc5e8414bbcc15e0aa5cf45f693b1d2ebe2afb3eb1ce/owlrl-7.1.4-py3-none-any.whl", hash = "sha256:e78b46020169783345636da93a467d318f18700c483184dd15e885850cf64775", size = 51981, upload-time = "2025-07-29T00:17:26.229Z" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "prettytable" +version = "3.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/45/b0847d88d6cfeb4413566738c8bbf1e1995fad3d42515327ff32cc1eb578/prettytable-3.17.0.tar.gz", hash = "sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0", size = 67892, upload-time = "2025-11-14T17:33:20.212Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl", hash = "sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287", size = 34433, upload-time = "2025-11-14T17:33:19.093Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pyshacl" +version = "0.31.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "owlrl" }, + { name = "packaging" }, + { name = "prettytable" }, + { name = "rdflib", extra = ["html"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/2d/8eaada41b9b57c028a54494688e45cfeefd6756098a6bf1bfa2dd9470cdf/pyshacl-0.31.0.tar.gz", hash = "sha256:327950875a5bb0d1a15c246a8a272b2dbf6bc9b96e28cfa8fdbfa4d73aadc0ba", size = 1406151, upload-time = "2026-01-16T06:34:06.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/3b/ebd7c9595fcdf176555aaf2fd2254f4d890658334ca3556b611e579f8294/pyshacl-0.31.0-py3-none-any.whl", hash = "sha256:5cae2184401d956b67deebb00e3c78ab7052784741a730e52e309e33c8a0b9a5", size = 1297210, upload-time = "2026-01-16T06:34:03.679Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "rdflib" +version = "7.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/1b/4cd9a29841951371304828d13282e27a5f25993702c7c87dcb7e0604bd25/rdflib-7.5.0.tar.gz", hash = "sha256:663083443908b1830e567350d72e74d9948b310f827966358d76eebdc92bf592", size = 4903859, upload-time = "2025-11-28T05:51:54.562Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl", hash = "sha256:b011dfc40d0fc8a44252e906dcd8fc806a7859bc231be190c37e9568a31ac572", size = 587215, upload-time = "2025-11-28T05:51:38.178Z" }, +] + +[package.optional-dependencies] +html = [ + { name = "html5rdf" }, +] + +[[package]] +name = "wcwidth" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/3e/3d456efe55d2d5e7938b5f9abd68333dd8dceb14e829f51f9a8deed2217e/wcwidth-0.5.2.tar.gz", hash = "sha256:c022c39a02a0134d1e10810da36d1f984c79648181efcc70a389f4569695f5ae", size = 152817, upload-time = "2026-01-29T19:32:52.22Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/72/da5a6f511a8267f962a08637464a70409736ac72f9f75b069e0e96d69b64/wcwidth-0.5.2-py3-none-any.whl", hash = "sha256:46912178a64217749bf3426b21e36e849fbc46e05c949407b3e364d9f7ffcadf", size = 90088, upload-time = "2026-01-29T19:32:50.592Z" }, +] From 9d0c69b121d0d86b46f056f72e198d288d3d6b64 Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Thu, 29 Jan 2026 14:01:24 -0700 Subject: [PATCH 2/6] feat: Adds Monograph and Serials tests --- tests/conftest.py | 72 +++++++++++++++++++++++++++++++++++++ tests/test_monograph.py | 80 +++++++++++++++++++++++++++++++++++++++++ tests/test_serials.py | 80 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 tests/conftest.py create mode 100644 tests/test_monograph.py create mode 100644 tests/test_serials.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..01da20f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,72 @@ +"""Pytest fixtures for DCTap to SHACL conversion testing.""" + +from pathlib import Path +from typing import Callable + +import pytest +from dctap2shacl import DCTap2SHACLTransformer +from rdflib import Graph + + +@pytest.fixture +def dctap_to_shacl() -> Callable[[str], Graph]: + """ + Factory fixture that converts a DCTap TSV file to a SHACL rdflib Graph. + + This fixture returns a function that takes a TSV filename (or relative path) + and converts it to a SHACL validation graph. The function automatically + searches for the file in the Monograph DCTAP and Serials DCTAP directories. + + Args: + tsv_filename: Name or relative path of the DCTap TSV file. + Examples: "Monograph_Work_Text.tsv", + "Monograph DCTAP/Monograph_Work_Text.tsv", + "Serials DCTAP/Serial_Work_Text.tsv" + + Returns: + rdflib.Graph: SHACL validation graph + + Example: + def test_monograph_work_validation(dctap_to_shacl): + shacl_graph = dctap_to_shacl("Monograph_Work_Text.tsv") + assert len(shacl_graph) > 0 + + def test_with_full_path(dctap_to_shacl): + shacl_graph = dctap_to_shacl("Monograph DCTAP/Monograph_Work_Text.tsv") + assert len(shacl_graph) > 0 + """ + + def _convert(tsv_filename: str) -> Graph: + """Convert a DCTap TSV file to SHACL graph.""" + # Get the project root (parent of tests directory) + project_root = Path(__file__).parent.parent + + # If the filename includes a directory path, use it directly + if "/" in tsv_filename or "\\" in tsv_filename: + tsv_path = project_root / tsv_filename + else: + # Search for the file in common locations + possible_paths = [ + project_root / "Monograph DCTAP" / tsv_filename, + project_root / "Serials DCTAP" / tsv_filename, + project_root / tsv_filename, + ] + + tsv_path = None + for path in possible_paths: + if path.exists(): + tsv_path = path + break + + if tsv_path is None: + raise FileNotFoundError( + f"DCTap file '{tsv_filename}' not found in Monograph DCTAP, " + f"Serials DCTAP, or project root directories" + ) + + # Convert to SHACL graph + transformer = DCTap2SHACLTransformer() + transformer.run(str(tsv_path)) + return transformer.graph + + return _convert diff --git a/tests/test_monograph.py b/tests/test_monograph.py new file mode 100644 index 0000000..1f30a92 --- /dev/null +++ b/tests/test_monograph.py @@ -0,0 +1,80 @@ +import pathlib + +import pytest +import rdflib + +from pyshacl import validate + +TEST_DIRECTORY = pathlib.Path(__file__).parent + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/monograph/12516952.cbd.rdf", 0, 0), + ("loc/monograph/22932823.cbd.rdf", 0, 0), + ("loc/monograph/23703536.cbd.rdf", 0, 0), + ("loc/monograph/22483233.cbd.rdf", 0, 0), + ("loc/monograph/23694998.cbd.rdf", 0, 0), + ], +) +def test_text_works(rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl): + """Tests BIBFRAME Text Works""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + text_graph = dctap_to_shacl("Monograph_Work_Text.tsv") + admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") + shacl_graph = admin_metadata_graph + text_graph + results = validate(str(rdf_test_file), shacl_graph) + assert violations == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True + ) + ] + ) + assert warnings == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True + ) + ] + ) + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/monograph/12516952.cbd.rdf", 0, 0), + ("loc/monograph/22932823.cbd.rdf", 0, 0), + ("loc/monograph/23703536.cbd.rdf", 0, 0), + ("loc/monograph/22483233.cbd.rdf", 0, 0), + ("loc/monograph/23694998.cbd.rdf", 0, 0), + ], +) +def test_print_instances( + rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl +): + """Tests BIBFRAME Print Instances""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + print_graph = dctap_to_shacl("Monograph_Instance_Print.tsv") + admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") + shacl_graph = admin_metadata_graph + print_graph + results = validate(str(rdf_test_file), shacl_graph) + assert violations == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True + ) + ] + ) + assert warnings == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True + ) + ] + ) diff --git a/tests/test_serials.py b/tests/test_serials.py new file mode 100644 index 0000000..dd116cd --- /dev/null +++ b/tests/test_serials.py @@ -0,0 +1,80 @@ +import pathlib + +import pytest +import rdflib + +from pyshacl import validate + +TEST_DIRECTORY = pathlib.Path(__file__).parent + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/serial/11158534.cbd.rdf", 0, 0), + ("loc/serial/21507607.cbd.rdf", 0, 0), + ("loc/serial/23326748.cbd.rdf", 0, 0), + ("loc/serial/23793113.cbd.rdf", 0, 0), + ("loc/serial/23996113.cbd.rdf", 0, 0), + ], +) +def test_text_works(rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl): + """Tests BIBFRAME Serial Works""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + text_graph = dctap_to_shacl("Serial_Work_Text.tsv") + admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") + shacl_graph = text_graph + admin_metadata_graph + results = validate(str(rdf_test_file), shacl_graph) + assert violations == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True + ) + ] + ) + assert warnings == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True + ) + ] + ) + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/serial/11158534.cbd.rdf", 0, 0), + ("loc/serial/21507607.cbd.rdf", 0, 0), + ("loc/serial/23326748.cbd.rdf", 0, 0), + ("loc/serial/23793113.cbd.rdf", 0, 0), + ("loc/serial/23996113.cbd.rdf", 0, 0), + ], +) +def test_print_instances( + rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl +): + """Tests BIBFRAME Serial Instances""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + print_graph = dctap_to_shacl("Serial_Instance_Electronic.tsv") + admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") + shacl_graph = print_graph + admin_metadata_graph + results = validate(str(rdf_test_file), shacl_graph) + assert violations == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True + ) + ] + ) + assert warnings == len( + [ + r + for r in results[1].subjects( + rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True + ) + ] + ) From 29300789dad356f6430a75a87feb69b7c88cfe98 Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Thu, 29 Jan 2026 14:35:11 -0700 Subject: [PATCH 3/6] feat: Adds Github action for automated tests on PR --- .github/workflows/test.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..58278d1 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: Test +on: + - push +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.13] + steps: + + - name: checkout + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Install dev dependencies + run: uv sync + + - name: Run tests + run: uv run pytest From 17351caa0486403c4f220cc8075dd74a13719569 Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Fri, 30 Jan 2026 10:19:39 -0700 Subject: [PATCH 4/6] refactor: Fixes validation and improves tests --- tests/conftest.py | 24 ++++++++++++ tests/test_monograph.py | 81 +++++++++++++++++------------------------ tests/test_serials.py | 81 +++++++++++++++++------------------------ 3 files changed, 92 insertions(+), 94 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 01da20f..36b5701 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,6 +8,30 @@ from rdflib import Graph +@pytest.fixture +def violation_query(): + return """ +PREFIX sh: + +SELECT (COUNT(DISTINCT ?result) AS ?count) +WHERE { + ?result sh:resultSeverity sh:Violation . +} +""" + + +@pytest.fixture +def warning_query(): + return """ +PREFIX sh: + +SELECT (COUNT(DISTINCT ?result) AS ?count) +WHERE { + ?result sh:resultSeverity sh:Warning . +} +""" + + @pytest.fixture def dctap_to_shacl() -> Callable[[str], Graph]: """ diff --git a/tests/test_monograph.py b/tests/test_monograph.py index 1f30a92..a668eb4 100644 --- a/tests/test_monograph.py +++ b/tests/test_monograph.py @@ -1,7 +1,6 @@ import pathlib import pytest -import rdflib from pyshacl import validate @@ -11,70 +10,58 @@ @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/monograph/12516952.cbd.rdf", 0, 0), - ("loc/monograph/22932823.cbd.rdf", 0, 0), - ("loc/monograph/23703536.cbd.rdf", 0, 0), - ("loc/monograph/22483233.cbd.rdf", 0, 0), - ("loc/monograph/23694998.cbd.rdf", 0, 0), + ("loc/monograph/12516952.cbd.rdf", 29, 2), + ("loc/monograph/22932823.cbd.rdf", 22, 2), + ("loc/monograph/23703536.cbd.rdf", 16, 3), + ("loc/monograph/22483233.cbd.rdf", 16, 3), + ("loc/monograph/23694998.cbd.rdf", 16, 3), ], ) -def test_text_works(rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl): +def test_text_works( + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, +): """Tests BIBFRAME Text Works""" rdf_test_file = TEST_DIRECTORY / rdf_file_path text_graph = dctap_to_shacl("Monograph_Work_Text.tsv") admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") shacl_graph = admin_metadata_graph + text_graph - results = validate(str(rdf_test_file), shacl_graph) - assert violations == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True - ) - ] - ) - assert warnings == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True - ) - ] - ) + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/monograph/12516952.cbd.rdf", 0, 0), - ("loc/monograph/22932823.cbd.rdf", 0, 0), - ("loc/monograph/23703536.cbd.rdf", 0, 0), - ("loc/monograph/22483233.cbd.rdf", 0, 0), - ("loc/monograph/23694998.cbd.rdf", 0, 0), + ("loc/monograph/12516952.cbd.rdf", 27, 1), + ("loc/monograph/22932823.cbd.rdf", 18, 1), + ("loc/monograph/23703536.cbd.rdf", 16, 1), + ("loc/monograph/22483233.cbd.rdf", 16, 1), + ("loc/monograph/23694998.cbd.rdf", 16, 1), ], ) def test_print_instances( - rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, ): """Tests BIBFRAME Print Instances""" rdf_test_file = TEST_DIRECTORY / rdf_file_path print_graph = dctap_to_shacl("Monograph_Instance_Print.tsv") admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") shacl_graph = admin_metadata_graph + print_graph - results = validate(str(rdf_test_file), shacl_graph) - assert violations == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True - ) - ] - ) - assert warnings == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True - ) - ] - ) + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count diff --git a/tests/test_serials.py b/tests/test_serials.py index dd116cd..18d06b1 100644 --- a/tests/test_serials.py +++ b/tests/test_serials.py @@ -1,7 +1,6 @@ import pathlib import pytest -import rdflib from pyshacl import validate @@ -11,70 +10,58 @@ @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/serial/11158534.cbd.rdf", 0, 0), - ("loc/serial/21507607.cbd.rdf", 0, 0), - ("loc/serial/23326748.cbd.rdf", 0, 0), - ("loc/serial/23793113.cbd.rdf", 0, 0), - ("loc/serial/23996113.cbd.rdf", 0, 0), + ("loc/serial/11158534.cbd.rdf", 16, 8), + ("loc/serial/21507607.cbd.rdf", 24, 6), + ("loc/serial/23326748.cbd.rdf", 16, 3), + ("loc/serial/23793113.cbd.rdf", 16, 3), + ("loc/serial/23996113.cbd.rdf", 38, 3), ], ) -def test_text_works(rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl): +def test_text_works( + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, +): """Tests BIBFRAME Serial Works""" rdf_test_file = TEST_DIRECTORY / rdf_file_path text_graph = dctap_to_shacl("Serial_Work_Text.tsv") admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") shacl_graph = text_graph + admin_metadata_graph - results = validate(str(rdf_test_file), shacl_graph) - assert violations == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True - ) - ] - ) - assert warnings == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True - ) - ] - ) + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/serial/11158534.cbd.rdf", 0, 0), - ("loc/serial/21507607.cbd.rdf", 0, 0), - ("loc/serial/23326748.cbd.rdf", 0, 0), - ("loc/serial/23793113.cbd.rdf", 0, 0), - ("loc/serial/23996113.cbd.rdf", 0, 0), + ("loc/serial/11158534.cbd.rdf", 16, 8), + ("loc/serial/21507607.cbd.rdf", 24, 4), + ("loc/serial/23326748.cbd.rdf", 16, 1), + ("loc/serial/23793113.cbd.rdf", 16, 2), + ("loc/serial/23996113.cbd.rdf", 36, 1), ], ) def test_print_instances( - rdf_file_path: str, violations: int, warnings: int, dctap_to_shacl + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, ): """Tests BIBFRAME Serial Instances""" rdf_test_file = TEST_DIRECTORY / rdf_file_path print_graph = dctap_to_shacl("Serial_Instance_Electronic.tsv") admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") shacl_graph = print_graph + admin_metadata_graph - results = validate(str(rdf_test_file), shacl_graph) - assert violations == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Violation, unique=True - ) - ] - ) - assert warnings == len( - [ - r - for r in results[1].subjects( - rdflib.SH.resultSeverity, rdflib.SH.Warning, unique=True - ) - ] - ) + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count From 8a2a11c0fcfa2a061e4da8168fa6193e386c1c5e Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Thu, 19 Feb 2026 10:21:22 -0700 Subject: [PATCH 5/6] feat Adds ruff to dev deps --- pyproject.toml | 1 + uv.lock | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 84289d7..b73d21e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,4 +12,5 @@ dependencies = [ [dependency-groups] dev = [ "pytest>=9.0.2", + "ruff>=0.15.1", ] diff --git a/uv.lock b/uv.lock index 6b3a52d..17402f4 100644 --- a/uv.lock +++ b/uv.lock @@ -14,6 +14,7 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "pytest" }, + { name = "ruff" }, ] [package.metadata] @@ -23,7 +24,10 @@ requires-dist = [ ] [package.metadata.requires-dev] -dev = [{ name = "pytest", specifier = ">=9.0.2" }] +dev = [ + { name = "pytest", specifier = ">=9.0.2" }, + { name = "ruff", specifier = ">=0.15.1" }, +] [[package]] name = "colorama" @@ -172,6 +176,31 @@ html = [ { name = "html5rdf" }, ] +[[package]] +name = "ruff" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/dc/4e6ac71b511b141cf626357a3946679abeba4cf67bc7cc5a17920f31e10d/ruff-0.15.1.tar.gz", hash = "sha256:c590fe13fb57c97141ae975c03a1aedb3d3156030cabd740d6ff0b0d601e203f", size = 4540855, upload-time = "2026-02-12T23:09:09.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/bf/e6e4324238c17f9d9120a9d60aa99a7daaa21204c07fcd84e2ef03bb5fd1/ruff-0.15.1-py3-none-linux_armv6l.whl", hash = "sha256:b101ed7cf4615bda6ffe65bdb59f964e9f4a0d3f85cbf0e54f0ab76d7b90228a", size = 10367819, upload-time = "2026-02-12T23:09:03.598Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ea/c8f89d32e7912269d38c58f3649e453ac32c528f93bb7f4219258be2e7ed/ruff-0.15.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:939c995e9277e63ea632cc8d3fae17aa758526f49a9a850d2e7e758bfef46602", size = 10798618, upload-time = "2026-02-12T23:09:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/5e/0f/1d0d88bc862624247d82c20c10d4c0f6bb2f346559d8af281674cf327f15/ruff-0.15.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1d83466455fdefe60b8d9c8df81d3c1bbb2115cede53549d3b522ce2bc703899", size = 10148518, upload-time = "2026-02-12T23:08:58.339Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c8/291c49cefaa4a9248e986256df2ade7add79388fe179e0691be06fae6f37/ruff-0.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9457e3c3291024866222b96108ab2d8265b477e5b1534c7ddb1810904858d16", size = 10518811, upload-time = "2026-02-12T23:09:31.865Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1a/f5707440e5ae43ffa5365cac8bbb91e9665f4a883f560893829cf16a606b/ruff-0.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92c92b003e9d4f7fbd33b1867bb15a1b785b1735069108dfc23821ba045b29bc", size = 10196169, upload-time = "2026-02-12T23:09:17.306Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ff/26ddc8c4da04c8fd3ee65a89c9fb99eaa5c30394269d424461467be2271f/ruff-0.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe5c41ab43e3a06778844c586251eb5a510f67125427625f9eb2b9526535779", size = 10990491, upload-time = "2026-02-12T23:09:25.503Z" }, + { url = "https://files.pythonhosted.org/packages/fc/00/50920cb385b89413f7cdb4bb9bc8fc59c1b0f30028d8bccc294189a54955/ruff-0.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66a6dd6df4d80dc382c6484f8ce1bcceb55c32e9f27a8b94c32f6c7331bf14fb", size = 11843280, upload-time = "2026-02-12T23:09:19.88Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6d/2f5cad8380caf5632a15460c323ae326f1e1a2b5b90a6ee7519017a017ca/ruff-0.15.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a4a42cbb8af0bda9bcd7606b064d7c0bc311a88d141d02f78920be6acb5aa83", size = 11274336, upload-time = "2026-02-12T23:09:14.907Z" }, + { url = "https://files.pythonhosted.org/packages/a3/1d/5f56cae1d6c40b8a318513599b35ea4b075d7dc1cd1d04449578c29d1d75/ruff-0.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ab064052c31dddada35079901592dfba2e05f5b1e43af3954aafcbc1096a5b2", size = 11137288, upload-time = "2026-02-12T23:09:07.475Z" }, + { url = "https://files.pythonhosted.org/packages/cd/20/6f8d7d8f768c93b0382b33b9306b3b999918816da46537d5a61635514635/ruff-0.15.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5631c940fe9fe91f817a4c2ea4e81f47bee3ca4aa646134a24374f3c19ad9454", size = 11070681, upload-time = "2026-02-12T23:08:55.43Z" }, + { url = "https://files.pythonhosted.org/packages/9a/67/d640ac76069f64cdea59dba02af2e00b1fa30e2103c7f8d049c0cff4cafd/ruff-0.15.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:68138a4ba184b4691ccdc39f7795c66b3c68160c586519e7e8444cf5a53e1b4c", size = 10486401, upload-time = "2026-02-12T23:09:27.927Z" }, + { url = "https://files.pythonhosted.org/packages/65/3d/e1429f64a3ff89297497916b88c32a5cc88eeca7e9c787072d0e7f1d3e1e/ruff-0.15.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:518f9af03bfc33c03bdb4cb63fabc935341bb7f54af500f92ac309ecfbba6330", size = 10197452, upload-time = "2026-02-12T23:09:12.147Z" }, + { url = "https://files.pythonhosted.org/packages/78/83/e2c3bade17dad63bf1e1c2ffaf11490603b760be149e1419b07049b36ef2/ruff-0.15.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:da79f4d6a826caaea95de0237a67e33b81e6ec2e25fc7e1993a4015dffca7c61", size = 10693900, upload-time = "2026-02-12T23:09:34.418Z" }, + { url = "https://files.pythonhosted.org/packages/a1/27/fdc0e11a813e6338e0706e8b39bb7a1d61ea5b36873b351acee7e524a72a/ruff-0.15.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3dd86dccb83cd7d4dcfac303ffc277e6048600dfc22e38158afa208e8bf94a1f", size = 11227302, upload-time = "2026-02-12T23:09:36.536Z" }, + { url = "https://files.pythonhosted.org/packages/f6/58/ac864a75067dcbd3b95be5ab4eb2b601d7fbc3d3d736a27e391a4f92a5c1/ruff-0.15.1-py3-none-win32.whl", hash = "sha256:660975d9cb49b5d5278b12b03bb9951d554543a90b74ed5d366b20e2c57c2098", size = 10462555, upload-time = "2026-02-12T23:09:29.899Z" }, + { url = "https://files.pythonhosted.org/packages/e0/5e/d4ccc8a27ecdb78116feac4935dfc39d1304536f4296168f91ed3ec00cd2/ruff-0.15.1-py3-none-win_amd64.whl", hash = "sha256:c820fef9dd5d4172a6570e5721704a96c6679b80cf7be41659ed439653f62336", size = 11599956, upload-time = "2026-02-12T23:09:01.157Z" }, + { url = "https://files.pythonhosted.org/packages/2a/07/5bda6a85b220c64c65686bc85bd0bbb23b29c62b3a9f9433fa55f17cda93/ruff-0.15.1-py3-none-win_arm64.whl", hash = "sha256:5ff7d5f0f88567850f45081fac8f4ec212be8d0b963e385c3f7d0d2eb4899416", size = 10874604, upload-time = "2026-02-12T23:09:05.515Z" }, +] + [[package]] name = "wcwidth" version = "0.5.2" From 7490b605e7a6847199cb6bd67c6f2599bbd70767 Mon Sep 17 00:00:00 2001 From: Jeremy Nelson Date: Thu, 19 Feb 2026 10:21:44 -0700 Subject: [PATCH 6/6] feat: Separates adminMetadata into its own tests --- tests/test_monograph.py | 56 +++++++++++++++++++++++++++----------- tests/test_serials.py | 60 ++++++++++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/tests/test_monograph.py b/tests/test_monograph.py index a668eb4..b624b13 100644 --- a/tests/test_monograph.py +++ b/tests/test_monograph.py @@ -10,11 +10,11 @@ @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/monograph/12516952.cbd.rdf", 29, 2), - ("loc/monograph/22932823.cbd.rdf", 22, 2), - ("loc/monograph/23703536.cbd.rdf", 16, 3), - ("loc/monograph/22483233.cbd.rdf", 16, 3), - ("loc/monograph/23694998.cbd.rdf", 16, 3), + ("loc/monograph/12516952.cbd.rdf", 5, 2), + ("loc/monograph/22932823.cbd.rdf", 6, 2), + ("loc/monograph/23703536.cbd.rdf", 0, 3), + ("loc/monograph/22483233.cbd.rdf", 0, 3), + ("loc/monograph/23694998.cbd.rdf", 0, 3), ], ) def test_text_works( @@ -27,9 +27,7 @@ def test_text_works( ): """Tests BIBFRAME Text Works""" rdf_test_file = TEST_DIRECTORY / rdf_file_path - text_graph = dctap_to_shacl("Monograph_Work_Text.tsv") - admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") - shacl_graph = admin_metadata_graph + text_graph + shacl_graph = dctap_to_shacl("Monograph_Work_Text.tsv") results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) violation_count = int(list(results[1].query(violation_query))[0][0]) warning_count = int(list(results[1].query(warning_query))[0][0]) @@ -40,11 +38,11 @@ def test_text_works( @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/monograph/12516952.cbd.rdf", 27, 1), - ("loc/monograph/22932823.cbd.rdf", 18, 1), - ("loc/monograph/23703536.cbd.rdf", 16, 1), - ("loc/monograph/22483233.cbd.rdf", 16, 1), - ("loc/monograph/23694998.cbd.rdf", 16, 1), + ("loc/monograph/12516952.cbd.rdf", 3, 1), + ("loc/monograph/22932823.cbd.rdf", 2, 1), + ("loc/monograph/23703536.cbd.rdf", 0, 1), + ("loc/monograph/22483233.cbd.rdf", 0, 1), + ("loc/monograph/23694998.cbd.rdf", 0, 1), ], ) def test_print_instances( @@ -57,9 +55,35 @@ def test_print_instances( ): """Tests BIBFRAME Print Instances""" rdf_test_file = TEST_DIRECTORY / rdf_file_path - print_graph = dctap_to_shacl("Monograph_Instance_Print.tsv") - admin_metadata_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") - shacl_graph = admin_metadata_graph + print_graph + shacl_graph = dctap_to_shacl("Monograph_Instance_Print.tsv") + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/monograph/12516952.cbd.rdf", 24, 0), + ("loc/monograph/22932823.cbd.rdf", 16, 0), + ("loc/monograph/23703536.cbd.rdf", 16, 0), + ("loc/monograph/22483233.cbd.rdf", 16, 0), + ("loc/monograph/23694998.cbd.rdf", 16, 0), + ], +) +def test_monograph_admin_metadata( + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, +): + """Tests BIBFRAME Monograph Admin Metadata""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + shacl_graph = dctap_to_shacl("Monograph_AdminMetadata.tsv") results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) violation_count = int(list(results[1].query(violation_query))[0][0]) warning_count = int(list(results[1].query(warning_query))[0][0]) diff --git a/tests/test_serials.py b/tests/test_serials.py index 18d06b1..d5c47fd 100644 --- a/tests/test_serials.py +++ b/tests/test_serials.py @@ -10,14 +10,14 @@ @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/serial/11158534.cbd.rdf", 16, 8), - ("loc/serial/21507607.cbd.rdf", 24, 6), - ("loc/serial/23326748.cbd.rdf", 16, 3), - ("loc/serial/23793113.cbd.rdf", 16, 3), - ("loc/serial/23996113.cbd.rdf", 38, 3), + ("loc/serial/11158534.cbd.rdf", 0, 8), + ("loc/serial/21507607.cbd.rdf", 0, 6), + ("loc/serial/23326748.cbd.rdf", 0, 3), + ("loc/serial/23793113.cbd.rdf", 0, 3), + ("loc/serial/23996113.cbd.rdf", 6, 3), ], ) -def test_text_works( +def test_serial_works( rdf_file_path: str, violations: int, warnings: int, @@ -27,9 +27,7 @@ def test_text_works( ): """Tests BIBFRAME Serial Works""" rdf_test_file = TEST_DIRECTORY / rdf_file_path - text_graph = dctap_to_shacl("Serial_Work_Text.tsv") - admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") - shacl_graph = text_graph + admin_metadata_graph + shacl_graph = dctap_to_shacl("Serial_Work_Text.tsv") results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) violation_count = int(list(results[1].query(violation_query))[0][0]) warning_count = int(list(results[1].query(warning_query))[0][0]) @@ -40,14 +38,14 @@ def test_text_works( @pytest.mark.parametrize( "rdf_file_path, violations, warnings", [ - ("loc/serial/11158534.cbd.rdf", 16, 8), - ("loc/serial/21507607.cbd.rdf", 24, 4), - ("loc/serial/23326748.cbd.rdf", 16, 1), - ("loc/serial/23793113.cbd.rdf", 16, 2), - ("loc/serial/23996113.cbd.rdf", 36, 1), + ("loc/serial/11158534.cbd.rdf", 0, 8), + ("loc/serial/21507607.cbd.rdf", 0, 4), + ("loc/serial/23326748.cbd.rdf", 0, 1), + ("loc/serial/23793113.cbd.rdf", 0, 2), + ("loc/serial/23996113.cbd.rdf", 4, 1), ], ) -def test_print_instances( +def test_serials_instances( rdf_file_path: str, violations: int, warnings: int, @@ -57,9 +55,35 @@ def test_print_instances( ): """Tests BIBFRAME Serial Instances""" rdf_test_file = TEST_DIRECTORY / rdf_file_path - print_graph = dctap_to_shacl("Serial_Instance_Electronic.tsv") - admin_metadata_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") - shacl_graph = print_graph + admin_metadata_graph + shacl_graph = dctap_to_shacl("Serial_Instance_Electronic.tsv") + results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) + violation_count = int(list(results[1].query(violation_query))[0][0]) + warning_count = int(list(results[1].query(warning_query))[0][0]) + assert violations == violation_count + assert warnings == warning_count + + +@pytest.mark.parametrize( + "rdf_file_path, violations, warnings", + [ + ("loc/serial/11158534.cbd.rdf", 16, 0), + ("loc/serial/21507607.cbd.rdf", 24, 0), + ("loc/serial/23326748.cbd.rdf", 16, 0), + ("loc/serial/23793113.cbd.rdf", 16, 0), + ("loc/serial/23996113.cbd.rdf", 32, 0), + ], +) +def test_serials_admin_metadata( + rdf_file_path: str, + violations: int, + warnings: int, + dctap_to_shacl, + violation_query, + warning_query, +): + """Tests BIBFRAME Serial Admin Metadata""" + rdf_test_file = TEST_DIRECTORY / rdf_file_path + shacl_graph = dctap_to_shacl("Serial_AdminMetadata.tsv") results = validate(str(rdf_test_file), shacl_graph=shacl_graph, allow_warnings=True) violation_count = int(list(results[1].query(violation_query))[0][0]) warning_count = int(list(results[1].query(warning_query))[0][0])