mirror of
https://github.com/p2p-ld/nwb-linkml.git
synced 2024-11-12 17:54:29 +00:00
test named slot, add skeletons for basemodel methods
This commit is contained in:
parent
016b81a5c5
commit
198ed3bcea
5 changed files with 84 additions and 4 deletions
|
@ -25,7 +25,7 @@ from linkml_runtime.utils.schemaview import SchemaView
|
|||
|
||||
from nwb_linkml.includes.base import (
|
||||
BASEMODEL_CAST_WITH_VALUE,
|
||||
BASEMODEL_COERCE_CHILD,
|
||||
BASEMODEL_COERCE_SUBCLASS,
|
||||
BASEMODEL_COERCE_VALUE,
|
||||
BASEMODEL_EXTRA_TO_VALUE,
|
||||
BASEMODEL_GETITEM,
|
||||
|
@ -56,7 +56,7 @@ class NWBPydanticGenerator(PydanticGenerator):
|
|||
BASEMODEL_GETITEM,
|
||||
BASEMODEL_COERCE_VALUE,
|
||||
BASEMODEL_CAST_WITH_VALUE,
|
||||
BASEMODEL_COERCE_CHILD,
|
||||
BASEMODEL_COERCE_SUBCLASS,
|
||||
BASEMODEL_EXTRA_TO_VALUE,
|
||||
)
|
||||
split: bool = True
|
||||
|
|
|
@ -44,7 +44,7 @@ BASEMODEL_CAST_WITH_VALUE = """
|
|||
raise e1
|
||||
"""
|
||||
|
||||
BASEMODEL_COERCE_CHILD = """
|
||||
BASEMODEL_COERCE_SUBCLASS = """
|
||||
@field_validator("*", mode="before")
|
||||
@classmethod
|
||||
def coerce_subclass(cls, v: Any, info) -> Any:
|
||||
|
|
9
nwb_linkml/tests/fixtures/schema.py
vendored
9
nwb_linkml/tests/fixtures/schema.py
vendored
|
@ -101,6 +101,15 @@ def linkml_schema_bare() -> TestSchemas:
|
|||
inlined_as_list=False,
|
||||
any_of=[{"range": "OtherClass"}, {"range": "StillAnotherClass"}],
|
||||
),
|
||||
SlotDefinition(
|
||||
name="named_slot",
|
||||
description=(
|
||||
"A slot that should use the Named[] generic to set the name param"
|
||||
),
|
||||
annotations=[{"named": True}],
|
||||
range="OtherClass",
|
||||
inlined=True,
|
||||
),
|
||||
SlotDefinition(
|
||||
name="value",
|
||||
description="Main class's array",
|
||||
|
|
|
@ -17,6 +17,7 @@ import pytest
|
|||
from linkml_runtime.utils.compile_python import compile_python
|
||||
from numpydantic.dtype import Float
|
||||
from numpydantic.ndarray import NDArrayMeta
|
||||
from pydantic import ValidationError
|
||||
|
||||
from nwb_linkml.generators.pydantic import NWBPydanticGenerator
|
||||
|
||||
|
@ -86,7 +87,9 @@ def imported_schema(linkml_schema, request) -> TestModules:
|
|||
|
||||
def test_array(imported_schema):
|
||||
"""
|
||||
Arraylike classes are converted to slots that specify nptyping arrays
|
||||
Arraylike classes are converted to slots that specify nptyping arrays.
|
||||
|
||||
Test that we can use any_of with the array slot (unlike the upstream generator, currently)
|
||||
|
||||
array: Optional[Union[
|
||||
NDArray[Shape["* x, * y"], Number],
|
||||
|
@ -155,3 +158,26 @@ def test_get_item(imported_schema):
|
|||
"""We can get without explicitly addressing array"""
|
||||
cls = imported_schema["core"].MainTopLevel(value=np.array([[1, 2, 3], [4, 5, 6]], dtype=float))
|
||||
assert np.array_equal(cls[0], np.array([1, 2, 3], dtype=float))
|
||||
|
||||
|
||||
def test_named_slot(imported_schema):
|
||||
"""
|
||||
Slots that have a ``named`` annotation should get their ``name`` attribute set automatically
|
||||
"""
|
||||
OtherClass = imported_schema["core"].OtherClass
|
||||
MainClass = imported_schema["core"].MainTopLevel
|
||||
|
||||
# We did in fact get the outer annotation
|
||||
# this is a wild ass way to get the function name but hey
|
||||
annotation = MainClass.model_fields["named_slot"].annotation.__args__[0]
|
||||
validation_fn_name = annotation.__metadata__[0].func.__name__
|
||||
assert validation_fn_name == "_get_name"
|
||||
|
||||
# we can't instantiate OtherClass without the ``name``
|
||||
with pytest.raises(ValidationError, match=".*name.*"):
|
||||
_ = OtherClass()
|
||||
|
||||
# but when we instantiate MainClass the name gets set automatically
|
||||
instance = MainClass(named_slot={})
|
||||
assert isinstance(instance.named_slot, OtherClass)
|
||||
assert instance.named_slot.name == "named_slot"
|
||||
|
|
45
nwb_linkml/tests/test_includes/test_base.py
Normal file
45
nwb_linkml/tests/test_includes/test_base.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
Base includes
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_basemodel_getitem(imported_schema):
|
||||
"""
|
||||
We can get a value from ``value`` if we have it
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_basemodel_coerce_value(imported_schema):
|
||||
"""
|
||||
We can instantiate something by trying to grab it's "value" item
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_basemodel_cast_with_value(imported_schema):
|
||||
"""
|
||||
Opposite of above, we try to cast **into** the ``value`` field
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_basemodel_coerce_subclass(imported_schema):
|
||||
"""
|
||||
We try to rescue by coercing to a child class if possible
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_basemodel_extra_to_value(imported_schema):
|
||||
"""
|
||||
We gather extra fields and put them into a value dict when it's present
|
||||
"""
|
||||
pass
|
Loading…
Reference in a new issue