Skip to content

Commit

Permalink
add uns-nested roundtrip test
Browse files Browse the repository at this point in the history
  • Loading branch information
rcannood committed Dec 12, 2024
1 parent e92b671 commit 2b5ffbb
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 15 deletions.
20 changes: 5 additions & 15 deletions inst/known_issues.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ known_issues:
- backend: HDF5AnnData
slot:
- uns
- uns_nested
dtype:
- empty
- none
Expand All @@ -91,21 +92,7 @@ known_issues:
- backend: HDF5AnnData
slot:
- uns
dtype:
- boolean_array
process: [reticulate]
error_message: |
adata_r$uns[[name]] (`actual`) not equal to reticulate::py_to_r(adata_py$uns[[name]]) (`expected`).
`dim(actual)` is absent
`dim(expected)` is an integer vector (10)
description: The python object has a dimension while the R object does not.
proposed_solution: Think about whether this is a problem or not. If it isn't, fix the unit test.
to_investigate: True
to_fix: True
- backend: HDF5AnnData
slot:
- uns
- uns_nested
dtype:
- boolean_array
- dense_array
Expand All @@ -124,6 +111,7 @@ known_issues:
- backend: HDF5AnnData
slot:
- uns
- uns_nested
dtype:
- categorical
- categorical_missing_values
Expand Down Expand Up @@ -155,6 +143,7 @@ known_issues:
- backend: HDF5AnnData
slot:
- uns
- uns_nested
dtype:
- nullable_boolean_array
- nullable_integer_array
Expand All @@ -171,6 +160,7 @@ known_issues:
- backend: HDF5AnnData
slot:
- uns
- uns_nested
dtype:
- boolean
- char
Expand Down
113 changes: 113 additions & 0 deletions tests/testthat/test-roundtrip-uns-nested.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
skip_if_no_anndata()
skip_if_not_installed("reticulate")

library(reticulate)
testthat::skip_if_not(
reticulate::py_module_available("dummy_anndata"),
message = "Python dummy_anndata module not available for testing"
)

ad <- reticulate::import("anndata", convert = FALSE)
da <- reticulate::import("dummy_anndata", convert = FALSE)
bi <- reticulate::import_builtins()

known_issues <- read_known_issues()

test_names <- c(
names(da$matrix_generators),
names(da$vector_generators),
names(da$scalar_generators)
)

for (name in test_names) {
# first generate a python h5ad
adata_py <- da$generate_dataset(
x_type = NULL,
obs_types = list(),
var_types = list(),
layer_types = list(),
obsm_types = list(),
varm_types = list(),
obsp_types = list(),
varp_types = list(),
uns_types = list(),
nested_uns_types = list(name)
)

# create a couple of paths
file_py <- withr::local_file(tempfile(paste0("anndata_py_", name), fileext = ".h5ad"))
file_r <- withr::local_file(tempfile(paste0("anndata_r_", name), fileext = ".h5ad"))

# write to file
adata_py$write_h5ad(file_py)

test_that(paste0("Reading an AnnData with uns_nested '", name, "' works"), {
msg <- message_if_known(
backend = "HDF5AnnData",
slot = c("uns_nested"),
dtype = name,
process = "read",
known_issues = known_issues
)
skip_if(!is.null(msg), message = msg)

adata_r <- read_h5ad(file_py, to = "HDF5AnnData")
expect_equal(
names(adata_r$uns$nested),
bi$list(adata_py$uns$nested$keys())
)

# check that the print output is the same
str_r <- capture.output(print(adata_r))
str_py <- capture.output(print(adata_py))
expect_equal(str_r, str_py)
})

# maybe this test simply shouldn't be run if there is a known issue with reticulate
test_that(paste0("Comparing an anndata with uns_nested '", name, "' with reticulate works"), {
msg <- message_if_known(
backend = "HDF5AnnData",
slot = c("uns_nested"),
dtype = name,
process = c("read", "reticulate"),
known_issues = known_issues
)
skip_if(!is.null(msg), message = msg)

adata_r <- read_h5ad(file_py, to = "HDF5AnnData")

expect_equal(
adata_r$uns[["nested"]][[name]],
reticulate::py_to_r(adata_py$uns$nested[[name]])
)
})

test_that(paste0("Writing an AnnData with uns_nested '", name, "' works"), {
msg <- message_if_known(
backend = "HDF5AnnData",
slot = c("uns_nested"),
dtype = name,
process = c("read", "write"),
known_issues = known_issues
)
skip_if(!is.null(msg), message = msg)

adata_r <- read_h5ad(file_py, to = "InMemoryAnnData")
write_h5ad(adata_r, file_r)

# read from file
adata_py2 <- ad$read_h5ad(file_r)

# expect name is one of the keys
expect_contains(
bi$list(adata_py2$uns$nested$keys()),
name
)

# expect that the objects are the same
expect_equal_py(
py_get_item(adata_py2$uns$nested, name),
py_get_item(adata_py$uns$nested, name)
)
})
}

0 comments on commit 2b5ffbb

Please sign in to comment.