Skip to content

Commit

Permalink
simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
jorisvandenbossche committed Dec 5, 2022
1 parent 954622d commit fb67fa6
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 17 deletions.
1 change: 0 additions & 1 deletion .github/workflows/scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ jobs:
run: |
python -m pip install pytest
cd tests
python generate_test_data.py
pytest test_json_schema.py -v
test-json-metadata:
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Ignore GeoPackage file used in conversion to GeoParquet
*.gpkg*
tests/valid/*
tests/invalid/*
tests/data/*
4 changes: 4 additions & 0 deletions tests/generate_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def write_metadata_json(metadata, name, case="valid"):
metadata["columns"]["geometry"]["crs"] = None
write_metadata_json(metadata, "crs_null")

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["crs"] = "EPSG:4326"
write_metadata_json(metadata, "crs_string", case="invalid")


# Orientation

Expand Down
171 changes: 157 additions & 14 deletions tests/test_json_schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

import copy
import json
import pathlib

Expand All @@ -11,14 +13,139 @@
SCHEMA = json.loads(SCHEMA_SRC.read_text())


@pytest.mark.parametrize(
"path", list((HERE / "valid").iterdir()), ids=lambda path: path.name
)
def test_valid_schema(path):
# # Define test cases

valid_cases = {}
invalid_cases = {}


metadata_template = {
"version": "0.5.0-dev",
"primary_column": "geometry",
"columns": {
"geometry": {
"encoding": "WKB",
"geometry_types": [],
},
},
}


# Minimum required metadata

metadata = copy.deepcopy(metadata_template)
valid_cases["minimal"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata.pop("version")
invalid_cases["missing_version"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata.pop("primary_column")
invalid_cases["missing_primary_column"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata.pop("columns")
invalid_cases["missing_columns"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"] = {}
invalid_cases["missing_columns_entry"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"].pop("encoding")
invalid_cases["missing_geometry_encoding"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"].pop("geometry_types")
invalid_cases["missing_geometry_type"] = metadata


# Geometry column name

metadata = copy.deepcopy(metadata_template)
metadata["primary_column"] = "geom"
metadata["columns"]["geom"] = metadata["columns"].pop("geometry")
valid_cases["geometry_column_name"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["primary_column"] = ""
invalid_cases["geometry_column_name_empty"] = metadata


# Encoding

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["encoding"] = "WKT"
invalid_cases["encoding"] = metadata


# Geometry type - non-empty list

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["geometry_types"] = ["Point"]
valid_cases["geometry_type_list"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["geometry_types"] = "Point"
invalid_cases["geometry_type_string"] = metadata

with open(path, "r") as f:
metadata = json.load(f)["geo"]
metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["geometry_types"] = ["Curve"]
invalid_cases["geometry_type_nonexistent"] = metadata

# CRS - explicit null

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["crs"] = None
valid_cases["crs_null"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["crs"] = "EPSG:4326"
invalid_cases["crs_string"] = metadata


# Orientation

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["orientation"] = "counterclockwise"
valid_cases["orientation"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["orientation"] = "clockwise"
invalid_cases["orientation"] = metadata

# Edges

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["edges"] = "planar"
valid_cases["edges_planar"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["edges"] = "spherical"
valid_cases["edges_spherical"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["edges"] = "ellipsoid"
invalid_cases["edges"] = metadata

# Epoch

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["epoch"] = 2015.1
valid_cases["epoch"] = metadata

metadata = copy.deepcopy(metadata_template)
metadata["columns"]["geometry"]["epoch"] = "2015.1"
invalid_cases["epoch_string"] = metadata


# # Tests

@pytest.mark.parametrize(
"metadata", valid_cases.values(), ids=valid_cases.keys()
)
def test_valid_schema(request, metadata):
errors = Draft7Validator(SCHEMA).iter_errors(metadata)

msgs = []
Expand All @@ -31,25 +158,41 @@ def test_valid_schema(path):
msgs.append(msg)

if not valid:
raise AssertionError(f"Error while validation {path.name}:\n" + "\n".join(msgs))
raise AssertionError(
f"Error while validating '{request.node.callspec.id}':\n"
+ json.dumps({"geo": metadata}, indent=2, sort_keys=True)
+ "\n\nErrors:\n" + "\n".join(msgs)
)


@pytest.mark.parametrize(
"path", list((HERE / "invalid").iterdir()), ids=lambda path: path.name
"metadata", invalid_cases.values(), ids=invalid_cases.keys()
)
def test_invalid_schema(request, path):
if "missing_columns_entry" in path.name:
def test_invalid_schema(request, metadata):
if "missing_columns_entry" in request.node.callspec.id:
request.node.add_marker(
pytest.mark.xfail(reason="Not yet working", strict=True)
)

with open(path, "r") as f:
metadata = json.load(f)["geo"]

errors = Draft7Validator(SCHEMA).iter_errors(metadata)

if not len(list(errors)):
raise AssertionError(
"This is an invalid GeoParquet file, but no validation error "
f"occurred for {path.name}."
f"occurred for '{request.node.callspec.id}':\n"
+ json.dumps({"geo": metadata}, indent=2, sort_keys=True)
)


if __name__ == "__main__":
(HERE / "data").mkdir(exist_ok=True)

def write_metadata_json(metadata, name):
with open(HERE / "data" / ("metadata_" + name + ".json"), "w") as f:
json.dump({"geo": metadata}, f, indent=2, sort_keys=True)

for case, metadata in valid_cases.items():
write_metadata_json(metadata, "valid_" + case)

for case, metadata in invalid_cases.items():
write_metadata_json(metadata, "invalid_" + case)

0 comments on commit fb67fa6

Please sign in to comment.