tests/testthat/test-ecomatrix.r

test_that("ecomatrix.c parsing logic is covered", {

  # Ensure Matrix and slam packages are available for testing
  skip_if_not_installed('Matrix')
  skip_if_not_installed('slam')
  
  if (packageVersion("Matrix") >= "1.5") {
    COMPRESSED <- "sparseMatrix"
    TRIPLET    <- "TsparseMatrix"
    UNPACKED   <- "unpackedMatrix"
  } else {
    COMPRESSED <- "dgCMatrix"
    TRIPLET    <- "dgTMatrix"
    UNPACKED   <- "dgeMatrix"
  }

  # Define a test function that calls an internal C function
  # We will test an alpha diversity metric which uses the ecomatrix parsing
  test_parsing <- function(m, margin = 1L) {
    observed(m, margin = margin)
  }

  # Expected result: number of non-zero entries per sample
  expected_margin1 <- c(A = 3, B = 3, C = 3, D = 2)
  expected_margin2 <- c(OTU1 = 2, OTU2 = 4, OTU3 = 4, OTU4 = 3, OTU5 = 2)

  # === Test with base R matrix ===
  m_base <- counts
  expect_equal(test_parsing(m_base, margin = 1L), expected_margin1)
  expect_equal(test_parsing(t(m_base), margin = 2L), expected_margin1)

  # Test with logical matrix
  m_logical <- m_base > 0
  expect_equal(test_parsing(m_logical, margin = 1L), expected_margin1)
  expect_equal(test_parsing(t(m_logical), margin = 2L), expected_margin1)

  # Test with double matrix
  m_double <- m_base * 1.1
  expect_equal(test_parsing(m_double, margin = 1L), expected_margin1)
  expect_equal(test_parsing(t(m_double), margin = 2L), expected_margin1)


  # === Test with Matrix package types ===
  m_base_t <- t(m_base)
  m_dgC    <- as(m_base,   COMPRESSED)
  m_dgC_t  <- as(m_base_t, COMPRESSED)
  m_dgT    <- as(m_base,   TRIPLET)
  m_dgT_t  <- as(m_base_t, TRIPLET)
  m_dge    <- as(m_base,   UNPACKED)
  m_dge_t  <- as(m_base_t, UNPACKED)

  # dgCMatrix
  expect_equal(test_parsing(m_dgC, margin = 1L), expected_margin1, info = "dgCMatrix margin 1")
  expect_equal(test_parsing(m_dgC_t, margin = 2L), expected_margin1, info = "dgCMatrix margin 2")

  # dgTMatrix
  expect_equal(test_parsing(m_dgT, margin = 1L), expected_margin1, info = "dgTMatrix margin 1")
  expect_equal(test_parsing(m_dgT_t, margin = 2L), expected_margin1, info = "dgTMatrix margin 2")

  # dgeMatrix
  expect_equal(test_parsing(m_dge, margin = 1L), expected_margin1, info = "dgeMatrix margin 1")
  expect_equal(test_parsing(m_dge_t, margin = 2L), expected_margin1, info = "dgeMatrix margin 2")

  # Test with logical Matrix types
  m_logical_t <- t(m_logical)
  m_lgC       <- as(m_logical,   COMPRESSED)
  m_lgC_t     <- as(m_logical_t, COMPRESSED)
  m_lgT       <- as(m_logical,   TRIPLET)
  m_lge       <- as(m_logical,   UNPACKED)
  expect_equal(test_parsing(m_lgC, margin = 1L), expected_margin1, info = "lgCMatrix margin 1")
  expect_equal(test_parsing(m_lgC_t, margin = 2L), expected_margin1, info = "lgCMatrix margin 2")
  expect_equal(test_parsing(m_lgT, margin = 1L), expected_margin1, info = "lgTMatrix margin 1")
  expect_equal(test_parsing(m_lge, margin = 1L), expected_margin1, info = "lgeMatrix margin 1")


  # === Test with slam::simple_triplet_matrix ===
  m_slam   <- slam::as.simple_triplet_matrix(m_base)
  m_slam_t <- slam::as.simple_triplet_matrix(m_base_t)
  expect_equal(test_parsing(m_slam, margin = 1L), expected_margin1, info = "slam margin 1")
  expect_equal(test_parsing(m_slam_t, margin = 2L), expected_margin1, info = "slam margin 2")

  # Test with logical slam
  m_slam_logical <- slam::as.simple_triplet_matrix(m_logical)
  expect_equal(test_parsing(m_slam_logical, margin = 1L), expected_margin1, info = "slam logical margin 1")

  # Test with double slam
  m_slam_double <- slam::as.simple_triplet_matrix(m_double)
  expect_equal(test_parsing(m_slam_double, margin = 1L), expected_margin1, info = "slam double margin 1")


  # === Test sorting logic for sparse matrices ===
  # Create an unsorted dgTMatrix
  unsorted_m_dgT <- m_dgT
  set.seed(1)
  idx <- sample(length(unsorted_m_dgT@i))
  unsorted_m_dgT@i <- unsorted_m_dgT@i[idx]
  unsorted_m_dgT@j <- unsorted_m_dgT@j[idx]
  unsorted_m_dgT@x <- unsorted_m_dgT@x[idx]
  expect_equal(test_parsing(unsorted_m_dgT, margin = 1L), expected_margin1, info = "unsorted dgTMatrix")

  # Create an unsorted simple_triplet_matrix
  unsorted_m_slam <- m_slam
  unsorted_m_slam$i <- unsorted_m_slam$i[idx]
  unsorted_m_slam$j <- unsorted_m_slam$j[idx]
  unsorted_m_slam$v <- unsorted_m_slam$v[idx]
  expect_equal(test_parsing(unsorted_m_slam, margin = 1L), expected_margin1, info = "unsorted slam")

  # Test already sorted triplet
  sorted_m_dgT   <- as(m_dgC, TRIPLET) # dgC is sorted by column, then row
  sorted_m_dgT_t <- as(m_dgC_t, TRIPLET)
  expect_equal(test_parsing(sorted_m_dgT_t, margin = 2L), expected_margin1, info = "sorted dgTMatrix")


  # === Test error handling ===
  expect_error(test_parsing("not a matrix"))
  expect_error(test_parsing(m_base, margin = 3L))

  # Test non-numeric input
  char_matrix <- matrix(as.character(counts), nrow = 4)
  rownames(char_matrix) <- rownames(counts)
  expect_error(test_parsing(char_matrix))

  # === Test dimnames ===
  m_no_dimnames <- counts
  dimnames(m_no_dimnames) <- NULL
  res_no_dimnames <- test_parsing(m_no_dimnames)
  expect_null(names(res_no_dimnames))
  expect_equal(unname(res_no_dimnames), unname(expected_margin1))

  m_slam_no_dimnames <- slam::as.simple_triplet_matrix(m_no_dimnames)
  res_slam_no_dimnames <- test_parsing(m_slam_no_dimnames)
  expect_null(names(res_slam_no_dimnames))
  expect_equal(unname(res_slam_no_dimnames), unname(expected_margin1))

})

Try the ecodive package in your browser

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

ecodive documentation built on Jan. 16, 2026, 5:11 p.m.