MDL-79863 qtype_ordering: Code checker & behat
Part of: MDL-79863
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user