
test_that("guide_legend_base can parse different designs", {

  guide <- guide_legend_base()
  expect_null(guide$params$design)

  example_design <- matrix(1L:4L, nrow = 2L, byrow = TRUE)

  guide <- guide_legend_base(design = example_design)
  expect_identical(guide$params$design, example_design)

  guide <- guide_legend_base(design = "AB\nCD")
  expect_equal(guide$params$design, example_design, ignore_attr = TRUE)

  guide <- guide_legend_base(design = 1L:4L)
  expect_identical(guide$params$design, as.matrix(1L:4L))

  # Check warning is emitted when there is a conflict
  expect_warning(
    guide_legend_base(design = example_design, ncol = 2L),
    "`ncol` argument is ignored"
  )

  # Check error is thrown when design is invalid
  expect_error(
    guide_legend_base(design = "AB\nCDE"),
    "must be rectangular"
  )

})

test_that("design application is correct", {

  data <- data.frame(value = 1L:8L)

  # Default horizontal
  test <- apply_design(data, direction = "horizontal")
  expect_identical(
    test,
    data.frame(
      value = 1L:8L,
      .index = 1L:8L,
      .row = rep(1L:2L, 4L),
      .col = rep(1L:4L, each = 2L)
    )
  )

  # Default vertical
  test <- apply_design(data, direction = "vertical")
  expect_identical(
    test,
    data.frame(value = 1L:8L, .index = 1L:8L, .row = 1L:8L, .col = rep(1L, 8L))
  )

  # Vertical with fixed columns
  test <- apply_design(data, ncol = 2L, direction = "vertical")
  expect_identical(
    test,
    data.frame(
      value = 1L:8L,
      .index = 1L:8L,
      .row = rep(1L:4L, 2L),
      .col = rep(1L:2L, each = 4L)
    )
  )

  # Custom design
  design <- matrix(c(1L:3L, 8L, NA, 4L, 7L:5L), nrow = 3L)
  test <- apply_design(data, design = design)
  expect_identical(
    test,
    data.frame(
      value  = c(1L, 2L, 3L, 8L, 4L, 7L, 6L, 5L),
      .index = c(1L, 2L, 3L, 8L, 4L, 7L, 6L, 5L),
      .row   = c(1L, 2L, 3L, 1L, 3L, 1L, 2L, 3L),
      .col   = rep(1L:3L, c(3L, 2L, 3L))
    )
  )

  # Warning about flawed design
  design <- matrix(c(1L:3L, NA, NA, 4L, 7L:5L), nrow = 3L)
  expect_warning(
    apply_design(data, design = design),
    "insufficient levels"
  )

  # Warning about flawed ncol/nrow
  expect_warning(
    apply_design(data, nrow = 2L, ncol = 2L),
    "insufficient levels"
  )
})

test_that("guide_legend_base can draw a custom design", {

  design <- "1#7\n2#6\n345"

  df <- data.frame(x = LETTERS[1L:7L])

  p <- ggplot(df, aes(x, x, fill = x)) +
    geom_tile()

  vdiffr::expect_doppelganger(
    "standard legend design",
    p + guides(fill = guide_legend_base())
  )

  vdiffr::expect_doppelganger(
    "custom legend design",
    p + guides(fill = guide_legend_base(design = design))
  )
})
