Skip to content

Commit e6c5547

Browse files
cying111claude
andcommitted
Add tests for summariseByExon
Covers end-to-end execution on the bundled fixture SE and verifies the exon-aggregation identity against synthetic Poisson counts, including a per-exon hand-check on the most-shared exon. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dbe2af9 commit e6c5547

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
context("Exon quantification")
2+
3+
test_that("summariseByExon runs on bundled SE and returns a well-formed SE", {
4+
se <- readRDS(system.file("extdata",
5+
"seOutput_SGNex_A549_directRNA_replicate5_run1_chr9_1_1000000.rds",
6+
package = "bambu"))
7+
8+
seExon <- summariseByExon(se)
9+
10+
expect_s4_class(seExon, "RangedSummarizedExperiment")
11+
expect_true("counts" %in% assayNames(seExon))
12+
expect_equal(ncol(seExon), ncol(se))
13+
expect_equal(colnames(seExon), colnames(se))
14+
expect_true("GENEID" %in% colnames(mcols(rowRanges(seExon))))
15+
# rownames are unique chr:start:end:strand keys
16+
expect_equal(length(unique(rownames(seExon))), nrow(seExon))
17+
})
18+
19+
test_that("summariseByExon aggregation identity holds with synthetic counts", {
20+
se <- readRDS(system.file("extdata",
21+
"seOutput_SGNex_A549_directRNA_replicate5_run1_chr9_1_1000000.rds",
22+
package = "bambu"))
23+
24+
# Rebuild SE with two samples of Poisson counts (bundled fixture is all zero)
25+
set.seed(1)
26+
n <- nrow(se)
27+
cnt <- Matrix::Matrix(cbind(
28+
sampleA = as.numeric(rpois(n, 5)),
29+
sampleB = as.numeric(rpois(n, 10))
30+
), sparse = TRUE)
31+
rownames(cnt) <- rownames(se)
32+
rr <- rowRanges(se)
33+
mcols(rr) <- rowData(se)
34+
se2 <- SummarizedExperiment(
35+
assays = S4Vectors::SimpleList(counts = cnt),
36+
rowRanges = rr,
37+
colData = DataFrame(id = c("sampleA", "sampleB"),
38+
row.names = c("sampleA", "sampleB")))
39+
40+
seExon <- summariseByExon(se2)
41+
42+
# Per-sample identity: colSums(exon) == sum_tx #exons(tx) * count(tx)
43+
exonPerTx <- lengths(rowRanges(se2))
44+
expected <- colSums(as.matrix(cnt) * exonPerTx)
45+
observed <- colSums(as.matrix(assays(seExon)$counts))
46+
expect_equal(unname(observed), unname(expected))
47+
48+
# Spot-check the most-shared exon against a manual tx-set sum
49+
ex <- unlist(rowRanges(se2), use.names = TRUE)
50+
key <- paste(as.character(seqnames(ex)), start(ex), end(ex),
51+
as.character(strand(ex)), sep = ":")
52+
top <- names(sort(table(key), decreasing = TRUE))[1]
53+
txs <- unique(names(ex)[key == top])
54+
manual <- colSums(as.matrix(cnt[txs, , drop = FALSE]))
55+
expect_equal(unname(as.numeric(assays(seExon)$counts[top, ])),
56+
unname(manual))
57+
})

0 commit comments

Comments
 (0)