From ba25bee79f055c762716c632c1b7e5a85c9b3013 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 9 May 2016 12:51:41 +0200 Subject: [PATCH] TemplateProcessing is now more robust. --- .../runtime/tests/AssessmentItemSession.php | 11 ++- src/qtism/runtime/tests/SessionManager.php | 6 +- .../binary/TemporaryQtiBinaryStorageTest.php | 84 +++++++++++++------ .../AssessmentTestSessionTemplatesTest.php | 2 +- ...e.xml => template_default_test_simple.xml} | 0 5 files changed, 73 insertions(+), 30 deletions(-) rename test/samples/custom/runtime/templates/{template_test_simple.xml => template_default_test_simple.xml} (100%) diff --git a/src/qtism/runtime/tests/AssessmentItemSession.php b/src/qtism/runtime/tests/AssessmentItemSession.php index 17bf579e2..634824df3 100644 --- a/src/qtism/runtime/tests/AssessmentItemSession.php +++ b/src/qtism/runtime/tests/AssessmentItemSession.php @@ -643,7 +643,9 @@ public function beginItemSession() $templateProcessing = $this->templateProcessing(); } - // Apply default values of outcomes variables. + // Apply default values of outcomes variables. We do it at this stage + // as templateProcessing could have change the default value of some + // Outcome Variables. $this->resetOutcomeVariables(); // The session gets the INITIAL state, ready for a first attempt, and @@ -1343,6 +1345,13 @@ public function templateProcessing() $templateProcessingEngine = new TemplateProcessingEngine($templateProcessing, $this); $templateProcessingEngine->process(); + if ($this->mustAutoTemplateProcessing() === false) { + // Apply default values of outcomes variables. We do it at this stage + // as templateProcessing could have change the default value of some + // Outcome Variables. + $this->resetOutcomeVariables(); + } + return true; } else { diff --git a/src/qtism/runtime/tests/SessionManager.php b/src/qtism/runtime/tests/SessionManager.php index df396316b..ec8025204 100644 --- a/src/qtism/runtime/tests/SessionManager.php +++ b/src/qtism/runtime/tests/SessionManager.php @@ -26,7 +26,7 @@ use qtism\data\IAssessmentItem; /** - * An SessionManager implementation that creates default AssessmentTestSession and + * A SessionManager implementation that creates default AssessmentTestSession and * AssessmentItemSession objects. * * @author Jérôme Bogaerts @@ -56,6 +56,8 @@ protected function instantiateAssessmentTestSession(AssessmentTest $test, Route */ protected function instantiateAssessmentItemSession(IAssessmentItem $assessmentItem, $navigationMode, $submissionMode) { - return new AssessmentItemSession($assessmentItem, $navigationMode, $submissionMode); + // When instantiating an AssessmentItemSession for a test, template processing must not occur automatically. + // is always false. + return new AssessmentItemSession($assessmentItem, $navigationMode, $submissionMode, false); } } diff --git a/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php b/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php index ae34253b3..735c97536 100644 --- a/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php +++ b/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php @@ -700,12 +700,14 @@ public function testTemplateProcessingBasic1() { $QTPL1Sessions = $session->getAssessmentItemSessions('QTPL1'); $QTPL1Session = $QTPL1Sessions[0]; - // The default values should be correctly initialized within their respective item sessions... + // The GOODSCORE and WRONGSCORE variable values should not have changed yet. Indeed, + // we are in a linear test part. In such a context, template processing occurs + // just prior the first attempt. $this->assertEquals(AssessmentItemSessionState::INITIAL, $QTPL1Session->getState()); - $this->assertEquals(1.0, $QTPL1Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(0.0, $QTPL1Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(1.0, $session['QTPL1.GOODSCORE']->getValue()); - $this->assertEquals(1.0, $QTPL1Session['GOODSCORE']->getValue()); + $this->assertNull($QTPL1Session->getVariable('GOODSCORE')->getDefaultValue()); + $this->assertNull($QTPL1Session->getVariable('WRONGSCORE')->getDefaultValue()); + $this->assertEquals(0.0, $session['QTPL1.GOODSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL1Session['GOODSCORE']->getValue()); $this->assertEquals(0.0, $session['QTPL1.WRONGSCORE']->getValue()); $this->assertEquals(0.0, $QTPL1Session['WRONGSCORE']->getValue()); @@ -713,25 +715,28 @@ public function testTemplateProcessingBasic1() { $QTPL2Session = $QTPL2Sessions[0]; $this->assertEquals(AssessmentItemSessionState::INITIAL, $QTPL2Session->getState()); - $this->assertEquals(2.0, $QTPL2Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(-1.0, $QTPL2Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(2.0, $session['QTPL2.GOODSCORE']->getValue()); - $this->assertEquals(2.0, $QTPL2Session['GOODSCORE']->getValue()); - $this->assertEquals(-1.0, $session['QTPL2.WRONGSCORE']->getValue()); - $this->assertEquals(-1.0, $QTPL2Session['WRONGSCORE']->getValue()); + $this->assertNull($QTPL2Session->getVariable('GOODSCORE')->getDefaultValue()); + $this->assertNull($QTPL2Session->getVariable('WRONGSCORE')->getDefaultValue()); + $this->assertEquals(0.0, $session['QTPL2.GOODSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL2Session['GOODSCORE']->getValue()); + $this->assertEquals(0.0, $session['QTPL2.WRONGSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL2Session['WRONGSCORE']->getValue()); // Now let's make sure the persistence works correctly when templating is in force... - // We do this by testing again that default values are correctly initialized within their respective - // item sessions... + // We do this by testing again that default values and values are stil the same after + // persistence. $storage->persist($session); unset($session); $session = $storage->retrieve($test, $sessionId); + $QTPL1Sessions = $session->getAssessmentItemSessions('QTPL1'); + $QTPL1Session = $QTPL1Sessions[0]; + $this->assertEquals(AssessmentItemSessionState::INITIAL, $QTPL1Session->getState()); - $this->assertEquals(1.0, $QTPL1Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(0.0, $QTPL1Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(1.0, $session['QTPL1.GOODSCORE']->getValue()); - $this->assertEquals(1.0, $QTPL1Session['GOODSCORE']->getValue()); + $this->assertNull($QTPL1Session->getVariable('GOODSCORE')->getDefaultValue()); + $this->assertNull($QTPL1Session->getVariable('WRONGSCORE')->getDefaultValue()); + $this->assertEquals(0.0, $session['QTPL1.GOODSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL1Session['GOODSCORE']->getValue()); $this->assertEquals(0.0, $session['QTPL1.WRONGSCORE']->getValue()); $this->assertEquals(0.0, $QTPL1Session['WRONGSCORE']->getValue()); @@ -739,15 +744,30 @@ public function testTemplateProcessingBasic1() { $QTPL2Session = $QTPL2Sessions[0]; $this->assertEquals(AssessmentItemSessionState::INITIAL, $QTPL2Session->getState()); - $this->assertEquals(2.0, $QTPL2Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(-1.0, $QTPL2Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); - $this->assertEquals(2.0, $session['QTPL2.GOODSCORE']->getValue()); - $this->assertEquals(2.0, $QTPL2Session['GOODSCORE']->getValue()); - $this->assertEquals(-1.0, $session['QTPL2.WRONGSCORE']->getValue()); - $this->assertEquals(-1.0, $QTPL2Session['WRONGSCORE']->getValue()); - - // It seems to be ok! Let's take the test! + $this->assertNull($QTPL2Session->getVariable('GOODSCORE')->getDefaultValue()); + $this->assertNull($QTPL2Session->getVariable('WRONGSCORE')->getDefaultValue()); + $this->assertEquals(0.0, $session['QTPL2.GOODSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL2Session['GOODSCORE']->getValue()); + $this->assertEquals(0.0, $session['QTPL2.WRONGSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL2Session['WRONGSCORE']->getValue()); + + // It seems to be ok! Let's take the test! By beginning the first attempt, + // template processing is applied on QTPL1. However, anything related to QTPL2 should not + // have changed. $session->beginAttempt(); + + // Let's check the values. Q01 should be affected by template processing, QTPL2 should not. + $QTPL1Sessions = $session->getAssessmentItemSessions('QTPL1'); + $QTPL1Session = $QTPL1Sessions[0]; + + $this->assertEquals(AssessmentItemSessionState::INTERACTING, $QTPL1Session->getState()); + $this->assertEquals(1.0, $QTPL1Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); + $this->assertEquals(0.0, $QTPL1Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); + $this->assertEquals(1.0, $session['QTPL1.GOODSCORE']->getValue()); + $this->assertEquals(1.0, $QTPL1Session['GOODSCORE']->getValue()); + $this->assertEquals(0.0, $session['QTPL1.WRONGSCORE']->getValue()); + $this->assertEquals(0.0, $QTPL1Session['WRONGSCORE']->getValue()); + // TPL1's responses should be applied their default values if any at the // beginning of the first attempt. $this->assertEquals('ChoiceB', $session['QTPL1.RESPONSE']->getValue()); @@ -784,6 +804,18 @@ public function testTemplateProcessingBasic1() { // -- TPL2 - Correct response. $session->beginAttempt(); + // QTPL2 should now be affected by Templat eProcessing. + $QTPL2Sessions = $session->getAssessmentItemSessions('QTPL2'); + $QTPL2Session = $QTPL2Sessions[0]; + + $this->assertEquals(AssessmentItemSessionState::INTERACTING, $QTPL2Session->getState()); + $this->assertEquals(2.0, $QTPL2Session->getVariable('GOODSCORE')->getDefaultValue()->getValue()); + $this->assertEquals(-1.0, $QTPL2Session->getVariable('WRONGSCORE')->getDefaultValue()->getValue()); + $this->assertEquals(2.0, $session['QTPL2.GOODSCORE']->getValue()); + $this->assertEquals(2.0, $QTPL2Session['GOODSCORE']->getValue()); + $this->assertEquals(-1.0, $session['QTPL2.WRONGSCORE']->getValue()); + $this->assertEquals(-1.0, $QTPL2Session['WRONGSCORE']->getValue()); + // TPL2's responses should be at their default values if any at // the beginning of the first attempt. $this->assertEquals('ChoiceA', $session['QTPL2.RESPONSE']->getValue()); @@ -826,7 +858,7 @@ public function testTemplateProcessingBasic1() { public function testTemplateDefault1() { $doc = new XmlCompactDocument(); - $doc->load(self::samplesDir() . 'custom/runtime/templates/template_test_simple.xml'); + $doc->load(self::samplesDir() . 'custom/runtime/templates/template_default_test_simple.xml'); $test = $doc->getDocumentComponent(); $sessionManager = new SessionManager($doc->getDocumentComponent()); diff --git a/test/qtismtest/runtime/tests/AssessmentTestSessionTemplatesTest.php b/test/qtismtest/runtime/tests/AssessmentTestSessionTemplatesTest.php index 9f25c8f07..37167971c 100644 --- a/test/qtismtest/runtime/tests/AssessmentTestSessionTemplatesTest.php +++ b/test/qtismtest/runtime/tests/AssessmentTestSessionTemplatesTest.php @@ -13,7 +13,7 @@ class AssessmentTestSessionTemplatesTest extends QtiSmAssessmentTestSessionTestCase { public function testSimpleTemplating() { - $session = self::instantiate(self::samplesDir() . 'custom/runtime/templates/template_test_simple.xml'); + $session = self::instantiate(self::samplesDir() . 'custom/runtime/templates/template_default_test_simple.xml'); $session->beginTestSession(); // We are in linear mode with no branching/preconditions, so the sessions are alive... // But the templateDefaults/templateProcessings will only occur at the beginning of the diff --git a/test/samples/custom/runtime/templates/template_test_simple.xml b/test/samples/custom/runtime/templates/template_default_test_simple.xml similarity index 100% rename from test/samples/custom/runtime/templates/template_test_simple.xml rename to test/samples/custom/runtime/templates/template_default_test_simple.xml