Make sure all lines in a MultiLineString are valid

Note we're starting to use hashes in tests because the objects here are
complex and using hashes makes the tests easier to read.
This commit is contained in:
Javi Martín
2024-12-02 12:38:28 +01:00
parent 9ef68f863a
commit c3bda443a6
2 changed files with 70 additions and 3 deletions

View File

@@ -80,10 +80,14 @@ class GeojsonFormatValidator < ActiveModel::EachValidator
when "Point" when "Point"
valid_wgs84_coordinates?(coordinates) valid_wgs84_coordinates?(coordinates)
when "LineString" when "LineString"
coordinates.many? && valid_coordinates_array?(coordinates) valid_linestring_coordinates?(coordinates)
when "MultiPoint" when "MultiPoint"
valid_coordinates_array?(coordinates) valid_coordinates_array?(coordinates)
when "Polygon", "MultiLineString" when "MultiLineString"
coordinates.all? do |linestring_coordinates|
valid_linestring_coordinates?(linestring_coordinates)
end
when "Polygon"
valid_polygon_coordinates?(coordinates) valid_polygon_coordinates?(coordinates)
when "MultiPolygon" when "MultiPolygon"
coordinates.all? do |polygon_coordinates| coordinates.all? do |polygon_coordinates|
@@ -102,9 +106,14 @@ class GeojsonFormatValidator < ActiveModel::EachValidator
end end
def valid_coordinates_array?(coordinates_array) def valid_coordinates_array?(coordinates_array)
coordinates_array.is_a?(Array) &&
coordinates_array.all? { |coordinates| valid_wgs84_coordinates?(coordinates) } coordinates_array.all? { |coordinates| valid_wgs84_coordinates?(coordinates) }
end end
def valid_linestring_coordinates?(coordinates)
valid_coordinates_array?(coordinates) && coordinates.many?
end
def valid_polygon_coordinates?(polygon_coordinates) def valid_polygon_coordinates?(polygon_coordinates)
polygon_coordinates.all? do |ring_coordinates| polygon_coordinates.all? do |ring_coordinates|
valid_coordinates_array?(ring_coordinates) valid_coordinates_array?(ring_coordinates)

View File

@@ -159,6 +159,64 @@ describe GeojsonFormatValidator do
end end
end end
context "Polygon or MultiLineString geometry" do
it "is not valid with a one-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "Polygon", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid with a two-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "Polygon", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).not_to be_valid
end
end
context "MultiLineString geometry" do
it "is valid with just one line" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [[[1.23, 4.56], [7.89, 4.56]]] }'
expect(record).to be_valid
end
it "is valid with multiple valid lines" do
record.geojson = <<~JSON
{
"type": "MultiLineString",
"coordinates": [
[[1.23, 4.56], [7.89, 4.56]],
[[10.11, 12.13], [14.15, 16.17]]
]
}
JSON
expect(record).to be_valid
end
it "is not valid if some lines are invalid" do
record.geojson = <<~JSON
{
"type": "MultiLineString",
"coordinates": [
[[1.23, 4.56], [7.89, 4.56]],
[[10.11, 12.13]]
]
}
JSON
expect(record).not_to be_valid
end
end
context "GeometryCollection" do context "GeometryCollection" do
it "is not valid if it doesn't contain geometries" do it "is not valid if it doesn't contain geometries" do
record.geojson = '{ "type": "GeometryCollection" }' record.geojson = '{ "type": "GeometryCollection" }'