Skip to content

Commit

Permalink
Add allow_multiple_stdins option. Change to version 3.2.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
trampgeek committed Jul 10, 2017
1 parent bb472f1 commit bc3f344
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 9 deletions.
13 changes: 13 additions & 0 deletions changehistory.md
@@ -1,5 +1,18 @@
# CHANGE HISTORY

### 11 July 2017. Version 3.2.0

* Add allow_multiple_stdins option for advanced use of combinator templates.
This option disables the usual behaviour of running combinator templates
once for each test when any tests have standard input defined. When enabled
the combinator is given all testcases (as when standard input is not present)
and must itself manage the switching of standard inputs between tests.
* Incorporate style changes from Open University (thanks Mahmoud Kassaei) for
improved accessibility of the Ace editor.
* Disable the suppression of a regrade when the same answer is
submitted twice in succession. The suppression was introduced in
version 3.1.5 but has proved confusing for question authors.

### 5 July 2017. Version 3.1.5+

* Fix bug in display of "For example" table when question has customised
Expand Down
4 changes: 2 additions & 2 deletions classes/jobrunner.php
Expand Up @@ -82,7 +82,8 @@ public function run_tests($question, $code, $testcases, $isprecheck) {
'STUDENT' => new qtype_coderunner_student($USER)
);

if ($question->get_is_combinator() and $this->has_no_stdins()) {
if ($question->get_is_combinator() and
($this->has_no_stdins() || $question->allow_multiple_stdins())) {
$outcome = $this->run_combinator($isprecheck);
} else {
$outcome = null;
Expand All @@ -95,7 +96,6 @@ public function run_tests($question, $code, $testcases, $isprecheck) {
// a test result for each test case.

if ($outcome == null) {
assert (!($question->get_is_combinator() && $this->grader->name() == 'TemplateGrader'));
$outcome = $this->run_tests_singly($isprecheck);
}

Expand Down
3 changes: 2 additions & 1 deletion db/install.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="question/type/coderunner/db" VERSION="20161229" COMMENT="XMLDB file for Moodle question/type/coderunner"
<XMLDB PATH="question/type/coderunner/db" VERSION="20170711" COMMENT="XMLDB file for Moodle question/type/coderunner"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
Expand All @@ -25,6 +25,7 @@
<FIELD NAME="template" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The template for this question, expanded by Twig to yield the program to be executed."/>
<FIELD NAME="iscombinatortemplate" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="True iff the template is a combinator template, i.e. takes a list of test cases rather than a single one."/>
<FIELD NAME="combinatortemplate" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="DEFUNCT: An optional template to be used to combine all tests into a single run"/>
<FIELD NAME="allowmultiplestdins" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Normally, if tests each have their own stdin, the combinator is run once for each testcase (as it's then difficult to combine all tests into a single program). Setting this field to true results in the combinator being called once with all test cases present, as happens when there is no stdin."/>
<FIELD NAME="testsplitterre" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The regular expression argument to preg_split to split output from the combinator run into the basic tests again. Meaningful only if combinator template provided"/>
<FIELD NAME="pertesttemplate" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="DEFUNCT: A template to build a test run for each test case. Required."/>
<FIELD NAME="templateparams" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="A json-encoded record of extra parameters to pass to the template engine when building the source code to be executed."/>
Expand Down
15 changes: 15 additions & 0 deletions db/upgrade.php
Expand Up @@ -174,6 +174,21 @@ function xmldb_qtype_coderunner_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2016123001, 'qtype', 'coderunner');
}

if ($oldversion < 2017071100) {

// Define field allowmultiplestdins to be added to question_coderunner_options.
$table = new xmldb_table('question_coderunner_options');
$field = new xmldb_field('allowmultiplestdins', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'combinatortemplate');

// Conditionally launch add field allowmultiplestdins.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Coderunner savepoint reached.
upgrade_plugin_savepoint(true, 2017071100, 'qtype', 'coderunner');
}

require_once(__DIR__ . '/upgradelib.php');
update_question_types();

Expand Down
3 changes: 3 additions & 0 deletions edit_coderunner_form.php
Expand Up @@ -552,6 +552,8 @@ private function make_customisation_panel($mform) {
$templatecontrols = array();
$templatecontrols[] = $mform->createElement('advcheckbox', 'iscombinatortemplate', null,
get_string('iscombinatortemplate', 'qtype_coderunner'));
$templatecontrols[] = $mform->createElement('advcheckbox', 'allowmultiplestdins', null,
get_string('allowmultiplestdins', 'qtype_coderunner'));

$templatecontrols[] = $mform->createElement('text', 'testsplitterre',
get_string('testsplitterre', 'qtype_coderunner'),
Expand Down Expand Up @@ -647,6 +649,7 @@ private function make_advanced_customisation_panel($mform) {

$mform->disabledIf('typename', 'prototypetype', 'neq', '2');
$mform->disabledIf('testsplitterre', 'iscombinatortemplate', 'eq', 0);
$mform->disabledIf('allowmultiplestdins', 'iscombinatortemplate', 'eq', 0);
}

// UTILITY FUNCTIONS.
Expand Down
10 changes: 7 additions & 3 deletions lang/en/qtype_coderunner.php
Expand Up @@ -33,6 +33,7 @@
The per-test-case marks can be specified only if the all-or-nothing checkbox is unchecked.
If using a template grader that awards part marks to test cases, \'All-or-nothing\' should generally be unchecked.';
$string['allowmultiplestdins'] = 'Allow multiple stdins';
$string['answer'] = 'Sample answer';
$string['answerprompt'] = 'Answer:';
$string['answer_help'] = 'A sample answer can be entered here and used for checking by the question author and optionally shown to students during review. It is also used by the bulk tester script. The correctness of a non-empty answer is checked when saving unless \'Validate on save\' is unchecked';
Expand Down Expand Up @@ -487,13 +488,16 @@
However, if testcases have standard input defined, combinator templates become
problematic. If the template constructs a single program, what should the standard
input be? There is no simple answer to that question so in this case coderunner
runs the test cases one at a time, using the combinator template to build
input be? The simplest (and default) solution is to
run the test cases one at a time, using the combinator template to build
each program, passing it a TESTCASES variable containing just a single test.
This \'trick\' allows the combinator template to serve a dual role: it behaves
as a per-test-case template (with a 1-element TESTCASES array) when the question
author supplies standard input but as a proper combinator (with an n-element
TESTCASES array) otherwise.
TESTCASES array) otherwise. To change this behaviour so that the combinator
receives all testcases, even when stdin is present, check the \'Allow multiple
stdins\' checkbox.
If a run of the combinator program results in any output to stderr, that
is interpreted as a run error. To ensure the student gets credit for as many
Expand Down
6 changes: 6 additions & 0 deletions question.php
Expand Up @@ -308,6 +308,12 @@ public function get_is_combinator() {
return $this->iscombinatortemplate;
}


// Return whether or not multiple stdins are allowed when using combiantor
public function allow_multiple_stdins() {
return $this->allowmultiplestdins;
}

// Return an instance of the sandbox to be used to run code for this question.
public function get_sandbox() {
global $CFG;
Expand Down
1 change: 1 addition & 0 deletions questiontype.php
Expand Up @@ -95,6 +95,7 @@ public function extra_question_fields() {
'resultcolumns',
'template',
'iscombinatortemplate',
'allowmultiplestdins',
'answer',
'validateonsave',
'testsplitterre',
Expand Down
25 changes: 24 additions & 1 deletion tests/walkthrough_extras.php
Expand Up @@ -86,7 +86,7 @@ public function test_result_column_selection() {
* or misconfigured" exception.
*
* @expectedException qtype_coderunner_exception
* @expectedExceptionMessageRegExp |.*jobesandbox is down or misconfigured.*|
* @expectedExceptionMessageRegExp |.*Error from the sandbox.*may be down or overloaded.*|
* @retrun void
*/
public function test_misconfigured_jobe() {
Expand All @@ -96,6 +96,29 @@ public function test_misconfigured_jobe() {
set_config('jobe_host', 'localhostxxx', 'qtype_coderunner'); // Broken jobe_host url.
$q = test_question_maker::make_question('coderunner', 'sqr');
$this->start_attempt_at_question($q, 'adaptive', 1, 1);
$this->process_submission(array('-submit' => 1, 'answer' => "def sqr(n): return n * n\n"));
}

/** Check that a combinator template is run once per test case when stdin
* is present and allowmultiplestdins is false, but run with all test
* cases when allowmutliplestdins is true.
*/
public function test_multiplestdins() {
$q = test_question_maker::make_question('coderunner', 'sqr');
$q->testcases[0]->stdin = 'A bit of standard input to trigger one-at-a-time mode';
$q->showsource = true;

// Submit a right answer.
$this->start_attempt_at_question($q, 'adaptive', 1, 1);
$this->process_submission(array('-submit' => 1, 'answer' => "def sqr(n): return n * n\n"));
$this->check_output_contains('Run 4');

// Now turn on allowmultiplestdins and try again
$q->allowmultiplestdins = true;
$this->start_attempt_at_question($q, 'adaptive', 1, 1);
$this->process_submission(array('-submit' => 1, 'answer' => "def sqr(n): return n * n\n"));
$this->check_output_does_not_contain('Run 4');
}

}

4 changes: 2 additions & 2 deletions version.php
Expand Up @@ -22,12 +22,12 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2017052600;
$plugin->version = 2017071100;
$plugin->requires = 2015051100;
$plugin->cron = 0;
$plugin->component = 'qtype_coderunner';
$plugin->maturity = MATURITY_STABLE;
$plugin->release = '3.1.5';
$plugin->release = '3.1.6';

$plugin->dependencies = array(
'qbehaviour_adaptive_adapted_for_coderunner' => 2017052600
Expand Down

0 comments on commit bc3f344

Please sign in to comment.