tests/testthat/test-level_partitioning.R

# Tests for level_partitioning()

test_that("level_partitioning returns correct structure", {
  adj <- matrix(c(
    0, 1, 0, 0,
    0, 0, 1, 1,
    0, 0, 0, 0,
    0, 0, 0, 0
  ), nrow = 4, byrow = TRUE)

  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  expect_s3_class(levels, "ism_levels")
  expect_true(is.list(levels))
  expect_true(length(levels) > 0)
})

test_that("level_partitioning identifies correct levels for chain", {
  # Chain: 1 -> 2 -> 3 -> 4
  adj <- matrix(c(
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
    0, 0, 0, 0
  ), nrow = 4, byrow = TRUE)

  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  # Should have 4 levels for a chain
  expect_equal(length(levels), 4)

  # Node 4 should be at top (Level 1) - it's the outcome
  expect_true(4 %in% levels[[1]])

  # Node 1 should be at bottom - it's the root cause
  expect_true(1 %in% levels[[length(levels)]])
})

test_that("level_partitioning handles parallel elements", {
  # 1 -> 3, 2 -> 3 (1 and 2 are parallel root causes)
  adj <- matrix(c(
    0, 0, 1,
    0, 0, 1,
    0, 0, 0
  ), nrow = 3, byrow = TRUE)

  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  # Node 3 should be at top (Level 1)
  expect_true(3 %in% levels[[1]])

  # Nodes 1 and 2 should be at same level (bottom)
  bottom_level <- levels[[length(levels)]]
  expect_true(all(c(1, 2) %in% bottom_level))
})

test_that("level_partitioning preserves labels", {
  adj <- matrix(c(0, 1, 0, 0), nrow = 2, byrow = TRUE)
  rownames(adj) <- colnames(adj) <- c("A", "B")

  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  # Check labels attribute
  expect_equal(attr(levels, "labels"), c("A", "B"))
})

test_that("level_partitioning validates input", {
  expect_error(level_partitioning(c(1, 2, 3)), "must be a matrix")
  expect_error(level_partitioning(matrix(1:6, nrow = 2)), "must be square")
  expect_error(level_partitioning(matrix(c(0, 0.5, 0, 0), nrow = 2)),
               "must contain only 0s and 1s")
})

test_that("level_partitioning warns about missing self-reachability", {
  adj <- matrix(c(0, 1, 0, 0), nrow = 2, byrow = TRUE)
  # Create reach matrix without self-reachability
  reach <- compute_reachability(adj, include_self = FALSE)

  expect_warning(level_partitioning(reach), "Diagonal elements should be 1")
})

test_that("level_partitioning handles single element", {
  reach <- matrix(1, nrow = 1, ncol = 1)
  levels <- level_partitioning(reach)

  expect_equal(length(levels), 1)
  expect_equal(levels[[1]], 1)
})

test_that("print.ism_levels works correctly", {
  adj <- matrix(c(0, 1, 0, 0), nrow = 2, byrow = TRUE)
  rownames(adj) <- colnames(adj) <- c("X", "Y")
  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  # Should print without error and include labels
  expect_output(print(levels), "ISM Hierarchical Levels")
  expect_output(print(levels), "X|Y")
})

test_that("summary.ism_levels returns data frame", {
  adj <- matrix(c(0, 1, 0, 0), nrow = 2, byrow = TRUE)
  reach <- compute_reachability(adj)
  levels <- level_partitioning(reach)

  summ <- summary(levels)
  expect_s3_class(summ, "data.frame")
  expect_true("level" %in% names(summ))
  expect_true("index" %in% names(summ))
})

Try the ISMtools package in your browser

Any scripts or data that you put into this service are public.

ISMtools documentation built on March 13, 2026, 1:06 a.m.