test_that("metrics match hand-computed values", { o <- c(10, 12, 14, 16, 18, 20); p <- c(11, 11, 15, 15, 19, 19) g <- gof(o, p, digits = NULL) expect_equal(g$n, 6L) expect_equal(g$rmse, sqrt(mean((p - o)^2))) expect_equal(g$mbe, mean(p - o)) expect_equal(g$sd_obs, sd(o)) expect_equal(g$rsr, sqrt(mean((p - o)^2)) / sd(o)) expect_equal(g$nse, 1 - sum((p - o)^2) / sum((o - mean(o))^2)) expect_equal(g$nnse, 1 / (2 - g$nse)) expect_equal(g$rmse^2, g$rmse_s^2 + g$rmse_u^2) # Willmott decomposition }) test_that("perfect prediction gives ideal scores", { o <- c(3, 6, 9, 12, 15); g <- gof(o, o, digits = NULL) expect_equal(g$rmse, 0); expect_equal(g$nse, 1) expect_equal(g$d, 1); expect_equal(g$r2, 1) }) test_that("small samples suppress unstable metrics but keep n", { g <- gof(c(1, 2, 3), c(1.1, 2.2, 2.9), min_n = 5) expect_equal(g$n, 3L); expect_true(is.na(g$r2)); expect_true(is.na(g$nse)) expect_false(is.na(g$rmse)) }) test_that("NA pairs are dropped, not propagated", { g <- gof(c(1, NA, 3, 4), c(1, 2, NA, 4), digits = NULL) expect_equal(g$n, 2L); expect_equal(g$rmse, 0) })