tests/testthat/test-datePad.R

# Helper: one week of hourly data with some rows removed to create gaps
make_gappy <- function(remove_idx = c(2, 5, 10)) {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1:7)
  dat[-remove_idx, ]
}

# --- Basic output ------------------------------------------------------------

test_that("datePad returns same data when no gaps exist", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1)

  result <- datePad(dat)

  expect_equal(nrow(result), nrow(dat))
})

test_that("datePad fills gaps to produce a contiguous hourly sequence", {
  gappy <- make_gappy()
  full <- selectByDate(mydata, year = 2003, month = 1, day = 1:7)

  result <- datePad(gappy)

  expect_equal(nrow(result), nrow(full))
})

test_that("datePad result covers exactly min to max date of input", {
  gappy <- make_gappy()
  result <- datePad(gappy)

  expect_equal(min(result$date), min(gappy$date))
  expect_equal(max(result$date), max(gappy$date))
})

test_that("datePad produces no duplicate dates", {
  gappy <- make_gappy()
  result <- datePad(gappy)

  expect_equal(anyDuplicated(result$date), 0L)
})

test_that("datePad introduced rows have NA for pollutant values", {
  gappy <- make_gappy()
  result <- datePad(gappy)

  added_dates <- setdiff(result$date, gappy$date)
  added_rows <- result[result$date %in% added_dates, ]

  expect_true(all(is.na(added_rows$no2)))
})

test_that("datePad preserves original non-gap rows unchanged", {
  gappy <- make_gappy()
  result <- datePad(gappy)

  kept <- result[result$date %in% gappy$date, ]
  expect_equal(kept$no2, gappy$no2)
})

# --- start.date / end.date ---------------------------------------------------

test_that("datePad respects explicit start.date earlier than data minimum", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 3:7)
  early_start <- as.POSIXct("2003-01-01 00:00:00", tz = "GMT")

  result <- datePad(dat, start.date = early_start)

  expect_equal(min(result$date), early_start)
})

test_that("datePad respects explicit end.date later than data maximum", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1:5)
  late_end <- as.POSIXct("2003-01-10 23:00:00", tz = "GMT")

  result <- datePad(dat, end.date = late_end)

  expect_equal(max(result$date), late_end)
})

# --- interval ----------------------------------------------------------------

test_that("datePad with interval = '30 min' doubles the row count on gap-free data", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1)

  result <- datePad(dat, interval = "30 min")

  # 24-hour day at 30-min intervals = 48 rows vs 24 at hourly
  expect_equal(nrow(result), 2L * nrow(dat) - 1L)
})

test_that("datePad timestamps are evenly spaced at requested interval", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1)
  result <- datePad(dat, interval = "30 min")

  diffs <- as.numeric(diff(result$date), units = "mins")
  expect_true(all(diffs == 30))
})

# --- fill = TRUE -------------------------------------------------------------

test_that("datePad fill = TRUE carries forward block values into sub-intervals", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1)
  result <- datePad(dat, interval = "30 min", fill = TRUE)

  # Each pair of rows (on-the-hour and half-past) should share the same no2 value
  on_hour <- result[as.numeric(format(result$date, "%M")) == 0, ]
  half_past <- result[as.numeric(format(result$date, "%M")) == 30, ]

  # Align by removing the last half-past (no following block)
  n <- min(nrow(on_hour), nrow(half_past))
  expect_equal(on_hour$no2[seq_len(n)], half_past$no2[seq_len(n)])
})

test_that("datePad fill = TRUE and fill = FALSE produce different results when interval is finer", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1)
  filled <- datePad(dat, interval = "30 min", fill = TRUE)
  unfilled <- datePad(dat, interval = "30 min", fill = FALSE)

  # unfilled half-past rows should be NA; filled ones should not (mostly)
  half_past_filled <- filled[as.numeric(format(filled$date, "%M")) == 30, ]
  half_past_unfilled <- unfilled[
    as.numeric(format(unfilled$date, "%M")) == 30,
  ]

  expect_gt(
    sum(!is.na(half_past_filled$no2)),
    sum(!is.na(half_past_unfilled$no2))
  )
})

# --- Edge cases --------------------------------------------------------------

test_that("datePad returns input unchanged for single-row data frame", {
  single <- mydata[1, ]

  result <- datePad(single)

  expect_equal(nrow(result), 1L)
  expect_equal(result$date, single$date)
})

test_that("datePad errors when 'date' column is absent", {
  no_date <- data.frame(no2 = 1:5)

  expect_error(datePad(no_date), regexp = "date")
})

test_that("datePad preserves POSIXct timezone", {
  dat <- selectByDate(mydata, year = 2003, month = 1, day = 1:3)
  result <- datePad(make_gappy())

  expect_equal(attr(result$date, "tzone"), attr(mydata$date, "tzone"))
})

Try the openair package in your browser

Any scripts or data that you put into this service are public.

openair documentation built on April 2, 2026, 9:07 a.m.