Nothing
test_that("known monosaccharides retain their identity without substituents", {
monos <- available_monosaccharides()
glycans <- as_glycan_structure(paste0(monos, "(?1-"))
graphs <- as.list(glycans)
expect_identical(
purrr::map_chr(graphs, \(graph) igraph::vertex_attr(graph, "mono")),
monos
)
expect_identical(
purrr::map_chr(graphs, \(graph) igraph::vertex_attr(graph, "sub")),
rep("", length(monos))
)
})
test_that("as_glycan_structure.character parses simple IUPAC-condensed strings", {
# Single monosaccharide
glycan1 <- as_glycan_structure("Man(?1-")
expect_s3_class(glycan1, "glyrepr_structure")
expect_equal(length(glycan1), 1)
expect_equal(structure_to_iupac(glycan1), "Man(?1-")
# Two monosaccharides
glycan2 <- as_glycan_structure("Gal(b1-3)GalNAc(?1-")
expect_s3_class(glycan2, "glyrepr_structure")
expect_equal(length(glycan2), 1)
expect_equal(structure_to_iupac(glycan2), "Gal(b1-3)GalNAc(?1-")
# With explicit anomer
glycan3 <- as_glycan_structure("Gal(b1-3)GalNAc(a1-")
expect_s3_class(glycan3, "glyrepr_structure")
expect_equal(structure_to_iupac(glycan3), "Gal(b1-3)GalNAc(a1-")
})
test_that("as_glycan_structure.character infers reducing-end anomer positions", {
iupacs <- c("Man", "Neu5Ac", "Gal(b1-3)GalNAc")
glycans <- as_glycan_structure(iupacs)
expect_equal(
structure_to_iupac(glycans),
c("Man(?1-", "Neu5Ac(?2-", "Gal(b1-3)GalNAc(?1-")
)
})
test_that("ordinary IUPAC parsing bypasses floating-part splitting", {
testthat::local_mocked_bindings(
split_floating_iupac = function(...) {
stop("floating parser should not run")
}
)
glycan <- as_glycan_structure("Gal(b1-3)GalNAc(a1-")
expect_identical(
unname(structure_to_iupac(glycan)),
"Gal(b1-3)GalNAc(a1-"
)
})
test_that("as_glycan_structure.character parses branched structures", {
# Simple branched structure
iupac <- "Man(a1-3)[Man(a1-6)]Man(b1-4)GlcNAc(b1-4)GlcNAc(?1-"
glycan <- as_glycan_structure(iupac)
expect_s3_class(glycan, "glyrepr_structure")
expect_equal(
structure_to_iupac(glycan),
"Man(a1-3)[Man(a1-6)]Man(b1-4)GlcNAc(b1-4)GlcNAc(?1-"
)
})
test_that("as_glycan_structure.character parses floating parts", {
iupacs <- c(
"{Neu5Ac(a2-3)}Gal(b1-3)GalNAc(a1-",
"{Neu5Ac(a2-6)|2,3}Gal(b1-3)GalNAc(a1-",
"{Neu5Ac(a2-3)|2,5}Man(a1-3)[Man(a1-6)]Man(b1-4)GlcNAc(b1-4)GlcNAc(b1-",
"{Neu5Ac(a2-3)Gal(b1-4)|3,4}Glc(b1-3)GalNAc(a1-"
)
glycans <- as_glycan_structure(iupacs)
graphs <- as.list(glycans)
expect_identical(unname(structure_to_iupac(glycans)), iupacs)
expect_equal(
purrr::map(graphs, ~ .x$floating_parts[[1]]$parents),
list(integer(), c(2L, 3L), c(2L, 5L), c(3L, 4L))
)
expect_equal(
purrr::map_int(graphs, ~ .x$floating_parts[[1]]$root),
c(1L, 1L, 1L, 2L)
)
expect_equal(
purrr::map(graphs, ~ .x$floating_parts[[1]]$nodes),
list(1L, 1L, 1L, c(1L, 2L))
)
expect_equal(
igraph::V(graphs[[4]])$mono,
c("Neu5Ac", "Gal", "Glc", "GalNAc")
)
})
test_that("floating parent indices follow canonicalized main-tree order", {
glycan <- as_glycan_structure(
paste0(
"{Neu5Ac(a2-4)|2,4}",
"Man(a1-6)[Man(a1-3)]Man(b1-4)GlcNAc(b1-4)GlcNAc(b1-"
)
)
expect_identical(
unname(structure_to_iupac(glycan)),
paste0(
"{Neu5Ac(a2-4)|3,4}",
"Man(a1-3)[Man(a1-6)]Man(b1-4)GlcNAc(b1-4)GlcNAc(b1-"
)
)
})
test_that("as_glycan_structure.character handles substituents", {
# With substituents
iupac <- "Man3S(a1-2)Gal6Ac(?1-"
glycan <- as_glycan_structure(iupac)
expect_s3_class(glycan, "glyrepr_structure")
# Check that substituents are preserved
graph <- get_structure_graphs(glycan, return_list = FALSE)
expect_equal(igraph::V(graph)$sub, c("3S", "6Ac"))
})
test_that("as_glycan_structure.character handles Neu5Ac correctly", {
# Neu5Ac with explicit anomer
glycan1 <- as_glycan_structure("Neu5Ac(?2-")
expect_equal(structure_to_iupac(glycan1), "Neu5Ac(?2-")
# Neu5Ac with explicit anomer
glycan2 <- as_glycan_structure("Neu5Ac(a2-")
expect_equal(structure_to_iupac(glycan2), "Neu5Ac(a2-")
# Neu5Ac with substituent
glycan3 <- as_glycan_structure("Neu5Ac9Ac(?2-")
graph <- get_structure_graphs(glycan3, return_list = FALSE)
expect_equal(igraph::V(graph)$mono, "Neu5Ac")
expect_equal(igraph::V(graph)$sub, "9Ac")
})
test_that("as_glycan_structure.character parses digit-leading monosaccharides", {
monos <- available_monosaccharides("concrete")
monos <- monos[stringr::str_detect(monos, "^[0-9]")]
iupacs <- paste0(monos, "(?", infer_anomer_pos(monos), "-")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_equal(purrr::map_chr(graphs, ~ igraph::V(.x)$mono), monos)
expect_equal(
purrr::map_chr(graphs, ~ igraph::V(.x)$sub),
rep("", length(monos))
)
expect_equal(structure_to_iupac(glycans), iupacs)
expect_equal(
structure_to_iupac(as_glycan_structure("6dGul(b1-")),
"6dGul(b1-"
)
})
test_that("as_glycan_structure.character parses every furanose form", {
monos <- unname(furanose_monosaccharides)
iupacs <- paste0(monos, "(?", infer_anomer_pos(monos), "-")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$mono),
monos
)
expect_identical(unname(structure_to_iupac(glycans)), iupacs)
})
test_that("as_glycan_structure.character parses every unusual configuration", {
monos <- unname(unusual_configuration_monosaccharides)
iupacs <- paste0(monos, "(?", infer_anomer_pos(monos), "-")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$mono),
monos
)
expect_identical(unname(structure_to_iupac(glycans)), iupacs)
})
test_that("unusual configurations support branches and omitted anomers", {
iupac <- "D-Fuc(a1-2)[L-Gul(b1-3)]Gal(?1-"
expect_identical(
unname(structure_to_iupac(as_glycan_structure(iupac))),
iupac
)
expect_identical(
unname(structure_to_iupac(as_glycan_structure("L-6dGul"))),
"L-6dGul(?1-"
)
})
test_that("unusual configurations retain substituents", {
iupacs <- c(
"D-Fuc3S(a1-",
"L-Neu5Ac9Ac(a2-",
"L-Neuf5Gc9Ac(a2-",
"L-Neu4Ac5Ac(a2-",
"L-Neuf4Ac5Gc(a2-"
)
expected_iupacs <- c(
iupacs[1:3],
"L-Neu5Ac4Ac(a2-",
"L-Neuf5Gc4Ac(a2-"
)
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$mono),
c("D-Fuc", "L-Neu5Ac", "L-Neuf5Gc", "L-Neu5Ac", "L-Neuf5Gc")
)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$sub),
c("3S", "9Ac", "9Ac", "4Ac", "4Ac")
)
expect_identical(unname(structure_to_iupac(glycans)), expected_iupacs)
})
test_that("redundant natural configuration prefixes are rejected", {
errors <- purrr::map(
c("L-Fuc(a1-", "D-Gul(b1-", "D-Neu5Ac(a2-"),
~ tryCatch(as_glycan_structure(.x), error = identity)
)
expect_identical(purrr::map_lgl(errors, inherits, "error"), rep(TRUE, 3))
expect_match(
purrr::map_chr(errors, conditionMessage),
"Unknown monosaccharide"
)
})
test_that("furanose forms retain additional substituents", {
iupacs <- c(
"Galf3Me(b1-",
"GlcfNAc6Ac(b1-",
"Neuf5Ac9Ac(a2-",
"Neuf4Ac5Gc(a2-"
)
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$mono),
c("Galf", "GlcfNAc", "Neuf5Ac", "Neuf5Gc")
)
expect_identical(
purrr::map_chr(graphs, ~ igraph::V(.x)$sub),
c("3Me", "6Ac", "9Ac", "4Ac")
)
expect_identical(
unname(structure_to_iupac(glycans)),
c(iupacs[1:3], "Neuf5Gc4Ac(a2-")
)
})
test_that("as_glycan_structure.character handles unknown linkages", {
# Unknown linkages
iupac <- "Man(a1-?)Man(?1-3)Man(?1-"
glycan <- as_glycan_structure(iupac)
expect_s3_class(glycan, "glyrepr_structure")
expect_equal(structure_to_iupac(glycan), "Man(a1-?)Man(?1-3)Man(?1-")
shorthand <- as_glycan_structure("Gal(?-?)GalNAc(?1-")
expect_equal(structure_to_iupac(shorthand), "Gal(??-?)GalNAc(?1-")
})
test_that("as_glycan_structure.character handles multiple linkages", {
# Multiple linkages
iupac <- "Neu5Ac(a2-3/6)Gal(?1-"
glycan <- as_glycan_structure(iupac)
expect_s3_class(glycan, "glyrepr_structure")
expect_equal(structure_to_iupac(glycan), "Neu5Ac(a2-3/6)Gal(?1-")
unknown_choices <- c(
"Gal(b1-4/?)GlcNAc(?1-",
"Gal(b1-?/4)GlcNAc(?1-",
"Gal(b1-3/?/6)GlcNAc(?1-"
)
normalized <- as_glycan_structure(unknown_choices)
expect_equal(
structure_to_iupac(normalized),
rep("Gal(b1-?)GlcNAc(?1-", length(unknown_choices))
)
})
test_that("as_glycan_structure.character works with vectors", {
# Multiple IUPAC strings
iupacs <- c("Man(?1-", "Gal(b1-3)GalNAc(?1-", "Neu5Ac(a2-")
glycans <- as_glycan_structure(iupacs)
expect_s3_class(glycans, "glyrepr_structure")
expect_equal(length(glycans), 3)
# Check each one
expect_equal(structure_to_iupac(glycans)[1], "Man(?1-")
expect_equal(structure_to_iupac(glycans)[2], "Gal(b1-3)GalNAc(?1-")
expect_equal(structure_to_iupac(glycans)[3], "Neu5Ac(a2-")
})
test_that("as_glycan_structure.character handles complex O-glycan", {
# Complex O-glycan structure
iupac <- "Neu5Ac(a2-3)Gal(b1-4)[Fuc(a1-3)]GlcNAc(b1-6)[Neu5Ac(a2-3)Gal(b1-3)]GalNAc(?1-"
glycan <- as_glycan_structure(iupac)
expect_s3_class(glycan, "glyrepr_structure")
expect_equal(length(glycan), 1)
# Check the structure has the correct number of nodes
graph <- get_structure_graphs(glycan, return_list = FALSE)
expect_equal(igraph::vcount(graph), 7) # 7 monosaccharides
})
test_that("as_glycan_structure.character error handling", {
# Empty string
expect_error(as_glycan_structure(""), "Cannot parse empty")
# NA is treated as a missing structure
expect_true(is.na(as_glycan_structure(NA_character_)))
# Invalid format - unknown monosaccharide
expect_error(as_glycan_structure("invalid_format"), "Could not parse")
})
test_that("as_glycan_structure.character round-trip consistency", {
# Test round-trip: structure -> IUPAC -> structure
original_structures <- c(
o_glycan_core_1(),
n_glycan_core()
)
for (i in seq_along(original_structures)) {
# Convert to IUPAC
iupac <- structure_to_iupac(original_structures[[i]])
# Parse back
parsed <- as_glycan_structure(iupac)
# Should be identical
expect_equal(structure_to_iupac(parsed), iupac)
}
})
# Edge cases and boundary conditions ----------------------------------------
test_that("as_glycan_structure.character handles whitespace", {
# Leading and trailing whitespace should be handled gracefully
expect_error(as_glycan_structure(" Man "), "Could not parse")
expect_error(as_glycan_structure(" "), "Cannot parse empty")
expect_error(as_glycan_structure("\t\n"), "Cannot parse empty")
})
test_that("as_glycan_structure.character handles malformed brackets", {
# Unmatched brackets
expect_error(as_glycan_structure("Man[Gal"), "Could not parse")
expect_error(as_glycan_structure("Man]Gal"), "Could not parse")
expect_error(as_glycan_structure("Man[[Gal]]"), "Could not parse")
expect_error(as_glycan_structure("Man(a1-3)[Gal"), "Could not parse")
})
test_that("as_glycan_structure.character handles malformed linkages", {
# Empty parentheses
expect_error(as_glycan_structure("Man()Gal"), "Could not parse")
# Incomplete linkages
expect_error(as_glycan_structure("Man(a1)Gal"), "Could not parse")
expect_error(as_glycan_structure("Man(-3)Gal"), "Could not parse")
# Invalid characters in linkages
expect_error(as_glycan_structure("Man(c1-3)Gal"), "Could not parse")
expect_error(as_glycan_structure("Man(a0-3)Gal"), "Could not parse")
expect_error(as_glycan_structure("Man(a3-3)Gal"), "Could not parse")
expect_error(as_glycan_structure("Man(a1-0)Gal"), "Could not parse")
expect_error(as_glycan_structure("Man(a#-3)Gal"), "Could not parse")
})
test_that("as_glycan_structure.character handles invalid monosaccharide names", {
# Too short
expect_error(as_glycan_structure("M"), "Could not parse")
expect_error(as_glycan_structure("G"), "Could not parse")
# Numbers at start
expect_error(as_glycan_structure("1Man"), "Could not parse")
expect_error(as_glycan_structure("2Gal"), "Could not parse")
# Special characters
expect_error(as_glycan_structure("Man@"), "Could not parse")
expect_error(as_glycan_structure("Gal#"), "Could not parse")
expect_error(as_glycan_structure("Man-Gal"), "Could not parse")
# Case sensitivity (monosaccharide names are case sensitive)
expect_error(as_glycan_structure("man"), "Could not parse")
expect_error(as_glycan_structure("MAN"), "Could not parse")
expect_error(as_glycan_structure("gal"), "Could not parse")
})
test_that("as_glycan_structure.character handles complex Neu variants", {
# Test special Neu variants from glyparse
glycan1 <- as_glycan_structure("Neu4Ac5Ac(?2-")
graph1 <- get_structure_graphs(glycan1, return_list = FALSE)
expect_equal(igraph::V(graph1)$mono, "Neu5Ac")
expect_equal(igraph::V(graph1)$sub, "4Ac")
glycan2 <- as_glycan_structure("Neu4Ac5Gc(?2-")
graph2 <- get_structure_graphs(glycan2, return_list = FALSE)
expect_equal(igraph::V(graph2)$mono, "Neu5Gc")
expect_equal(igraph::V(graph2)$sub, "4Ac")
# Neu5Ac should not be split even though it matches substituent pattern
glycan3 <- as_glycan_structure("Neu5Ac(?2-")
graph3 <- get_structure_graphs(glycan3, return_list = FALSE)
expect_equal(igraph::V(graph3)$mono, "Neu5Ac")
expect_equal(igraph::V(graph3)$sub, "")
})
test_that("as_glycan_structure.character handles invalid substituents", {
# Invalid substituent positions
expect_error(as_glycan_structure("Man0Ac"), "Could not parse")
expect_error(as_glycan_structure("ManAAc"), "Could not parse")
expect_error(as_glycan_structure("Man1X"), "Could not parse") # X is not a valid substituent
})
test_that("as_glycan_structure.character handles deeply nested structures", {
# Very deep nesting
deep_structure <- "Man(a1-2)[Man(a1-4)[Man(a1-4)[Man(a1-5)Man(a1-2)]Man(a1-3)]Man(a1-4)]Man(a1-"
glycan <- as_glycan_structure(deep_structure)
expect_s3_class(glycan, "glyrepr_structure")
# Verify the graph has correct number of nodes
graph <- get_structure_graphs(glycan, return_list = FALSE)
expect_equal(igraph::vcount(graph), 8)
})
test_that("as_glycan_structure.character handles mixed valid/invalid in vectors", {
# Vector with some valid and some invalid strings
mixed_vector <- c("Man", "invalid_mono", "Gal")
expect_error(as_glycan_structure(mixed_vector), "Could not parse")
# All invalid
all_invalid <- c("invalid1", "invalid2")
expect_error(as_glycan_structure(all_invalid), "Could not parse")
})
test_that("as_glycan_structure.character accepts mixed mono types with NA", {
mixed_vector <- c("Glc(a1-", NA, "Hex(a1-")
result <- as_glycan_structure(mixed_vector)
expect_identical(
get_mono_type(result),
c("concrete", NA_character_, "generic")
)
})
test_that("as_glycan_structure.character handles extreme linkage cases", {
# Maximum valid positions
glycan1 <- as_glycan_structure("Man(a2-9)Gal(?1-")
expect_s3_class(glycan1, "glyrepr_structure")
glycan2 <- as_glycan_structure("Man(b1-1)Gal(?1-")
expect_s3_class(glycan2, "glyrepr_structure")
# Complex multi-position linkages
glycan3 <- as_glycan_structure("Man(a1-2/3/4/5/6)Gal(?1-")
expect_s3_class(glycan3, "glyrepr_structure")
expect_equal(structure_to_iupac(glycan3), "Man(a1-2/3/4/5/6)Gal(?1-")
})
test_that("as_glycan_structure.character handles single character edge cases", {
# Very short but invalid inputs
expect_error(as_glycan_structure("("), "Could not parse")
expect_error(as_glycan_structure(")"), "Could not parse")
expect_error(as_glycan_structure("["), "Could not parse")
expect_error(as_glycan_structure("]"), "Could not parse")
expect_error(as_glycan_structure("-"), "Could not parse")
})
test_that("as_glycan_structure.character handles unusual anomer cases", {
# Various anomer edge cases
glycan1 <- as_glycan_structure("Neu5Ac(?2-")
expect_equal(structure_to_iupac(glycan1), "Neu5Ac(?2-")
glycan2 <- as_glycan_structure("Man(??-")
expect_equal(structure_to_iupac(glycan2), "Man(??-")
glycan3 <- as_glycan_structure("Fuc(?1-")
expect_equal(structure_to_iupac(glycan3), "Fuc(?1-")
})
test_that("as_glycan_structure.character preserves complex substituent patterns", {
# Test various substituent combinations
glycan1 <- as_glycan_structure("Gal6S(b1-3)GlcNAc4S(?1-")
graph1 <- get_structure_graphs(glycan1, return_list = FALSE)
expect_equal(sort(igraph::V(graph1)$sub), sort(c("4S", "6S")))
# Unknown position substituents
glycan2 <- as_glycan_structure("Man?S(?1-")
graph2 <- get_structure_graphs(glycan2, return_list = FALSE)
expect_equal(igraph::V(graph2)$sub, "?S")
})
test_that("as_glycan_structure.character handles multiple substituents", {
glycan <- as_glycan_structure("Glc3Me6S(a1-")
graph <- get_structure_graphs(glycan, return_list = FALSE)
expect_equal(igraph::V(graph)$sub, "3Me,6S")
})
test_that("as_glycan_structure.character handles multiple unknown substituents", {
iupacs <- c("Gal?Me?S(a1-", "Gal?S?S(a1-")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_equal(
purrr::map_chr(graphs, ~ igraph::V(.x)$sub),
c("?Me,?S", "?S,?S")
)
expect_equal(structure_to_iupac(glycans), iupacs)
})
test_that("as_glycan_structure.character handles ambiguous substituent positions", {
iupacs <- c(
"Gal4/6S(a1-",
"Gal3/4/6S(a1-",
"Gal4/6Ac(a1-",
"Neu4/5Ac(a2-"
)
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
expect_identical(
purrr::map_chr(graphs, \(graph) igraph::V(graph)$mono),
c("Gal", "Gal", "Gal", "Neu")
)
expect_identical(
purrr::map_chr(graphs, \(graph) igraph::V(graph)$sub),
c("4/6S", "3/4/6S", "4/6Ac", "4/5Ac")
)
expect_identical(unname(structure_to_iupac(glycans)), iupacs)
expect_identical(unname(count_mono(glycans, "S")), c(1L, 1L, 0L, 0L))
})
test_that("ambiguous substituent alternatives are canonicalized", {
iupacs <- c("Gal6/4S(a1-", "Gal4/6S(a1-", "Gal4/4S(a1-")
glycans <- as_glycan_structure(iupacs)
expect_identical(
unname(structure_to_iupac(glycans)),
c("Gal4/6S(a1-", "Gal4/6S(a1-", "Gal4S(a1-")
)
expect_identical(glycans[[1]], glycans[[2]])
})
test_that("as_glycan_structure.character rejects malformed ambiguous positions", {
iupacs <- c("Gal/6S(a1-", "Gal4/S(a1-", "Gal4//6S(a1-")
parsed <- purrr::map_lgl(iupacs, function(iupac) {
tryCatch(
{
as_glycan_structure(iupac)
TRUE
},
error = \(error) FALSE
)
})
expect_identical(parsed, rep(FALSE, length(iupacs)))
})
test_that("as_glycan_structure.character prefers longer substituent tokens", {
iupacs <- c("Glc3Pyr(a1-", "Glc3PC(a1-", "Glc3PPEtn(a1-", "Glc3PEtn(a1-")
expected_subs <- c("3Pyr", "3PC", "3PPEtn", "3PEtn")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
subs <- purrr::map_chr(graphs, ~ igraph::V(.x)$sub)
expect_equal(subs, expected_subs)
expect_equal(structure_to_iupac(glycans), iupacs)
})
test_that("as_glycan_structure.character handles glycolyl substituents", {
iupacs <- c("Glc3NGc(a1-", "Glc3Gc(a1-")
expected_subs <- c("3NGc", "3Gc")
glycans <- as_glycan_structure(iupacs)
graphs <- get_structure_graphs(glycans)
subs <- purrr::map_chr(graphs, ~ igraph::V(.x)$sub)
expect_equal(subs, expected_subs)
expect_equal(structure_to_iupac(glycans), iupacs)
})
test_that("Neu monosaccharides with 5Ac are correctly parsed as Neu5Ac", {
# Test cases where 5Ac should result in Neu5Ac base monosaccharide
expect_equal(
.extract_substituent("Neu3Me5Ac"),
c(mono = "Neu5Ac", sub = "3Me")
)
expect_equal(
.extract_substituent("Neu4Ac5Ac"),
c(mono = "Neu5Ac", sub = "4Ac")
)
expect_equal(
.extract_substituent("Neu4Ac5Ac9Ac"),
c(mono = "Neu5Ac", sub = "4Ac,9Ac")
)
expect_equal(.extract_substituent("Neu7S5Ac"), c(mono = "Neu5Ac", sub = "7S"))
})
test_that("Neu monosaccharides with 5Gc are correctly parsed as Neu5Gc", {
# Test cases where 5Gc should result in Neu5Gc base monosaccharide
expect_equal(
.extract_substituent("Neu3Me5Gc"),
c(mono = "Neu5Gc", sub = "3Me")
)
expect_equal(
.extract_substituent("Neu4Ac5Gc"),
c(mono = "Neu5Gc", sub = "4Ac")
)
expect_equal(
.extract_substituent("Neu3Gc5Gc"),
c(mono = "Neu5Gc", sub = "3Gc")
)
expect_equal(.extract_substituent("Neu7S5Gc"), c(mono = "Neu5Gc", sub = "7S"))
})
test_that("Neu monosaccharides without 5Ac or 5Gc remain as Neu", {
# Test cases where no 5Ac or 5Gc should result in Neu base monosaccharide
expect_equal(.extract_substituent("Neu"), c(mono = "Neu", sub = ""))
expect_equal(.extract_substituent("Neu7Ac"), c(mono = "Neu", sub = "7Ac"))
expect_equal(
.extract_substituent("Neu3Me7Ac"),
c(mono = "Neu", sub = "3Me,7Ac")
)
expect_equal(.extract_substituent("Neu3Gc"), c(mono = "Neu", sub = "3Gc"))
})
test_that("Neu5Ac and Neu5Gc exact matches work correctly", {
# Test exact matches
expect_equal(.extract_substituent("Neu5Ac"), c(mono = "Neu5Ac", sub = ""))
expect_equal(.extract_substituent("Neu5Gc"), c(mono = "Neu5Gc", sub = ""))
})
test_that("Neu5Ac and Neu5Gc with additional substituents work correctly", {
# Test Neu5Ac/Neu5Gc with additional substituents
expect_equal(
.extract_substituent("Neu5Ac9Ac"),
c(mono = "Neu5Ac", sub = "9Ac")
)
expect_equal(
.extract_substituent("Neu5Gc9Ac"),
c(mono = "Neu5Gc", sub = "9Ac")
)
expect_equal(
.extract_substituent("Neu5Ac7S9Ac"),
c(mono = "Neu5Ac", sub = "7S,9Ac")
)
})
test_that("Error is thrown for monosaccharides with both 5Ac and 5Gc", {
# This should be an error case
expect_error(
.extract_substituent("Neu5Ac5Gc"),
"cannot have both 5Ac and 5Gc"
)
expect_error(
.extract_substituent("Neu5Gc5Ac"),
"cannot have both 5Ac and 5Gc"
)
})
test_that("Full IUPAC parsing works with corrected Neu substituents", {
# Test full IUPAC parsing
result1 <- suppressMessages(as_glycan_structure(
"Neu3Me5Ac(a2-3)Gal(b1-4)Glc(a1-"
))
expect_true(is_glycan_structure(result1))
result2 <- suppressMessages(as_glycan_structure(
"Neu4Ac5Gc(a2-3)Gal(b1-4)Glc(a1-"
))
expect_true(is_glycan_structure(result2))
# Check that the output contains the correct monosaccharide names
expect_match(as.character(result1), "Neu5Ac3Me")
expect_match(as.character(result2), "Neu5Gc4Ac")
})
test_that("as_glycan_structure.character makes order of vertices and edges consistent with IUPAC-condensed", {
glycan <- as_glycan_structure(
"GlcNAc(b1-2)Man(a1-3)[GlcNAc(b1-2)Man(a1-6)]Man(b1-4)GlcNAc(b1-4)[Fuc(a1-3)]GlcNAc(b1-"
)
graph <- get_structure_graphs(glycan, return_list = FALSE)
expect_equal(
igraph::V(graph)$mono,
c("GlcNAc", "Man", "GlcNAc", "Man", "Man", "GlcNAc", "Fuc", "GlcNAc")
)
expect_equal(
igraph::E(graph)$linkage,
c("b1-2", "a1-3", "b1-2", "a1-6", "b1-4", "b1-4", "a1-3")
)
})
test_that("tree parsing preserves nested branch attachments and attributes", {
graph <- .parse_iupac_tree_single(paste0(
"Gal6S(b1-4)[Fuc(a1-3)]GlcNAc(b1-2)",
"[Man(a1-6)]Man(b1-4)GlcNAc-ol"
))
expect_identical(igraph::vertex_attr(graph, "name"), as.character(1:6))
expect_identical(
igraph::vertex_attr(graph, "mono"),
c("GlcNAc", "Man", "Man", "GlcNAc", "Fuc", "Gal")
)
expect_identical(igraph::vertex_attr(graph, "sub"), c(rep("", 5), "6S"))
expect_equal(
igraph::as_edgelist(graph, names = FALSE),
matrix(c(1, 2, 2, 3, 2, 4, 4, 5, 4, 6), ncol = 2, byrow = TRUE)
)
expect_identical(
igraph::edge_attr(graph, "linkage"),
c("b1-4", "a1-6", "b1-2", "a1-3", "b1-4")
)
expect_identical(
igraph::graph_attr(graph),
list(anomer = "?1", alditol = TRUE)
)
})
test_that("single-residue trees retain empty linkage metadata", {
graph <- .parse_iupac_tree_single("GlcNAc-ol(b1-")
expect_identical(
igraph::vertex_attr(graph),
list(name = "1", mono = "GlcNAc", sub = "")
)
expect_identical(igraph::edge_attr(graph), list(linkage = character()))
expect_identical(
igraph::graph_attr(graph),
list(anomer = "b1", alditol = TRUE)
)
})
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.