Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add json validation to tests #310

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ package-dir = {"probeinterface" = "src/probeinterface"}
[project.optional-dependencies]

test = [
"jsonschema",
"pytest",
"pytest-cov",
"matplotlib",
Expand Down
8 changes: 6 additions & 2 deletions resources/probe.json.schema
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
"annotations": {
"type": "object",
"properties": {
"name": { "type": "string" },
"model_name": { "type": "string" },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about this name change. Both "name" and "model_name" are present as metadata, and neither required by the probe object. Should we make it required here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want the json_schema to map perfectly onto the Probe object, or might it make sense of have them hav slightly different requirements?

"manufacturer": { "type": "string" }
},
"required": ["name", "manufacturer"],
"required": ["model_name", "manufacturer"],
"additionalProperties": true
},
"contact_annotations": {
Expand Down Expand Up @@ -101,6 +101,10 @@
"shank_ids": {
"type": "array",
"items": { "type": "string" }
},
"device_channel_indices": {
"type": "array",
"items": { "type": "integer" }
}
},
"required": [
Expand Down
1 change: 0 additions & 1 deletion src/probeinterface/probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import numpy as np
from typing import Optional
from pathlib import Path
import json

from .shank import Shank

Expand Down
13 changes: 13 additions & 0 deletions src/probeinterface/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import json
from pathlib import Path

from probeinterface import __version__ as version
import jsonschema

json_schema_file = Path(__file__).absolute().parent.parent.parent / "resources" / "probe.json.schema"
schema = json.load(open(json_schema_file, "r"))


def validate_probe_dict(probe_dict):
instance = dict(specification="probeinterface", version=version, probes=[probe_dict])
jsonschema.validate(instance=instance, schema=schema)
12 changes: 12 additions & 0 deletions tests/test_io/test_3brain.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import glob
from pathlib import Path
import numpy as np

import pytest

from probeinterface import read_3brain

from probeinterface.testing import validate_probe_dict


data_path = Path(__file__).absolute().parent.parent / "data" / "3brain"
brw_files = glob.glob(str(data_path / "*.brw"))


@pytest.mark.parametrize("file_", brw_files)
def test_valid_probe_dict(file_: str):
probe = read_3brain(data_path / file_)
probe_dict = probe.to_dict(array_as_list=True)
probe_dict["annotations"].update(model_name="placeholder")
validate_probe_dict(probe_dict)

def test_3brain():
"""Files on ephy_test_data"""
Expand Down
11 changes: 11 additions & 0 deletions tests/test_io/test_imro.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import glob
from pathlib import Path

import pytest
import numpy as np

from probeinterface import read_imro, write_imro
from probeinterface.testing import validate_probe_dict

data_path = Path(__file__).absolute().parent.parent / "data" / "imro"
imro_files = glob.glob(str(data_path / "*.imro"))

imro_files.pop(imro_files.index(str(data_path / "test_non_standard.imro")))


@pytest.mark.parametrize("file_", imro_files)
def test_valid_probe_dict(file_: str):
probe = read_imro(data_path / file_)
validate_probe_dict(probe.to_dict(array_as_list=True))


def test_reading_multishank_imro(tmp_path):
Expand Down
9 changes: 9 additions & 0 deletions tests/test_io/test_maxwell.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@
import pytest

from probeinterface import read_maxwell
from probeinterface.testing import validate_probe_dict

data_path = Path(__file__).absolute().parent.parent / "data" / "maxwell"


def test_valid_probe_dict():
file_ = "data.raw.h5"
probe = read_maxwell(data_path / file_)
probe_dict = probe.to_dict(array_as_list=True)
probe_dict["annotations"].update(model_name="placeholder")
validate_probe_dict(probe_dict)


def test_maxwell():
"""Basic file taken from the ephys data repository and provided by Alessio Buccino"""

Expand Down
9 changes: 9 additions & 0 deletions tests/test_io/test_spikeglx.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import glob
from pathlib import Path
import numpy as np

Expand All @@ -8,8 +9,16 @@
parse_spikeglx_meta,
get_saved_channel_indices_from_spikeglx_meta,
)
from probeinterface.testing import validate_probe_dict

data_path = Path(__file__).absolute().parent.parent / "data" / "spikeglx"
meta_files = glob.glob(str(data_path / "*.meta"))


@pytest.mark.parametrize("meta_file", meta_files)
def test_valid_probe_dict(meta_file: str):
probe = read_spikeglx(data_path / meta_file)
validate_probe_dict(probe.to_dict(array_as_list=True))


def test_parse_meta():
Expand Down
Loading