tests/testthat/test-substituent.R

# Tests for substituent functions

test_that("available_substituents returns expected values", {
  subs <- available_substituents()
  expect_type(subs, "character")
  expect_true(length(subs) > 0)
  expect_true("Me" %in% subs)
  expect_true("Ac" %in% subs)
  expect_true("NGc" %in% subs)
  expect_true("Gc" %in% subs)
  expect_true("S" %in% subs)
})

test_that("normalize_substituents handles empty strings", {
  expect_equal(normalize_substituents(""), "")
})

test_that("normalize_substituents handles single substituents", {
  expect_equal(normalize_substituents("6S"), "6S")
  expect_equal(normalize_substituents("4/6S"), "4/6S")
  expect_equal(normalize_substituents("6/4S"), "4/6S")
  expect_equal(normalize_substituents("4/4S"), "4S")
  expect_equal(normalize_substituents("3Me"), "3Me")
  expect_equal(normalize_substituents("?Ac"), "?Ac")
})

test_that("normalize_substituents sorts multiple substituents by position", {
  expect_equal(normalize_substituents("4Ac,3Me"), "3Me,4Ac")
  expect_equal(normalize_substituents("6P,2S,4Ac"), "2S,4Ac,6P")
  expect_equal(normalize_substituents("9Ac,1Me,5S"), "1Me,5S,9Ac")
})

test_that("normalize_substituents handles ? positions correctly", {
  expect_equal(normalize_substituents("?S,3Me"), "3Me,?S")
  expect_equal(normalize_substituents("?Ac,?Me"), "?Ac,?Me") # Original order preserved for same position
  expect_equal(normalize_substituents("4Ac,?S,2Me"), "2Me,4Ac,?S")
})

test_that("normalize_substituents removes empty components", {
  expect_equal(normalize_substituents("3Me,,4Ac"), "3Me,4Ac")
  expect_equal(normalize_substituents(",6S,"), "6S")
})

test_that("normalize_substituents input validation", {
  expect_error(normalize_substituents(c("3Me", "4Ac")))
  expect_error(normalize_substituents(123))
})

test_that("substituent position helpers parse and sort positions consistently", {
  subs <- c("6S", "?Ac", "4/6Me", "3/4/6S")

  expect_equal(substituent_position_tokens(subs), c("6", "?", "4/6", "3/4/6"))
  expect_equal(substituent_position_values(subs), c(6, Inf, 4, 3))
  expect_equal(
    sort_substituent_tokens(subs),
    c("3/4/6S", "4/6Me", "6S", "?Ac")
  )
  expect_equal(
    collapse_substituent_tokens(subs),
    "3/4/6S,4/6Me,6S,?Ac"
  )
})

test_that("ambiguous substituent position validation rejects malformed syntax", {
  expect_identical(
    valid_substituent(c("4/6S", "3/4/6Ac", "/6S", "4/S", "4//6S")),
    c(TRUE, TRUE, FALSE, FALSE, FALSE)
  )
})

test_that("substituent positions require a conflict-free assignment", {
  expect_identical(
    valid_substituent(c(
      "4Ac,4/6S",
      "4/6Ac,4/6S",
      "4Ac,4/6S,6Me",
      "4/6Ac,4/6S,4/6Me"
    )),
    c(TRUE, TRUE, FALSE, FALSE)
  )
})

test_that("remove_substituents works on glycan structures", {
  # Create a test glycan with substituents
  graph <- igraph::make_graph(~ 1 - +2)
  igraph::V(graph)$mono <- c("Glc", "Gal")
  igraph::V(graph)$sub <- c("3Me,4Ac", "6S")
  igraph::E(graph)$linkage <- "b1-4"
  graph$anomer <- "a1"
  graph$alditol <- FALSE

  glycan <- glycan_structure(graph)

  # Remove substituents
  clean_glycan <- remove_substituents(glycan)

  # Check that substituents are removed
  clean_graph <- get_structure_graphs(clean_glycan, return_list = FALSE)
  expect_equal(igraph::V(clean_graph)$sub, c("", ""))
  expect_equal(igraph::V(clean_graph)$mono, c("Gal", "Glc")) # Monos should be unchanged
})

test_that("remove_substituents works on glycan graphs without reordering", {
  structure <- as_glycan_structure("Gal3Me6S(b1-3)GalNAc(a1-")
  graph <- get_structure_graphs(structure)
  names_before <- igraph::V(graph)$name
  edges_before <- igraph::as_edgelist(graph, names = FALSE)
  monos_before <- igraph::V(graph)$mono

  result <- remove_substituents(graph)

  expect_s3_class(result, "igraph")
  expect_identical(igraph::V(result)$name, names_before)
  expect_identical(igraph::as_edgelist(result, names = FALSE), edges_before)
  expect_identical(igraph::V(result)$mono, monos_before)
  expect_identical(igraph::V(result)$sub, c("", ""))
})

test_that("remove_substituents input validation", {
  expect_error(remove_substituents("not_a_glycan"))
  expect_error(remove_substituents(123))
})

Try the glyrepr package in your browser

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

glyrepr documentation built on Sept. 22, 2026, 5:09 p.m.