Nothing
# ==============================================================================
# Additional coverage tests for edge cases
# ==============================================================================
# ------------------------------------------------------------------------------
# matching_constraints.R additional tests
# ------------------------------------------------------------------------------
test_that("apply_max_distance with edge value at threshold", {
cost <- matrix(c(1, 2, 3, 4), 2, 2)
# Value exactly at threshold stays unchanged
result <- couplr:::apply_max_distance(cost, max_distance = 3)
expect_equal(result[1, 2], 3)
expect_true(result[2, 2] > 1e15) # 4 > 3
})
test_that("apply_max_distance with zero value", {
cost <- matrix(c(0, 1, 2, 3), 2, 2)
result <- couplr:::apply_max_distance(cost, max_distance = 0.5)
expect_equal(result[1, 1], 0)
expect_true(result[2, 1] > 1e15)
})
test_that("apply_calipers with single caliper matching exactly", {
left <- data.frame(x = c(1, 2))
right <- data.frame(x = c(2, 4))
cost <- matrix(1, 2, 2)
vars <- "x"
calipers <- list(x = 1) # Exactly 1 unit allowed
result <- couplr:::apply_calipers(cost, left, right, calipers, vars)
expect_equal(result[1, 1], 1) # diff = 1, allowed
expect_true(result[1, 2] > 1e15) # diff = 3, not allowed
expect_equal(result[2, 1], 1) # diff = 0, allowed
expect_true(result[2, 2] > 1e15) # diff = 2, not allowed
})
test_that("mark_forbidden_pairs with single pair", {
cost <- matrix(1, 3, 3)
forbidden <- matrix(c(1, 1), ncol = 2)
result <- couplr:::mark_forbidden_pairs(cost, forbidden)
expect_true(result[1, 1] > 1e15)
expect_equal(sum(result > 1e15), 1)
})
test_that("has_valid_pairs with mixed values", {
cost <- matrix(c(1, Inf, 2, couplr:::BIG_COST), 2, 2)
expect_true(couplr:::has_valid_pairs(cost))
})
test_that("count_valid_pairs with single valid pair", {
cost <- matrix(couplr:::BIG_COST, 3, 3)
cost[2, 2] <- 5
expect_equal(couplr:::count_valid_pairs(cost), 1)
})
# ------------------------------------------------------------------------------
# matching_messages.R additional tests
# ------------------------------------------------------------------------------
test_that("couplr_emoji returns correct types", {
old <- getOption("couplr.emoji")
on.exit(options(couplr.emoji = old))
options(couplr.emoji = FALSE)
types <- c("error", "warning", "info", "success", "heart",
"broken", "sparkles", "search", "chart", "warning_sign",
"stop", "check")
for (type in types) {
result <- couplr:::couplr_emoji(type)
expect_type(result, "character")
}
})
test_that("warn_extreme_costs without problem vars", {
expect_warning(
couplr:::warn_extreme_costs(10, 200, 20, NULL),
"skewed"
)
})
test_that("warn_many_forbidden with moderate severity", {
expect_warning(
couplr:::warn_many_forbidden(55, 50, 100),
"forbidden"
)
})
test_that("check_cost_distribution with no extreme ratios", {
cost <- matrix(runif(100, min = 1, max = 2), 10, 10)
result <- couplr:::check_cost_distribution(cost, warn = FALSE)
expect_true(result$valid)
expect_true(is.na(result$p95) || result$p99 / result$p95 <= 10)
})
test_that("diagnose_distance_matrix with good quality matrix", {
cost <- matrix(runif(25), 5, 5)
result <- diagnose_distance_matrix(cost, warn = FALSE)
expect_equal(result$quality, "good")
})
# ------------------------------------------------------------------------------
# matching_diagnostics.R additional tests
# ------------------------------------------------------------------------------
test_that("standardized_difference with large difference", {
x1 <- c(1, 2, 3)
x2 <- c(100, 101, 102)
result <- couplr:::standardized_difference(x1, x2, pooled = TRUE)
expect_true(abs(result) > 1)
})
test_that("calculate_var_balance handles KS test failure gracefully", {
# Very small samples where KS test might fail
left_vals <- c(1)
right_vals <- c(2)
result <- couplr:::calculate_var_balance(left_vals, right_vals, "x")
# Should not error
expect_type(result, "list")
expect_equal(result$variable, "x")
})
test_that("balance_diagnostics infers vars from result when stored", {
left <- data.frame(id = 1:5, x = 1:5)
right <- data.frame(id = 6:10, x = c(1.1, 2.1, 3.1, 4.1, 5.1))
result <- match_couples(left, right, vars = "x")
# Check if vars is stored in result
if (!is.null(result$info$vars)) {
# vars = NULL should infer from result
balance <- balance_diagnostics(result, left, right, vars = NULL)
expect_s3_class(balance, "balance_diagnostics")
} else {
# vars not stored, explicit vars required
expect_error(
balance_diagnostics(result, left, right, vars = NULL),
"vars must be specified"
)
}
})
test_that("balance_table with multiple variables", {
left <- data.frame(id = 1:10, x = rnorm(10), y = rnorm(10), z = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10), y = rnorm(10), z = rnorm(10))
result <- match_couples(left, right, vars = c("x", "y", "z"))
balance <- balance_diagnostics(result, left, right, vars = c("x", "y", "z"))
tbl <- balance_table(balance)
expect_equal(nrow(tbl), 3)
})
test_that("summary.balance_diagnostics classifies quality correctly", {
# Create well-matched data
set.seed(123)
left <- data.frame(id = 1:20, x = rnorm(20))
right <- data.frame(id = 21:40, x = rnorm(20))
result <- match_couples(left, right, vars = "x")
balance <- balance_diagnostics(result, left, right, vars = "x")
smry <- summary(balance)
expect_true(smry$quality %in% c("Excellent", "Good", "Acceptable", "Poor"))
})
test_that("plot.balance_diagnostics with custom threshold", {
skip_if_not_installed("graphics")
left <- data.frame(id = 1:10, x = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10))
result <- match_couples(left, right, vars = "x")
balance <- balance_diagnostics(result, left, right, vars = "x")
# Should not error with different thresholds
expect_invisible(plot(balance, type = "love", threshold = 0.05))
expect_invisible(plot(balance, type = "love", threshold = 0.5))
})
# ------------------------------------------------------------------------------
# matching_parallel.R additional tests
# ------------------------------------------------------------------------------
test_that("setup_parallel handles invalid plan string", {
skip_if_not(couplr:::can_parallelize())
skip_on_cran()
expect_warning(
result <- couplr:::setup_parallel(parallel = "invalid_plan_name"),
"Could not set"
)
})
test_that("restore_parallel handles non-setup state", {
state <- list(setup = FALSE, original_plan = NULL)
# Should not error
expect_silent(couplr:::restore_parallel(state))
})
test_that("parallel_lapply handles additional arguments", {
add_val <- function(x, val) x + val
result <- couplr:::parallel_lapply(1:3, add_val, val = 10, parallel = FALSE)
expect_equal(result, list(11, 12, 13))
})
test_that("match_blocks_parallel handles blocks with only left data", {
left <- data.frame(
id = 1:5,
block_id = rep("A", 5),
x = rnorm(5)
)
right <- data.frame(
id = 6:10,
block_id = rep("B", 5),
x = rnorm(5)
)
result <- couplr:::match_blocks_parallel(
blocks = c("A"), # Only request block A
left = left,
right = right,
left_ids = as.character(left$id),
right_ids = as.character(right$id),
block_col = "block_id",
vars = "x",
distance = "euclidean",
weights = NULL,
scale = FALSE,
max_distance = Inf,
calipers = NULL,
method = "auto",
parallel = FALSE
)
# Block A has left but no right data
expect_equal(nrow(result$pairs), 0)
expect_equal(result$block_summary$n_matched, 0)
})
test_that("greedy_blocks_parallel handles blocks with only right data", {
left <- data.frame(
id = 1:5,
block_id = rep("A", 5),
x = rnorm(5)
)
right <- data.frame(
id = 6:10,
block_id = rep("B", 5),
x = rnorm(5)
)
result <- couplr:::greedy_blocks_parallel(
blocks = c("B"), # Only request block B
left = left,
right = right,
left_ids = as.character(left$id),
right_ids = as.character(right$id),
block_col = "block_id",
vars = "x",
distance = "euclidean",
weights = NULL,
scale = FALSE,
max_distance = Inf,
calipers = NULL,
strategy = "sorted",
parallel = FALSE
)
# Block B has right but no left data
expect_equal(nrow(result$pairs), 0)
})
# ------------------------------------------------------------------------------
# matching_blocks.R additional tests
# ------------------------------------------------------------------------------
test_that("matchmaker auto-determines n_blocks", {
set.seed(123)
left <- data.frame(id = 1:50, x = rnorm(50))
right <- data.frame(id = 51:100, x = rnorm(50))
result <- matchmaker(
left, right,
block_type = "cluster",
block_vars = "x",
n_blocks = NULL
)
expect_true(result$info$n_blocks_kept >= 1)
})
test_that("filter_blocks handles imbalance threshold correctly", {
left <- data.frame(
id = 1:15,
block_id = c(rep("A", 10), rep("B", 5))
)
right <- data.frame(
id = 16:25,
block_id = c(rep("A", 5), rep("B", 5)) # A has 5, B has 5
)
# A is imbalanced (10 left vs 5 right = 0.5 ratio)
result <- couplr:::filter_blocks(
left, right,
min_left = 1,
min_right = 1,
drop_imbalanced = TRUE,
imbalance_threshold = 0.3
)
# A should be dropped due to imbalance
expect_true("A" %in% result$dropped$blocks)
expect_equal(result$dropped$reason[result$dropped$blocks == "A"], "imbalanced")
})
test_that("summarize_blocks handles missing block_vars gracefully", {
left <- data.frame(id = 1:4, block_id = c("A", "A", "B", "B"))
right <- data.frame(id = 5:8, block_id = c("A", "A", "B", "B"))
result <- couplr:::summarize_blocks(left, right, block_vars = "nonexistent")
# Should still work, just without mean columns
expect_s3_class(result, "tbl_df")
expect_equal(nrow(result), 2)
})
# ------------------------------------------------------------------------------
# matching_preprocessing.R additional tests
# ------------------------------------------------------------------------------
test_that("check_variable_health summary has all expected columns", {
left <- data.frame(x = 1:10, y = rnorm(10))
right <- data.frame(x = 11:20, y = rnorm(10))
result <- couplr:::check_variable_health(left, right, vars = c("x", "y"))
expected_cols <- c("variable", "n_total", "n_na", "prop_na", "n_valid",
"mean", "sd", "min", "max", "range", "skewness", "issue")
for (col in expected_cols) {
expect_true(col %in% names(result$summary), info = paste("Missing column:", col))
}
})
test_that("check_variable_health with normal data has no issues", {
set.seed(123)
left <- data.frame(x = rnorm(100), y = rnorm(100))
right <- data.frame(x = rnorm(100), y = rnorm(100))
result <- couplr:::check_variable_health(left, right, vars = c("x", "y"))
# Normal data should have no exclusions
expect_equal(length(result$exclude_vars), 0)
})
# ------------------------------------------------------------------------------
# utils.R additional tests
# ------------------------------------------------------------------------------
test_that("validate_cost_data with single element matrix", {
cost <- matrix(5, 1, 1)
result <- couplr:::validate_cost_data(cost)
expect_equal(dim(result), c(1, 1))
expect_equal(result[1, 1], 5)
})
test_that("as_assignment_matrix with empty result and no dimensions", {
result <- tibble::tibble(
source = integer(0),
target = integer(0),
cost = numeric(0)
)
class(result) <- c("lap_solve_result", class(result))
attr(result, "total_cost") <- 0
attr(result, "method_used") <- "test"
mat <- as_assignment_matrix(result)
expect_equal(dim(mat), c(0, 0))
})
test_that("get_total_cost handles batch result with single problem", {
costs <- list(matrix(c(1, 2, 3, 4), 2, 2))
result <- lap_solve_batch(costs)
tc <- get_total_cost(result)
expect_length(tc, 1)
})
test_that("get_method_used handles kbest result", {
cost <- matrix(c(1, 5, 5, 1), 2, 2)
result <- lap_solve_kbest(cost, k = 2)
# kbest doesn't have method_used in get_method_used
expect_error(
get_method_used(result),
"not a valid assignment result"
)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.