mirror of
https://github.com/moodle/moodle.git
synced 2025-01-29 11:46:19 +01:00
Merge branch 'MDL-21904' of git://github.com/jmvedrine/moodle
This commit is contained in:
commit
d08e28a3bb
@ -937,11 +937,15 @@ class qformat_default {
|
||||
}
|
||||
}
|
||||
|
||||
// export the question displaying message
|
||||
$count++;
|
||||
|
||||
// Add the question to result.
|
||||
if (!$checkcapabilities || question_has_capability_on($question, 'view')) {
|
||||
$expout .= $this->writequestion($question, $contextid) . "\n";
|
||||
$expquestion = $this->writequestion($question, $contextid);
|
||||
// Don't add anything if witequestion returned nothing.
|
||||
// This will permit qformat plugins to exclude some questions.
|
||||
if ($expquestion !== null) {
|
||||
$expout .= $expquestion . "\n";
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,10 @@ class qformat_aiken extends qformat_default {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function provide_export() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function readquestions($lines) {
|
||||
$questions = array();
|
||||
$question = null;
|
||||
@ -151,6 +155,49 @@ class qformat_aiken extends qformat_default {
|
||||
// This is no longer needed but might still be called by default.php.
|
||||
return;
|
||||
}
|
||||
|
||||
public function exportpreprocess() {
|
||||
// This format is not able to export categories.
|
||||
$this->setCattofile(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function writequestion($question) {
|
||||
$endchar = "\n";
|
||||
|
||||
// Only export multichoice questions.
|
||||
if ($question->qtype != 'multichoice') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Do not export multichoice multi questions.
|
||||
if (!$question->options->single) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Aiken format is not able to handle question with more than 26 answers.
|
||||
if (count($question->options->answers) > 26) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Export the question displaying message.
|
||||
$expout = str_replace("\n", '', question_utils::to_plain_text($question->questiontext,
|
||||
$question->questiontextformat, array('para' => false, 'newlines' => false))) . $endchar;
|
||||
$num = 0;
|
||||
foreach ($question->options->answers as $answer) {
|
||||
$number = chr(ord('A') + $num);
|
||||
$expout .= $number . ') ' . str_replace("\n", '', question_utils::to_plain_text($answer->answer,
|
||||
$answer->answerformat, array('para' => false, 'newlines' => false))) . $endchar;
|
||||
if ($answer->fraction > .99) {
|
||||
$correctanswer = $number;
|
||||
}
|
||||
$num++;
|
||||
}
|
||||
// Add the correct answer.
|
||||
$expout .= 'ANSWER: ' . $correctanswer;
|
||||
|
||||
return $expout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
36
question/format/aiken/tests/behat/aiken_export.feature
Normal file
36
question/format/aiken/tests/behat/aiken_export.feature
Normal file
@ -0,0 +1,36 @@
|
||||
@qformat @qformat_aiken
|
||||
Feature: Test exporting questions using Aiken format.
|
||||
In order to reuse questions
|
||||
As an teacher
|
||||
I need to be able to export them in Aiken format.
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | 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 | multichoice | Multi-choice-001 | two_of_four |
|
||||
| Test questions | multichoice | Multi-choice-002 | one_of_four |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
Scenario: Aiken export
|
||||
When I navigate to "Question bank > Export" in current page administration
|
||||
And I set the field "id_format_aiken" to "1"
|
||||
When I press "Export questions to file"
|
||||
Then following "click here" should download between "68" and "70" 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
|
30
question/format/aiken/tests/behat/aiken_import.feature
Normal file
30
question/format/aiken/tests/behat/aiken_import.feature
Normal file
@ -0,0 +1,30 @@
|
||||
@qformat @qformat_aiken
|
||||
Feature: Test importing questions from Aiken format.
|
||||
In order to reuse questions
|
||||
As an teacher
|
||||
I need to be able to import them in Aiken format.
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "users" exist:
|
||||
| username | firstname |
|
||||
| teacher | Teacher |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher | C1 | editingteacher |
|
||||
And I log in as "teacher"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@javascript @_file_upload
|
||||
Scenario: import some Aiken questions
|
||||
When I navigate to "Question bank > Import" in current page administration
|
||||
And I set the field "id_format_aiken" to "1"
|
||||
And I upload "question/format/aiken/tests/fixtures/questions.aiken.txt" file to "Import" filemanager
|
||||
And I press "id_submitbutton"
|
||||
Then I should see "Parsing questions from import file."
|
||||
And I should see "Importing 2 questions from file"
|
||||
And I should see "The Moodle project was started by:"
|
||||
And I press "Continue"
|
||||
And I should see "The Moodle project was started by:"
|
114
question/format/aiken/tests/qformat_aiken_export_test.php
Normal file
114
question/format/aiken/tests/qformat_aiken_export_test.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* Unit tests for export/import description (info) for question category in the Moodle XML format.
|
||||
*
|
||||
* @package qformat_aiken
|
||||
* @copyright 2018 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
require_once($CFG->dirroot . '/question/format.php');
|
||||
require_once($CFG->dirroot . '/question/format/aiken/format.php');
|
||||
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
||||
require_once($CFG->dirroot . '/question/editlib.php');
|
||||
|
||||
/**
|
||||
* Unit tests for the Aiken question format export.
|
||||
*
|
||||
* @copyright 2018 Jean-Michel vedrine)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qformat_aiken_export_test extends advanced_testcase {
|
||||
/**
|
||||
* Assert that 2 strings are the same, ignoring ends of line.
|
||||
* We need to override this function because we don't want any output
|
||||
* @param string $expectedtext The expected string.
|
||||
* @param string $text The actual string.
|
||||
*/
|
||||
public function assert_same_aiken($expectedtext, $text) {
|
||||
$this->assertEquals(str_replace("\r\n", "\n", $expectedtext),
|
||||
str_replace("\r\n", "\n", $text));
|
||||
}
|
||||
|
||||
public function test_export_questions() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
// Create a new course category and and a new course in that.
|
||||
$category = $this->getDataGenerator()->create_category();
|
||||
$course = $this->getDataGenerator()->create_course(array('category' => $category->id));
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
$context = context_coursecat::instance($category->id);
|
||||
$cat = $generator->create_question_category(array('contextid' => $context->id));
|
||||
$question1 = $generator->create_question('shortanswer', null,
|
||||
array('category' => $cat->id));
|
||||
$question2 = $generator->create_question('essay', null,
|
||||
array('category' => $cat->id));
|
||||
$question3 = $generator->create_question('numerical', null,
|
||||
array('category' => $cat->id));
|
||||
$question4 = $generator->create_question('multichoice', 'one_of_four',
|
||||
array('category' => $cat->id));
|
||||
$question4 = $generator->create_question('multichoice', 'two_of_four',
|
||||
array('category' => $cat->id));
|
||||
$exporter = new qformat_aiken();
|
||||
$exporter->category = $cat;
|
||||
$exporter->setCourse($course);
|
||||
$expectedoutput = <<<EOT
|
||||
Which is the oddest number?
|
||||
A) One
|
||||
B) Two
|
||||
C) Three
|
||||
D) Four
|
||||
ANSWER: A
|
||||
|
||||
EOT;
|
||||
$this->assert_same_aiken($expectedoutput, $exporter->exportprocess());
|
||||
}
|
||||
|
||||
public function test_export_multiline_question() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
// Create a new course category and and a new course in that.
|
||||
$category = $this->getDataGenerator()->create_category();
|
||||
$course = $this->getDataGenerator()->create_course(array('category' => $category->id));
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
$context = context_coursecat::instance($category->id);
|
||||
$cat = $generator->create_question_category(array('contextid' => $context->id));
|
||||
$question = $generator->create_question('multichoice', 'one_of_four',
|
||||
array('category' => $cat->id));
|
||||
$question->questiontext = <<<EOT
|
||||
<p>Which is the</p>
|
||||
<p>oddest number?</p>
|
||||
EOT;
|
||||
$exporter = new qformat_aiken();
|
||||
$exporter->category = $cat;
|
||||
$exporter->setCourse($course);
|
||||
$expectedoutput = <<<EOT
|
||||
Which is the oddest number?
|
||||
A) One
|
||||
B) Two
|
||||
C) Three
|
||||
D) Four
|
||||
ANSWER: A
|
||||
|
||||
EOT;
|
||||
$this->assert_same_aiken($expectedoutput, $exporter->exportprocess());
|
||||
}
|
||||
}
|
@ -7,6 +7,10 @@ qtype_numerical and qtype_multianswer plugins in the qtype_numerical_edit_form
|
||||
and qtype_multianswer_edit_form classes has been moved to a static function
|
||||
in the qtype_numerical class of the qtype_numerical plugin.
|
||||
|
||||
The exportprocess function of the qformat_default class doesn't output a blank line
|
||||
if the result of the writequestion function is null. This permit to qformat plugins
|
||||
to ignore some questions without the need to overwrite this function.
|
||||
|
||||
=== 3.5 ===
|
||||
|
||||
1) The question format exportprocess function now adds a
|
||||
|
Loading…
x
Reference in New Issue
Block a user