# library(testthat); library(scrapper); source("test-aggregateAcrossCells.R")

library(Matrix)

test_that("aggregateAcrossCells works for single factors", {
    x <- round(abs(rsparsematrix(1000, 100, 0.1) * 100))
    clusters <- sample(LETTERS, 100, replace=TRUE)
    agg <- aggregateAcrossCells(x, list(cluster=clusters))

    for (u in unique(clusters)) {
        chosen <- clusters == u
        m <- match(u, agg$combinations[,1])

        submat <- x[,chosen,drop=FALSE]
        sum.expected <- Matrix::rowSums(submat)
        expect_equal(sum.expected, agg$sums[,m])

        detected.expected <- Matrix::rowSums(submat > 0)
        expect_equal(detected.expected, agg$detected[,m])
    }

    expect_identical(agg$counts, as.integer(table(clusters)))

    expect_error(aggregateAcrossCells(SummarizedExperiment::SummarizedExperiment(x), list(cluster=clusters)), "not supported")
})

test_that("aggregateAcrossCells works for medians", {
    x <- matrix(runif(100000), ncol=100)
    clusters <- sample(LETTERS, 100, replace=TRUE)
    agg <- aggregateAcrossCells(x, list(cluster=clusters), compute.sum=FALSE, compute.detected=FALSE, compute.median=TRUE)

    for (u in unique(clusters)) {
        chosen <- clusters == u
        m <- match(u, agg$combinations[,1])
        submat <- x[,chosen,drop=FALSE]
        median.expected <- apply(submat, 1, median)
        expect_equal(median.expected, agg$medians[,m])
    }
})

test_that("aggregateAcrossCells works for multiple factors", {
    x <- round(abs(rsparsematrix(1000, 100, 0.1) * 100))
    clusters <- sample(LETTERS, 100, replace=TRUE)
    samples <- sample(1:3, 100, replace=TRUE)
    agg <- aggregateAcrossCells(x, list(sample=samples, cluster=clusters))

    full <- data.frame(samples, clusters)
    df <- unique(full)
    df <- df[order(df[,1], df[,2]),]

    expected.counts <- integer(nrow(df))
    for (u in seq_len(nrow(df))) {
        chosen <- clusters == df$clusters[u] & samples == df$samples[u]
        expected.counts[u] <- sum(chosen)
        m <- which(agg$combinations$cluster  == df$clusters[u] & agg$combinations$sample == df$samples[u])

        submat <- x[,chosen,drop=FALSE]
        sum.expected <- Matrix::rowSums(submat)
        expect_equal(sum.expected, agg$sums[,m])

        detected.expected <- Matrix::rowSums(submat > 0)
        expect_equal(detected.expected, agg$detected[,m])
    }

    expect_identical(agg$counts, expected.counts)
})
