diff --git a/tests/testthat/_snaps/constructor.md b/tests/testthat/_snaps/constructor.md index 224bee13..eb98eff3 100644 --- a/tests/testthat/_snaps/constructor.md +++ b/tests/testthat/_snaps/constructor.md @@ -29,3 +29,27 @@ Error in `new_model()`: ! `blueprint` must be a , not the number 1. +# `new_scalar()` must have elements + + Code + new_scalar(list()) + Condition + Error in `check_elems()`: + ! `elems` must be a list of length 1 or greater. + +# `new_scalar()` must have unique names + + Code + new_scalar(list(x = 1, x = 2)) + Condition + Error in `check_elems()`: + ! `elems` must have unique names. + +# `new_scalar()` must have no extra attributes + + Code + new_scalar(x) + Condition + Error in `check_elems()`: + ! `elems` must have no attributes (apart from names). + diff --git a/tests/testthat/_snaps/forge-formula.md b/tests/testthat/_snaps/forge-formula.md index b015313a..695a321d 100644 --- a/tests/testthat/_snaps/forge-formula.md +++ b/tests/testthat/_snaps/forge-formula.md @@ -1,3 +1,67 @@ +# asking for the outcome when it isn't there fails + + Code + forge(example_train2, x1$blueprint, outcomes = TRUE) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'fac_1'. + +--- + + Code + forge(example_train2, x2$blueprint, outcomes = TRUE) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'fac_1'. + +# new_data can only be a data frame / matrix + + Code + forge("hi", x1$blueprint) + Condition + Error in `forge()`: + ! The class of `new_data`, 'character', is not recognized. + +--- + + Code + forge("hi", x2$blueprint) + Condition + Error in `forge()`: + ! The class of `new_data`, 'character', is not recognized. + +# missing predictor columns fail appropriately + + Code + forge(example_train[, 1, drop = FALSE], x1$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'num_2'. + +--- + + Code + forge(example_train[, 1, drop = FALSE], x2$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'num_2'. + +--- + + Code + forge(example_train[, 3, drop = FALSE], x1$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'num_1', 'num_2'. + +--- + + Code + forge(example_train[, 3, drop = FALSE], x2$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'num_1', 'num_2'. + # novel predictor levels are caught Code diff --git a/tests/testthat/_snaps/forge-recipe.md b/tests/testthat/_snaps/forge-recipe.md index d7230cfa..fde9c1ca 100644 --- a/tests/testthat/_snaps/forge-recipe.md +++ b/tests/testthat/_snaps/forge-recipe.md @@ -1,3 +1,35 @@ +# asking for the outcome when it isn't there fails + + Code + forge(iris2, x1$blueprint, outcomes = TRUE) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Species'. + +--- + + Code + forge(iris2, x2$blueprint, outcomes = TRUE) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Species'. + +# missing predictor columns fail appropriately + + Code + forge(iris[, 1, drop = FALSE], x$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Width'. + +--- + + Code + forge(iris[, 3, drop = FALSE], x$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Length', 'Sepal.Width'. + # novel predictor levels are caught Code diff --git a/tests/testthat/_snaps/forge-xy.md b/tests/testthat/_snaps/forge-xy.md index a5a14f83..1a6ed11a 100644 --- a/tests/testthat/_snaps/forge-xy.md +++ b/tests/testthat/_snaps/forge-xy.md @@ -1,3 +1,79 @@ +# asking for the outcome is special cased for vector `y` values + + Code + forge(iris, x1$blueprint, outcomes = TRUE) + Condition + Error in `validate_missing_name_isnt_.outcome()`: + ! The following required columns are missing: '.outcome'. + + (This indicates that `mold()` was called with a vector for `y`. When this is the case, and the outcome columns are requested in `forge()`, `new_data` must include a column with the automatically generated name, '.outcome', containing the outcome.) + +--- + + Code + forge(iris, x2$blueprint, outcomes = TRUE) + Condition + Error in `validate_missing_name_isnt_.outcome()`: + ! The following required columns are missing: '.outcome'. + + (This indicates that `mold()` was called with a vector for `y`. When this is the case, and the outcome columns are requested in `forge()`, `new_data` must include a column with the automatically generated name, '.outcome', containing the outcome.) + +# new_data can only be a data frame / matrix + + Code + forge("hi", x1$blueprint) + Condition + Error in `forge()`: + ! The class of `new_data`, 'character', is not recognized. + +--- + + Code + forge("hi", x2$blueprint) + Condition + Error in `forge()`: + ! The class of `new_data`, 'character', is not recognized. + +--- + + Code + forge("hi", x3$blueprint) + Condition + Error in `forge()`: + ! The class of `new_data`, 'character', is not recognized. + +# missing predictor columns fail appropriately + + Code + forge(iris[, 1, drop = FALSE], x1$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Width'. + +--- + + Code + forge(iris[, 1, drop = FALSE], x2$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Width'. + +--- + + Code + forge(iris[, 3, drop = FALSE], x1$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Length', 'Sepal.Width'. + +--- + + Code + forge(iris[, 3, drop = FALSE], x2$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Length', 'Sepal.Width'. + # novel predictor levels are caught Code diff --git a/tests/testthat/_snaps/levels.md b/tests/testthat/_snaps/levels.md new file mode 100644 index 00000000..e8207e5e --- /dev/null +++ b/tests/testthat/_snaps/levels.md @@ -0,0 +1,8 @@ +# Can extract levels from an outcome + + Code + get_outcome_levels("a") + Condition + Error in `standardize()`: + ! `y` is of unknown type 'character'. + diff --git a/tests/testthat/_snaps/model-offset.md b/tests/testthat/_snaps/model-offset.md new file mode 100644 index 00000000..cd93def8 --- /dev/null +++ b/tests/testthat/_snaps/model-offset.md @@ -0,0 +1,16 @@ +# Only numeric columns can be offsets + + Code + mold(~ Sepal.Width + offset(Species), iris) + Condition + Error in `model_offset()`: + ! Column, 'offset(Species)', is tagged as an offset, but is not numeric. All offsets must be numeric. + +# offset columns are stored as predictors + + Code + forge(iris2, x$blueprint) + Condition + Error in `validate_column_names()`: + ! The following required columns are missing: 'Sepal.Length'. + diff --git a/tests/testthat/_snaps/mold-formula.md b/tests/testthat/_snaps/mold-formula.md index b2c96456..4dd7d4f3 100644 --- a/tests/testthat/_snaps/mold-formula.md +++ b/tests/testthat/_snaps/mold-formula.md @@ -121,6 +121,79 @@ ! Functions involving factors or characters have been detected on the RHS of `formula`. These are not allowed when `indicators = "none"`. i Functions involving factors were detected for "fac_1" in `paste0(fac_1)`. +# formulas with non-existent columns are caught + + Code + mold(fac_1 ~ y + z, example_train) + Condition + Error in `get_all_predictors()`: + ! The following predictors were not found in `data`: 'y', 'z'. + +--- + + Code + mold(fac_1 ~ y + z, example_train, blueprint = bp) + Condition + Error in `get_all_predictors()`: + ! The following predictors were not found in `data`: 'y', 'z'. + +--- + + Code + mold(y + z ~ fac_1, example_train) + Condition + Error in `get_all_outcomes()`: + ! The following outcomes were not found in `data`: 'y', 'z'. + +--- + + Code + mold(y + z ~ fac_1, example_train, blueprint = bp) + Condition + Error in `get_all_outcomes()`: + ! The following outcomes were not found in `data`: 'y', 'z'. + +# global environment variables cannot be used + + Code + y <- 1 + mold(fac_1 ~ y, example_train) + Condition + Error in `get_all_predictors()`: + ! The following predictors were not found in `data`: 'y'. + +# cannot manually remove intercept in the formula itself + + Code + mold(fac_1 ~ y + 0, example_train) + Condition + Error in `mold_formula_default_clean()`: + ! `formula` must not contain the intercept removal term: `+ 0` or `0 +`. + +--- + + Code + mold(fac_1 ~ y + 0, example_train, blueprint = bp) + Condition + Error in `mold_formula_default_clean()`: + ! `formula` must not contain the intercept removal term: `+ 0` or `0 +`. + +--- + + Code + mold(fac_1 ~ 0 + y, example_train) + Condition + Error in `mold_formula_default_clean()`: + ! `formula` must not contain the intercept removal term: `+ 0` or `0 +`. + +--- + + Code + mold(fac_1 ~ y - 1, example_train) + Condition + Error in `mold_formula_default_clean()`: + ! `formula` must not contain the intercept removal term: `- 1`. + # RHS with _only_ intercept related terms are caught Code @@ -169,6 +242,22 @@ Error in `mold_formula_default_clean()`: ! `formula` must not contain the intercept removal term, `0`. +# `data` is validated + + Code + mold(fac_1 ~ num_2, 1) + Condition + Error in `mold_formula_default_clean()`: + ! `data` must be a data frame or a matrix, not the number 1. + +--- + + Code + mold(fac_1 ~ num_2, 1, blueprint = bp) + Condition + Error in `mold_formula_default_clean()`: + ! `data` must be a data frame or a matrix, not the number 1. + # LHS of the formula cannot contain interactions Code @@ -223,6 +312,22 @@ ! Interaction terms can't be specified on the LHS of `formula`. i The following interaction term was found: `num_1/num_2`. +# `.` notation fails on the LHS + + Code + mold(. ~ fac_1, example_train) + Condition + Error in `get_all_outcomes()`: + ! The left hand side of the formula cannot contain `.` + +--- + + Code + mold(. ~ fac_1, example_train, blueprint = bp) + Condition + Error in `get_all_outcomes()`: + ! The left hand side of the formula cannot contain `.` + # `blueprint` is validated Code diff --git a/tests/testthat/_snaps/mold-recipe.md b/tests/testthat/_snaps/mold-recipe.md new file mode 100644 index 00000000..28674f15 --- /dev/null +++ b/tests/testthat/_snaps/mold-recipe.md @@ -0,0 +1,8 @@ +# `data` is validated + + Code + mold(recipes::recipe(Species ~ Sepal.Length, data = iris), 1) + Condition + Error in `mold_recipe_default_clean()`: + ! `data` must be a data frame or a matrix, not the number 1. + diff --git a/tests/testthat/_snaps/spruce.md b/tests/testthat/_snaps/spruce.md index 2a345c45..cb6cc552 100644 --- a/tests/testthat/_snaps/spruce.md +++ b/tests/testthat/_snaps/spruce.md @@ -1,3 +1,77 @@ +# spruce - numeric + + Code + spruce_numeric("hi") + Condition + Error in `spruce_numeric()`: + ! `pred` must be a numeric vector, not the string "hi". + +--- + + Code + spruce_numeric(matrix(1)) + Condition + Error in `spruce_numeric()`: + ! `pred` must be a numeric vector, not a double matrix. + +# spruce - class + + Code + spruce_class(1) + Condition + Error in `spruce_class()`: + ! `pred_class` must be a factor, not the number 1. + +--- + + Code + spruce_class("hi") + Condition + Error in `spruce_class()`: + ! `pred_class` must be a factor, not the string "hi". + +# spruce - prob + + Code + spruce_prob(1, prob_matrix) + Condition + Error in `spruce_prob()`: + ! `pred_levels` must be a character vector, not the number 1. + +--- + + Code + spruce_prob(pred_levels, 1) + Condition + Error in `spruce_prob()`: + ! `prob_matrix` must be a numeric matrix, not the number 1. + +--- + + Code + spruce_prob("a", matrix("a")) + Condition + Error in `spruce_prob()`: + ! `prob_matrix` must be a numeric matrix, not a character matrix. + +--- + + Code + spruce_prob(c("a", "b"), matrix(1, ncol = 3)) + Condition + Error in `spruce_prob()`: + ! The number of levels (2) must be + equal to the number of class probability columns (3). + +--- + + Code + spruce_prob(c("a"), matrix(1, ncol = 2)) + Condition + Error in `spruce_prob()`: + ! The number of levels (1) must be + equal to the number of class probability columns (2). + # spruce multiple helpers check input type Code diff --git a/tests/testthat/_snaps/standardize.md b/tests/testthat/_snaps/standardize.md index b1021630..23967906 100644 --- a/tests/testthat/_snaps/standardize.md +++ b/tests/testthat/_snaps/standardize.md @@ -38,3 +38,27 @@ Error in `standardize()`: ! All columns of `y` must have unique names. +--- + + Code + standardize(bad2) + Condition + Error in `validate_has_known_outcome_types()`: + ! Not all columns of `y` are known outcome types. These columns have unknown types: 'x'. + +# standardize - unknown + + Code + standardize("hi") + Condition + Error in `standardize()`: + ! `y` is of unknown type 'character'. + +--- + + Code + standardize(Sys.time()) + Condition + Error in `standardize()`: + ! `y` is of unknown type 'POSIXct'. + diff --git a/tests/testthat/_snaps/tune.md b/tests/testthat/_snaps/tune.md new file mode 100644 index 00000000..66df0ba6 --- /dev/null +++ b/tests/testthat/_snaps/tune.md @@ -0,0 +1,24 @@ +# `id` is validated + + Code + tune(1) + Condition + Error in `tune()`: + ! The `id` should be a single character string. + +--- + + Code + tune(c("x", "y")) + Condition + Error in `tune()`: + ! The `id` should be a single character string. + +--- + + Code + tune(NA_character_) + Condition + Error in `tune()`: + ! The `id` can't be missing. + diff --git a/tests/testthat/_snaps/validation.md b/tests/testthat/_snaps/validation.md new file mode 100644 index 00000000..4c397ab9 --- /dev/null +++ b/tests/testthat/_snaps/validation.md @@ -0,0 +1,117 @@ +# validate_outcomes_are_univariate() + + Code + validate_outcomes_are_univariate(iris) + Condition + Error in `validate_outcomes_are_univariate()`: + ! The outcome must be univariate, but 5 columns were found. + +# validate_outcomes_are_numeric() + + Code + validate_outcomes_are_numeric(iris) + Condition + Error in `validate_outcomes_are_numeric()`: + ! All outcomes must be numeric, but the following are not: + 'Species': 'factor' + +--- + + Code + validate_outcomes_are_numeric(x) + Condition + Error in `validate_outcomes_are_numeric()`: + ! All outcomes must be numeric, but the following are not: + 'x': 'POSIXct', 'POSIXt' + 'y': 'factor' + +# validate_no_formula_duplication() + + Code + validate_no_formula_duplication(y ~ y) + Condition + Error in `validate_no_formula_duplication()`: + ! The following terms are duplicated on the left and right hand side of the `formula`: 'y'. + +--- + + Code + validate_no_formula_duplication(y ~ log(y), original = TRUE) + Condition + Error in `validate_no_formula_duplication()`: + ! The following terms are duplicated on the left and right hand side of the `formula`: 'y'. + +--- + + Code + validate_no_formula_duplication(y + x ~ y + x) + Condition + Error in `validate_no_formula_duplication()`: + ! The following terms are duplicated on the left and right hand side of the `formula`: 'y', 'x'. + +--- + + Code + validate_no_formula_duplication(y ~ . + y) + Condition + Error in `validate_no_formula_duplication()`: + ! The following terms are duplicated on the left and right hand side of the `formula`: 'y'. + +--- + + Code + validate_no_formula_duplication(y ~ offset(y), original = TRUE) + Condition + Error in `validate_no_formula_duplication()`: + ! The following terms are duplicated on the left and right hand side of the `formula`: 'y'. + +# validate_outcomes_are_factors() + + Code + validate_outcomes_are_factors(x) + Condition + Error in `validate_outcomes_are_factors()`: + ! All outcomes must be factors, but the following are not: + 'x': 'POSIXct', 'POSIXt' + 'y': 'character' + +# validate_outcomes_are_binary() + + Code + validate_outcomes_are_binary(iris) + Condition + Error in `validate_outcomes_are_binary()`: + ! The outcome must be binary, but the following number of levels were found: + 'Sepal.Length': 0 + 'Sepal.Width': 0 + 'Petal.Length': 0 + 'Petal.Width': 0 + 'Species': 3 + +# validate_predictors_are_numeric() + + Code + validate_predictors_are_numeric(iris) + Condition + Error in `validate_predictors_are_numeric()`: + ! All predictors must be numeric, but the following are not: + 'Species': 'factor' + +--- + + Code + validate_predictors_are_numeric(x) + Condition + Error in `validate_predictors_are_numeric()`: + ! All predictors must be numeric, but the following are not: + 'x': 'POSIXct', 'POSIXt' + 'y': 'factor' + +# validate_prediction_size() + + Code + validate_prediction_size(mtcars[1:5, ], mtcars) + Condition + Error in `validate_prediction_size()`: + ! The size of `new_data` (32) must match the size of `pred` (5). + diff --git a/tests/testthat/test-constructor.R b/tests/testthat/test-constructor.R index e1f0bcf7..bad5d5cc 100644 --- a/tests/testthat/test-constructor.R +++ b/tests/testthat/test-constructor.R @@ -32,9 +32,8 @@ test_that("can have custom elements", { }) test_that("must use a valid blueprint", { - expect_error( - new_model(blueprint = default_xy_blueprint(), class = "custom"), - NA + expect_no_error( + new_model(blueprint = default_xy_blueprint(), class = "custom") ) expect_snapshot(error = TRUE, { @@ -43,15 +42,15 @@ test_that("must use a valid blueprint", { }) test_that("`new_scalar()` must have elements", { - expect_error(new_scalar(list()), "must be a list of length 1 or greater") + expect_snapshot(error = TRUE, new_scalar(list())) }) test_that("`new_scalar()` must have unique names", { - expect_error(new_scalar(list(x = 1, x = 2)), "must have unique names") + expect_snapshot(error = TRUE, new_scalar(list(x = 1, x = 2))) }) test_that("`new_scalar()` must have no extra attributes", { x <- list(x = 1) attr(x, "extra") <- 1 - expect_error(new_scalar(x), "must have no attributes") + expect_snapshot(error = TRUE, new_scalar(x)) }) diff --git a/tests/testthat/test-forge-formula.R b/tests/testthat/test-forge-formula.R index 93fb59ef..dfeebff0 100644 --- a/tests/testthat/test-forge-formula.R +++ b/tests/testthat/test-forge-formula.R @@ -131,13 +131,13 @@ test_that("asking for the outcome when it isn't there fails", { example_train2 <- example_train example_train2$fac_1 <- NULL - expect_error( - forge(example_train2, x1$blueprint, outcomes = TRUE), - "The following required columns" + expect_snapshot( + error = TRUE, + forge(example_train2, x1$blueprint, outcomes = TRUE) ) - expect_error( - forge(example_train2, x2$blueprint, outcomes = TRUE), - "The following required columns" + expect_snapshot( + error = TRUE, + forge(example_train2, x2$blueprint, outcomes = TRUE) ) }) @@ -178,14 +178,8 @@ test_that("new_data can be a matrix", { x2 <- mold(fac_1 ~ num_1, example_train, blueprint = bp) example_train_mat <- as.matrix(example_train[, "num_1", drop = FALSE]) - expect_error( - xx1 <- forge(example_train_mat, x1$blueprint), - NA - ) - expect_error( - xx2 <- forge(example_train_mat, x2$blueprint), - NA - ) + expect_no_error(xx1 <- forge(example_train_mat, x1$blueprint)) + expect_no_error(xx2 <- forge(example_train_mat, x2$blueprint)) sep_len <- example_train$num_1 @@ -204,13 +198,13 @@ test_that("new_data can only be a data frame / matrix", { x1 <- mold(fac_1 ~ num_1, example_train) x2 <- mold(fac_1 ~ num_1, example_train, blueprint = bp) - expect_error( - forge("hi", x1$blueprint), - "The class of `new_data`, 'character'" + expect_snapshot( + error = TRUE, + forge("hi", x1$blueprint) ) - expect_error( - forge("hi", x2$blueprint), - "The class of `new_data`, 'character'" + expect_snapshot( + error = TRUE, + forge("hi", x2$blueprint) ) }) @@ -219,22 +213,22 @@ test_that("missing predictor columns fail appropriately", { x1 <- mold(fac_1 ~ num_1 + num_2, example_train) x2 <- mold(fac_1 ~ num_1 + num_2, example_train, blueprint = bp) - expect_error( - forge(example_train[, 1, drop = FALSE], x1$blueprint), - "num_2" + expect_snapshot( + error = TRUE, + forge(example_train[, 1, drop = FALSE], x1$blueprint) ) - expect_error( - forge(example_train[, 1, drop = FALSE], x2$blueprint), - "num_2" + expect_snapshot( + error = TRUE, + forge(example_train[, 1, drop = FALSE], x2$blueprint) ) - expect_error( - forge(example_train[, 3, drop = FALSE], x1$blueprint), - "'num_1', 'num_2'" + expect_snapshot( + error = TRUE, + forge(example_train[, 3, drop = FALSE], x1$blueprint) ) - expect_error( - forge(example_train[, 3, drop = FALSE], x2$blueprint), - "'num_1', 'num_2'" + expect_snapshot( + error = TRUE, + forge(example_train[, 3, drop = FALSE], x2$blueprint) ) }) @@ -770,9 +764,8 @@ test_that("new data classes are caught", { x <- mold(num_1 ~ fac_1, example_train, blueprint = default_formula_blueprint(indicators = "none")) # Silently recover character -> factor - expect_error( - x_example_train2 <- forge(example_train2, x$blueprint), - NA + expect_no_error( + x_example_train2 <- forge(example_train2, x$blueprint) ) expect_s3_class( @@ -782,9 +775,8 @@ test_that("new data classes are caught", { xx <- mold(fac_1 ~ num_1, example_train) - expect_error( - xx_example_train2 <- forge(example_train2, xx$blueprint, outcomes = TRUE), - NA + expect_no_error( + xx_example_train2 <- forge(example_train2, xx$blueprint, outcomes = TRUE) ) expect_s3_class( @@ -801,25 +793,17 @@ test_that("new data classes can interchange integer/numeric", { x1 <- mold(fac_1 ~ num_1, example_train) x2 <- mold(fac_1 ~ num_1, example_train, blueprint = bp) - expect_error( - forge(example_train2, x1$blueprint), - NA - ) - expect_error( - forge(example_train2, x2$blueprint), - NA - ) + expect_no_error(forge(example_train2, x1$blueprint)) + expect_no_error(forge(example_train2, x2$blueprint)) x3 <- mold(num_1 ~ fac_1, example_train) x4 <- mold(num_1 ~ fac_1, example_train, blueprint = bp) - expect_error( - forge(example_train2, x3$blueprint, outcomes = TRUE), - NA + expect_no_error( + forge(example_train2, x3$blueprint, outcomes = TRUE) ) - expect_error( - forge(example_train2, x4$blueprint, outcomes = TRUE), - NA + expect_no_error( + forge(example_train2, x4$blueprint, outcomes = TRUE) ) }) diff --git a/tests/testthat/test-forge-recipe.R b/tests/testthat/test-forge-recipe.R index aa16eead..66e23998 100644 --- a/tests/testthat/test-forge-recipe.R +++ b/tests/testthat/test-forge-recipe.R @@ -98,14 +98,14 @@ test_that("asking for the outcome when it isn't there fails", { iris2 <- iris iris2$Species <- NULL - expect_error( - forge(iris2, x1$blueprint, outcomes = TRUE), - "The following required columns" + expect_snapshot( + error = TRUE, + forge(iris2, x1$blueprint, outcomes = TRUE) ) - expect_error( - forge(iris2, x2$blueprint, outcomes = TRUE), - "The following required columns" + expect_snapshot( + error = TRUE, + forge(iris2, x2$blueprint, outcomes = TRUE) ) }) @@ -141,14 +141,14 @@ test_that("missing predictor columns fail appropriately", { iris ) - expect_error( - forge(iris[, 1, drop = FALSE], x$blueprint), - "Sepal.Width" + expect_snapshot( + error = TRUE, + forge(iris[, 1, drop = FALSE], x$blueprint) ) - expect_error( - forge(iris[, 3, drop = FALSE], x$blueprint), - "'Sepal.Length', 'Sepal.Width'" + expect_snapshot( + error = TRUE, + forge(iris[, 3, drop = FALSE], x$blueprint) ) }) @@ -390,14 +390,8 @@ test_that("new data classes are caught", { x2 <- mold(recipes::step_dummy(rec, Species), iris, blueprint = sparse_bp) # Silent recovery - expect_error( - xx1 <- forge(iris2, x1$blueprint), - NA - ) - expect_error( - xx2 <- forge(iris2, x2$blueprint), - NA - ) + expect_no_error(xx1 <- forge(iris2, x1$blueprint)) + expect_no_error(xx2 <- forge(iris2, x2$blueprint)) expect_s3_class( xx1$predictors$Species, @@ -411,14 +405,8 @@ test_that("new data classes are caught", { x3 <- mold(recipes::recipe(Species ~ Sepal.Length, iris), iris) x4 <- mold(recipes::recipe(Species ~ Sepal.Length, iris), iris, blueprint = sparse_bp) - expect_error( - xx3 <- forge(iris2, x3$blueprint, outcomes = TRUE), - NA - ) - expect_error( - xx4 <- forge(iris2, x4$blueprint, outcomes = TRUE), - NA - ) + expect_no_error(xx3 <- forge(iris2, x3$blueprint, outcomes = TRUE)) + expect_no_error(xx4 <- forge(iris2, x4$blueprint, outcomes = TRUE)) expect_s3_class( xx3$outcomes$Species, @@ -441,26 +429,18 @@ test_that("new data classes can interchange integer/numeric", { x1 <- mold(recipes::recipe(Species ~ Sepal.Length, iris), iris) x2 <- mold(recipes::recipe(Species ~ Sepal.Length, iris), iris, blueprint = sparse_bp) - expect_error( - forge(iris2, x1$blueprint), - NA - ) - expect_error( - forge(iris2, x2$blueprint), - NA - ) + expect_no_error(forge(iris2, x1$blueprint)) + expect_no_error(forge(iris2, x2$blueprint)) rec <- recipes::recipe(Sepal.Length ~ Species, iris) x3 <- mold(rec, iris) x4 <- mold(recipes::step_dummy(rec, Species), iris, blueprint = sparse_bp) - expect_error( - forge(iris2, x3$blueprint, outcomes = TRUE), - NA + expect_no_error( + forge(iris2, x3$blueprint, outcomes = TRUE) ) - expect_error( - forge(iris2, x4$blueprint, outcomes = TRUE), - NA + expect_no_error( + forge(iris2, x4$blueprint, outcomes = TRUE) ) }) diff --git a/tests/testthat/test-forge-xy.R b/tests/testthat/test-forge-xy.R index 248fb429..22253e08 100644 --- a/tests/testthat/test-forge-xy.R +++ b/tests/testthat/test-forge-xy.R @@ -100,24 +100,16 @@ test_that("asking for the outcome is special cased for vector `y` values", { expect_equal(xx1$outcomes, xx3$outcomes) expect_equal(xx1$outcomes, xx3$outcomes) - # standard message - expect_error( - forge(iris, x1$blueprint, outcomes = TRUE), - "The following required columns" + # This expects: + # - standard message: "The following required columns" + # - more detail: "`new_data` must include a column with the automatically generated name, '.outcome'" + expect_snapshot( + error = TRUE, + forge(iris, x1$blueprint, outcomes = TRUE) ) - expect_error( - forge(iris, x2$blueprint, outcomes = TRUE), - "The following required columns" - ) - - # but also more detail - expect_error( - forge(iris, x1$blueprint, outcomes = TRUE), - "`new_data` must include a column with the automatically generated name, '.outcome'" - ) - expect_error( - forge(iris, x3$blueprint, outcomes = TRUE), - "`new_data` must include a column with the automatically generated name, '.outcome'" + expect_snapshot( + error = TRUE, + forge(iris, x2$blueprint, outcomes = TRUE) ) }) @@ -125,10 +117,7 @@ test_that("new_data can be a matrix", { x <- mold(iris[, "Sepal.Length", drop = FALSE], iris$Species) iris_mat <- as.matrix(iris[, "Sepal.Length", drop = FALSE]) - expect_error( - xx <- forge(iris_mat, x$blueprint), - NA - ) + expect_no_error(xx <- forge(iris_mat, x$blueprint)) sep_len <- iris$Sepal.Length pred_tbl <- tibble::tibble(Sepal.Length = sep_len) @@ -147,18 +136,9 @@ test_that("new_data can only be a data frame / matrix", { x2 <- mold(iris[, "Sepal.Length", drop = FALSE], iris$Species, blueprint = sparse_bp) x3 <- mold(iris[, "Sepal.Length", drop = FALSE], iris$Species, blueprint = matrix_bp) - expect_error( - forge("hi", x1$blueprint), - "The class of `new_data`, 'character'" - ) - expect_error( - forge("hi", x2$blueprint), - "The class of `new_data`, 'character'" - ) - expect_error( - forge("hi", x3$blueprint), - "The class of `new_data`, 'character'" - ) + expect_snapshot(error = TRUE, forge("hi", x1$blueprint)) + expect_snapshot(error = TRUE, forge("hi", x2$blueprint)) + expect_snapshot(error = TRUE, forge("hi", x3$blueprint)) }) test_that("missing predictor columns fail appropriately", { @@ -170,22 +150,22 @@ test_that("missing predictor columns fail appropriately", { blueprint = bp ) - expect_error( - forge(iris[, 1, drop = FALSE], x1$blueprint), - "Sepal.Width" + expect_snapshot( + error = TRUE, + forge(iris[, 1, drop = FALSE], x1$blueprint) ) - expect_error( - forge(iris[, 1, drop = FALSE], x2$blueprint), - "Sepal.Width" + expect_snapshot( + error = TRUE, + forge(iris[, 1, drop = FALSE], x2$blueprint) ) - expect_error( - forge(iris[, 3, drop = FALSE], x1$blueprint), - "'Sepal.Length', 'Sepal.Width'" + expect_snapshot( + error = TRUE, + forge(iris[, 3, drop = FALSE], x1$blueprint) ) - expect_error( - forge(iris[, 3, drop = FALSE], x2$blueprint), - "'Sepal.Length', 'Sepal.Width'" + expect_snapshot( + error = TRUE, + forge(iris[, 3, drop = FALSE], x2$blueprint) ) }) @@ -341,9 +321,8 @@ test_that("new data classes are caught", { x <- mold(iris[, "Species", drop = FALSE], iris$Sepal.Length) # Silent recovery - expect_error( - x_iris2 <- forge(iris2, x$blueprint), - NA + expect_no_error( + x_iris2 <- forge(iris2, x$blueprint) ) expect_s3_class( @@ -357,9 +336,8 @@ test_that("new data classes are caught", { iris3$.outcome <- iris2$Species iris3$Species <- NULL - expect_error( - xx_iris3 <- forge(iris3, xx$blueprint, outcomes = TRUE), - NA + expect_no_error( + xx_iris3 <- forge(iris3, xx$blueprint, outcomes = TRUE) ) expect_s3_class( @@ -383,14 +361,8 @@ test_that("new data classes can interchange integer/numeric", { blueprint = bp ) - expect_error( - forge(iris2, x1$blueprint), - NA - ) - expect_error( - forge(iris2, x2$blueprint), - NA - ) + expect_no_error(forge(iris2, x1$blueprint)) + expect_no_error(forge(iris2, x2$blueprint)) }) test_that("intercept is not included as a predictor", { @@ -412,14 +384,8 @@ test_that("intercept is not included as a predictor", { "(Intercept)" %in% colnames(x2$blueprint$ptypes$predictors) ) - expect_error( - xx1 <- forge(iris, x1$blueprint), - NA - ) - expect_error( - xx2 <- forge(iris, x2$blueprint), - NA - ) + expect_no_error(xx1 <- forge(iris, x1$blueprint)) + expect_no_error(xx2 <- forge(iris, x2$blueprint)) expect_equal( colnames(xx1$predictors), diff --git a/tests/testthat/test-levels.R b/tests/testthat/test-levels.R index 2a556df6..a2004499 100644 --- a/tests/testthat/test-levels.R +++ b/tests/testthat/test-levels.R @@ -66,9 +66,9 @@ test_that("Can extract levels from an outcome", { NULL ) - expect_error( - get_outcome_levels("a"), - "`y` is of unknown type" + expect_snapshot( + error = TRUE, + get_outcome_levels("a") ) expect_equal( diff --git a/tests/testthat/test-model-offset.R b/tests/testthat/test-model-offset.R index 205a69c2..40b46b94 100644 --- a/tests/testthat/test-model-offset.R +++ b/tests/testthat/test-model-offset.R @@ -38,9 +38,9 @@ test_that("(offset) is not recognized as an offset", { }) test_that("Only numeric columns can be offsets", { - expect_error( - mold(~ Sepal.Width + offset(Species), iris), - "Column, 'offset" + expect_snapshot( + error = TRUE, + mold(~ Sepal.Width + offset(Species), iris) ) }) @@ -117,9 +117,9 @@ test_that("offset columns are stored as predictors", { iris2 <- iris iris2$Sepal.Length <- NULL - expect_error( - forge(iris2, x$blueprint), - "Sepal.Length" + expect_snapshot( + error = TRUE, + forge(iris2, x$blueprint) ) }) diff --git a/tests/testthat/test-mold-formula.R b/tests/testthat/test-mold-formula.R index 8540a3e4..d4342504 100644 --- a/tests/testthat/test-mold-formula.R +++ b/tests/testthat/test-mold-formula.R @@ -110,9 +110,8 @@ test_that("can mold and not expand dummies", { }) test_that("errors are thrown if `indicator = 'none'` and factor interactions exist", { - expect_error( - mold(~fac_1, example_train, blueprint = default_formula_blueprint(indicators = "none")), - NA + expect_no_error( + mold(~fac_1, example_train, blueprint = default_formula_blueprint(indicators = "none")) ) expect_snapshot(error = TRUE, { @@ -311,54 +310,54 @@ test_that("can mold formulas with special terms", { test_that("formulas with non-existent columns are caught", { bp <- default_formula_blueprint(composition = "dgCMatrix") - expect_error( - mold(fac_1 ~ y + z, example_train), - "predictors were not found in `data`: 'y', 'z'" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ y + z, example_train) ) - expect_error( - mold(fac_1 ~ y + z, example_train, blueprint = bp), - "predictors were not found in `data`: 'y', 'z'" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ y + z, example_train, blueprint = bp) ) - expect_error( - mold(y + z ~ fac_1, example_train), - "outcomes were not found in `data`: 'y', 'z'" + expect_snapshot( + error = TRUE, + mold(y + z ~ fac_1, example_train) ) - expect_error( - mold(y + z ~ fac_1, example_train, blueprint = bp), - "outcomes were not found in `data`: 'y', 'z'" + expect_snapshot( + error = TRUE, + mold(y + z ~ fac_1, example_train, blueprint = bp) ) }) test_that("global environment variables cannot be used", { - expect_error( + expect_snapshot( + error = TRUE, { y <- 1 mold(fac_1 ~ y, example_train) - }, - "predictors were not found in `data`: 'y'" + } ) }) test_that("cannot manually remove intercept in the formula itself", { bp <- default_formula_blueprint(composition = "dgCMatrix") - expect_error( - mold(fac_1 ~ y + 0, example_train), - "`formula` must not contain" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ y + 0, example_train) ) - expect_error( - mold(fac_1 ~ y + 0, example_train, blueprint = bp), - "`formula` must not contain" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ y + 0, example_train, blueprint = bp) ) - expect_error( - mold(fac_1 ~ 0 + y, example_train), - "`formula` must not contain" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ 0 + y, example_train) ) - expect_error( - mold(fac_1 ~ y - 1, example_train), - "`formula` must not contain" + expect_snapshot( + error = TRUE, + mold(fac_1 ~ y - 1, example_train) ) }) @@ -390,13 +389,11 @@ test_that("`NULL` can be used to represent empty RHS formulas", { mold(~0, example_train, blueprint = bp) }) - expect_error( - x1 <- mold(~NULL, example_train), - NA + expect_no_error( + x1 <- mold(~NULL, example_train) ) - expect_error( - x2 <- mold(~NULL, example_train, blueprint = bp), - NA + expect_no_error( + x2 <- mold(~NULL, example_train, blueprint = bp) ) expect_equal(nrow(x1$predictors), 12) @@ -404,9 +401,8 @@ test_that("`NULL` can be used to represent empty RHS formulas", { expect_equal(nrow(x2$predictors), 12) expect_equal(nrow(x2$outcomes), 12) - expect_error( - y <- mold(~NULL, example_train, blueprint = default_formula_blueprint(intercept = TRUE)), - NA + expect_no_error( + y <- mold(~NULL, example_train, blueprint = default_formula_blueprint(intercept = TRUE)) ) expect_equal(colnames(y$predictors), "(Intercept)") @@ -431,14 +427,8 @@ test_that("intercepts can still be added when not using indicators (i.e. model.m test_that("`data` is validated", { bp <- default_formula_blueprint(composition = "dgCMatrix") - expect_error( - mold(fac_1 ~ num_2, 1), - "`data` must be a data.frame or a matrix" - ) - expect_error( - mold(fac_1 ~ num_2, 1, blueprint = bp), - "`data` must be a data.frame or a matrix" - ) + expect_snapshot(error = TRUE, mold(fac_1 ~ num_2, 1)) + expect_snapshot(error = TRUE, mold(fac_1 ~ num_2, 1, blueprint = bp)) }) test_that("full interaction syntax is supported", { @@ -563,13 +553,13 @@ test_that("`.` notation works as expected", { # the `"."` as a variable. test_that("`.` notation fails on the LHS", { bp <- default_formula_blueprint(composition = "dgCMatrix") - expect_error( - mold(. ~ fac_1, example_train), - "The left hand side of the formula cannot contain `.`" + expect_snapshot( + error = TRUE, + mold(. ~ fac_1, example_train) ) - expect_error( - mold(. ~ fac_1, example_train, blueprint = bp), - "The left hand side of the formula cannot contain `.`" + expect_snapshot( + error = TRUE, + mold(. ~ fac_1, example_train, blueprint = bp) ) }) diff --git a/tests/testthat/test-mold-recipe.R b/tests/testthat/test-mold-recipe.R index ee5a3777..52e19270 100644 --- a/tests/testthat/test-mold-recipe.R +++ b/tests/testthat/test-mold-recipe.R @@ -136,10 +136,10 @@ test_that("can pass `strings_as_factors` through to `prep()`", { test_that("`data` is validated", { skip_if_not_installed("recipes") - - expect_error( - mold(recipes::recipe(Species ~ Sepal.Length, data = iris), 1), - "`data` must be a data.frame or a matrix" + + expect_snapshot( + error = TRUE, + mold(recipes::recipe(Species ~ Sepal.Length, data = iris), 1) ) }) diff --git a/tests/testthat/test-spruce.R b/tests/testthat/test-spruce.R index df474ddc..9a4b6e9d 100644 --- a/tests/testthat/test-spruce.R +++ b/tests/testthat/test-spruce.R @@ -4,8 +4,8 @@ test_that("spruce - numeric", { expect_s3_class(spruced, "tbl_df") expect_equal(colnames(spruced), ".pred") - expect_error(spruce_numeric("hi")) - expect_error(spruce_numeric(matrix(1))) + expect_snapshot(error = TRUE, spruce_numeric("hi")) + expect_snapshot(error = TRUE, spruce_numeric(matrix(1))) }) test_that("spruce - class", { @@ -14,8 +14,8 @@ test_that("spruce - class", { expect_s3_class(spruced, "tbl_df") expect_equal(colnames(spruced), ".pred_class") - expect_error(spruce_class(1)) - expect_error(spruce_class("hi")) + expect_snapshot(error = TRUE, spruce_class(1)) + expect_snapshot(error = TRUE, spruce_class("hi")) }) test_that("spruce - prob", { @@ -27,29 +27,20 @@ test_that("spruce - prob", { expect_s3_class(spruced, "tbl_df") expect_equal(colnames(spruced), paste0(".pred_", pred_levels)) - expect_error(spruce_prob(1, prob_matrix)) - expect_error(spruce_prob(pred_levels, 1)) - expect_error(spruce_prob("a", matrix("a"))) + expect_snapshot(error = TRUE, spruce_prob(1, prob_matrix)) + expect_snapshot(error = TRUE, spruce_prob(pred_levels, 1)) + expect_snapshot(error = TRUE, spruce_prob("a", matrix("a"))) - expect_error( - spruce_prob(c("a", "b"), matrix(1, ncol = 3)), - "2" + expect_snapshot( + error = TRUE, + spruce_prob(c("a", "b"), matrix(1, ncol = 3)) ) - expect_error( - spruce_prob(c("a", "b"), matrix(1, ncol = 3)), - "3" + expect_snapshot( + error = TRUE, + spruce_prob(c("a"), matrix(1, ncol = 2)) ) - expect_error( - spruce_prob(c("a"), matrix(1, ncol = 2)), - "1" - ) - - expect_error( - spruce_prob(c("a"), matrix(1, ncol = 2)), - "2" - ) }) test_that("`spruce_numeric_multiple()` generates the correct output", { diff --git a/tests/testthat/test-standardize.R b/tests/testthat/test-standardize.R index b3ce7fd6..bb6aff38 100644 --- a/tests/testthat/test-standardize.R +++ b/tests/testthat/test-standardize.R @@ -71,7 +71,7 @@ test_that("standardize - data.frame", { bad2 <- data.frame(x = "a", stringsAsFactors = FALSE) - expect_error(standardize(bad2), "These columns have unknown types: 'x'.") + expect_snapshot(error = TRUE, standardize(bad2)) good <- bad colnames(good) <- c("a", "b") @@ -88,6 +88,6 @@ test_that("standardize - data.frame", { }) test_that("standardize - unknown", { - expect_error(standardize("hi"), "`y` is of unknown type 'character'") - expect_error(standardize(Sys.time()), "`y` is of unknown type 'POSIXct'") + expect_snapshot(error = TRUE, standardize("hi")) + expect_snapshot(error = TRUE, standardize(Sys.time())) }) diff --git a/tests/testthat/test-tune.R b/tests/testthat/test-tune.R index 169a0657..19d0be2a 100644 --- a/tests/testthat/test-tune.R +++ b/tests/testthat/test-tune.R @@ -10,7 +10,7 @@ test_that("tune `id` value", { }) test_that("`id` is validated", { - expect_error(tune(1), "The `id` should be a single character string.") - expect_error(tune(c("x", "y")), "The `id` should be a single character string.") - expect_error(tune(NA_character_), "The `id` can't be missing.") + expect_snapshot(error = TRUE, tune(1)) + expect_snapshot(error = TRUE, tune(c("x", "y"))) + expect_snapshot(error = TRUE, tune(NA_character_)) }) diff --git a/tests/testthat/test-validation.R b/tests/testthat/test-validation.R index 464575aa..69530a1d 100644 --- a/tests/testthat/test-validation.R +++ b/tests/testthat/test-validation.R @@ -5,9 +5,9 @@ test_that("validate_outcomes_are_univariate()", { expect_silent(validate_outcomes_are_univariate(1)) - expect_error( - validate_outcomes_are_univariate(iris), - "The outcome must be univariate, but 5 columns were found." + expect_snapshot( + error = TRUE, + validate_outcomes_are_univariate(iris) ) }) @@ -16,53 +16,53 @@ test_that("validate_outcomes_are_numeric()", { validate_outcomes_are_numeric(mtcars) ) - expect_error( - validate_outcomes_are_numeric(iris), - "'Species': 'factor'" + expect_snapshot( + error = TRUE, + validate_outcomes_are_numeric(iris) ) date <- as.POSIXct(as.POSIXlt(as.Date("2019-01-01"))) x <- data.frame(x = date, y = factor("hi")) - expect_error( - validate_outcomes_are_numeric(x), - "'x': 'POSIXct', 'POSIXt'\n'y': 'factor'" + expect_snapshot( + error = TRUE, + validate_outcomes_are_numeric(x) ) }) test_that("validate_no_formula_duplication()", { expect_silent(validate_no_formula_duplication(y ~ x)) - expect_error( - validate_no_formula_duplication(y ~ y), - "'y'" + expect_snapshot( + error = TRUE, + validate_no_formula_duplication(y ~ y) ) expect_silent(validate_no_formula_duplication(y ~ log(y))) - expect_error( - validate_no_formula_duplication(y ~ log(y), original = TRUE), - "'y'" + expect_snapshot( + error = TRUE, + validate_no_formula_duplication(y ~ log(y), original = TRUE) ) - expect_error( - validate_no_formula_duplication(y + x ~ y + x), - "'y', 'x'" + expect_snapshot( + error = TRUE, + validate_no_formula_duplication(y + x ~ y + x) ) expect_silent(validate_no_formula_duplication(y ~ .)) - expect_error( - validate_no_formula_duplication(y ~ . + y), - "'y'" + expect_snapshot( + error = TRUE, + validate_no_formula_duplication(y ~ . + y) ) # offset() is a weird special case but this is ok expect_silent(validate_no_formula_duplication(offset(y) ~ offset(y))) - expect_error( - validate_no_formula_duplication(y ~ offset(y), original = TRUE), - "'y'" + expect_snapshot( + error = TRUE, + validate_no_formula_duplication(y ~ offset(y), original = TRUE) ) }) @@ -74,9 +74,9 @@ test_that("validate_outcomes_are_factors()", { date <- as.POSIXct(as.POSIXlt(as.Date("2019-01-01"))) x <- data.frame(x = date, y = "hi", stringsAsFactors = FALSE) - expect_error( - validate_outcomes_are_factors(x), - "'x': 'POSIXct', 'POSIXt'\n'y': 'character'" + expect_snapshot( + error = TRUE, + validate_outcomes_are_factors(x) ) }) @@ -85,9 +85,9 @@ test_that("validate_outcomes_are_binary()", { validate_outcomes_are_binary(data.frame(x = factor(c("A", "B")))) ) - expect_error( - validate_outcomes_are_binary(iris), - "'Sepal.Length': 0\n'Sepal.Width': 0\n'Petal.Length': 0\n'Petal.Width': 0\n'Species': 3" + expect_snapshot( + error = TRUE, + validate_outcomes_are_binary(iris) ) }) @@ -96,17 +96,17 @@ test_that("validate_predictors_are_numeric()", { validate_predictors_are_numeric(mtcars) ) - expect_error( - validate_predictors_are_numeric(iris), - "'Species': 'factor'" + expect_snapshot( + error = TRUE, + validate_predictors_are_numeric(iris) ) date <- as.POSIXct(as.POSIXlt(as.Date("2019-01-01"))) x <- data.frame(x = date, y = factor("hi")) - expect_error( - validate_predictors_are_numeric(x), - "'x': 'POSIXct', 'POSIXt'\n'y': 'factor'" + expect_snapshot( + error = TRUE, + validate_predictors_are_numeric(x) ) }) @@ -115,8 +115,8 @@ test_that("validate_prediction_size()", { validate_prediction_size(mtcars, mtcars) ) - expect_error( - validate_prediction_size(mtcars[1:5, ], mtcars), - "The size of `new_data` \\(32\\) must match the size of `pred` \\(5\\)." + expect_snapshot( + error = TRUE, + validate_prediction_size(mtcars[1:5, ], mtcars) ) })