mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-20636 And fix XML import unit tests too.
This commit is contained in:
parent
5f7cfba7fa
commit
fe0412432f
@ -422,8 +422,8 @@ class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_tes
|
||||
$this->check_current_mark(3);
|
||||
|
||||
// Now change the quiestion so that answer is only partially right, and regrade.
|
||||
$q->answers[0]->fraction = 0.6666667;
|
||||
$q->answers[1]->fraction = 1;
|
||||
$q->answers[13]->fraction = 0.6666667;
|
||||
$q->answers[14]->fraction = 1;
|
||||
|
||||
$this->quba->regrade_all_questions(false);
|
||||
|
||||
@ -455,8 +455,8 @@ class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_tes
|
||||
$this->check_current_mark(3);
|
||||
|
||||
// Now change the quiestion so that answer is only partially right, and regrade.
|
||||
$q->answers[0]->fraction = 0.6666667;
|
||||
$q->answers[1]->fraction = 1;
|
||||
$q->answers[13]->fraction = 0.6666667;
|
||||
$q->answers[14]->fraction = 1;
|
||||
|
||||
$this->quba->regrade_all_questions(true);
|
||||
|
||||
|
@ -237,11 +237,11 @@ class test_question_maker {
|
||||
$num->questiontext = 'What is pi to two d.p.?';
|
||||
$num->generalfeedback = 'Generalfeedback: 3.14 is the right answer.';
|
||||
$num->answers = array(
|
||||
new qtype_numerical_answer('3.14', 1.0, 'Very good.', 0),
|
||||
new qtype_numerical_answer('3.142', 0.0, 'Too accurate.', 0.005),
|
||||
new qtype_numerical_answer('3.1', 0.0, 'Not accurate enough.', 0.05),
|
||||
new qtype_numerical_answer('3', 0.0, 'Not accurate enough.', 0.5),
|
||||
new qtype_numerical_answer('*', 0.0, 'Completely wrong.', 0),
|
||||
13 => new qtype_numerical_answer(13, '3.14', 1.0, 'Very good.', FORMAT_HTML, 0),
|
||||
14 => new qtype_numerical_answer(14, '3.142', 0.0, 'Too accurate.', FORMAT_HTML, 0.005),
|
||||
15 => new qtype_numerical_answer(15, '3.1', 0.0, 'Not accurate enough.', FORMAT_HTML, 0.05),
|
||||
16 => new qtype_numerical_answer(16, '3', 0.0, 'Not accurate enough.', FORMAT_HTML, 0.5),
|
||||
17 => new qtype_numerical_answer(17, '*', 0.0, 'Completely wrong.', FORMAT_HTML, 0),
|
||||
);
|
||||
$num->qtype = question_bank::get_qtype('numerical');
|
||||
$num->ap = new qtype_numerical_answer_processor(array());
|
||||
|
@ -282,12 +282,25 @@ class qformat_xml extends qformat_default {
|
||||
* @param boolean $withshownumpartscorrect include the shownumcorrect field.
|
||||
*/
|
||||
public function import_combined_feedback($qo, $questionxml, $withshownumpartscorrect = false) {
|
||||
$qo->correctfeedback = $this->getpath($questionxml,
|
||||
array('#', 'correctfeedback', 0, '#', 'text', 0, '#'), '', true);
|
||||
$qo->partiallycorrectfeedback = $this->getpath($questionxml,
|
||||
array('#', 'partiallycorrectfeedback', 0, '#', 'text', 0, '#'), '', true);
|
||||
$qo->incorrectfeedback = $this->getpath($questionxml,
|
||||
array('#', 'incorrectfeedback', 0, '#', 'text', 0, '#'), '', true);
|
||||
foreach (array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback') as $field) {
|
||||
$text = array();
|
||||
$text['text'] = $this->getpath($questionxml,
|
||||
array('#', $field, 0, '#', 'text', 0, '#'), '', true);
|
||||
$text['format'] = $this->trans_format($this->getpath($questionxml,
|
||||
array('#', $field, 0, '@', 'format'), 'moodle_auto_format'));
|
||||
|
||||
$text['files'] = array();
|
||||
$files = $this->getpath($questionxml, array('#', $field, 0, '#','file'), array(), false);
|
||||
foreach ($files as $file) {
|
||||
$data = new stdClass();
|
||||
$data->content = $file['#'];
|
||||
$data->encoding = $file['@']['encoding'];
|
||||
$data->name = $file['@']['name'];
|
||||
$text['files'][] = $data;
|
||||
}
|
||||
|
||||
$qo->$field = $text;
|
||||
}
|
||||
|
||||
if ($withshownumpartscorrect) {
|
||||
$qo->shownumcorrect = array_key_exists('shownumcorrect', $questionxml['#']);
|
||||
@ -341,7 +354,8 @@ class qformat_xml extends qformat_default {
|
||||
if (!isset($questionxml['#']['hint'])) {
|
||||
return;
|
||||
}
|
||||
// TODO files in hints.
|
||||
|
||||
// TODO Handle files in hints.
|
||||
foreach ($questionxml['#']['hint'] as $hintxml) {
|
||||
$hint = $this->import_hint($hintxml);
|
||||
$qo->hint[] = $hint->hint;
|
||||
@ -374,52 +388,6 @@ class qformat_xml extends qformat_default {
|
||||
$qo->answernumbering = $this->getpath($question, array('#', 'answernumbering', 0, '#'), 'abc');
|
||||
$qo->shuffleanswers = $this->trans_single($shuffleanswers);
|
||||
|
||||
// TODO move into import_combined_feedback
|
||||
$qo->correctfeedback = array();
|
||||
$qo->correctfeedback['text'] = $this->getpath($question, array('#', 'correctfeedback', 0, '#', 'text', 0, '#'), '', true);
|
||||
$qo->correctfeedback['format'] = $this->trans_format(
|
||||
$this->getpath($question, array('#', 'correctfeedback', 0, '@', 'format'), 'moodle_auto_format'));
|
||||
$qo->correctfeedback['files'] = array();
|
||||
// restore files in correctfeedback
|
||||
$files = $this->getpath($question, array('#', 'correctfeedback', 0, '#','file'), array(), false);
|
||||
foreach ($files as $file) {
|
||||
$data = new stdclass;
|
||||
$data->content = $file['#'];
|
||||
$data->encoding = $file['@']['encoding'];
|
||||
$data->name = $file['@']['name'];
|
||||
$qo->correctfeedback['files'][] = $data;
|
||||
}
|
||||
|
||||
$qo->partiallycorrectfeedback = array();
|
||||
$qo->partiallycorrectfeedback['text'] = $this->getpath( $question, array('#','partiallycorrectfeedback',0,'#','text',0,'#'), '', true );
|
||||
$qo->partiallycorrectfeedback['format'] = $this->trans_format(
|
||||
$this->getpath($question, array('#', 'partiallycorrectfeedback', 0, '@', 'format'), 'moodle_auto_format'));
|
||||
$qo->partiallycorrectfeedback['files'] = array();
|
||||
// restore files in partiallycorrectfeedback
|
||||
$files = $this->getpath($question, array('#', 'partiallycorrectfeedback', 0, '#','file'), array(), false);
|
||||
foreach ($files as $file) {
|
||||
$data = new stdclass;
|
||||
$data->content = $file['#'];
|
||||
$data->encoding = $file['@']['encoding'];
|
||||
$data->name = $file['@']['name'];
|
||||
$qo->partiallycorrectfeedback['files'][] = $data;
|
||||
}
|
||||
|
||||
$qo->incorrectfeedback = array();
|
||||
$qo->incorrectfeedback['text'] = $this->getpath( $question, array('#','incorrectfeedback',0,'#','text',0,'#'), '', true );
|
||||
$qo->incorrectfeedback['format'] = $this->trans_format(
|
||||
$this->getpath($question, array('#', 'incorrectfeedback', 0, '@', 'format'), 'moodle_auto_format'));
|
||||
$qo->incorrectfeedback['files'] = array();
|
||||
// restore files in incorrectfeedback
|
||||
$files = $this->getpath($question, array('#', 'incorrectfeedback', 0, '#','file'), array(), false);
|
||||
foreach ($files as $file) {
|
||||
$data = new stdclass;
|
||||
$data->content = $file['#'];
|
||||
$data->encoding = $file['@']['encoding'];
|
||||
$data->name = $file['@']['name'];
|
||||
$qo->incorrectfeedback['files'][] = $data;
|
||||
}
|
||||
|
||||
// There was a time on the 1.8 branch when it could output an empty answernumbering tag, so fix up any found.
|
||||
if (empty($qo->answernumbering)) {
|
||||
$qo->answernumbering = 'abc';
|
||||
@ -530,16 +498,14 @@ class qformat_xml extends qformat_default {
|
||||
$qo->feedbacktrue = array();
|
||||
$qo->feedbacktrue['text'] = $feedback;
|
||||
$qo->feedbacktrue['format'] = $this->trans_format($feedbackformat);
|
||||
$qo->feedbacktrue['itemid'] = null;
|
||||
$qo->feedbacktruefiles = $files;
|
||||
$qo->feedbacktrue['files'] = $files;
|
||||
} else {
|
||||
$qo->answer = ($answer['@']['fraction'] != 100);
|
||||
$qo->correctanswer = $qo->answer;
|
||||
$qo->feedbackfalse = array();
|
||||
$qo->feedbackfalse['text'] = $feedback;
|
||||
$qo->feedbackfalse['format'] = $this->trans_format($feedbackformat);
|
||||
$qo->feedbackfalse['itemid'] = null;
|
||||
$qo->feedbackfalsefiles = $files;
|
||||
$qo->feedbackfalse['files'] = $files;
|
||||
}
|
||||
$first = false;
|
||||
}
|
||||
@ -576,7 +542,7 @@ class qformat_xml extends qformat_default {
|
||||
$acount = 0;
|
||||
foreach ($answers as $answer) {
|
||||
$ans = $this->import_answer($answer);
|
||||
$qo->answer[$acount] = $ans->answer;
|
||||
$qo->answer[$acount] = $ans->answer['text'];
|
||||
$qo->fraction[$acount] = $ans->fraction;
|
||||
$qo->feedback[$acount] = $ans->feedback;
|
||||
++$acount;
|
||||
@ -688,30 +654,27 @@ class qformat_xml extends qformat_default {
|
||||
$qo->shuffleanswers = $this->trans_single($this->getpath($question,
|
||||
array('#', 'shuffleanswers', 0, '#'), 1));
|
||||
|
||||
// get subquestions
|
||||
$subquestions = $question['#']['subquestion'];
|
||||
// run through subquestions
|
||||
$qo->subquestions = array();
|
||||
$qo->subanswers = array();
|
||||
foreach ($question['#']['subquestion'] as $subqxml) {
|
||||
$subquestion = array();
|
||||
$subquestion['text'] = $this->getpath($subqxml, array('#', 'text', 0, '#'), '', true);
|
||||
$subquestion['format'] = $this->trans_format(
|
||||
$this->getpath($subqxml, array('@', 'format'), 'moodle_auto_format'));
|
||||
$subquestion['files'] = array();
|
||||
|
||||
// run through subquestions
|
||||
foreach ($subquestions as $subquestion) {
|
||||
$question = array();
|
||||
$question['text'] = $this->getpath($subquestion, array('#', 'text', 0, '#'), '', true);
|
||||
$question['format'] = $this->trans_format(
|
||||
$this->getpath($subquestion, array('@', 'format'), 'moodle_auto_format'));
|
||||
$question['files'] = array();
|
||||
|
||||
$files = $this->getpath($subquestion, array('#', 'file'), array());
|
||||
$files = $this->getpath($subqxml, array('#', 'file'), array());
|
||||
foreach ($files as $file) {
|
||||
$data = new stdclass();
|
||||
$data->content = $file['#'];
|
||||
$data->encoding = $file['@']['encoding'];
|
||||
$data->name = $file['@']['name'];
|
||||
$question['files'][] = $data;
|
||||
$subquestion['files'][] = $data;
|
||||
}
|
||||
$qo->subquestions[] = $question;
|
||||
$answers = $this->getpath($subquestion, array('#', 'answer'), array());
|
||||
$qo->subanswers[] = $this->getpath($subquestion, array('#','answer',0,'#','text',0,'#'), '', true);
|
||||
$qo->subquestions[] = $subquestion;
|
||||
$answers = $this->getpath($subqxml, array('#', 'answer'), array());
|
||||
$qo->subanswers[] = $this->getpath($subqxml, array('#','answer',0,'#','text',0,'#'), '', true);
|
||||
}
|
||||
|
||||
$this->import_combined_feedback($qo, $question, true);
|
||||
@ -1122,16 +1085,16 @@ class qformat_xml extends qformat_default {
|
||||
|
||||
$fs = get_file_storage();
|
||||
$contextid = $question->contextid;
|
||||
// files used by questiontext
|
||||
$files = $fs->get_area_files($contextid, 'question', 'questiontext', $question->id);
|
||||
$question->questiontextfiles = $files;
|
||||
// files used by generalfeedback
|
||||
$files = $fs->get_area_files($contextid, 'question', 'generalfeedback', $question->id);
|
||||
$question->generalfeedbackfiles = $files;
|
||||
// Get files used by the questiontext.
|
||||
$question->questiontextfiles = $fs->get_area_files(
|
||||
$contextid, 'question', 'questiontext', $question->id);
|
||||
// Get files used by the generalfeedback.
|
||||
$question->generalfeedbackfiles = $fs->get_area_files(
|
||||
$contextid, 'question', 'generalfeedback', $question->id);
|
||||
if (!empty($question->options->answers)) {
|
||||
foreach ($question->options->answers as $answer) {
|
||||
$files = $fs->get_area_files($contextid, 'question', 'answerfeedback', $answer->id);
|
||||
$answer->feedbackfiles = $files;
|
||||
$answer->feedbackfiles = $fs->get_area_files(
|
||||
$contextid, 'question', 'answerfeedback', $answer->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ END;
|
||||
$this->assert_same_xml($expectedxml, $xml);
|
||||
}
|
||||
|
||||
public function test_import_match() {
|
||||
public function test_import_match_19() {
|
||||
$xml = ' <question type="matching">
|
||||
<name>
|
||||
<text>Matching question</text>
|
||||
@ -398,16 +398,21 @@ END;
|
||||
$expectedq->name = 'Matching question';
|
||||
$expectedq->questiontext = 'Match the upper and lower case letters.';
|
||||
$expectedq->questiontextformat = FORMAT_HTML;
|
||||
$expectedq->correctfeedback = 'Well done.';
|
||||
$expectedq->partiallycorrectfeedback = 'Not entirely.';
|
||||
$expectedq->correctfeedback = array('text' => 'Well done.', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->partiallycorrectfeedback = array('text' => 'Not entirely.', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->shownumcorrect = false;
|
||||
$expectedq->incorrectfeedback = 'Completely wrong!';
|
||||
$expectedq->incorrectfeedback = array('text' => 'Completely wrong!', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
|
||||
$expectedq->generalfeedbackformat = FORMAT_MOODLE;
|
||||
$expectedq->defaultmark = 1;
|
||||
$expectedq->length = 1;
|
||||
$expectedq->penalty = 0.3333333;
|
||||
$expectedq->shuffleanswers = 0;
|
||||
$expectedq->subquestions = array('A', 'B', 'C', '');
|
||||
$expectedq->subquestions = array(
|
||||
array('text' => 'A', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => 'B', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => 'C', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '', 'format' => FORMAT_MOODLE, 'files' => array()));
|
||||
$expectedq->subanswers = array('a', 'b', 'c', 'd');
|
||||
$expectedq->hint = array('Hint 1', '');
|
||||
$expectedq->hintshownumcorrect = array(true, true);
|
||||
@ -539,7 +544,7 @@ END;
|
||||
$this->assert_same_xml($expectedxml, $xml);
|
||||
}
|
||||
|
||||
public function test_import_multichoice() {
|
||||
public function test_import_multichoice_19() {
|
||||
$xml = ' <question type="multichoice">
|
||||
<name>
|
||||
<text>Multiple choice question</text>
|
||||
@ -607,10 +612,11 @@ END;
|
||||
$expectedq->name = 'Multiple choice question';
|
||||
$expectedq->questiontext = 'Which are the even numbers?';
|
||||
$expectedq->questiontextformat = FORMAT_HTML;
|
||||
$expectedq->correctfeedback = '<p>Your answer is correct.</p>';
|
||||
$expectedq->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
|
||||
$expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->shownumcorrect = false;
|
||||
$expectedq->partiallycorrectfeedback = array('text' => '<p>Your answer is partially correct.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->shownumcorrect = true;
|
||||
$expectedq->incorrectfeedback = '<p>Your answer is incorrect.</p>';
|
||||
$expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->generalfeedback = 'The even numbers are 2 and 4.';
|
||||
$expectedq->defaultmark = 2;
|
||||
$expectedq->length = 1;
|
||||
@ -618,9 +624,17 @@ END;
|
||||
$expectedq->shuffleanswers = 0;
|
||||
$expectedq->single = false;
|
||||
|
||||
$expectedq->answer = array('1', '2', '3', '4');
|
||||
$expectedq->answer = array(
|
||||
array('text' => '1', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '2', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '3', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '4', 'format' => FORMAT_MOODLE, 'files' => array()));
|
||||
$expectedq->fraction = array(0, 1, 0, 1);
|
||||
$expectedq->feedback = array('', '', '', '');
|
||||
$expectedq->feedback = array(
|
||||
array('text' => '', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => '', 'format' => FORMAT_MOODLE, 'files' => array()));
|
||||
|
||||
$expectedq->hint = array('Hint 1.', 'Hint 2.');
|
||||
$expectedq->hintshownumcorrect = array(false, false);
|
||||
@ -734,7 +748,7 @@ END;
|
||||
$this->assert_same_xml($expectedxml, $xml);
|
||||
}
|
||||
|
||||
public function test_import_numerical() {
|
||||
public function test_import_numerical_19() {
|
||||
$xml = ' <question type="numerical">
|
||||
<name>
|
||||
<text>Numerical question</text>
|
||||
@ -781,13 +795,17 @@ END;
|
||||
$expectedq->questiontext = 'What is the answer?';
|
||||
$expectedq->questiontextformat = FORMAT_HTML;
|
||||
$expectedq->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
|
||||
$expectedq->generalfeedbackformat = FORMAT_MOODLE;
|
||||
$expectedq->defaultmark = 1;
|
||||
$expectedq->length = 1;
|
||||
$expectedq->penalty = 0.1;
|
||||
|
||||
$expectedq->answer = array('42', '13', '*');
|
||||
$expectedq->fraction = array(1, 0, 0);
|
||||
$expectedq->feedback = array('Well done!', 'What were you thinking?!', 'Completely wrong.');
|
||||
$expectedq->feedback = array(
|
||||
array('text' => 'Well done!', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => 'What were you thinking?!', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => 'Completely wrong.', 'format' => FORMAT_MOODLE, 'files' => array()));
|
||||
$expectedq->tolerance = array(0.001, 1, 0);
|
||||
|
||||
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||
@ -798,20 +816,22 @@ END;
|
||||
|
||||
$qdata = new stdClass;
|
||||
$qdata->id = 123;
|
||||
$qdata->contextid = 0;
|
||||
$qdata->qtype = 'numerical';
|
||||
$qdata->name = 'Numerical question';
|
||||
$qdata->questiontext = 'What is the answer?';
|
||||
$qdata->questiontextformat = FORMAT_HTML;
|
||||
$qdata->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
|
||||
$qdata->generalfeedbackformat = FORMAT_HTML;
|
||||
$qdata->defaultmark = 1;
|
||||
$qdata->length = 1;
|
||||
$qdata->penalty = 0.1;
|
||||
$qdata->hidden = 0;
|
||||
|
||||
$qdata->options->answers = array(
|
||||
new qtype_numerical_answer('42', 1, 'Well done!', 0.001),
|
||||
new qtype_numerical_answer('13', 0, 'What were you thinking?!', 1),
|
||||
new qtype_numerical_answer('*', 0, 'Completely wrong.', ''),
|
||||
13 => new qtype_numerical_answer(13, '42', 1, 'Well done!', FORMAT_HTML, 0.001),
|
||||
14 => new qtype_numerical_answer(14, '13', 0, 'What were you thinking?!', FORMAT_HTML, 1),
|
||||
15 => new qtype_numerical_answer(15, '*', 0, 'Completely wrong.', FORMAT_HTML, ''),
|
||||
);
|
||||
|
||||
$qdata->options->units = array();
|
||||
@ -827,7 +847,7 @@ END;
|
||||
<questiontext format="html">
|
||||
<text>What is the answer?</text>
|
||||
</questiontext>
|
||||
<generalfeedback>
|
||||
<generalfeedback format="html">
|
||||
<text>General feedback: Think Hitch-hikers guide to the Galaxy.</text>
|
||||
</generalfeedback>
|
||||
<defaultgrade>1</defaultgrade>
|
||||
@ -835,21 +855,21 @@ END;
|
||||
<hidden>0</hidden>
|
||||
<answer fraction="100">
|
||||
<text>42</text>
|
||||
<feedback>
|
||||
<feedback format="html">
|
||||
<text>Well done!</text>
|
||||
</feedback>
|
||||
<tolerance>0.001</tolerance>
|
||||
</answer>
|
||||
<answer fraction="0">
|
||||
<text>13</text>
|
||||
<feedback>
|
||||
<feedback format="html">
|
||||
<text>What were you thinking?!</text>
|
||||
</feedback>
|
||||
<tolerance>1</tolerance>
|
||||
</answer>
|
||||
<answer fraction="0">
|
||||
<text>*</text>
|
||||
<feedback>
|
||||
<feedback format="html">
|
||||
<text>Completely wrong.</text>
|
||||
</feedback>
|
||||
<tolerance>0</tolerance>
|
||||
@ -860,7 +880,7 @@ END;
|
||||
$this->assert_same_xml($expectedxml, $xml);
|
||||
}
|
||||
|
||||
public function test_import_shortanswer() {
|
||||
public function test_import_shortanswer_19() {
|
||||
$xml = ' <question type="shortanswer">
|
||||
<name>
|
||||
<text>Short answer question</text>
|
||||
@ -912,7 +932,9 @@ END;
|
||||
|
||||
$expectedq->answer = array('Beta', '*');
|
||||
$expectedq->fraction = array(1, 0);
|
||||
$expectedq->feedback = array('Well done!', 'Doh!');
|
||||
$expectedq->feedback = array(
|
||||
array('text' => 'Well done!', 'format' => FORMAT_MOODLE, 'files' => array()),
|
||||
array('text' => 'Doh!', 'format' => FORMAT_MOODLE, 'files' => array()));
|
||||
|
||||
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||
}
|
||||
@ -955,7 +977,7 @@ END;
|
||||
<questiontext format="html">
|
||||
<text>Fill in the gap in this sequence: Alpha, ________, Gamma.</text>
|
||||
</questiontext>
|
||||
<generalfeedback>
|
||||
<generalfeedback format="html">
|
||||
<text>The answer is Beta.</text>
|
||||
</generalfeedback>
|
||||
<defaultgrade>1</defaultgrade>
|
||||
@ -964,20 +986,20 @@ END;
|
||||
<usecase>0</usecase>
|
||||
<answer fraction="100">
|
||||
<text>Beta</text>
|
||||
<feedback>
|
||||
<feedback format="html">
|
||||
<text>Well done!</text>
|
||||
</feedback>
|
||||
</answer>
|
||||
<answer fraction="0">
|
||||
<text>*</text>
|
||||
<feedback>
|
||||
<feedback format="html">
|
||||
<text>Doh!</text>
|
||||
</feedback>
|
||||
</answer>
|
||||
<hint>
|
||||
<hint format="html">
|
||||
<text>Hint 1</text>
|
||||
</hint>
|
||||
<hint>
|
||||
<hint format="html">
|
||||
<text>Hint 2</text>
|
||||
</hint>
|
||||
</question>
|
||||
@ -986,7 +1008,7 @@ END;
|
||||
$this->assert_same_xml($expectedxml, $xml);
|
||||
}
|
||||
|
||||
public function test_import_truefalse() {
|
||||
public function test_import_truefalse_19() {
|
||||
$xml = ' <question type="truefalse">
|
||||
<name>
|
||||
<text>True false question</text>
|
||||
@ -1028,8 +1050,8 @@ END;
|
||||
$expectedq->length = 1;
|
||||
$expectedq->penalty = 1;
|
||||
|
||||
$expectedq->feedbacktrue = 'Well done!';
|
||||
$expectedq->feedbackfalse = 'Doh!';
|
||||
$expectedq->feedbacktrue = array('text' => 'Well done!', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->feedbackfalse = array('text' => 'Doh!', 'format' => FORMAT_MOODLE, 'files' => array());
|
||||
$expectedq->correctanswer = true;
|
||||
|
||||
$this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
|
||||
|
@ -160,9 +160,13 @@ DONE mod/quiz/protect_js.php | 56 -
|
||||
mod/quiz/report/statistics/statistics_table.php | 335 +++
|
||||
mod/quiz/report/statistics/version.php | 26 +
|
||||
|
||||
pix/i/flagged.png | Bin 0 -> 193 bytes
|
||||
pix/i/ne_red_mark.png | Bin 0 -> 121 bytes
|
||||
pix/i/unflagged.png | Bin 0 -> 197 bytes
|
||||
theme/standard/styles_color.css | 72 +-
|
||||
theme/standard/styles_fonts.css | 20 +-
|
||||
theme/standard/styles_layout.css | 265 ++-
|
||||
|
||||
DONE pix/i/flagged.png | Bin 0 -> 193 bytes
|
||||
DONE pix/i/ne_red_mark.png | Bin 0 -> 121 bytes
|
||||
DONE pix/i/unflagged.png | Bin 0 -> 197 bytes
|
||||
|
||||
question/backuplib.php | 26 +-
|
||||
DONE question/comment.html | 25 -
|
||||
@ -246,10 +250,10 @@ DONE question/behaviour/informationitem/lang/en_utf8/qbehaviour_informationitem.
|
||||
DONE question/behaviour/informationitem/renderer.php | 42 +
|
||||
DONE question/behaviour/informationitem/simpletest/testwalkthrough.php | 78 +
|
||||
|
||||
DONE question/behaviour/interactive/behaviour.php | 232 ++
|
||||
question/behaviour/interactive/behaviour.php | 232 ++
|
||||
DONE question/behaviour/interactive/lang/en_utf8/qbehaviour_interactive.php | 6 +
|
||||
DONE question/behaviour/interactive/renderer.php | 62 +
|
||||
DONE question/behaviour/interactive/interactive/simpletest/testwalkthrough.php | 470 ++++
|
||||
question/behaviour/interactive/interactive/simpletest/testwalkthrough.php | 470 ++++
|
||||
|
||||
DONE question/behaviour/interactivecountback/behaviour.php | 91 +
|
||||
DONE question/behaviour/interactivecountback/en_utf8/qbehaviour_interactivecountback.php | 3 +
|
||||
@ -276,8 +280,8 @@ DONE question/format/blackboard/format.php | 2 +-
|
||||
DONE question/format/gift/format.php | 6 +-
|
||||
DONE question/format/hotpot/format.php | 10 +-
|
||||
DONE question/format/webct/format.php | 4 +-
|
||||
question/format/xml/format.php | 985 ++++---
|
||||
question/format/xml/simpletest/testxmlformat.php | 1064 ++++++++
|
||||
DONE question/format/xml/format.php | 985 ++++---
|
||||
DONE question/format/xml/simpletest/testxmlformat.php | 1064 ++++++++
|
||||
|
||||
question/type/calculated/db/upgrade.php | 2 -
|
||||
question/type/calculated/edit_calculated_form.php | 5 +-
|
||||
@ -441,8 +445,3 @@ DONE question/type/truefalse/renderer.php | 142 +
|
||||
DONE question/type/truefalse/simpletest/testquestion.php | 99 +
|
||||
DONE question/type/truefalse/simpletest/testquestiontype.php | 73 +
|
||||
DONE question/type/truefalse/version.php | 4 +-
|
||||
|
||||
theme/standard/styles_color.css | 72 +-
|
||||
theme/standard/styles_fonts.css | 20 +-
|
||||
theme/standard/styles_layout.css | 265 ++-
|
||||
|
||||
|
151
question/type/numerical/question.php
Normal file
151
question/type/numerical/question.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Numerical question definition class.
|
||||
*
|
||||
* @package qtype_numerical
|
||||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
|
||||
|
||||
|
||||
/**
|
||||
* Represents a numerical question.
|
||||
*
|
||||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_numerical_question extends question_graded_by_strategy
|
||||
implements question_response_answer_comparer {
|
||||
/** @var array of question_answer. */
|
||||
public $answers = array();
|
||||
/** @var qtype_numerical_answer_processor */
|
||||
public $ap;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(new question_first_matching_answer_grading_strategy($this));
|
||||
}
|
||||
|
||||
public function get_expected_data() {
|
||||
return array('answer' => PARAM_TRIM);
|
||||
}
|
||||
|
||||
public function init_first_step(question_attempt_step $step) {
|
||||
if ($step->has_qt_var('_separators')) {
|
||||
list($point, $separator) = explode('$', $step->get_qt_var('_separators'));
|
||||
$this->ap->set_characters($point, $separator);
|
||||
} else {
|
||||
$step->set_qt_var('_separators',
|
||||
$this->ap->get_point() . '$' . $this->ap->get_separator());
|
||||
}
|
||||
}
|
||||
|
||||
public function summarise_response(array $response) {
|
||||
if (isset($response['answer'])) {
|
||||
return $response['answer'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function is_complete_response(array $response) {
|
||||
return array_key_exists('answer', $response) &&
|
||||
($response['answer'] || $response['answer'] === '0' || $response['answer'] === 0);
|
||||
}
|
||||
|
||||
public function get_validation_error(array $response) {
|
||||
if ($this->is_gradable_response($response)) {
|
||||
return '';
|
||||
}
|
||||
return get_string('pleaseenterananswer', 'qtype_numerical');
|
||||
}
|
||||
|
||||
public function is_same_response(array $prevresponse, array $newresponse) {
|
||||
return question_utils::arrays_same_at_key_missing_is_blank(
|
||||
$prevresponse, $newresponse, 'answer');
|
||||
}
|
||||
|
||||
public function get_answers() {
|
||||
return $this->answers;
|
||||
}
|
||||
|
||||
public function compare_response_with_answer(array $response, question_answer $answer) {
|
||||
list($value, $unit) = $this->ap->apply_units($response['answer']);
|
||||
return $answer->within_tolerance($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of {@link question_answer} with the extra information required by
|
||||
* the numerical question type.
|
||||
*
|
||||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_numerical_answer extends question_answer {
|
||||
/** @var float allowable margin of error. */
|
||||
public $tolerance;
|
||||
/** @var integer|string see {@link get_tolerance_interval()} for the meaning of this value. */
|
||||
public $tolerancetype = 2;
|
||||
|
||||
public function __construct($id, $answer, $fraction, $feedback, $feedbackformat, $tolerance) {
|
||||
parent::__construct($id, $answer, $fraction, $feedback, $feedbackformat);
|
||||
$this->tolerance = abs($tolerance);
|
||||
}
|
||||
|
||||
public function get_tolerance_interval() {
|
||||
if ($this->answer === '*') {
|
||||
throw new Exception('Cannot work out tolerance interval for answer *.');
|
||||
}
|
||||
|
||||
// We need to add a tiny fraction depending on the set precision to make
|
||||
// the comparison work correctly, otherwise seemingly equal values can
|
||||
// yield false. See MDL-3225.
|
||||
$tolerance = (float) $this->tolerance + pow(10, -1 * ini_get('precision'));
|
||||
|
||||
switch ($this->tolerancetype) {
|
||||
case 1: case 'relative':
|
||||
$range = abs($this->answer) * $tolerance;
|
||||
return array($this->answer - $range, $this->answer + $range);
|
||||
|
||||
case 2: case 'nominal':
|
||||
$tolerance = $this->tolerance + pow(10, -1 * ini_get('precision')) *
|
||||
max(1, abs($this->answer));
|
||||
return array($this->answer - $tolerance, $this->answer + $tolerance);
|
||||
|
||||
case 3: case 'geometric':
|
||||
$quotient = 1 + abs($tolerance);
|
||||
return array($this->answer / $quotient, $this->answer * $quotient);
|
||||
|
||||
default:
|
||||
throw new Exception('Unknown tolerance type ' . $this->tolerancetype);
|
||||
}
|
||||
}
|
||||
|
||||
public function within_tolerance($value) {
|
||||
if ($this->answer === '*') {
|
||||
return true;
|
||||
}
|
||||
list($min, $max) = $this->get_tolerance_interval();
|
||||
return $min <= $value && $value <= $max;
|
||||
}
|
||||
}
|
@ -131,13 +131,13 @@ class qtype_shortanswer_question_test extends UnitTestCase {
|
||||
$sa->init_first_step(new question_attempt_step());
|
||||
|
||||
$this->assertEqual(array(
|
||||
new question_classified_response(0, 'frog', 1.0)),
|
||||
new question_classified_response(13, 'frog', 1.0)),
|
||||
$sa->classify_response(array('answer' => 'frog')));
|
||||
$this->assertEqual(array(
|
||||
new question_classified_response(1, 'toad', 0.8)),
|
||||
new question_classified_response(14, 'toad', 0.8)),
|
||||
$sa->classify_response(array('answer' => 'toad')));
|
||||
$this->assertEqual(array(
|
||||
new question_classified_response(2, 'cat', 0.0)),
|
||||
new question_classified_response(15, 'cat', 0.0)),
|
||||
$sa->classify_response(array('answer' => 'cat')));
|
||||
$this->assertEqual(array(
|
||||
question_classified_response::no_response()),
|
||||
|
@ -72,7 +72,7 @@ class question_first_matching_answer_grading_strategy_test extends UnitTestCase
|
||||
|
||||
public function test_matching_answer_returned2() {
|
||||
$answer = new question_answer(0, 'frog', 1, '', FORMAT_HTML);
|
||||
$answer2 = new question_answer(0, 'frog', 0.5, '');
|
||||
$answer2 = new question_answer(0, 'frog', 0.5, '', FORMAT_HTML);
|
||||
$question = new test_response_answer_comparer(array($answer, $answer2));
|
||||
$strategy = new question_first_matching_answer_grading_strategy($question);
|
||||
$this->assertIdentical($answer, $strategy->grade(array('answer' => 'frog')));
|
||||
|
Loading…
x
Reference in New Issue
Block a user