From 1053329a6247c50ca28746a2e56fbb681572bb37 Mon Sep 17 00:00:00 2001 From: pegeler Date: Fri, 22 Jun 2018 22:24:34 -0400 Subject: [PATCH 1/3] Turned routines to preprocess user inputs into S3 methods. Still needs to be tested. --- R/DESCRIPTION | 6 +++-- R/R/JSON2data.frame.r | 37 ---------------------------- R/R/REDCap_split.r | 15 ++++++------ R/R/process_user_input.r | 53 ++++++++++++++++++++++++++++++++++++++++ R/man/REDCap_split.Rd | 9 ++++--- 5 files changed, 70 insertions(+), 50 deletions(-) delete mode 100644 R/R/JSON2data.frame.r create mode 100644 R/R/process_user_input.r diff --git a/R/DESCRIPTION b/R/DESCRIPTION index ab0f3d3..dcae790 100644 --- a/R/DESCRIPTION +++ b/R/DESCRIPTION @@ -9,7 +9,9 @@ Description: Split REDCap repeating instruments output into multiple tables. This will take raw output from a REDCap export and split it into a base table and child tables for each repeating instrument. Depends: R (>= 3.4.0) -Suggests: RCurl, +Suggests: + RCurl, + httr, jsonlite, testthat License: GPL-3 @@ -19,5 +21,5 @@ RoxygenNote: 6.0.1 URL: https://github.com/SpectrumHealthResearch/REDCapRITS BugReports: https://github.com/SpectrumHealthResearch/REDCapRITS/issues Collate: - 'JSON2data.frame.r' + 'process_user_input.r' 'REDCap_split.r' diff --git a/R/R/JSON2data.frame.r b/R/R/JSON2data.frame.r deleted file mode 100644 index 7b97f16..0000000 --- a/R/R/JSON2data.frame.r +++ /dev/null @@ -1,37 +0,0 @@ -JSON2data.frame <- function (x) { - - if (inherits(x, "data.frame")) { - - return(x) - - } else if (inherits(x, "character")) { - - if (requireNamespace("jsonlite", quietly = TRUE)) { - - return(jsonlite::fromJSON(x)) - - } else { - - stop( - "The package 'jsonlite' is needed to convert ", - deparse(substitute(x)), - " into a data frame.", - "\n Either install 'jsonlite' or pass ", - deparse(substitute(x)), - " as a 'data.frame'.", - call. = FALSE - ) - - } - - } else { - - stop( - deparse(substitute(x)), - " must be a 'data.frame' or JSON string of class 'character'.", - call. = FALSE - ) - - } - -} diff --git a/R/R/REDCap_split.r b/R/R/REDCap_split.r index f1ac040..ea55290 100644 --- a/R/R/REDCap_split.r +++ b/R/R/REDCap_split.r @@ -4,11 +4,12 @@ #' and child tables for each repeating instrument. Metadata #' is used to determine which fields should be included in each resultant table. #' -#' @param records Exported project records. May be a \code{data.frame} or -#' \code{character} vector containing JSON from an API call. -#' @param metadata Project metadata (the data dictionary). May be a -#' \code{data.frame} or \code{character} vector containing JSON from an API +#' @param records Exported project records. May be a \code{data.frame}, +#' \code{response}, or \code{character} vector containing JSON from an API #' call. +#' @param metadata Project metadata (the data dictionary). May be a +#' \code{data.frame}, \code{response}, or \code{character} vector containing +#' JSON from an API call. #' @author Paul W. Egeler, M.S., GStat #' @examples #' \dontrun{ @@ -65,13 +66,13 @@ #' } #' @return A list of \code{"data.frame"}s: one base table and zero or more #' tables for each repeating instrument. -#' @include JSON2data.frame.r +#' @include process_user_input.r #' @export REDCap_split <- function(records, metadata) { # Process user input - records <- JSON2data.frame(records) - metadata <- JSON2data.frame(metadata) + records <- process_user_input(records) + metadata <- process_user_input(metadata) # Get the variable names in the dataset vars_in_data <- names(records) diff --git a/R/R/process_user_input.r b/R/R/process_user_input.r new file mode 100644 index 0000000..9da1601 --- /dev/null +++ b/R/R/process_user_input.r @@ -0,0 +1,53 @@ +process_user_input <- function (x) { + UseMethod("process_user_input", x) +} + +process_user_input.default <- function(x, ...) { + stop( + deparse(substitute(x)), + " must be a 'data.frame',", + " a 'response',", + " or a 'character' vector containing JSON.", + call. = FALSE + ) +} + +process_user_input.data.frame <- function(x, ...) { + x +} + +process_user_input.character <- function(x, ...) { + + if (!requireNamespace("jsonlite", quietly = TRUE)) { + stop( + "The package 'jsonlite' is needed to convert ", + deparse(substitute(x)), + " into a data frame.", + "\n Either install 'jsonlite' or pass ", + deparse(substitute(x)), + " as a 'data.frame'.", + call. = FALSE + ) + } + + jsonlite::fromJSON(x) + +} + +process_user_input.response <- function(x, ...) { + + if (!requireNamespace("httr", quietly = TRUE)) { + stop( + "The package 'httr' is needed to convert ", + deparse(substitute(x)), + " into a data frame.", + "\n Either install 'httr' or pass ", + deparse(substitute(x)), + " as a 'data.frame'.", + call. = FALSE + ) + } + + httr::content(x, as = "text") + +} diff --git a/R/man/REDCap_split.Rd b/R/man/REDCap_split.Rd index 7a1b827..8bd4793 100644 --- a/R/man/REDCap_split.Rd +++ b/R/man/REDCap_split.Rd @@ -7,12 +7,13 @@ REDCap_split(records, metadata) } \arguments{ -\item{records}{Exported project records. May be a \code{data.frame} or -\code{character} vector containing JSON from an API call.} +\item{records}{Exported project records. May be a \code{data.frame}, +\code{response}, or \code{character} vector containing JSON from an API +call.} \item{metadata}{Project metadata (the data dictionary). May be a -\code{data.frame} or \code{character} vector containing JSON from an API -call.} +\code{data.frame}, \code{response}, or \code{character} vector containing +JSON from an API call.} } \value{ A list of \code{"data.frame"}s: one base table and zero or more From 4389f2bca6b3b8385163dfd76004d5828406b404 Mon Sep 17 00:00:00 2001 From: pegeler Date: Fri, 22 Jun 2018 22:34:35 -0400 Subject: [PATCH 2/3] Adding in recursive call to process_user_input for 'response' Also removing partial dependency on httr --- R/R/process_user_input.r | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/R/R/process_user_input.r b/R/R/process_user_input.r index 9da1601..5a4a3ac 100644 --- a/R/R/process_user_input.r +++ b/R/R/process_user_input.r @@ -36,18 +36,6 @@ process_user_input.character <- function(x, ...) { process_user_input.response <- function(x, ...) { - if (!requireNamespace("httr", quietly = TRUE)) { - stop( - "The package 'httr' is needed to convert ", - deparse(substitute(x)), - " into a data frame.", - "\n Either install 'httr' or pass ", - deparse(substitute(x)), - " as a 'data.frame'.", - call. = FALSE - ) - } - - httr::content(x, as = "text") + process_user_input(rawToChar(x$content)) } From 4841e1170e32f92a35165ae96e832d39c7d034af Mon Sep 17 00:00:00 2001 From: pegeler Date: Mon, 25 Jun 2018 23:48:55 -0400 Subject: [PATCH 3/3] Writing unit tests for basic examples of data export for R. --- R/DESCRIPTION | 7 +- R/tests/testthat.R | 8 +- .../ExampleProject_DATA_2018-06-07_1129.csv | 46 + ...ampleProject_DataDictionary_2018-06-07.csv | 19 + .../data/ExampleProject_R_2018-06-07_1129.r | 77 + .../data/ExampleProject_metadata.json | 362 +++++ .../testthat/data/ExampleProject_records.json | 1352 +++++++++++++++++ R/tests/testthat/test-API.R | 32 + R/tests/testthat/test-csv-exports.R | 35 + 9 files changed, 1932 insertions(+), 6 deletions(-) create mode 100644 R/tests/testthat/data/ExampleProject_DATA_2018-06-07_1129.csv create mode 100644 R/tests/testthat/data/ExampleProject_DataDictionary_2018-06-07.csv create mode 100644 R/tests/testthat/data/ExampleProject_R_2018-06-07_1129.r create mode 100644 R/tests/testthat/data/ExampleProject_metadata.json create mode 100644 R/tests/testthat/data/ExampleProject_records.json create mode 100644 R/tests/testthat/test-API.R create mode 100644 R/tests/testthat/test-csv-exports.R diff --git a/R/DESCRIPTION b/R/DESCRIPTION index ab0f3d3..d37aa35 100644 --- a/R/DESCRIPTION +++ b/R/DESCRIPTION @@ -9,9 +9,12 @@ Description: Split REDCap repeating instruments output into multiple tables. This will take raw output from a REDCap export and split it into a base table and child tables for each repeating instrument. Depends: R (>= 3.4.0) -Suggests: RCurl, +Suggests: + RCurl, jsonlite, - testthat + testthat, + Hmisc, + httr License: GPL-3 Encoding: UTF-8 LazyData: true diff --git a/R/tests/testthat.R b/R/tests/testthat.R index dae14a9..58c6dcf 100644 --- a/R/tests/testthat.R +++ b/R/tests/testthat.R @@ -1,4 +1,4 @@ -# library(testthat) -# library(REDCapRITS) -# -# test_check("REDCapRITS") +library(testthat) +library(REDCapRITS) + +test_check("REDCapRITS") diff --git a/R/tests/testthat/data/ExampleProject_DATA_2018-06-07_1129.csv b/R/tests/testthat/data/ExampleProject_DATA_2018-06-07_1129.csv new file mode 100644 index 0000000..3709b9e --- /dev/null +++ b/R/tests/testthat/data/ExampleProject_DATA_2018-06-07_1129.csv @@ -0,0 +1,46 @@ +row,redcap_repeat_instrument,redcap_repeat_instance,mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb,color_available___red,color_available___green,color_available___blue,color_available___black,motor_trend_cars_complete,letter_group___a,letter_group___b,letter_group___c,choice,grouping_complete,price,color,customer,sale_complete +"AMC Javelin",,,15.2,8,304,150,3.15,3.435,17.3,0,0,3,2,1,1,1,0,1,1,1,0,choice2,2,,,, +"AMC Javelin",sale,1,,,,,,,,,,,,,,,,,,,,,,12000.50,1,Bob,0 +"AMC Javelin",sale,2,,,,,,,,,,,,,,,,,,,,,,13750.77,3,Sue,2 +"AMC Javelin",sale,3,,,,,,,,,,,,,,,,,,,,,,15004.57,2,Kim,0 +"Cadillac Fleetwood",,,10.4,8,472,205,2.93,5.25,17.98,0,0,3,4,0,0,0,0,0,0,0,0,,0,,,, +"Camaro Z28",,,13.3,8,350,245,3.73,3.84,15.41,0,0,3,4,0,0,0,0,0,1,0,1,choice1,2,,,, +"Camaro Z28",sale,1,,,,,,,,,,,,,,,,,,,,,,7800.00,2,Janice,2 +"Camaro Z28",sale,2,,,,,,,,,,,,,,,,,,,,,,8000.00,3,Tim,0 +"Chrysler Imperial",,,14.7,8,440,230,3.23,5.345,17.42,0,0,3,4,0,0,0,0,0,0,1,1,choice1,2,,,, +"Chrysler Imperial",sale,1,,,,,,,,,,,,,,,,,,,,,,7500.00,1,Jim,2 +"Datsun 710",,,22.8,4,108,93,3.85,2.32,18.61,1,1,4,1,0,0,0,0,0,0,1,1,,0,,,, +"Dodge Challenger",,,15.5,8,318,150,2.76,3.52,16.87,0,0,3,2,0,0,0,0,0,0,0,0,,0,,,, +"Duster 360",,,14.3,8,360,245,3.21,3.57,15.84,0,0,3,4,0,0,0,0,0,0,1,1,choice1,1,,,, +"Duster 360",sale,1,,,,,,,,,,,,,,,,,,,,,,8756.40,4,Sarah,1 +"Duster 360",sale,2,,,,,,,,,,,,,,,,,,,,,,6800.88,2,Pablo,0 +"Duster 360",sale,3,,,,,,,,,,,,,,,,,,,,,,8888.88,1,Erica,0 +"Duster 360",sale,4,,,,,,,,,,,,,,,,,,,,,,970.00,4,Juan,0 +"Ferrari Dino",,,19.7,6,145,175,3.62,2.77,15.5,0,1,5,6,0,0,0,0,0,0,0,0,,0,,,, +"Fiat 128",,,32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1,0,0,0,0,0,0,0,0,,0,,,, +"Fiat X1-9",,,27.3,4,79,66,4.08,1.935,18.9,1,1,4,1,0,0,0,0,0,0,0,0,,0,,,, +"Ford Pantera L",,,15.8,8,351,264,4.22,3.17,14.5,0,1,5,4,0,0,0,0,0,0,0,0,,0,,,, +"Honda Civic",,,30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2,0,0,0,0,0,0,0,0,,0,,,, +"Hornet 4 Drive",,,21.4,6,258,110,3.08,3.215,19.44,1,0,3,1,0,0,0,0,0,0,0,0,,0,,,, +"Hornet Sportabout",,,18.7,8,360,175,3.15,3.44,17.02,0,0,3,2,0,0,0,0,0,0,0,0,,0,,,, +"Lincoln Continental",,,10.4,8,460,215,3,5.424,17.82,0,0,3,4,0,0,0,0,0,0,0,0,,0,,,, +"Lotus Europa",,,30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2,0,0,0,0,0,0,0,0,,0,,,, +"Maserati Bora",,,15,8,301,335,3.54,3.57,14.6,0,1,5,8,0,0,0,0,0,0,0,0,,0,,,, +"Mazda RX4",,,21,6,160,110,3.9,2.62,16.46,0,1,4,4,0,0,0,0,0,0,0,0,,0,,,, +"Mazda RX4 Wag",,,21,6,160,110,3.9,2.875,17.02,0,1,4,4,0,0,0,0,0,1,1,0,,0,,,, +"Merc 230",,,22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2,0,0,0,0,0,1,1,0,choice2,0,,,, +"Merc 230",sale,1,,,,,,,,,,,,,,,,,,,,,,7800.98,2,Ted,0 +"Merc 230",sale,2,,,,,,,,,,,,,,,,,,,,,,7954.00,1,Quentin,0 +"Merc 230",sale,3,,,,,,,,,,,,,,,,,,,,,,6800.55,3,Sharon,2 +"Merc 240D",,,24.4,4,146.7,62,3.69,3.19,20,1,0,4,2,0,0,0,0,0,0,0,0,,0,,,, +"Merc 280",,,19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4,0,0,0,0,0,0,0,0,,0,,,, +"Merc 280C",,,17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4,0,0,0,0,0,0,0,0,,0,,,, +"Merc 450SE",,,16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3,0,0,0,0,0,0,0,0,,0,,,, +"Merc 450SL",,,17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3,0,0,0,0,0,0,0,0,,0,,,, +"Merc 450SLC",,,15.2,8,275.8,180,3.07,3.78,18,0,0,3,3,0,0,0,0,0,0,0,0,,0,,,, +"Pontiac Firebird",,,19.2,8,400,175,3.08,3.845,17.05,0,0,3,2,0,0,0,0,0,0,0,0,,0,,,, +"Porsche 914-2",,,26,4,120.3,91,4.43,2.14,16.7,0,1,5,2,0,0,0,0,0,0,0,0,,0,,,, +"Toyota Corolla",,,33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1,0,0,0,0,0,0,0,0,,0,,,, +"Toyota Corona",,,21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1,0,0,0,0,0,0,0,0,,0,,,, +Valiant,,,18.1,6,225,105,2.76,3.46,20.22,1,0,3,1,0,0,0,0,0,0,0,0,,0,,,, +"Volvo 142E",,,21.4,4,121,109,4.11,2.78,18.6,1,1,4,2,0,0,0,0,0,0,0,0,,0,,,, diff --git a/R/tests/testthat/data/ExampleProject_DataDictionary_2018-06-07.csv b/R/tests/testthat/data/ExampleProject_DataDictionary_2018-06-07.csv new file mode 100644 index 0000000..b30b189 --- /dev/null +++ b/R/tests/testthat/data/ExampleProject_DataDictionary_2018-06-07.csv @@ -0,0 +1,19 @@ +"Variable / Field Name","Form Name","Section Header","Field Type","Field Label","Choices, Calculations, OR Slider Labels","Field Note","Text Validation Type OR Show Slider Number","Text Validation Min","Text Validation Max",Identifier?,"Branching Logic (Show field only if...)","Required Field?","Custom Alignment","Question Number (surveys only)","Matrix Group Name","Matrix Ranking?","Field Annotation" +row,motor_trend_cars,,text,Name,,,,,,,,,,,,, +mpg,motor_trend_cars,,text,"Miles/(US) gallon",,,number,,,,,,,,,, +cyl,motor_trend_cars,,radio,"Number of cylinders","3, 3 | 4, 4 | 5, 5 | 6, 6 | 7, 7 | 8, 8",,,,,,,,,,,, +disp,motor_trend_cars,,text,Displacement,,(cu.in.),number,,,,,,,,,, +hp,motor_trend_cars,,text,"Gross horsepower",,,number,,,,,,,,,, +drat,motor_trend_cars,,text,"Rear axle ratio",,,number,,,,,,,,,, +wt,motor_trend_cars,,text,Weight,,"(1000 lbs)",number,,,,,,,,,, +qsec,motor_trend_cars,,text,"1/4 mile time",,,number,,,,,,,,,, +vs,motor_trend_cars,,yesno,"V engine?",,,,,,,,,,,,, +am,motor_trend_cars,,dropdown,Transmission,"0, Automatic | 1, Manual"," (0 = automatic, 1 = manual)",,,,,,,,,,, +gear,motor_trend_cars,,radio,"Number of forward gears","3, 3 | 4, 4 | 5, 5",,,,,,,,,,,, +carb,motor_trend_cars,,radio,"Number of carburetors","1, 1 | 2, 2 | 3, 3 | 4, 4 | 5, 5 | 6, 6 | 7, 7 | 8, 8",,,,,,,,,,,, +color_available,motor_trend_cars,,checkbox,"Colors Available","red, Red | green, Green | blue, Blue | black, Black",,,,,,,,,,,, +letter_group,grouping,,checkbox,"Which group?","a, A | b, B | c, C",,,,,,,,,,,, +choice,grouping,,radio,"Choose one","choice1, Choice 1 | choice2, Choice 2",,,,,,,,,,,, +price,sale,,text,"Sale price",,,number_2dp,,,,,,,,,, +color,sale,,dropdown,Color,"1, red | 2, green | 3, blue | 4, black",,,,,,,,,,,, +customer,sale,,text,"Customer Name",,,,,,,,,RH,,,, diff --git a/R/tests/testthat/data/ExampleProject_R_2018-06-07_1129.r b/R/tests/testthat/data/ExampleProject_R_2018-06-07_1129.r new file mode 100644 index 0000000..6c6a6cf --- /dev/null +++ b/R/tests/testthat/data/ExampleProject_R_2018-06-07_1129.r @@ -0,0 +1,77 @@ +REDCap_process_csv <- function(data) { + #Load Hmisc library + if (!require(Hmisc)) + stop("This test requires the 'Hmisc' package") + + label(data$row)="Name" + label(data$redcap_repeat_instrument)="Repeat Instrument" + label(data$redcap_repeat_instance)="Repeat Instance" + label(data$mpg)="Miles/(US) gallon" + label(data$cyl)="Number of cylinders" + label(data$disp)="Displacement" + label(data$hp)="Gross horsepower" + label(data$drat)="Rear axle ratio" + label(data$wt)="Weight" + label(data$qsec)="1/4 mile time" + label(data$vs)="V engine?" + label(data$am)="Transmission" + label(data$gear)="Number of forward gears" + label(data$carb)="Number of carburetors" + label(data$color_available___red)="Colors Available (choice=Red)" + label(data$color_available___green)="Colors Available (choice=Green)" + label(data$color_available___blue)="Colors Available (choice=Blue)" + label(data$color_available___black)="Colors Available (choice=Black)" + label(data$motor_trend_cars_complete)="Complete?" + label(data$letter_group___a)="Which group? (choice=A)" + label(data$letter_group___b)="Which group? (choice=B)" + label(data$letter_group___c)="Which group? (choice=C)" + label(data$choice)="Choose one" + label(data$grouping_complete)="Complete?" + label(data$price)="Sale price" + label(data$color)="Color" + label(data$customer)="Customer Name" + label(data$sale_complete)="Complete?" + #Setting Units + + + #Setting Factors(will create new variable for factors) + data$redcap_repeat_instrument.factor = factor(data$redcap_repeat_instrument,levels=c("sale")) + data$cyl.factor = factor(data$cyl,levels=c("3","4","5","6","7","8")) + data$vs.factor = factor(data$vs,levels=c("1","0")) + data$am.factor = factor(data$am,levels=c("0","1")) + data$gear.factor = factor(data$gear,levels=c("3","4","5")) + data$carb.factor = factor(data$carb,levels=c("1","2","3","4","5","6","7","8")) + data$color_available___red.factor = factor(data$color_available___red,levels=c("0","1")) + data$color_available___green.factor = factor(data$color_available___green,levels=c("0","1")) + data$color_available___blue.factor = factor(data$color_available___blue,levels=c("0","1")) + data$color_available___black.factor = factor(data$color_available___black,levels=c("0","1")) + data$motor_trend_cars_complete.factor = factor(data$motor_trend_cars_complete,levels=c("0","1","2")) + data$letter_group___a.factor = factor(data$letter_group___a,levels=c("0","1")) + data$letter_group___b.factor = factor(data$letter_group___b,levels=c("0","1")) + data$letter_group___c.factor = factor(data$letter_group___c,levels=c("0","1")) + data$choice.factor = factor(data$choice,levels=c("choice1","choice2")) + data$grouping_complete.factor = factor(data$grouping_complete,levels=c("0","1","2")) + data$color.factor = factor(data$color,levels=c("1","2","3","4")) + data$sale_complete.factor = factor(data$sale_complete,levels=c("0","1","2")) + + levels(data$redcap_repeat_instrument.factor)=c("Sale") + levels(data$cyl.factor)=c("3","4","5","6","7","8") + levels(data$vs.factor)=c("Yes","No") + levels(data$am.factor)=c("Automatic","Manual") + levels(data$gear.factor)=c("3","4","5") + levels(data$carb.factor)=c("1","2","3","4","5","6","7","8") + levels(data$color_available___red.factor)=c("Unchecked","Checked") + levels(data$color_available___green.factor)=c("Unchecked","Checked") + levels(data$color_available___blue.factor)=c("Unchecked","Checked") + levels(data$color_available___black.factor)=c("Unchecked","Checked") + levels(data$motor_trend_cars_complete.factor)=c("Incomplete","Unverified","Complete") + levels(data$letter_group___a.factor)=c("Unchecked","Checked") + levels(data$letter_group___b.factor)=c("Unchecked","Checked") + levels(data$letter_group___c.factor)=c("Unchecked","Checked") + levels(data$choice.factor)=c("Choice 1","Choice 2") + levels(data$grouping_complete.factor)=c("Incomplete","Unverified","Complete") + levels(data$color.factor)=c("red","green","blue","black") + levels(data$sale_complete.factor)=c("Incomplete","Unverified","Complete") + + data +} diff --git a/R/tests/testthat/data/ExampleProject_metadata.json b/R/tests/testthat/data/ExampleProject_metadata.json new file mode 100644 index 0000000..00b10dc --- /dev/null +++ b/R/tests/testthat/data/ExampleProject_metadata.json @@ -0,0 +1,362 @@ +[ + { + "field_name": "row", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Name", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "mpg", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Miles/(US) gallon", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "cyl", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "radio", + "field_label": "Number of cylinders", + "select_choices_or_calculations": "3, 3 | 4, 4 | 5, 5 | 6, 6 | 7, 7 | 8, 8", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "disp", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Displacement", + "select_choices_or_calculations": "", + "field_note": "(cu.in.)", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "hp", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Gross horsepower", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "drat", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Rear axle ratio", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "wt", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "Weight", + "select_choices_or_calculations": "", + "field_note": "(1000 lbs)", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "qsec", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "text", + "field_label": "1/4 mile time", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "number", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "vs", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "yesno", + "field_label": "V engine?", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "am", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "dropdown", + "field_label": "Transmission", + "select_choices_or_calculations": "0, Automatic | 1, Manual", + "field_note": " (0 = automatic, 1 = manual)", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "gear", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "radio", + "field_label": "Number of forward gears", + "select_choices_or_calculations": "3, 3 | 4, 4 | 5, 5", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "carb", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "radio", + "field_label": "Number of carburetors", + "select_choices_or_calculations": "1, 1 | 2, 2 | 3, 3 | 4, 4 | 5, 5 | 6, 6 | 7, 7 | 8, 8", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "color_available", + "form_name": "motor_trend_cars", + "section_header": "", + "field_type": "checkbox", + "field_label": "Colors Available", + "select_choices_or_calculations": "red, Red | green, Green | blue, Blue | black, Black", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "letter_group", + "form_name": "grouping", + "section_header": "", + "field_type": "checkbox", + "field_label": "Which group?", + "select_choices_or_calculations": "a, A | b, B | c, C", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "choice", + "form_name": "grouping", + "section_header": "", + "field_type": "radio", + "field_label": "Choose one", + "select_choices_or_calculations": "choice1, Choice 1 | choice2, Choice 2", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "price", + "form_name": "sale", + "section_header": "", + "field_type": "text", + "field_label": "Sale price", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "number_2dp", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "color", + "form_name": "sale", + "section_header": "", + "field_type": "dropdown", + "field_label": "Color", + "select_choices_or_calculations": "1, red | 2, green | 3, blue | 4, black", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + }, + { + "field_name": "customer", + "form_name": "sale", + "section_header": "", + "field_type": "text", + "field_label": "Customer Name", + "select_choices_or_calculations": "", + "field_note": "", + "text_validation_type_or_show_slider_number": "", + "text_validation_min": "", + "text_validation_max": "", + "identifier": "", + "branching_logic": "", + "required_field": "", + "custom_alignment": "RH", + "question_number": "", + "matrix_group_name": "", + "matrix_ranking": "", + "field_annotation": "" + } +] diff --git a/R/tests/testthat/data/ExampleProject_records.json b/R/tests/testthat/data/ExampleProject_records.json new file mode 100644 index 0000000..7993b56 --- /dev/null +++ b/R/tests/testthat/data/ExampleProject_records.json @@ -0,0 +1,1352 @@ +[ + { + "row": "AMC Javelin", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "15.2", + "cyl": "8", + "disp": "304", + "hp": "150", + "drat": "3.15", + "wt": "3.435", + "qsec": "17.3", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "2", + "color_available___red": "1", + "color_available___green": "1", + "color_available___blue": "1", + "color_available___black": "0", + "motor_trend_cars_complete": "1", + "letter_group___a": "1", + "letter_group___b": "1", + "letter_group___c": "0", + "choice": "choice2", + "grouping_complete": "2", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "AMC Javelin", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 1, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "12000.50", + "color": "1", + "customer": "Bob", + "sale_complete": "0" + }, + { + "row": "AMC Javelin", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 2, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "13750.77", + "color": "3", + "customer": "Sue", + "sale_complete": "2" + }, + { + "row": "AMC Javelin", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 3, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "15004.57", + "color": "2", + "customer": "Kim", + "sale_complete": "0" + }, + { + "row": "Cadillac Fleetwood", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "10.4", + "cyl": "8", + "disp": "472", + "hp": "205", + "drat": "2.93", + "wt": "5.25", + "qsec": "17.98", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Camaro Z28", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "13.3", + "cyl": "8", + "disp": "350", + "hp": "245", + "drat": "3.73", + "wt": "3.84", + "qsec": "15.41", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "1", + "letter_group___b": "0", + "letter_group___c": "1", + "choice": "choice1", + "grouping_complete": "2", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Camaro Z28", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 1, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "7800.00", + "color": "2", + "customer": "Janice", + "sale_complete": "2" + }, + { + "row": "Camaro Z28", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 2, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "8000.00", + "color": "3", + "customer": "Tim", + "sale_complete": "0" + }, + { + "row": "Chrysler Imperial", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "14.7", + "cyl": "8", + "disp": "440", + "hp": "230", + "drat": "3.23", + "wt": "5.345", + "qsec": "17.42", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "1", + "letter_group___c": "1", + "choice": "choice1", + "grouping_complete": "2", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Chrysler Imperial", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 1, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "7500.00", + "color": "1", + "customer": "Jim", + "sale_complete": "2" + }, + { + "row": "Datsun 710", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "22.8", + "cyl": "4", + "disp": "108", + "hp": "93", + "drat": "3.85", + "wt": "2.32", + "qsec": "18.61", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "1", + "letter_group___c": "1", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Dodge Challenger", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "15.5", + "cyl": "8", + "disp": "318", + "hp": "150", + "drat": "2.76", + "wt": "3.52", + "qsec": "16.87", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Duster 360", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "14.3", + "cyl": "8", + "disp": "360", + "hp": "245", + "drat": "3.21", + "wt": "3.57", + "qsec": "15.84", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "1", + "letter_group___c": "1", + "choice": "choice1", + "grouping_complete": "1", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Duster 360", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 1, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "8756.40", + "color": "4", + "customer": "Sarah", + "sale_complete": "1" + }, + { + "row": "Duster 360", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 2, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "6800.88", + "color": "2", + "customer": "Pablo", + "sale_complete": "0" + }, + { + "row": "Duster 360", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 3, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "8888.88", + "color": "1", + "customer": "Erica", + "sale_complete": "0" + }, + { + "row": "Duster 360", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 4, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "970.00", + "color": "4", + "customer": "Juan", + "sale_complete": "0" + }, + { + "row": "Ferrari Dino", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "19.7", + "cyl": "6", + "disp": "145", + "hp": "175", + "drat": "3.62", + "wt": "2.77", + "qsec": "15.5", + "vs": "0", + "am": "1", + "gear": "5", + "carb": "6", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Fiat 128", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "32.4", + "cyl": "4", + "disp": "78.7", + "hp": "66", + "drat": "4.08", + "wt": "2.2", + "qsec": "19.47", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Fiat X1-9", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "27.3", + "cyl": "4", + "disp": "79", + "hp": "66", + "drat": "4.08", + "wt": "1.935", + "qsec": "18.9", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Ford Pantera L", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "15.8", + "cyl": "8", + "disp": "351", + "hp": "264", + "drat": "4.22", + "wt": "3.17", + "qsec": "14.5", + "vs": "0", + "am": "1", + "gear": "5", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Honda Civic", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "30.4", + "cyl": "4", + "disp": "75.7", + "hp": "52", + "drat": "4.93", + "wt": "1.615", + "qsec": "18.52", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Hornet 4 Drive", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "21.4", + "cyl": "6", + "disp": "258", + "hp": "110", + "drat": "3.08", + "wt": "3.215", + "qsec": "19.44", + "vs": "1", + "am": "0", + "gear": "3", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Hornet Sportabout", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "18.7", + "cyl": "8", + "disp": "360", + "hp": "175", + "drat": "3.15", + "wt": "3.44", + "qsec": "17.02", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Lincoln Continental", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "10.4", + "cyl": "8", + "disp": "460", + "hp": "215", + "drat": "3", + "wt": "5.424", + "qsec": "17.82", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Lotus Europa", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "30.4", + "cyl": "4", + "disp": "95.1", + "hp": "113", + "drat": "3.77", + "wt": "1.513", + "qsec": "16.9", + "vs": "1", + "am": "1", + "gear": "5", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Maserati Bora", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "15", + "cyl": "8", + "disp": "301", + "hp": "335", + "drat": "3.54", + "wt": "3.57", + "qsec": "14.6", + "vs": "0", + "am": "1", + "gear": "5", + "carb": "8", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Mazda RX4", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "21", + "cyl": "6", + "disp": "160", + "hp": "110", + "drat": "3.9", + "wt": "2.62", + "qsec": "16.46", + "vs": "0", + "am": "1", + "gear": "4", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Mazda RX4 Wag", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "21", + "cyl": "6", + "disp": "160", + "hp": "110", + "drat": "3.9", + "wt": "2.875", + "qsec": "17.02", + "vs": "0", + "am": "1", + "gear": "4", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "1", + "letter_group___b": "1", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 230", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "22.8", + "cyl": "4", + "disp": "140.8", + "hp": "95", + "drat": "3.92", + "wt": "3.15", + "qsec": "22.9", + "vs": "1", + "am": "0", + "gear": "4", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "1", + "letter_group___b": "1", + "letter_group___c": "0", + "choice": "choice2", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 230", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 1, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "7800.98", + "color": "2", + "customer": "Ted", + "sale_complete": "0" + }, + { + "row": "Merc 230", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 2, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "7954.00", + "color": "1", + "customer": "Quentin", + "sale_complete": "0" + }, + { + "row": "Merc 230", + "redcap_repeat_instrument": "sale", + "redcap_repeat_instance": 3, + "mpg": "", + "cyl": "", + "disp": "", + "hp": "", + "drat": "", + "wt": "", + "qsec": "", + "vs": "", + "am": "", + "gear": "", + "carb": "", + "color_available___red": "", + "color_available___green": "", + "color_available___blue": "", + "color_available___black": "", + "motor_trend_cars_complete": "", + "letter_group___a": "", + "letter_group___b": "", + "letter_group___c": "", + "choice": "", + "grouping_complete": "", + "price": "6800.55", + "color": "3", + "customer": "Sharon", + "sale_complete": "2" + }, + { + "row": "Merc 240D", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "24.4", + "cyl": "4", + "disp": "146.7", + "hp": "62", + "drat": "3.69", + "wt": "3.19", + "qsec": "20", + "vs": "1", + "am": "0", + "gear": "4", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 280", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "19.2", + "cyl": "6", + "disp": "167.6", + "hp": "123", + "drat": "3.92", + "wt": "3.44", + "qsec": "18.3", + "vs": "1", + "am": "0", + "gear": "4", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 280C", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "17.8", + "cyl": "6", + "disp": "167.6", + "hp": "123", + "drat": "3.92", + "wt": "3.44", + "qsec": "18.9", + "vs": "1", + "am": "0", + "gear": "4", + "carb": "4", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 450SE", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "16.4", + "cyl": "8", + "disp": "275.8", + "hp": "180", + "drat": "3.07", + "wt": "4.07", + "qsec": "17.4", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "3", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 450SL", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "17.3", + "cyl": "8", + "disp": "275.8", + "hp": "180", + "drat": "3.07", + "wt": "3.73", + "qsec": "17.6", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "3", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Merc 450SLC", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "15.2", + "cyl": "8", + "disp": "275.8", + "hp": "180", + "drat": "3.07", + "wt": "3.78", + "qsec": "18", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "3", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Pontiac Firebird", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "19.2", + "cyl": "8", + "disp": "400", + "hp": "175", + "drat": "3.08", + "wt": "3.845", + "qsec": "17.05", + "vs": "0", + "am": "0", + "gear": "3", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Porsche 914-2", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "26", + "cyl": "4", + "disp": "120.3", + "hp": "91", + "drat": "4.43", + "wt": "2.14", + "qsec": "16.7", + "vs": "0", + "am": "1", + "gear": "5", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Toyota Corolla", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "33.9", + "cyl": "4", + "disp": "71.1", + "hp": "65", + "drat": "4.22", + "wt": "1.835", + "qsec": "19.9", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Toyota Corona", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "21.5", + "cyl": "4", + "disp": "120.1", + "hp": "97", + "drat": "3.7", + "wt": "2.465", + "qsec": "20.01", + "vs": "1", + "am": "0", + "gear": "3", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Valiant", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "18.1", + "cyl": "6", + "disp": "225", + "hp": "105", + "drat": "2.76", + "wt": "3.46", + "qsec": "20.22", + "vs": "1", + "am": "0", + "gear": "3", + "carb": "1", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + }, + { + "row": "Volvo 142E", + "redcap_repeat_instrument": "", + "redcap_repeat_instance": "", + "mpg": "21.4", + "cyl": "4", + "disp": "121", + "hp": "109", + "drat": "4.11", + "wt": "2.78", + "qsec": "18.6", + "vs": "1", + "am": "1", + "gear": "4", + "carb": "2", + "color_available___red": "0", + "color_available___green": "0", + "color_available___blue": "0", + "color_available___black": "0", + "motor_trend_cars_complete": "0", + "letter_group___a": "0", + "letter_group___b": "0", + "letter_group___c": "0", + "choice": "", + "grouping_complete": "0", + "price": "", + "color": "", + "customer": "", + "sale_complete": "" + } +] diff --git a/R/tests/testthat/test-API.R b/R/tests/testthat/test-API.R new file mode 100644 index 0000000..a01af3f --- /dev/null +++ b/R/tests/testthat/test-API.R @@ -0,0 +1,32 @@ +context("Reading in JSON") + +# Set up the path ---------------------------------------------------------- + +data_dir <- system.file("tests", "testthat", "data", package = "REDCapRITS") + +# Check the RCurl export --------------------------------------------------- +test_that("JSON character vector from RCurl matches reference", { + + metadata <- jsonlite::fromJSON( + file.path( + data_dir, + "ExampleProject_metadata.json" + ) + ) + + records <- jsonlite::fromJSON( + file.path( + data_dir, + "ExampleProject_records.json" + ) + ) + + redcap_output_json1 <- REDCap_split(records, metadata) + + expect_known_hash(redcap_output_json1, "2c8b6531597182af1248f92124161e0c") + +}) + +# Check the httr export --------------------------------------------------- + +# Something will go here. diff --git a/R/tests/testthat/test-csv-exports.R b/R/tests/testthat/test-csv-exports.R new file mode 100644 index 0000000..61e6ba7 --- /dev/null +++ b/R/tests/testthat/test-csv-exports.R @@ -0,0 +1,35 @@ +context("CSV Exports") + +# Set up the path and data ------------------------------------------------- + +data_dir <- system.file("tests", "testthat", "data", package = "REDCapRITS") + +metadata <- read.csv( + file.path( + data_dir, + "ExampleProject_DataDictionary_2018-06-07.csv" + ) +) + +records <- read.csv( + file.path( + data_dir, + "ExampleProject_DATA_2018-06-07_1129.csv" + ) +) + +# Test that basic CSV export matches reference ------------------------------ +test_that("CSV export matches reference", { + redcap_output_csv1 <- REDCap_split(records, metadata) + + expect_known_hash(redcap_output_csv1, "f74558d1939c17d9ff0e08a19b956e26") +}) + +# Test that R code enhanced CSV export matches reference -------------------- +test_that("R code enhanced export matches reference", { + source(file.path(data_dir, "ExampleProject_R_2018-06-07_1129.r")) + + redcap_output_csv2 <- REDCap_split(REDCap_process_csv(records), metadata) + + expect_known_hash(redcap_output_csv2, "34f82cab35bf8aae47d08cd96f743e6b") +})