# if running manually, please run the following line first: # source("tests/testthat/setup.R") tester <- function(travel_matrix = smaller_matrix, land_use_data = get("land_use_data", envir = parent.frame()), opportunity = "jobs", travel_cost = "travel_time", interval = c(10, 30), interval_increment = 1, summary_function = stats::median, group_by = "mode", active = TRUE) { cumulative_interval( travel_matrix, land_use_data, opportunity, travel_cost, interval, interval_increment, summary_function, group_by, active ) } test_that("raises errors due to incorrect input", { expect_error(tester(interval = "banana")) expect_error(tester(interval = 3)) expect_error(tester(interval = c(-1, 10))) expect_error(tester(interval = c(11, 10))) expect_error(tester(interval = c(10, 10))) expect_error(tester(interval = c(1, Inf))) expect_error(tester(interval = c(1, NA))) expect_error(tester(interval = list("a"))) expect_error(tester(interval = list())) expect_error(tester(interval = list(c(10, 20), c(10, 20)))) expect_error(tester(interval = list(3))) expect_error(tester(interval = list(c(-1, 10)))) expect_error(tester(interval = list(c(11, 10)))) expect_error(tester(interval = list(c(10, 10)))) expect_error(tester(interval = list(c(1, Inf)))) expect_error(tester(interval = list(c(1, NA)))) expect_error(tester(interval_increment = "a")) expect_error(tester(interval_increment = Inf)) expect_error(tester(interval_increment = c(1, 1))) expect_error(tester(interval_increment = -1)) expect_error(tester(summary_function = "test")) expect_error(tester(summary_function = readRDS)) expect_error(tester(summary_function = identity)) expect_error(tester(opportunity = 1)) expect_error(tester(opportunity = c("schools", "jobs"))) expect_error(tester(travel_cost = 1)) expect_error(tester(travel_cost = c("travel_time", "monetary_cost"))) expect_error(tester(group_by = 1)) expect_error(tester(group_by = NA)) expect_error(tester(group_by = "from_id")) expect_error(tester(group_by = c("mode", "mode"))) expect_error(tester(active = 1)) expect_error(tester(active = c(TRUE, TRUE))) expect_error(tester(active = NA)) expect_error(tester(as.list(travel_matrix))) expect_error(tester(travel_matrix[, .(oi = from_id, to_id, travel_time)])) expect_error(tester(travel_matrix[, .(from_id, oi = to_id, travel_time)])) expect_error( tester( travel_matrix[, .(from_id, to_id, oi = travel_time)], travel_cost = "travel_time" ) ) expect_error( tester( travel_matrix[, .(from_id, to_id, travel_time, oi = mode)], group_by = "mode" ) ) expect_error(tester(as.list(land_use_data))) expect_error(tester(land_use_data = land_use_data[, .(oi = id, jobs)])) expect_error( tester( land_use_data = land_use_data[, .(id, oi = jobs)], opportunity = "jobs" ) ) }) test_that("throws warning if travel_matrix extra col", { # i.e. col not listed in travel_cost and by_col expect_warning(tester(group_by = character(0))) }) test_that("returns a dataframe whose class is the same as travel_matrix's", { result <- tester() expect_is(result, "data.table") result <- tester(land_use_data = as.data.frame(land_use_data)) expect_is(result, "data.table") result <- tester(as.data.frame(smaller_matrix)) expect_false(inherits(result, "data.table")) expect_is(result, "data.frame") result <- tester( as.data.frame(smaller_matrix), land_use_data = as.data.frame(land_use_data) ) expect_false(inherits(result, "data.table")) expect_is(result, "data.frame") }) test_that("result has correct structure", { result <- tester() expect_true(ncol(result) == 3) expect_is(result$id, "character") expect_is(result$mode, "character") expect_is(result$jobs, "integer") result <- tester(opportunity = "schools") expect_true(ncol(result) == 3) expect_is(result$id, "character") expect_is(result$mode, "character") expect_is(result$schools, "integer") suppressWarnings(result <- tester(group_by = character(0))) expect_true(ncol(result) == 2) expect_is(result$id, "character") expect_is(result$jobs, "integer") result <- tester( data.table::data.table( mode = character(), from_id = character(), to_id = character(), travel_time = integer() ) ) expect_true(ncol(result) == 3) expect_true(nrow(result) == 0) expect_is(result$id, "character") expect_is(result$mode, "character") expect_is(result$jobs, "integer") result <- tester(interval = list(c(10, 30), c(20, 30))) expect_true(ncol(result) == 4) expect_is(result$id, "character") expect_is(result$mode, "character") expect_is(result$interval, "character") expect_is(result$jobs, "integer") }) test_that("input data sets remain unchanged", { original_smaller_matrix <- travel_matrix[1:10] original_land_use_data <- readRDS(file.path(data_dir, "land_use_data.rds")) result <- tester() # subsets in other functions tests set smaller_matrix index data.table::setindex(smaller_matrix, NULL) expect_equal(original_smaller_matrix, smaller_matrix) expect_equal(original_land_use_data, land_use_data) }) test_that("active and passive accessibility is correctly calculated", { selected_ids <- c( "89a88cdb57bffff", "89a88cdb597ffff", "89a88cdb5b3ffff", "89a88cdb5cfffff", "89a88cd909bffff" ) smaller_travel_matrix <- travel_matrix[ from_id %in% selected_ids & to_id %in% selected_ids ] result <- tester( smaller_travel_matrix, interval = c(40, 45), group_by = "mode" ) expected_result <- data.table::data.table( id = rep(selected_ids, 2), mode = rep(c("transit", "transit2"), each = 5), jobs = rep(as.integer(c(82, 517, 517, 304, 0)), 2) ) expect_identical(result, expected_result) result <- tester( smaller_travel_matrix, interval = c(40, 45), opportunity = "population", group_by = "mode", active = FALSE ) expected_result <- data.table::data.table( id = rep(selected_ids, 2), mode = rep(c("transit", "transit2"), each = 5), population = rep(as.integer(c(1946, 3457, 2363, 4552, 0)), 2) ) expect_identical(result, expected_result) # with more than one interval result <- tester( smaller_travel_matrix, interval = list(c(40, 45), c(40, 50)), group_by = "mode" ) expected_result <- data.table::data.table( id = rep(selected_ids, 4), mode = rep(rep(c("transit", "transit2"), each = 5), 2), interval = rep(c("[40,45]", "[40,50]"), each = 10), jobs = c( rep(as.integer(c(82, 517, 517, 304, 0)), 2), rep(as.integer(c(82, 599, 599, 499, 0)), 2) ) ) expect_identical(result, expected_result) result <- tester( smaller_travel_matrix, interval = list(c(40, 45), c(40, 50)), opportunity = "population", group_by = "mode", active = FALSE ) expected_result <- data.table::data.table( id = rep(selected_ids, 4), mode = rep(rep(c("transit", "transit2"), each = 5), 2), interval = rep(c("[40,45]", "[40,50]"), each = 10), population = c( rep(as.integer(c(1946, 3457, 2363, 4552, 0)), 2), rep(as.integer(c(5404, 4552, 2363, 4552, 0)), 2) ) ) expect_identical(result, expected_result) }) test_that("summarizes the result according to summary function", { selected_ids <- c( "89a88cdb57bffff", "89a88cdb597ffff", "89a88cdb5b3ffff", "89a88cdb5cfffff", "89a88cd909bffff" ) smaller_travel_matrix <- travel_matrix[ from_id %in% selected_ids & to_id %in% selected_ids ] result <- tester( smaller_travel_matrix, interval = c(40, 45), summary_function = min, group_by = "mode" ) expected_result <- data.table::data.table( id = rep(selected_ids, 2), mode = rep(c("transit", "transit2"), each = 5), jobs = rep(as.integer(c(82, 408, 408, 109, 0)), 2) ) expect_identical(result, expected_result) result <- tester( smaller_travel_matrix, interval = c(40, 45), summary_function = mean, group_by = "mode" ) expected_result <- data.table::data.table( id = rep(selected_ids, 2), mode = rep(c("transit", "transit2"), each = 5), jobs = rep(as.integer(c(82, 512, 508, 304, 0)), 2) ) expect_identical(result, expected_result) }) test_that("accessibility is correctly calculated when ids are missing", { selected_ids <- c( "89a88cdb57bffff", "89a88cdb597ffff", "89a88cdb5b3ffff", "89a88cdb5cfffff", "89a88cd909bffff" ) smaller_travel_matrix <- travel_matrix[ from_id %in% selected_ids & to_id %in% selected_ids ] result <- tester( smaller_travel_matrix, interval = c(5, 6), summary_function = min, group_by = "mode" ) expected_result <- data.table::data.table( id = rep(selected_ids[order(selected_ids)], each = 2), mode = rep(c("transit", "transit2"), 5), jobs = rep(as.integer(c(0, 0, 0, 0, 0)), 2) ) expect_identical(result, expected_result) }) test_that("interval_increment arg is being used", { # hard to "perfectly" assess if the interval_increment value is being applied # correctly, but the code is trivial enough to let us say that it's correctly # applied if the results are different when using different increments selected_ids <- c( "89a88cdb57bffff", "89a88cdb597ffff", "89a88cdb5b3ffff", "89a88cdb5cfffff", "89a88cd909bffff" ) smaller_travel_matrix <- travel_matrix[ from_id %in% selected_ids & to_id %in% selected_ids ] result_increment_1 <- tester( smaller_travel_matrix, interval_increment = 1, interval = c(5, 7) ) result_increment_2 <- tester( smaller_travel_matrix, interval_increment = 2, interval = c(5, 7) ) expect_false(identical(result_increment_1, result_increment_2)) }) test_that("works even if travel_matrix and land_use has specific colnames", { expected_result <- tester() smaller_matrix[, opportunity := "oi"] result <- suppressWarnings(tester(smaller_matrix)) expect_identical(expected_result, result) smaller_matrix[, opportunity := NULL] smaller_matrix[, travel_cost := "oi"] result <- suppressWarnings(tester(smaller_matrix)) expect_identical(expected_result, result) smaller_matrix[, travel_cost := NULL] smaller_matrix[, groups := "oi"] result <- suppressWarnings(tester(smaller_matrix)) expect_identical(expected_result, result) smaller_matrix[, groups := NULL] land_use_data[, opportunity := "oi"] result <- suppressWarnings(tester(land_use_data = land_use_data)) expect_identical(expected_result, result) land_use_data[, opportunity := NULL] })