tests/testthat/test-gars.R

test_that("gars_fwd works with single point", {
  code <- gars_fwd(c(-74, 40.7))
  
  expect_type(code, "character")
  expect_length(code, 1)
  expect_equal(nchar(code), 7)  # Default precision 2 = 7 characters
})

test_that("gars_fwd works with different precisions", {
  pt <- c(-74, 40.7)
  
  code0 <- gars_fwd(pt, precision = 0)
  code1 <- gars_fwd(pt, precision = 1)
  code2 <- gars_fwd(pt, precision = 2)
  
  expect_equal(nchar(code0), 5)  # 30-minute
  expect_equal(nchar(code1), 6)  # 15-minute
  expect_equal(nchar(code2), 7)  # 5-minute
  
  # Higher precision codes should start with lower precision code
  expect_equal(substr(code1, 1, 5), code0)
  expect_equal(substr(code2, 1, 6), code1)
})

test_that("gars_fwd works with multiple points", {
  pts <- cbind(lon = c(-74, 139.7, 0), lat = c(40.7, 35.7, 51.5))
  codes <- gars_fwd(pts)
  
  expect_length(codes, 3)
  expect_true(all(nchar(codes) == 7))
})

test_that("gars_fwd accepts different input formats", {
  code1 <- gars_fwd(c(-74, 40.7))
  code2 <- gars_fwd(cbind(-74, 40.7))
  code3 <- gars_fwd(list(lon = -74, lat = 40.7))
  
  expect_equal(code1, code2)
  expect_equal(code1, code3)
})

test_that("gars_fwd rejects invalid precision", {
  expect_error(gars_fwd(c(0, 0), precision = -1), "precision must be")
  expect_error(gars_fwd(c(0, 0), precision = 3), "precision must be")
})

test_that("gars_rev returns correct structure", {
  result <- gars_rev("213LR29")
  
  expect_s3_class(result, "data.frame")
  expect_named(result, c("lon", "lat", "precision", "lat_resolution", "lon_resolution"))
  expect_equal(nrow(result), 1)
  
  expect_type(result$lon, "double")
  expect_type(result$lat, "double")
  expect_type(result$precision, "integer")
})

test_that("gars_rev is vectorized", {
  codes <- c("213LR29", "498MH18", "361NS47")
  result <- gars_rev(codes)
  
  expect_equal(nrow(result), 3)
})

test_that("gars_rev detects precision from code length", {
  code0 <- "213LR"     # 5 chars = precision 0
  code1 <- "213LR2"    # 6 chars = precision 1
  code2 <- "213LR29"   # 7 chars = precision 2
  
  result0 <- gars_rev(code0)
  result1 <- gars_rev(code1)
  result2 <- gars_rev(code2)
  
  expect_equal(result0$precision, 0)
  expect_equal(result1$precision, 1)
  expect_equal(result2$precision, 2)
})

test_that("gars_rev resolution matches precision", {
  result0 <- gars_rev("213LR")
  result1 <- gars_rev("213LR2")
  result2 <- gars_rev("213LR29")
  
  # Precision 0: 30 minutes = 0.5 degrees
  expect_equal(result0$lat_resolution, 0.5)
  
  # Precision 1: 15 minutes = 0.25 degrees
  expect_equal(result1$lat_resolution, 0.25)
  
  # Precision 2: 5 minutes = 5/60 degrees
  expect_equal(result2$lat_resolution, 5/60)
})

test_that("gars round-trip preserves location within resolution", {
  pts <- cbind(lon = c(-74, 139.7, 0), lat = c(40.7, 35.7, 51.5))
  
  codes <- gars_fwd(pts, precision = 2)
  result <- gars_rev(codes)
  
  # Should be within 5-minute resolution
  expect_equal(result$lon, pts[, 1], tolerance = 5/60)
  expect_equal(result$lat, pts[, 2], tolerance = 5/60)
})

test_that("gars works at extreme latitudes", {
  # Near poles (but within GARS coverage: -90 to 90)
  high_lat <- gars_fwd(c(0, 89))
  low_lat <- gars_fwd(c(0, -89))
  
  expect_type(high_lat, "character")
  expect_type(low_lat, "character")
})

test_that("gars works at date line", {
  # Near 180 degrees
  east <- gars_fwd(c(179.9, 0))
  west <- gars_fwd(c(-179.9, 0))
  
  expect_type(east, "character")
  expect_type(west, "character")
})

test_that("gars codes have correct format", {
  code <- gars_fwd(c(0, 0), precision = 2)
  
  # GARS format: 3 digits + 2 letters + digit + digit
  expect_match(code, "^[0-9]{3}[A-Z]{2}[1-4][1-9]$")
})

Try the geographiclib package in your browser

Any scripts or data that you put into this service are public.

geographiclib documentation built on March 4, 2026, 9:07 a.m.