##############################################
  # dat1
  set.seed(1)
  exp1 <- array(rnorm(120), dim = c(dataset = 3, sdate = 5, ftime = 2, lon = 1, lat = 4))
  set.seed(2)
  obs1 <- array(rnorm(80),  dim = c(dataset = 2, sdate = 5, ftime = 2, lon = 1, lat = 4))
  set.seed(2)
  na <- floor(runif(10, min = 1, max = 80))
  obs1[na] <- NA

  # dat 2: vector
  set.seed(5)
  exp2 <- rnorm(10)
  set.seed(6)
  obs2 <- rnorm(10)

  # dat3
  set.seed(1)
  exp3 <- array(rnorm(120), dim = c(sdate = 5, ftime = 2, member = 3))
  set.seed(2)
  obs3 <- array(rnorm(80),  dim = c(sdate = 5, ftime = 2, member = 2))

  # dat4
  set.seed(1)
  exp4 <- array(rnorm(120), dim = c(dataset = 2, sdate = 5, time = 1))
  set.seed(2)
  obs4 <- array(rnorm(80),  dim = c(dataset = 1, sdate = 5, member = 2, time = 1))

##############################################
test_that("1. Input checks", {

  expect_error(
  MSE(c(), c()),
  "Parameter 'exp' and 'obs' cannot be NULL."
  )
  expect_error(
  MSE(c('b'), c('a')),
  "Parameter 'exp' and 'obs' must be a numeric array."
  )
  expect_error(
  MSE(c(1:10), c(2:4)),
  "Parameter 'exp' and 'obs' must be array with as least two dimensions time_dim and dat_dim, or vector of same length."
  )
  expect_error(
  MSE(array(1:10, dim = c(2, 5)), array(1:4, dim = c(2, 2))),
  "Parameter 'exp' and 'obs' must have dimension names."
  )
  expect_error(
  MSE(array(1:20, dim = c(dat = 2, sdate = 5, member = 2)), 
      array(1:10, dim = c(dat = 2, sdate = 5, time = 1))),
  "Parameter 'exp' and 'obs' must have the same dimension names."
  )
  expect_error(
  MSE(exp1, obs1, dat_dim = 1),
  "Parameter 'dat_dim' must be a character string."
  )
  expect_error(
  MSE(exp1, obs1, dat_dim = 'a'),
  "Parameter 'dat_dim' is not found in 'exp' or 'obs' dimension."
  )
  expect_error(
  MSE(exp1, obs1, time_dim = c('sdate', 'a')),
  "Parameter 'time_dim' must be a character string."
  )
  expect_error(
  MSE(exp1, obs1, time_dim = 'a'),
  "Parameter 'time_dim' is not found in 'exp' or 'obs' dimension."
  )
  expect_error(
  MSE(exp1, obs1, comp_dim = c('sdate', 'ftime')),
  "Parameter 'comp_dim' must be a character string."
  )
  expect_error(
  MSE(exp1, obs1, comp_dim = 'a'),
  "Parameter 'comp_dim' is not found in 'exp' or 'obs' dimension."
  )
  expect_error(
  MSE(exp1, obs1, limits = c(1,3)),
  "Paramter 'comp_dim' cannot be NULL if 'limits' is assigned."
  )
  expect_error(
  MSE(exp1, obs1, comp_dim = 'ftime', limits = c(1)),
  paste0("Parameter 'limits' must be a vector of two positive ",
                  "integers smaller than the length of paramter 'comp_dim'.")
  )
  expect_error(
  MSE(exp1, obs1, alpha = -1),
  "Parameter 'alpha' must be a numeric number between 0 and 1."
  )
  expect_error(
  MSE(exp1, obs1, conf = 1),
  "Parameter 'conf' must be one logical value."
  )
  expect_error(
  MSE(exp1, obs1, ncores = 1.5),
  "Parameter 'ncores' must be a positive integer."
  )
  expect_error(
  MSE(exp = array(1:10, dim = c(dataset = 1, member = 5, sdate = 1)),
      obs = array(1:4, dim = c(dataset = 2, member = 2, sdate = 2))),
  "Parameter 'exp' and 'obs' must have same length of all dimensions except 'dat_dim' and 'memb_dim'."
  )
  expect_error(
  MSE(exp = array(1:5, dim = c(sdate = 1, dataset = 5, a = 1)),
      obs = array(1:2, dim = c(a = 1, sdate = 1, dataset = 2)), dat_dim = "dataset"),
  "The length of time_dim must be at least 2 to compute MSE."
  )



})

##############################################
test_that("2. Output checks: dat1", {
suppressWarnings(
  expect_equal(
    dim(MSE(exp1, obs1, dat_dim = 'dataset')$mse),
    c(nexp = 3, nobs = 2, ftime = 2, lon = 1, lat = 4)
  )
)
suppressWarnings(
  expect_equal(
    MSE(exp1, obs1, dat_dim = 'dataset')$mse[1:6],
    c(1.2815677, 2.0832803, 1.1894637, 1.3000403, 1.4053807, 0.8157563)^2, 
    tolerance = 0.001
  )
)
suppressWarnings(
  expect_equal(
    length(which(is.na(MSE(exp1, obs1, dat_dim = 'dataset')$conf.lower))),
    4
  )
)
suppressWarnings(
  expect_equal(
    c(MSE(exp1, obs1, dat_dim = 'dataset')$conf.lower[2,1,,1,2:3]),
    c(1.8869268, 0.4418298, 0.2694637, 0.8215383),
    tolerance = 0.001
  )
)
suppressWarnings(
  expect_equal(
    length(which(is.na(MSE(exp1, obs1, dat_dim = 'dataset', comp_dim = 'ftime')$mse))),
    0
  )
)
suppressWarnings(
  expect_equal(
    length(which(is.na(MSE(exp1, obs1, dat_dim = 'dataset', comp_dim = 'ftime')$conf.upper))),
    8
  )
)
suppressWarnings(
  expect_equal(
    length(which(is.na(MSE(exp1, obs1, dat_dim = 'dataset', comp_dim = 'lat')$conf.lower))),
    36
  )
)
suppressWarnings(
  expect_equal(
    length(which(is.na(MSE(exp1, obs1, dat_dim = 'dataset', comp_dim = 'lat', limits = c(1, 2))$conf.lower))),
    21
  )
)
suppressWarnings(
  expect_equal(
    c(MSE(exp1, obs1, dat_dim = 'dataset', alpha = 0.01)$conf.upper[2,1,,1,2:3]),
    c(13.844841, 5.044269, 1.977121, 6.027826),
    tolerance = 0.0001
  )
)
suppressWarnings(
  expect_equal(
    length(MSE(exp1, obs1, dat_dim = 'dataset', conf = FALSE)),
    1
  )
)


})

##############################################
test_that("3. Output checks: dat2", {

  expect_equal(
    dim(MSE(exp2, obs2)$mse),
    NULL 
  )

  expect_equal(
  as.vector(MSE(exp2, obs2)$mse),
  1.429815^2,
  tolerance = 0.00001
  )
})

##############################################
test_that("4. Output checks: dat3", {

  expect_equal(
    dim(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member')$mse),
    c(ftime = 2)
  )

  expect_equal(
  as.vector(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member')$mse),
  c(0.6191331, 0.7133894)^2,
  tolerance = 0.00001
  )
  expect_equal(
  names(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member', conf = FALSE)),
  c("mse")
  )
  expect_equal(
  names(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member', conf = TRUE)),
  c('mse', 'conf.lower', 'conf.upper')
  )
  expect_equal(
  c(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member')$conf.lower),
  c(0.2567713, 0.3409037),
  tolerance = 0.0001
  )
  expect_equal(
  c(MSE(exp3, obs3, dat_dim = NULL, memb_dim = 'member')$conf.upper),
  c(1.231523, 1.635038),
  tolerance = 0.0001
  )

})

##############################################

test_that("5. Output checks: dat4", {

  expect_equal(
  dim(MSE(exp4, obs4, dat_dim = 'dataset', memb_dim = 'member')$mse),
  c(nexp = 2, nobs = 1, time = 1)
  )
  expect_equal(
  c(MSE(exp4, obs4, dat_dim = 'dataset', memb_dim = 'member')$mse),
  c(0.6775320, 0.8954404)^2,
  tolerance = 0.0001
  )
  expect_equal(
  c(MSE(exp4, obs4, dat_dim = 'dataset', memb_dim = 'member')$conf.lower),
  c(0.3074949, 0.5370958),
  tolerance = 0.0001
  )
  expect_equal(
  c(MSE(exp4, obs4, dat_dim = 'dataset', memb_dim = 'member')$conf.upper),
  c(1.474804, 2.576013),
  tolerance = 0.0001
  )


})

##############################################

