test_that("validate_rainfall_data detects missing columns", { data <- data.frame(time = 1:5, wrong_col = 1:5) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("Depth column", result$issues))) }) test_that("validate_rainfall_data detects negative rainfall", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:15")), depth = c(5, -2) ) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("Negative rainfall", result$issues))) }) test_that("validate_rainfall_data detects non-monotonic time", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 09:00")), depth = c(5, 3) ) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("monotonically", result$issues))) }) test_that("validate_rainfall_data passes valid data", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:15", "2024-01-01 10:30")), depth = c(5.2, 3.1, 2.8) ) result <- validate_rainfall_data(data, "time", "depth") expect_true(result$valid) expect_length(result$issues, 0) }) test_that("validate_rainfall_data warns on very small rainfall", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:15")), depth = c(0.3, 0.2) ) result <- validate_rainfall_data(data, "time", "depth") expect_true(any(grepl("less than 1 mm", result$warnings))) }) # ── NA values ───────────────────────────────────────────────────────────────── test_that("validate_rainfall_data detects NA in depth column", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:15")), depth = c(5, NA) ) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("Missing values", result$issues))) }) test_that("validate_rainfall_data detects NA in time column", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", NA)), depth = c(5, 3) ) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("Missing values", result$issues))) }) # ── Duplicate timestamps ────────────────────────────────────────────────────── test_that("validate_rainfall_data detects duplicate timestamps", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:00", "2024-01-01 10:15")), depth = c(5, 3, 2) ) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) expect_true(any(grepl("[Dd]uplicate", result$issues))) }) # ── Empty data frame ────────────────────────────────────────────────────────── test_that("validate_rainfall_data rejects empty data frame", { data <- data.frame(time = as.POSIXct(character(0)), depth = numeric(0)) result <- validate_rainfall_data(data, "time", "depth") expect_false(result$valid) }) # ── Returns correct structure ───────────────────────────────────────────────── test_that("validate_rainfall_data always returns valid/issues/warnings", { data <- data.frame( time = as.POSIXct(c("2024-01-01 10:00", "2024-01-01 10:15")), depth = c(5, 3) ) result <- validate_rainfall_data(data, "time", "depth") expect_named(result, c("valid", "issues", "warnings")) expect_type(result$valid, "logical") expect_type(result$issues, "character") expect_type(result$warnings, "character") }) # ── Built-in dataset ────────────────────────────────────────────────────────── test_that("validate_rainfall_data passes built-in rainfall_single dataset", { data("rainfall_single", package = "rainerosr") result <- validate_rainfall_data(rainfall_single, "datetime", "rainfall_mm") expect_true(result$valid) expect_length(result$issues, 0) })