Nothing
# Tests targeting 90%+ coverage - uncovered branches
# ==============================================================================
# matching_core.R - Error handling branches
# ==============================================================================
test_that("match_couples validates NULL right", {
left <- data.frame(id = 1:3, x = rnorm(3))
expect_error(match_couples(left, right = NULL, vars = "x"))
})
test_that("match_couples validates NULL vars", {
left <- data.frame(id = 1:3, x = rnorm(3))
right <- data.frame(id = 4:6, x = rnorm(3))
expect_error(match_couples(left, right, vars = NULL))
})
test_that("greedy_couples validates NULL right", {
left <- data.frame(id = 1:3, x = rnorm(3))
expect_error(greedy_couples(left, right = NULL, vars = "x"))
})
test_that("greedy_couples validates NULL vars", {
left <- data.frame(id = 1:3, x = rnorm(3))
right <- data.frame(id = 4:6, x = rnorm(3))
expect_error(greedy_couples(left, right, vars = NULL))
})
test_that("greedy_couples handles sparse matching", {
left <- data.frame(id = 1:3, x = c(1, 2, 3))
right <- data.frame(id = 4:6, x = c(100, 200, 300))
expect_warning(
greedy_couples(left, right, vars = "x", max_distance = 0.001, auto_scale = FALSE)
)
})
# ==============================================================================
# matching_preprocessing.R - Edge cases
# ==============================================================================
test_that("preprocess_matching_vars handles empty vars", {
left <- data.frame(id = 1:3, x = rnorm(3))
right <- data.frame(id = 4:6, x = rnorm(3))
expect_error(preprocess_matching_vars(left, right, vars = character(0)))
})
test_that("preprocess_matching_vars detects constant variable", {
left <- data.frame(id = 1:5, x = rep(5, 5), y = 1:5)
right <- data.frame(id = 6:10, x = rep(5, 5), y = 6:10)
expect_warning(preprocess_matching_vars(left, right, vars = c("x", "y")))
})
test_that("preprocess_matching_vars with different scale options", {
left <- data.frame(id = 1:10, x = rnorm(10), y = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10), y = rnorm(10))
for (scale in c("robust", "standardize", "range", "none")) {
result <- preprocess_matching_vars(left, right, vars = c("x", "y"), scale = scale)
expect_true(!is.null(result))
}
})
# ==============================================================================
# matching_diagnostics.R - Untested code paths
# ==============================================================================
test_that("balance_diagnostics handles single observation", {
left <- data.frame(id = 1, x = 5)
right <- data.frame(id = 2, x = 5.1)
suppressWarnings(result <- match_couples(left, right, vars = "x"))
diag <- balance_diagnostics(result, left, right, vars = "x")
expect_s3_class(diag, "balance_diagnostics")
})
test_that("balance_diagnostics print works", {
left <- data.frame(id = 1:10, x = rnorm(10), y = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10), y = rnorm(10))
result <- match_couples(left, right, vars = c("x", "y"))
diag <- balance_diagnostics(result, left, right, vars = c("x", "y"))
expect_no_error(print(diag))
})
# ==============================================================================
# lap_solve.R - Validation and special cases
# ==============================================================================
test_that("lap_solve handles 1x1 matrix", {
cost <- matrix(42, nrow = 1, ncol = 1)
result <- lap_solve(cost)
expect_equal(sum(result$cost), 42)
})
test_that("lap_solve auto-selects for binary costs", {
cost <- matrix(c(0, 1, 1, 0), nrow = 2)
result <- lap_solve(cost, method = "auto")
expect_equal(nrow(result), 2)
})
test_that("lap_solve_line_metric validates empty input", {
expect_error(lap_solve_line_metric(numeric(0), numeric(0)))
})
test_that("lap_solve_line_metric validates infinite values", {
expect_error(lap_solve_line_metric(c(1, Inf), c(2, 3)))
})
test_that("bottleneck_assignment handles square matrix", {
cost <- matrix(1:9, nrow = 3, ncol = 3)
result <- bottleneck_assignment(cost)
expect_true("bottleneck" %in% names(result))
expect_equal(result$status, "optimal")
})
test_that("sinkhorn validates lambda", {
cost <- matrix(1:4, nrow = 2)
expect_error(sinkhorn(cost, lambda = -1))
expect_error(sinkhorn(cost, lambda = 0))
})
# ==============================================================================
# morph_pixel.R - Boundary conditions
# ==============================================================================
test_that("pixel_morph warns on invalid upscale", {
skip_if_not_installed("png")
skip_if_not_installed("magick")
img <- magick::image_blank(8, 8, "white")
expect_warning(pixel_morph(img, img, upscale = 0))
expect_warning(pixel_morph(img, img, upscale = -1))
})
test_that("pixel_morph warns on invalid n_frames", {
skip_if_not_installed("png")
skip_if_not_installed("magick")
img <- magick::image_blank(8, 8, "white")
expect_warning(pixel_morph(img, img, n_frames = 0))
expect_warning(pixel_morph(img, img, n_frames = 1))
})
# ==============================================================================
# matching_distance_cache.R - Edge cases
# ==============================================================================
test_that("compute_distances validates ID columns", {
left <- data.frame(x = 1:3)
right <- data.frame(x = 4:6)
expect_error(compute_distances(left, right, vars = "x"))
})
test_that("compute_distances detects duplicate IDs", {
left <- data.frame(id = c(1, 1, 2), x = 1:3)
right <- data.frame(id = 4:6, x = 4:6)
expect_error(compute_distances(left, right, vars = "x"))
})
# ==============================================================================
# matching_blocks.R - Edge cases
# ==============================================================================
test_that("matchmaker handles 'none' block_type", {
left <- data.frame(id = 1:5, group = c("A", "A", "B", "B", "B"))
right <- data.frame(id = 6:10, group = c("A", "B", "B", "A", "B"))
blocks <- matchmaker(left, right, block_type = "none")
expect_true(inherits(blocks, "matchmaker_result") || inherits(blocks, "data.frame"))
})
test_that("matchmaker validates block_type", {
left <- data.frame(id = 1:3, x = 1:3)
right <- data.frame(id = 4:6, x = 4:6)
expect_error(matchmaker(left, right, block_type = "invalid"))
})
# ==============================================================================
# matching_constraints.R - Edge cases
# ==============================================================================
test_that("update_constraints with max_distance = 0", {
left <- data.frame(id = 1:3, x = c(1, 2, 3))
right <- data.frame(id = 4:6, x = c(1, 2, 3))
dist_obj <- compute_distances(left, right, vars = "x")
updated <- update_constraints(dist_obj, max_distance = 0)
expect_true(inherits(updated, "distance_object") || inherits(updated, "couplr_distance"))
})
# ==============================================================================
# Additional edge cases
# ==============================================================================
test_that("assignment handles all-Inf matrix", {
cost <- matrix(Inf, nrow = 3, ncol = 3)
expect_error(assignment(cost))
})
test_that("assignment handles mixed Inf matrix", {
cost <- matrix(c(1, Inf, Inf, Inf, 2, Inf, Inf, Inf, 3), nrow = 3)
result <- assignment(cost)
expect_equal(result$status, "optimal")
expect_equal(result$total_cost, 6)
})
test_that("assignment with maximize = TRUE", {
cost <- matrix(c(1, 2, 3, 4), nrow = 2)
result <- assignment(cost, maximize = TRUE)
expect_equal(result$status, "optimal")
})
test_that("assignment with different methods", {
cost <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3)
for (method in c("hungarian", "jv", "auction")) {
result <- assignment(cost, method = method)
expect_equal(result$status, "optimal")
}
})
test_that("assignment_duals returns dual variables", {
cost <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3)
result <- assignment_duals(cost)
expect_true("u" %in% names(result))
expect_true("v" %in% names(result))
})
# ==============================================================================
# Augment and join coverage
# ==============================================================================
test_that("augment.matching_result works", {
left <- data.frame(id = 1:5, x = rnorm(5))
right <- data.frame(id = 6:10, x = rnorm(5))
result <- match_couples(left, right, vars = "x")
augmented <- augment(result, left, right)
expect_true(nrow(augmented) > 0)
})
test_that("join_matched works", {
left <- data.frame(id = 1:5, x = rnorm(5))
right <- data.frame(id = 6:10, x = rnorm(5))
result <- match_couples(left, right, vars = "x")
joined <- join_matched(result, left, right)
expect_true(nrow(joined) > 0 || nrow(result$pairs) == 0)
})
# ==============================================================================
# Edge cases in core matching
# ==============================================================================
test_that("match_couples with caliper", {
left <- data.frame(id = 1:10, x = 1:10, y = rnorm(10))
right <- data.frame(id = 11:20, x = 1:10 + 0.5, y = rnorm(10))
result <- match_couples(left, right, vars = c("x", "y"), caliper = c(x = 1))
expect_s3_class(result, "matching_result")
})
test_that("match_couples with weight parameter", {
left <- data.frame(id = 1:10, x = rnorm(10), y = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10), y = rnorm(10))
result <- match_couples(left, right, vars = c("x", "y"), weights = c(x = 2, y = 1))
expect_s3_class(result, "matching_result")
})
test_that("match_couples with blocking", {
left <- data.frame(id = 1:20, block = rep(1:4, 5), x = rnorm(20))
right <- data.frame(id = 21:40, block = rep(1:4, 5), x = rnorm(20))
result <- match_couples(left, right, vars = "x", block_id = "block")
expect_s3_class(result, "matching_result")
})
test_that("match_couples return_diagnostics", {
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", return_diagnostics = TRUE)
# return_diagnostics keeps additional fields in info like solver
expect_true("solver" %in% names(result$info) || length(result$info) > 3)
})
# ==============================================================================
# Greedy strategies
# ==============================================================================
test_that("greedy_couples with different strategies", {
left <- data.frame(id = 1:10, x = rnorm(10))
right <- data.frame(id = 11:20, x = rnorm(10))
for (strategy in c("sorted", "row_best", "pq")) {
result <- greedy_couples(left, right, vars = "x", strategy = strategy)
expect_s3_class(result, "matching_result")
}
})
# ==============================================================================
# K-best and batch
# ==============================================================================
test_that("lap_solve_kbest works", {
cost <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3)
result <- lap_solve_kbest(cost, k = 2)
expect_true(nrow(result) >= 1)
})
test_that("lap_solve_batch works", {
costs <- list(
matrix(1:4, nrow = 2),
matrix(1:9, nrow = 3)
)
result <- lap_solve_batch(costs)
# Returns a tibble with columns: problem_id, source, target, cost, total_cost, method_used
expect_true(inherits(result, "data.frame"))
expect_true("problem_id" %in% names(result))
# 2 problems: 2x2 (2 matches) + 3x3 (3 matches) = 5 rows
expect_true(nrow(result) >= 5)
})
# ==============================================================================
# Print methods
# ==============================================================================
test_that("print.matching_result works", {
left <- data.frame(id = 1:5, x = rnorm(5))
right <- data.frame(id = 6:10, x = rnorm(5))
result <- match_couples(left, right, vars = "x")
expect_no_error(print(result))
})
test_that("summary.matching_result works", {
left <- data.frame(id = 1:5, x = rnorm(5))
right <- data.frame(id = 6:10, x = rnorm(5))
result <- match_couples(left, right, vars = "x")
expect_no_error(summary(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.