mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
gift import/export MDL-25088 another attempt at fixing it, this time with unit tests.
This commit is contained in:
parent
94263cca87
commit
5b744492a6
2 changed files with 815 additions and 102 deletions
|
@ -54,29 +54,31 @@ class qformat_gift extends qformat_default {
|
||||||
return $answer_weight;
|
return $answer_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentparser(&$answer) {
|
function commentparser($answer, $defaultformat) {
|
||||||
if (strpos($answer,"#") > 0) {
|
$bits = explode('#', $answer, 2);
|
||||||
$hashpos = strpos($answer,"#");
|
$ans = $this->parse_text_with_format(trim($bits[0]), $defaultformat);
|
||||||
$comment = substr($answer, $hashpos+1);
|
if (count($bits) > 1) {
|
||||||
$comment = trim($this->escapedchar_post($comment));
|
$feedback = $this->parse_text_with_format(trim($bits[1]), $defaultformat);
|
||||||
$answer = substr($answer, 0, $hashpos);
|
|
||||||
} else {
|
} else {
|
||||||
$comment = " ";
|
$feedback = array('text' => '', 'format' => $defaultformat, 'files' => array());
|
||||||
}
|
}
|
||||||
return $comment;
|
return array($ans, $feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function split_truefalse_comment($comment) {
|
function split_truefalse_comment($answer, $defaultformat) {
|
||||||
// splits up comment around # marks
|
$bits = explode('#', $answer, 3);
|
||||||
// returns an array of true/false feedback
|
$ans = $this->parse_text_with_format(trim($bits[0]), $defaultformat);
|
||||||
$bits = explode('#',$comment);
|
if (count($bits) > 1) {
|
||||||
$feedback = array('wrong' => $bits[0]);
|
$wrongfeedback = $this->parse_text_with_format(trim($bits[1]), $defaultformat);
|
||||||
if (count($bits) >= 2) {
|
|
||||||
$feedback['right'] = $bits[1];
|
|
||||||
} else {
|
} else {
|
||||||
$feedback['right'] = '';
|
$wrongfeedback = array('text' => '', 'format' => $defaultformat, 'files' => array());
|
||||||
}
|
}
|
||||||
return $feedback;
|
if (count($bits) > 2) {
|
||||||
|
$rightfeedback = $this->parse_text_with_format(trim($bits[2]), $defaultformat);
|
||||||
|
} else {
|
||||||
|
$rightfeedback = array('text' => '', 'format' => $defaultformat, 'files' => array());
|
||||||
|
}
|
||||||
|
return array($ans, $wrongfeedback, $rightfeedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapedchar_pre($string) {
|
function escapedchar_pre($string) {
|
||||||
|
@ -110,6 +112,24 @@ class qformat_gift extends qformat_default {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function parse_text_with_format($text, $defaultformat = FORMAT_MOODLE) {
|
||||||
|
$result = array(
|
||||||
|
'text' => $text,
|
||||||
|
'format' => $defaultformat,
|
||||||
|
'files' => array(),
|
||||||
|
);
|
||||||
|
if (strpos($text, '[') === 0) {
|
||||||
|
$formatend = strpos($text, ']');
|
||||||
|
$result['format'] = $this->format_name_to_const(substr($text, 1, $formatend - 1));
|
||||||
|
if ($result['format'] == -1) {
|
||||||
|
$result['format'] = $defaultformat;
|
||||||
|
} else {
|
||||||
|
$result['text'] = substr($text, $formatend + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result['text'] = trim($this->escapedchar_post($result['text']));
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
function readquestion($lines) {
|
function readquestion($lines) {
|
||||||
// Given an array of lines known to define a question in this format, this function
|
// Given an array of lines known to define a question in this format, this function
|
||||||
|
@ -196,18 +216,10 @@ class qformat_gift extends qformat_default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get questiontext format from questiontext
|
// Get questiontext format from questiontext
|
||||||
$questiontextformat = FORMAT_MOODLE;
|
$text = $this->parse_text_with_format($questiontext);
|
||||||
if (strpos($questiontext, '[') === 0) {
|
$question->questiontextformat = $text['format'];
|
||||||
$formatend = strpos($questiontext, ']');
|
$question->generalfeedbackformat = $text['format'];
|
||||||
$questiontextformat = $this->format_name_to_const(substr($questiontext, 1, $formatend));
|
$question->questiontext = $text['text'];
|
||||||
if ($questiontextformat == -1) {
|
|
||||||
$questiontextformat = FORMAT_MOODLE;
|
|
||||||
} else {
|
|
||||||
$questiontext = substr($questiontext, $formatend + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$question->questiontextformat = $questiontextformat;
|
|
||||||
$question->questiontext = trim($this->escapedchar_post($questiontext));
|
|
||||||
|
|
||||||
// set question name if not already set
|
// set question name if not already set
|
||||||
if ($question->name === false) {
|
if ($question->name === false) {
|
||||||
|
@ -279,7 +291,7 @@ class qformat_gift extends qformat_default {
|
||||||
case ESSAY:
|
case ESSAY:
|
||||||
$question->fraction = 0;
|
$question->fraction = 0;
|
||||||
$question->feedback['text'] = '';
|
$question->feedback['text'] = '';
|
||||||
$question->feedback['format'] = $questiontextformat;
|
$question->feedback['format'] = $question->questiontextformat;
|
||||||
$question->feedback['files'] = array();
|
$question->feedback['files'] = array();
|
||||||
return $question;
|
return $question;
|
||||||
break;
|
break;
|
||||||
|
@ -290,13 +302,13 @@ class qformat_gift extends qformat_default {
|
||||||
$question->single = 1; // only one answer allowed (the default)
|
$question->single = 1; // only one answer allowed (the default)
|
||||||
}
|
}
|
||||||
$question->correctfeedback['text'] = '';
|
$question->correctfeedback['text'] = '';
|
||||||
$question->correctfeedback['format'] = $questiontextformat;
|
$question->correctfeedback['format'] = $question->questiontextformat;
|
||||||
$question->correctfeedback['files'] = array();
|
$question->correctfeedback['files'] = array();
|
||||||
$question->partiallycorrectfeedback['text'] = '';
|
$question->partiallycorrectfeedback['text'] = '';
|
||||||
$question->partiallycorrectfeedback['format'] = $questiontextformat;
|
$question->partiallycorrectfeedback['format'] = $question->questiontextformat;
|
||||||
$question->partiallycorrectfeedback['files'] = array();
|
$question->partiallycorrectfeedback['files'] = array();
|
||||||
$question->incorrectfeedback['text'] = '';
|
$question->incorrectfeedback['text'] = '';
|
||||||
$question->incorrectfeedback['format'] = $questiontextformat;
|
$question->incorrectfeedback['format'] = $question->questiontextformat;
|
||||||
$question->incorrectfeedback['files'] = array();
|
$question->incorrectfeedback['files'] = array();
|
||||||
|
|
||||||
$answertext = str_replace("=", "~=", $answertext);
|
$answertext = str_replace("=", "~=", $answertext);
|
||||||
|
@ -329,14 +341,9 @@ class qformat_gift extends qformat_default {
|
||||||
} else { //default, i.e., wrong anwer
|
} else { //default, i.e., wrong anwer
|
||||||
$answer_weight = 0;
|
$answer_weight = 0;
|
||||||
}
|
}
|
||||||
$question->answer[$key]['text'] =
|
list($question->answer[$key], $question->feedback[$key]) =
|
||||||
$this->escapedchar_post($answer);
|
$this->commentparser($answer, $question->questiontextformat);
|
||||||
$question->answer[$key]['format'] = $questiontextformat;
|
|
||||||
$question->answer[$key]['files'] = array();
|
|
||||||
$question->fraction[$key] = $answer_weight;
|
$question->fraction[$key] = $answer_weight;
|
||||||
$question->feedback[$key]['text'] = $this->commentparser($answer); // commentparser also removes comment from $answer
|
|
||||||
$question->feedback[$key]['format'] = $questiontextformat;
|
|
||||||
$question->feedback[$key]['files'] = array();
|
|
||||||
} // end foreach answer
|
} // end foreach answer
|
||||||
|
|
||||||
//$question->defaultgrade = 1;
|
//$question->defaultgrade = 1;
|
||||||
|
@ -368,38 +375,30 @@ class qformat_gift extends qformat_default {
|
||||||
}
|
}
|
||||||
|
|
||||||
$marker = strpos($answer, '->');
|
$marker = strpos($answer, '->');
|
||||||
$question->subquestions[$key]['text'] =
|
$question->subquestions[$key] = $this->parse_text_with_format(
|
||||||
trim($this->escapedchar_post(substr($answer, 0, $marker)));
|
substr($answer, 0, $marker), $question->questiontextformat);
|
||||||
$question->subquestions[$key]['format'] = $questiontextformat;
|
$question->subanswers[$key] = trim($this->escapedchar_post(
|
||||||
$question->subquestions[$key]['files'] = array();
|
substr($answer, $marker + 2)));
|
||||||
$question->subanswers[$key] =
|
}
|
||||||
trim($this->escapedchar_post(substr($answer, $marker + 2)));
|
|
||||||
} // end foreach answer
|
|
||||||
|
|
||||||
return $question;
|
return $question;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRUEFALSE:
|
case TRUEFALSE:
|
||||||
$answer = $answertext;
|
list($answer, $wrongfeedback, $rightfeedback) =
|
||||||
$comment = $this->commentparser($answer); // commentparser also removes comment from $answer
|
$this->split_truefalse_comment($answertext, $question->questiontextformat);
|
||||||
$feedback = $this->split_truefalse_comment($comment);
|
|
||||||
|
|
||||||
if ($answer == "T" OR $answer == "TRUE") {
|
if ($answer == "T" OR $answer == "TRUE") {
|
||||||
$question->answer = 1;
|
$question->correctanswer = 1;
|
||||||
$question->feedbacktrue['text'] = $feedback['right'];
|
$question->feedbacktrue = $rightfeedback;
|
||||||
$question->feedbackfalse['text'] = $feedback['wrong'];
|
$question->feedbackfalse = $wrongfeedback;
|
||||||
} else {
|
} else {
|
||||||
$question->answer = 0;
|
$question->correctanswer = 0;
|
||||||
$question->feedbackfalse['text'] = $feedback['right'];
|
$question->feedbacktrue = $wrongfeedback;
|
||||||
$question->feedbacktrue['text'] = $feedback['wrong'];
|
$question->feedbackfalse = $rightfeedback;
|
||||||
}
|
}
|
||||||
$question->feedbackfalse['format'] = $questiontextformat;
|
|
||||||
$question->feedbacktrue['format'] = $questiontextformat;
|
|
||||||
$question->feedbackfalse['files'] = array();
|
|
||||||
$question->feedbacktrue['files'] = array();
|
|
||||||
|
|
||||||
$question->penalty = 1;
|
$question->penalty = 1;
|
||||||
$question->correctanswer = $question->answer;
|
|
||||||
|
|
||||||
return $question;
|
return $question;
|
||||||
break;
|
break;
|
||||||
|
@ -414,7 +413,7 @@ class qformat_gift extends qformat_default {
|
||||||
array_shift($answers);
|
array_shift($answers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->check_answer_count(1,$answers,$text)) {
|
if (!$this->check_answer_count(1, $answers, $text)) {
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -422,22 +421,20 @@ class qformat_gift extends qformat_default {
|
||||||
foreach ($answers as $key => $answer) {
|
foreach ($answers as $key => $answer) {
|
||||||
$answer = trim($answer);
|
$answer = trim($answer);
|
||||||
|
|
||||||
// Answer Weight
|
// Answer weight
|
||||||
if (preg_match($gift_answerweight_regex, $answer)) { // check for properly formatted answer weight
|
if (preg_match($gift_answerweight_regex, $answer)) { // check for properly formatted answer weight
|
||||||
$answer_weight = $this->answerweightparser($answer);
|
$answer_weight = $this->answerweightparser($answer);
|
||||||
} else { //default, i.e., full-credit anwer
|
} else { //default, i.e., full-credit anwer
|
||||||
$answer_weight = 1;
|
$answer_weight = 1;
|
||||||
}
|
}
|
||||||
$question->answer[$key] = $this->escapedchar_post($answer);
|
|
||||||
$question->fraction[$key] = $answer_weight;
|
|
||||||
$question->feedback[$key]['text'] = $this->commentparser($answer); //commentparser also removes comment from $answer
|
|
||||||
$question->feedback[$key]['format'] = $questiontextformat;
|
|
||||||
$question->feedback[$key]['files'] = array();
|
|
||||||
} // end foreach
|
|
||||||
|
|
||||||
//$question->usecase = 0; // Ignore case
|
list($answer, $question->feedback[$key]) = $this->commentparser(
|
||||||
//$question->defaultgrade = 1;
|
$answer, $question->questiontextformat);
|
||||||
//$question->image = ""; // No images with this format
|
|
||||||
|
$question->answer[$key] = $answer['text'];
|
||||||
|
$question->fraction[$key] = $answer_weight;
|
||||||
|
}
|
||||||
|
|
||||||
return $question;
|
return $question;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -478,10 +475,11 @@ class qformat_gift extends qformat_default {
|
||||||
} else { //default, i.e., full-credit anwer
|
} else { //default, i.e., full-credit anwer
|
||||||
$answer_weight = 1;
|
$answer_weight = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list($answer, $question->feedback[$key]) = $this->commentparser(
|
||||||
|
$answer, $question->questiontextformat);
|
||||||
$question->fraction[$key] = $answer_weight;
|
$question->fraction[$key] = $answer_weight;
|
||||||
$question->feedback[$key]['text'] = $this->commentparser($answer); //commentparser also removes comment from $answer
|
$answer = $answer['text'];
|
||||||
$question->feedback[$key]['format'] = $questiontextformat;
|
|
||||||
$question->feedback[$key]['files'] = array();
|
|
||||||
|
|
||||||
//Calculate Answer and Min/Max values
|
//Calculate Answer and Min/Max values
|
||||||
if (strpos($answer,"..") > 0) { // optional [min]..[max] format
|
if (strpos($answer,"..") > 0) { // optional [min]..[max] format
|
||||||
|
@ -509,14 +507,13 @@ class qformat_gift extends qformat_default {
|
||||||
// store results
|
// store results
|
||||||
$question->answer[$key] = $ans;
|
$question->answer[$key] = $ans;
|
||||||
$question->tolerance[$key] = $tol;
|
$question->tolerance[$key] = $tol;
|
||||||
} // end foreach
|
}
|
||||||
|
|
||||||
if ($wrongfeedback) {
|
if ($wrongfeedback) {
|
||||||
$key += 1;
|
$key += 1;
|
||||||
$question->fraction[$key] = 0;
|
$question->fraction[$key] = 0;
|
||||||
$question->feedback[$key]['text'] = $this->commentparser($wrongfeedback);
|
list($notused, $question->feedback[$key]) = $this->commentparser(
|
||||||
$question->feedback[$key]['format'] = $questiontextformat;
|
$wrongfeedback, $question->questiontextformat);
|
||||||
$question->feedback[$key]['files'] = array();
|
|
||||||
$question->answer[$key] = '*';
|
$question->answer[$key] = '*';
|
||||||
$question->tolerance[$key] = '';
|
$question->tolerance[$key] = '';
|
||||||
}
|
}
|
||||||
|
@ -526,7 +523,7 @@ class qformat_gift extends qformat_default {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->error(get_string('giftnovalidquestion', 'quiz'), $text);
|
$this->error(get_string('giftnovalidquestion', 'quiz'), $text);
|
||||||
return false;
|
return fale;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -569,7 +566,7 @@ class qformat_gift extends qformat_default {
|
||||||
if ($format == 'moodle') {
|
if ($format == 'moodle') {
|
||||||
return FORMAT_MOODLE;
|
return FORMAT_MOODLE;
|
||||||
} else if ($format == 'html') {
|
} else if ($format == 'html') {
|
||||||
return FORMAT_PLAIN;
|
return FORMAT_HTML;
|
||||||
} else if ($format == 'plain') {
|
} else if ($format == 'plain') {
|
||||||
return FORMAT_PLAIN;
|
return FORMAT_PLAIN;
|
||||||
} else if ($format == 'markdown') {
|
} else if ($format == 'markdown') {
|
||||||
|
@ -583,9 +580,9 @@ class qformat_gift extends qformat_default {
|
||||||
return '::' . $this->repchar($name) . '::';
|
return '::' . $this->repchar($name) . '::';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function write_questiontext($text, $format) {
|
public function write_questiontext($text, $format, $defaultformat = FORMAT_MOODLE) {
|
||||||
$output = '';
|
$output = '';
|
||||||
if ($format != FORMAT_MOODLE) {
|
if ($text != '' && $format != $defaultformat) {
|
||||||
$output .= '[' . $this->format_const_to_name($format) . ']';
|
$output .= '[' . $this->format_const_to_name($format) . ']';
|
||||||
}
|
}
|
||||||
$output .= $this->repchar($text, $format);
|
$output .= $this->repchar($text, $format);
|
||||||
|
@ -596,7 +593,7 @@ class qformat_gift extends qformat_default {
|
||||||
global $QTYPES, $OUTPUT;
|
global $QTYPES, $OUTPUT;
|
||||||
|
|
||||||
// Start with a comment
|
// Start with a comment
|
||||||
$expout = "// question: $question->id name: $question->name \n";
|
$expout = "// question: $question->id name: $question->name\n";
|
||||||
|
|
||||||
// output depends on question type
|
// output depends on question type
|
||||||
switch($question->qtype) {
|
switch($question->qtype) {
|
||||||
|
@ -622,27 +619,28 @@ class qformat_gift extends qformat_default {
|
||||||
$falseanswer = $question->options->answers[$question->options->falseanswer];
|
$falseanswer = $question->options->answers[$question->options->falseanswer];
|
||||||
if ($trueanswer->fraction == 1) {
|
if ($trueanswer->fraction == 1) {
|
||||||
$answertext = 'TRUE';
|
$answertext = 'TRUE';
|
||||||
$right_feedback = $trueanswer->feedback;
|
$rightfeedback = $this->write_questiontext($trueanswer->feedback,
|
||||||
$wrong_feedback = $falseanswer->feedback;
|
$trueanswer->feedbackformat, $question->questiontextformat);
|
||||||
|
$wrongfeedback = $this->write_questiontext($falseanswer->feedback,
|
||||||
|
$falseanswer->feedbackformat, $question->questiontextformat);
|
||||||
} else {
|
} else {
|
||||||
$answertext = 'FALSE';
|
$answertext = 'FALSE';
|
||||||
$right_feedback = $falseanswer->feedback;
|
$rightfeedback = $this->write_questiontext($falseanswer->feedback,
|
||||||
$wrong_feedback = $trueanswer->feedback;
|
$falseanswer->feedbackformat, $question->questiontextformat);
|
||||||
|
$wrongfeedback = $this->write_questiontext($trueanswer->feedback,
|
||||||
|
$trueanswer->feedbackformat, $question->questiontextformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
$wrong_feedback = $this->repchar($wrong_feedback);
|
|
||||||
$right_feedback = $this->repchar($right_feedback);
|
|
||||||
|
|
||||||
$expout .= $this->write_name($question->name);
|
$expout .= $this->write_name($question->name);
|
||||||
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
|
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
|
||||||
$expout .= '{' . $this->repchar($answertext);
|
$expout .= '{' . $this->repchar($answertext);
|
||||||
if ($wrong_feedback) {
|
if ($wrongfeedback) {
|
||||||
$expout .= '#' . $wrong_feedback;
|
$expout .= '#' . $wrongfeedback;
|
||||||
} else if ($right_feedback) {
|
} else if ($rightfeedback) {
|
||||||
$expout .= '#';
|
$expout .= '#';
|
||||||
}
|
}
|
||||||
if ($right_feedback) {
|
if ($rightfeedback) {
|
||||||
$expout .= '#' . $right_feedback;
|
$expout .= '#' . $rightfeedback;
|
||||||
}
|
}
|
||||||
$expout .= "}\n";
|
$expout .= "}\n";
|
||||||
break;
|
break;
|
||||||
|
@ -660,9 +658,11 @@ class qformat_gift extends qformat_default {
|
||||||
$weight = $answer->fraction * 100;
|
$weight = $answer->fraction * 100;
|
||||||
$answertext = '~%' . $weight . '%';
|
$answertext = '~%' . $weight . '%';
|
||||||
}
|
}
|
||||||
$expout .= "\t" . $answertext . $this->repchar($answer->answer);
|
$expout .= "\t" . $answertext . $this->write_questiontext($answer->answer,
|
||||||
|
$answer->answerformat, $question->questiontextformat);
|
||||||
if ($answer->feedback != '') {
|
if ($answer->feedback != '') {
|
||||||
$expout .= '#' . $this->repchar($answer->feedback);
|
$expout .= '#' . $this->write_questiontext($answer->feedback,
|
||||||
|
$answer->feedbackformat, $question->questiontextformat);
|
||||||
}
|
}
|
||||||
$expout .= "\n";
|
$expout .= "\n";
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,8 @@ class qformat_gift extends qformat_default {
|
||||||
foreach($question->options->answers as $answer) {
|
foreach($question->options->answers as $answer) {
|
||||||
$weight = 100 * $answer->fraction;
|
$weight = 100 * $answer->fraction;
|
||||||
$expout .= "\t=%" . $weight . '%' . $this->repchar($answer->answer) .
|
$expout .= "\t=%" . $weight . '%' . $this->repchar($answer->answer) .
|
||||||
'#' . $this->repchar($answer->feedback) . "\n";
|
'#' . $this->write_questiontext($answer->feedback,
|
||||||
|
$answer->feedbackformat, $question->questiontextformat) . "\n";
|
||||||
}
|
}
|
||||||
$expout .= "}\n";
|
$expout .= "}\n";
|
||||||
break;
|
break;
|
||||||
|
@ -689,9 +690,11 @@ class qformat_gift extends qformat_default {
|
||||||
if ($answer->answer != '' && $answer->answer != '*') {
|
if ($answer->answer != '' && $answer->answer != '*') {
|
||||||
$weight = 100 * $answer->fraction;
|
$weight = 100 * $answer->fraction;
|
||||||
$expout .= "\t=%" . $weight . '%' . $answer->answer . ':' .
|
$expout .= "\t=%" . $weight . '%' . $answer->answer . ':' .
|
||||||
(float)$answer->tolerance . '#' . $this->repchar($answer->feedback) . "\n";
|
(float)$answer->tolerance . '#' . $this->write_questiontext($answer->feedback,
|
||||||
|
$answer->feedbackformat, $question->questiontextformat) . "\n";
|
||||||
} else {
|
} else {
|
||||||
$expout .= "\t~#" . $this->repchar($answer->feedback) . "\n";
|
$expout .= "\t~#" . $this->write_questiontext($answer->feedback,
|
||||||
|
$answer->feedbackformat, $question->questiontextformat) . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$expout .= "}\n";
|
$expout .= "}\n";
|
||||||
|
@ -702,7 +705,7 @@ class qformat_gift extends qformat_default {
|
||||||
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
|
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
|
||||||
$expout .= "{\n";
|
$expout .= "{\n";
|
||||||
foreach($question->options->subquestions as $subquestion) {
|
foreach($question->options->subquestions as $subquestion) {
|
||||||
$expout .= "\t=" . $this->repchar($subquestion->questiontext) .
|
$expout .= "\t=" . $this->repchar($this->write_questiontext($subquestion->questiontext, $subquestion->questiontextformat, $question->questiontextformat)) .
|
||||||
' -> ' . $this->repchar($subquestion->answertext) . "\n";
|
' -> ' . $this->repchar($subquestion->answertext) . "\n";
|
||||||
}
|
}
|
||||||
$expout .= "}\n";
|
$expout .= "}\n";
|
||||||
|
|
710
question/format/gift/simpletest/testgiftformat.php
Normal file
710
question/format/gift/simpletest/testgiftformat.php
Normal file
|
@ -0,0 +1,710 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the Moodle GIFT format.
|
||||||
|
*
|
||||||
|
* @package qformat_xml
|
||||||
|
* @copyright 2010 The Open University
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once($CFG->libdir . '/questionlib.php');
|
||||||
|
require_once($CFG->dirroot . '/question/format.php');
|
||||||
|
require_once($CFG->dirroot . '/question/format/gift/format.php');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the GIFT import/export format.
|
||||||
|
*
|
||||||
|
* @copyright 2010 The Open University
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
class qformat_gift_test extends UnitTestCase {
|
||||||
|
public function assert_same_gift($expectedtext, $text) {
|
||||||
|
$this->assertEqual(str_replace("\r\n", "\n", $expectedtext),
|
||||||
|
str_replace("\r\n", "\n", $text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_essay() {
|
||||||
|
$gift = '
|
||||||
|
// essay
|
||||||
|
::Q8:: How are you? {}';
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Q8',
|
||||||
|
'questiontext' => 'How are you?',
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'qtype' => 'essay',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'feedback' => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_essay() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Q8',
|
||||||
|
'questiontext' => 'How are you?',
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'essay',
|
||||||
|
'options' => (object) array(
|
||||||
|
'answers' => array(
|
||||||
|
123 => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'answer' => 666,
|
||||||
|
'answerformat' => FORMAT_MOODLE,
|
||||||
|
'fraction' => 0,
|
||||||
|
'feedback' => '',
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Q8
|
||||||
|
::Q8::How are you?{}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_match() {
|
||||||
|
$gift = '
|
||||||
|
// question: 2 name: Moodle activities
|
||||||
|
::Moodle activities::[html]Match the <b>activity</b> to the description.{
|
||||||
|
=[html]An activity supporting asynchronous discussions. -> Forum
|
||||||
|
=[moodle]A teacher asks a question and specifies a choice of multiple responses. -> Choice
|
||||||
|
=[plain]A bank of record entries which participants can add to. -> Database
|
||||||
|
=[markdown]A collection of web pages that anyone can add to or edit. -> Wiki
|
||||||
|
= -> Chat
|
||||||
|
}';
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Moodle activities',
|
||||||
|
'questiontext' => 'Match the <b>activity</b> to the description.',
|
||||||
|
'questiontextformat' => FORMAT_HTML,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_HTML,
|
||||||
|
'qtype' => 'match',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'shuffleanswers' => '1',
|
||||||
|
'subquestions' => array(
|
||||||
|
0 => array(
|
||||||
|
'text' => 'An activity supporting asynchronous discussions.',
|
||||||
|
'format' => FORMAT_HTML,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'text' => 'A teacher asks a question and specifies a choice of multiple responses.',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'text' => 'A bank of record entries which participants can add to.',
|
||||||
|
'format' => FORMAT_PLAIN,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
3 => array(
|
||||||
|
'text' => 'A collection of web pages that anyone can add to or edit.',
|
||||||
|
'format' => FORMAT_MARKDOWN,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
4 => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_HTML,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'subanswers' => array(
|
||||||
|
0 => 'Forum',
|
||||||
|
1 => 'Choice',
|
||||||
|
2 => 'Database',
|
||||||
|
3 => 'Wiki',
|
||||||
|
4 => 'Chat',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Repeated test for better failure messages.
|
||||||
|
$this->assertEqual($expectedq->subquestions, $q->subquestions);
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_match() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Moodle activities',
|
||||||
|
'questiontext' => 'Match the <b>activity</b> to the description.',
|
||||||
|
'questiontextformat' => FORMAT_HTML,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_HTML,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'match',
|
||||||
|
'options' => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'question' => 666,
|
||||||
|
'shuffleanswers' => 1,
|
||||||
|
'subquestions' => array(
|
||||||
|
42 => (object) array(
|
||||||
|
'id' => 1234,
|
||||||
|
'code' => 12341234,
|
||||||
|
'question' => 666,
|
||||||
|
'questiontext' => 'An activity supporting asynchronous discussions.',
|
||||||
|
'questiontextformat' => FORMAT_HTML,
|
||||||
|
'answertext' => 'Forum',
|
||||||
|
),
|
||||||
|
43 => (object) array(
|
||||||
|
'id' => 1234,
|
||||||
|
'code' => 12341234,
|
||||||
|
'question' => 666,
|
||||||
|
'questiontext' => 'A teacher asks a question and specifies a choice of multiple responses.',
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'answertext' => 'Choice',
|
||||||
|
),
|
||||||
|
44 => (object) array(
|
||||||
|
'id' => 1234,
|
||||||
|
'code' => 12341234,
|
||||||
|
'question' => 666,
|
||||||
|
'questiontext' => 'A bank of record entries which participants can add to.',
|
||||||
|
'questiontextformat' => FORMAT_PLAIN,
|
||||||
|
'answertext' => 'Database',
|
||||||
|
),
|
||||||
|
45 => (object) array(
|
||||||
|
'id' => 1234,
|
||||||
|
'code' => 12341234,
|
||||||
|
'question' => 666,
|
||||||
|
'questiontext' => 'A collection of web pages that anyone can add to or edit.',
|
||||||
|
'questiontextformat' => FORMAT_MARKDOWN,
|
||||||
|
'answertext' => 'Wiki',
|
||||||
|
),
|
||||||
|
46 => (object) array(
|
||||||
|
'id' => 1234,
|
||||||
|
'code' => 12341234,
|
||||||
|
'question' => 666,
|
||||||
|
'questiontext' => '',
|
||||||
|
'questiontextformat' => FORMAT_MARKDOWN,
|
||||||
|
'answertext' => 'Chat',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Moodle activities
|
||||||
|
::Moodle activities::[html]Match the <b>activity</b> to the description.{
|
||||||
|
\t=An activity supporting asynchronous discussions. -> Forum
|
||||||
|
\t=[moodle]A teacher asks a question and specifies a choice of multiple responses. -> Choice
|
||||||
|
\t=[plain]A bank of record entries which participants can add to. -> Database
|
||||||
|
\t=[markdown]A collection of web pages that anyone can add to or edit. -> Wiki
|
||||||
|
\t= -> Chat
|
||||||
|
}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_multichoice() {
|
||||||
|
$gift = "
|
||||||
|
// multiple choice with specified feedback for right and wrong answers
|
||||||
|
::Q2:: What's between orange and green in the spectrum?
|
||||||
|
{
|
||||||
|
=yellow # right; good!
|
||||||
|
~red # [html]wrong, it's yellow
|
||||||
|
~[plain]blue # wrong, it's yellow
|
||||||
|
}";
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Q2',
|
||||||
|
'questiontext' => "What's between orange and green in the spectrum?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'qtype' => 'multichoice',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'single' => 1,
|
||||||
|
'shuffleanswers' => '1',
|
||||||
|
'answernumbering' => 'abc',
|
||||||
|
'correctfeedback' => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
'partiallycorrectfeedback' => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
'incorrectfeedback' => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
'answer' => array(
|
||||||
|
0 => array(
|
||||||
|
'text' => 'yellow',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'text' => 'red',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'text' => 'blue',
|
||||||
|
'format' => FORMAT_PLAIN,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'fraction' => array(1, 0, 0),
|
||||||
|
'feedback' => array(
|
||||||
|
0 => array(
|
||||||
|
'text' => 'right; good!',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'text' => "wrong, it's yellow",
|
||||||
|
'format' => FORMAT_HTML,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'text' => "wrong, it's yellow",
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Repeated test for better failure messages.
|
||||||
|
$this->assertEqual($expectedq->answer, $q->answer);
|
||||||
|
$this->assertEqual($expectedq->feedback, $q->feedback);
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_multichoice() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Q8',
|
||||||
|
'questiontext' => "What's between orange and green in the spectrum?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'multichoice',
|
||||||
|
'options' => (object) array(
|
||||||
|
'single' => 1,
|
||||||
|
'shuffleanswers' => '1',
|
||||||
|
'answernumbering' => 'abc',
|
||||||
|
'correctfeedback' => '',
|
||||||
|
'correctfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'partiallycorrectfeedback' => '',
|
||||||
|
'partiallycorrectfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'incorrectfeedback' => '',
|
||||||
|
'incorrectfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'answers' => array(
|
||||||
|
123 => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'answer' => 'yellow',
|
||||||
|
'answerformat' => FORMAT_MOODLE,
|
||||||
|
'fraction' => 1,
|
||||||
|
'feedback' => 'right; good!',
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
124 => (object) array(
|
||||||
|
'id' => 124,
|
||||||
|
'answer' => 'red',
|
||||||
|
'answerformat' => FORMAT_MOODLE,
|
||||||
|
'fraction' => 0,
|
||||||
|
'feedback' => "wrong, it's yellow",
|
||||||
|
'feedbackformat' => FORMAT_HTML,
|
||||||
|
),
|
||||||
|
125 => (object) array(
|
||||||
|
'id' => 125,
|
||||||
|
'answer' => 'blue',
|
||||||
|
'answerformat' => FORMAT_PLAIN,
|
||||||
|
'fraction' => 0,
|
||||||
|
'feedback' => "wrong, it's yellow",
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Q8
|
||||||
|
::Q8::What's between orange and green in the spectrum?{
|
||||||
|
\t=yellow#right; good!
|
||||||
|
\t~red#[html]wrong, it's yellow
|
||||||
|
\t~[plain]blue#wrong, it's yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_numerical() {
|
||||||
|
$gift = "
|
||||||
|
// math range question
|
||||||
|
::Q5:: What is a number from 1 to 5? {#3:2~#Completely wrong}";
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Q5',
|
||||||
|
'questiontext' => "What is a number from 1 to 5?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'qtype' => 'numerical',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'answer' => array(
|
||||||
|
'3',
|
||||||
|
'*',
|
||||||
|
),
|
||||||
|
'fraction' => array(1, 0),
|
||||||
|
'feedback' => array(
|
||||||
|
0 => array(
|
||||||
|
'text' => '',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'text' => "Completely wrong",
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'tolerance' => array(2, 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Repeated test for better failure messages.
|
||||||
|
$this->assertEqual($expectedq->answer, $q->answer);
|
||||||
|
$this->assertEqual($expectedq->fraction, $q->fraction);
|
||||||
|
$this->assertEqual($expectedq->feedback, $q->feedback);
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_numerical() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Q5',
|
||||||
|
'questiontext' => "What is a number from 1 to 5?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'numerical',
|
||||||
|
'options' => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'question' => 666,
|
||||||
|
'instructions' => '',
|
||||||
|
'instructionsformat' => FORMAT_MOODLE,
|
||||||
|
'showunits' => 0,
|
||||||
|
'unitsleft' => 0,
|
||||||
|
'showunits' => 2,
|
||||||
|
'unitgradingtype' => 0,
|
||||||
|
'unitpenalty' => 0,
|
||||||
|
'answers' => array(
|
||||||
|
1 => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'answer' => '3',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 1,
|
||||||
|
'tolerance' => 2,
|
||||||
|
'feedback' => '',
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
2 => (object) array(
|
||||||
|
'id' => 124,
|
||||||
|
'answer' => '*',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 0,
|
||||||
|
'tolerance' => 0,
|
||||||
|
'feedback' => "Completely wrong",
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Q5
|
||||||
|
::Q5::What is a number from 1 to 5?{#
|
||||||
|
\t=%100%3:2#
|
||||||
|
\t~#Completely wrong
|
||||||
|
}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_shortanswer() {
|
||||||
|
$gift = "
|
||||||
|
// question: 666 name: Shortanswer
|
||||||
|
::Shortanswer::Which is the best animal?{
|
||||||
|
=Frog#Good!
|
||||||
|
=%50%Cat#What is it with Moodlers and cats?
|
||||||
|
=%0%*#Completely wrong
|
||||||
|
}";
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Shortanswer',
|
||||||
|
'questiontext' => "Which is the best animal?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'qtype' => 'shortanswer',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 0.1,
|
||||||
|
'length' => 1,
|
||||||
|
'answer' => array(
|
||||||
|
'Frog',
|
||||||
|
'Cat',
|
||||||
|
'*',
|
||||||
|
),
|
||||||
|
'fraction' => array(1, 0.5, 0),
|
||||||
|
'feedback' => array(
|
||||||
|
0 => array(
|
||||||
|
'text' => 'Good!',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
1 => array(
|
||||||
|
'text' => "What is it with Moodlers and cats?",
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
2 => array(
|
||||||
|
'text' => "Completely wrong",
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Repeated test for better failure messages.
|
||||||
|
$this->assertEqual($expectedq->answer, $q->answer);
|
||||||
|
$this->assertEqual($expectedq->fraction, $q->fraction);
|
||||||
|
$this->assertEqual($expectedq->feedback, $q->feedback);
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_shortanswer() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Shortanswer',
|
||||||
|
'questiontext' => "Which is the best animal?",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'shortanswer',
|
||||||
|
'options' => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'question' => 666,
|
||||||
|
'usecase' => 1,
|
||||||
|
'answers' => array(
|
||||||
|
1 => (object) array(
|
||||||
|
'id' => 1,
|
||||||
|
'answer' => 'Frog',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 1,
|
||||||
|
'feedback' => 'Good!',
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
2 => (object) array(
|
||||||
|
'id' => 2,
|
||||||
|
'answer' => 'Cat',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 0.5,
|
||||||
|
'feedback' => "What is it with Moodlers and cats?",
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
3 => (object) array(
|
||||||
|
'id' => 3,
|
||||||
|
'answer' => '*',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 0,
|
||||||
|
'feedback' => "Completely wrong",
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Shortanswer
|
||||||
|
::Shortanswer::Which is the best animal?{
|
||||||
|
\t=%100%Frog#Good!
|
||||||
|
\t=%50%Cat#What is it with Moodlers and cats?
|
||||||
|
\t=%0%*#Completely wrong
|
||||||
|
}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_import_truefalse() {
|
||||||
|
$gift = "
|
||||||
|
// true/false
|
||||||
|
::Q1:: 42 is the Absolute Answer to everything.{
|
||||||
|
FALSE#42 is the Ultimate Answer.#You gave the right answer.}";
|
||||||
|
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||||
|
|
||||||
|
$importer = new qformat_gift();
|
||||||
|
$q = $importer->readquestion($lines);
|
||||||
|
|
||||||
|
$expectedq = (object) array(
|
||||||
|
'name' => 'Q1',
|
||||||
|
'questiontext' => "42 is the Absolute Answer to everything.",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'qtype' => 'truefalse',
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 1,
|
||||||
|
'length' => 1,
|
||||||
|
'correctanswer' => 0,
|
||||||
|
'feedbacktrue' => array(
|
||||||
|
'text' => '42 is the Ultimate Answer.',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
'feedbackfalse' => array(
|
||||||
|
'text' => 'You gave the right answer.',
|
||||||
|
'format' => FORMAT_MOODLE,
|
||||||
|
'files' => array(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_export_truefalse() {
|
||||||
|
$qdata = (object) array(
|
||||||
|
'id' => 666 ,
|
||||||
|
'name' => 'Q1',
|
||||||
|
'questiontext' => "42 is the Absolute Answer to everything.",
|
||||||
|
'questiontextformat' => FORMAT_MOODLE,
|
||||||
|
'generalfeedback' => '',
|
||||||
|
'generalfeedbackformat' => FORMAT_MOODLE,
|
||||||
|
'defaultgrade' => 1,
|
||||||
|
'penalty' => 1,
|
||||||
|
'length' => 1,
|
||||||
|
'qtype' => 'truefalse',
|
||||||
|
'options' => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'question' => 666,
|
||||||
|
'trueanswer' => 1,
|
||||||
|
'falseanswer' => 2,
|
||||||
|
'answers' => array(
|
||||||
|
1 => (object) array(
|
||||||
|
'id' => 123,
|
||||||
|
'answer' => 'True',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 1,
|
||||||
|
'feedback' => 'You gave the right answer.',
|
||||||
|
'feedbackformat' => FORMAT_MOODLE,
|
||||||
|
),
|
||||||
|
2 => (object) array(
|
||||||
|
'id' => 124,
|
||||||
|
'answer' => 'False',
|
||||||
|
'answerformat' => 0,
|
||||||
|
'fraction' => 0,
|
||||||
|
'feedback' => "42 is the Ultimate Answer.",
|
||||||
|
'feedbackformat' => FORMAT_HTML,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$exporter = new qformat_gift();
|
||||||
|
$gift = $exporter->writequestion($qdata);
|
||||||
|
|
||||||
|
$expectedgift = "// question: 666 name: Q1
|
||||||
|
::Q1::42 is the Absolute Answer to everything.{TRUE#[html]42 is the Ultimate Answer.#You gave the right answer.}
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
$this->assert_same_gift($expectedgift, $gift);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue