Expected `all(ann_na_counts == 0)` to be TRUE.
Differences:
`actual`:   FALSE
`expected`: TRUE 

context: downsample single-cell deterministic
annotation shape: 8x16
repertoire shape: 2x4
missing annotation columns: <none>
missing repertoire columns: <none>
annotation NA counts: imd_receptor_id=0, imd_repertoire_id=8, imd_count=8, imd_proportion=8, n_repertoires=0
repertoire NA counts: imd_repertoire_id=0, n_barcodes=0, n_receptors=2
unmatched repertoire ids: NA

annotations dump:
# A tibble: 8 x 16
  cell_id sample_id v_call j_call junction_aa locus umi_count filename          
* <chr>   <chr>     <chr>  <chr>  <chr>       <chr>     <dbl> <chr>             
1 c1      S1        IGHV1  IGHJ1  CARA        IGH          10 "D:\\temp\\2026_0~
2 c2      S1        IGHV2  IGHJ2  CARB        IGH          11 "D:\\temp\\2026_0~
3 c3      S1        IGHV3  IGHJ3  CARC        IGH          12 "D:\\temp\\2026_0~
4 c4      S1        IGHV4  IGHJ4  CARD        IGH          13 "D:\\temp\\2026_0~
5 c5      S2        IGHV1  IGHJ1  CARE        IGH          14 "D:\\temp\\2026_0~
6 c6      S2        IGHV2  IGHJ2  CARF        IGH          15 "D:\\temp\\2026_0~
7 c7      S2        IGHV3  IGHJ3  CARG        IGH          16 "D:\\temp\\2026_0~
8 c8      S2        IGHV4  IGHJ4  CARH        IGH          17 "D:\\temp\\2026_0~
# i 8 more variables: imd_barcode <chr>, imd_chain_id <int>,
#   imd_receptor_id <int>, imd_n_chains <dbl>, imd_count <dbl>,
#   imd_repertoire_id <int>, imd_proportion <dbl>, n_repertoires <int>

repertoires dump:
# A tibble: 2 x 4
  imd_repertoire_id sample_id n_barcodes n_receptors
              <int> <chr>          <dbl>       <int>
1                 1 S1                 4          NA
2                 2 S2                 4          NA

test_that("downsample_immundata downsamples single-cell repertoires and is deterministic with seed", {
v_call = c("IGHV1", "IGHV2", "IGHV3", "IGHV4", "IGHV1", "IGHV2", "IGHV3", "IGHV4"),
j_call = c("IGHJ1", "IGHJ2", "IGHJ3", "IGHJ4", "IGHJ1", "IGHJ2", "IGHJ3", "IGHJ4"),
junction_aa = c("CARA", "CARB", "CARC", "CARD", "CARE", "CARF", "CARG", "CARH"),
features = c("v_call", "j_call", "junction_aa"),
ds1 <- downsample_immundata(idata, n = 2, seed = 100)
ds2 <- downsample_immundata(idata, n = 2, seed = 100)
test_that("downsample_immundata downsampled bulk repertoires by count", {
v_call = c("TRBV1", "TRBV2", "TRBV3", "TRBV4"),
j_call = c("TRBJ1", "TRBJ2", "TRBJ1", "TRBJ2"),
junction_aa = c("AAAA", "BBBB", "CCCC", "DDDD"),
schema = c("v_call", "j_call", "junction_aa"),
expect_agg_repertoires_integrity(idata, "downsample bulk count mode")
ds <- downsample_immundata(idata, n = 5, seed = 42)
test_that("downsample_immundata keeps paired chains intact", {
v_call = c("IGHV1", "IGLV1", "IGHV2", "IGLV2", "IGHV3", "IGLV3", "IGHV1", "IGLV1", "IGHV2", "IGLV2", "IGHV3", "IGLV3"),
j_call = c("IGHJ1", "IGLJ1", "IGHJ2", "IGLJ2", "IGHJ3", "IGLJ3", "IGHJ1", "IGLJ1", "IGHJ2", "IGLJ2", "IGHJ3", "IGLJ3"),
locus = c("IGH", "IGL", "IGH", "IGL", "IGH", "IGL", "IGH", "IGL", "IGH", "IGL", "IGH", "IGL"),
ds <- downsample_immundata(idata, n = 2, seed = 7)
test_that("downsample_immundata works on IG test data with proportion n", {
n_before <- idata$repertoires |> collect() |> pull(n_barcodes)
ds <- downsample_immundata(idata, n = 0.5, seed = 123)
n_after <- ds$repertoires |> collect() |> pull(n_barcodes)
test_that("downsample_immundata with n = 1 keeps one receptor per repertoire", {
v_call = c("IGHV1", "IGHV1", "IGHV2", "IGHV3", "IGHV4", "IGHV5", "IGHV5", "IGHV6"),
j_call = c("IGHJ1", "IGHJ1", "IGHJ2", "IGHJ3", "IGHJ4", "IGHJ5", "IGHJ5", "IGHJ6"),
expect_agg_repertoires_integrity(idata, "downsample n=1 receptor mode")
ds1 <- downsample_immundata(idata, n = 1, seed = 321)
ds2 <- downsample_immundata(idata, n = 1, seed = 321)
test_that("downsample_immundata validates n and handles no-repertoire fallback", {
ds <- downsample_immundata(idata, n = 0.1, seed = 1)
test_that("downsample_immundata warns and keeps repertoire unchanged when n exceeds available units", {
v_call = c("IGHV1", "IGHV2", "IGHV3", "IGHV1", "IGHV2", "IGHV3"),
j_call = c("IGHJ1", "IGHJ2", "IGHJ3", "IGHJ1", "IGHJ2", "IGHJ3"),
schema = make_receptor_schema(features = c("v_call", "j_call", "junction_aa"), chains = "IGH"),
expect_agg_repertoires_integrity(idata, "downsample n exceeds units")
ds <- downsample_immundata(idata, n = 10, seed = 42),
test_that("downsample_immundata supports count-mode proportion downsampling", {
ds <- downsample_immundata(idata, n = 0.5, seed = 101)
test_that("downsample_immundata is deterministic in count mode with seed", {
ds1 <- downsample_immundata(idata, n = 5, seed = 222)
ds2 <- downsample_immundata(idata, n = 5, seed = 222)
test_that("downsample_immundata errors when proportion results in zero target", {
downsample_immundata(idata, n = 0.0001, seed = 1),
test_that("downsample_immundata produces consistent imd_count and imd_proportion invariants", {
v_call = c("IGHV1", "IGHV1", "IGHV2", "IGHV1", "IGHV2", "IGHV2"),
j_call = c("IGHJ1", "IGHJ1", "IGHJ2", "IGHJ1", "IGHJ2", "IGHJ2"),
ds <- downsample_immundata(idata, n = 2, seed = 33)
select(imd_repertoire_id, imd_receptor_id, imd_count, imd_proportion) |>
reps <- reps |> arrange(imd_repertoire_id)
expect_true(all(abs(receptor_stats$sum_prop - 1) < 1e-8))