tests/testthat/test-comp_barplot.R

data("dietswap", package = "microbiome")

test_that("comp_barplot throws correct errors", {
  expect_error(
    object = comp_barplot(dietswap, tax_level = "geenus"),
    regexp = "must be the name of a valid rank"
  )
  expect_error(
    object = comp_barplot(dietswap, tax_level = ".Taxon"),
    regexp = "'.Taxon' cannot be used as a rank name! You must rename that rank."
  )
  expect_error(
    object = comp_barplot(dietswap, tax_level = "Genus", n_taxa = 1:15),
    regexp = "n_taxa must be a positive integer"
  )
  expect_error(
    object = comp_barplot(dietswap, tax_level = "Genus", max_taxa = 5),
    regexp = "max_taxa must be a positive integer, and not lower than n_taxa"
  )
})


# manual taxa ordering -------------------------------------------------------

test_that("fixing tax order of comp_barplot works", {
  fixed_order <- c(
    "Fusobacteria", "Cyanobacteria", "Verrucomicrobia", "Spirochaetes",
    "Actinobacteria", "Firmicutes", "Proteobacteria", "Bacteroidetes"
  )
  p8 <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(tax_level = "Phylum", n_taxa = 8, tax_order = fixed_order) +
    ggplot2::coord_flip()

  expect_equal(levels(p8$data$.Taxon), rev(fixed_order))

  p7 <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(tax_level = "Phylum", n_taxa = 7, tax_order = fixed_order) +
    ggplot2::coord_flip()

  expect_equal(levels(p7$data$.Taxon), rev(c(fixed_order[1:7], "Other")))
})

# manual sample ordering -----------------------------------------------------

test_that("fixing sample order of comp_barplot works", {
  ps_A <- ps_arrange(dietswap, subject, timepoint)
  plotA <- comp_barplot(ps_A, tax_level = "Genus", sample_order = "asis")

  ps_B <- ps_reorder(dietswap, phyloseq::sample_names(ps_A))
  plotB <- comp_barplot(ps_B, tax_level = "Genus", sample_order = "asis")

  plotC <- dietswap %>%
    comp_barplot("Genus", sample_order = phyloseq::sample_names(ps_A))

  expect_equal(ps_A, ps_B)
  expect_equal(plotA, plotB)
  expect_equal(plotA, plotC)
})


# standard dynamic ordering of samples and taxa stays consistent -------------

test_that("comp_barplot doesn't change", {
  local_edition(3)

  p <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(
      tax_level = "Genus", n_taxa = 8,
      sample_order = "aitchison",
      merge_other = FALSE,
      tax_order = sum,
    ) + ggplot2::coord_flip()

  expect_snapshot_csv(
    name = "unique_taxa_order",
    object = levels(p$data$.Taxon)
  )
  expect_snapshot_csv(
    name = "SAMPLE_order",
    object = levels(p$data$SAMPLE)
  )
  expect_equal(object = levels(p$data[["Genus"]]), expected = c(
    "Prevotella melaninogenica et rel.", "Bacteroides vulgatus et rel.",
    "Oscillospira guillermondii et rel.", "Prevotella oralis et rel.",
    "Faecalibacterium prausnitzii et rel.", "Clostridium cellulosi et rel.",
    "Clostridium symbiosum et rel.", "Allistipes et rel.", "Other"
  ))

  # vdiffr visual test
  skip_if(packageVersion("ggplot2") < "3.4.0") # stroke-linecap changed from square to butt
  vdiffr::expect_doppelganger(title = "comp_barplot", fig = p)
})

test_that("comp_barplot taxa ordering at level of 'unique' works", {
  local_edition(3)

  p <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(
      tax_level = "unique", n_taxa = 8, sample_order = "asis", tax_order = sum,
      merge_other = FALSE
    )
  expect_snapshot_csv(levels(p$data$.Taxon), name = "uniqueTaxonLevelsUnmerged")

  p2 <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(
      tax_level = "unique", n_taxa = 3, sample_order = "asis", tax_order = sum,
      merge_other = TRUE
    )
  expect_equal(object = levels(p2$data$.Taxon), expected = c(
    "Other", "Oscillospira guillermondii et rel.",
    "Bacteroides vulgatus et rel.", "Prevotella melaninogenica et rel."
  ))
})

test_that("list of plots generated by group_by works", {
  local_edition(3)
  plots <- dietswap %>%
    ps_filter(timepoint == 1) %>%
    comp_barplot(
      tax_level = "Genus",
      sample_order = "bray",
      group_by = "bmi_group",
      keep_all_vars = FALSE
    )
  expect_equal(
    object = names(plots),
    expected = c("overweight", "lean", "obese")
  )

  for (p in names(plots)) {
    expect_snapshot_csv(
      name = paste0("unique_taxa_order-", p),
      object = levels(plots[[p]]$data$.Taxon)
    )
    expect_snapshot_csv(
      name = paste0("SAMPLE_order-", p),
      object = levels(plots[[p]]$data$SAMPLE)
    )
    expect_snapshot(print(p))
    expect_equal(levels(plots[[p]]$data[["Genus"]]), c(
      "Prevotella melaninogenica et rel.", "Bacteroides vulgatus et rel.",
      "Oscillospira guillermondii et rel.", "Prevotella oralis et rel.",
      "Faecalibacterium prausnitzii et rel.", "Clostridium cellulosi et rel.",
      "Clostridium symbiosum et rel.", "Allistipes et rel.", "Other"
    ))

    # check dropping variables (for faster melting) works (keep_all_vars = F)
    # only label 'SAMPLE' and group 'bmi_group' variables kept
    expect_equal(
      object = colnames(plots[[p]]$data),
      expected = c(
        "OTU", "Sample", "Abundance", "SAMPLE", "bmi_group", "Phylum",
        "Family", "Genus", "unique", ".Taxon"
      )
    )
  }
})



# test internal helper --------------------------------------------------------

test_that("tt_add_topN_var helper works as expected", {
  local_edition(3)
  tt <- microViz:::tt_add_topN_var(
    phyloseq::tax_table(dietswap),
    N = 4, other = "things", varname = "test"
  )
  expect_snapshot(
    print(head(x = tt, 6), width = 80)
  )
})


# manual sample ordering errors -----------------------------------------------

test_that("sample_order arg errors nicely when invalid names provided", {
  # invalid names (not in sample_names)
  expect_error(
    object = comp_barplot(dietswap, tax_level = "Genus", sample_order = letters),
    regexp = "1 or more of the sample_order values are not phyloseq sample_names"
  )

  # incorrect number of otherwise valid sample names
  expect_error(
    object = comp_barplot(
      ps = dietswap, tax_level = "Genus",
      sample_order = phyloseq::sample_names(dietswap)[1:10]
    ),
    regexp = "Length of sample_order must be 1 or same as number of samples!"
  )
})
david-barnett/microViz documentation built on April 17, 2025, 4:25 a.m.