context("s2dv::Clim tests")

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

  # dat3
  set.seed(1)
  exp3 <- array(rnorm(120), dim = c(dat = 1, ensemble = 3, date = 5,
                                    lon = 2, lat = 4))
  set.seed(2)
  obs3 <- array(rnorm(40), dim = c(dat = 1, ensemble = 1,
                                    lon = 2, lat = 4, date = 5))

  # dat4
  set.seed(1)
  exp4 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5))
  set.seed(2)
  obs4 <- array(rnorm(10), dim = c(dataset = 1, member = 1, sdate = 5))

  # dat5
  set.seed(1)
  exp5 <- array(rnorm(30), dim = c(member = 3, sdate = 5))
  set.seed(2)
  obs5 <- array(rnorm(10), dim = c(member = 1, sdate = 5))

  # dat6
  set.seed(1)
  exp6 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5))
  set.seed(2)
  obs6 <- array(rnorm(10), dim = c(dataset = 1, sdate = 5))

  # dat7
  set.seed(1)
  exp7 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5))
  set.seed(2)
  obs7 <- array(rnorm(10), dim = c(sdate = 5))

  # dat8
  set.seed(1)
  exp8 <- array(rnorm(30), dim = c(member = 3, sdate = 5))
  set.seed(2)
  obs8 <- array(rnorm(10), dim = c(sdate = 5))

  # dat9
  set.seed(1)
  exp9 <- array(rnorm(30), dim = c(sdate = 5))
  set.seed(2)
  obs9 <- array(rnorm(10), dim = c(sdate = 5))


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

  expect_error(
  Clim(c(), c()),
  "Parameter 'exp' and 'obs' cannot be NULL."
  )
  expect_error(
  Clim(c('b'), c('a')),
  "Parameter 'exp' and 'obs' must be a numeric array."
  )
  expect_error(
  Clim(c(1:10), c(2:4)),
  paste0("Parameter 'exp' and 'obs' must be at least two dimensions ",
         "containing time_dim and dat_dim.")
  )
  expect_error(
  Clim(array(1:10, dim = c(2, 5)), array(1:4, dim = c(2, 2))),
  "Parameter 'exp' and 'obs' must have dimension names."
  )
  expect_error(
  Clim(exp1, obs1, method = TRUE),
  "Parameter 'method' must be one of 'clim', 'kharin' or 'NDV'."
  )
  expect_error(
  Clim(exp1, obs1, time_dim = c('sdate','ftime')),
  "Parameter 'time_dim' must be a character string."
  )
  expect_error(
  Clim(exp1, obs1, time_dim = 'asd'),
  "Parameter 'time_dim' is not found in 'exp' or 'obs' dimension."
  )
  expect_error(
  Clim(exp1, obs1, dat_dim = c(1,2)),
  "Parameter 'dat_dim' must be a character vector."
  )
  expect_error(
  Clim(exp1, obs1, dat_dim = c('member', 'dat')),
  "Parameter 'dat_dim' is not found in 'exp' dimensions."
  )
  expect_error(
  Clim(exp1, obs1, method = 'NDV', ftime_dim = 4),
  "Parameter 'ftime_dim' must be a character string."
  )
  expect_error(
  Clim(exp3, obs3, time_dim = "date", dat_dim = c("dat", "ensemble"),  method = 'NDV'),
  "Parameter 'ftime_dim' is not found in 'exp' or 'obs' dimension."
  )
  expect_error(
  Clim(exp1, obs1, memb = 'member'),
  "Parameter 'memb' must be one logical value."
  )
  expect_error(
  Clim(exp1, obs1, memb = FALSE, memb_dim = c('dataset', 'member')),
  "Parameter 'memb_dim' must be a character string."
  )
  expect_error(
  Clim(exp1, obs1, memb = FALSE, memb_dim = 'memb'),
  "Parameter 'memb_dim' is not found in 'exp' dimension."
  )
  expect_error(
  Clim(exp1, obs1, na.rm = na.omit),
  "Parameter 'na.rm' must be one logical value."
  )
  expect_error(
  Clim(exp1, obs1, ncores = T),
  "Parameter 'ncores' must be a positive integer."
  )
  expect_error(
  Clim(array(1:10, dim = c(dataset = 2, member = 5, sdate = 4, ftime = 3)), 
       array(1:4, dim = c(dataset = 2, member = 2, sdate = 5, ftime = 3))),
  "Parameter 'exp' and 'obs' must have the same dimensions expect 'dat_dim'."
  )

})

##############################################
test_that("2. Output checks: dat1", {

  # dimension
  expect_equal(
    dim(Clim(exp1, obs1)$clim_exp),
    c(dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1)$clim_obs),
    c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1, memb = FALSE)$clim_exp),
    c(dataset = 1, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1, memb = FALSE)$clim_obs),
    c(dataset = 1, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1, time_dim = 'lon')$clim_exp),
    c(dataset = 1, member = 3, sdate = 5, ftime = 3, lat = 4)
  )
  # clim_exp
  expect_equal(
    (Clim(exp1, obs1, memb = TRUE)$clim_exp)[1:5],
     c(0.10592542, 0.10971142, 0.08689170, 0.14149945, 0.02359945),
     tolerance = 0.001
  )
  expect_equal(
    (Clim(exp1, obs1, memb = FALSE)$clim_exp)[1:5],
     c(0.10084284, 0.06407350, 0.09028584, 0.17526332, 0.18004387),
     tolerance = 0.001
  )
  expect_equal(
    max(Clim(exp1, obs1)$clim_exp, na.rm = T),
    1.026186,
    tolerance = 0.001
  )
  # clim_obs
  expect_equal(
    (Clim(exp1, obs1)$clim_obs)[1:5],
     c(0.14831161, -0.60462627, 0.06609153, -0.23378059, 0.50553522),
     tolerance = 0.001
  )
  expect_equal(
    (Clim(exp1, obs1, memb = F)$clim_obs)[1:5],
     c(0.14831161, -0.60462627, 0.06609153, -0.23378059, 0.50553522),
     tolerance = 0.001
  )

  # method = 'kharin'
  expect_equal(
    dim(Clim(exp1, obs1, method = 'kharin')$clim_exp),
    c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1, method = 'kharin')$clim_obs),
    c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    max(Clim(exp1, obs1, method = 'kharin')$clim_exp, na.rm = T),
    2.282634,
    tolerance = 0.001
  )

  # method = 'NDV'
  expect_equal(
    dim(Clim(exp1, obs1, method = 'NDV')$clim_exp),
    c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    dim(Clim(exp1, obs1, method = 'NDV')$clim_obs),
    c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4)
  )
  expect_equal(
    min(Clim(exp1, obs1, method = 'NDV')$clim_exp, na.rm = T),
    -4.025745,
    tolerance = 0.001
  )

})

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

  expect_equal(
    (Clim(exp2, obs2)$clim_obs)[1:5],
     c(0.23142987, -0.60462627, -0.03669491, -0.14193572, 0.61163024),
     tolerance = 0.001
  )
  expect_equal(
    (Clim(exp2, obs2)$clim_exp)[1:5],
     c(0.01054951, -0.04744191, -0.03533071, 0.14149945, 0.02359945),
     tolerance = 0.001
  )
  expect_equal(
    length(which(is.na(Clim(exp2, obs2, na.rm = FALSE)$clim_exp))),
    57
  )
  expect_equal(
    length(which(is.na(Clim(exp2, obs2, na.rm = FALSE)$clim_obs))),
    19
  )
  expect_equal(
    length(which(is.na(Clim(exp2, obs2)$clim_obs))),
    0
  )

})

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

  expect_equal(
    (Clim(exp3, obs3, time_dim = 'date', dat_dim = c('dat', 'ensemble'))$clim_obs)[1:5],
     c(0.6094532, -0.5307990, 0.5437774, -0.1817153, 0.1368191),
     tolerance = 0.00001
  )
  expect_equal(
    (Clim(exp3, obs3, time_dim = 'date', dat_dim = c('dat', 'ensemble'))$clim_exp)[1:5],
     c(0.10592542, 0.10971142, 0.08689170, 0.14149945, 0.02359945),
     tolerance = 0.00001
  )

})


##############################################
test_that("5. Output checks: dat4", {
res1 <- Clim(exp4, obs4, memb = T)
res2 <- Clim(exp4, obs4, memb = F)
expect_equal(
dim(res1$clim_exp),
c(dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1, member = 1)
)
expect_equal(
dim(res2$clim_exp),
c(dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1)
)
expect_equal(
as.vector(res1$clim_exp),
c(0.1059254, 0.1097114, 0.0868917),
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1008428,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)
# method = 'kharin'
res1 <- Clim(exp4, obs4, memb = T, method = 'kharin')
res2 <- Clim(exp4, obs4, memb = F, method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1, member = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1)
)

# method = 'NDV'
exp4 <- array(exp4, dim = c(dim(exp4), ftime = 1))
obs4 <- array(obs4, dim = c(dim(obs4), ftime = 1))
res1 <- Clim(exp4, obs4, memb = T, method = 'NDV')
res2 <- Clim(exp4, obs4, memb = F, method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1, member = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1, ftime = 1)
)

})


##############################################
test_that("6. Output checks: dat5", {
res1 <- Clim(exp5, obs5, dat_dim = 'member', memb = T)
res2 <- Clim(exp5, obs5, dat_dim = 'member', memb = F)
expect_equal(
dim(res1$clim_exp),
c(member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(member = 1)
)
expect_equal(
dim(res2$clim_exp),
NULL
)
expect_equal(
dim(res2$clim_obs),
NULL
)
expect_equal(
as.vector(res1$clim_exp),
c(0.1059254, 0.1097114, 0.0868917),
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1008428,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)

# method = 'kharin'
res1 <- Clim(exp5, obs5, memb = T, dat_dim = 'member', method = 'kharin')
res2 <- Clim(exp5, obs5, memb = F, dat_dim = 'member', method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(member = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5)
)
expect_equal(
dim(res2$clim_obs),
NULL
)

# method = 'NDV'
exp5 <- array(exp5, dim = c(dim(exp5), ftime = 1))
obs5 <- array(obs5, dim = c(dim(obs5), ftime = 1))
res1 <- Clim(exp5, obs5, memb = T, dat_dim = 'member', method = 'NDV')
res2 <- Clim(exp5, obs5, memb = F, dat_dim = 'member', method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, member = 3, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(member = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(ftime = 1)
)

})

##############################################
test_that("7. Output checks: dat6", {
res1 <- Clim(exp6, obs6, memb = T)
res2 <- Clim(exp6, obs6, memb = F)
expect_equal(
dim(res1$clim_exp),
c(dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1)
)
expect_equal(
dim(res2$clim_exp),
c(dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1)
)
expect_equal(
as.vector(res1$clim_exp),
c(0.1059254, 0.1097114, 0.0868917),
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1008428,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)

# method = 'kharin'
res1 <- Clim(exp6, obs6, memb = T, method = 'kharin')
res2 <- Clim(exp6, obs6, memb = F, method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1)
)

# method = 'NDV'
exp6 <- array(exp6, dim = c(dim(exp6), ftime = 1))
obs6 <- array(obs6, dim = c(dim(obs6), ftime = 1))
res1 <- Clim(exp6, obs6, memb = T, method = 'NDV')
res2 <- Clim(exp6, obs6, memb = F, method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(dataset = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(dataset = 1, ftime = 1)
)

})

##############################################
test_that("8. Output checks: dat7", {
res1 <- Clim(exp7, obs7, memb = T)
res2 <- Clim(exp7, obs7, memb = F)
expect_equal(
dim(res1$clim_exp),
c(dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
c(dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
NULL
)
expect_equal(
as.vector(res1$clim_exp),
c(0.1059254, 0.1097114, 0.0868917),
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1008428,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)

# method = 'kharin'
res1 <- Clim(exp7, obs7, memb = T, method = 'kharin')
res2 <- Clim(exp7, obs7, memb = F, method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3)
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1)
)
expect_equal(
dim(res2$clim_obs),
NULL
)

# method = 'NDV'
exp7 <- array(exp7, dim = c(dim(exp7), ftime = 1))
obs7 <- array(obs7, dim = c(dim(obs7), ftime = 1))
res1 <- Clim(exp7, obs7, memb = T, method = 'NDV')
res2 <- Clim(exp7, obs7, memb = F, method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, dataset = 1, member = 3, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, dataset = 1, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(ftime = 1)
)


})


##############################################
test_that("9. Output checks: dat8", {
res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T)
res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F)
expect_equal(
dim(res1$clim_exp),
c(member = 3)
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
NULL
)
expect_equal(
dim(res2$clim_obs),
NULL
)
expect_equal(
as.vector(res1$clim_exp),
c(0.1059254, 0.1097114, 0.0868917),
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1008428,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)

# method = 'kharin'
res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T, method = 'kharin')
res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F, method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, member = 3)
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5)
)
expect_equal(
dim(res2$clim_obs),
NULL
)

# method = 'NDV'
exp8 <- array(exp8, dim = c(dim(exp8), ftime = 1))
obs8 <- array(obs8, dim = c(dim(obs8), ftime = 1))
res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T, method = 'NDV')
res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F, method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, member = 3, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(ftime = 1)
)

})

##############################################
test_that("10. Output checks: dat9", {
res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T)
res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F)
expect_equal(
dim(res1$clim_exp),
NULL
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
NULL
)
expect_equal(
dim(res2$clim_obs),
NULL
)
expect_equal(
as.vector(res1$clim_exp),
0.1292699,
tolerance = 0.0001
)
expect_equal(
as.vector(res1$clim_obs),
-0.06696949,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_exp),
0.1292699,
tolerance = 0.0001
)
expect_equal(
as.vector(res2$clim_obs),
-0.06696949,
tolerance = 0.0001
)

# method = 'kharin'
res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T, method = 'kharin')
res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F, method = 'kharin')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5)
)
expect_equal(
dim(res1$clim_obs),
NULL
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5)
)
expect_equal(
dim(res2$clim_obs),
NULL
)

# method = 'NDV'
exp9 <- array(exp9, dim = c(dim(exp9), ftime = 1))
obs9 <- array(obs9, dim = c(dim(obs9), ftime = 1))
res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T, method = 'NDV')
res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F, method = 'NDV')
expect_equal(
dim(res1$clim_exp),
c(sdate = 5, ftime = 1)
)
expect_equal(
dim(res1$clim_obs),
c(ftime = 1)
)
expect_equal(
dim(res2$clim_exp),
c(sdate = 5, ftime = 1)
)
expect_equal(
dim(res2$clim_obs),
c(ftime = 1)
)


})

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