# Tests for weighting() # Run with: devtools::test() or testthat::test_file("tests/testthat/test-weighting.R") # Helper: create a small minority data frame with known outliers make_minority <- function(n_normal = 30, n_outlier = 3, seed = 42) { set.seed(seed) normal <- data.frame( x1 = rnorm(n_normal, mean = 0, sd = 1), x2 = rnorm(n_normal, mean = 0, sd = 1), class = "positive" ) outliers <- data.frame( x1 = rnorm(n_outlier, mean = 10, sd = 0.1), x2 = rnorm(n_outlier, mean = 10, sd = 0.1), class = "positive" ) rbind(normal, outliers) } # ── Output structure ─────────────────────────────────────────────────────── test_that("weighting returns a data frame", { df <- make_minority() result <- weighting(df, threshold = 0.01, weight_func = 1) expect_s3_class(result, "data.frame") }) test_that("weighting adds MD, weights, and prob columns", { df <- make_minority() result <- weighting(df, threshold = 0.01, weight_func = 1) expect_true(all(c("MD", "weights", "prob") %in% colnames(result))) }) test_that("number of rows is unchanged after weighting", { df <- make_minority() result <- weighting(df, threshold = 0.01, weight_func = 1) expect_equal(nrow(result), nrow(df)) }) # ── Probability distribution ─────────────────────────────────────────────── test_that("prob column sums to 1", { df <- make_minority() result <- weighting(df, threshold = 0.01, weight_func = 1) expect_equal(sum(result$prob), 1, tolerance = 1e-10) }) test_that("prob values are all non-negative", { df <- make_minority() result <- weighting(df, threshold = 0.01, weight_func = 1) expect_true(all(result$prob >= 0)) }) # ── Weighting functions ──────────────────────────────────────────────────── test_that("weight_func = 1: outliers receive weight 0", { df <- make_minority(n_outlier = 3) result <- weighting(df, threshold = 0.01, weight_func = 1) # Outlier observations (last 3 rows) should have weight 0 outlier_rows <- tail(result, 3) expect_true(all(outlier_rows$weights == 0)) }) test_that("weight_func = 1: non-outliers receive weight 1", { df <- make_minority(n_outlier = 3) result <- weighting(df, threshold = 0.01, weight_func = 1) normal_rows <- head(result, 30) expect_true(sum(normal_rows$weights > 0) >= 24) }) test_that("weight_func = 2: outliers receive weight < 1", { df <- make_minority(n_outlier = 3) result <- weighting(df, threshold = 0.01, weight_func = 2) outlier_rows <- tail(result, 3) expect_true(all(outlier_rows$weights < 1)) expect_true(all(outlier_rows$weights > 0)) # not zero }) test_that("weight_func = 3: outliers receive weight < 1", { df <- make_minority(n_outlier = 3) result <- weighting(df, threshold = 0.01, weight_func = 3) outlier_rows <- tail(result, 3) expect_true(all(outlier_rows$weights < 1)) expect_true(all(outlier_rows$weights > 0)) # not zero }) test_that("weight ordering: omega_A <= omega_B <= omega_C for outliers", { df <- make_minority(n_outlier = 3) r1 <- weighting(df, threshold = 0.01, weight_func = 1) r2 <- weighting(df, threshold = 0.01, weight_func = 2) r3 <- weighting(df, threshold = 0.01, weight_func = 3) # For each outlier: w_A <= w_B <= w_C outlier_idx <- tail(seq_len(nrow(df)), 3) expect_true(all(r1$weights[outlier_idx] <= r2$weights[outlier_idx])) expect_true(all(r2$weights[outlier_idx] <= r3$weights[outlier_idx])) }) # ── Input validation ─────────────────────────────────────────────────────── test_that("missing 'class' column raises error", { df <- data.frame(x1 = rnorm(20), x2 = rnorm(20)) expect_error(weighting(df), regexp = "class") }) test_that("invalid weight_func raises error", { df <- make_minority() expect_error(weighting(df, weight_func = 5), regexp = "weight_func") }) test_that("threshold outside (0,1) raises error", { df <- make_minority() expect_error(weighting(df, threshold = 1.5), regexp = "threshold") expect_error(weighting(df, threshold = 0), regexp = "threshold") }) test_that("non-data-frame input raises error", { expect_error(weighting(list(x = 1:10, class = "positive")), regexp = "data frame") }) # ── All estimators ───────────────────────────────────────────────────────── test_that("all cov_method options work in weighting", { df <- make_minority(n_normal = 50) methods <- c("mcd", "mve", "mest", "mmest", "sde", "sest", "ogk") for (m in methods) { expect_no_error(weighting(df, cov_method = m)) } })