read_zip_xml <- function(zipfile, member) { readLines(unz(zipfile, member), warn = FALSE) } fixture_path <- function(name) { test_path("..", "fixtures", name) } example_path <- function(name) { system.file("examples", name, package = "exams2ilias") } test_that("non-placeholder cloze export uses ILIAS top-level items", { mydir <- tempfile("exams2ilias-") dir.create(mydir) exams2ilias( system.file("exercises/lm.Rmd", package = "exams"), n = 1, dir = mydir, name = "lm_ilias", xmlcollapse = FALSE ) lm_zip <- file.path(mydir, "lm_ilias_qpl.zip") expect_true(file.exists(lm_zip)) lm_qti <- read_zip_xml(lm_zip, "lm_ilias_qpl/lm_ilias_qti.xml") lm_qpl <- read_zip_xml(lm_zip, "lm_ilias_qpl/lm_ilias_qpl.xml") expect_false(any(grepl("CLOZE QUESTION", lm_qti, fixed = TRUE))) expect_true(any(grepl('maxattempts="0"', lm_qti, fixed = TRUE))) expect_true(any(grepl('textgaprating", lm_qti, fixed = TRUE))) expect_false(any(grepl("AUTHOR", lm_qti, fixed = TRUE))) expect_false(any(grepl("fixedTextLength", lm_qti, fixed = TRUE))) expect_false(any(grepl("', lm_qpl, perl = TRUE))) }) test_that("metadata fields are emitted as siblings in single-choice items", { mydir <- tempfile("exams2ilias-") dir.create(mydir) exams2ilias( system.file("exercises/swisscapital.Rmd", package = "exams"), n = 1, dir = mydir, name = "swiss_ilias", xmlcollapse = FALSE ) swiss_zip <- file.path(mydir, "swiss_ilias_qpl.zip") swiss_qti <- paste(read_zip_xml(swiss_zip, "swiss_ilias_qpl/swiss_ilias_qti.xml"), collapse = "\n") expect_true(grepl( "QUESTIONTYPE\\s*SINGLE CHOICE QUESTION\\s*\\s*\\s*AUTHOR", swiss_qti, perl = TRUE )) expect_false(grepl( "identicalScoring\\s*", swiss_qti, perl = TRUE )) expect_true(grepl( "fixedTextLength\\s*\\s*\\s*\\s*identicalScoring", swiss_qti, perl = TRUE )) }) test_that("placeholder cloze export keeps the simplified ILIAS structure", { mydir <- tempfile("exams2ilias-") dir.create(mydir) exams2ilias( system.file("exercises/vowels.Rmd", package = "exams"), n = 1, dir = mydir, name = "vowels_ilias", xmlcollapse = FALSE ) vowels_zip <- file.path(mydir, "vowels_ilias_qpl.zip") expect_true(file.exists(vowels_zip)) vowels_qti <- read_zip_xml(vowels_zip, "vowels_ilias_qpl/vowels_ilias_qti.xml") expect_false(any(grepl(" ', vowels_qti, fixed = TRUE))) expect_false(any(grepl("'), qti, fixed = TRUE))) expect_true(any(grepl('1', qti, fixed = TRUE))) expect_false(any(grepl('1', qti, fixed = TRUE))) }) test_that("multiple-choice export keeps partial-credit scoring without all-or-nothing fallback", { mydir <- tempfile("exams2ilias-") dir.create(mydir) exams2ilias( fixture_path("mchoice_01_math.Rmd"), n = 1, dir = mydir, name = "mchoice_math", xmlcollapse = FALSE, eval = list(partial = TRUE, negative = TRUE) ) qti <- read_zip_xml(file.path(mydir, "mchoice_math_qpl.zip"), "mchoice_math_qpl/mchoice_math_qti.xml") expect_true(any(grepl('1', qti, fixed = TRUE)), 3L) expect_true(any(grepl('-1\\.5', qti, perl = TRUE))) expect_false(any(grepl('3', qti, fixed = TRUE))) }) test_that("bundled example exercises export individually", { example_files <- c( "stats_cloze.Rmd", "stats_schoice.Rmd", "stats_mchoice.Rmd", "stats_num.Rmd", "stats_string.Rmd" ) mydir <- tempfile("exams2ilias-") dir.create(mydir) for(file in example_files) { example_file <- example_path(file) expect_true(file.exists(example_file), info = file) export_name <- tools::file_path_sans_ext(basename(file)) expect_no_error({ exams2ilias( example_file, n = 1, dir = mydir, name = export_name, xmlcollapse = FALSE, solutionswitch = FALSE ) }) zipfile <- file.path(mydir, paste0(export_name, "_qpl.zip")) expect_true(file.exists(zipfile), info = file) } }) test_that("bundled generator script exports example set and combined pool", { script <- example_path("generate_examples.R") expect_true(file.exists(script)) env <- new.env(parent = globalenv()) source(script, local = env) expect_true(is.function(env$generate_example_exports)) mydir <- tempfile("exams2ilias-") dir.create(mydir) result <- env$generate_example_exports(output_dir = mydir, n = 1, combined = TRUE) expect_length(result$individual, 5L) expect_true(all(file.exists(result$individual))) expect_true(file.exists(result$combined)) })