Emphasizing the testing functionality, some simple functions following the syntax of expect_xyz
were created, enacting as cohesive components to achieve the task of testing a function for an expected complexity class, as per one of the base objectives.
Function Details : Parameters
expect_x_time
- …: The arguments passed onto the time quantifier for the required function.
expect_time_complexity
- complexity.class : A string denoting the expected complexity class.
- …: Extracts the arguments from the above function when used in conjunction (or when the above function is called), otherwise requires them again if used separately (not meant to be).
- f: A function to operate on the arguments given by the ellipsis, which by default is
asymptoticTimings
.
expect_complexity_class
- object: Any chunk of code which returns a string to be compared against the expected string.
- complexity.class: Same as above, its a string which is passed directly from
expect_time_complexity
based onx
inexpect_x_time
, which denotes the expected complexity class.
Function Details : Implementation
To make it convenient for testing, the expect_x_time
(where again x
denotes the complexity class, such as linear
, loglinear
etc.) functions internally call expect_time_complexity
which carries over the arguments supplied to asymptoticTimings
by default and then tests for the expected complexity class with the data frame so returned passed onto asymptoticTimeComplexityClass
, which in turn is passed as the first argument to expect_complexity_class
along with the complexity class (as the second arg). The object is captured inside with quasi-labelling (utilizing quasi_label
function from testthat
) and quosure creation via the enquo()
function. The captured object’s value is compared with the complexity class inside an expect
function’s first argument, with the inclusion of an appropriate error message for the second argument. (failure_message
) Put altogether, this helper function acts as the checking stone with an appropriate error message with a call to traceback shown in the case of test failure.
Function Details : Return value
expect_complexity_class
invisibly returns the input object, so as to allow chaining of expectations or expect functions. If the expect()
block test for ok
fails then an error message governed by the second parameter of expect()
is returned. expect_time_complexity
and expect_x_time
functions follow the same since they are tied together and link back to it.
Usage
Just pass the parameters as accepted in asymptoticTimings
to the expect_x_time
function of your choice:
test_that("PeakSegOptimal::PeakSegPDPA() function test", {
# Passes:
expect_loglinear_time({
data.vec <- rpois(N, 1)
PeakSegOptimal::PeakSegPDPA(data.vec, max.segments = 3L)}, data.sizes = 10^seq(1, 4, by = 0.5))
# Fails:
expect_quadratic_time({
data.vec <- rpois(N, 1)
PeakSegOptimal::PeakSegPDPA(data.vec, max.segments = 3L)}, data.sizes = 10^seq(1, 4, by = 0.5))
})
Code
expect_complexity_class
expect_complexity_class <- function(object, complexity.class) { # Use quasi-labelling to capture value and label of passed object: actual.obj <- quasi_label(enquo(object), arg = "object") # Use the expect function: expect( # Set ok or success condition when the object returned matches with the complexity class supplied: actual.obj$val == complexity.class, # If failure of the above occurs, print a suitable error message regarding complexity message: sprintf("Complexity mismatch: Expected %s complexity, instead of the predicted %s complexity from %s.", complexity.class, actual.obj$val, actual.obj$lab) ) # Return the object invisibly, to allow chaining of expectations/expect-functions: invisible(actual.obj$val) }
expect_time_complexity
expect_time_complexity = function(complexity.class, ..., f) { # Use asymptoticTimings if function is not supplied: f <- if(missing(f)) asymptoticTimings else f # Collect the data frame returned by asymptoticTimings with parameters passed through the ellipsis: timings.df <- f(...) # Use the helper function to check/test for complexity class mismatch: expect_complexity_class(asymptoticTimeComplexityClass(timings.df), complexity.class) }
expect_linear_time
expect_linear_time = function(...) { # Pass the arguments of this function to the time complexity testing helper function specifying the complexity class as linear: expect_time_complexity("linear", ...) }
expect_loglinear_time
expect_loglinear_time = function(...) { # Pass the arguments of this function to the time complexity testing helper function specifying the complexity class as loglinear: expect_time_complexity("loglinear", ...) }
expect_quadratic_time
expect_quadratic_time = function(...) { # Pass the arguments of this function to the time complexity testing helper function specifying the complexity class as quadratic: expect_time_complexity("quadratic", ...) }
rxoygen-documented versions:
- expect_complexity_class
- expect_time_complexity
- expect_linear_time
- expect_loglinear_time
- expect_quadratic_time
Anirban | 07/30/2020 |