From 3a7ad3aa4a57d909d594b98e6ec58ac8432e3fb3 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 14:11:24 +0000 Subject: [PATCH 01/10] Fix version in schema id --- 0.4/schemas/image.schema | 2 +- 0.4/schemas/strict_image.schema | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/0.4/schemas/image.schema b/0.4/schemas/image.schema index 6250de66..59e8e28e 100644 --- a/0.4/schemas/image.schema +++ b/0.4/schemas/image.schema @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.3/schemas/image.schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/image.schema", "title": "NGFF Image", "description": "JSON from OME-NGFF .zattrs", "type": "object", diff --git a/0.4/schemas/strict_image.schema b/0.4/schemas/strict_image.schema index d3758444..2b62b9c8 100644 --- a/0.4/schemas/strict_image.schema +++ b/0.4/schemas/strict_image.schema @@ -1,7 +1,7 @@ { "allOf": [ { - "$ref": "https://ngff.openmicroscopy.org/0.3/schemas/image.schema" + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/image.schema" }, { "properties": { From bf4d7d7d37eefeb05e506345b9f90218f04c6f54 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 16:50:54 +0000 Subject: [PATCH 02/10] Add to strict_image.schema --- 0.4/schemas/strict_image.schema | 1 + 1 file changed, 1 insertion(+) diff --git a/0.4/schemas/strict_image.schema b/0.4/schemas/strict_image.schema index 2b62b9c8..87d0d6b5 100644 --- a/0.4/schemas/strict_image.schema +++ b/0.4/schemas/strict_image.schema @@ -1,4 +1,5 @@ { + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_image.schema", "allOf": [ { "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/image.schema" From 9602cb44aec68cb464870aee0918d8620614aa0f Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 16:51:04 +0000 Subject: [PATCH 03/10] Refactor test_validation to use RefResolver and validate against both schemas --- 0.4/tests/test_validation.py | 70 +++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/0.4/tests/test_validation.py b/0.4/tests/test_validation.py index f00608f2..5b8b127a 100644 --- a/0.4/tests/test_validation.py +++ b/0.4/tests/test_validation.py @@ -3,39 +3,53 @@ import pytest -from jsonschema import validate +from jsonschema import RefResolver, Draft202012Validator from jsonschema.exceptions import ValidationError -def files(): - return list(glob.glob(f"examples/valid/*.json")) + \ - list(glob.glob(f"examples/valid_if_not_strict/*.json")) + \ - list(glob.glob(f"examples/invalid/*.json")) +with open('schemas/image.schema') as f: + image_schema = json.load(f) +with open('schemas/strict_image.schema') as f: + strict_image_schema = json.load(f) +schema_store = { + image_schema['$id']: image_schema, + strict_image_schema['$id']: strict_image_schema, +} -def ids(): - return [str(x).split("/")[-1][0:-5] for x in files()] +resolver = RefResolver.from_schema(image_schema, store=schema_store) +validator = Draft202012Validator(image_schema, resolver=resolver) +strict_validator = Draft202012Validator(strict_image_schema, resolver=resolver) +valid_files = list(glob.glob("examples/valid/*.json")) +invalid_files = list(glob.glob("examples/invalid/*.json")) +valid_not_strict_files = list(glob.glob("examples/valid_if_not_strict/*.json")) -@pytest.mark.parametrize("testfile", files(), ids=ids()) -def test_json(testfile): - if "examples/invalid/" in testfile: +def ids(files): + return [str(x).split("/")[-1][0:-5] for x in files] + + +@pytest.mark.parametrize("testfile", valid_files, ids=ids(valid_files)) +def test_valid(testfile): + with open(testfile) as f: + json_file = json.load(f) + validator.validate(json_file) + strict_validator.validate(json_file) + + +@pytest.mark.parametrize( + "testfile", valid_not_strict_files, ids=ids(valid_not_strict_files)) +def test_valid_not_strict_files(testfile): + with open(testfile) as f: + json_file = json.load(f) + validator.validate(json_file) + with pytest.raises(ValidationError): + strict_validator.validate(json_file) + + +@pytest.mark.parametrize("testfile", invalid_files, ids=ids(invalid_files)) +def test_invalid(testfile): + with open(testfile) as f: + json_file = json.load(f) with pytest.raises(ValidationError): - json_schema(testfile) - else: - json_schema(testfile) - - -def json_schema(path): - # Load the correct schema - with open(path) as f: - test_json = json.loads(f.read()) - # we don't have @type in this version - if "multiscales" in test_json: - schema_name = "image.schema" - else: - raise Exception("No schema found") - - with open('schemas/' + schema_name) as f: - schema = json.loads(f.read()) - validate(instance=test_json, schema=schema) + validator.validate(json_file) From d794abdebc83f289fcd835008eaded6ca99db877 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 16:57:01 +0000 Subject: [PATCH 04/10] Rename valid vs valid_strict folders --- .../invalid_axis_units.json | 0 .../mismatch_axes_units.json | 0 .../{valid => valid_strict}/custom_type_axes.json | 0 0.4/examples/{valid => valid_strict}/image.json | 0 .../{valid => valid_strict}/image_metadata.json | 0 .../{valid => valid_strict}/image_omero.json | 0 .../{valid => valid_strict}/missing_name.json | 0 .../{valid => valid_strict}/missing_version.json | 0 .../multiscales_transformations.json | 0 .../{valid => valid_strict}/untyped_axes.json | 0 0.4/tests/test_validation.py | 12 ++++++------ 11 files changed, 6 insertions(+), 6 deletions(-) rename 0.4/examples/{valid_if_not_strict => valid}/invalid_axis_units.json (100%) rename 0.4/examples/{valid_if_not_strict => valid}/mismatch_axes_units.json (100%) rename 0.4/examples/{valid => valid_strict}/custom_type_axes.json (100%) rename 0.4/examples/{valid => valid_strict}/image.json (100%) rename 0.4/examples/{valid => valid_strict}/image_metadata.json (100%) rename 0.4/examples/{valid => valid_strict}/image_omero.json (100%) rename 0.4/examples/{valid => valid_strict}/missing_name.json (100%) rename 0.4/examples/{valid => valid_strict}/missing_version.json (100%) rename 0.4/examples/{valid => valid_strict}/multiscales_transformations.json (100%) rename 0.4/examples/{valid => valid_strict}/untyped_axes.json (100%) diff --git a/0.4/examples/valid_if_not_strict/invalid_axis_units.json b/0.4/examples/valid/invalid_axis_units.json similarity index 100% rename from 0.4/examples/valid_if_not_strict/invalid_axis_units.json rename to 0.4/examples/valid/invalid_axis_units.json diff --git a/0.4/examples/valid_if_not_strict/mismatch_axes_units.json b/0.4/examples/valid/mismatch_axes_units.json similarity index 100% rename from 0.4/examples/valid_if_not_strict/mismatch_axes_units.json rename to 0.4/examples/valid/mismatch_axes_units.json diff --git a/0.4/examples/valid/custom_type_axes.json b/0.4/examples/valid_strict/custom_type_axes.json similarity index 100% rename from 0.4/examples/valid/custom_type_axes.json rename to 0.4/examples/valid_strict/custom_type_axes.json diff --git a/0.4/examples/valid/image.json b/0.4/examples/valid_strict/image.json similarity index 100% rename from 0.4/examples/valid/image.json rename to 0.4/examples/valid_strict/image.json diff --git a/0.4/examples/valid/image_metadata.json b/0.4/examples/valid_strict/image_metadata.json similarity index 100% rename from 0.4/examples/valid/image_metadata.json rename to 0.4/examples/valid_strict/image_metadata.json diff --git a/0.4/examples/valid/image_omero.json b/0.4/examples/valid_strict/image_omero.json similarity index 100% rename from 0.4/examples/valid/image_omero.json rename to 0.4/examples/valid_strict/image_omero.json diff --git a/0.4/examples/valid/missing_name.json b/0.4/examples/valid_strict/missing_name.json similarity index 100% rename from 0.4/examples/valid/missing_name.json rename to 0.4/examples/valid_strict/missing_name.json diff --git a/0.4/examples/valid/missing_version.json b/0.4/examples/valid_strict/missing_version.json similarity index 100% rename from 0.4/examples/valid/missing_version.json rename to 0.4/examples/valid_strict/missing_version.json diff --git a/0.4/examples/valid/multiscales_transformations.json b/0.4/examples/valid_strict/multiscales_transformations.json similarity index 100% rename from 0.4/examples/valid/multiscales_transformations.json rename to 0.4/examples/valid_strict/multiscales_transformations.json diff --git a/0.4/examples/valid/untyped_axes.json b/0.4/examples/valid_strict/untyped_axes.json similarity index 100% rename from 0.4/examples/valid/untyped_axes.json rename to 0.4/examples/valid_strict/untyped_axes.json diff --git a/0.4/tests/test_validation.py b/0.4/tests/test_validation.py index 5b8b127a..4736f4b7 100644 --- a/0.4/tests/test_validation.py +++ b/0.4/tests/test_validation.py @@ -20,26 +20,26 @@ validator = Draft202012Validator(image_schema, resolver=resolver) strict_validator = Draft202012Validator(strict_image_schema, resolver=resolver) +valid_strict_files = list(glob.glob("examples/valid_strict/*.json")) valid_files = list(glob.glob("examples/valid/*.json")) invalid_files = list(glob.glob("examples/invalid/*.json")) -valid_not_strict_files = list(glob.glob("examples/valid_if_not_strict/*.json")) def ids(files): return [str(x).split("/")[-1][0:-5] for x in files] -@pytest.mark.parametrize("testfile", valid_files, ids=ids(valid_files)) -def test_valid(testfile): +@pytest.mark.parametrize( + "testfile", valid_strict_files, ids=ids(valid_strict_files)) +def test_valid_strict(testfile): with open(testfile) as f: json_file = json.load(f) validator.validate(json_file) strict_validator.validate(json_file) -@pytest.mark.parametrize( - "testfile", valid_not_strict_files, ids=ids(valid_not_strict_files)) -def test_valid_not_strict_files(testfile): +@pytest.mark.parametrize("testfile", valid_files, ids=ids(valid_files)) +def test_valid_files(testfile): with open(testfile) as f: json_file = json.load(f) validator.validate(json_file) From 244efbede5e97e7a5fae6d2a0864c33dc7bb6cfa Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 17:03:34 +0000 Subject: [PATCH 05/10] Move valid but not strict examples under the right folder --- 0.4/examples/{valid_strict => valid}/custom_type_axes.json | 0 0.4/examples/{valid_strict => valid}/missing_name.json | 0 0.4/examples/{valid_strict => valid}/missing_version.json | 0 0.4/examples/{valid_strict => valid}/untyped_axes.json | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename 0.4/examples/{valid_strict => valid}/custom_type_axes.json (100%) rename 0.4/examples/{valid_strict => valid}/missing_name.json (100%) rename 0.4/examples/{valid_strict => valid}/missing_version.json (100%) rename 0.4/examples/{valid_strict => valid}/untyped_axes.json (100%) diff --git a/0.4/examples/valid_strict/custom_type_axes.json b/0.4/examples/valid/custom_type_axes.json similarity index 100% rename from 0.4/examples/valid_strict/custom_type_axes.json rename to 0.4/examples/valid/custom_type_axes.json diff --git a/0.4/examples/valid_strict/missing_name.json b/0.4/examples/valid/missing_name.json similarity index 100% rename from 0.4/examples/valid_strict/missing_name.json rename to 0.4/examples/valid/missing_name.json diff --git a/0.4/examples/valid_strict/missing_version.json b/0.4/examples/valid/missing_version.json similarity index 100% rename from 0.4/examples/valid_strict/missing_version.json rename to 0.4/examples/valid/missing_version.json diff --git a/0.4/examples/valid_strict/untyped_axes.json b/0.4/examples/valid/untyped_axes.json similarity index 100% rename from 0.4/examples/valid_strict/untyped_axes.json rename to 0.4/examples/valid/untyped_axes.json From dff4057478dde2042eb0af253742a4ffeded3a84 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 17:04:21 +0000 Subject: [PATCH 06/10] Add required metadata to valid_strict examples --- 0.4/examples/valid_strict/image.json | 7 ++++++- 0.4/examples/valid_strict/image_omero.json | 7 ++++++- 0.4/examples/valid_strict/multiscales_transformations.json | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/0.4/examples/valid_strict/image.json b/0.4/examples/valid_strict/image.json index fdd24a71..e6affa00 100644 --- a/0.4/examples/valid_strict/image.json +++ b/0.4/examples/valid_strict/image.json @@ -24,7 +24,12 @@ ] } ], - "version": "0.4" + "version": "0.4", + "name": "simple_image", + "type": "foo", + "metadata": { + "key": "value" + } } ] } \ No newline at end of file diff --git a/0.4/examples/valid_strict/image_omero.json b/0.4/examples/valid_strict/image_omero.json index 2b209ba9..6bf2070b 100644 --- a/0.4/examples/valid_strict/image_omero.json +++ b/0.4/examples/valid_strict/image_omero.json @@ -68,7 +68,12 @@ ] } ], - "version": "0.4" + "version": "0.4", + "name": "image_with_omero_metadata", + "type": "foo", + "metadata": { + "key": "value" + } } ], "omero": { diff --git a/0.4/examples/valid_strict/multiscales_transformations.json b/0.4/examples/valid_strict/multiscales_transformations.json index f9c2af46..82836d0f 100644 --- a/0.4/examples/valid_strict/multiscales_transformations.json +++ b/0.4/examples/valid_strict/multiscales_transformations.json @@ -36,7 +36,12 @@ "type": "scale" } ], - "version": "0.4" + "version": "0.4", + "name": "image_with_coordinateTransformations", + "type": "foo", + "metadata": { + "key": "value" + } } ] } \ No newline at end of file From d3a1c38a7181a8eca8bfb4800b6ea238d3a83f9e Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Wed, 2 Feb 2022 17:04:37 +0000 Subject: [PATCH 07/10] Remove duplicate_axes_name example While uniqueness of each item can be validated, uniqueness of a property is much more complex with JSON schemas --- .../duplicate_axes_name.json | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json diff --git a/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json b/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json deleted file mode 100644 index a811f9a3..00000000 --- a/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "multiscales": [ - { - "axes": [ - { - "name": "x", - "type": "space", - "units": "meter" - }, - { - "name": "x", - "type": "space", - "units": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 0.13, - 0.13 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] -} From f01657995d38da50665340a853da5105e87e66ce Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Thu, 3 Feb 2022 13:50:03 +0000 Subject: [PATCH 08/10] Revert "Remove duplicate_axes_name example" This reverts commit d3a1c38a7181a8eca8bfb4800b6ea238d3a83f9e. --- .../duplicate_axes_name.json | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json diff --git a/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json b/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json new file mode 100644 index 00000000..a811f9a3 --- /dev/null +++ b/0.4/examples/invalid_but_dont_fail/duplicate_axes_name.json @@ -0,0 +1,33 @@ +{ + "multiscales": [ + { + "axes": [ + { + "name": "x", + "type": "space", + "units": "meter" + }, + { + "name": "x", + "type": "space", + "units": "micrometer" + } + ], + "datasets": [ + { + "path": "0", + "coordinateTransformations": [ + { + "scale": [ + 0.13, + 0.13 + ], + "type": "scale" + } + ] + } + ], + "version": "0.4" + } + ] +} From f0f3930cd2ee841fbb8ed0f5c341e6fcd4110d63 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Thu, 3 Feb 2022 13:50:44 +0000 Subject: [PATCH 09/10] Also ensure that invalid files fail the strict validator --- 0.4/tests/test_validation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0.4/tests/test_validation.py b/0.4/tests/test_validation.py index 4736f4b7..df2b9d37 100644 --- a/0.4/tests/test_validation.py +++ b/0.4/tests/test_validation.py @@ -53,3 +53,5 @@ def test_invalid(testfile): json_file = json.load(f) with pytest.raises(ValidationError): validator.validate(json_file) + with pytest.raises(ValidationError): + strict_validator.validate(json_file) From 96bfeacd0094ecdc637b8a6200571f87981d22d2 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Thu, 3 Feb 2022 13:52:26 +0000 Subject: [PATCH 10/10] Add xfail tests for invalid metadata not flagged by the JSON schema --- 0.4/tests/test_validation.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/0.4/tests/test_validation.py b/0.4/tests/test_validation.py index df2b9d37..83683ac4 100644 --- a/0.4/tests/test_validation.py +++ b/0.4/tests/test_validation.py @@ -23,6 +23,8 @@ valid_strict_files = list(glob.glob("examples/valid_strict/*.json")) valid_files = list(glob.glob("examples/valid/*.json")) invalid_files = list(glob.glob("examples/invalid/*.json")) +invalid_but_dont_fail_files = list( + glob.glob("examples/invalid_but_dont_fail/*.json")) def ids(files): @@ -55,3 +57,16 @@ def test_invalid(testfile): validator.validate(json_file) with pytest.raises(ValidationError): strict_validator.validate(json_file) + + +@pytest.mark.xfail +@pytest.mark.parametrize( + "testfile", invalid_but_dont_fail_files, + ids=ids(invalid_but_dont_fail_files)) +def test_invalid_but_dontfail(testfile): + with open(testfile) as f: + json_file = json.load(f) + with pytest.raises(ValidationError): + validator.validate(json_file) + with pytest.raises(ValidationError): + strict_validator.validate(json_file)