test_that("predict classification - no submodels - no calibration", {
  skip_if_not_installed("modeldata")

  cls <- make_post_data()

  pca_rec <- recipe(class ~ ., data = cls$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  wflow <- workflow(pca_rec, logistic_reg())
  grd <- tibble()

  wflow_fit <- fit(wflow, cls$data)

  class_only <- metric_set(accuracy)
  prob_only <- metric_set(brier_class)
  both_types <- metric_set(brier_class, accuracy)

  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  fac_0 <- factor(levels = levels(cls$data$class))

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------
  # Only predict classes

  static_class <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = class_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_class <- tune:::update_static(static_class, data_1)
  static_class$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_class)

  class_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_class,
    submodel_grid = NULL
  )

  expect_equal(
    class_res[0, ],
    tibble(.pred_class = fac_0, .row = integer(0), class = fac_0)
  )
  expect_equal(nrow(class_res), nrow(assessment(cls$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # Only predict probabilities

  static_prob <- tune:::.make_static(
    wflow,
    pred_df_1,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = prob_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_prob <- tune:::update_static(static_prob, data_1)
  static_prob$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_prob)

  prob_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_prob,
    submodel_grid = NULL
  )

  expect_equal(
    prob_res[0, ],
    tibble(
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      .row = integer(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res), nrow(assessment(cls$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # Both prediction types

  static_both <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = both_types,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_both <- tune:::update_static(static_both, data_1)
  static_both$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_both)

  both_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_both,
    submodel_grid = NULL
  )

  expect_equal(
    both_res[0, ],
    tibble(
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(both_res), nrow(assessment(cls$rs$splits[[1]])))
})

test_that("predict classification - no submodels - with calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("probably")
  skip_if_not_installed("mgcv")

  cls <- make_post_data()

  pca_rec <- recipe(class ~ ., data = cls$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  cal_pst <- tailor() |> adjust_probability_calibration()

  wflow <- workflow(pca_rec, logistic_reg(), cal_pst)
  wflow_fit <- fit(wflow, cls$data, data_calibration = cls$data)
  grd <- tibble()

  class_only <- metric_set(accuracy)
  prob_only <- metric_set(brier_class)
  both_types <- metric_set(brier_class, accuracy)

  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  fac_0 <- factor(levels = levels(cls$data$class))

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------
  # Only predict classes

  static_class <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = class_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_class <- tune:::update_static(static_class, data_1)
  static_class$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_class)

  class_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_class,
    submodel_grid = NULL
  )

  expect_equal(
    class_res_prd[0, ],
    tibble(
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(class_res_prd), nrow(data_1$pred$data))

  # ----------------------------------------------------------------------------
  # Only predict probabilities

  static_prob <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = prob_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_prob <- tune:::update_static(static_prob, data_1)
  static_prob$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_prob)

  prob_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_prob,
    submodel_grid = NULL
  )

  expect_equal(
    prob_res_prd[0, ],
    tibble(
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res_prd), nrow(data_1$pred$data))

  # ----------------------------------------------------------------------------
  # Both prediction types

  static_both <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = both_types,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_both <- tune:::update_static(static_both, data_1)
  static_both$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_both)

  both_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_both,
    submodel_grid = NULL
  )

  expect_equal(
    both_res_prd[0, ],
    tibble(
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res_prd), nrow(data_1$pred$data))
})

test_that("predict classification - with submodels - no calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("kknn")

  cls <- make_post_data()

  pca_rec <- recipe(class ~ ., data = cls$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  knn_cls_spec <- parsnip::nearest_neighbor(
    mode = "classification",
    neighbors = 12
  )

  five_neighbors <- tibble(neighbors = 5)

  wflow <- workflow(pca_rec, knn_cls_spec)
  wflow_fit <- fit(wflow, cls$data)
  grd <- tibble()

  class_only <- metric_set(accuracy)
  prob_only <- metric_set(brier_class)
  both_types <- metric_set(brier_class, accuracy)

  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  fac_0 <- factor(levels = levels(cls$data$class))

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------
  # Only predict classes

  static_class <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = class_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_class <- tune:::update_static(static_class, data_1)
  static_class$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_class)

  class_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_class,
    submodel_grid = five_neighbors
  )

  expect_equal(
    class_res[0, ],
    tibble(
      neighbors = double(0),
      .pred_class = fac_0,
      .row = integer(0),
      class = fac_0
    )
  )
  expect_equal(nrow(class_res), nrow(assessment(cls$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # Only predict probabilities

  static_prob <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = prob_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_prob <- tune:::update_static(static_prob, data_1)
  static_prob$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_prob)

  prob_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_prob,
    submodel_grid = five_neighbors
  )

  expect_equal(
    prob_res[0, ],
    tibble(
      neighbors = double(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      .row = integer(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res), nrow(assessment(cls$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # Both prediction types

  static_both <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = both_types,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_both <- tune:::update_static(static_both, data_1)
  static_both$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_both)

  both_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_both,
    submodel_grid = five_neighbors
  )

  expect_equal(
    both_res[0, ],
    tibble(
      neighbors = double(0),
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(both_res), nrow(assessment(cls$rs$splits[[1]])))
})

test_that("predict classification - with submodels - with calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("kknn")
  skip_if_not_installed("probably")
  skip_if_not_installed("mgcv")

  cls <- make_post_data()

  pca_rec <- recipe(class ~ ., data = cls$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  knn_cls_spec <- parsnip::nearest_neighbor(
    mode = "classification",
    neighbors = 12
  )

  five_neighbors <- tibble(neighbors = 5)

  cal_pst <- tailor() |> adjust_probability_calibration()

  wflow <- workflow(pca_rec, knn_cls_spec, cal_pst)
  wflow_fit <- fit(wflow, cls$data, data_calibration = cls$data)
  grd <- tibble()

  class_only <- metric_set(accuracy)
  prob_only <- metric_set(brier_class)
  both_types <- metric_set(brier_class, accuracy)

  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  fac_0 <- factor(levels = levels(cls$data$class))

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------
  # Only predict classes

  static_class <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = class_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_class <- tune:::update_static(static_class, data_1)
  static_class$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_class)

  class_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_class,
    submodel_grid = five_neighbors
  )

  expect_equal(
    class_res_prd[0, ],
    tibble(
      neighbors = double(0),
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(class_res_prd), nrow(data_1$pred$data))

  # ----------------------------------------------------------------------------
  # Only predict probabilities

  static_prob <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = prob_only,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_prob <- tune:::update_static(static_prob, data_1)
  static_prob$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_prob)

  prob_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_prob,
    submodel_grid = five_neighbors
  )

  expect_equal(
    prob_res_prd[0, ],
    tibble(
      neighbors = double(0),
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res_prd), nrow(data_1$pred$data))

  # ----------------------------------------------------------------------------
  # Both prediction types

  static_both <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = both_types,
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )

  static_both <- tune:::update_static(static_both, data_1)
  static_both$y_name <- "class"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_both)

  both_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_both,
    submodel_grid = five_neighbors
  )

  expect_equal(
    both_res_prd[0, ],
    tibble(
      neighbors = double(0),
      .pred_class = fac_0,
      .row = integer(0),
      .pred_class_1 = double(0),
      .pred_class_2 = double(0),
      class = fac_0
    )
  )
  expect_equal(nrow(prob_res_prd), nrow(data_1$pred$data))
})

test_that("predict regression - no submodels - no calibration", {
  skip_if_not_installed("modeldata")

  reg <- make_post_data(mode = "regression")

  pca_rec <- recipe(outcome ~ ., data = reg$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  wflow <- workflow(pca_rec, linear_reg())
  wflow_fit <- fit(wflow, reg$data)
  grd <- tibble()

  reg_mtr <- metric_set(rmse)

  data_1 <- tune:::.get_data_subsets(wflow, reg$rs$splits[[1]], reg$args)

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = reg_mtr,
    eval_time = NULL,
    split_args = reg$args,
    control = ctrl
  )

  static <- tune:::update_static(static, data_1)
  static$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static)

  class_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static,
    submodel_grid = NULL
  )

  expect_equal(
    class_res[0, ],
    tibble(.pred = double(0), .row = integer(0), outcome = double(0))
  )
  expect_equal(nrow(class_res), nrow(assessment(reg$rs$splits[[1]])))
})

test_that("predict regression - no submodels - with calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("probably")
  skip_if_not_installed("mgcv")

  reg <- make_post_data(mode = "regression")

  pca_rec <- recipe(outcome ~ ., data = reg$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  reg_pst <- tailor() |> adjust_numeric_calibration()

  wflow <- workflow(pca_rec, linear_reg(), reg_pst)
  wflow_fit <- fit(wflow, reg$data, data_calibration = reg$data)
  grd <- tibble()

  reg_mtr <- metric_set(rmse)

  data_1 <- tune:::.get_data_subsets(wflow, reg$rs$splits[[1]], reg$args)

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = reg_mtr,
    eval_time = NULL,
    split_args = reg$args,
    control = ctrl
  )

  static <- tune:::update_static(static, data_1)
  static$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static)

  class_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static,
    submodel_grid = NULL
  )

  expect_equal(
    class_res_prd[0, ],
    tibble(
      .pred = double(0),
      .row = integer(0),
      outcome = double(0)
    )
  )
  expect_equal(nrow(class_res_prd), nrow(data_1$pred$data))
})

test_that("predict regression - with submodels - no calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("kknn")

  reg <- make_post_data(mode = "regression")

  pca_rec <- recipe(outcome ~ ., data = reg$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  knn_reg_spec <- parsnip::nearest_neighbor(
    mode = "regression",
    neighbors = 12
  )

  five_neighbors <- tibble(neighbors = 5)

  wflow <- workflow(pca_rec, knn_reg_spec)
  wflow_fit <- fit(wflow, reg$data)

  reg_mtr <- metric_set(rmse)

  data_1 <- tune:::.get_data_subsets(wflow, reg$rs$splits[[1]], reg$args)

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = tibble(),
    metrics = reg_mtr,
    eval_time = NULL,
    split_args = reg$args,
    control = ctrl
  )

  static <- tune:::update_static(static, data_1)
  static$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static)

  class_res <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static,
    submodel_grid = five_neighbors
  )

  expect_equal(
    class_res[0, ],
    tibble(
      neighbors = double(0),
      .pred = double(0),
      .row = integer(0),
      outcome = double(0)
    )
  )
  expect_equal(nrow(class_res), nrow(assessment(reg$rs$splits[[1]])))
})

test_that("predict regression - with submodels - with calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("kknn")
  skip_if_not_installed("probably")
  skip_if_not_installed("mgcv")

  reg <- make_post_data(mode = "regression")

  pca_rec <- recipe(outcome ~ ., data = reg$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  knn_reg_spec <- parsnip::nearest_neighbor(
    mode = "regression",
    neighbors = 12
  )

  five_neighbors <- tibble(neighbors = 5)

  reg_pst <- tailor() |> adjust_numeric_calibration()

  wflow <- workflow(pca_rec, knn_reg_spec, reg_pst)
  wflow_fit <- fit(wflow, reg$data, data_calibration = reg$data)

  reg_mtr <- metric_set(rmse)

  data_1 <- tune:::.get_data_subsets(wflow, reg$rs$splits[[1]], reg$args)

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = tibble(),
    metrics = reg_mtr,
    eval_time = NULL,
    split_args = reg$args,
    control = ctrl
  )

  static <- tune:::update_static(static, data_1)
  static$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static)

  class_res_prd <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static,
    submodel_grid = five_neighbors
  )

  expect_equal(
    class_res_prd[0, ],
    tibble(
      neighbors = double(0),
      .pred = double(0),
      .row = integer(0),
      outcome = double(0)
    )
  )
  expect_equal(nrow(class_res_prd), nrow(data_1$pred$data))
})

test_that("predict censored regression - no submodels - no calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("censored")
  skip_if_not_installed("survival")

  library(censored)

  cens <- make_post_data(mode = "censored")

  pca_rec <- recipe(outcome ~ ., data = cens$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  wflow <- workflow(pca_rec, survival_reg())
  wflow_fit <- fit(wflow, cens$data)
  grd <- tibble()

  mtr_stc <- metric_set(concordance_survival)
  mtr_dyn <- metric_set(brier_survival)
  mtr_int <- metric_set(brier_survival_integrated)
  mtr_all <- metric_set(
    concordance_survival,
    brier_survival,
    brier_survival_integrated
  )

  .times <- c(15, 25)

  data_1 <- tune:::.get_data_subsets(wflow, cens$rs$splits[[1]], cens$args)

  ctrl <- tune::control_grid()

  # ----------------------------------------------------------------------------
  # static metrics

  static_stc <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = mtr_stc,
    eval_time = .times,
    split_args = cens$args,
    control = ctrl
  )

  static_stc <- tune:::update_static(static_stc, data_1)
  static_stc$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_stc)

  res_stc <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_stc,
    submodel_grid = NULL
  )

  expect_equal(
    res_stc[0, ],
    tibble(.pred_time = numeric(0), .row = integer(0), outcome = surv_0)
  )
  expect_equal(nrow(res_stc), nrow(assessment(cens$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # dynamic metrics

  static_dyn <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = mtr_dyn,
    eval_time = .times,
    split_args = cens$args,
    control = ctrl
  )

  static_dyn <- tune:::update_static(static_dyn, data_1)
  static_dyn$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_dyn)

  res_dyn <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_dyn,
    submodel_grid = NULL
  )

  expect_equal(
    res_dyn[0, ],
    tibble(.pred = list(), .row = integer(0), outcome = surv_0)
  )

  expect_equal(
    res_dyn$.pred[[1]][0, ],
    pred_dyn_0
  )
  expect_equal(nrow(res_dyn), nrow(assessment(cens$rs$splits[[1]])))
})

# TODO put this in extratests
test_that("predict censored regression - submodels - no calibration", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("censored")
  skip_if_not_installed("survival")
  skip_if_not_installed("glmnet")

  library(censored)

  cens <- make_post_data(mode = "censored")

  pca_rec <- recipe(outcome ~ ., data = cens$data) |>
    step_pca(all_numeric_predictors(), num_comp = 2)

  glmn_cens <- proportional_hazards(penalty = tune()) |> set_engine("glmnet")

  wflow <- workflow(pca_rec, glmn_cens)

  grd <-
    wflow |>
    extract_parameter_set_dials() |>
    grid_space_filling(size = 3)

  mtr_stc <- metric_set(concordance_survival)
  mtr_dyn <- metric_set(brier_survival)
  mtr_int <- metric_set(brier_survival_integrated)
  mtr_all <- metric_set(
    concordance_survival,
    brier_survival,
    brier_survival_integrated
  )

  .times <- c(15, 25)

  data_1 <- tune:::.get_data_subsets(wflow, cens$rs$splits[[1]], cens$args)

  ctrl <- tune::control_grid()

  wflow_fit <-
    wflow |>
    finalize_workflow(grd[1, ]) |>
    fit(cens$data)

  # ----------------------------------------------------------------------------
  # static metrics

  static_stc <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = mtr_stc,
    eval_time = .times,
    split_args = cens$args,
    control = ctrl
  )

  static_stc <- tune:::update_static(static_stc, data_1)
  static_stc$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_stc)

  res_stc <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_stc,
    submodel_grid = NULL
  )

  expect_equal(
    res_stc[0, ],
    tibble(.pred_time = numeric(0), .row = integer(0), outcome = surv_0)
  )
  expect_equal(nrow(res_stc), nrow(assessment(cens$rs$splits[[1]])))

  # ----------------------------------------------------------------------------
  # dynamic metrics

  static_dyn <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = grd,
    metrics = mtr_dyn,
    eval_time = .times,
    split_args = cens$args,
    control = ctrl
  )

  static_dyn <- tune:::update_static(static_dyn, data_1)
  static_dyn$y_name <- "outcome"
  pred_df_1 <- tune:::process_prediction_data(wflow_fit, static_dyn)

  res_dyn <- tune:::predict_all_types(
    wflow_fit,
    pred_df_1,
    static_dyn,
    submodel_grid = NULL
  )

  expect_equal(
    res_dyn[0, ],
    tibble(.pred = list(), .row = integer(0), outcome = surv_0)
  )

  expect_equal(
    res_dyn$.pred[[1]][0, ],
    pred_dyn_0
  )
  expect_equal(nrow(res_dyn), nrow(assessment(cens$rs$splits[[1]])))
})

# ------------------------------------------------------------------------------
# Row availability checks

test_that("process_prediction_data errors when recipe drops rows", {
  skip_if_not_installed("modeldata")

  cls <- make_post_data()

  filter_rec <- recipe(class ~ ., data = cls$data) |>
    step_filter(non_linear_1 > 0, skip = FALSE)

  wflow <- workflow(filter_rec, logistic_reg())
  wflow_fit <- fit(wflow, cls$data)

  ctrl <- tune::control_grid()
  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = tibble(),
    metrics = metric_set(accuracy),
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )
  static <- tune:::update_static(static, data_1)

  expect_snapshot(
    tune:::process_prediction_data(wflow_fit, static),
    error = TRUE
  )
})

test_that("process_prediction_data errors when recipe drops calibration rows", {
  skip_if_not_installed("modeldata")
  skip_if_not_installed("probably")

  cls <- make_post_data()

  filter_rec <- recipe(class ~ ., data = cls$data) |>
    step_filter(non_linear_1 > 0, skip = FALSE)

  wflow <- workflow(filter_rec, logistic_reg(), cls_est_post)
  # TODO just use cls$data
  # after https://github.com/tidymodels/workflows/issues/315 is fixed
  wflow_fit <- fit(
    wflow,
    data = cls$data,
    data_calibration = cls$data |> filter(non_linear_1 > 0)
  )

  ctrl <- tune::control_grid()
  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = tibble(),
    metrics = metric_set(accuracy),
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )
  static <- tune:::update_static(static, data_1)

  expect_snapshot(
    tune:::process_prediction_data(wflow_fit, static, source = "cal"),
    error = TRUE
  )
})

test_that("process_prediction_data errors when non-recipe preprocessor drops rows", {
  skip_if_not_installed("modeldata")

  cls <- make_post_data()

  wflow <- workflow(class ~ ., logistic_reg())
  wflow_fit <- fit(wflow, cls$data)

  ctrl <- tune::control_grid()
  data_1 <- tune:::.get_data_subsets(wflow, cls$rs$splits[[1]], cls$args)

  static <- tune:::.make_static(
    wflow,
    param_info = wflow |> extract_parameter_set_dials(),
    grid = tibble(),
    metrics = metric_set(accuracy),
    eval_time = NULL,
    split_args = cls$args,
    control = ctrl
  )
  static <- tune:::update_static(static, data_1)

  local_mocked_bindings(
    forge_from_workflow = function(new_data, workflow) {
      res <- hardhat::forge(
        new_data,
        workflow$pre$mold$blueprint,
        outcomes = TRUE
      )
      res$predictors <- res$predictors[1:5, ]
      res
    }
  )

  expect_snapshot(
    tune:::process_prediction_data(wflow_fit, static),
    error = TRUE
  )
})
