# Test build_lines context('test build_lines') DT <- fread('../testdata/DT.csv') utm <- 'EPSG:32736' DT[, datetime := as.POSIXct(datetime)] test_that('DT is required', { expect_error( build_lines( DT = NULL, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'DT must be provided' ) }) test_that('coords, id, crs, sortBy must be provided, proper format', { expect_error( build_lines( DT = DT, id = NULL, coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'id must be provided' ) expect_error( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = NULL, sortBy = 'datetime' ), 'crs must be provided' ) expect_error( build_lines( DT = DT, id = 'ID', coords = NULL, crs = utm, sortBy = 'datetime' ), 'coords must be provided' ) expect_error( build_lines( DT = DT, id = 'ID', coords = c('ID', 'ID'), crs = utm, sortBy = 'datetime' ), 'coords must be of class numeric' ) expect_error( build_lines( DT = DT, id = 'ID', coords = c('X'), crs = utm, sortBy = 'datetime' ), 'coords must be length 2', fixed = FALSE ) expect_error( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = NULL ), 'sortBy must be provided' ) expect_error( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'ID' ), 'sortBy must be', fixed = FALSE ) }) test_that('column names must exist in DT', { expect_error( build_lines( DT = DT, id = 'ID', coords = c('potatoX', 'potatoY'), crs = utm, sortBy = 'datetime' ), 'not present in input', fixed = FALSE ) expect_error( build_lines( DT = DT, id = 'potato', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'not present in input', fixed = FALSE ) expect_error( build_lines( DT = DT, id = 'potato', coords = c('X', 'Y'), crs = utm, sortBy = 'potato' ), 'not present in input', fixed = FALSE ) }) test_that('returns same number of lines as unique IDs/splitBy provided', { # without splitBy expect_equal(nrow( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ) ), DT[, uniqueN(ID)]) # with splitBy DT[, jul := data.table::yday(as.POSIXct(datetime))] splitBy <- c('ID', 'jul') DT[, count := .N, by = splitBy] subDT <- DT[count >= 2] expect_equal(nrow( build_lines( DT = subDT, id = 'ID', coords = c('X', 'Y'), crs = utm, splitBy = 'jul', sortBy = 'datetime' ) ), nrow(unique(subDT[, .SD, .SDcols = splitBy]))) }) test_that("build lines warns if < 2 locs per ID/byField", { # for ID (one row's ID is "potato") copyDT <- copy(DT)[1, ID := 'potato'] expect_warning( build_lines( DT = copyDT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'some rows dropped, cannot build lines with less than two points' ) copyDT <- copy(DT)[1, ID := 'potato'] expect_warning( build_lines( DT = copyDT, id = 'ID', coords = c('X', 'Y'), crs = utm, splitBy = 'population', sortBy = 'datetime' ), 'some rows dropped, cannot build', fixed = FALSE ) }) test_that('splitBy and id provided are not correct format', { copyDT <- copy(DT)[, datetime := as.POSIXct(datetime)] expect_error( build_lines( DT = copyDT, id = 'datetime', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'id must be of class numeric/character/integer', fixed = FALSE ) expect_error( build_lines( DT = copyDT, id = 'ID', coords = c('X', 'Y'), crs = utm, splitBy = 'datetime', sortBy = 'datetime' ), 'splitBy must be of class numeric/character/integer', fixed = FALSE ) # with factor IDs copyDT <- copy(DT)[, ID := as.factor(ID)] expect_error( build_lines( DT = copyDT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'id must be of class numeric/character/integer', fixed = FALSE ) }) test_that('build_lines returns an sf object with LINESTRINGs', { expect_s3_class( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), 'sf' ) expect_in( 'LINESTRING', sf::st_geometry_type(build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ), by_geometry = FALSE) ) }) test_that('build_lines builds ordered lines', { base_lines <- build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ) random_lines <- build_lines( DT = DT[sample(.N)], id = 'ID', coords = c('X', 'Y'), crs = utm, sortBy = 'datetime' ) expect_equal( base_lines[order(base_lines$ID),], random_lines[order(random_lines$ID),] ) }) test_that('splitBy argument doesnt use splitBy column', { copyDT <- copy(DT) copyDT[, splitBy := as.IDate(datetime)] utm <- 'EPSG:32736' expect_equal( nrow(build_lines( DT = copyDT, id = 'ID', coords = c('X', 'Y'), crs = utm, splitBy = 'splitBy', sortBy = 'datetime' )), copyDT[, uniqueN(splitBy) * uniqueN(ID)] ) }) test_that('projection arg is deprecated', { expect_warning( build_lines( DT = DT, id = 'ID', coords = c('X', 'Y'), sortBy = 'datetime', projection = utm ), 'projection argument is deprecated' ) })