mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 12:40:01 +01:00
Merge branch 'MDL-28183' of git://github.com/jmvedrine/moodle
This commit is contained in:
commit
b5b418b2a7
@ -471,7 +471,7 @@ class qformat_xml extends qformat_default {
|
||||
$qo->penalty = 0.3333333;
|
||||
}
|
||||
|
||||
$this->import_hints($qo, $question, false, false, $this->get_format($qo->questiontextformat));
|
||||
$this->import_hints($qo, $question, true, false, $this->get_format($qo->questiontextformat));
|
||||
|
||||
return $qo;
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ class qtype_multianswer_edit_form extends question_edit_form {
|
||||
$mform->addElement('hidden', 'confirm', 0);
|
||||
}
|
||||
|
||||
$this->add_interactive_settings();
|
||||
$this->add_interactive_settings(true, true);
|
||||
}
|
||||
|
||||
|
||||
@ -419,7 +419,7 @@ class qtype_multianswer_edit_form extends question_edit_form {
|
||||
if ($default_values != "") {
|
||||
$question = (object)((array)$question + $default_values);
|
||||
}
|
||||
$question = $this->data_preprocessing_hints($question);
|
||||
$question = $this->data_preprocessing_hints($question, true, true);
|
||||
parent::set_data($question);
|
||||
}
|
||||
|
||||
|
@ -231,6 +231,38 @@ class qtype_multianswer_question extends question_graded_automatically {
|
||||
return array($fractionsum / $fractionmax, $overallstate);
|
||||
}
|
||||
|
||||
public function clear_wrong_from_response(array $response) {
|
||||
foreach ($this->subquestions as $i => $subq) {
|
||||
$substep = $this->get_substep(null, $i);
|
||||
$subresp = $substep->filter_array($response);
|
||||
list($subfraction, $newstate) = $subq->grade_response($subresp);
|
||||
if ($newstate != question_state::$gradedright) {
|
||||
foreach ($subresp as $ind => $resp) {
|
||||
if (($subq->layout == qtype_multichoice_base::LAYOUT_VERTICAL)
|
||||
|| ($subq->layout == qtype_multichoice_base::LAYOUT_HORIZONTAL)) {
|
||||
$response[$substep->add_prefix($ind)] = '-1';
|
||||
} else {
|
||||
$response[$substep->add_prefix($ind)] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function get_num_parts_right(array $response) {
|
||||
$numright = 0;
|
||||
foreach ($this->subquestions as $i => $subq) {
|
||||
$substep = $this->get_substep(null, $i);
|
||||
$subresp = $substep->filter_array($response);
|
||||
list($subfraction, $newstate) = $subq->grade_response($subresp);
|
||||
if ($newstate == question_state::$gradedright) {
|
||||
$numright += 1;
|
||||
}
|
||||
}
|
||||
return array($numright, count($this->subquestions));
|
||||
}
|
||||
|
||||
public function summarise_response(array $response) {
|
||||
$summary = array();
|
||||
foreach ($this->subquestions as $i => $subq) {
|
||||
|
@ -165,7 +165,7 @@ class qtype_multianswer extends question_type {
|
||||
}
|
||||
}
|
||||
|
||||
$this->save_hints($question);
|
||||
$this->save_hints($question, true);
|
||||
}
|
||||
|
||||
public function save_question($authorizedquestion, $form) {
|
||||
@ -183,6 +183,10 @@ class qtype_multianswer extends question_type {
|
||||
return parent::save_question($question, $form);
|
||||
}
|
||||
|
||||
protected function make_hint($hint) {
|
||||
return question_hint_with_parts::load_from_record($hint);
|
||||
}
|
||||
|
||||
public function delete_question($questionid, $contextid) {
|
||||
global $DB;
|
||||
$DB->delete_records('question_multianswer', array('question' => $questionid));
|
||||
|
@ -276,8 +276,10 @@ class qtype_multianswer_test_helper extends question_test_helper {
|
||||
$mc->layout = qtype_multichoice_base::LAYOUT_DROPDOWN;
|
||||
|
||||
$mc->answers = array(
|
||||
10 * $i => new question_answer(13, 'California', $data['California'] == 'OK', $data['California'], FORMAT_HTML),
|
||||
10 * $i + 1 => new question_answer(14, 'Arizona', $data['Arizona'] == 'OK', $data['Arizona'], FORMAT_HTML),
|
||||
10 * $i => new question_answer(13, 'California', (float) ($data['California'] == 'OK'),
|
||||
$data['California'], FORMAT_HTML),
|
||||
10 * $i + 1 => new question_answer(14, 'Arizona', (float) ($data['Arizona'] == 'OK'),
|
||||
$data['Arizona'], FORMAT_HTML),
|
||||
);
|
||||
$mc->qtype = question_bank::get_qtype('multichoice');
|
||||
$mc->maxmark = 1;
|
||||
|
@ -114,4 +114,67 @@ class qtype_multianswer_question_test extends advanced_testcase {
|
||||
array('i' => 2, 'response' => 'Pussy-cat')), $question->summarise_response(
|
||||
array('sub1_answer' => 'Owl', 'sub2_answer' => reset($rightchoice))));
|
||||
}
|
||||
}
|
||||
|
||||
public function test_get_num_parts_right() {
|
||||
$question = test_question_maker::make_question('multianswer');
|
||||
$question->start_attempt(new question_attempt_step(), 1);
|
||||
|
||||
$rightchoice = $question->subquestions[2]->get_correct_response();
|
||||
$right = reset($rightchoice);
|
||||
|
||||
$response = array('sub1_answer' => 'Frog', 'sub2_answer' => $right);
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(1, $numpartsright);
|
||||
$this->assertEquals(2, $numparts);
|
||||
$response = array('sub1_answer' => 'Owl', 'sub2_answer' => $right);
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(2, $numpartsright);
|
||||
$response = array('sub1_answer' => 'Dog', 'sub2_answer' => 3);
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(0, $numpartsright);
|
||||
$response = array('sub1_answer' => 'Owl');
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(1, $numpartsright);
|
||||
$response = array('sub1_answer' => 'Dog');
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(0, $numpartsright);
|
||||
$response = array('sub2_answer' => $right);
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(1, $numpartsright);
|
||||
}
|
||||
|
||||
public function test_get_num_parts_right_fourmc() {
|
||||
// Create a multianswer question with four mcq.
|
||||
$question = test_question_maker::make_question('multianswer', 'fourmc');
|
||||
$question->start_attempt(new question_attempt_step(), 1);
|
||||
|
||||
$response = array('sub1_answer' => '1', 'sub2_answer' => '1',
|
||||
'sub3_answer' => '1', 'sub4_answer' => '1');
|
||||
list($numpartsright, $numparts) = $question->get_num_parts_right($response);
|
||||
$this->assertEquals(2, $numpartsright);
|
||||
}
|
||||
|
||||
public function test_clear_wrong_from_response() {
|
||||
$question = test_question_maker::make_question('multianswer');
|
||||
$question->start_attempt(new question_attempt_step(), 1);
|
||||
|
||||
$rightchoice = $question->subquestions[2]->get_correct_response();
|
||||
$right = reset($rightchoice);
|
||||
|
||||
$response = array('sub1_answer' => 'Frog', 'sub2_answer' => $right);
|
||||
$this->assertEquals($question->clear_wrong_from_response($response),
|
||||
array('sub1_answer' => '', 'sub2_answer' => $right));
|
||||
$response = array('sub1_answer' => 'Owl', 'sub2_answer' => $right);
|
||||
$this->assertEquals($question->clear_wrong_from_response($response),
|
||||
array('sub1_answer' => 'Owl', 'sub2_answer' => $right));
|
||||
$response = array('sub1_answer' => 'Dog', 'sub2_answer' => 3);
|
||||
$this->assertEquals($question->clear_wrong_from_response($response),
|
||||
array('sub1_answer' => '', 'sub2_answer' => ''));
|
||||
$response = array('sub1_answer' => 'Owl');
|
||||
$this->assertEquals($question->clear_wrong_from_response($response),
|
||||
array('sub1_answer' => 'Owl'));
|
||||
$response = array('sub2_answer' => $right);
|
||||
$this->assertEquals($question->clear_wrong_from_response($response),
|
||||
array('sub2_answer' => $right));
|
||||
}
|
||||
}
|
||||
|
@ -198,4 +198,128 @@ class qtype_multianswer_walkthrough_test extends qbehaviour_walkthrough_test_bas
|
||||
$this->get_contains_subq_status(question_state::$gradedwrong),
|
||||
$this->get_does_not_contain_validation_error_expectation());
|
||||
}
|
||||
|
||||
public function test_interactive_feedback() {
|
||||
|
||||
// Create a multianswer question.
|
||||
$q = test_question_maker::make_question('multianswer', 'fourmc');
|
||||
$q->hints = array(
|
||||
new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true),
|
||||
new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
|
||||
);
|
||||
$choices = array('' => '', '0' => 'Califormia', '1' => 'Arizona');
|
||||
|
||||
$this->start_attempt_at_question($q, 'interactive', 4);
|
||||
|
||||
// Check the initial state.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
// TODO change to interactivecountback after MDL-36955 is integrated.
|
||||
$this->assertEquals('interactive',
|
||||
$this->quba->get_question_attempt($this->slot)->get_behaviour_name());
|
||||
$this->check_current_output(
|
||||
$this->get_contains_marked_out_of_summary(),
|
||||
$this->get_contains_select_expectation('sub1_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub2_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub3_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub4_answer', $choices, null, true),
|
||||
$this->get_contains_submit_button_expectation(true),
|
||||
$this->get_does_not_contain_validation_error_expectation(),
|
||||
$this->get_does_not_contain_feedback_expectation(),
|
||||
$this->get_tries_remaining_expectation(3),
|
||||
$this->get_does_not_contain_num_parts_correct(),
|
||||
$this->get_no_hint_visible_expectation());
|
||||
|
||||
// Submit a completely wrong response.
|
||||
$this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '0',
|
||||
'sub3_answer' => '1', 'sub4_answer' => '0', '-submit' => 1));
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_current_output(
|
||||
$this->get_contains_select_expectation('sub1_answer', $choices, 1, false),
|
||||
$this->get_contains_select_expectation('sub2_answer', $choices, 0, false),
|
||||
$this->get_contains_select_expectation('sub3_answer', $choices, 1, false),
|
||||
$this->get_contains_select_expectation('sub4_answer', $choices, 0, false),
|
||||
$this->get_does_not_contain_num_parts_correct(),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub2_answer', ''),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub4_answer', ''),
|
||||
$this->get_contains_submit_button_expectation(false),
|
||||
$this->get_contains_try_again_button_expectation(true),
|
||||
$this->get_does_not_contain_correctness_expectation(),
|
||||
$this->get_contains_hint_expectation('This is the first hint.'));
|
||||
|
||||
// Check that, if we review in this state, the try again button is disabled.
|
||||
$displayoptions = new question_display_options();
|
||||
$displayoptions->readonly = true;
|
||||
$html = $this->quba->render_question($this->slot, $displayoptions);
|
||||
$this->assert($this->get_contains_try_again_button_expectation(false), $html);
|
||||
|
||||
// Try again.
|
||||
$this->process_submission(array('sub1_answer' => '',
|
||||
'sub2_answer' => '', 'sub3_answer' => '',
|
||||
'sub4_answer' => '', '-tryagain' => 1));
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_current_output(
|
||||
$this->get_contains_select_expectation('sub1_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub2_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub3_answer', $choices, null, true),
|
||||
$this->get_contains_select_expectation('sub4_answer', $choices, null, true),
|
||||
$this->get_contains_submit_button_expectation(true),
|
||||
$this->get_does_not_contain_feedback_expectation(),
|
||||
$this->get_tries_remaining_expectation(2),
|
||||
$this->get_no_hint_visible_expectation());
|
||||
|
||||
// Submit a partially wrong response.
|
||||
$this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1',
|
||||
'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1));
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_current_output(
|
||||
$this->get_contains_select_expectation('sub1_answer', $choices, 1, false),
|
||||
$this->get_contains_select_expectation('sub2_answer', $choices, 1, false),
|
||||
$this->get_contains_select_expectation('sub3_answer', $choices, 1, false),
|
||||
$this->get_contains_select_expectation('sub4_answer', $choices, 1, false),
|
||||
$this->get_contains_num_parts_correct(2),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub2_answer', '1'),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''),
|
||||
$this->get_contains_hidden_expectation(
|
||||
$this->quba->get_field_prefix($this->slot) . 'sub4_answer', '1'),
|
||||
$this->get_contains_submit_button_expectation(false),
|
||||
$this->get_contains_hint_expectation('This is the second hint.'));
|
||||
|
||||
// Try again.
|
||||
$this->process_submission(array('sub1_answer' => '',
|
||||
'sub2_answer' => '1', 'sub3_answer' => '',
|
||||
'sub4_answer' => '1', '-tryagain' => 1));
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$todo);
|
||||
$this->check_current_mark(null);
|
||||
$this->check_current_output(
|
||||
$this->get_contains_select_expectation('sub1_answer', $choices, '', true),
|
||||
$this->get_contains_select_expectation('sub2_answer', $choices, '1', true),
|
||||
$this->get_contains_select_expectation('sub3_answer', $choices, '', true),
|
||||
$this->get_contains_select_expectation('sub4_answer', $choices, '1', true),
|
||||
$this->get_contains_submit_button_expectation(true),
|
||||
$this->get_does_not_contain_feedback_expectation(),
|
||||
$this->get_tries_remaining_expectation(1),
|
||||
$this->get_no_hint_visible_expectation());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user