Skip to content

Commit fa83337

Browse files
authored
tests: more tests for schema (#166)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
1 parent 9ec5b2a commit fa83337

12 files changed

+101
-14
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ repos:
7373
- id: check-jsonschema
7474
name: Validate Histogram examples
7575
args: [--schemafile, src/uhi/resources/histogram.schema.json]
76-
files: ^tests/resources/.*\.json
76+
files: ^tests/resources/valid/.*\.json
7777

7878
- repo: https://github.com/henryiii/validate-pyproject-schema-store
7979
rev: 2025.02.24

docs/serialization.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ Or with code:
9393
```python
9494
import uhi.schema
9595

96-
uhi.schema.validate("some/file.json")
96+
with filename.open(encoding="utf-8") as f:
97+
data = json.load(f)
98+
99+
uhi.schema.validate(data)
97100
```
98101

99102
Eventually this should also be usable for JSON's inside zip, HDF5 attributes,

src/uhi/schema.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

3+
import functools
34
import json
45
import sys
6+
from collections.abc import Callable
57
from pathlib import Path
6-
7-
import fastjsonschema
8+
from typing import Any
89

910
if sys.version_info < (3, 9):
1011
import importlib_resources as resources
@@ -13,17 +14,47 @@
1314

1415
histogram_file = resources.files("uhi") / "resources/histogram.schema.json"
1516

16-
with histogram_file.open(encoding="utf-8") as f:
17-
histogram_schema = fastjsonschema.compile(json.load(f))
17+
__all__ = ["histogram_file", "validate"]
18+
19+
20+
def __dir__() -> list[str]:
21+
return __all__
22+
23+
24+
@functools.lru_cache(maxsize=None)
25+
def _histogram_schema() -> Callable[[dict[str, Any]], None]:
26+
import fastjsonschema
27+
28+
with histogram_file.open(encoding="utf-8") as f:
29+
return fastjsonschema.compile(json.load(f)) # type: ignore[no-any-return]
30+
31+
32+
def validate(data: dict[str, Any]) -> None:
33+
"""Validate a histogram object against the schema."""
34+
validate = _histogram_schema()
35+
validate(data)
36+
37+
38+
def main(*files: str) -> None:
39+
"""Validate histogram files."""
40+
import fastjsonschema
1841

42+
retval = 0
1943

20-
def validate(path: str | Path) -> None:
21-
path = Path(path)
22-
with path.open(encoding="utf-8") as f:
23-
example = json.load(f)
44+
for file in files:
45+
with Path(file).open(encoding="utf-8") as f:
46+
data = json.load(f)
47+
try:
48+
validate(data)
49+
except fastjsonschema.JsonSchemaValueException as e:
50+
print(f"ERROR {file}: {e.message}") # noqa: T201
51+
retval = 1
52+
else:
53+
print(f"OK {file}") # noqa: T201
2454

25-
histogram_schema(example)
55+
if retval:
56+
raise SystemExit(retval)
2657

2758

2859
if __name__ == "__main__":
29-
validate(*sys.argv[1:])
60+
main(*sys.argv[1:])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data.one.metadata.one must be valid exactly by one definition
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"one": {
3+
"metadata": { "one": { "two": 2 } },
4+
"axes": [],
5+
"storage": { "type": "int", "values": [1] }
6+
}
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data.one must contain ['axes'] properties
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"one": {
3+
"storage": { "type": "int", "values": [1] }
4+
}
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data.one must contain ['storage'] properties
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"one": {
3+
"axes": []
4+
}
5+
}

tests/resources/valid/noaxes.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"one": {
3+
"axes": [],
4+
"storage": { "type": "int", "values": [1] }
5+
}
6+
}
File renamed without changes.

tests/test_histogram_schema.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
from __future__ import annotations
22

3+
import json
4+
import re
35
from pathlib import Path
46

7+
import fastjsonschema
8+
import pytest
9+
510
import uhi.schema
611

712
DIR = Path(__file__).parent.resolve()
813

14+
VALID_FILES = DIR.glob("resources/valid/*.json")
15+
INVALID_FILES = DIR.glob("resources/invalid/*.json")
16+
17+
18+
@pytest.mark.parametrize("filename", VALID_FILES, ids=lambda p: p.name)
19+
def test_valid_schemas(filename: Path) -> None:
20+
with filename.open(encoding="utf-8") as f:
21+
data = json.load(f)
22+
uhi.schema.validate(data)
23+
24+
25+
@pytest.mark.parametrize("filename", INVALID_FILES, ids=lambda p: p.name)
26+
def test_invalid_schemas(filename: Path) -> None:
27+
with filename.open(encoding="utf-8") as f:
28+
data = json.load(f)
29+
30+
try:
31+
errmsg = filename.with_suffix(".error.txt").read_text(encoding="utf-8").strip()
32+
except FileNotFoundError:
33+
errmsg = "NO ERROR MESSAGE FILE FOUND"
934

10-
def test_example_1() -> None:
11-
uhi.schema.validate(DIR / "resources/reg.json")
35+
with pytest.raises(
36+
fastjsonschema.exceptions.JsonSchemaException, match=re.escape(errmsg)
37+
):
38+
uhi.schema.validate(data)

0 commit comments

Comments
 (0)