library(testthat) # most common expectations: # equality: expect_equal() and expect_identical() # regexp: expect_match() # catch-all: expect_true() and expect_false() # console output: expect_output() # messages: expect_message() # warning: expect_warning() # errors: expect_error() escapeString <- function(s) { t <- gsub("(\\\\)", "\\\\\\\\", s) t <- gsub("(\n)", "\\\\n", t) t <- gsub("(\r)", "\\\\r", t) t <- gsub("(\")", "\\\\\"", t) return(t) } prepStr <- function(s) { t <- escapeString(s) u <- eval(parse(text=paste0("\"", t, "\""))) if(s!=u) stop("Unable to escape string!") t <- paste0("\thtml <- \"", t, "\"") utils::writeClipboard(t) return(invisible()) } evaluationMode <- "sequential" processingLibrary <- "dplyr" description <- "test: sequential dplyr" countFunction <- "n()" isDevelopmentVersion <- (length(strsplit(packageDescription("pivottabler")$Version, "\\.")[[1]]) > 3) testScenarios <- function(description="test", releaseEvaluationMode="batch", releaseProcessingLibrary="dplyr", runAllForReleaseVersion=FALSE) { isDevelopmentVersion <- (length(strsplit(packageDescription("pivottabler")$Version, "\\.")[[1]]) > 3) if(isDevelopmentVersion||runAllForReleaseVersion) { evaluationModes <- c("sequential", "batch") processingLibraries <- c("dplyr", "data.table") } else { evaluationModes <- releaseEvaluationMode processingLibraries <- releaseProcessingLibrary } testCount <- length(evaluationModes)*length(processingLibraries) c1 <- character(testCount) c2 <- character(testCount) c3 <- character(testCount) c4 <- character(testCount) testCount <- 0 for(evaluationMode in evaluationModes) for(processingLibrary in processingLibraries) { testCount <- testCount + 1 c1[testCount] <- evaluationMode c2[testCount] <- processingLibrary c3[testCount] <- paste0(description, ": ", evaluationMode, " ", processingLibrary) c4[testCount] <- ifelse(processingLibrary=="data.table", ".N", "n()") } df <- data.frame(evaluationMode=c1, processingLibrary=c2, description=c3, countFunction=c4, stringsAsFactors=FALSE) return(df) } context("SMOKE TESTS") scenarios <- testScenarios("smoke tests: bhmtrains basic pivot") for(i in 1:nrow(scenarios)) { evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE)) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addRowDataGroups("TOC") pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # cat(paste(as.vector(pt$cells$asMatrix()), sep=", ", collapse=", ")) # prepStr(as.character(pt$getHtml())) res <- c(3079, 22865, 14487, 8594, 49025, 830, 63, 33792, NA, 34685, 3909, 22928, 48279, 8594, 83710) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
Arriva Trains Wales30798303909
CrossCountry228656322928
London Midland144873379248279
Virgin Trains85948594
Total490253468583710
" expect_equal(pt$cells$asMatrix(), matrix(res, nrow=5)) expect_identical(as.character(pt$getHtml()), html) }) } scenarios <- testScenarios("smoke tests: bhmtrains basic pivot two levels") for(i in 1:nrow(scenarios)) { if(!isDevelopmentVersion) break evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE)) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addColumnDataGroups("PowerType") pt$addRowDataGroups("TOC") pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # cat(paste(as.vector(pt$cells$asMatrix()), sep=", ", collapse=", ")) # prepStr(as.character(pt$getHtml())) res <- c(3079, 22133, 5638, 2137, 32987, NA, NA, 8849, 6457, 15306, NA, 732, NA, NA, 732, 3079, 22865, 14487, 8594, 49025, 830, 63, 5591, NA, 6484, NA, NA, 28201, NA, 28201, 830, 63, 33792, NA, 34685, 3909, 22928, 48279, 8594, 83710) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
DMUEMUHSTTotalDMUEMUTotal 
Arriva Trains Wales307930798308303909
CrossCountry2213373222865636322928
London Midland56388849144875591282013379248279
Virgin Trains2137645785948594
Total3298715306732490256484282013468583710
" expect_equal(pt$cells$asMatrix(), matrix(res, nrow=5)) expect_identical(as.character(pt$getHtml()), html) }) } scenarios <- testScenarios("smoke tests: bhmtrains basic pivot two levels expanded") for(i in 1:nrow(scenarios)) { if(!isDevelopmentVersion) break evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { skip_on_cran() library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE)) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addColumnDataGroups("PowerType", expandExistingTotals=TRUE) pt$addRowDataGroups("TOC") pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # cat(paste(as.vector(pt$cells$asMatrix()), sep=", ", collapse=", ")) # prepStr(as.character(pt$getHtml())) res <- c(3079, 22133, 5638, 2137, 32987, NA, NA, 8849, 6457, 15306, NA, 732, NA, NA, 732, 3079, 22865, 14487, 8594, 49025, 830, 63, 5591, NA, 6484, NA, NA, 28201, NA, 28201, 830, 63, 33792, NA, 34685, 3909, 22196, 11229, 2137, 39471, NA, NA, 37050, 6457, 43507, NA, 732, NA, NA, 732, 3909, 22928, 48279, 8594, 83710) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
DMUEMUHSTTotalDMUEMUTotalDMUEMUHSTTotal
Arriva Trains Wales3079307983083039093909
CrossCountry221337322286563632219673222928
London Midland563888491448755912820133792112293705048279
Virgin Trains213764578594213764578594
Total32987153067324902564842820134685394714350773283710
" expect_equal(pt$cells$asMatrix(), matrix(res, nrow=5)) expect_identical(as.character(pt$getHtml()), html) }) } if (requireNamespace("lubridate", quietly = TRUE)) { scenarios <- testScenarios("smoke tests: calculation filters") for(i in 1:nrow(scenarios)) { if(!isDevelopmentVersion) break evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(dplyr) library(lubridate) library(pivottabler) # get the date of each train and whether that date is a weekday or weekend trains <- bhmtrains %>% mutate(GbttDateTime=if_else(is.na(GbttArrival), GbttDeparture, GbttArrival), DayNumber=wday(GbttDateTime), WeekdayOrWeekend=ifelse(DayNumber %in% c(1,7), "Weekend", "Weekday")) # render the pivot table pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE)) pt$addData(trains) pt$addColumnDataGroups("TrainCategory") pt$addRowDataGroups("TOC") weekendFilter <- PivotFilters$new(pt, variableName="WeekdayOrWeekend", values="Weekend") pt$defineCalculation(calculationName="WeekendTrains", summariseExpression=countFunction, filters=weekendFilter, visible=FALSE) pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction, visible=FALSE) pt$defineCalculation(calculationName="WeekendTrainsPercentage", type="calculation", basedOn=c("WeekendTrains", "TotalTrains"), format="%.1f %%", calculationExpression="values$WeekendTrains/values$TotalTrains*100") pt$evaluatePivot() # pt$renderPivot() # sum(pt$cells$asMatrix(), na.rm=TRUE) # cat(paste(as.vector(pt$cells$asMatrix()), sep=", ", collapse=", ")) # prepStr(as.character(pt$getHtml())) res <- c(26.6320233842157, 23.7480865952329, 18.7892593359564, 24.4240167558762, 22.5823559408465, 17.710843373494, NA, 22.8693181818182, NA, 22.7043390514632, 24.7377845996419, 23.6828332170272, 21.6450216450216, 24.4240167558762, 22.6328992951858) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
Arriva Trains Wales26.6 %17.7 %24.7 %
CrossCountry23.7 %23.7 %
London Midland18.8 %22.9 %21.6 %
Virgin Trains24.4 %24.4 %
Total22.6 %22.7 %22.6 %
" expect_equal(sum(pt$cells$asMatrix(), na.rm=TRUE), 296.5828) expect_equal(pt$cells$asMatrix(), matrix(res, nrow=5)) expect_identical(as.character(pt$getHtml()), html) }) } } scenarios <- testScenarios("smoke tests: ignoring parent groups") for(i in 1:nrow(scenarios)) { if(!isDevelopmentVersion) break evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE, noDataGroupNBSP=TRUE)) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addColumnDataGroups("PowerType", onlyCombinationsThatExist=FALSE) pt$addRowDataGroups("TOC") pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # sum(pt$cells$asMatrix(), na.rm=TRUE) # prepStr(as.character(pt$getHtml())) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
DMUEMUHSTTotalDMUEMUHSTTotal
Arriva Trains Wales307930798308303909
CrossCountry2213373222865636322928
London Midland56388849144875591282013379248279
Virgin Trains2137645785948594
Total3298715306732490256484282013468583710
" expect_equal(sum(pt$cells$asMatrix(), na.rm=TRUE), 502260) expect_identical(as.character(pt$getHtml()), html) }) } scenarios <- testScenarios("smoke tests: contradictory filters") for(i in 1:nrow(scenarios)) { if(!isDevelopmentVersion) break evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode, compatibility=list(totalStyleIsCellStyle=TRUE)) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addRowDataGroups("TrainCategory") pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # sum(pt$cells$asMatrix(), na.rm=TRUE) # prepStr(as.character(pt$getHtml())) html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
Express Passenger4902549025
Ordinary Passenger3468534685
Total490253468583710
" expect_equal(sum(pt$cells$asMatrix(), na.rm=TRUE), 334840) expect_identical(as.character(pt$getHtml()), html) }) } scenarios <- testScenarios("smoke tests: outline layout") for(i in 1:nrow(scenarios)) { evaluationMode <- scenarios$evaluationMode[i] processingLibrary <- scenarios$processingLibrary[i] description <- scenarios$description[i] countFunction <- scenarios$countFunction[i] test_that(description, { library(pivottabler) pt <- PivotTable$new(processingLibrary=processingLibrary, evaluationMode=evaluationMode) pt$addData(bhmtrains) pt$addColumnDataGroups("TrainCategory") pt$addRowDataGroups("TOC", outlineBefore=list(groupStyleDeclarations=list(color="blue")), outlineAfter=list(isEmpty=FALSE, mergeSpace="dataGroupsOnly", caption="Total ({value})", groupStyleDeclarations=list("font-style"="italic")), outlineTotal=list(groupStyleDeclarations=list(color="blue"), cellStyleDeclarations=list("color"="blue"))) pt$addRowDataGroups("PowerType", addTotal=FALSE) pt$defineCalculation(calculationName="TotalTrains", summariseExpression=countFunction) pt$evaluatePivot() # pt$renderPivot() # sum(pt$cells$asMatrix(), na.rm=TRUE) # prepStr(as.character(pt$getCss())) # prepStr(as.character(pt$getHtml())) css <- ".Table {display: table; border-collapse: collapse; }\r\n.ColumnHeader {font-family: Arial; font-size: 0.75em; border: 1px solid lightgray; vertical-align: middle; font-weight: bold; background-color: #F2F2F2; padding: 2px; text-align: center; }\r\n.RowHeader {font-family: Arial; font-size: 0.75em; border: 1px solid lightgray; vertical-align: middle; font-weight: bold; background-color: #F2F2F2; padding: 2px 8px 2px 2px; text-align: left; }\r\n.Cell {font-family: Arial; font-size: 0.75em; padding: 2px 2px 2px 8px; border: 1px solid lightgray; vertical-align: middle; text-align: right; }\r\n.OutlineColumnHeader {font-family: Arial; font-size: 0.75em; border: 1px solid lightgray; vertical-align: middle; font-weight: bold; background-color: #F2F2F2; padding: 2px; text-align: center; }\r\n.OutlineRowHeader {font-family: Arial; font-size: 0.75em; border: 1px solid lightgray; vertical-align: middle; font-weight: bold; background-color: #F2F2F2; padding: 2px 8px 2px 2px; text-align: left; }\r\n.OutlineCell {font-family: Arial; font-size: 0.75em; padding: 2px 2px 2px 8px; border: 1px solid lightgray; vertical-align: middle; text-align: right; background-color: #F8F8F8; font-weight: bold; }\r\n.Total {font-family: Arial; font-size: 0.75em; padding: 2px 2px 2px 8px; border: 1px solid lightgray; vertical-align: middle; text-align: right; }\r\n" html <- "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
 Express PassengerOrdinary PassengerTotal
Arriva Trains Wales 
 DMU30798303909
Total (Arriva Trains Wales)30798303909
CrossCountry 
 DMU221336322196
HST732732
Total (CrossCountry)228656322928
London Midland 
 DMU5638559111229
EMU88492820137050
Total (London Midland)144873379248279
Virgin Trains 
 DMU21372137
EMU64576457
Total (Virgin Trains)85948594
Total490253468583710
" expect_equal(sum(pt$cells$asMatrix(), na.rm=TRUE), 502260) expect_identical(as.character(pt$getCss()), css) expect_identical(as.character(pt$getHtml()), html) }) }