Skip to content

Commit

Permalink
Merge pull request #96 from clhunsen/cumulative-ranges
Browse files Browse the repository at this point in the history
Cumulative ranges

Reviewed-by: Thomas Bock <[email protected]>
  • Loading branch information
bockthom authored Feb 27, 2018
2 parents 22e1ba5 + 22124ee commit e9183bd
Show file tree
Hide file tree
Showing 5 changed files with 1,046 additions and 215 deletions.
304 changes: 304 additions & 0 deletions tests/test-misc.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,310 @@
## (c) Thomas Bock, 2017
## [email protected]


## / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
## Date handling -----------------------------------------------------------

##
## Parse date from a string.
##

test_that("Parse date from a string.", {

## full date:
date.string = "2018-02-22 10:44:27"
date.posixct = as.POSIXct(strptime(date.string, format = "%Y-%m-%d %H:%M:%S"))
## 1) from string
expect_equal(get.date.from.string(date.string), date.posixct, info = "From string.")
## 2) from POSIXct
expect_equal(get.date.from.string(date.posixct), date.posixct, info = "From POSIXct.")

## partial date:
## 1) no seconds
date.string = "2018-02-22 10:22"
date.posixct = as.POSIXct(strptime(date.string, format = "%Y-%m-%d %H:%M"))
expect_equal(get.date.from.string(date.string), date.posixct, info = "Partial date (no seconds).")
## 2) no seconds, no minutes
date.string = "2018-02-22 10"
date.posixct = as.POSIXct(strptime(date.string, format = "%Y-%m-%d %H"))
expect_equal(get.date.from.string(date.string), date.posixct, info = "Partial date (no seconds, no minutes).")
## 3) no time
date.string = "2018-02-22"
date.posixct = as.POSIXct(strptime(date.string, format = "%Y-%m-%d"))
expect_equal(get.date.from.string(date.string), date.posixct, info = "Partial date (no time).")

})

##
## Parse date from a UNIX timestamp.
##

test_that("Parse date from a UNIX timestamp.", {

date.numeric = 1519296267
date.string = "2018-02-22 10:44:27"
date.posixct = get.date.from.string(date.string)

expect_equal(get.date.from.unix.timestamp(date.numeric), date.posixct, info = "From string.")

})

##
## Format a POSIXct object.
##

test_that("Format a POSIXct object.", {

## full date:
date.string = "2018-02-22 10:44:27"
date.posixct = get.date.from.string(date.string)
## 1) from string
expect_identical(get.date.string(date.string), date.string, info = "From string.")
## 2) from POSIXct
expect_identical(get.date.string(date.posixct), date.string, info = "From POSIXct.")

## partial date:
## 1) no seconds
date.string = "2018-02-22 10:44"
date.string.formatted = "2018-02-22 10:44:00"
date.posixct = get.date.from.string(date.string)
expect_equal(get.date.string(date.posixct), date.string.formatted, info = "Partial date (no seconds).")
## 2) no seconds, no minutes
date.string = "2018-02-22 10"
date.string.formatted = "2018-02-22 10:00:00"
date.posixct = get.date.from.string(date.string)
expect_equal(get.date.string(date.posixct), date.string.formatted, info = "Partial date (no seconds, no minutes).")
## 3) no time
date.string = "2018-02-22"
date.string.formatted = "2018-02-22 00:00:00"
date.posixct = get.date.from.string(date.string)
expect_equal(get.date.string(date.posixct), date.string.formatted, info = "Partial date (no time).")

})

##
## Generate a date sequence.
##

test_that("Generate a date sequence.", {

## parameter configuration
time.period = "2 hours"
time.period.duration = lubridate::duration(time.period)

start.date = "2018-02-22 00:00:00"
start.date.posixct = get.date.from.string(start.date)

## short last range:
end.date.short = "2018-02-22 06:05:01"
end.date.short.posixct = get.date.from.string(end.date.short)
## 1) expected results
expected = get.date.from.string(c("2018-02-22 00:00:00", "2018-02-22 02:00:00",
"2018-02-22 04:00:00", "2018-02-22 06:00:00",
"2018-02-22 06:05:01"))
## 2) From string.
result = generate.date.sequence(start.date, end.date.short, time.period)
expect_equal(result, expected, info = "Date sequence from strings.")
## 3) From POSIXct.
result = generate.date.sequence(start.date.posixct, end.date.short.posixct, time.period)
expect_equal(result, expected, info = "Date sequence from dates.")
## 4) With lubridate::duration.
result = generate.date.sequence(start.date.posixct, end.date.short.posixct, time.period.duration)
expect_equal(result, expected, info = "Date sequence with lubridate::duration")

## precise last range:
end.date.precise = "2018-02-22 06:00:00"
end.date.precise.posixct = get.date.from.string(end.date.precise)
## 1) expected results
expected = get.date.from.string(c("2018-02-22 00:00:00", "2018-02-22 02:00:00",
"2018-02-22 04:00:00", "2018-02-22 06:00:00"))
## 2) From string.
result = generate.date.sequence(start.date, end.date.precise, time.period)
expect_equal(result, expected, info = "Date sequence from strings.")
## 3) From POSIXct.
result = generate.date.sequence(start.date.posixct, end.date.precise.posixct, time.period)
expect_equal(result, expected, info = "Date sequence from dates.")
## 4) With lubridate::duration.
result = generate.date.sequence(start.date.posixct, end.date.precise.posixct, time.period.duration)
expect_equal(result, expected, info = "Date sequence with lubridate::duration")

})


## / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
## Range construction and handling -----------------------------------------

##
## Construct consecutive and overlapping ranges.
##

test_that("Construct consecutive and overlapping ranges.", {

start = ("2018-01-01 00:00:00")
start.date = get.date.from.string(start)
end = ("2018-01-01 06:05:00")
end.date = get.date.from.string(end)
end.including = end.date + 1

## standard overlapping ranges:
## 1) expected results
expected.formatted = c(
"2018-01-01 00:00:00-2018-01-01 02:00:00",
"2018-01-01 01:30:00-2018-01-01 03:30:00",
"2018-01-01 03:00:00-2018-01-01 05:00:00",
"2018-01-01 04:30:00-2018-01-01 06:05:01"
)
expected.raw = lapply(expected.formatted, get.range.bounds)
names(expected.raw) = expected.formatted
## 2) formatted
result.formatted = construct.overlapping.ranges(start, end, time.period = "2 hours", overlap = "30 minutes", raw = FALSE)
expect_identical(result.formatted, expected.formatted, info = "Standard overlapping ranges (formatted).")
## 3) raw
result.raw = construct.overlapping.ranges(start, end, time.period = "2 hours", overlap = "30 minutes", raw = TRUE)
expect_equal(result.raw, expected.raw, info = "Standard overlapping ranges (raw).")
## TODO use expect_identical here? why failing?

## non-overlapping/consecutive ranges:
## 1) expected results
expected.formatted = c(
"2018-01-01 00:00:00-2018-01-01 02:00:00",
"2018-01-01 02:00:00-2018-01-01 04:00:00",
"2018-01-01 04:00:00-2018-01-01 06:00:00",
"2018-01-01 06:00:00-2018-01-01 06:05:01"
)
expected.raw = lapply(expected.formatted, get.range.bounds)
names(expected.raw) = expected.formatted
## 2) formatted
result.formatted = construct.overlapping.ranges(start.date, end.date, time.period = "2 hours", overlap = 0, raw = FALSE)
expect_identical(result.formatted, expected.formatted, info = "Non-overlapping ranges (formatted).")
## 3) raw
result.raw = construct.overlapping.ranges(start.date, end.date, time.period = "2 hours", overlap = 0, raw = TRUE)
expect_equal(result.raw, expected.raw, info = "Non-overlapping ranges (raw).")
## TODO use expect_identical here? why failing?
## 4) matching with consecutive ranges
results.raw = construct.consecutive.ranges(start.date, end.date, time.period = "2 hours", raw = FALSE)
expect_equal(result.raw, expected.raw, info = "Non-overlapping ranges (consecutive).")

## illegal overlap
expect_error(
construct.overlapping.ranges(start.date, end.date, time.period = "2 hours", overlap = "1 year", raw = FALSE),
info = "Error expected (illegal overlap)."
)
})

##
## Construct cumulative ranges.
##

test_that("Construct cumulative ranges.", {

start = ("2018-01-01 00:00:00")
start.date = get.date.from.string(start)
end = ("2018-01-01 06:05:00")
end.date = get.date.from.string(end)
end.including = end.date + 1

## standard overlapping ranges:
## 1) expected results
expected.formatted = c(
"2018-01-01 00:00:00-2018-01-01 02:00:00",
"2018-01-01 00:00:00-2018-01-01 04:00:00",
"2018-01-01 00:00:00-2018-01-01 06:00:00",
"2018-01-01 00:00:00-2018-01-01 06:05:01"
)
expected.raw = lapply(expected.formatted, get.range.bounds)
names(expected.raw) = expected.formatted
## 2) formatted
result.formatted = construct.cumulative.ranges(start, end, time.period = "2 hours", raw = FALSE)
expect_identical(result.formatted, expected.formatted, info = "Cumulative ranges (formatted).")
## 3) raw
result.raw = construct.cumulative.ranges(start, end, time.period = "2 hours", raw = TRUE)
expect_equal(result.raw, expected.raw, info = "Cumulative ranges (raw).")
## TODO use expect_identical here? why failing?
})

##
## Aggregate ranges.
##

test_that("Aggregate ranges.", {

aggregation.level = c("range", "cumulative", "all.ranges",
"project.cumulative", "project.all.ranges",
"complete")

project.start = get.date.from.string("2017-12-01 00:00:00")
start = ("2018-01-01 00:00:00")
start.date = get.date.from.string(start)
end = ("2018-01-01 06:05:00")
end.date = get.date.from.string(end)
end.including = end.date + 1
project.end = get.date.from.string("2019-04-04 00:00:00")

## construct ranges to aggregate
ranges = construct.consecutive.ranges(start.date, end.date, time.period = "2 hours", raw = FALSE)
ranges.raw = construct.consecutive.ranges(start.date, end.date, time.period = "2 hours", raw = FALSE)

## get results
results = lapply(aggregation.level, function(level)
aggregate.ranges(ranges, project.start, project.end, level, raw = FALSE) ## FIXME raw = TRUE
)
names(results) = aggregation.level

## expected results
expected = list(
range = c(
"2018-01-01 00:00:00-2018-01-01 02:00:00",
"2018-01-01 02:00:00-2018-01-01 04:00:00",
"2018-01-01 04:00:00-2018-01-01 06:00:00",
"2018-01-01 06:00:00-2018-01-01 06:05:01"
),
cumulative = c(
"2018-01-01 00:00:00-2018-01-01 02:00:00",
"2018-01-01 00:00:00-2018-01-01 04:00:00",
"2018-01-01 00:00:00-2018-01-01 06:00:00",
"2018-01-01 00:00:00-2018-01-01 06:05:01"
),
all.ranges = c(
"2018-01-01 00:00:00-2018-01-01 06:05:01",
"2018-01-01 00:00:00-2018-01-01 06:05:01",
"2018-01-01 00:00:00-2018-01-01 06:05:01",
"2018-01-01 00:00:00-2018-01-01 06:05:01"
),
project.cumulative = c(
"2017-12-01 00:00:00-2018-01-01 02:00:00",
"2017-12-01 00:00:00-2018-01-01 04:00:00",
"2017-12-01 00:00:00-2018-01-01 06:00:00",
"2017-12-01 00:00:00-2018-01-01 06:05:01"
),
project.all.ranges = c(
"2017-12-01 00:00:00-2018-01-01 06:05:01",
"2017-12-01 00:00:00-2018-01-01 06:05:01",
"2017-12-01 00:00:00-2018-01-01 06:05:01",
"2017-12-01 00:00:00-2018-01-01 06:05:01"
),
complete = c(
"2017-12-01 00:00:00-2019-04-04 00:00:01",
"2017-12-01 00:00:00-2019-04-04 00:00:01",
"2017-12-01 00:00:00-2019-04-04 00:00:01",
"2017-12-01 00:00:00-2019-04-04 00:00:01"
)
)

lapply(aggregation.level, function(aggregation.level) {
expected.ranges = expected[[aggregation.level]]
results.ranges = results[[aggregation.level]]

expect_identical(results.ranges, expected.ranges)
})
})

##
## Parse ranges.
##

test_that("Parse range", {

range.input = c("2012-07-10 15:58:00-2012-07-15 16:02:00",
"2012-07-10-2012-07-15 16:02:00",
"2012-07-10 15:58:00-2012-07-15",
Expand All @@ -24,3 +327,4 @@ test_that("Parse range", {

expect_equal(actual.output, expected.output, "Parsed Range")
})

Loading

0 comments on commit e9183bd

Please sign in to comment.