tests/testthat/test-union.R

test_that("subsetting a GSONList keeps it a GSONList", {
  a <- gson(data.frame(gsid = "A1", gene = "g1"), gsname = "Alpha")
  b <- gson(data.frame(gsid = "B1", gene = "g2"), gsname = "Beta")
  x <- gsonList(a, b)

  expect_identical(class(x[1]), c("GSONList", "list"))
  expect_identical(names(x["Beta"]), "Beta")
  expect_identical(x[["Alpha"]], a)
  expect_output(print(x[1]), "list of 1 GSON")
  ## the underlying GSON objects survive a subset untouched
  expect_identical(x[2][[1]]@gsname, "Beta")
  expect_length(x[0], 0)
  expect_s3_class(x[0], "GSONList")
})

test_that("gson_union merges two sources into one collection", {
  go <- gson(
    data.frame(gsid = c("GO:1", "GO:2"), gene = c("g1", "g2")),
    gsid2name = data.frame(gsid = c("GO:1", "GO:2"), name = c("set 1", "set 2")),
    gene2name = data.frame(gene = c("g1", "g2"), name = c("Gene 1", "Gene 2")),
    gsname = "GO", gsidtype = "GO", species = "human", keytype = "SYMBOL"
  )
  ke <- gson(
    data.frame(gsid = c("hsa1", "hsa2"), gene = c("g3", "g4")),
    gsid2name = data.frame(gsid = c("hsa1", "hsa2"), name = c("path 1", "path 2")),
    gsname = "KEGG", gsidtype = "KEGG", species = "human", keytype = "SYMBOL"
  )

  x <- gson_union(go, ke)

  expect_s4_class(x, "GSON")
  expect_identical(names(x), c("GO:1", "GO:2", "hsa1", "hsa2"))
  expect_identical(x@gsid2gene$gene, c("g1", "g2", "g3", "g4"))
  ## both name tables are carried over, so a merged gene set is still readable
  expect_identical(x@gsid2name$name, c("set 1", "set 2", "path 1", "path 2"))
  ## gene names come from the object that holds them; a gene no set contains
  ## is not carried over, and neither is a name table the other object lacks
  expect_identical(x@gene2name,
                   data.frame(gene = c("g1", "g2"), name = c("Gene 1", "Gene 2")))
  expect_identical(x@gsname, "GO + KEGG")
  expect_identical(x@gsidtype, "GO + KEGG")
  expect_identical(x@species, "human")
  expect_identical(x@keytype, "SYMBOL")
  expect_true(validate_gson(x))
})

test_that("gson_union refuses to mix two ID domains under one ID", {
  go <- gson(data.frame(gsid = c("0001", "0002"), gene = c("g1", "g2")),
             gsid2name = data.frame(gsid = c("0001", "0002"), name = c("go 1", "go 2")),
             gsname = "GO", gsidtype = "GO")
  ke <- gson(data.frame(gsid = c("0002", "0003"), gene = c("g3", "g4")),
             gsid2name = data.frame(gsid = c("0002", "0003"), name = c("kegg 2", "kegg 3")),
             gsname = "KEGG", gsidtype = "KEGG")

  expect_error(gson_union(go, ke),
               "gene set ID\\(s\\) used by more than one source: 0002")
  ## prefix says which source every ID came from
  expect_identical(names(gson_union(go, ke, .conflict = "prefix")),
                   c("GO:0001", "GO:0002", "KEGG:0002", "KEGG:0003"))
  ## rename leaves the IDs that nobody else uses alone
  renamed <- gson_union(go, ke, .conflict = "rename")
  expect_identical(names(renamed), c("0001", "GO:0002", "KEGG:0002", "0003"))
  ## a gene set that moved is still readable under its new ID
  expect_identical(renamed@gsid2name,
                   data.frame(gsid = c("0001", "GO:0002", "KEGG:0002", "0003"),
                              name = c("go 1", "go 2", "kegg 2", "kegg 3")))
  ## an ID that already carries its source is not qualified twice
  named <- gson(data.frame(gsid = "GO:0006915", gene = "g1"), gsname = "GO")
  expect_identical(names(gson_union(named, go, .conflict = "prefix")),
                   c("GO:0006915", "GO:0001", "GO:0002"))
  ## prefixing two collections with the same name would say nothing
  other_domain <- gson(data.frame(gsid = "0003", gene = "g5"),
                       gsname = "GO", gsidtype = "ALL")
  expect_error(gson_union(go, other_domain, .conflict = "prefix"),
               "both named 'GO'")
  expect_identical(names(gson_union(go, other_domain)),
                   c("0001", "0002", "0003"))
  expect_identical(gson_union(go, other_domain)@gsidtype, "GO + ALL")
})

test_that("gson_union of one source merges the files instead of colliding", {
  monday <- gson(data.frame(gsid = c("WP1", "WP2"), gene = c("g1", "g2")),
                 gsid2name = data.frame(gsid = c("WP1", "WP2"), name = c("one", "two")),
                 gsname = "WP", gsidtype = "WP", species = "human",
                 urlpattern = "https://example.org/{gsid}.html")
  tuesday <- gson(data.frame(gsid = c("WP2", "WP3"), gene = c("g2", "g3")),
                  gsid2name = data.frame(gsid = c("WP2", "WP3"), name = c("two", "three")),
                  gsname = "WP", gsidtype = "WP", species = "human",
                  urlpattern = "https://example.org/{gsid}.html")

  x <- gson_union(monday, tuesday)

  expect_identical(names(x), c("WP1", "WP2", "WP3"))
  ## WP2 is one gene set shared by both files, not two that collide
  expect_identical(x@gsid2gene,
                   data.frame(gsid = c("WP1", "WP2", "WP3"), gene = c("g1", "g2", "g3")))
  expect_identical(x@gsid2name$name, c("one", "two", "three"))
  expect_identical(x@gsname, "WP")
  expect_identical(x@gsidtype, "WP")
  ## every object declares the same pattern and no ID moved, so it still resolves
  expect_identical(x@urlpattern, "https://example.org/{gsid}.html")
  ## a single object passes through unchanged
  expect_identical(gson_union(monday), monday)
})

test_that("gson_union pairs each name table with its own object", {
  unnamed <- gson(data.frame(gsid = "A1", gene = "g1"), gsname = "Alpha")
  named <- gson(data.frame(gsid = c("B1", "B2"), gene = c("g2", "g3")),
                gsid2name = data.frame(gsid = c("B1", "B2"),
                                       name = c("b one", "b two")),
                gsname = "Beta")
  last <- gson(data.frame(gsid = "C1", gene = "g4"),
               gsid2name = data.frame(gsid = "C1", name = "c one"),
               gsname = "Gamma")

  x <- gson_union(unnamed, named, last)
  expect_identical(x@gsid2name,
                   data.frame(gsid = c("B1", "B2", "C1"),
                              name = c("b one", "b two", "c one")))
  ## the same when every ID moves to a qualified one
  y <- gson_union(unnamed, named, last, .conflict = "prefix")
  expect_identical(y@gsid2name,
                   data.frame(gsid = c("Beta:B1", "Beta:B2", "Gamma:C1"),
                              name = c("b one", "b two", "c one")))
  expect_identical(split(y@gsid2gene$gene, y@gsid2gene$gsid),
                   list(`Alpha:A1` = "g1", `Beta:B1` = "g2", `Beta:B2` = "g3",
                        `Gamma:C1` = "g4"))
})

test_that("gson_union drops a URL pattern it can no longer resolve", {
  with_url <- gson(data.frame(gsid = "A1", gene = "g1"), gsname = "Alpha",
                   urlpattern = "https://alpha.example.org/{gsid}")
  without <- gson(data.frame(gsid = "B1", gene = "g2"), gsname = "Beta")
  same_as_first <- gson(data.frame(gsid = "A2", gene = "g3"), gsname = "Alpha",
                        urlpattern = "https://alpha.example.org/{gsid}")

  ## Beta's gene sets would resolve to an Alpha page
  expect_null(gson_union(with_url, without)@urlpattern)
  ## the pattern is right until the IDs it indexes move
  expect_identical(gson_union(with_url, same_as_first)@urlpattern,
                   "https://alpha.example.org/{gsid}")
  other_name <- gson(data.frame(gsid = "A2", gene = "g3"), gsname = "Gamma",
                     urlpattern = "https://alpha.example.org/{gsid}")
  renamed <- gson_union(with_url, other_name, .conflict = "prefix")
  expect_identical(names(renamed), c("Alpha:A1", "Gamma:A2"))
  expect_null(renamed@urlpattern)
})

test_that("gson_union will not merge two kinds of gene or two species", {
  entrez <- gson(data.frame(gsid = "A1", gene = "101"), gsname = "Alpha",
                 keytype = "ENTREZID", species = "human")
  symbol <- gson(data.frame(gsid = "B1", gene = "TP53"), gsname = "Beta",
                 keytype = "SYMBOL", species = "human")
  mouse <- gson(data.frame(gsid = "C1", gene = "213"), gsname = "Gamma",
                keytype = "ENTREZID", species = "mouse")

  expect_error(gson_union(entrez, symbol), "different keytype values")
  expect_error(gson_union(entrez, symbol, .conflict = "prefix"),
               "different keytype values")
  expect_error(gson_union(entrez, mouse), "different species values")
  ## the schema the merged object is written to cannot be two things at once
  other <- gson(data.frame(gsid = "D1", gene = "102"), gsname = "Delta",
                keytype = "ENTREZID", species = "human", schema_version = "1.1")
  expect_error(gson_union(entrez, other), "different schema_version values")
})

test_that("gson_union takes a GSONList and rejects what it cannot merge", {
  a <- gson(data.frame(gsid = "A1", gene = "g1"), gsname = "Alpha")
  b <- gson(data.frame(gsid = "B1", gene = "g2"), gsname = "Beta")

  expect_identical(gson_union(gsonList(a, b)), gson_union(a, b))
  expect_error(gson_union(a, "Alpha"), "not character")
  expect_error(gson_union(), "at least one GSON object")
  ## memberships that carry no gene set ID or no gene cannot be merged into a
  ## collection, and say so the way the writers do
  incomplete <- gson(data.frame(gsid = c("A1", NA), gene = c("g1", "g2")),
                     gsname = "Alpha")
  expect_warning(x <- gson_union(a, incomplete), "omitted from the output")
  expect_identical(names(x), "A1")
})

test_that("gson_union of the bundled WikiPathways file is a bigger collection", {
  gmt <- system.file("extdata", "wikipathways-20220310-gmt-Homo_sapiens.gmt",
                     package = "gson")
  wp <- read.gmt.wp(gmt, output = "GSON")
  cut <- length(wp) %/% 2
  half <- wp[seq_len(cut)]
  other <- wp[seq(cut + 1, length(wp))]

  expect_identical(gson_union(half, other), wp)
  ## one source, so nothing is qualified and the collection says the same thing
  expect_identical(gson_union(half, other)@gsname, wp@gsname)
  expect_true(validate_gson(gson_union(half, wp)))
})

Try the gson package in your browser

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

gson documentation built on Oct. 9, 2026, 5:09 p.m.