set.seed(321)
# mock up some single-cell, mixture & marker data
sce <- mockSC(ng = 200, nc = 10, nt = 3)
spe <- mockSP(sce)
mgs <- getMGS(sce)
# Create SpatialExperiment
spe1 <- SpatialExperiment::SpatialExperiment(
    assay = list(counts = SingleCellExperiment::counts(spe)),
    colData = SummarizedExperiment::colData(spe))

# Function to run the checks
.checks <- function(decon, sce, spe) {
    mtr <- decon[[1]]
    rss <- decon[[2]]
    expect_is(decon, "list")
    expect_is(mtr, "matrix")
    expect_is(rss, "numeric")
    expect_identical(ncol(mtr), length(unique(sce$type)))
    expect_identical(sort(colnames(mtr)), sort(unique(as.character(sce$type))))
    expect_identical(nrow(mtr), length(rss))
    expect_identical(sort(rownames(mtr)), sort(names(rss)))
    
    dif <- rowSums((mtr - metadata(spe)$props)^2)
    median_ss <- median(dif)
    mean_ss <- mean(dif)
    expect_true(mean_ss < 0.1 & median_ss < 0.1)
}

# Train NMF
res <- trainNMF(
    x = as.matrix(counts(sce)),
    y = rownames(spe),
    groups = sce$type,
    mgs = mgs,
    weight_id = "weight",
    group_id = "type",
    gene_id = "gene"
)
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# ----  Check runDeconvolution x, y inputs  ------------------------------------
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# runDeconvolution with SCE ----
test_that("runDeconvolution x SCE", {
    decon <- runDeconvolution(
        x = spe,
        mod = res[["mod"]],
        ref = res[["topic"]]
    )
    
    .checks(decon, sce, spe)
})

test_that("runDeconvolution x SPE", {
    decon <- runDeconvolution(
        x = spe1,
        mod = res[["mod"]],
        ref = res[["topic"]]
    )
    
    .checks(decon, sce, spe)
})


# runDeconvolution with sparse matrix sp ----
test_that("runDeconvolution x dgCMatrix SP", {
    decon <- runDeconvolution(
        x = Matrix::Matrix(counts(spe), sparse = TRUE),
        mod = res[["mod"]],
        ref = res[["topic"]]
    )
    
    .checks(decon, sce, spe)
})

# runDeconvolution with sparse matrix sp ----
test_that("runDeconvolution x DelayedMatrix SP", {
    decon <- runDeconvolution(
        x = DelayedArray::DelayedArray(counts(spe)),
        mod = res[["mod"]],
        ref = res[["topic"]]
    )
    
    .checks(decon, sce, spe)
})

# runDeconvolution with matrices in both ----
test_that("runDeconvolution x matrices", {
    decon <- runDeconvolution(
        x = as.matrix(counts(spe)),
        mod = res[["mod"]],
        ref = res[["topic"]]
    )
    
    .checks(decon, sce, spe)
})

