test_that("missing argument fails", {
  f <- function(z) {
    check_missing(z)
  }
  expect_error(
    f(),
    "Argument `z` is missing\\."
  )
})

test_that("missing values fail", {
  f <- function(z) {
    check_na(z)
  }
  expect_error(
    f(c(1, 2, NA)),
    "Argument `z` must not contain missing values\\."
  )
})

test_that("invalid model type fails", {
  expect_error(
    check_model_type("unknown"),
    "Argument `type` must be either"
  )
})

test_that("invalid scaling options fail", {
  expect_error(
    check_model_scaling("unknown"),
    "Elements of `scaling` must be either"
  )
})

test_that("invalid class fails", {
  f <- function(z) {
    check_class(z, "test_class")
  }
  expect_error(
    f(z = 1),
    "Argument `z` must be a <test_class> object\\."
  )
})

test_that("non-sequence data tna fails", {
  f <- function(z) {
    check_tna_seq(z)
  }
  expect_error(
    f(z = mock_tna),
    "Argument `z` must be a <tna> object created from sequence data\\."
  )
})

test_that("invalid centrality measures fail", {
  expect_error(
    check_measures("unknown"),
    "Argument `measures` contains invalid centrality measures:"
  )
})

test_that("negative values fail", {
  opts <- expand.grid(
    type = c("integer", "numeric"),
    strict = c(FALSE, TRUE),
    scalar = c(FALSE, TRUE)
  )
  f <- function(i, z) {
    check_values(
      z,
      type = opts[i, 1],
      strict = opts[i, 2],
      scalar = opts[i, 3]
    )
  }
  expect_error(
    f(i = 1, z = -1),
    "Argument `z` must be a non-negative <integer> vector\\."
  )
  expect_error(
    f(i = 2, z = -1),
    "Argument `z` must be a non-negative <numeric> vector\\."
  )
  expect_error(
    f(i = 3, z = -1),
    "Argument `z` must be a positive <integer> vector\\."
  )
  expect_error(
    f(i = 4, z = -1),
    "Argument `z` must be a positive <numeric> vector\\."
  )
  expect_error(
    f(i = 5, z = -1),
    "Argument `z` must be a non-negative <integer>\\."
  )
  expect_error(
    f(i = 6, z = -1),
    "Argument `z` must be a non-negative <numeric> value\\."
  )
  expect_error(
    f(i = 7, z = -1),
    "Argument `z` must be a positive <integer>\\."
  )
  expect_error(
    f(i = 8, z = -1),
    "Argument `z` must be a positive <numeric> value\\."
  )
})

test_that("invalid range check fails", {
  opts <- expand.grid(
    type = c("integer", "numeric"),
    scalar = c(FALSE, TRUE)
  )
  f <- function(i, z) {
    check_range(
      z, type = opts[i, 1], scalar = opts[i, 2], lower = -2, upper = 2
    )
  }
  expect_error(
    f(i = 1, z = 3),
    "Argument `z` must only contain <integer> values between -2 and 2\\."
  )
  expect_error(
    f(i = 2, z = 4),
    "Argument `z` must only contain <numeric> values between -2 and 2\\."
  )
  expect_error(
    f(i = 3, z = -4),
    "Argument `z` must be a single <integer> between -2 and 2\\."
  )
  expect_error(
    f(i = 4, z = -3),
    "Argument `z` must be a single <numeric> value between -2 and 2\\."
  )
})

test_that("invalid logical fails", {
  f <- function(z) {
    check_flag(z)
  }
  expect_error(
    f(data.frame()),
    "Argument `z` must be a single <logical> value\\."
  )
})

test_that("cluster check fails on invalid clusters", {
  expect_error(
    check_clusters(mmm_model, i = 1, j = 1),
    "Arguments `i` and `j` must be different\\."
  )
  expect_error(
    check_clusters(mmm_model, i = 1, j = 4),
    "Argument `j` must be between 1 and 3 when of type <numeric>\\."
  )
  expect_error(
    check_clusters(mmm_model, i = c(2, 3), j = 1),
    "Argument `i` must be a <numeric> or a <character> vector of length 1\\."
  )
  expect_error(
    check_clusters(mmm_model, i = 1, j = "Cluster 4"),
    "Argument `j` must be a name of `x` when of type <character>\\."
  )
})

test_that("range check variants are correct", {
  value <- 1
  expect_error(
    check_range(value, lower = 2),
    "Argument `value` must be a single <numeric> value greater than or equal to 2\\."
  )
  expect_error(
    check_range(value, upper = 0),
    "Argument `value` must be a single <numeric> value less than or equal to 0\\."
  )
  expect_error(
    check_range(value, lower = -1, upper = 0),
    "Argument `value` must be a single <numeric> value between -1 and 0\\."
  )
})

test_that("check_numeric validates correctly", {
  f <- function(z) {
    check_numeric(z)
  }
  expect_error(
    f("not numeric"),
    "must be a single <numeric> value"
  )
  expect_error(
    f(c(1, 2, 3)),
    "must be a single <numeric> value"
  )
  expect_error(f(1), NA)
})

test_that("check_string validates correctly", {
  f <- function(z) {
    check_string(z)
  }
  expect_error(
    f(123),
    "must be a <character> vector of length 1"
  )
  expect_error(
    f(c("a", "b")),
    "must be a <character> vector of length 1"
  )
  expect_error(f("valid"), NA)
})

test_that("check_cols validates correctly", {
  expect_error(
    check_cols(missing_ok = FALSE),
    "is missing"
  )
  expect_error(
    check_cols(c("a", "b"), single = TRUE),
    "must provide a single column name"
  )
})

test_that("check_cluster validates correctly", {
  # Invalid character cluster
  expect_error(
    check_cluster(mmm_model, "NonExistent"),
    "must only contain names of"
  )
  # Invalid numeric cluster
  expect_error(
    check_cluster(mmm_model, 99),
    "must contain integers between"
  )
  # Valid cases
  expect_error(check_cluster(mmm_model, 1), NA)
  expect_error(check_cluster(mmm_model, "Cluster 1"), NA)
})

test_that("check_dots validates correctly", {
  expect_error(
    check_dots(invalid_arg = 1),
    "not recognized"
  )
  expect_error(
    check_dots(cols = 1:3),
    NA
  )
})
