Skip to content

Commit 0807ac7

Browse files
committed
test: refactor tile format detection and extraction tests using rstest
1 parent 6d6a200 commit 0807ac7

1 file changed

Lines changed: 132 additions & 54 deletions

File tree

versatiles_pipeline/src/operations/read/from_tilejson.rs

Lines changed: 132 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -286,92 +286,170 @@ crate::operations::macros::define_read_factory!("from_tilejson", Args, Operation
286286
#[cfg(test)]
287287
mod tests {
288288
use super::*;
289-
289+
use rstest::rstest;
290+
291+
// ── detect_tile_format ──────────────────────────────────────────────
292+
293+
#[rstest]
294+
#[case(".pbf", TileFormat::MVT)]
295+
#[case(".png", TileFormat::PNG)]
296+
#[case(".webp", TileFormat::WEBP)]
297+
#[case(".jpg", TileFormat::JPG)]
298+
#[case(".jpeg", TileFormat::JPG)]
299+
#[case(".avif", TileFormat::AVIF)]
300+
#[case(".geojson", TileFormat::GEOJSON)]
301+
#[case(".json", TileFormat::JSON)]
302+
#[case(".svg", TileFormat::SVG)]
303+
#[case(".topojson", TileFormat::TOPOJSON)]
304+
#[case(".PNG", TileFormat::PNG)]
290305
#[test]
291-
fn test_detect_tile_format_from_tilejson_field() {
292-
let tilejson = TileJSON {
293-
tile_format: Some(TileFormat::MVT),
294-
..Default::default()
295-
};
296-
let result = detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}");
297-
assert_eq!(result.unwrap(), TileFormat::MVT);
306+
fn detect_format_from_url_extension(#[case] ext: &str, #[case] expected: TileFormat) {
307+
let url = format!("https://example.com/{{z}}/{{x}}/{{y}}{ext}");
308+
assert_eq!(detect_tile_format(&TileJSON::default(), &url).unwrap(), expected);
298309
}
299310

311+
#[rstest]
312+
#[case("https://example.com/{z}/{x}/{y}")]
313+
#[case("https://example.com/{z}/{x}/{y}.xyz")]
314+
#[case("https://example.com/{z}/{x}/{y}?format=png")]
300315
#[test]
301-
fn test_detect_tile_format_from_url_pbf() {
302-
let tilejson = TileJSON::default();
303-
let result = detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}.pbf");
304-
assert_eq!(result.unwrap(), TileFormat::MVT);
316+
fn detect_format_from_url_fails(#[case] url: &str) {
317+
assert!(detect_tile_format(&TileJSON::default(), url).is_err());
305318
}
306319

307320
#[test]
308-
fn test_detect_tile_format_from_url_png() {
309-
let tilejson = TileJSON::default();
310-
let result = detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}.png");
311-
assert_eq!(result.unwrap(), TileFormat::PNG);
312-
}
313-
314-
#[test]
315-
fn test_detect_tile_format_missing() {
316-
let tilejson = TileJSON::default();
317-
let result = detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}");
318-
assert!(result.is_err());
321+
fn detect_format_from_tilejson_field() {
322+
let tilejson = TileJSON {
323+
tile_format: Some(TileFormat::MVT),
324+
..Default::default()
325+
};
326+
assert_eq!(
327+
detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}").unwrap(),
328+
TileFormat::MVT,
329+
);
319330
}
320331

321332
#[test]
322-
fn test_detect_tile_format_tilejson_takes_precedence() {
333+
fn detect_format_tilejson_takes_precedence_over_url() {
323334
let tilejson = TileJSON {
324335
tile_format: Some(TileFormat::JPG),
325336
..Default::default()
326337
};
327-
let result = detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}.png");
328-
assert_eq!(result.unwrap(), TileFormat::JPG);
338+
assert_eq!(
339+
detect_tile_format(&tilejson, "https://example.com/{z}/{x}/{y}.png").unwrap(),
340+
TileFormat::JPG,
341+
);
329342
}
330343

344+
// ── extract_tile_url ────────────────────────────────────────────────
345+
346+
#[rstest]
347+
#[case(
348+
r#"{"tilejson":"3.0.0","tiles":["https://example.com/{z}/{x}/{y}.pbf"]}"#,
349+
"https://example.com/{z}/{x}/{y}.pbf"
350+
)]
351+
#[case(
352+
r#"{"tilejson":"3.0.0","tiles":["https://a.example.com/{z}/{x}/{y}.pbf","https://b.example.com/{z}/{x}/{y}.pbf"]}"#,
353+
"https://a.example.com/{z}/{x}/{y}.pbf"
354+
)]
355+
#[case(
356+
r#"{"tilejson":"3.0.0","tiles":["https://tiles.example.com/v1/{z}/{x}/{y}.mvt?token=abc123"]}"#,
357+
"https://tiles.example.com/v1/{z}/{x}/{y}.mvt?token=abc123"
358+
)]
331359
#[test]
332-
fn test_extract_tile_url_valid() -> Result<()> {
333-
let tilejson = TileJSON::try_from(r#"{"tilejson":"3.0.0","tiles":["https://example.com/{z}/{x}/{y}.pbf"]}"#)?;
334-
let url = extract_tile_url(&tilejson)?;
335-
assert_eq!(url, "https://example.com/{z}/{x}/{y}.pbf");
360+
fn extract_url_valid(#[case] json: &str, #[case] expected: &str) -> Result<()> {
361+
let tilejson = TileJSON::try_from(json)?;
362+
assert_eq!(extract_tile_url(&tilejson)?, expected);
336363
Ok(())
337364
}
338365

339366
#[test]
340-
fn test_extract_tile_url_missing_tiles() {
341-
let tilejson = TileJSON::default();
342-
let result = extract_tile_url(&tilejson);
343-
assert!(result.is_err());
367+
fn extract_url_missing_tiles() {
368+
assert!(extract_tile_url(&TileJSON::default()).is_err());
344369
}
345370

346371
#[test]
347-
fn test_extract_tile_url_empty_tiles() -> Result<()> {
372+
fn extract_url_empty_tiles() -> Result<()> {
348373
let tilejson = TileJSON::try_from(r#"{"tilejson":"3.0.0","tiles":[]}"#)?;
349-
let result = extract_tile_url(&tilejson);
350-
assert!(result.is_err());
374+
assert!(extract_tile_url(&tilejson).is_err());
351375
Ok(())
352376
}
353377

378+
// ── build_tile_url ──────────────────────────────────────────────────
379+
380+
#[rstest]
381+
#[case("https://example.com/{z}/{x}/{y}.pbf", 3, 5, 7, "https://example.com/3/5/7.pbf")]
382+
#[case(
383+
"https://tiles.example.com/data/{z}/{x}/{y}.png",
384+
0,
385+
0,
386+
0,
387+
"https://tiles.example.com/data/0/0/0.png"
388+
)]
389+
#[case(
390+
"https://example.com/{z}/{x}/{y}.pbf",
391+
18,
392+
131072,
393+
262143,
394+
"https://example.com/18/131072/262143.pbf"
395+
)]
396+
#[case(
397+
"https://example.com/{z}/{x}/{y}.pbf?token=secret&v=2",
398+
5,
399+
10,
400+
20,
401+
"https://example.com/5/10/20.pbf?token=secret&v=2"
402+
)]
403+
#[case(
404+
"https://{z}.tiles.example.com/{x}/{y}.png",
405+
4,
406+
8,
407+
12,
408+
"https://4.tiles.example.com/8/12.png"
409+
)]
410+
#[case(
411+
"https://example.com/{z}/{x}/{y}?zoom={z}",
412+
7,
413+
100,
414+
50,
415+
"https://example.com/7/100/50?zoom=7"
416+
)]
354417
#[test]
355-
fn test_build_tile_url() {
356-
let template = "https://example.com/{z}/{x}/{y}.pbf";
357-
let coord = TileCoord::new(3, 5, 7).unwrap();
358-
let url = build_tile_url(template, &coord);
359-
assert_eq!(url, "https://example.com/3/5/7.pbf");
418+
fn build_url(#[case] template: &str, #[case] z: u8, #[case] x: u32, #[case] y: u32, #[case] expected: &str) {
419+
let coord = TileCoord::new(z, x, y).unwrap();
420+
assert_eq!(build_tile_url(template, &coord), expected);
360421
}
361422

362-
#[test]
363-
fn test_build_tile_url_origin() {
364-
let template = "https://tiles.example.com/data/{z}/{x}/{y}.png";
365-
let coord = TileCoord::new(0, 0, 0).unwrap();
366-
let url = build_tile_url(template, &coord);
367-
assert_eq!(url, "https://tiles.example.com/data/0/0/0.png");
423+
// ── fetch_tile ──────────────────────────────────────────────────────
424+
425+
#[tokio::test]
426+
async fn fetch_tile_404_returns_none() {
427+
let client = reqwest::Client::new();
428+
let result = fetch_tile(
429+
client,
430+
"https://httpbin.org/status/404".to_string(),
431+
TileCoord::new(0, 0, 0).unwrap(),
432+
TileFormat::PNG,
433+
0,
434+
)
435+
.await;
436+
assert!(result.is_none());
368437
}
369438

370-
#[test]
371-
fn test_build_tile_url_high_zoom() {
372-
let template = "https://example.com/{z}/{x}/{y}.pbf";
373-
let coord = TileCoord::new(18, 131072, 262143).unwrap();
374-
let url = build_tile_url(template, &coord);
375-
assert_eq!(url, "https://example.com/18/131072/262143.pbf");
439+
#[tokio::test]
440+
async fn fetch_tile_connection_refused_returns_none() {
441+
let client = reqwest::Client::builder()
442+
.timeout(Duration::from_millis(500))
443+
.build()
444+
.unwrap();
445+
let result = fetch_tile(
446+
client,
447+
"http://127.0.0.1:1/{z}/{x}/{y}.pbf".to_string(),
448+
TileCoord::new(0, 0, 0).unwrap(),
449+
TileFormat::MVT,
450+
0,
451+
)
452+
.await;
453+
assert!(result.is_none());
376454
}
377455
}

0 commit comments

Comments
 (0)