test_that("grid_item_container()", { expect_snapshot( grid_item_container( div(class = "layout-column-child-element"), class = "g-col-md-6 g-col-lg-4", fillable = TRUE ) ) expect_snapshot( grid_item_container( div(class = "layout-column-child-element"), class = "g-col-md-6 g-col-lg-4", fillable = FALSE ) ) }) test_that("grid-breakpoints are known", { brks <- bs_get_variables( bs_add_variables( bs_theme(), "grid-brk-names" = "map-keys($grid-breakpoints)", .where = "declarations" ), "grid-brk-names" ) # In bslib::breakpoints() we flag these as "known" breakpoints... # which mostly means we order them, but also, in the NA case, # we use lg/xl/xxl to fill in md expect_equal( strsplit(brks, ", ")[[1]], c("xs", "sm", "md", "lg", "xl", "xxl") ) }) test_that("breakpoints() re-orders well-known breaks and test print method", { bp <- breakpoints( xl = 5, sm = 2, xs = 1, giant = 7, lg = 4, huge = 8, md = 3, xxl = 6 ) expect_snapshot(bp) expect_equal(unclass(unname(unlist(bp))), 1:8) }) test_that("breakpoints() has correct classes and structure", { bp <- breakpoints( lg = c(-2, 2, -1, -2, 3, -2), md = c(-1, 2, -2, 3), sm = c(1, -1, 1), xl = c(1, 2, 3, NA), huge = list(1, 2, 3, "auto") ) expect_true(is_breakpoints(bp)) # names are ordered, custom breakpoint names are last expect_named(bp, c("sm", "md", "lg", "xl", "huge")) expect_snapshot(bp) }) test_that("breakpoints() with negative widths to indicate empty columns", { bp <- breakpoints( sm = c(1, -1, 1), md = c(-1, 2, -2, 3), lg = c(-2, 2, -1, -2, 3, -2), xl = c(1, 2, 3) ) bp <- as_column_breakpoints(bp) expect_equal(bp$sm$width, c(1, 1), ignore_attr = TRUE) expect_equal(bp$md$width, c(2, 3), ignore_attr = TRUE) expect_equal(bp$lg$width, c(2, 3), ignore_attr = TRUE) expect_equal(bp$xl$width, c(1, 2, 3), ignore_attr = TRUE) expect_equal(bp$sm[["before"]], c(0, 1)) expect_equal(bp$md[["before"]], c(1, 2)) expect_equal(bp$lg[["before"]], c(2, 3)) expect_equal(bp$xl[["before"]], c(0, 0, 0)) expect_equal(bp$sm[["after"]], c(0, 0)) expect_equal(bp$md[["after"]], c(0, 0)) expect_equal(bp$lg[["after"]], c(0, 2)) expect_equal(bp$xl[["after"]], c(0, 0, 0)) }) test_that("breakpoints() must be named", { expect_error(breakpoints(1:3)) }) test_that("breakpoints() can be a single NA", { bp <- breakpoints( sm = NA, md = c(-1, 2, -2, 3), lg = c(-2, 2, -1, -2, 3, -2), xl = NA ) bp <- as_column_breakpoints(bp) expect_equal(bp$sm$width, NA, ignore_attr = TRUE) expect_equal(bp$md$width, c(2, 3), ignore_attr = TRUE) expect_equal(bp$lg$width, c(2, 3), ignore_attr = TRUE) expect_equal(bp$xl$width, NA, ignore_attr = TRUE) expect_equal(bp$sm[["before"]], c(0)) expect_equal(bp$md[["before"]], c(1, 2)) expect_equal(bp$lg[["before"]], c(2, 3)) expect_equal(bp$xl[["before"]], c(0)) expect_equal(bp$sm[["after"]], c(0)) expect_equal(bp$md[["after"]], c(0, 0)) expect_equal(bp$lg[["after"]], c(0, 2)) expect_equal(bp$xl[["after"]], c(0)) }) test_that("breakpoints() throws if NAs are mixed with other column values", { expect_snapshot_error( layout_columns(col_widths = breakpoints(sm = c(-1, NA, 1))) ) }) test_that("bs_css_grid_width_classes() warns when too many column widths", { expect_snapshot_warning( expect_equal( col_width_grid_classes(breakpoints(md = 1:4), 3), c("g-col-md-1", "g-col-md-2", "g-col-md-3") ) ) }) test_that("bs_css_grid_width_classes()", { expect_equal( col_width_grid_classes(breakpoints(md = 6), 3), c("g-col-md-6", "g-col-md-6", "g-col-md-6") ) expect_equal( col_width_grid_classes(breakpoints(lg = c(4, 8)), 3), c("g-col-lg-4", "g-col-lg-8", "g-col-lg-4") ) expect_equal( col_width_grid_classes(breakpoints(lg = c(12)), n_kids = 3), c("g-col-lg-12", "g-col-lg-12", "g-col-lg-12") ) # accounts for leading and trailing empty columns expect_equal( col_width_grid_classes(breakpoints(lg = c(-1, 4, 6, -1)), n_kids = 3), c("g-start-lg-2 g-col-lg-4", "g-col-lg-6", "g-start-lg-2 g-col-lg-4") ) # accounts for trailing empty columns (restarts on first column with class if needed) expect_equal( col_width_grid_classes(breakpoints(lg = c(1, 3, -1, 6, -1)), n_kids = 4), c("g-col-lg-1", "g-col-lg-3", "g-start-lg-6 g-col-lg-6", "g-start-lg-1 g-col-lg-1") ) # accounts for trailing empty columns (restarts on first column without class if possible) expect_equal( col_width_grid_classes(breakpoints(lg = c(4, -1, 6, -1)), n_kids = 3), c("g-col-lg-4", "g-start-lg-6 g-col-lg-6", "g-col-lg-4") ) # doesn't allow empty columns to cause an empty row due to row break # skipping 8 columns would start the second row on column 5, but the next 9 # column-item would cause a row break, leaving an empty row (which we avoid) expect_equal( col_width_grid_classes(breakpoints(lg = c(8, -8, 9)), n_kids = 4), c("g-col-lg-8", "g-col-lg-9", "g-col-lg-8", "g-col-lg-9") ) # Same as above, except that 8 columns *will* fit on next row with an offset expect_equal( col_width_grid_classes(breakpoints(lg = c(8, -8, 8)), n_kids = 4), c("g-col-lg-8", "g-start-lg-5 g-col-lg-8", "g-col-lg-8", "g-start-lg-5 g-col-lg-8") ) # recycles the pattern to match number of kids expect_equal( col_width_grid_classes(breakpoints(lg = c(5, -2, 5, 12)), n_kids = 7), c( "g-col-lg-5", "g-start-lg-8 g-col-lg-5", "g-col-lg-12", # repeats "g-col-lg-5", "g-start-lg-8 g-col-lg-5", "g-col-lg-12", # repeats (partially) "g-col-lg-5" ) ) # variant of previous test where first/last columns are empty expect_equal( col_width_grid_classes(breakpoints(lg = c(-1, 5, 5, -1, 12)), n_kids = 7), c( "g-start-lg-2 g-col-lg-5", "g-col-lg-5", "g-col-lg-12", # repeats "g-start-lg-2 g-col-lg-5", "g-col-lg-5", "g-col-lg-12", # repeats (partially) "g-start-lg-2 g-col-lg-5" ) ) }) test_that("breakpoint_columns() throws if a column is 0", { expect_error( col_width_grid_classes(breakpoints(md = c(-1, 0, 1)), 3) ) }) test_that("breakpoint_columns() throws if no columns are positive", { expect_error( col_width_grid_classes(breakpoints(md = -1), 1) ) expect_error( col_width_grid_classes(breakpoints(md = c(-1, -1, -1)), 3) ) }) test_that("impute_col_spec() auto layout with col_widths = NA", { get_col_spec <- function(x, n_kids) { spec <- impute_col_spec(x, n_kids) list( n_cols = spec$n_cols, col_widths = as_column_breakpoints(spec$col_widths) ) } kids_1 <- get_col_spec(NA, 1) # bare NA is the same as NA breakpoints at sm and lg expect_equal( get_col_spec(breakpoints(sm = NA, lg = NA), 1), kids_1 ) expect_equal(kids_1$n_cols, 1) expect_equal(kids_1$col_widths$sm, list(width = 1, before = 0, after = 0)) kids_2 <- get_col_spec(NA, 2) expect_equal(kids_2$n_cols, 2) expect_equal(kids_2$col_widths$sm, list(width = 1, before = 0, after = 0)) kids_3 <- get_col_spec(NA, 3) expect_equal(kids_3$n_cols, 3) expect_equal(kids_3$col_widths$sm, list(width = 1, before = 0, after = 0)) kids_4 <- get_col_spec(NA, 4) expect_equal(kids_4$n_cols, 8) expect_equal(kids_4$col_widths$sm, list(width = 4, before = 0, after = 0)) expect_equal(kids_4$col_widths$lg, list(width = 2, before = 0, after = 0)) kids_5 <- get_col_spec(NA, 5) expect_equal(kids_5$n_cols, 5 * 2) expect_equal(kids_5$col_widths$sm, list(width = 5, before = 0, after = 0)) expect_equal(kids_5$col_widths$lg, list(width = 2, before = 0, after = 0)) kids_6 <- get_col_spec(NA, 6) expect_equal(kids_6$n_cols, 6 * 2) expect_equal(kids_6$col_widths$sm, list(width = 6, before = 0, after = 0)) expect_equal(kids_6$col_widths$lg, list(width = 2, before = 0, after = 0)) kids_7 <- get_col_spec(NA, 7) expect_equal(kids_7$n_cols, 7 * 2) expect_equal(kids_7$col_widths$sm, list(width = 7, before = 0, after = 0)) expect_equal(kids_7$col_widths$lg, list(width = 2, before = 0, after = 0)) kids_8 <- get_col_spec(NA, 8) expect_equal(kids_8$n_cols, 12) expect_equal(kids_8$col_widths$sm, list(width = 6, before = 0, after = 0)) expect_equal(kids_8$col_widths$lg, list(width = 3, before = 0, after = 0)) }) test_that("impute_col_spec() missing smaller breakpoints inherit from lg+", { expect_equal( impute_col_spec(breakpoints(lg = c(4, -4, 4)), 2)$col_widths, breakpoints( md = c(4, -4, 4), lg = c(4, -4, 4) ) ) expect_equal( impute_col_spec(breakpoints(xl = c(4, -4, 4)), 2)$col_widths, breakpoints( md = c(4, -4, 4), xl = c(4, -4, 4) ) ) expect_equal( impute_col_spec(breakpoints(xxl = c(4, -4, 4)), 2)$col_widths, breakpoints( md = c(4, -4, 4), xxl = c(4, -4, 4) ) ) }) test_that("impute_col_spec() base case", { expect_equal( impute_col_spec(1:3, 6), list(n_cols = 12, col_widths = breakpoints(md = 1:3)) ) }) test_that("row_heights_css_vars() decides fr/px for numeric, passes character", { expect_equal( row_heights_css_vars(breakpoints(md = c(2, 1)))$style, "--bslib-grid--row-heights--md:2fr 1fr;" ) expect_equal( row_heights_css_vars(breakpoints(md = list(2, 1)))$style, "--bslib-grid--row-heights--md:2fr 1fr;" ) expect_equal( row_heights_css_vars(breakpoints(md = list("auto", 1)))$style, "--bslib-grid--row-heights--md:auto 1fr;" ) expect_equal( row_heights_css_vars(breakpoints(md = list("10px", 1)))$style, "--bslib-grid--row-heights--md:10px 1fr;" ) }) test_that("layout_column_wrap() handles deprecated width as first arg", { # first arg is fractional lifecycle::expect_deprecated( lc_implicit_width_frac <- layout_column_wrap(1/2, "one", "two") ) expect_equal( as.character(lc_implicit_width_frac), as.character(layout_column_wrap(width = 1/2, "one", "two")) ) # first arg is explicitly px character lifecycle::expect_deprecated( lc_implicit_width_px <- layout_column_wrap("400px", "one", "two") ) expect_equal( as.character(lc_implicit_width_px), as.character(layout_column_wrap(width = "400px", "one", "two")) ) # first arg is px, but numeric lifecycle::expect_deprecated( lc_implicit_width_px_implied <- layout_column_wrap(365, "one", "two") ) expect_equal( as.character(lc_implicit_width_px_implied), as.character(layout_column_wrap(width = 365, "one", "two")) ) # first arg is NULL lifecycle::expect_deprecated( lc_implicit_width_null <- layout_column_wrap(NULL, "one", "two") ) expect_equal( as.character(lc_implicit_width_null), as.character(layout_column_wrap(width = NULL, "one", "two")) ) # first arg is not a CSS unit rlang::local_options(lifecycle_verbosity = "warning") testthat::expect_silent( as.character(layout_column_wrap("1ft", "one", "two")) ) })