# Tests for compute_reachability() test_that("compute_reachability returns correct reachability matrix", { # Simple chain: 1 -> 2 -> 3 adj <- matrix(c( 0, 1, 0, 0, 0, 1, 0, 0, 0 ), nrow = 3, byrow = TRUE) reach <- compute_reachability(adj) # With self-reachability (diagonal = 1) expect_equal(diag(reach), c(1L, 1L, 1L)) # 1 can reach 2 and 3 expect_equal(reach[1, 2], 1L) expect_equal(reach[1, 3], 1L) # 2 can reach 3 expect_equal(reach[2, 3], 1L) # 3 cannot reach others expect_equal(reach[3, 1], 0L) expect_equal(reach[3, 2], 0L) }) test_that("compute_reachability handles include_self parameter", { adj <- matrix(c(0, 1, 0, 0), nrow = 2, byrow = TRUE) # With self-reachability (default) reach_self <- compute_reachability(adj, include_self = TRUE) expect_equal(diag(reach_self), c(1L, 1L)) # Without self-reachability reach_no_self <- compute_reachability(adj, include_self = FALSE) expect_equal(diag(reach_no_self), c(0L, 0L)) }) test_that("compute_reachability handles branching structure", { # 1 -> 2, 1 -> 3, 2 -> 4, 3 -> 4 adj <- matrix(c( 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ), nrow = 4, byrow = TRUE) reach <- compute_reachability(adj) # Node 1 should reach all others expect_equal(reach[1, ], c(1L, 1L, 1L, 1L)) # Nodes 2 and 3 should reach 4 expect_equal(reach[2, 4], 1L) expect_equal(reach[3, 4], 1L) }) test_that("compute_reachability preserves dimnames", { adj <- matrix(c(0, 1, 0, 0, 0, 1, 0, 0, 0), nrow = 3, byrow = TRUE) rownames(adj) <- colnames(adj) <- c("A", "B", "C") reach <- compute_reachability(adj) expect_equal(rownames(reach), c("A", "B", "C")) expect_equal(colnames(reach), c("A", "B", "C")) }) test_that("compute_reachability validates input", { # Non-matrix input expect_error(compute_reachability(c(1, 2, 3)), "must be a matrix") # Non-square matrix expect_error(compute_reachability(matrix(1:6, nrow = 2)), "must be square") # Invalid values expect_error(compute_reachability(matrix(c(0, 2, 0, 0), nrow = 2)), "must contain only 0s and 1s") }) test_that("compute_reachability handles single element", { adj <- matrix(0, nrow = 1, ncol = 1) reach <- compute_reachability(adj) expect_equal(reach[1, 1], 1L) # Self-reachability }) test_that("compute_reachability handles disconnected graph", { # No connections adj <- matrix(0, nrow = 3, ncol = 3) reach <- compute_reachability(adj) # Only diagonal should be 1 expect_equal(diag(reach), c(1L, 1L, 1L)) expect_equal(sum(reach) - 3, 0) # No off-diagonal 1s })