Skip to content

Commit

Permalink
Add tests and bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ecnama committed Nov 30, 2024
1 parent c85586f commit 0b0a96f
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 21 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ Imports:
openxlsx,
readODS
Suggests:
testthat (>= 3.0.0)
testthat (>= 3.0.0),
mockr
Config/testthat/edition: 3
26 changes: 13 additions & 13 deletions R/input.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@ source("R/variables.R")
#'
#' @param file_path The path to the file to parse
#' @return The file as a data frame
select_file_type <- function(file_path) {
read_file <- function(file_path) {
# Check if file extension is supported (xlsx or ods)
if (grepl(".xlsx", file_path)) {
file_data <- read.xlsx(file_path, sheet = 1, skipEmptyRows = FALSE, skipEmptyCols = FALSE, colNames = TRUE, cols = (8:25))
file_data <- openxlsx::read.xlsx(file_path, sheet = 1, skipEmptyRows = FALSE, skipEmptyCols = FALSE, colNames = TRUE, cols = (8:25), sep.names = " ")
file_data <- file_data[, c(8:25)]
} else if (grepl(".ods", file_path)) {
file_data <- read_ods(file_path, sheet = 1, col_names = TRUE, as_tibble = FALSE, na = "NULL")
file_data <- readODS::read_ods(file_path, sheet = 1, col_names = TRUE, as_tibble = FALSE, na = "NULL")
file_data <- file_data[, c(8:25)]
} else {
stop("File type not supported")
}
return(file_data)
}

#' Synthesizes a student's wishes from multiple columns per filière to 7 columns for all filières
#' Synthesizes a student's wishes from multiple columns per filiere to 7 columns for all filieres
#'
#' @param wishes The wishes columns
#' @return A vector with the filière and the 7 wishes (NA if no wish)
#' @return A vector with the filiere and the 7 wishes (NA if no wish)
synthesize_wishes <- function(wishes) {
# Get the head of the columns
colnames <- colnames(wishes)
# Extract the filière info
# Extract the filiere info
if (length(grep("FC_FIRE", wishes[1])) > 0) {
# Dataframe from rank number and speciality name
df <- data.frame(rank = unlist(wishes[2:8]), spe = sub(Q2_PREFIX, "", colnames[2:8]))
# Sort the dataframe by rank
df <- df[order(df$rank), ]
# Set result to the filière and the specialities ordered by the student's preferences
# Set result to the filiere and the specialities ordered by the student's preferences
result <- c("FC_FIRE", df$spe)
} else if (length(grep("EMIR", wishes[1])) > 0) {
df <- data.frame(rank = unlist(wishes[9:12]), spe = sub(Q3_PREFIX, "", colnames[9:12]))
Expand All @@ -45,7 +45,7 @@ synthesize_wishes <- function(wishes) {
df <- df[order(df$rank), ]
result <- c("MICA", df$spe)
} else {
stop("Unknown filière")
stop("Unknown filiere")
}
return(result)
}
Expand All @@ -57,15 +57,15 @@ synthesize_wishes <- function(wishes) {
parse_file <- function(file_path) {
# Get file data as a data frame
tryCatch({
file_data <- select_file_type(file_path)
file_data <- read_file(file_path)
}, error = function(e) {
stop("Error while reading the file : ", conditionMessage(e))
})
# Build the result data frame
data <- data.frame(
Nom = rep(NA_character_, nrow(file_data)),
Prénom = rep(NA_character_, nrow(file_data)),
Filière = rep(NA_character_, nrow(file_data)),
Prenom = rep(NA_character_, nrow(file_data)),
Filiere = rep(NA_character_, nrow(file_data)),
V1 = rep(NA_character_, nrow(file_data)),
V2 = rep(NA_character_, nrow(file_data)),
V3 = rep(NA_character_, nrow(file_data)),
Expand All @@ -87,8 +87,8 @@ parse_file <- function(file_path) {
for (i in seq_len(nrow(file_data))) {
# Name
name_split <- strsplit(file_data[i, 1], split = " ")[[1]] # We assume that the first and last name are separated by a space
data[i, 1] <- name_split[1]
data[i, 2] <- name_split[2]
data[i, 1] <- name_split[2]
data[i, 2] <- name_split[1]
# Wishes
tryCatch({
synthesized_wishes <- synthesize_wishes(file_data[i, 3:18])
Expand Down
6 changes: 3 additions & 3 deletions man/select_file_type.Rd → man/read_file.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions man/synthesize_wishes.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added tests/data/test_file.ods
Binary file not shown.
Binary file added tests/data/test_file.xlsx
Binary file not shown.
5 changes: 4 additions & 1 deletion tests/testthat.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@

library(testthat)
library(ADSPlanner)
library(mockr)
library(openxlsx)
library(readODS)

test_check("ADSPlanner")
test_check("ADSPlanner")
172 changes: 172 additions & 0 deletions tests/testthat/setup.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
read_file_output <- data.frame(
"Nom complet" = c("Laurence Marchand", "Laurence ROZE", "Laurence Roze"),
"Nom d’utilisateur" = c("[email protected]", "[email protected]", "[email protected]"),
"Q01_Filiere" = c("1 : FC_FIRE (Filière classique ou filière internationale)", "2 : EMIR", "3 : MICA"),
"Q02_Voeux->EII" = c(1, NA, NA),
"Q02_Voeux->E&T" = c(2, NA, NA),
"Q02_Voeux->INFO" = c(5, NA, NA),
"Q02_Voeux->MA" = c(4, NA, NA),
"Q02_Voeux->GCU" = c(3, NA, NA),
"Q02_Voeux->GMA" = c(6, NA, NA),
"Q02_Voeux->GPM" = c(7, NA, NA),
"Q03_VoeuxEMIR->EII" = c(NA, 4, NA),
"Q03_VoeuxEMIR->INFO" = c(NA, 3, NA),
"Q03_VoeuxEMIR->GPM" = c(NA, 2, NA),
"Q03_VoeuxEMIR->E&T" = c(NA, 1, NA),
"Q04_voeuxMICA->GCU" = c(NA, NA, 4),
"Q04_voeuxMICA->MA" = c(NA, NA, 1),
"Q04_voeuxMICA->GMA" = c(NA, NA, 3),
"Q04_voeuxMICA->INFO" = c(NA, NA, 2),
check.names = FALSE
)

read_file_output_invalid <- data.frame(
"Nom complet" = c("Laurence Marchand", "Laurence ROZE", "Laurence Roze"),
"Nom d’utilisateur" = c("[email protected]", "[email protected]", "[email protected]"),
"Q01_Filiere" = c("1 : FC_FIRE (Filière classique ou filière internationale)", "4 : Filière that doesn't exist", "3 : MICA"),
"Q02_Voeux->EII" = c(1, NA, NA),
"Q02_Voeux->E&T" = c(2, NA, NA),
"Q02_Voeux->INFO" = c(5, NA, NA),
"Q02_Voeux->MA" = c(4, NA, NA),
"Q02_Voeux->GCU" = c(3, NA, NA),
"Q02_Voeux->GMA" = c(6, NA, NA),
"Q02_Voeux->GPM" = c(7, NA, NA),
"Q03_VoeuxEMIR->EII" = c(NA, 4, NA),
"Q03_VoeuxEMIR->INFO" = c(NA, 3, NA),
"Q03_VoeuxEMIR->GPM" = c(NA, 2, NA),
"Q03_VoeuxEMIR->E&T" = c(NA, 1, NA),
"Q04_voeuxMICA->GCU" = c(NA, NA, 4),
"Q04_voeuxMICA->MA" = c(NA, NA, 1),
"Q04_voeuxMICA->GMA" = c(NA, NA, 3),
"Q04_voeuxMICA->INFO" = c(NA, NA, 2),
check.names = FALSE
)

synth_wishes_input_fc_fire <- data.frame(
"Q01_Filiere" = "1 : FC_FIRE (Filière classique ou filière internationale)",
"Q02_Voeux->EII" = 1,
"Q02_Voeux->E&T" = 2,
"Q02_Voeux->INFO" = 5,
"Q02_Voeux->MA" = 4,
"Q02_Voeux->GCU" = 3,
"Q02_Voeux->GMA" = 6,
"Q02_Voeux->GPM" = 7,
"Q03_VoeuxEMIR->EII" = NA,
"Q03_VoeuxEMIR->INFO" = NA,
"Q03_VoeuxEMIR->GPM" = NA,
"Q03_VoeuxEMIR->E&T" = NA,
"Q04_voeuxMICA->GCU" = NA,
"Q04_voeuxMICA->MA" = NA,
"Q04_voeuxMICA->GMA" = NA,
"Q04_voeuxMICA->INFO" = NA,
check.names = FALSE
)

synth_wishes_output_fc_fire <- c(
"FC_FIRE",
"EII",
"E&T",
"GCU",
"MA",
"INFO",
"GMA",
"GPM"
)

synth_wishes_input_emir <- data.frame(
"Q01_Filiere" = "2 : EMIR",
"Q02_Voeux->EII" = NA,
"Q02_Voeux->E&T" = NA,
"Q02_Voeux->INFO" = NA,
"Q02_Voeux->MA" = NA,
"Q02_Voeux->GCU" = NA,
"Q02_Voeux->GMA" = NA,
"Q02_Voeux->GPM" = NA,
"Q03_VoeuxEMIR->EII" = 4,
"Q03_VoeuxEMIR->INFO" = 3,
"Q03_VoeuxEMIR->GPM" = 2,
"Q03_VoeuxEMIR->E&T" = 1,
"Q04_voeuxMICA->GCU" = NA,
"Q04_voeuxMICA->MA" = NA,
"Q04_voeuxMICA->GMA" = NA,
"Q04_voeuxMICA->INFO" = NA,
check.names = FALSE
)

synth_wishes_output_emir <- c(
"EMIR",
"E&T",
"GPM",
"INFO",
"EII"
)

synth_wishes_input_mica <- data.frame(
"Q01_Filiere" = "3 : MICA",
"Q02_Voeux->EII" = NA,
"Q02_Voeux->E&T" = NA,
"Q02_Voeux->INFO" = NA,
"Q02_Voeux->MA" = NA,
"Q02_Voeux->GCU" = NA,
"Q02_Voeux->GMA" = NA,
"Q02_Voeux->GPM" = NA,
"Q03_VoeuxEMIR->EII" = NA,
"Q03_VoeuxEMIR->INFO" = NA,
"Q03_VoeuxEMIR->GPM" = NA,
"Q03_VoeuxEMIR->E&T" = NA,
"Q04_voeuxMICA->GCU" = 4,
"Q04_voeuxMICA->MA" = 1,
"Q04_voeuxMICA->GMA" = 3,
"Q04_voeuxMICA->INFO" = 2,
check.names = FALSE
)

synth_wishes_output_mica <- c(
"MICA",
"MA",
"INFO",
"GMA",
"GCU"
)

synth_wishes_input_invalid <- data.frame(
"Q01_Filiere" = "4 : Filière that doesn't exist",
"Q02_Voeux->EII" = NA,
"Q02_Voeux->E&T" = NA,
"Q02_Voeux->INFO" = NA,
"Q02_Voeux->MA" = NA,
"Q02_Voeux->GCU" = NA,
"Q02_Voeux->GMA" = NA,
"Q02_Voeux->GPM" = NA,
"Q03_VoeuxEMIR->EII" = NA,
"Q03_VoeuxEMIR->INFO" = NA,
"Q03_VoeuxEMIR->GPM" = NA,
"Q03_VoeuxEMIR->E&T" = NA,
"Q04_voeuxMICA->GCU" = 4,
"Q04_voeuxMICA->MA" = 1,
"Q04_voeuxMICA->GMA" = 3,
"Q04_voeuxMICA->INFO" = 2,
check.names = FALSE
)

parse_file_output <- data.frame(
Nom = c("Marchand", "ROZE", "Roze"),
Prenom = c("Laurence", "Laurence", "Laurence"),
Filiere = c("FC_FIRE", "EMIR", "MICA"),
V1 = c("EII", "E&T", "MA"),
V2 = c("E&T", "GPM", "INFO"),
V3 = c("GCU", "INFO", "GMA"),
V4 = c("MA", "EII", "GCU"),
V5 = c("INFO", NA_character_, NA_character_),
V6 = c("GMA", NA_character_, NA_character_),
V7 = c("GPM", NA_character_, NA_character_),
Aff_V1_S1 = c(NA_character_, NA_character_, NA_character_),
Aff_V1_S2 = c(NA_character_, NA_character_, NA_character_),
Aff_V1_S3 = c(NA_character_, NA_character_, NA_character_),
Aff_V2_S1 = c(NA_character_, NA_character_, NA_character_),
Aff_V2_S2 = c(NA_character_, NA_character_, NA_character_),
Aff_V2_S3 = c(NA_character_, NA_character_, NA_character_),
Aff_V3_S1 = c(NA_character_, NA_character_, NA_character_),
Aff_V3_S2 = c(NA_character_, NA_character_, NA_character_),
Aff_V3_S3 = c(NA_character_, NA_character_, NA_character_)
)
80 changes: 80 additions & 0 deletions tests/testthat/test-input.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Testing read_file

test_that("read_file reads xlsx files correctly", {
file_path <- "../data/test_file.xlsx"
result <- read_file(file_path)
expect_true(is.data.frame(result))
expect_equal(ncol(result), 18)
expect_equal(result, read_file_output)
})

test_that("read_file reads ods files correctly", {
file_path <- "../data/test_file.ods"
result <- read_file(file_path)
expect_true(is.data.frame(result))
expect_equal(ncol(result), 18)
expect_equal(result, read_file_output)
})

test_that("read_file throws error for unsupported file types", {
file_path <- "../data/test_file.csv"
expect_error(read_file(file_path), "File type not supported")
})

test_that("read_file throws error for non existing file", {
file_path <- "../data/imaginary_file.xlsx"
expect_error(read_file(file_path), "File does not exist")
})

# Testing synthesize_wishes

test_that("synthesize_wishes return correct result for FC_FIRE", {
result <- synthesize_wishes(synth_wishes_input_fc_fire)
expect_true(is.vector(result))
expect_equal(length(result), 8)
expect_equal(result, synth_wishes_output_fc_fire)
})

test_that("synthesize_wishes return correct result for EMIR", {
result <- synthesize_wishes(synth_wishes_input_emir)
expect_true(is.vector(result))
expect_equal(length(result), 5)
expect_equal(result, synth_wishes_output_emir)
})

test_that("synthesize_wishes return correct result for MICA", {
result <- synthesize_wishes(synth_wishes_input_mica)
expect_true(is.vector(result))
expect_equal(length(result), 5)
expect_equal(result, synth_wishes_output_mica)
})

test_that("synthesize_wishes throws error for non existing filière", {
expect_error(synthesize_wishes(synth_wishes_input_invalid), "Unknown filiere")
})

# Testing parse_file

test_that("parse_file returns correct result for a valid input file", {
local_mock(read_file = function(file_path) read_file_output)
result <- parse_file("../data/test_file.xlsx")
expect_equal(result, parse_file_output)
})

test_that("parse_file throws error for invalid input file type", {
local_mock(read_file = function(file_path) stop("File type not supported"))
expect_error(parse_file("../data/test_file.csv"), "Error while reading the file : File type not supported")
})

test_that("parse_file throws error for non existent file", {
local_mock(read_file = function(file_path) stop("File does not exist"))
expect_error(parse_file("../data/imaginary_file.xlsx"), "Error while reading the file : File does not exist")
})

test_that("parse_file throws error for invalid data", {
local_mock(
read_file = function(file_path) read_file_output_invalid,
synthesize_wishes = function(wishes) stop("Unknown filière")
)
expect_error(parse_file("../data/test_file.xlsx"), "Error while synthesizing the wishes \\(l\\.1\\): Unknown filière")
})
Empty file removed tests/testthat/tests.R
Empty file.

0 comments on commit 0b0a96f

Please sign in to comment.