library(testthat)
library(DataAudit)

#==========================================================
# validate_data()
#==========================================================

test_that("validate_data accepts data.frame", {

  expect_true(
    DataAudit:::validate_data(iris)
  )

})

test_that("validate_data accepts one-column data.frame", {

  dat <- data.frame(
    x = 1:10
  )

  expect_true(
    DataAudit:::validate_data(dat)
  )

})

test_that("validate_data accepts zero-row data.frame", {

  dat <- data.frame(
    x = numeric(0)
  )

  expect_true(
    DataAudit:::validate_data(dat)
  )

})

test_that("validate_data accepts tibble", {

  skip_if_not_installed("tibble")

  dat <- tibble::as_tibble(iris)

  expect_true(
    DataAudit:::validate_data(dat)
  )

})

test_that("validate_data rejects NULL", {

  expect_error(
    DataAudit:::validate_data(NULL),
    "'data' cannot be NULL"
  )

})

test_that("validate_data rejects numeric vector", {

  expect_error(
    DataAudit:::validate_data(1:10),
    "'data' must be a data.frame"
  )

})

test_that("validate_data rejects character vector", {

  expect_error(
    DataAudit:::validate_data(letters),
    "'data' must be a data.frame"
  )

})

test_that("validate_data rejects list", {

  expect_error(
    DataAudit:::validate_data(
      list(x = 1:10)
    ),
    "'data' must be a data.frame"
  )

})

test_that("validate_data rejects data.frame without variables", {

  expect_error(
    DataAudit:::validate_data(
      data.frame()
    ),
    "at least one variable"
  )

})


#==========================================================
# .validate_column()
#==========================================================

test_that(".validate_column accepts valid column", {

  expect_true(
    DataAudit:::.validate_column(
      iris,
      "Sepal.Length"
    )
  )

})

test_that(".validate_column rejects NULL column", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      NULL
    ),
    "single non-missing character string"
  )

})

test_that(".validate_column rejects numeric column argument", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      1
    ),
    "single non-missing character string"
  )

})

test_that(".validate_column rejects multiple names", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      c("Sepal.Length", "Sepal.Width")
    ),
    "single non-missing character string"
  )

})

test_that(".validate_column rejects NA", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      NA_character_
    ),
    "single non-missing character string"
  )

})

test_that(".validate_column rejects empty name", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      ""
    ),
    "'column' cannot be empty"
  )

})

test_that(".validate_column rejects unknown column", {

  expect_error(
    DataAudit:::.validate_column(
      iris,
      "ABC"
    ),
    "was not found"
  )

})


#==========================================================
# .validate_numeric_scalar()
#==========================================================

test_that(".validate_numeric_scalar accepts numeric scalar", {

  expect_true(
    DataAudit:::.validate_numeric_scalar(
      1.5,
      "cutoff"
    )
  )

})

test_that(".validate_numeric_scalar accepts integer scalar", {

  expect_true(
    DataAudit:::.validate_numeric_scalar(
      2L,
      "cutoff"
    )
  )

})

test_that(".validate_numeric_scalar rejects character value", {

  expect_error(
    DataAudit:::.validate_numeric_scalar(
      "1",
      "cutoff"
    ),
    "'cutoff' must be a single finite numeric value"
  )

})

test_that(".validate_numeric_scalar rejects multiple values", {

  expect_error(
    DataAudit:::.validate_numeric_scalar(
      c(1, 2),
      "cutoff"
    ),
    "single finite numeric value"
  )

})

test_that(".validate_numeric_scalar rejects NA", {

  expect_error(
    DataAudit:::.validate_numeric_scalar(
      NA_real_,
      "cutoff"
    ),
    "single finite numeric value"
  )

})

test_that(".validate_numeric_scalar rejects Inf", {

  expect_error(
    DataAudit:::.validate_numeric_scalar(
      Inf,
      "cutoff"
    ),
    "single finite numeric value"
  )

})

test_that(".validate_numeric_scalar rejects NaN", {

  expect_error(
    DataAudit:::.validate_numeric_scalar(
      NaN,
      "cutoff"
    ),
    "single finite numeric value"
  )

})


#==========================================================
# .validate_logical_scalar()
#==========================================================

test_that(".validate_logical_scalar accepts TRUE and FALSE", {

  expect_true(
    DataAudit:::.validate_logical_scalar(
      TRUE,
      "remove"
    )
  )

  expect_true(
    DataAudit:::.validate_logical_scalar(
      FALSE,
      "remove"
    )
  )

})

test_that(".validate_logical_scalar rejects numeric", {

  expect_error(
    DataAudit:::.validate_logical_scalar(
      1,
      "remove"
    ),
    "'remove' must be TRUE or FALSE"
  )

})

test_that(".validate_logical_scalar rejects NA", {

  expect_error(
    DataAudit:::.validate_logical_scalar(
      NA,
      "remove"
    ),
    "'remove' must be TRUE or FALSE"
  )

})

test_that(".validate_logical_scalar rejects multiple values", {

  expect_error(
    DataAudit:::.validate_logical_scalar(
      c(TRUE, FALSE),
      "remove"
    ),
    "'remove' must be TRUE or FALSE"
  )

})


#==========================================================
# .is_blank()
#==========================================================

test_that(".is_blank detects empty strings", {

  x <- c(
    "",
    " ",
    "   ",
    "A",
    NA
  )

  result <- DataAudit:::.is_blank(x)

  expect_equal(
    result,
    c(
      TRUE,
      TRUE,
      TRUE,
      FALSE,
      FALSE
    )
  )

})

test_that(".is_blank returns FALSE for numeric values", {

  expect_equal(
    DataAudit:::.is_blank(1:5),
    rep(FALSE, 5)
  )

})

test_that(".is_blank returns FALSE for logical values", {

  expect_equal(
    DataAudit:::.is_blank(
      c(TRUE, FALSE, NA)
    ),
    c(FALSE, FALSE, FALSE)
  )

})

test_that(".is_blank handles zero-length character vector", {

  expect_length(
    DataAudit:::.is_blank(
      character(0)
    ),
    0
  )

})
