import json
from hypothesis import given, settings
from hypothesis import strategies as st
import maplibre_tiles as mlt
EXTENT = 4096
_coord = st.integers(min_value=0, max_value=EXTENT - 1)
_position = st.tuples(_coord, _coord).map(list)
_point = _position.map(lambda c: {"type": "Point", "coordinates": c})
_linestring = st.lists(_position, min_size=2, max_size=8).map(
lambda cs: {"type": "LineString", "coordinates": cs}
)
_multipoint = st.lists(_position, min_size=1, max_size=8).map(
lambda cs: {"type": "MultiPoint", "coordinates": cs}
)
_ring = st.lists(_position, min_size=3, max_size=6).map(lambda pts: pts + [pts[0]])
_polygon = st.lists(_ring, min_size=1, max_size=3).map(
lambda rings: {"type": "Polygon", "coordinates": rings}
)
_multipolygon = st.lists(st.lists(_ring, min_size=1, max_size=2), min_size=1, max_size=3).map(
lambda polys: {"type": "MultiPolygon", "coordinates": polys}
)
_geometry = st.one_of(_point, _linestring, _multipoint, _polygon, _multipolygon)
_scalar = st.one_of(
st.booleans(),
st.integers(min_value=-(2**63), max_value=2**64 - 1),
st.floats(allow_nan=False, allow_infinity=False),
st.text(max_size=12),
)
_key = st.text(
alphabet=st.characters(min_codepoint=ord("a"), max_codepoint=ord("z")),
min_size=1,
max_size=8,
)
def _fc(features):
return {"type": "FeatureCollection", "features": features}
@given(geometries=st.lists(_geometry, min_size=1, max_size=10))
@settings(max_examples=300)
def test_geometry_roundtrips_for_any_input(geometries):
features = [
{"type": "Feature", "id": i, "geometry": g} for i, g in enumerate(geometries)
]
blob = mlt.encode_geojson(_fc(features), name="l", extent=EXTENT)
fc = json.loads(mlt.decode_mlt_to_geojson(blob))
by_id = {f["id"]: f["geometry"] for f in fc["features"]}
assert len(by_id) == len(geometries)
for i, geometry in enumerate(geometries):
assert by_id[i] == geometry
@given(feature_id=st.integers(min_value=0, max_value=2**64 - 1))
@settings(max_examples=200)
def test_id_roundtrips_for_any_u64(feature_id):
blob = mlt.encode_geojson(
_fc(
[
{
"type": "Feature",
"id": feature_id,
"geometry": {"type": "Point", "coordinates": [1, 2]},
}
]
),
name="l",
extent=EXTENT,
)
assert mlt.decode_mlt(blob)[0].features[0].id == feature_id
@given(props=st.dictionaries(_key, _scalar, max_size=8))
@settings(max_examples=300)
def test_scalar_properties_roundtrip_for_any_dict(props):
blob = mlt.encode_geojson(
_fc(
[
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [1, 2]},
"properties": props,
}
]
),
name="l",
extent=EXTENT,
)
got = mlt.decode_mlt(blob)[0].features[0].properties
for key, value in props.items():
assert got[key] == value
assert isinstance(got[key], type(value))