MDL-53140 qtype_numerical: Support locale-aware decimal points
authorShamim Rezaie <shamim@moodle.com>
Mon, 4 Feb 2019 19:39:43 +0000 (06:39 +1100)
committerShamim Rezaie <shamim@moodle.com>
Wed, 1 May 2019 02:10:32 +0000 (12:10 +1000)
question/type/numerical/edit_numerical_form.php
question/type/numerical/tests/behat/add.feature [new file with mode: 0644]
question/type/numerical/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/numerical/tests/behat/edit.feature [new file with mode: 0644]
question/type/numerical/tests/behat/export.feature [new file with mode: 0644]
question/type/numerical/tests/behat/import.feature [new file with mode: 0644]
question/type/numerical/tests/behat/preview.feature [new file with mode: 0644]
question/type/numerical/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]

index 8802761..ef71376 100644 (file)
@@ -57,9 +57,8 @@ class qtype_numerical_edit_form extends question_edit_form {
         $repeated = parent::get_per_answer_fields($mform, $label, $gradeoptions,
                 $repeatedoptions, $answersoption);
 
-        $tolerance = $mform->createElement('text', 'tolerance',
+        $tolerance = $mform->createElement('float', 'tolerance',
                 get_string('answererror', 'qtype_numerical'), array('size' => 15));
-        $repeatedoptions['tolerance']['type'] = PARAM_FLOAT;
         $repeatedoptions['tolerance']['default'] = 0;
         $elements = $repeated[0]->getElements();
         $elements[0]->setSize(15);
@@ -91,9 +90,8 @@ class qtype_numerical_edit_form extends question_edit_form {
                 get_string('unithandling', 'qtype_numerical'), $unitoptions);
 
         $penaltygrp = array();
-        $penaltygrp[] = $mform->createElement('text', 'unitpenalty',
+        $penaltygrp[] = $mform->createElement('float', 'unitpenalty',
                 get_string('unitpenalty', 'qtype_numerical'), array('size' => 6));
-        $mform->setType('unitpenalty', PARAM_FLOAT);
         $mform->setDefault('unitpenalty', 0.1000000);
 
         $unitgradingtypes = array(
@@ -148,7 +146,6 @@ class qtype_numerical_edit_form extends question_edit_form {
         $repeatedoptions['unit']['disabledif'] = array('unitrole', 'eq', qtype_numerical::UNITNONE);
         $repeatedoptions['unit']['type'] = PARAM_NOTAGS;
         $repeatedoptions['multiplier']['disabledif'] = array('unitrole', 'eq', qtype_numerical::UNITNONE);
-        $repeatedoptions['multiplier']['type'] = PARAM_NUMBER;
 
         $mform->disabledIf('addunits', 'unitrole', 'eq', qtype_numerical::UNITNONE);
 
@@ -186,7 +183,7 @@ class qtype_numerical_edit_form extends question_edit_form {
     protected function unit_group($mform) {
         $grouparray = array();
         $grouparray[] = $mform->createElement('text', 'unit', get_string('unit', 'qtype_numerical'), array('size'=>10));
-        $grouparray[] = $mform->createElement('text', 'multiplier',
+        $grouparray[] = $mform->createElement('float', 'multiplier',
                 get_string('multiplier', 'qtype_numerical'), array('size'=>10));
 
         return $grouparray;
@@ -291,7 +288,7 @@ class qtype_numerical_edit_form extends question_edit_form {
                 if ($data['fraction'][$key] == 1) {
                     $maxgrade = true;
                 }
-                if ($answer !== '*' && !is_numeric($data['tolerance'][$key])) {
+                if ($answer !== '*' && $data['tolerance'][$key] === false) {
                     $errors['answeroptions['.$key.']'] =
                             get_string('xmustbenumeric', 'qtype_numerical',
                                 get_string('acceptederror', 'qtype_numerical'));
@@ -361,7 +358,7 @@ class qtype_numerical_edit_form extends question_edit_form {
             if (empty($trimmedmultiplier)) {
                 $errors['units[' . $key . ']'] =
                         get_string('youmustenteramultiplierhere', 'qtype_numerical');
-            } else if (!is_numeric($trimmedmultiplier)) {
+            } else if ($trimmedmultiplier === false) {
                 $errors['units[' . $key . ']'] =
                         get_string('xmustbenumeric', 'qtype_numerical',
                             get_string('multiplier', 'qtype_numerical'));
diff --git a/question/type/numerical/tests/behat/add.feature b/question/type/numerical/tests/behat/add.feature
new file mode 100644 (file)
index 0000000..8133a89
--- /dev/null
@@ -0,0 +1,39 @@
+@qtype @qtype_numerical
+Feature: Test creating a Numerical question
+  As a teacher
+  In order to test my students
+  I need to be able to create a Numerical question
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email               |
+      | teacher1 | T1        | Teacher1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And the following "language customisations" exist:
+      | component       | stringid | value |
+      | core_langconfig | decsep   | #     |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "Question bank" in current page administration
+
+  Scenario: Create a Numerical question
+    When I add a "Numerical" question filling the form with:
+      | Question name                      | Numerical-001                          |
+      | Question text                      | What is the average of 4, 5, 6 and 10? |
+      | Default mark                       | 1                                      |
+      | General feedback                   | The average is 6.25                    |
+      | id_answer_0                        | 6.25                                   |
+      | id_tolerance_0                     | 0.05                                   |
+      | id_fraction_0                      | 100%                                   |
+      | id_answer_1                        | 2#25                                   |
+      | id_tolerance_1                     | 0#05                                   |
+      | id_fraction_1                      | 0%                                     |
+      | id_answer_2                        | 5,1                                    |
+      | id_tolerance_2                     | 0                                      |
+      | id_fraction_2                      | 100%                                   |
+    Then I should see "Numerical-001"
diff --git a/question/type/numerical/tests/behat/backup_and_restore.feature b/question/type/numerical/tests/behat/backup_and_restore.feature
new file mode 100644 (file)
index 0000000..faac89a
--- /dev/null
@@ -0,0 +1,57 @@
+@qtype @qtype_numerical
+Feature: Test duplicating a quiz containing a Numerical question
+  As a teacher
+  In order re-use my courses containing Numerical questions
+  I need to be able to backup and restore them
+
+  Background:
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "question categories" exist:
+      | contextlevel | reference | name           |
+      | Course       | C1        | Test questions |
+    And the following "questions" exist:
+      | questioncategory | qtype     | name          | template    |
+      | Test questions   | numerical | Numerical-001 | pi          |
+    And the following "activities" exist:
+      | activity   | name      | course | idnumber |
+      | quiz       | Test quiz | C1     | quiz1    |
+    And quiz "Test quiz" contains the following questions:
+      | Numerical-001 | 1 |
+    And I log in as "admin"
+    And I am on "Course 1" course homepage
+
+  @javascript
+  Scenario: Backup and restore a course containing a Numerical question
+    When I backup "Course 1" course using this options:
+      | Confirmation | Filename | test_backup.mbz |
+    And I restore "test_backup.mbz" backup into a new course using this options:
+      | Schema | Course name | Course 2 |
+    And I navigate to "Question bank" in current page administration
+    And I click on "Edit" "link" in the "Numerical-001" "table_row"
+    Then the following fields match these values:
+      | Question name                      | Numerical-001                              |
+      | Question text                      | What is pi to two d.p.?                    |
+      | General feedback                   | Generalfeedback: 3.14 is the right answer. |
+      | Default mark                       | 1                                          |
+      | id_answer_0                        | 3.14                                       |
+      | id_tolerance_0                     | 0                                          |
+      | id_fraction_0                      | 100%                                       |
+      | id_feedback_0                      | Very good.                                 |
+      | id_answer_1                        | 3.142                                      |
+      | id_tolerance_1                     | 0                                          |
+      | id_fraction_1                      | None                                       |
+      | id_feedback_1                      | Too accurate.                              |
+      | id_answer_2                        | 3.1                                        |
+      | id_tolerance_2                     | 0                                          |
+      | id_fraction_2                      | None                                       |
+      | id_feedback_2                      | Not accurate enough.                       |
+      | id_answer_3                        | 3                                          |
+      | id_tolerance_3                     | 0                                          |
+      | id_fraction_3                      | None                                       |
+      | id_feedback_3                      | Not accurate enough.                       |
+      | id_answer_4                        | *                                          |
+      | id_tolerance_4                     | 0                                          |
+      | id_fraction_4                      | None                                       |
+      | id_feedback_4                      | Completely wrong.                          |
diff --git a/question/type/numerical/tests/behat/edit.feature b/question/type/numerical/tests/behat/edit.feature
new file mode 100644 (file)
index 0000000..5343510
--- /dev/null
@@ -0,0 +1,49 @@
+@qtype @qtype_numerical
+Feature: Test editing a Numerical question
+  As a teacher
+  In order to be able to update my Numerical question
+  I need to edit them
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | T1        | Teacher1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And the following "question categories" exist:
+      | contextlevel | reference | name           |
+      | Course       | C1        | Test questions |
+    And the following "questions" exist:
+      | questioncategory | qtype     | name                  | template |
+      | Test questions   | numerical | Numerical for editing | pi |
+    And the following "language customisations" exist:
+      | component       | stringid | value |
+      | core_langconfig | decsep   | #     |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "Question bank" in current page administration
+
+  Scenario: Edit a Numerical question
+    When I click on "Edit" "link" in the "Numerical for editing" "table_row"
+    Then the field "id_answer_0" matches value "3#14"
+    When I set the following fields to these values:
+      | Question name | |
+    And I press "id_submitbutton"
+    Then I should see "You must supply a value here."
+    When I set the following fields to these values:
+      | Question name | Edited Numerical name |
+    And I press "id_submitbutton"
+    Then I should see "Edited Numerical name"
+    When I click on "Edit" "link" in the "Edited Numerical name" "table_row"
+    And I set the following fields to these values:
+      | id_answer_1    | 3#141592 |
+      | id_tolerance_1 | 0#005    |
+      | id_answer_2    | 3.05     |
+      | id_tolerance_2 | 0.005    |
+      | id_answer_3    | 3,01     |
+    And I press "id_submitbutton"
+    Then I should see "Edited Numerical name"
diff --git a/question/type/numerical/tests/behat/export.feature b/question/type/numerical/tests/behat/export.feature
new file mode 100644 (file)
index 0000000..7d3f920
--- /dev/null
@@ -0,0 +1,36 @@
+@qtype @qtype_numerical
+Feature: Test exporting Numerical questions
+  As a teacher
+  In order to be able to reuse my Numerical questions
+  I need to export them
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | T1        | Teacher1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And the following "question categories" exist:
+      | contextlevel | reference | name           |
+      | Course       | C1        | Test questions |
+    And the following "questions" exist:
+      | questioncategory | qtype     | name          | template |
+      | Test questions   | numerical | Numerical-001 | pi       |
+      | Test questions   | numerical | Numerical-002 | pi3tries |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+
+  Scenario: Export a Numerical question
+    When I navigate to "Question bank > Export" in current page administration
+    And I set the field "id_format_xml" to "1"
+    And I press "Export questions to file"
+    Then following "click here" should download between "3650" and "3750" bytes
+    # If the download step is the last in the scenario then we can sometimes run
+    # into the situation where the download page causes a http redirect but behat
+    # has already conducted its reset (generating an error). By putting a logout
+    # step we avoid behat doing the reset until we are off that page.
+    And I log out
diff --git a/question/type/numerical/tests/behat/import.feature b/question/type/numerical/tests/behat/import.feature
new file mode 100644 (file)
index 0000000..6995a63
--- /dev/null
@@ -0,0 +1,30 @@
+@qtype @qtype_numerical
+Feature: Test importing Numerical questions
+  As a teacher
+  In order to reuse Numerical questions
+  I need to import them
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | T1        | Teacher1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+
+  @javascript @_file_upload
+  Scenario: import Numerical question.
+    When I navigate to "Question bank > Import" in current page administration
+    And I set the field "id_format_xml" to "1"
+    And I upload "question/type/numerical/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
+    And I press "id_submitbutton"
+    Then I should see "Parsing questions from import file."
+    And I should see "Importing 1 questions from file"
+    And I should see "1. What is the average of 4, 5, 6 and 10?"
+    And I press "Continue"
+    And I should see "Numerical-001"
diff --git a/question/type/numerical/tests/behat/preview.feature b/question/type/numerical/tests/behat/preview.feature
new file mode 100644 (file)
index 0000000..c794d88
--- /dev/null
@@ -0,0 +1,51 @@
+@qtype @qtype_numerical
+Feature: Preview a Numerical question
+  As a teacher
+  In order to check my Numerical questions will work for students
+  I need to preview them
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | T1        | Teacher1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And the following "question categories" exist:
+      | contextlevel | reference | name           |
+      | Course       | C1        | Test questions |
+    And the following "questions" exist:
+      | questioncategory | qtype     | name          | template |
+      | Test questions   | numerical | Numerical-001 | pi       |
+      | Test questions   | numerical | Numerical-002 | pi3tries |
+    And the following "language customisations" exist:
+      | component       | stringid | value |
+      | core_langconfig | decsep   | #     |
+    Given I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I navigate to "Question bank" in current page administration
+
+  @javascript @_switch_window
+  Scenario: Preview a Numerical question and submit a correct response.
+    When I click on "Preview" "link" in the "Numerical-001" "table_row"
+    And I switch to "questionpreview" window
+    Then I should see "What is pi to two d.p.?"
+    When I set the field "How questions behave" to "Immediate feedback"
+    And I press "Start again with these options"
+    And I set the field with xpath "//span[@class='answer']//input[contains(@id, '1_answer')]" to "3.14"
+    And I press "Check"
+    Then I should see "Very good."
+    And I should see "Mark 1#00 out of 1#00"
+    When I press "Start again"
+    And I set the field with xpath "//span[@class='answer']//input[contains(@id, '1_answer')]" to "3,14"
+    And I press "Check"
+    Then I should see "Please enter your answer without using the thousand separator (,)."
+    When I press "Start again"
+    And I set the field with xpath "//span[@class='answer']//input[contains(@id, '1_answer')]" to "3#14"
+    And I press "Check"
+    Then I should see "Very good."
+    And I should see "Mark 1#00 out of 1#00"
+    And I switch to the main window
diff --git a/question/type/numerical/tests/fixtures/testquestion.moodle.xml b/question/type/numerical/tests/fixtures/testquestion.moodle.xml
new file mode 100644 (file)
index 0000000..7966cad
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<quiz>
+<!-- question: 0  -->
+  <question type="category">
+    <category>
+        <text>$course$/Default for C1</text>
+
+    </category>
+  </question>
+
+<!-- question: 115000  -->
+  <question type="numerical">
+    <name>
+      <text>Numerical-001</text>
+    </name>
+    <questiontext format="html">
+      <text>What is the average of 4, 5, 6 and 10?</text>
+    </questiontext>
+    <generalfeedback format="html">
+      <text>The average is 6.25</text>
+    </generalfeedback>
+    <defaultgrade>1.0000000</defaultgrade>
+    <penalty>0.3333333</penalty>
+    <answer fraction="100" format="html">
+      <text>6.25</text>
+      <feedback format="html">
+        <text></text>
+      </feedback>
+      <tolerance>0.05</tolerance>
+    </answer>
+    <hint format="html">
+      <text>First hint</text>
+    </hint>
+    <hint format="html">
+      <text>Second hint</text>
+    </hint>
+  </question>
+
+</quiz>