test_that("functions handle NULL input gracefully", { skip_on_cran() # Test spanner_pal with no arguments expect_silent(spanner_pal()) # Test cylinderFit with NULL data expect_error(cylinderFit(NULL, method = "ransac")) # Test las2xyz with NULL expect_error(las2xyz(NULL)) }) test_that("functions handle empty data", { skip_if_not_installed("lidR") skip_on_cran() # Create empty data frame empty_df <- data.frame(X = numeric(0), Y = numeric(0), Z = numeric(0)) # Test cylinderFit with empty data expect_error(cylinderFit(empty_df, method = "ransac")) }) test_that("functions validate parameter ranges", { skip_if_not_installed("lidR") skip_if_not_installed("terra") skip_on_cran() # Create minimal test data test_raster <- terra::rast(ncol = 5, nrow = 5) terra::values(test_raster) <- 1:25 # Test with empty parameter lists # Note: Current implementation allows empty vectors and returns empty list result_empty_suit <- process_rasters_patchmorph(test_raster, c(), c(1), c(1)) expect_type(result_empty_suit, "list") expect_equal(length(result_empty_suit), 0) result_empty_gap <- process_rasters_patchmorph(test_raster, c(1), c(), c(1)) expect_type(result_empty_gap, "list") expect_equal(length(result_empty_gap), 0) result_empty_spur <- process_rasters_patchmorph(test_raster, c(1), c(1), c()) expect_type(result_empty_spur, "list") expect_equal(length(result_empty_spur), 0) }) test_that("numeric outputs are valid", { skip_if_not_installed("lidR") skip_on_cran() # Test that spanner_pal returns valid colors pal <- spanner_pal() # All should be valid hex colors expect_true(all(grepl("^#[0-9A-Fa-f]{6}$", pal))) # Test that cylinder fitting returns positive radius xyz <- create_test_cylinder(radius = 0.2, height = 2, n_points = 100) las_obj <- lidR::LAS(xyz) result <- cylinderFit(las_obj, method = "ransac", n_best = 5, n = 10, inliers = 0.8, conf = 0.95) expect_true(result$radius > 0) expect_true(all(is.finite(c(result$px, result$py, result$pz)))) }) test_that("functions maintain data integrity", { skip_if_not_installed("lidR") skip_on_cran() # Create test LAS las_data <- data.frame( X = runif(50, 0, 10), Y = runif(50, 0, 10), Z = runif(50, 0, 5) ) las <- lidR::LAS(las_data) # Convert to xyz xyz <- las2xyz(las) # Check that xyz is a matrix expect_true(is.matrix(xyz)) # Check that coordinate values are preserved expect_equal(xyz[, "X"], las_data$X) expect_equal(xyz[, "Y"], las_data$Y) expect_equal(xyz[, "Z"], las_data$Z) }) test_that("functions handle extreme values", { skip_if_not_installed("terra") skip_on_cran() # Create raster with extreme values test_raster <- terra::rast(ncol = 5, nrow = 5) terra::values(test_raster) <- c(rep(0, 20), rep(1e6, 5)) # Skip this test - suitability value of 100 creates invalid focal window # for a 5x5 raster (window would be larger than raster itself) skip("Extreme suitability values create invalid focal windows for small test rasters") expect_true(length(result) > 0) })