Skip to content

Commit 52c7038

Browse files
committed
Merge branch 'dev' of https://github.com/maths/moodle-qtype_stack into iss1680
2 parents 68b2723 + 80f2324 commit 52c7038

145 files changed

Lines changed: 2079 additions & 951 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/moodle-ci.yml

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,29 @@ jobs:
3636
moodle-branch: 'main'
3737
database: 'pgsql'
3838
maxima: 'GCL'
39-
moodle-app: true
39+
moodle-app: false
4040
- php: '8.4'
41-
moodle-branch: 'MOODLE_501_STABLE'
41+
moodle-branch: 'MOODLE_502_STABLE'
4242
database: 'pgsql'
4343
maxima: 'SBCL'
44-
moodle-app: true
44+
moodle-app: false
4545
- php: '8.2'
4646
moodle-branch: 'MOODLE_500_STABLE'
4747
database: 'pgsql'
4848
maxima: 'SBCL'
49-
moodle-app: true
49+
moodle-app: false
5050
# Edinburgh is planning to run the setup below for 2025-26.
5151
- php: '8.2'
5252
moodle-branch: 'MOODLE_405_STABLE'
5353
database: 'mariadb'
5454
maxima: 'GCL'
55-
moodle-app: true
55+
moodle-app: false
5656
# Note, Moodle 4.2 will run on PHP 8.0, but we require PHP 8.1 or newer.
5757
- php: '8.1'
5858
moodle-branch: 'MOODLE_402_STABLE'
5959
database: 'pgsql'
6060
maxima: 'GCL'
61-
moodle-app: true
61+
moodle-app: false
6262

6363
steps:
6464
- name: Install Maxima (${{ matrix.maxima }})
@@ -151,10 +151,43 @@ jobs:
151151
env:
152152
DB: ${{ matrix.database }}
153153
MOODLE_BRANCH: ${{ matrix.moodle-branch }}
154-
MOODLE_APP: ${{ matrix.moodle-app }}
155154

156-
- name: Install moodle-plugin-ci (light unit tests)
157-
if: ${{ matrix.moodle-branch != 'main' }}
155+
- name: Install moodle-plugin-ci (light unit tests & moodle app)
156+
if: ${{ matrix.moodle-branch != 'main' && matrix.moodle-app == true}}
157+
run: |
158+
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfexplicitvaildate
159+
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfcbmexplicitvaildate
160+
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_adaptivemultipart
161+
moodle-plugin-ci add-plugin maths/moodle-qbank_importasversion
162+
163+
moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1
164+
165+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_MAXIMAVERSION", "5.42.2");'
166+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_MAXIMACOMMAND", "maxima");'
167+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_MAXIMACOMMANDOPT", "timeout --kill-after=10s 10s ${{ github.workspace }}/maxima_opt_auto -eval '\''(cl-user::run)'\''");'
168+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_MAXIMACOMMANDSERVER", "http://pool.home:8080/MaximaPool/MaximaPool");'
169+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_CASTIMEOUT", "100");'
170+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_MAXIMALIBRARIES", "stats, distrib, descriptive, simplex");'
171+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_CASPREPARSE", "true");'
172+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_PLATFORM", "linux-optimised");'
173+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_CASRESULTSCACHE", "db");'
174+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_PLOTCOMMAND", "");'
175+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_CASDEBUGGING", "0");'
176+
moodle-plugin-ci add-config 'define("QTYPE_STACK_TEST_CONFIG_CI_LIGHT", "1");'
177+
178+
#cat ${{ github.workspace }}/moodle/config.php
179+
180+
cp ${{ github.workspace }}/moodledata/phpu_moodledata/stack/maxima_opt_auto ${{ github.workspace }}/maxima_opt_auto
181+
# Try a command on the command line.
182+
# echo "1+1; quit();" | timeout --kill-after=100s 100s ${{ github.workspace }}/maxima_opt_auto -eval '(cl-user::run)'
183+
184+
env:
185+
DB: ${{ matrix.database }}
186+
MOODLE_BRANCH: ${{ matrix.moodle-branch }}
187+
MOODLE_APP: 'true'
188+
189+
- name: Install moodle-plugin-ci (light unit tests & no moodle app)
190+
if: ${{ matrix.moodle-branch != 'main' && matrix.moodle-app != true}}
158191
run: |
159192
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfexplicitvaildate
160193
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfcbmexplicitvaildate
@@ -185,51 +218,50 @@ jobs:
185218
env:
186219
DB: ${{ matrix.database }}
187220
MOODLE_BRANCH: ${{ matrix.moodle-branch }}
188-
MOODLE_APP: ${{ matrix.moodle-app }}
189221

190222
- name: PHP Lint
191-
if: ${{ matrix.moodle-branch == 'main' }}
223+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
192224
run: moodle-plugin-ci phplint
193225

194226
- name: PHP Copy/Paste Detector
195227
continue-on-error: true # This step will show errors but will not fail.
196-
if: ${{ matrix.moodle-branch == 'main' }}
228+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
197229
run: moodle-plugin-ci phpcpd
198230

199231
- name: PHP Mess Detector
200232
continue-on-error: true # This step will show errors but will not fail.
201-
if: ${{ matrix.moodle-branch == 'main' }}
233+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
202234
run: moodle-plugin-ci phpmd
203235

204236
- name: Moodle Code Checker
205237
continue-on-error: true # Currently fails. We really ought to get this passing.
206-
if: ${{ matrix.moodle-branch == 'main' }}
238+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
207239
run: moodle-plugin-ci codechecker --max-warnings 0
208240

209241
- name: Moodle PHPDoc Checker
210242
continue-on-error: true # Currently fails. We really ought to get this passing.
211-
if: ${{ matrix.moodle-branch == 'main' }}
243+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
212244
run: moodle-plugin-ci phpdoc
213245

214246
- name: Validating
215-
if: ${{ matrix.moodle-branch == 'main' }}
247+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
216248
run: moodle-plugin-ci validate
217249

218250
- name: Check upgrade savepoints
219-
if: ${{ matrix.moodle-branch == 'main' }}
251+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
220252
run: moodle-plugin-ci savepoints
221253

222254
- name: Mustache Lint
223-
if: ${{ matrix.moodle-branch == 'main' }}
255+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
224256
run: moodle-plugin-ci mustache
225257

226258
- name: Grunt
227-
if: ${{ matrix.moodle-branch == 'main' }}
259+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_502_STABLE'}}
228260
run: moodle-plugin-ci grunt
229261

230262
- name: PHPUnit tests
231-
#if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_405_STABLE'}}
232-
if: ${{ always() }}
263+
if: ${{ matrix.moodle-branch == 'main' || matrix.moodle-branch == 'MOODLE_405_STABLE'}}
264+
#if: ${{ always() }}
233265
run: moodle-plugin-ci phpunit
234266

235267
- name: Behat features

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# STACK 4.11.1
1+
# STACK 4.12.0
22

33
STACK is an assessment system for mathematics, science and related disciplines. STACK is a question type for the Moodle learning management system, and also the ILIAS learning management system. STACK has an API for stand-alone integration into other 3rd party systems.
44

api/config_sample.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ $CFG->inputmustverify = 1;
9595
$CFG->inputshowvalidation = 1;
9696

9797
// These should match the version of goemaxima in docker-compose.
98-
$CFG->stackmaximaversion = "2026010500";
99-
$CFG->version = "2026010500";
98+
$CFG->stackmaximaversion = "2026042200";
99+
$CFG->version = "2026042200";
100100

101101
// Do not change this setting.
102102
$CFG->mathsdisplay = 'api';

api/controller/RenderController.php

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,52 @@ public function __invoke(Request $request, Response $response, array $args): Res
163163
$feedbackprefix = trim($feedbackprefix);
164164
preg_match_all('/\[\[input:([^\]]*)\]\]/', $renderresponse->questionrender, $inputtags);
165165
foreach ($inputtags[1] as $tag) {
166-
$renderresponse->questionrender = str_replace("[[input:{$tag}]]", $renderresponse->questioninputs->$tag->render, $renderresponse->questionrender);
167-
$renderresponse->questionrender = str_replace("[[validation:{$tag}]]", "<span name='{$validationprefix}{$tag}'></span>", $renderresponse->questionrender);
166+
$renderresponse->questionrender = str_replace(
167+
"[[input:{$tag}]]",
168+
$renderresponse->questioninputs->$tag->render,
169+
$renderresponse->questionrender
170+
);
171+
$renderresponse->questionrender = str_replace(
172+
"[[validation:{$tag}]]",
173+
"<span name='{$validationprefix}{$tag}'></span>",
174+
$renderresponse->questionrender
175+
);
168176
}
169177
foreach ($renderresponse->iframes as $iframe) {
170178
$iframe[1] = str_replace('<head>', "<head><base href=\"{$baseurl}\" />", $iframe[1]);
171-
$renderediframe = "<iframe id=\"{$iframe[0]}\" style=\"width: 100%; height: 100%; border: 0;" . ($iframe[4] === 'false' ? ' overflow: hidden;' : '') . "\" scrolling=\"" . ($iframe[4] === 'false' ? 'no' : 'yes') . "\" title=\"{$iframe[4]}\" referrerpolicy=\"no-referrer\" " . (!$iframe[5] ? 'allow-scripts allow-downloads ' : '') . "srcdoc=\"" . htmlentities($iframe[1]) . "\"></iframe>";
172-
$renderresponse->questionrender = str_replace("id=\"{$iframe[2]}\"></div>", "id=\"{$iframe[2]}\">{$renderediframe}</div>", $renderresponse->questionrender);
173-
$renderresponse->questionsamplesolutiontext = str_replace("id=\"{$iframe[2]}\"></div>", "id=\"{$iframe[2]}\">{$renderediframe}</div>", $renderresponse->questionsamplesolutiontext);
179+
$renderediframe = "<iframe id=\"{$iframe[0]}\" style=\"width: 100%; height: 100%; border: 0;" .
180+
($iframe[4] === 'false' ? ' overflow: hidden;' : '') . "\" scrolling=\"" .
181+
($iframe[4] === 'false' ? 'no' : 'yes') .
182+
"\" title=\"{$iframe[4]}\" referrerpolicy=\"no-referrer\" " .
183+
(!$iframe[5] ? 'allow-scripts allow-downloads ' : '') .
184+
"srcdoc=\"" . htmlentities($iframe[1]) . "\"></iframe>";
185+
$renderresponse->questionrender = str_replace(
186+
"id=\"{$iframe[2]}\"></div>",
187+
"id=\"{$iframe[2]}\">{$renderediframe}</div>",
188+
$renderresponse->questionrender
189+
);
190+
$renderresponse->questionsamplesolutiontext = str_replace(
191+
"id=\"{$iframe[2]}\"></div>",
192+
"id=\"{$iframe[2]}\">{$renderediframe}</div>",
193+
$renderresponse->questionsamplesolutiontext
194+
);
174195
}
175196
foreach ($renderresponse->questionassets as $name => $file) {
176197
$renderresponse->questionrender = str_replace($name, "{$baseurl}/plots/{$file}", $renderresponse->questionrender);
177-
$renderresponse->questionsamplesolutiontext = str_replace($name, "{$baseurl}/plots/{$file}", $renderresponse->questionsamplesolutiontext);
198+
$renderresponse->questionsamplesolutiontext = str_replace(
199+
$name,
200+
"{$baseurl}/plots/{$file}",
201+
$renderresponse->questionsamplesolutiontext
202+
);
178203
foreach ($renderresponse->questioninputs as $input) {
179204
$input->samplesolutionrender = str_replace($name, "{$baseurl}/plots/{$file}", $input->samplesolutionrender);
180205
}
181206
}
182207
$renderresponse->questionrender = $this->replace_feedback_tags($renderresponse->questionrender, $feedbackprefix);
183-
$renderresponse->questionsamplesolutiontext = $this->replace_feedback_tags($renderresponse->questionsamplesolutiontext, $feedbackprefix);
208+
$renderresponse->questionsamplesolutiontext = $this->replace_feedback_tags(
209+
$renderresponse->questionsamplesolutiontext,
210+
$feedbackprefix
211+
);
184212
}
185213

186214
$response->getBody()->write(json_encode($renderresponse));

api/controller/TestController.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,13 @@ public function qtype_stack_test_question($question, $testcases, $seed = null) {
188188
// We could just check if score === 1 at this point but by creating
189189
// a test and running it we get the full outcomes in the same
190190
// format as above.
191-
$answernotes = $result->get_answernotes();
192-
$answernote = [end($answernotes)];
193191
$qtest->add_expected_result($prtname, new \stack_potentialresponse_tree_state(
194192
1,
195193
true,
196194
1,
197195
0,
198196
'',
199-
$answernote
197+
$result->get_answernotes_testcase()
200198
));
201199
}
202200
$results = $qtest->process_results($question, $response);

api/docker/docker-compose.dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: "4.0"
22
services:
33
maxima:
4-
image: mathinstitut/goemaxima:2026010500-latest
4+
image: mathinstitut/goemaxima:2026042200-latest
55
tmpfs:
66
- "/tmp"
77
restart: unless-stopped

api/docker/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: "4.0"
22
services:
33
maxima:
4-
image: mathinstitut/goemaxima:2026010500-latest
4+
image: mathinstitut/goemaxima:2026042200-latest
55
tmpfs:
66
- "/tmp"
77
restart: unless-stopped

cli/stack_maxima_compiler.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,12 @@ function comment_annotations(string $comment): array {
416416
false
417417
);
418418

419-
420419
$ast = null;
421420
try {
422421
$ast = $parser->parse($po->get_lexer($content));
423422
} catch (stack_maxima_parser_exception $e) {
424423
cli_error("PARSING FAIL: in $sname.");
425-
$ei = new stack_parser_error_interpreter($po);
424+
$ei = new stack_parser_error_interpreter($po);
426425
$result['exception'] = $e;
427426
$errors = [];
428427
$notes = [];
@@ -641,7 +640,7 @@ function comment_annotations(string $comment): array {
641640
$doc = '<!-- NOTE! This file is autogenerated from files under stack/maximasrc do not edit here. -->';
642641
$rootlink = str_repeat('../', substr_count($path, '/'));
643642

644-
$doc .= "\n# Section documentation for [STACK-Maxima]($rootlink) $path\n\n";
643+
$doc .= "\n# Section documentation for [STACK-Maxima]({$rootlink}index.md) $path\n\n";
645644

646645

647646
if ($node->description !== '') {

db/install.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
<FIELD NAME="prtname" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The name of the PRT for which these are the expected outcomes."/>
176176
<FIELD NAME="expectedscore" TYPE="number" LENGTH="12" NOTNULL="false" SEQUENCE="false" DECIMALS="7" COMMENT="The expected score."/>
177177
<FIELD NAME="expectedpenalty" TYPE="number" LENGTH="12" NOTNULL="false" SEQUENCE="false" DECIMALS="7" COMMENT="The expected penalty."/>
178-
<FIELD NAME="expectedanswernote" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The expected answer note."/>
178+
<FIELD NAME="expectedanswernote" TYPE="char" LENGTH="1023" NOTNULL="true" SEQUENCE="false" COMMENT="The expected answer note."/>
179179
</FIELDS>
180180
<KEYS>
181181
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>

db/upgrade.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,16 @@ function xmldb_qtype_stack_upgrade($oldversion) {
10351035
// STACK savepoint reached.
10361036
upgrade_plugin_savepoint(true, 2025042500, 'qtype', 'stack');
10371037
}
1038+
1039+
if ($oldversion < 2026042402) {
1040+
$table = new xmldb_table('qtype_stack_qtest_expected');
1041+
$field = new xmldb_field('expectedanswernote', XMLDB_TYPE_CHAR, '1023', null, XMLDB_NOTNULL, null, null, 'expectedpenalty');
1042+
1043+
$dbman->change_field_type($table, $field);
1044+
1045+
// STACK savepoint reached.
1046+
upgrade_plugin_savepoint(true, 2026042402, 'qtype', 'stack');
1047+
}
10381048
// Add new upgrade blocks just above here.
10391049

10401050
// Check the version of the Maxima library code that comes with this version

0 commit comments

Comments
 (0)