Skip to content

Commit e529cc6

Browse files
committed
test coverage improvements
1 parent 33e4228 commit e529cc6

1 file changed

Lines changed: 140 additions & 26 deletions

File tree

tiles/src/test/java/com/protomaps/basemap/layers/BoundariesTest.java

Lines changed: 140 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.protomaps.basemap.layers;
22

33
import static com.onthegomap.planetiler.TestUtils.newLineString;
4+
import static com.onthegomap.planetiler.TestUtils.newPolygon;
45

6+
import com.onthegomap.planetiler.FeatureCollector;
57
import com.onthegomap.planetiler.reader.SimpleFeature;
68
import com.onthegomap.planetiler.reader.osm.OsmElement;
79
import com.onthegomap.planetiler.reader.osm.OsmReader;
@@ -11,6 +13,7 @@
1113
import org.junit.jupiter.api.Test;
1214
import org.junit.jupiter.params.ParameterizedTest;
1315
import org.junit.jupiter.params.provider.CsvSource;
16+
import org.junit.jupiter.params.provider.ValueSource;
1417

1518
class BoundariesTest extends LayerTest {
1619
@Test
@@ -104,46 +107,157 @@ void testDisputedOsmWay(String key, String value) {
104107
collector);
105108
}
106109

107-
// The Natural Earth GeoPackage spells the admin columns upper case and the sqlite package lower case,
108-
// so the same feature has to be read correctly either way.
110+
private static final String NE_ADMIN_1_LINES = "ne_10m_admin_1_states_provinces_lines";
109111

110-
@Test
111-
void testNeAdmin1LineGeoPackageCasing() {
112+
private FeatureCollector processNe(String sourceLayer, Map<String, Object> tags) {
113+
return process(SimpleFeature.create(
114+
newLineString(0, 0, 1, 1),
115+
new HashMap<>(tags),
116+
"ne",
117+
sourceLayer,
118+
1
119+
));
120+
}
121+
122+
/** Attributes every Natural Earth boundary line is expected to carry. */
123+
private static Map<String, Object> neLine(String kind, int kindDetail, boolean disputed) {
124+
return Map.of(
125+
"_layer", "boundaries",
126+
"_type", "line",
127+
"kind", kind,
128+
"kind_detail", kindDetail,
129+
"sort_rank", disputed ? 288 : 289,
130+
"disputed", disputed ? true : "<null>"
131+
);
132+
}
133+
134+
// Every featurecla value the Natural Earth switch knows about, so that a mistyped or reordered
135+
// case arm is caught rather than silently falling through to the "drop the feature" default.
136+
@ParameterizedTest
137+
@CsvSource(value = {
138+
"Disputed (please verify),country,2,true",
139+
"Indefinite (please verify),country,2,true",
140+
"Indeterminant frontier,country,2,true",
141+
"Line of control (please verify),country,2,true",
142+
"International boundary (verify),country,2,false",
143+
"Lease limit,lease_limit,3,false",
144+
"Overlay limit,overlay_limit,3,false",
145+
"Unrecognized,unrecognized_country,2,false",
146+
"Map unit boundary,map_unit,3,false",
147+
"Breakaway,unrecognized_country,3,false",
148+
"Claim boundary,unrecognized_country,3,false",
149+
"Elusive frontier,unrecognized_country,3,false",
150+
"Reference line,unrecognized_country,3,false",
151+
"Admin-1 region boundary,macroregion,3,false",
152+
"Admin-1 boundary,region,4,false",
153+
"Admin-1 statistical boundary,region,4,false",
154+
"Admin-1 statistical meta bounds,region,4,false",
155+
"1st Order Admin Lines,region,4,false",
156+
"Unrecognized Admin-1 region boundary,unrecognized_macroregion,4,false",
157+
"Unrecognized Admin-1 boundary,unrecognized_region,4,false",
158+
"Unrecognized Admin-1 statistical boundary,unrecognized_region,4,false",
159+
"Unrecognized Admin-1 statistical meta bounds,unrecognized_region,4,false"
160+
})
161+
void testNeFeatureClass(String featureClass, String kind, int kindDetail, boolean disputed) {
112162
assertFeatures(5,
113-
List.of(Map.of("kind", "region", "kind_detail", 4, "brk_a3", "USA")),
114-
process(SimpleFeature.create(
115-
newLineString(0, 0, 1, 1),
116-
new HashMap<>(Map.of("FEATURECLA", "Admin-1 boundary", "MIN_ZOOM", 2.0, "BRK_A3", "USA")),
117-
"ne",
118-
"ne_10m_admin_1_states_provinces_lines",
119-
1
120-
)));
163+
List.of(neLine(kind, kindDetail, disputed)),
164+
processNe(NE_ADMIN_1_LINES, Map.of("FEATURECLA", featureClass, "MIN_ZOOM", 2.0)));
165+
}
166+
167+
@ParameterizedTest
168+
@ValueSource(strings = {
169+
"ne_10m_admin_0_boundary_lines_land",
170+
"ne_10m_admin_0_boundary_lines_map_units",
171+
"ne_10m_admin_0_boundary_lines_disputed_areas",
172+
NE_ADMIN_1_LINES
173+
})
174+
void testNeSourceLayers(String sourceLayer) {
175+
assertFeatures(5,
176+
List.of(neLine("country", 2, false)),
177+
processNe(sourceLayer, Map.of("FEATURECLA", "International boundary (verify)", "MIN_ZOOM", 2.0)));
178+
}
179+
180+
// Natural Earth column casing is not consistent: the sqlite package lower cases every column, the GeoPackage
181+
// package preserves the source shapefile spelling, and some GeoPackage tables mix both in one table.
182+
// MIN_ZOOM also arrives as a REAL from the GeoPackage but as text from sqlite.
183+
@ParameterizedTest
184+
@CsvSource(value = {
185+
"FEATURECLA,MIN_ZOOM,BRK_A3",
186+
"featurecla,min_zoom,brk_a3",
187+
"FEATURECLA,min_zoom,BRK_A3",
188+
"featurecla,MIN_ZOOM,brk_a3"
189+
})
190+
void testNeColumnCasing(String featureClassKey, String minZoomKey, String brkA3Key) {
191+
assertFeatures(5,
192+
List.of(Map.of("kind", "region", "kind_detail", 4, "brk_a3", "USA", "_minzoom", 1, "_maxzoom", 5)),
193+
processNe(NE_ADMIN_1_LINES,
194+
Map.of(featureClassKey, "Admin-1 boundary", minZoomKey, 2.0, brkA3Key, "USA")));
195+
}
196+
197+
// min_zoom drives the low end of the zoom range, and the Natural Earth boundaries always stop at z5
198+
// where the OpenStreetMap ones take over. Note that min_zoom above 6 is left uncovered here: it produces
199+
// an inverted zoom range, which trips an assertion inside planetiler's setZoomRange.
200+
@ParameterizedTest
201+
@CsvSource(value = {
202+
"1.0,0",
203+
"2.0,1",
204+
"4.5,3",
205+
"6.0,5"
206+
})
207+
void testNeZoomRange(String minZoom, int expectedMinZoom) {
208+
assertFeatures(5,
209+
List.of(Map.of("_minzoom", expectedMinZoom, "_maxzoom", 5)),
210+
processNe(NE_ADMIN_1_LINES, Map.of("FEATURECLA", "Admin-1 boundary", "MIN_ZOOM", minZoom)));
121211
}
122212

123213
@Test
124-
void testNeAdmin1LineSqliteCasing() {
214+
void testNeMissingBrkA3() {
125215
assertFeatures(5,
126-
List.of(Map.of("kind", "region", "kind_detail", 4, "brk_a3", "USA")),
127-
process(SimpleFeature.create(
128-
newLineString(0, 0, 1, 1),
129-
new HashMap<>(Map.of("featurecla", "Admin-1 boundary", "min_zoom", "2.0", "brk_a3", "USA")),
130-
"ne",
131-
"ne_10m_admin_1_states_provinces_lines",
132-
1
133-
)));
216+
List.of(Map.of("kind", "region", "brk_a3", "<null>")),
217+
processNe(NE_ADMIN_1_LINES, Map.of("FEATURECLA", "Admin-1 boundary", "MIN_ZOOM", 2.0)));
134218
}
135219

136220
// Regression test for the NullPointerException from switching the "ne" source to the GeoPackage:
137-
// FEATURECLA is present but featurecla is not, which used to blow up on a null switch expression.
221+
// FEATURECLA was present but featurecla was not, which blew up on a null switch expression.
222+
@Test
223+
void testNeMissingFeatureClass() {
224+
assertFeatures(5,
225+
List.of(),
226+
processNe(NE_ADMIN_1_LINES, Map.of("MIN_ZOOM", 2.0)));
227+
}
228+
229+
@Test
230+
void testNeUnknownFeatureClass() {
231+
assertFeatures(5,
232+
List.of(),
233+
processNe(NE_ADMIN_1_LINES, Map.of("FEATURECLA", "Some new NE value", "MIN_ZOOM", 2.0)));
234+
}
235+
236+
@Test
237+
void testNeMissingMinZoom() {
238+
assertFeatures(5,
239+
List.of(),
240+
processNe(NE_ADMIN_1_LINES, Map.of("FEATURECLA", "Admin-1 boundary")));
241+
}
242+
243+
// Natural Earth has many more boundary tables than the four this layer reads.
244+
@Test
245+
void testNeUnhandledSourceLayer() {
246+
assertFeatures(5,
247+
List.of(),
248+
processNe("ne_10m_admin_0_boundary_lines_maritime_indicator",
249+
Map.of("FEATURECLA", "Admin-1 boundary", "MIN_ZOOM", 2.0)));
250+
}
251+
138252
@Test
139-
void testNeAdmin1LineNullFeatureClass() {
253+
void testNePolygonIsIgnored() {
140254
assertFeatures(5,
141255
List.of(),
142256
process(SimpleFeature.create(
143-
newLineString(0, 0, 1, 1),
144-
new HashMap<>(Map.of("MIN_ZOOM", 2.0)),
257+
newPolygon(0, 0, 0, 1, 1, 1, 0, 0),
258+
new HashMap<>(Map.of("FEATURECLA", "Admin-1 boundary", "MIN_ZOOM", 2.0)),
145259
"ne",
146-
"ne_10m_admin_1_states_provinces_lines",
260+
NE_ADMIN_1_LINES,
147261
1
148262
)));
149263
}

0 commit comments

Comments
 (0)