Nothing
# Additional tests to push coverage to 90%+
# Targets: morph_pixel.R, morph_utils.R, matching_core.R, network_simplex, cycle_cancel
# ---------- morph_utils.R coverage ----------
test_that(".gif_delay_from_fps handles edge cases", {
skip_on_cran()
# Test various fps values
expect_equal(couplr:::.gif_delay_from_fps(1), 100L)
expect_equal(couplr:::.gif_delay_from_fps(5), 20L)
expect_equal(couplr:::.gif_delay_from_fps(25), 4L)
expect_equal(couplr:::.gif_delay_from_fps(100), 1L)
# Edge cases
expect_equal(couplr:::.gif_delay_from_fps(0), 10L) # Invalid -> default
expect_equal(couplr:::.gif_delay_from_fps(Inf), 10L) # Invalid -> default
})
test_that(".clamp_rgb handles various inputs", {
skip_on_cran()
# Scalar
expect_equal(couplr:::.clamp_rgb(50), 50L)
expect_equal(couplr:::.clamp_rgb(300), 255L)
expect_equal(couplr:::.clamp_rgb(-100), 0L)
# Vector
vec <- c(-50, 0, 127, 255, 1000)
result <- couplr:::.clamp_rgb(vec)
expect_equal(result, c(0L, 0L, 127L, 255L, 255L))
# Matrix
mat <- matrix(c(-10, 150, 300, 100), nrow = 2)
result <- couplr:::.clamp_rgb(mat)
expect_equal(dim(result), c(2, 2))
})
test_that(".to_planar_rgb and .from_planar_rgb work correctly", {
skip_on_cran()
skip_if_not_installed("magick")
# Create simple test array
set.seed(42)
arr <- array(sample(0:255, 75, replace = TRUE), dim = c(5, 5, 3))
storage.mode(arr) <- "integer"
# Convert to planar
planar <- couplr:::.to_planar_rgb(arr)
expect_equal(length(planar), 75)
# Convert back
arr2 <- couplr:::.from_planar_rgb(planar, 5, 5)
expect_equal(dim(arr2), c(5, 5, 3))
# Values should match
expect_equal(as.numeric(arr), as.numeric(arr2))
})
test_that(".has_namespace works", {
skip_on_cran()
expect_true(couplr:::.has_namespace("base"))
expect_true(couplr:::.has_namespace("couplr"))
expect_false(couplr:::.has_namespace("nonexistent_package_xyz"))
})
# ---------- matching_core.R coverage ----------
test_that("match_couples handles edge cases", {
skip_on_cran()
# Very small dataset
left <- data.frame(id = 1:2, x = c(0, 1))
right <- data.frame(id = 1:2, x = c(0.1, 1.1))
result <- match_couples(left, right, vars = "x")
expect_equal(nrow(result$pairs), 2)
# Single variable
set.seed(42)
left <- data.frame(id = 1:10, x = rnorm(10))
right <- data.frame(id = 1:10, x = rnorm(10))
result <- match_couples(left, right, vars = "x")
expect_equal(nrow(result$pairs), 10)
})
test_that("match_couples with different methods", {
skip_on_cran()
set.seed(42)
n <- 8
left <- data.frame(id = 1:n, x = rnorm(n))
right <- data.frame(id = 1:n, x = rnorm(n))
# Test multiple methods
for (method in c("jv", "hungarian", "auction")) {
result <- tryCatch(
match_couples(left, right, vars = "x", method = method),
error = function(e) NULL
)
if (!is.null(result)) {
expect_true(nrow(result$pairs) > 0)
}
}
})
test_that("match_couples with weights", {
skip_on_cran()
set.seed(42)
n <- 10
left <- data.frame(id = 1:n, x = rnorm(n), y = rnorm(n))
right <- data.frame(id = 1:n, x = rnorm(n), y = rnorm(n))
# Weights as vector
result <- match_couples(left, right, vars = c("x", "y"), weights = c(1, 2))
expect_true(nrow(result$pairs) > 0)
# Weights as named vector
result <- match_couples(left, right, vars = c("x", "y"), weights = c(x = 0.5, y = 0.5))
expect_true(nrow(result$pairs) > 0)
})
test_that("match_couples handles NA in data", {
skip_on_cran()
set.seed(42)
left <- data.frame(id = 1:5, x = c(1, NA, 3, 4, 5))
right <- data.frame(id = 1:5, x = c(1.1, 2.1, 3.1, NA, 5.1))
# Should handle or warn about NA values
result <- tryCatch(
match_couples(left, right, vars = "x"),
warning = function(w) { conditionMessage(w) },
error = function(e) list(error = TRUE)
)
expect_true(!is.null(result))
})
test_that("greedy_couples with different strategies", {
skip_on_cran()
set.seed(42)
n <- 10
left <- data.frame(id = 1:n, x = rnorm(n))
right <- data.frame(id = 1:n, x = rnorm(n))
# Test all strategies
for (strategy in c("sorted", "row_best", "pq")) {
result <- greedy_couples(left, right, vars = "x", strategy = strategy)
expect_true(nrow(result$pairs) > 0)
}
})
# ---------- network_simplex coverage ----------
test_that("network_simplex handles various sizes", {
skip_on_cran()
for (n in c(2, 3, 4, 6)) {
set.seed(n * 10)
cost <- matrix(sample(1:50, n * n, replace = TRUE), nrow = n, ncol = n)
result <- assignment(cost, method = "network_simplex")
expect_equal(length(result$match), n)
expect_true(all(sort(result$match) == 1:n))
}
})
test_that("network_simplex with Inf costs", {
skip_on_cran()
# Some forbidden edges
cost <- matrix(c(1, Inf, 2, Inf, Inf, 3, Inf, 4, 5), nrow = 3, ncol = 3)
result <- tryCatch(
assignment(cost, method = "network_simplex"),
error = function(e) list(error = TRUE)
)
# Should either succeed or fail gracefully
expect_true(!is.null(result))
})
# ---------- cycle_cancel coverage ----------
test_that("cycle_cancel with varying matrix sizes", {
skip_on_cran()
for (n in c(2, 3, 4, 6)) {
set.seed(n * 20)
cost <- matrix(runif(n * n) * 100, nrow = n, ncol = n)
result <- assignment(cost, method = "cycle_cancel")
expect_equal(length(result$match), n)
expect_true(result$total_cost > 0)
}
})
test_that("cycle_cancel with zero costs", {
skip_on_cran()
cost <- matrix(0, nrow = 3, ncol = 3)
result <- assignment(cost, method = "cycle_cancel")
expect_equal(result$total_cost, 0)
})
# ---------- Additional solver coverage ----------
test_that("gabow_tarjan with larger matrices", {
skip_on_cran()
for (n in c(4, 5, 6)) {
set.seed(n * 30)
cost <- matrix(sample(1:100, n * n, replace = TRUE), nrow = n, ncol = n)
result <- assignment(cost, method = "gabow_tarjan")
expect_equal(length(result$match), n)
}
})
test_that("hungarian with negative costs", {
skip_on_cran()
cost <- matrix(c(-5, -1, -2, -10), nrow = 2, ncol = 2)
result <- assignment(cost, method = "hungarian")
expect_true(result$total_cost < 0)
})
test_that("auction with various epsilon values", {
skip_on_cran()
cost <- matrix(c(1, 5, 3, 2), nrow = 2, ncol = 2)
# Default epsilon
result1 <- assignment(cost, method = "auction")
expect_equal(result1$total_cost, 3)
# Test auction_gs variant
result2 <- assignment(cost, method = "auction_gs")
expect_equal(result2$total_cost, 3)
})
# ---------- morph_pixel.R edge cases ----------
test_that("pixel_morph_animate validates parameters", {
skip_on_cran()
skip_if_not_installed("magick")
# Create tiny test images
imgA <- system.file("extdata/icons/circleA_40.png", package = "couplr")
imgB <- system.file("extdata/icons/circleB_40.png", package = "couplr")
skip_if(!nzchar(imgA), "Test images not found")
skip_if(!nzchar(imgB), "Test images not found")
# Test with invalid upscale
expect_error(
pixel_morph_animate(imgA, imgB, upscale = "invalid", show = FALSE, n_frames = 2)
)
# Test with invalid n_frames
expect_error(
pixel_morph_animate(imgA, imgB, n_frames = "invalid", show = FALSE)
)
# Test with invalid alpha
expect_error(
pixel_morph_animate(imgA, imgB, alpha = -1, show = FALSE, n_frames = 2)
)
# Test with alpha = 0 and beta = 0
expect_error(
pixel_morph_animate(imgA, imgB, alpha = 0, beta = 0, show = FALSE, n_frames = 2)
)
})
# ---------- Additional matching coverage ----------
test_that("match_couples with return_diagnostics", {
skip_on_cran()
set.seed(42)
n <- 10
left <- data.frame(id = 1:n, x = rnorm(n))
right <- data.frame(id = 1:n, x = rnorm(n))
result <- match_couples(left, right, vars = "x", return_diagnostics = TRUE)
# Check that result has diagnostic information
expect_true("info" %in% names(result) || "pairs" %in% names(result))
})
test_that("match_couples auto_scale feature", {
skip_on_cran()
set.seed(42)
n <- 15
# Different scales for x and y
left <- data.frame(id = 1:n, x = rnorm(n, 0, 100), y = rnorm(n, 0, 0.01))
right <- data.frame(id = 1:n, x = rnorm(n, 0, 100), y = rnorm(n, 0, 0.01))
result <- match_couples(left, right, vars = c("x", "y"), auto_scale = TRUE)
expect_true(nrow(result$pairs) > 0)
})
test_that("balance_diagnostics with various inputs", {
skip_on_cran()
set.seed(42)
n <- 15
left <- data.frame(id = 1:n, x = rnorm(n), y = rnorm(n), z = rnorm(n))
right <- data.frame(id = 1:n, x = rnorm(n), y = rnorm(n), z = rnorm(n))
result <- match_couples(left, right, vars = c("x", "y", "z"))
balance <- balance_diagnostics(result, left, right, c("x", "y", "z"))
expect_true("var_stats" %in% names(balance))
expect_equal(nrow(balance$var_stats), 3)
})
test_that("join_matched with suffix options", {
skip_on_cran()
set.seed(42)
n <- 10
left <- data.frame(id = 1:n, x = rnorm(n), value = letters[1:n])
right <- data.frame(id = 1:n, x = rnorm(n), value = LETTERS[1:n])
result <- match_couples(left, right, vars = "x")
joined <- join_matched(result, left, right, suffix = c("_L", "_R"))
# Should have suffixed columns for overlapping names
expect_true(ncol(joined) > 2)
})
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.