2023-09-12 02:38:29 +00:00
|
|
|
import shutil
|
2023-09-22 07:31:34 +00:00
|
|
|
import sys
|
|
|
|
from pathlib import Path
|
2024-07-02 04:44:35 +00:00
|
|
|
from typing import Optional
|
2023-09-09 02:46:42 +00:00
|
|
|
|
|
|
|
import pytest
|
2024-07-02 04:44:35 +00:00
|
|
|
from nptyping import Shape, UByte
|
2024-07-10 07:20:01 +00:00
|
|
|
from numpydantic import NDArray
|
2023-09-09 02:46:42 +00:00
|
|
|
|
2023-09-22 07:31:34 +00:00
|
|
|
import nwb_linkml
|
|
|
|
from nwb_linkml.maps.naming import version_module_case
|
2024-07-10 06:52:58 +00:00
|
|
|
from nwb_linkml.providers import LinkMLProvider, PydanticProvider
|
2023-10-12 04:31:00 +00:00
|
|
|
from nwb_linkml.providers.git import DEFAULT_REPOS
|
2023-09-09 02:46:42 +00:00
|
|
|
|
2023-09-12 02:38:29 +00:00
|
|
|
CORE_MODULES = (
|
2024-07-02 04:23:31 +00:00
|
|
|
"core.nwb.base",
|
|
|
|
"core.nwb.device",
|
|
|
|
"core.nwb.epoch",
|
|
|
|
"core.nwb.image",
|
|
|
|
"core.nwb.file",
|
|
|
|
"core.nwb.misc",
|
|
|
|
"core.nwb.behavior",
|
|
|
|
"core.nwb.ecephys",
|
|
|
|
"core.nwb.icephys",
|
|
|
|
"core.nwb.ogen",
|
|
|
|
"core.nwb.ophys",
|
|
|
|
"core.nwb.retinotopy",
|
|
|
|
"core.nwb.language",
|
2023-09-12 02:38:29 +00:00
|
|
|
)
|
2024-07-02 04:23:31 +00:00
|
|
|
|
|
|
|
|
2023-09-12 02:38:29 +00:00
|
|
|
@pytest.mark.parametrize(
|
2024-07-02 04:23:31 +00:00
|
|
|
["repo_version", "schema_version", "schema_dir"], [("2.6.0", "2.6.0-alpha", "v2_6_0_alpha")]
|
2023-09-12 02:38:29 +00:00
|
|
|
)
|
|
|
|
def test_linkml_provider(tmp_output_dir, repo_version, schema_version, schema_dir):
|
|
|
|
|
2023-10-12 03:55:03 +00:00
|
|
|
provider = LinkMLProvider(path=tmp_output_dir, allow_repo=False)
|
2023-09-12 02:38:29 +00:00
|
|
|
# clear any prior output
|
2023-10-12 04:31:00 +00:00
|
|
|
shutil.rmtree(provider.path)
|
2023-09-12 02:38:29 +00:00
|
|
|
assert not provider.path.exists()
|
2024-07-02 04:23:31 +00:00
|
|
|
assert not (provider.namespace_path("core", repo_version) / "namespace.yaml").exists()
|
2023-09-12 02:38:29 +00:00
|
|
|
|
|
|
|
# end to end, check that we can get the 'core' repo at the latest version
|
|
|
|
# in the gitrepo
|
2024-07-02 04:23:31 +00:00
|
|
|
core = provider.get("core", version=repo_version)
|
2023-09-12 02:38:29 +00:00
|
|
|
|
|
|
|
assert core.schema.version == schema_version
|
|
|
|
assert all([mod in core.schema.imports for mod in CORE_MODULES])
|
2024-07-02 04:23:31 +00:00
|
|
|
assert schema_dir in [path.name for path in (provider.path / "core").iterdir()]
|
|
|
|
|
2023-09-12 02:38:29 +00:00
|
|
|
|
2023-10-12 06:28:22 +00:00
|
|
|
@pytest.mark.skip()
|
2023-10-12 04:31:00 +00:00
|
|
|
def test_linkml_build_from_yaml(tmp_output_dir):
|
2024-07-02 04:23:31 +00:00
|
|
|
core = DEFAULT_REPOS["core"]
|
|
|
|
git_dir = nwb_linkml.Config().git_dir / "core"
|
2023-10-12 04:31:00 +00:00
|
|
|
if git_dir.exists():
|
|
|
|
shutil.rmtree(str(git_dir))
|
2024-07-02 04:23:31 +00:00
|
|
|
ns_file = core.provide_from_git("2.6.0")
|
2023-10-12 04:31:00 +00:00
|
|
|
assert git_dir.exists()
|
|
|
|
assert ns_file.exists()
|
|
|
|
|
|
|
|
provider = LinkMLProvider(path=tmp_output_dir, allow_repo=False)
|
|
|
|
|
|
|
|
res = provider.build_from_yaml(ns_file)
|
|
|
|
|
2024-07-02 04:23:31 +00:00
|
|
|
|
2024-07-20 04:28:24 +00:00
|
|
|
# @pytest.mark.depends(on=["test_linkml_provider"])
|
2024-07-30 01:20:30 +00:00
|
|
|
@pytest.mark.xfail
|
2023-09-12 02:38:29 +00:00
|
|
|
@pytest.mark.parametrize(
|
2024-07-02 04:23:31 +00:00
|
|
|
["class_name", "test_fields"],
|
2023-09-12 02:38:29 +00:00
|
|
|
[
|
2024-07-02 04:23:31 +00:00
|
|
|
(
|
|
|
|
"TimeSeries",
|
|
|
|
{
|
|
|
|
"name": str,
|
|
|
|
"description": Optional[str],
|
|
|
|
"comments": Optional[str],
|
|
|
|
"data": "TimeSeriesData",
|
|
|
|
"timestamps": "Optional", # __name__ just gets the first part of Optional[TimeSeriesTimestamps]
|
|
|
|
"control": Optional[NDArray[Shape["* num_times"], UByte]],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
2023-09-12 02:38:29 +00:00
|
|
|
)
|
2023-09-22 07:31:34 +00:00
|
|
|
def test_pydantic_provider_core(tmp_output_dir, class_name, test_fields):
|
2023-09-12 02:38:29 +00:00
|
|
|
provider = PydanticProvider(path=tmp_output_dir)
|
2023-09-12 02:55:45 +00:00
|
|
|
# clear any prior output
|
|
|
|
assert provider.path.parent == tmp_output_dir
|
|
|
|
shutil.rmtree(provider.path, ignore_errors=True)
|
|
|
|
assert not provider.path.exists()
|
2023-09-09 02:46:42 +00:00
|
|
|
|
2023-09-22 07:31:34 +00:00
|
|
|
# first, we should not build if we're allowed to get core from repo
|
2024-07-02 04:23:31 +00:00
|
|
|
core = provider.get("core", allow_repo=True)
|
2023-09-22 07:31:34 +00:00
|
|
|
assert Path(nwb_linkml.__file__).parent in Path(core.__file__).parents
|
2024-07-02 04:23:31 +00:00
|
|
|
assert not (provider.path / "core").exists()
|
2023-09-22 07:31:34 +00:00
|
|
|
|
|
|
|
# then, if we're not allowed to get repo versions, we build!
|
|
|
|
del sys.modules[core.__name__]
|
2024-07-02 04:23:31 +00:00
|
|
|
core = provider.get("core", allow_repo=False)
|
2023-09-22 07:31:34 +00:00
|
|
|
# ensure we didn't get the builtin one
|
|
|
|
assert Path(nwb_linkml.__file__).parent not in Path(core.__file__).parents
|
2024-07-02 04:23:31 +00:00
|
|
|
namespace_path = (
|
|
|
|
tmp_output_dir / "pydantic" / "core" / version_module_case(core.version) / "namespace.py"
|
|
|
|
)
|
2023-10-05 05:54:20 +00:00
|
|
|
assert namespace_path.exists()
|
|
|
|
assert Path(core.__file__) == namespace_path
|
|
|
|
|
2023-09-12 02:38:29 +00:00
|
|
|
test_class = getattr(core, class_name)
|
2024-07-02 04:23:31 +00:00
|
|
|
assert test_class == provider.get_class("core", class_name)
|
2023-09-12 02:38:29 +00:00
|
|
|
|
|
|
|
for k, v in test_fields.items():
|
|
|
|
if isinstance(v, str):
|
|
|
|
assert test_class.model_fields[k].annotation.__name__ == v
|
|
|
|
else:
|
|
|
|
assert test_class.model_fields[k].annotation == v
|