MDL-79863 qtype_ordering: Code checker & behat

Part of: MDL-79863
This commit is contained in:
Mathew May
2024-04-05 09:24:02 +08:00
parent aa2ef1fe9c
commit db7abb51cb
17 changed files with 205 additions and 104 deletions
+20 -9
View File
@@ -6,10 +6,10 @@ Change log for qtype_ordering
- small fix to download URLs in readme.txt
2023-05-31 (08)
- * Fix Behat failure following button change in Moodle master branch
- * Fix Behat failure following button change in Moodle master branch
2023-04-29 (07)
- Co-authored-by: Anupama Sarjoshi <[email protected]>
- Co-authored-by: Anupama Sarjoshi <[email protected]>
2022-09-27 (07)
- This version works with Moodle 4.0, 4.1 and 4.2.
@@ -48,7 +48,8 @@ Change log for qtype_ordering
- fix behavior in Adaptive mode, with 'Whether correct' review option enabled
2019-07-31 (93)
- (github-issue #43 and #44): rename upper case numberstyles to ABCD and IIII in order to differentiate from lower case styles on DBs, such as MySQL, which use case insensitive indexes.
- (github-issue #43 and #44): rename upper case numberstyles to ABCD and IIII in order to
differentiate from lower case styles on DBs, such as MySQL, which use case insensitive indexes.
2019-07-12 (92)
- rename 'answernumbering' to 'numberingstyle' and include this field in import/export of xml/gift formats.
@@ -69,13 +70,19 @@ Change log for qtype_ordering
- fix small typo in language file and optimize logic in form validation
2019-03-05 (87)
- Qtype ordering should not allow duplicatue items (#40) Thank you Mahmoud Kassaei for your continuing work to improve the Ordering question type
- Qtype ordering should not allow duplicatue items (#40)
Thank you Mahmoud Kassaei for your continuing work to improve the Ordering question type
2019-02-19 (86)
- small fix to spelling and whitespace
2019-02-19 (86)
- qtype_ordering: Ordering codechecker (#39) * Code checker issues on edit_ordering_form.php * function question_register_questiontype() not needed in questiontype.php * Code checker issues in questiontype.php * Code checker issues in question.php * Code checker issues in renderer.php * Code checker issues in version.php
- qtype_ordering: Ordering codechecker (#39)
* Code checker issues on edit_ordering_form.php *function question_register_questiontype() not needed in questiontype.php
* Code checker issues in questiontype.php
* Code checker issues in question.php
* Code checker issues in renderer.php
* Code checker issues in version.php
2019-02-08 (85)
- Merge pull request #38 from mkassaei/ordering_cleanup Ordering cleanup - thanks Mahmoud Kassaei!
@@ -84,7 +91,8 @@ Change log for qtype_ordering
- remove deprecated jquery folder and amd/*.js files
2019-01-25 (84)
- Merge pull request #37 from timhunt/qtype-ordering-js-css New JavaScript implementation - many thanks to Tim Hunt and Mahmoud Kassei of Open University
- Merge pull request #37 from timhunt/qtype-ordering-js-css New JavaScript implementation -
many thanks to Tim Hunt and Mahmoud Kassei of Open University
2019-01-08 (83)
- add showgrading field to backup file
@@ -105,7 +113,8 @@ Change log for qtype_ordering
- improve logic and of code to get_subset and code to add repeated elements to form
2018-12-15 (78)
- fix Github issue #35: Clicking Add to add items more than once without saving the question in between has incorrect and unwanted behavior
- fix Github issue #35: Clicking Add to add items more than once without saving the question
in between has incorrect and unwanted behavior
2018-12-12 (77)
- rename variables to improve readability of loop that detects ordered subsets
@@ -124,7 +133,8 @@ Change log for qtype_ordering
- fix detection of Longest ordered/contiguous subset where two or more such subsets exist
2018-11-26 (74)
- fix indexing of items when "Item selection type" is "Select a contiguous subset of items". The incorrect indexing resulted in less than the exptected number of items being displayed.
- fix indexing of items when "Item selection type" is "Select a contiguous subset of items".
The incorrect indexing resulted in less than the exptected number of items being displayed.
2018-11-19 (73)
- update version.php for recent BEHAT modifications
@@ -245,7 +255,8 @@ Change log for qtype_ordering
- fix handling of unscored items in grading details during review of question attempt
2016-01-01 (36)
- fix grade calculation for RELATIVE_ONE_PREVIOUS_AND_NEXT and RELATIVE_ALL_PREVIOUS_AND_NEXT, and add grade/score details for less than perfect grades
- fix grade calculation for RELATIVE_ONE_PREVIOUS_AND_NEXT and RELATIVE_ALL_PREVIOUS_AND_NEXT,
and add grade/score details for less than perfect grades
2015-12-31 (35)
- finish implementation of new setting, gradingtype, to allow different grading methods for ordering questions
@@ -55,7 +55,8 @@ class backup_qtype_ordering_plugin extends backup_qtype_plugin {
'gradingtype', 'showgrading', 'numberingstyle',
'correctfeedback', 'correctfeedbackformat',
'incorrectfeedback', 'incorrectfeedbackformat',
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat', 'shownumcorrect'];
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat', 'shownumcorrect',
];
$ordering = new backup_nested_element('ordering', ['id'], $fields);
// Now the own qtype tree.
@@ -59,7 +59,7 @@ class correct_response extends renderable_base {
$this->qa, 'question', 'answer', $answerid);
$data['correctanswers'][] = [
'answertext' => $answertext
'answertext' => $answertext,
];
}
@@ -36,7 +36,8 @@ class feedback extends renderable_base {
* The class constructor.
*
* @param question_attempt $qa The question attempt object.
* @param question_display_options $options Controls what should and should not be displayed via question_display_options but unit tests are fickle.
* @param question_display_options $options Controls what should and should not be displayed
* via question_display_options but unit tests are fickle.
*/
public function __construct(question_attempt $qa, question_display_options $options) {
parent::__construct($qa);
@@ -77,7 +77,10 @@ class formulation_and_controls extends renderable_base {
}
// In the multi-tries, the highlight response base on the hint highlight option.
if ((isset($this->options->highlightresponse) && $this->options->highlightresponse) || !$this->qa->get_state()->is_active()) {
if (
(isset($this->options->highlightresponse) && $this->options->highlightresponse) ||
!$this->qa->get_state()->is_active()
) {
$data['active'] = false;
} else if ($this->qa->get_state()->is_active()) {
$data['active'] = true;
+28 -28
View File
@@ -36,28 +36,28 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
$select = 'qn.*, qo.id AS questionorderingid';
$from = '{question} qn LEFT JOIN {question_ordering} qo ON qn.id = qo.question';
$where = 'qn.qtype = ? AND qo.id IS NULL';
$params = array('ordering');
$params = ['ordering'];
if ($questions = $DB->get_records_sql("SELECT $select FROM $from WHERE $where", $params)) {
foreach ($questions as $question) {
if ($answers = $DB->get_records('question_answers', array('question' => $question->id))) {
if ($answers = $DB->get_records('question_answers', ['question' => $question->id])) {
// Add "options" for this ordering question.
$questionordering = (object) array(
$questionordering = (object) [
'question' => $question->id,
'logical' => 1,
'studentsee' => min(6, count($answers)),
'correctfeedback' => '',
'partiallycorrectfeedback' => '',
'incorrectfeedback' => ''
);
'incorrectfeedback' => '',
];
$questionordering->id = $DB->insert_record('question_ordering', $questionordering);
} else {
// This is a faulty ordering question - remove it.
$DB->delete_records('question', array('id' => $question->id));
$DB->delete_records('question', ['id' => $question->id]);
if ($dbman->table_exists('quiz_question_instances')) {
$DB->delete_records('quiz_question_instances', array('question' => $question->id));
$DB->delete_records('quiz_question_instances', ['question' => $question->id]);
}
if ($dbman->table_exists('reader_question_instances')) {
$DB->delete_records('reader_question_instances', array('question' => $question->id));
$DB->delete_records('reader_question_instances', ['question' => $question->id]);
}
}
}
@@ -82,10 +82,10 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
// Remove index on question(id) field (because we want to modify the field).
$table = new xmldb_table('qtype_ordering_options');
$fields = array('question', 'questionid');
$fields = ['question', 'questionid'];
foreach ($fields as $field) {
if ($dbman->field_exists($table, $field)) {
$index = new xmldb_index('qtypordeopti_que_uix', XMLDB_INDEX_UNIQUE, array($field));
$index = new xmldb_index('qtypordeopti_que_uix', XMLDB_INDEX_UNIQUE, [$field]);
if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}
@@ -97,7 +97,7 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
// Rename "studentsee" -> "selectcount".
// Add "(xxx)feedbackformat" fields.
$table = new xmldb_table('qtype_ordering_options');
$fields = array(
$fields = [
'questionid' => new xmldb_field('question', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, '0', 'id'),
'selecttype' => new xmldb_field('logical', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'questionid'),
'selectcount' => new xmldb_field('studentsee', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'selecttype'),
@@ -106,8 +106,8 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
'incorrectfeedbackformat' => new xmldb_field('incorrectfeedbackformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL,
null, '0', 'incorrectfeedback'),
'partiallycorrectfeedbackformat' => new xmldb_field('partiallycorrectfeedbackformat', XMLDB_TYPE_INTEGER, '2', null,
XMLDB_NOTNULL, null, '0', 'partiallycorrectfeedback')
);
XMLDB_NOTNULL, null, '0', 'partiallycorrectfeedback'),
];
foreach ($fields as $newname => $field) {
$oldexists = $dbman->field_exists($table, $field);
$newexists = $dbman->field_exists($table, $newname);
@@ -133,18 +133,18 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
$from = '{qtype_ordering_options}';
$group = 'questionid';
$having = 'countduplicates > ?';
$params = array(1);
$params = [1];
if ($records = $DB->get_records_sql("SELECT $select FROM $from GROUP BY $group HAVING $having", $params)) {
foreach ($records as $record) {
$select = 'id <> ? AND questionid = ?';
$params = array($record->maxid, $record->questionid);
$params = [$record->maxid, $record->questionid];
$DB->delete_records_select('qtype_ordering_options', $select, $params);
}
}
// Restore index on questionid field.
$table = new xmldb_table('qtype_ordering_options');
$index = new xmldb_index('qtypordeopti_que_uix', XMLDB_INDEX_UNIQUE, array('questionid'));
$index = new xmldb_index('qtypordeopti_que_uix', XMLDB_INDEX_UNIQUE, ['questionid']);
if (! $dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
@@ -154,10 +154,10 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
if ($oldversion < 2015110725) {
$table = new xmldb_table('qtype_ordering_options');
$fields = array(
$fields = [
new xmldb_field('layouttype', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0, 'questionid'),
new xmldb_field('selecttype', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0, 'layouttype')
);
new xmldb_field('selecttype', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0, 'layouttype'),
];
foreach ($fields as $field) {
if ($dbman->field_exists($table, $field)) {
$dbman->change_field_type($table, $field);
@@ -170,9 +170,9 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
if ($oldversion < 2015121734) {
$table = new xmldb_table('qtype_ordering_options');
$fields = array(
new xmldb_field('gradingtype', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0, 'selectcount')
);
$fields = [
new xmldb_field('gradingtype', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0, 'selectcount'),
];
foreach ($fields as $field) {
if ($dbman->field_exists($table, $field)) {
$dbman->change_field_type($table, $field);
@@ -180,7 +180,7 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
$dbman->add_field($table, $field);
// When adding this field to existing records,
// the gradingtype is set to whatever the selecttype is.
$DB->execute('UPDATE {qtype_ordering_options} SET gradingtype = selecttype', array());
$DB->execute('UPDATE {qtype_ordering_options} SET gradingtype = selecttype', []);
}
}
upgrade_plugin_savepoint(true, 2015121734, 'qtype', 'ordering');
@@ -193,7 +193,7 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
'LEFT JOIN {question} q ON rqi.question = q.id';
$where = 'q.qtype = ?';
$group = 'rqi.question';
$params = array('ordering');
$params = ['ordering'];
if ($questions = $DB->get_records_sql("SELECT $select FROM $from WHERE $where GROUP BY $group", $params)) {
$questions = array_keys($questions);
list($select, $params) = $DB->get_in_or_equal($questions);
@@ -256,15 +256,15 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
$table = 'qtype_ordering_options';
$field = 'numberingstyle';
$select = "$field = ? OR $field = ?";
$params = array('III', 'ABC');
$params = ['III', 'ABC'];
if ($options = $DB->get_records_select($table, $select, $params, $field, "id,$field")) {
foreach ($options as $option) {
switch ($option->numberingstyle) {
case 'ABC':
$DB->set_field($table, $field, 'ABCD', array('id' => $option->id));
$DB->set_field($table, $field, 'ABCD', ['id' => $option->id]);
break;
case 'III':
$DB->set_field($table, $field, 'IIII', array('id' => $option->id));
$DB->set_field($table, $field, 'IIII', ['id' => $option->id]);
break;
// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
// Ignore "abc", "iii", and anything else.
@@ -347,7 +347,7 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
WHERE selectcount = :selectcount
GROUP BY qoo.id";
$questionoptions = $DB->get_recordset_sql($sql, ['selectcount' => 0]);
foreach($questionoptions as $questionoption) {
foreach ($questionoptions as $questionoption) {
// Update the value of the 'selectcount' configuration option for the current ordering question and set it
// to the total number of answers related to this question. This way, we are making sure that the original
// behavior is preserved and all existing items (answers) related to the question will be included in the
+10 -6
View File
@@ -360,9 +360,11 @@ class qtype_ordering_edit_form extends question_edit_form {
$format = $answer->answerformat;
$text = file_prepare_draft_area($itemid, $this->context->id, 'question', 'answer',
$answerid, $this->editoroptions, $answer->answer);
$question->answer[$i] = ['text' => $text,
$question->answer[$i] = [
'text' => $text,
'format' => $format,
'itemid' => $itemid];
'itemid' => $itemid,
];
}
$question->fraction[$i] = ($i + 1);
}
@@ -446,7 +448,7 @@ class qtype_ordering_edit_form extends question_edit_form {
}
// If there are no answers provided, show error message under first 2 answer boxes
// If only 1 answer provided, show error message under second answer box
// If only 1 answer provided, show error message under second answer box.
if ($answercount < 2) {
$errors['answer[1]'] = get_string('notenoughanswers', $plugin, 2);
@@ -457,8 +459,10 @@ class qtype_ordering_edit_form extends question_edit_form {
// If adding a new ordering question, update defaults.
if (empty($errors) && empty($data['id'])) {
$fields = ['layouttype', 'selecttype', 'selectcount',
'gradingtype', 'showgrading', 'numberingstyle'];
$fields = [
'layouttype', 'selecttype', 'selectcount',
'gradingtype', 'showgrading', 'numberingstyle',
];
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
question_bank::get_qtype($this->qtype())->set_default_value($field, $data[$field]);
@@ -541,7 +545,7 @@ class qtype_ordering_edit_form extends question_edit_form {
$options = $this->get_addcount_options($type);
$mform->addGroup([
$mform->createElement('submit', $addtypes, get_string('add')),
$mform->createElement('select', $addtypescount, '', $options)
$mform->createElement('select', $addtypescount, '', $options),
], $addtypesgroup, '', ' ', false);
// Set default value and type of select element.
+6 -6
View File
@@ -29,9 +29,6 @@ use qtype_ordering\output\specific_grade_detail_feedback;
*/
class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
// Disable coverage report for most of this file as each method is tested separately and as a while via Behat.
// @codeCoverageIgnoreStart
/**
* Generate the display of the formulation part of the question. This is the
* area that contains the question text, and the controls for students to
@@ -42,6 +39,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
* @param question_display_options $options controls what should and should not be displayed.
* @return string HTML fragment.
* @throws moodle_exception
* @codeCoverageIgnore
*/
public function formulation_and_controls(question_attempt $qa, question_display_options $options): string {
$formulationandcontrols = new formulation_and_controls($qa, $options);
@@ -58,6 +56,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
* @param question_display_options $options Controls what should and should not be displayed.
* @return string HTML fragment.
* @throws moodle_exception
* @codeCoverageIgnore
*/
public function feedback(question_attempt $qa, question_display_options $options): string {
$feedback = new feedback($qa, $options);
@@ -71,6 +70,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
* @param question_attempt $qa The question attempt to display.
* @return string Output grade detail of the response.
* @throws moodle_exception
* @codeCoverageIgnore
*/
public function specific_grade_detail_feedback(question_attempt $qa): string {
$specificgradedetailfeedback = new specific_grade_detail_feedback($qa);
@@ -84,6 +84,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
*
* @param question_attempt $qa The question attempt to display.
* @return string HTML fragment.
* @codeCoverageIgnore
*/
public function specific_feedback(question_attempt $qa): string {
return $this->combined_feedback($qa);
@@ -97,6 +98,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
* @throws moodle_exception
* @codeCoverageIgnore
*/
public function correct_response(question_attempt $qa): string {
$correctresponse = new correct_response($qa);
@@ -112,6 +114,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
* @param question_attempt $qa The question attempt to display.
* @return string HTML fragment.
* @throws moodle_exception
* @codeCoverageIgnore
*/
protected function num_parts_correct(question_attempt $qa): string {
$numpartscorrect = new num_parts_correct($qa);
@@ -119,9 +122,6 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
$numpartscorrect->export_for_template($this->output));
}
// Below this point, is code that will be included in the report as it isn't reported in isolation.
// @codeCoverageIgnoreEnd
/**
* Return an appropriate icon (green tick, red cross, etc.) for a grade.
* Note: Strict typing the params here breaks code eval as the parent function is not strictly typed.
@@ -48,13 +48,13 @@
"id": "ordering_item_497031794414a552435f90151ac3b54b",
"scoreclass": "correct",
"answertext": "Oriented",
"feedbackimage": "<i class="icon fa fa-remove text-danger fa-fw" title="Incorrect" role="img" aria-label="Incorrect"></i>"
"feedbackimage": "<i class='icon fa fa-remove text-danger fa-fw' title='Incorrect' role='img' aria-label='Incorrect'></i>"
},
{
"id": "ordering_item_5a35edab0f2bf86dfa3901baa8c235dc",
"scoreclass": "correct",
"answertext": "Object",
"feedbackimage": "<i class="icon fa fa-remove text-danger fa-fw" title="Incorrect" role="img" aria-label="Incorrect"></i>"
"feedbackimage": "<i class='icon fa fa-remove text-danger fa-fw' title='Incorrect' role='img' aria-label='Incorrect'></i>"
}
]
}
@@ -37,10 +37,11 @@
Example context (json):
{
listClassName: 'osep-list',
itemClassName: 'osep-item osep-itemmoving',
itemHtml: 'Item 1',
proxyStyles: 'left: 0px; top: 0px; width: 100px; height: 100px;'
"listClassName": "osep-list",
"itemClassName": "osep-item osep-itemmoving",
"itemHtml": "Item 1",
"proxyStyles": "left: 0px; top: 0px; width: 100px; height: 100px;"
}
}}
<div class="que ordering dragproxy" style="position: absolute; {{proxyStyles}}">
<ul class="{{listClassName}}">
@@ -32,6 +32,8 @@ require_once($CFG->dirroot . '/course/externallib.php');
* @package qtype_ordering
* @copyright 2020 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
* @covers \backup_qtype_ordering_plugin
* @covers \restore_qtype_ordering_plugin
*/
class backup_test extends \advanced_testcase {
@@ -40,7 +40,8 @@ class behat_qtype_ordering extends behat_base {
* @return string the xpath expression.
*/
protected function item_xpath_by_label(string $label): string {
return '//li[@class = "sortableitem" and contains(normalize-space(.), "' . $this->escape($label) . '")]';
return "//li[contains(concat(' ', normalize-space(@class), ' '), 'sortableitem') and contains(normalize-space(.), '" .
$this->escape($label) . "')]";
}
/**
@@ -49,7 +50,7 @@ class behat_qtype_ordering extends behat_base {
* @return string the xpath expression.
*/
protected function item_xpath_by_position(string $position): string {
return '//li[@class = "sortableitem"][' . $position . ']';
return "//li[contains(concat(' ', normalize-space(@class), ' '), 'sortableitem')][" . $position . "]";
}
/**
@@ -67,21 +68,32 @@ class behat_qtype_ordering extends behat_base {
* @Given /^I drag "(?P<label>[^"]*)" to space "(?P<position>\d+)" in the ordering question$/
*/
public function i_drag_to_space_in_the_drag_and_drop_into_text_question(string $label, int $position): void {
$testingpos = $position - 1; // 0-based index.
$generalcontext = behat_context_helper::get('behat_general');
// There was a weird issue where drag-drop was not reliable if an item was being
// dragged to the same place it already was. So, first drag below the bottom to reliably
// move it to the last place.
$generalcontext->i_drag_and_i_drop_it_in(
$this->item_xpath_by_label($label),
'xpath_element',
get_string('check', 'question'),
'button'
$this->execute_script("
(function() {
var droptarget = document.createElement('li');
droptarget.setAttribute('class', 'dtb');
var items = document.querySelector('.sortablelist');
items.insertBefore(droptarget, items.children[$testingpos]);
}())"
);
$generalcontext->i_drag_and_i_drop_it_in(
$this->item_xpath_by_label($label),
'xpath_element',
$this->item_xpath_by_position($position),
"//li[contains(concat(' ', normalize-space(@class), ' '), 'dtb')]",
'xpath_element'
);
$this->execute_script("
(function() {
var item = document.querySelector('.dtb');
item.parentNode.removeChild(item);
}())"
);
}
}
@@ -32,8 +32,9 @@ Feature: Preview an Ordering question
And I drag "Oriented" to space "3" in the ordering question
And I drag "Dynamic" to space "4" in the ordering question
And I drag "Learning" to space "5" in the ordering question
And I drag "Environment" to space "6" in the ordering question
And I press "Submit and finish"
Then I should see "Correct items: 6"
Then I should see "Well done!"
And I should see "Mark 1.00 out of 1.00"
@javascript
@@ -43,6 +44,7 @@ Feature: Preview an Ordering question
And I set the field "How questions behave" to "Immediate feedback"
And I press "id_saverestart"
And I drag "Modular" to space "1" in the ordering question
And I drag "Object" to space "6" in the ordering question
And I drag "Oriented" to space "4" in the ordering question
And I drag "Dynamic" to space "3" in the ordering question
And I drag "Learning" to space "5" in the ordering question
@@ -63,10 +65,11 @@ Feature: Preview an Ordering question
And I set the field "How questions behave" to "Immediate feedback"
And I press "id_saverestart"
And I drag "Modular" to space "1" in the ordering question
And I drag "Oriented" to space "4" in the ordering question
And I drag "Dynamic" to space "3" in the ordering question
And I drag "Learning" to space "5" in the ordering question
And I drag "Environment" to space "2" in the ordering question
And I drag "Dynamic" to space "3" in the ordering question
And I drag "Oriented" to space "4" in the ordering question
And I drag "Learning" to space "5" in the ordering question
And I drag "Object" to space "6" in the ordering question
And I press "Submit and finish"
And I should not see "You have 1 item correct."
And I should not see "You have 5 items partially correct."
@@ -39,22 +39,22 @@ class feedback_test extends qbehaviour_walkthrough_test_base {
/** @var array $correctanswers The correct answers for the question, added to quickly reference. */
private $correctanswers = [
0 => [
'answertext' => 'Modular'
'answertext' => 'Modular',
],
1 => [
'answertext' => 'Object'
'answertext' => 'Object',
],
2 => [
'answertext' => 'Oriented'
'answertext' => 'Oriented',
],
3 => [
'answertext' => 'Dynamic'
'answertext' => 'Dynamic',
],
4 => [
'answertext' => 'Learning'
'answertext' => 'Learning',
],
5 => [
'answertext' => 'Environment'
'answertext' => 'Environment',
],
];
@@ -136,12 +136,12 @@ class feedback_test extends qbehaviour_walkthrough_test_base {
'numincorrect' => 0,
],
'specificgradedetailfeedback' => [
'showpartialwrong' => 0
'showpartialwrong' => 0,
],
'generalfeedback' => 'The correct answer is "Modular Object Oriented Dynamic Learning Environment".',
'rightanswer' => [
'hascorrectresponse' => true,
'showcorrect' => false
'showcorrect' => false,
],
],
],
@@ -205,7 +205,8 @@ class feedback_test extends qbehaviour_walkthrough_test_base {
],
],
],
'Partially correct question attempt in progress (horizontal layout). Relative to ALL the previous and next items with hints' => [
'Partially correct question attempt in progress (horizontal layout). Relative to ALL the previous and next ' .
'items with hints' => [
[13 => 'Modular', 14 => 'Object', 15 => 'Oriented', 17 => 'Learning', 16 => 'Dynamic', 18 => 'Environment'],
qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT,
['rot' => 'horizontal', 'inprogress' => true, 'feedback' => true],
@@ -89,11 +89,12 @@ class formulation_and_controls_test extends advanced_testcase {
* @return array
*/
public function export_for_template_provider(): array {
global $CFG;
global $CFG, $OUTPUT;
require_once($CFG->dirroot . '/question/type/ordering/question.php');
$success = "<i class=\"icon fa fa-check text-success fa-fw \" title=\"Correct\" role=\"img\" aria-label=\"Correct\"></i>";
$warning = "<i class=\"icon fa fa-check-square fa-fw \" title=\"Partially correct\" role=\"img\" aria-label=\"Partially correct\"></i>";
$error = "<i class=\"icon fa fa-remove text-danger fa-fw \" title=\"Incorrect\" role=\"img\" aria-label=\"Incorrect\"></i>";
$correct = $OUTPUT->pix_icon('i/grade_correct', get_string('correct', 'question'));
$partiallycorrect = $OUTPUT->pix_icon('i/grade_partiallycorrect', get_string('partiallycorrect', 'question'));
$incorrect = $OUTPUT->pix_icon('i/grade_incorrect', get_string('incorrect', 'question'));
return [
'Horizontal, correct and partially correct' => [
@@ -117,12 +118,42 @@ class formulation_and_controls_test extends advanced_testcase {
'active' => false,
'sortableid' => 'id_sortable_0',
'answers' => [
['scoreclass' => 'correct', 'id' => 'ordering_item_' . md5('Modular'), 'answertext' => "Modular", 'feedbackimage' => $success],
['scoreclass' => 'correct', 'id' => 'ordering_item_' . md5('Object'), 'answertext' => "Object", 'feedbackimage' => $success],
['scoreclass' => 'correct', 'id' => 'ordering_item_' . md5('Oriented'), 'answertext' => "Oriented", 'feedbackimage' => $success],
['scoreclass' => 'partial66', 'id' => 'ordering_item_' . md5('Learning'), 'answertext' => "Learning", 'feedbackimage' => $warning],
['scoreclass' => 'partial66', 'id' => 'ordering_item_' . md5('Dynamic'), 'answertext' => "Dynamic", 'feedbackimage' => $warning],
['scoreclass' => 'correct', 'id' => 'ordering_item_' . md5('Environment'), 'answertext' => "Environment", 'feedbackimage' => $success],
[
'scoreclass' => 'correct',
'id' => 'ordering_item_' . md5('Modular'),
'answertext' => "Modular",
'feedbackimage' => $correct,
],
[
'scoreclass' => 'correct',
'id' => 'ordering_item_' . md5('Object'),
'answertext' => "Object",
'feedbackimage' => $correct,
],
[
'scoreclass' => 'correct',
'id' => 'ordering_item_' . md5('Oriented'),
'answertext' => "Oriented",
'feedbackimage' => $correct,
],
[
'scoreclass' => 'partial66',
'id' => 'ordering_item_' . md5('Learning'),
'answertext' => "Learning",
'feedbackimage' => $partiallycorrect,
],
[
'scoreclass' => 'partial66',
'id' => 'ordering_item_' . md5('Dynamic'),
'answertext' => "Dynamic",
'feedbackimage' => $partiallycorrect,
],
[
'scoreclass' => 'correct',
'id' => 'ordering_item_' . md5('Environment'),
'answertext' => "Environment",
'feedbackimage' => $correct,
],
],
],
],
@@ -147,12 +178,42 @@ class formulation_and_controls_test extends advanced_testcase {
'active' => false,
'sortableid' => 'id_sortable_0',
'answers' => [
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Object'), 'answertext' => "Object", 'feedbackimage' => $error],
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Dynamic'), 'answertext' => "Dynamic", 'feedbackimage' => $error],
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Modular'), 'answertext' => "Modular", 'feedbackimage' => $error],
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Learning'), 'answertext' => "Learning", 'feedbackimage' => $error],
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Environment'), 'answertext' => "Environment", 'feedbackimage' => $error],
['scoreclass' => 'incorrect', 'id' => 'ordering_item_' . md5('Oriented'), 'answertext' => "Oriented", 'feedbackimage' => $error],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Object'),
'answertext' => "Object",
'feedbackimage' => $incorrect,
],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Dynamic'),
'answertext' => "Dynamic",
'feedbackimage' => $incorrect,
],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Modular'),
'answertext' => "Modular",
'feedbackimage' => $incorrect,
],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Learning'),
'answertext' => "Learning",
'feedbackimage' => $incorrect,
],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Environment'),
'answertext' => "Environment",
'feedbackimage' => $incorrect,
],
[
'scoreclass' => 'incorrect',
'id' => 'ordering_item_' . md5('Oriented'),
'answertext' => "Oriented",
'feedbackimage' => $incorrect,
],
],
],
],
@@ -48,7 +48,8 @@ class specific_grade_detail_feedback_test extends advanced_testcase {
* @return void
* @covers ::export_for_template
*/
public function test_export_for_template(array $answeritems, int $gradingtype, string $layouttype, array $expected, int $selecttype): void {
public function test_export_for_template(array $answeritems, int $gradingtype, string $layouttype, array $expected,
int $selecttype): void {
global $PAGE;
$this->resetAfterTest();
$question = test_question_maker::make_question('ordering');
@@ -253,7 +253,7 @@ class questiontype_test extends \question_testcase {
public function test_xml_import(): void {
$this->resetAfterTest();
// Import a question from XML
// Import a question from XML.
$xml = file_get_contents(__DIR__ . '/fixtures/testimport.moodle.xml');
$xmldata = xmlize($xml);
$format = new \qformat_xml();
@@ -265,7 +265,7 @@ class questiontype_test extends \question_testcase {
public function test_xml_import_empty(): void {
$this->resetAfterTest();
// Import a question from XML
// Import a question from XML.
$xml = file_get_contents(__DIR__ . '/fixtures/testimportempty.moodle.xml');
$xmldata = xmlize($xml);
$format = new \qformat_xml();
@@ -279,7 +279,7 @@ class questiontype_test extends \question_testcase {
public function test_xml_import_long(): void {
$this->resetAfterTest();
// Import a question from XML
// Import a question from XML.
$xml = file_get_contents(__DIR__ . '/fixtures/testimportlong.moodle.xml');
$xmldata = xmlize($xml);
$format = new \qformat_xml();
@@ -317,7 +317,7 @@ class questiontype_test extends \question_testcase {
public function test_gift_import(): void {
$this->resetAfterTest();
// Import a question from GIFT
// Import a question from GIFT.
$gift = file_get_contents(__DIR__ . '/fixtures/testimport.gift.txt');
$format = new qformat_gift();
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));