public function test_false_right_does_not_show_feedback_when_not_answered() { // Create a true-false question with correct answer false. $tf = test_question_maker::make_question('truefalse', 'false'); $this->start_attempt_at_question($tf, 'deferredfeedback', 1); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_question_text_expectation($tf), $this->get_does_not_contain_feedback_expectation(), new question_contains_tag_with_contents('h3', get_string('questiontext', 'question'))); $this->assertEquals(get_string('false', 'qtype_truefalse'), $this->quba->get_right_answer_summary($this->slot)); $this->assertRegExp('/' . preg_quote($tf->questiontext, '/') . '/', $this->quba->get_question_summary($this->slot)); $this->assertNull($this->quba->get_response_summary($this->slot)); // Finish the attempt without answering. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$gaveup); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_tf_true_radio_expectation(false, false), $this->get_contains_tf_false_radio_expectation(false, false), // In particular, check that the false feedback is not displayed. new question_no_pattern_expectation('/' . preg_quote($tf->falsefeedback, '/') . '/')); }
public function test_interactive() { // Create a gapselect question. $q = test_question_maker::make_question('calculated'); $q->hints = array(new question_hint(1, 'This is the first hint.', FORMAT_HTML), new question_hint(2, 'This is the second hint.', FORMAT_HTML)); $this->start_attempt_at_question($q, 'interactive', 3, 1); $values = $q->vs->get_values(); $this->assertEquals($values, $q->datasetloader->load_values(1)); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_marked_out_of_summary(), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Submit blank. $this->process_submission(array('-submit' => 1, 'answer' => '')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output($this->get_contains_marked_out_of_summary(), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_feedback_expectation(), $this->get_contains_validation_error_expectation(), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Sumit something that does not look like a number. $this->process_submission(array('-submit' => 1, 'answer' => 'newt')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output($this->get_contains_marked_out_of_summary(), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_feedback_expectation(), $this->get_contains_validation_error_expectation(), new question_pattern_expectation('/' . preg_quote(get_string('invalidnumber', 'qtype_numerical'), '/') . '/'), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Now get it right. $this->process_submission(array('-submit' => 1, 'answer' => $values['a'] + $values['b'])); // Verify. $this->check_current_state(question_state::$gradedright); $this->check_current_mark(3); $this->check_current_output($this->get_contains_mark_summary(3), $this->get_does_not_contain_submit_button_expectation(), $this->get_contains_correct_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_no_hint_visible_expectation()); }
public function test_render_missing() { $records = new question_test_recordset(array(array('questionattemptid', 'contextid', 'questionusageid', 'slot', 'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged', 'questionsummary', 'rightanswer', 'responsesummary', 'timemodified', 'attemptstepid', 'sequencenumber', 'state', 'fraction', 'timecreated', 'userid', 'name', 'value'), array(1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, '_order', '1,2,3'), array(1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 2, 1, 'complete', 0.5, 1256233705, 1, '-submit', '1'), array(1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 2, 1, 'complete', 0.5, 1256233705, 1, 'choice0', '1'))); $question = test_question_maker::make_question('truefalse', 'true'); $question->id = -1; question_bank::start_unit_test(); question_bank::load_test_question_data($question); $qa = question_attempt::load_from_records($records, 1, new question_usage_null_observer(), 'deferredfeedback'); question_bank::end_unit_test(); $this->assertEquals(2, $qa->get_num_steps()); $step = $qa->get_step(0); $this->assertEquals(question_state::$todo, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233700, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('_order' => '1,2,3'), $step->get_all_data()); $step = $qa->get_step(1); $this->assertEquals(question_state::$complete, $step->get_state()); $this->assertEquals(0.5, $step->get_fraction()); $this->assertEquals(1256233705, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('-submit' => '1', 'choice0' => '1'), $step->get_all_data()); $output = $qa->render(new question_display_options(), '1'); $this->assertRegExp('/' . preg_quote($qa->get_question()->questiontext, '/') . '/', $output); $this->assertRegExp('/' . preg_quote(get_string('questionusedunknownmodel', 'qbehaviour_missing'), '/') . '/', $output); $this->assertTag(array('tag' => 'div', 'attributes' => array('class' => 'warning')), $output); }
public function test_manual_graded_truefalse() { // Create a true-false question with correct answer true. $tf = test_question_maker::make_question('truefalse', 'true'); $this->start_attempt_at_question($tf, 'manualgraded', 2); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_question_text_expectation($tf), $this->get_does_not_contain_feedback_expectation()); // Process a true answer and check the expected result. $this->process_submission(array('answer' => 1)); $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->check_current_output($this->get_contains_tf_true_radio_expectation(true, true), $this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_feedback_expectation()); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$needsgrading); $this->check_current_mark(null); $this->check_current_output($this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_specific_feedback_expectation()); // Process a manual comment. $this->manual_grade('Not good enough!', 1); $this->check_current_state(question_state::$mangrpartial); $this->check_current_mark(1); $this->check_current_output($this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_specific_feedback_expectation(), new PatternExpectation('/' . preg_quote('Not good enough!') . '/')); }
public function test_summarise_response() { $question = test_question_maker::make_question('multianswer'); $question->start_attempt(new question_attempt_step(), 1); $rightchoice = $question->subquestions[2]->get_correct_response(); $this->assertEqual(get_string('subqresponse', 'qtype_multianswer', array('i' => 1, 'response' => 'Owl')) . '; ' . get_string('subqresponse', 'qtype_multianswer', array('i' => 2, 'response' => 'Pussy-cat')), $question->summarise_response(array('sub1_answer' => 'Owl', 'sub2_answer' => reset($rightchoice)))); }
protected function setUp() { $this->question = test_question_maker::make_question('description'); $this->question->defaultmark = 3; $this->usageid = 13; $this->qa = new question_attempt($this->question, $this->usageid); }
public function test_informationitem_feedback_description() { // Create a true-false question with correct answer true. $description = test_question_maker::make_question('description'); $this->start_attempt_at_question($description, 'deferredfeedback'); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_question_text_expectation($description), new question_contains_tag_with_attributes('input', array('type' => 'hidden', 'name' => $this->quba->get_field_prefix($this->slot) . '-seen', 'value' => 1)), $this->get_does_not_contain_feedback_expectation()); // Process a submission indicating this question has been seen. $this->process_submission(array('-seen' => 1)); $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->check_current_output($this->get_does_not_contain_correctness_expectation(), new question_no_pattern_expectation('/type=\\"hidden\\"[^>]*name=\\"[^"]*seen\\"|name=\\"[^"]*seen\\"[^>]*type=\\"hidden\\"/'), $this->get_does_not_contain_feedback_expectation()); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$finished); $this->check_current_mark(null); $this->check_current_output($this->get_contains_question_text_expectation($description), $this->get_contains_general_feedback_expectation($description)); // Process a manual comment. $this->manual_grade('Not good enough!', null, FORMAT_HTML); $this->check_current_state(question_state::$manfinished); $this->check_current_mark(null); $this->check_current_output(new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/')); // Check that trying to process a manual comment with a grade causes an exception. $this->setExpectedException('moodle_exception'); $this->manual_grade('Not good enough!', 1, FORMAT_HTML); }
public function test_classify_response() { $tf = test_question_maker::make_question('truefalse', 'true'); $tf->start_attempt(new question_attempt_step(), 1); $this->assertEquals(array($tf->id => new question_classified_response(0, get_string('false', 'qtype_truefalse'), 0.0)), $tf->classify_response(array('answer' => '0'))); $this->assertEquals(array($tf->id => new question_classified_response(1, get_string('true', 'qtype_truefalse'), 1.0)), $tf->classify_response(array('answer' => '1'))); $this->assertEquals(array($tf->id => question_classified_response::no_response()), $tf->classify_response(array())); }
protected function setUp() { $this->question = test_question_maker::make_question('description'); $this->qa = new testable_question_attempt($this->question, 0, null, 2); for ($i = 0; $i < 3; $i++) { $step = new question_attempt_step(array('i' => $i)); $this->qa->add_step($step); } }
public function test_initialise_question_instance() { $qdata = test_question_maker::get_question_data('stack', 'test3'); $q = $this->qtype->make_question($qdata); $expectedq = test_question_maker::make_question('stack', 'test3'); $expectedq->stamp = $q->stamp; $expectedq->version = $q->version; $this->assertEquals($expectedq, $q); }
public function test_classify_response() { $question = test_question_maker::make_question('calculatedsimple'); $question->start_attempt(new question_attempt_step(), 1); $values = $question->vs->get_values(); $this->assertEquals(array(new question_classified_response(13, $values['a'] + $values['b'], 1.0)), $question->classify_response(array('answer' => $values['a'] + $values['b']))); $this->assertEquals(array(new question_classified_response(14, $values['a'] - $values['b'], 0.0)), $question->classify_response(array('answer' => $values['a'] - $values['b']))); $this->assertEquals(array(new question_classified_response(17, 7 * $values['a'], 0.0)), $question->classify_response(array('answer' => 7 * $values['a']))); $this->assertEquals(array(question_classified_response::no_response()), $question->classify_response(array('answer' => ''))); }
public function make_question($question) { try { $q = test_question_maker::make_question('coderunner', $question); } catch (qtype_coderunner_missing_question_type $ex) { $this->markTestSkipped("{$question} question unavailable: test skipped"); } $q->contextid = $this->category->contextid; return $q; }
protected function setUp() { $this->quba = question_engine::make_questions_usage_by_activity('unit_test', context_system::instance()); $this->quba->set_preferred_behaviour('deferredfeedback'); $slot = $this->quba->add_question(test_question_maker::make_question('description')); $this->qas[$slot] = $this->quba->get_question_attempt($slot); $slot = $this->quba->add_question(test_question_maker::make_question('description')); $this->qas[$slot] = $this->quba->get_question_attempt($slot); $this->iterator = $this->quba->get_attempt_iterator(); }
protected function setUp() { $question = test_question_maker::make_question('description'); $this->qa = new testable_question_attempt($question, 0); for ($i = 0; $i < 3; $i++) { $step = new question_attempt_step(array('i' => $i)); $this->qa->add_step($step); } $this->iterator = $this->qa->get_step_iterator(); }
public function test_synchronised_question_should_use_the_same_dataset() { // Actually, we cheat here. We use the same question twice, not two different synchronised questions. $question = test_question_maker::make_question('calculated'); $quba = question_engine::make_questions_usage_by_activity('test', context_system::instance()); $quba->set_preferred_behaviour('deferredfeedback'); $slot1 = $quba->add_question($question); $slot2 = $quba->add_question($question); $quba->start_all_questions(new core_question\engine\variants\least_used_strategy($quba, new qubaid_list(array()))); $this->assertEquals($quba->get_variant($slot1), $quba->get_variant($slot2)); }
public function test_informationitem_feedback_description() { // Create a description question. $description = test_question_maker::make_question('description'); $this->start_attempt_at_question($description, 'deferredfeedback'); // Check the initial state. $this->assertEquals('informationitem', $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); $this->check_current_output(new question_contains_tag_with_contents('h4', get_string('informationtext', 'qtype_description'))); // Further tests of the description qtype are in // question/behaviour/informationitem/tests/testwalkthrough.php. }
/** Make sure that if the Jobe URL is wrong we get "jobesandbox is down * or misconfigured" exception. * * @expectedException coderunner_exception * @expectedExceptionMessageRegExp |.*jobesandbox is down or misconfigured.*| * @retrun void */ public function test_misconfigured_jobe() { // if (!get_config('qtype_coderunner', 'jobesandbox_enabled')) { $this->markTestSkipped("Sandbox {$sandbox} unavailable: test skipped"); } set_config('jobe_host', 'localhostxxx', 'qtype_coderunner'); // Broken jobe_host url $q = test_question_maker::make_question('coderunner', 'sqr'); $this->start_attempt_at_question($q, 'adaptive', 1, 1); }
public function test_deferredfeedback_feedback_truefalse() { // Create a true-false question with correct answer true. $tf = test_question_maker::make_question('truefalse', 'true'); $this->start_attempt_at_question($tf, 'deferredfeedback', 2); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_output_contains_lang_string('notyetanswered', 'question'); $this->check_current_mark(null); $this->check_current_output($this->get_contains_question_text_expectation($tf), $this->get_does_not_contain_feedback_expectation()); $this->assertEquals(get_string('true', 'qtype_truefalse'), $this->quba->get_right_answer_summary($this->slot)); $this->assertRegExp('/' . preg_quote($tf->questiontext, '/') . '/', $this->quba->get_question_summary($this->slot)); $this->assertNull($this->quba->get_response_summary($this->slot)); // Process a true answer and check the expected result. $this->process_submission(array('answer' => 1)); $this->check_current_state(question_state::$complete); $this->check_output_contains_lang_string('answersaved', 'question'); $this->check_current_mark(null); $this->check_current_output($this->get_contains_tf_true_radio_expectation(true, true), $this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_feedback_expectation()); // Process the same data again, check it does not create a new step. $numsteps = $this->get_step_count(); $this->process_submission(array('answer' => 1)); $this->check_step_count($numsteps); // Process different data, check it creates a new step. $this->process_submission(array('answer' => 0)); $this->check_step_count($numsteps + 1); $this->check_current_state(question_state::$complete); // Change back, check it creates a new step. $this->process_submission(array('answer' => 1)); $this->check_step_count($numsteps + 2); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$gradedright); $this->check_current_mark(2); $this->check_current_output($this->get_contains_correct_expectation(), $this->get_contains_tf_true_radio_expectation(false, true), new question_pattern_expectation('/class="r0 correct"/')); $this->assertEquals(get_string('true', 'qtype_truefalse'), $this->quba->get_response_summary($this->slot)); // Process a manual comment. $this->manual_grade('Not good enough!', 1, FORMAT_HTML); $this->check_current_state(question_state::$mangrpartial); $this->check_current_mark(1); $this->check_current_output(new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/')); // Now change the correct answer to the question, and regrade. $tf->rightanswer = false; $this->quba->regrade_all_questions(); // Verify. $this->check_current_state(question_state::$mangrpartial); $this->check_current_mark(1); $autogradedstep = $this->get_step($this->get_step_count() - 2); $this->assertEquals($autogradedstep->get_fraction(), 0, '', 1.0E-7); }
public function test_deferred_feedback() { // Create a gapselect question. $q = test_question_maker::make_question('multianswer', 'fourmc'); $this->start_attempt_at_question($q, 'deferredfeedback', 4); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation()); // Save in incomplete answer. $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '', 'sub3_answer' => '', 'sub4_answer' => '')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation()); // TODO, really, it should. See MDL-32049. // Save a partially correct answer. $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 'sub3_answer' => '1', 'sub4_answer' => '1')); // Verify. $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation()); // Now submit all and finish. $this->process_submission(array('-finish' => 1)); // Verify. $this->check_current_state(question_state::$gradedpartial); $this->check_current_mark(2); $this->check_current_output( $this->get_contains_mark_summary(2), $this->get_contains_partcorrect_expectation(), $this->get_does_not_contain_validation_error_expectation()); }
public function test_load() { $scid = context_system::instance()->id; $records = new question_test_recordset(array(array('qubaid', 'contextid', 'component', 'preferredbehaviour', 'questionattemptid', 'questionusageid', 'slot', 'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged', 'questionsummary', 'rightanswer', 'responsesummary', 'timemodified', 'attemptstepid', 'sequencenumber', 'state', 'fraction', 'timecreated', 'userid', 'name', 'value'), array(1, $scid, 'unit_test', 'interactive', 1, 1, 1, 'interactive', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null), array(1, $scid, 'unit_test', 'interactive', 1, 1, 1, 'interactive', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 2, 1, 'todo', null, 1256233705, 1, 'answer', '1'), array(1, $scid, 'unit_test', 'interactive', 1, 1, 1, 'interactive', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 5, 2, 'gradedright', 1.0, 1256233720, 1, '-finish', '1'))); $question = test_question_maker::make_question('truefalse', 'true'); $question->id = -1; question_bank::start_unit_test(); question_bank::load_test_question_data($question); $quba = question_usage_by_activity::load_from_records($records, 1); question_bank::end_unit_test(); $this->assertEquals('unit_test', $quba->get_owning_component()); $this->assertEquals(1, $quba->get_id()); $this->assertInstanceOf('question_engine_unit_of_work', $quba->get_observer()); $this->assertEquals('interactive', $quba->get_preferred_behaviour()); $qa = $quba->get_question_attempt(1); $this->assertEquals($question->questiontext, $qa->get_question()->questiontext); $this->assertEquals(3, $qa->get_num_steps()); $step = $qa->get_step(0); $this->assertEquals(question_state::$todo, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233700, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array(), $step->get_all_data()); $step = $qa->get_step(1); $this->assertEquals(question_state::$todo, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233705, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('answer' => '1'), $step->get_all_data()); $step = $qa->get_step(2); $this->assertEquals(question_state::$gradedright, $step->get_state()); $this->assertEquals(1, $step->get_fraction()); $this->assertEquals(1256233720, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('-finish' => '1'), $step->get_all_data()); }
public function test_immediatecbm_cbm_truefalse_no_certainty_feedback_when_not_answered() { // Create a true-false question with correct answer true. $tf = test_question_maker::make_question('truefalse', 'true'); $this->start_attempt_at_question($tf, 'immediatecbm', 2); // Verify. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_does_not_contain_correctness_expectation(), $this->get_contains_cbm_radio_expectation(1, true, false), $this->get_does_not_contain_feedback_expectation()); // Finish without answering. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$gaveup); $this->check_current_mark(null); $this->check_current_output(new question_no_pattern_expectation('/class=\\"im-feedback/')); }
public function test_deferredfeedback_unit() { // Create a gapselect question. $q = test_question_maker::make_question('numerical', 'unit'); $this->start_attempt_at_question($q, 'deferredfeedback', 1); $unitchoices = array( '' => get_string('choosedots'), 'm' => 'm', 'cm' => 'cm', ); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_contains_select_expectation('unit', $unitchoices, null, true), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Submit blank. $this->process_submission(array('answer' => '')); // Verify. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_contains_select_expectation('unit', $unitchoices, null, true), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Sumit something that does not look like a number, but with a unit. $this->process_submission(array('answer' => 'newt', 'unit' => 'cm')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_contains_validation_error_expectation(), new question_pattern_expectation('/' . preg_quote(get_string('invalidnumber', 'qtype_numerical') . '/')), $this->get_contains_select_expectation('unit', $unitchoices, 'cm', true), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Now put in the right answer but without a unit. $this->process_submission(array('answer' => '1.25', 'unit' => '')); $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_contains_validation_error_expectation(), new question_pattern_expectation('/' . preg_quote(get_string('unitnotselected', 'qtype_numerical') . '/')), $this->get_contains_select_expectation('unit', $unitchoices, '', true), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Now put in the right answer with a unit. $this->process_submission(array('answer' => '1.25', 'unit' => 'm')); $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_contains_select_expectation('unit', $unitchoices, 'm', true), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Submit all and finish. $this->process_submission(array('-finish' => '1')); // Verify. $this->check_current_state(question_state::$gradedright); $this->check_current_mark(1); $this->check_current_output( $this->get_contains_mark_summary(1), $this->get_contains_correct_expectation(), $this->get_does_not_contain_validation_error_expectation(), $this->get_contains_select_expectation('unit', $unitchoices, 'm', false), $this->get_no_hint_visible_expectation()); $this->assertEquals('1.25 m', $this->quba->get_response_summary($this->slot)); }
public function test_load_with_unnecessary_autosaved_data() { // The point here is that the somehow (probably due to two things // happening concurrently, we have autosaved data in the database that // has already been superceded by real data, so it should be ignored. // There is also a second lot of redundant data to delete. $records = new question_test_recordset(array(array('questionattemptid', 'contextid', 'questionusageid', 'slot', 'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged', 'questionsummary', 'rightanswer', 'responsesummary', 'timemodified', 'attemptstepid', 'sequencenumber', 'state', 'fraction', 'timecreated', 'userid', 'name', 'value'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 5, -2, 'complete', null, 1256233715, 1, 'answer', '0'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 4, -1, 'complete', null, 1256233715, 1, 'answer', '0'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1.0, 0, '', '', '', 1256233790, 2, 1, 'complete', null, 1256233705, 1, 'answer', '1'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1.0, 1, '', '', '', 1256233790, 3, 2, 'complete', null, 1256233710, 1, 'answer', '0'))); $question = test_question_maker::make_question('truefalse', 'true'); $question->id = -1; question_bank::start_unit_test(); question_bank::load_test_question_data($question); $observer = new testable_question_engine_unit_of_work(question_engine::make_questions_usage_by_activity('unit_test', context_system::instance())); $qa = question_attempt::load_from_records($records, 1, $observer, 'deferredfeedback'); question_bank::end_unit_test(); $this->assertEquals($question->questiontext, $qa->get_question()->questiontext); $this->assertEquals(3, $qa->get_num_steps()); $this->assertFalse($qa->has_autosaved_step()); $step = $qa->get_step(0); $this->assertEquals(question_state::$todo, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233700, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array(), $step->get_all_data()); $step = $qa->get_step(1); $this->assertEquals(question_state::$complete, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233705, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('answer' => '1'), $step->get_all_data()); $step = $qa->get_step(2); $this->assertEquals(question_state::$complete, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEquals(1256233710, $step->get_timecreated()); $this->assertEquals(1, $step->get_user_id()); $this->assertEquals(array('answer' => '0'), $step->get_all_data()); $this->assertEquals(2, count($observer->get_steps_deleted())); }
public function test_load() { $records = new test_recordset(array(array('questionattemptid', 'contextid', 'questionusageid', 'slot', 'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'flagged', 'questionsummary', 'rightanswer', 'responsesummary', 'timemodified', 'attemptstepid', 'sequencenumber', 'state', 'fraction', 'timecreated', 'userid', 'name', 'value'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 2, 1, 'complete', null, 1256233705, 1, 'answer', '1'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 1, '', '', '', 1256233790, 3, 2, 'complete', null, 1256233710, 1, 'answer', '0'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 4, 3, 'complete', null, 1256233715, 1, 'answer', '1'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 5, 4, 'gradedright', 1.0, 1256233720, 1, '-finish', '1'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5, 1256233790, 1, '-comment', 'Not good enough!'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5, 1256233790, 1, '-mark', '1'), array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0, 0.0, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5, 1256233790, 1, '-maxmark', '2'))); $question = test_question_maker::make_question('truefalse', 'true'); $question->id = -1; question_bank::start_unit_test(); question_bank::load_test_question_data($question); $qa = question_attempt::load_from_records($records, 1, new question_usage_null_observer(), 'deferredfeedback'); question_bank::end_unit_test(); $this->assertEqual($question->questiontext, $qa->get_question()->questiontext); $this->assertEqual(6, $qa->get_num_steps()); $step = $qa->get_step(0); $this->assertEqual(question_state::$todo, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEqual(1256233700, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array(), $step->get_all_data()); $step = $qa->get_step(1); $this->assertEqual(question_state::$complete, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEqual(1256233705, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array('answer' => '1'), $step->get_all_data()); $step = $qa->get_step(2); $this->assertEqual(question_state::$complete, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEqual(1256233710, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array('answer' => '0'), $step->get_all_data()); $step = $qa->get_step(3); $this->assertEqual(question_state::$complete, $step->get_state()); $this->assertNull($step->get_fraction()); $this->assertEqual(1256233715, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array('answer' => '1'), $step->get_all_data()); $step = $qa->get_step(4); $this->assertEqual(question_state::$gradedright, $step->get_state()); $this->assertEqual(1, $step->get_fraction()); $this->assertEqual(1256233720, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array('-finish' => '1'), $step->get_all_data()); $step = $qa->get_step(5); $this->assertEqual(question_state::$mangrpartial, $step->get_state()); $this->assertEqual(0.5, $step->get_fraction()); $this->assertEqual(1256233790, $step->get_timecreated()); $this->assertEqual(1, $step->get_user_id()); $this->assertEqual(array('-comment' => 'Not good enough!', '-mark' => '1', '-maxmark' => '2'), $step->get_all_data()); }
public function test_display_of_right_answer_when_shuffled() { // Create a drag-and-drop question. $dd = test_question_maker::make_question('ddmarker'); $this->start_attempt_at_question($dd, 'deferredfeedback', 3); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_hidden_expectation(1), $this->get_contains_hidden_expectation(2), $this->get_contains_hidden_expectation(3), $this->get_does_not_contain_feedback_expectation()); // Save a partial answer. $this->process_submission($dd->get_correct_response()); // Verify. $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $rightanswer = array($dd->get_right_choice_for(1) => '50,50', $dd->get_right_choice_for(2) => '150,50', $dd->get_right_choice_for(3) => '100,150'); $this->check_current_output($this->get_contains_hidden_expectation(1, $rightanswer[1]), $this->get_contains_hidden_expectation(2, $rightanswer[2]), $this->get_contains_hidden_expectation(3, $rightanswer[3]), $this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_feedback_expectation()); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->displayoptions->rightanswer = question_display_options::VISIBLE; $this->assertEquals('{Drop zone 1 -> quick}, ' . '{Drop zone 2 -> fox}, ' . '{Drop zone 3 -> lazy}', $dd->get_right_answer_summary()); $this->check_current_state(question_state::$gradedright); $this->check_current_mark(3); }
public function test_classify_response_currency() { $num = test_question_maker::make_question('numerical', 'currency'); $num->start_attempt(new question_attempt_step(), 1); $this->assertEqual(array(new question_classified_response(14, '$100', 0)), $num->classify_response(array('answer' => '$100'))); $this->assertEqual(array(new question_classified_response(13, '1 332', 0.8)), $num->classify_response(array('answer' => '1 332'))); }
public function test_numerical_invalid() { // Create a numerical question $numq = test_question_maker::make_question('numerical', 'pi'); $numq->penalty = 0.1; $this->start_attempt_at_question($numq, 'adaptivenopenalty'); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_marked_out_of_summary(), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_feedback_expectation()); // Submit a non-numerical answer. $this->process_submission(array('-submit' => 1, 'answer' => 'Pi')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(null); $this->check_current_output($this->get_contains_marked_out_of_summary(1), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_correctness_expectation(), $this->get_contains_validation_error_expectation(), $this->get_does_not_contain_feedback_expectation()); // Submit an incorrect answer. $this->process_submission(array('-submit' => 1, 'answer' => '-5')); // Verify. $this->check_current_state(question_state::$todo); $this->check_current_mark(0); $this->check_current_output($this->get_contains_mark_summary(0), $this->get_contains_submit_button_expectation(true), $this->get_contains_incorrect_expectation(), $this->get_does_not_contain_penalty_info_expectation(), $this->get_does_not_contain_total_penalty_expectation(), $this->get_does_not_contain_validation_error_expectation()); // Submit another non-numerical answer. $this->process_submission(array('-submit' => 1, 'answer' => 'Pi*2')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(0); $this->check_current_output($this->get_contains_mark_summary(0), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_correctness_expectation(), $this->get_contains_validation_error_expectation(), $this->get_does_not_contain_gradingdetails_expectation()); // Submit the correct answer. $this->process_submission(array('-submit' => 1, 'answer' => '3.14')); // Verify. $this->check_current_state(question_state::$complete); $this->check_current_mark(1.0); $this->check_current_output($this->get_contains_mark_summary(1.0), $this->get_contains_submit_button_expectation(true), $this->get_contains_correct_expectation(), $this->get_does_not_contain_validation_error_expectation()); // Submit another non-numerical answer. $this->process_submission(array('-submit' => 1, 'answer' => 'Pi/3')); // Verify. $this->check_current_state(question_state::$invalid); $this->check_current_mark(1.0); $this->check_current_output($this->get_contains_mark_summary(1.0), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_correctness_expectation(), $this->get_contains_validation_error_expectation(), $this->get_does_not_contain_gradingdetails_expectation()); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->check_current_state(question_state::$gradedwrong); $this->check_current_mark(1.0); $this->check_current_output($this->get_contains_mark_summary(1.0), $this->get_does_not_contain_submit_button_expectation(), $this->get_contains_incorrect_expectation(), $this->get_does_not_contain_validation_error_expectation()); }
public function test_display_of_right_answer_when_shuffled() { // Create a drag-and-drop question. $dd = test_question_maker::make_question('ddwtos'); $this->start_attempt_at_question($dd, 'deferredfeedback', 3); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output($this->get_contains_drop_box_expectation('1', 1, false), $this->get_contains_drop_box_expectation('2', 2, false), $this->get_contains_drop_box_expectation('3', 3, false), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p1', '0'), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p2', '0'), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p3', '0'), $this->get_does_not_contain_feedback_expectation()); // Save a partial answer. $this->process_submission($dd->get_correct_response()); // Verify. $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->check_current_output($this->get_contains_drop_box_expectation('1', 1, false), $this->get_contains_drop_box_expectation('2', 2, false), $this->get_contains_drop_box_expectation('3', 3, false), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p1', $dd->get_right_choice_for(1)), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p2', $dd->get_right_choice_for(2)), $this->get_contains_hidden_expectation($this->quba->get_field_prefix($this->slot) . 'p3', $dd->get_right_choice_for(3)), $this->get_does_not_contain_correctness_expectation(), $this->get_does_not_contain_feedback_expectation()); // Finish the attempt. $this->quba->finish_all_questions(); // Verify. $this->displayoptions->rightanswer = question_display_options::VISIBLE; $this->assertEquals('{quick} {fox} {lazy}', $dd->get_right_answer_summary()); $this->check_current_state(question_state::$gradedright); $this->check_current_mark(3); $this->check_current_output($this->get_contains_drop_box_expectation('1', 1, true, 'correct'), $this->get_contains_drop_box_expectation('2', 2, true, 'correct'), $this->get_contains_drop_box_expectation('3', 3, true, 'correct'), $this->get_contains_correct_expectation(), new question_pattern_expectation('/' . preg_quote('The [quick] brown [fox] jumped over the [lazy] dog.') . '/')); }
public function test_combinator_template_grading() { // Use the question maker to provide a dummy question. // Mostly ignore it. This question wants an answer with exactly // two occurrences of each of the tokens 'hi' and 'ho' and awards // a mark according to how well this criterion is satisfied. $q = test_question_maker::make_question('coderunner', 'sqrnoprint'); $q->combinatortemplate = <<<EOTEMPLATE import json answer = """{{ STUDENT_ANSWER | e('py') }}""" tokens = answer.split() num_hi = len([t for t in tokens if t.lower() == 'hi']) num_ho = len([t for t in tokens if t.lower() == 'ho']) hi_mark = 2 if num_hi == 2 else 1 if abs(num_hi - 2) == 1 else 0 ho_mark = 2 if num_ho == 2 else 1 if abs(num_ho - 2) == 1 else 0 fraction = (hi_mark + ho_mark) / 4 if fraction == 1.0: feedback = '<h2>Well done</h2><p>I got 2 of each of hi and ho.</p>' else: feedback = '<h2>Wrong numbers of hi and/or ho</h2><p>I wanted 2 of each but got {} and {} respectively.</p>'.format(num_hi, num_ho) print(json.dumps({'fraction': fraction, 'feedback_html': feedback})) EOTEMPLATE; $q->allornothing = false; $q->grader = 'CombinatorTemplateGrader'; $q->customise = true; $q->enablecombinator = true; $q->unitpenalty = 0; // Submit a right answer $this->start_attempt_at_question($q, 'adaptive', 1, 1); $this->process_submission(array('-submit' => 1, 'answer' => "hi di hi and HO DI HO")); //echo $html = $this->quba->render_question($this->slot, $this->displayoptions); $this->check_current_mark(1.0); $this->check_current_output(new question_pattern_expectation('|<h2>Well done</h2>|')); // Submit a partially right answer $this->start_attempt_at_question($q, 'adaptive', 1, 1); $this->process_submission(array('-submit' => 1, 'answer' => "hi di nothi and HO DI NOTHO")); //echo $html = $this->quba->render_question($this->slot, $this->displayoptions); $this->check_current_mark(0.5); $this->check_current_output(new question_pattern_expectation('|<h2>Wrong numbers of hi and/or ho</h2>|')); }
public function test_get_variants_selection_seed_q_synchronised() { $question = test_question_maker::make_question('calculated'); $question->synchronised = true; $question->datasetloader->set_are_synchronised($question->category, true); $this->assertEqual('category' . $question->category, $question->get_variants_selection_seed()); }