protected static function instantiate($url) { $doc = new XmlCompactDocument(); $doc->load($url); $manager = new SessionManager(); return $manager->createAssessmentTestSession($doc->getDocumentComponent()); }
public function setUp() { parent::setUp(); $testFilePath = self::samplesDir() . 'custom/runtime/itemsubset.xml'; $doc = new XmlCompactDocument(); $doc->load($testFilePath); $sessionManager = new SessionManager(); $testSession = $sessionManager->createAssessmentTestSession($doc->getDocumentComponent()); $testSession->beginTestSession(); $this->setTestSession($testSession); }
public function testParametricAssessmentTestSessionCreation() { $acceptableLatency = new Duration('PT5S'); $considerMinTime = false; $manager = new SessionManager(); $manager->setAcceptableLatency($acceptableLatency); $manager->setConsiderMinTime($considerMinTime); $session = $manager->createAssessmentTestSession($this->getTest()); $this->assertInstanceOf('qtism\\runtime\\tests\\AssessmentTestSession', $session); $this->assertFalse($session->mustConsiderMinTime()); $this->assertTrue($session->getAcceptableLatency()->equals(new Duration('PT5S')), 'The custom acceptable latency must be PT5S'); }
/** * Get the route (the way items are delivered into a test). * This method will compute the shuffling and other predefined conditions to take the test. * * @param string $testFilePath - the path of the QTI Test definition * @return array the test structure as it should be delivered. */ private function getRoute($testFilePath) { $route = array(); // Load the test definition. $testDefinition = new XmlDocument(); $testDefinition->load($testFilePath); // Make the test definition a compact one. Compact tests combine all needed // information to run a test instance. $resolver = new taoQtiTest_helpers_ItemResolver(); $compactTestDef = XmlCompactDocument::createFromXmlAssessmentTestDocument($testDefinition, $resolver); $sessionManager = new SessionManager(); $testSession = $sessionManager->createAssessmentTestSession($compactTestDef->getDocumentComponent()); $assessmentTest = $testSession->getAssessmentTest(); $renderingEngine = new XhtmlRenderingEngine(); $testPartId = null; $sectionId = null; //We are getting items with their respective test part and sections, so we need to restructure it foreach ($testSession->getRoute() as $routeItem) { $item = array('id' => $routeItem->getAssessmentItemRef()->getIdentifier(), 'href' => $routeItem->getAssessmentItemRef()->getHref()); $routeSections = $routeItem->getAssessmentSections()->getArrayCopy(); $lastSection = $routeSections[count($routeSections) - 1]; if ($sectionId != $lastSection->getIdentifier() || $testPartId != $routeItem->getTestPart()->getIdentifier()) { $sectionId = $lastSection->getIdentifier(); $rubricBlocks = array(); foreach ($routeItem->getAssessmentSections() as $section) { foreach ($section->getRubricBlocks() as $rubricBlock) { $xmlRendering = $renderingEngine->render($rubricBlock); $strRendering = $xmlRendering->saveXML($xmlRendering->documentElement); $finalRendering = ''; // No formatting at all :) ! foreach (preg_split('/\\n|\\r/u', $strRendering, -1, PREG_SPLIT_NO_EMPTY) as $line) { $finalRendering .= trim($line); } $rubricBlocks[] = $finalRendering; } } $section = array('id' => $section->getIdentifier(), 'title' => $section->getTitle(), 'rubricBlock' => $rubricBlocks, 'items' => array($item)); if ($testPartId != $routeItem->getTestPart()->getIdentifier()) { $testPartId = $routeItem->getTestPart()->getIdentifier(); $route[] = array('id' => $testPartId, 'sections' => array($section)); } else { $route = $this->addSectionToRoute($route, $testPartId, $section); } } else { $route = $this->addItemToRoute($route, $testPartId, $sectionId, $item); } } return array('id' => $assessmentTest->getIdentifier(), 'title' => $assessmentTest->getTitle(), 'testParts' => $route); }
/** * @dataProvider branchingMultipleOccurencesProvider */ public function testBranchingMultipleOccurences($response, $expectedTarget, $occurence) { // This test aims at testing the possibility to jump // on a particular item ref occurence. $doc = new XmlCompactDocument('1.0'); $doc->load(self::samplesDir() . 'custom/runtime/branchings/branchings_multiple_occurences.xml'); $manager = new SessionManager(); $testSession = $manager->createAssessmentTestSession($doc->getDocumentComponent()); $testSession->beginTestSession(); $testSession->beginAttempt(); if (empty($response) === true) { $testSession->skip(); $testSession->moveNext(); } else { $testSession->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, $response)))); $testSession->moveNext(); } $this->assertEquals($expectedTarget, $testSession->getCurrentAssessmentItemRef()->getIdentifier()); $this->assertEquals($occurence, $testSession->getCurrentAssessmentItemRefOccurence()); }
public function testWritePendingResponses() { $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/itemsubset_simultaneous.xml'); $seeker = new AssessmentTestSeeker($doc->getDocumentComponent(), array('assessmentItemRef', 'assessmentSection', 'testPart', 'outcomeDeclaration', 'responseDeclaration', 'branchRule', 'preCondition')); $stream = new MemoryStream(); $stream->open(); $access = new QtiBinaryStreamAccess($stream, new FileSystemFileManager()); $factory = new SessionManager(); $session = $factory->createAssessmentTestSession($doc->getDocumentComponent()); $session->beginTestSession(); $session->beginAttempt(); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new QtiIdentifier('ChoiceB'))))); $store = $session->getPendingResponseStore(); $pendingResponses = $store->getPendingResponses($doc->getDocumentComponent()->getComponentByIdentifier('Q01')); $access->writePendingResponses($seeker, $pendingResponses); $stream->rewind(); $pendingResponses = $access->readPendingResponses($seeker); $state = $pendingResponses->getState(); $this->assertEquals('ChoiceB', $state['RESPONSE']->getValue()); $this->assertEquals('Q01', $pendingResponses->getAssessmentItemRef()->getIdentifier()); $this->assertEquals(0, $pendingResponses->getOccurence()); $this->assertInternalType('integer', $pendingResponses->getOccurence()); }
public function testEmptySection() { // Aims at testing that even a section of the test is empty, // it is simply ignored at runtime. $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/empty_section.xml'); $manager = new SessionManager(); $session = $manager->createAssessmentTestSession($doc->getDocumentComponent()); $session->beginTestSession(); // First section contains a single item. $this->assertEquals('Q01', $session->getCurrentAssessmentItemRef()->getIdentifier()); $session->beginAttempt(); $session->skip(); $session->moveNext(); // The second section is empty, moveNext() goes to the end of the current route, // and the session is then closed. $this->assertEquals(AssessmentTestSessionState::CLOSED, $session->getState()); }
public function testDefaultAssessmentTestSessionCreation() { $manager = new SessionManager(); $session = $manager->createAssessmentTestSession($this->getTest()); $this->assertInstanceOf('qtism\\runtime\\tests\\AssessmentTestSession', $session); }
public function testIsTimeout() { $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/linear_5_items.xml'); $manager = new SessionManager(); $session = $manager->createAssessmentTestSession($doc->getDocumentComponent()); // If the session has not begun, the method systematically returns false. $this->assertFalse($session->isTimeout()); // If no time limits in force, the test session is never considered timeout while running. $session->beginTestSession(); $this->assertSame(0, $session->isTimeout()); // Q01. $session->beginAttempt(); $this->assertSame(0, $session->isTimeout()); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceA'))))); $this->assertSame(0, $session->isTimeout()); $session->moveNext(); // Q02. $session->beginAttempt(); $this->assertSame(0, $session->isTimeout()); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceB'))))); $this->assertSame(0, $session->isTimeout()); $session->moveNext(); // Q03. $session->beginAttempt(); $this->assertSame(0, $session->isTimeout()); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceC'))))); $this->assertSame(0, $session->isTimeout()); $session->moveNext(); // Q04. $session->beginAttempt(); $this->assertSame(0, $session->isTimeout()); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceD'))))); $this->assertSame(0, $session->isTimeout()); $session->moveNext(); // Q05. $session->beginAttempt(); $this->assertSame(0, $session->isTimeout()); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceE'))))); $this->assertSame(0, $session->isTimeout()); $session->moveNext(); // If the session is closed, the method systematically returns false. $this->assertEquals(AssessmentTestSessionState::CLOSED, $session->getState()); $this->assertFalse($session->isTimeout()); }
public function testMultipleOccurences() { $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/scenario_basic_nonadaptive_linear_singlesection_withreplacement.xml'); $sessionManager = new SessionManager(); $session = $sessionManager->createAssessmentTestSession($doc->getDocumentComponent()); $variableExpr = $this->createComponentFromXml('<variable identifier="Q01.SCORE"/>'); $occurenceVariableExpression = $this->createComponentFromXml('<variable identifier="Q01.1.SCORE"/>'); $variableProcessor = new VariableProcessor($variableExpr); $variableProcessor->setState($session); // non begun test session. $this->assertSame(null, $variableProcessor->process()); $variableProcessor->setExpression($occurenceVariableExpression); $this->assertSame(null, $variableProcessor->process()); // begun test session. $variableProcessor->setExpression($variableExpr); $session->beginTestSession(); // Why not 0.0? Because when using a non sequenced variable identifier // for an item with multiple occurence, the very last instance submitted becomes // the item where the values will be pulled out. No instances were submitted yet // and NULL is returned. $this->assertSame(null, $variableProcessor->process()); $variableProcessor->setExpression($occurenceVariableExpression); // Why not NULL? Because we are in a linear test and Q01 is eligible for selection. // The item session is then instantiated. Outcome variables are set to their default // when the item session instantiation occurs. $this->assertSame(0.0, $variableProcessor->process()->getValue()); // Q01.1 $session->beginAttempt(); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceA'))))); $variableProcessor->setExpression($variableExpr); $result = $variableProcessor->process(); // Null because submission mode is individual... $this->assertSame(null, $result); $variableProcessor->setExpression($occurenceVariableExpression); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\Float', $result); $this->assertEquals(1.0, $result->getValue()); $session->moveNext(); // Q01.2 $session->beginAttempt(); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('ChoiceB'))))); $variableProcessor->setExpression($variableExpr); $result = $variableProcessor->process(); $this->assertSame(null, $result); // $occurenceVariableExpression still targets Q01.1 $variableProcessor->setExpression($occurenceVariableExpression); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\Float', $result); $this->assertEquals(1.0, $result->getValue()); // $occurenceVariableExpression now targets Q01.2 $occurenceVariableExpression->setIdentifier('Q01.2.SCORE'); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\Float', $result); $this->assertEquals(0.0, $result->getValue()); }
public function testMultipleOccurences() { $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/scenario_basic_nonadaptive_linear_singlesection_withreplacement.xml'); $sessionManager = new SessionManager(); $session = $sessionManager->createAssessmentTestSession($doc->getDocumentComponent()); $variableExpr = $this->createComponentFromXml('<variable identifier="Q01.SCORE"/>'); $occurenceVariableExpression = $this->createComponentFromXml('<variable identifier="Q01.1.SCORE"/>'); $variableProcessor = new VariableProcessor($variableExpr); $variableProcessor->setState($session); // non begun test session. $this->assertSame(null, $variableProcessor->process()); $variableProcessor->setExpression($occurenceVariableExpression); $this->assertSame(null, $variableProcessor->process()); // begun test session. $variableProcessor->setExpression($variableExpr); $session->beginTestSession(); // Why not 0.0? Because we are in individual mode. $variableProcessor->setExpression($occurenceVariableExpression); // Why not NULL? Because we are in a linear test and Q01 is eligible for selection. // The item session is then instantiated. Outcome variables are set to their default // when the item session instantiation occurs. $this->assertSame(0.0, $variableProcessor->process()->getValue()); // Q01.1 $session->beginAttempt(); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new QtiIdentifier('ChoiceA'))))); $variableProcessor->setExpression($variableExpr); $result = $variableProcessor->process(); // Null because submission mode is individual... // From IMS QTI: // The value of an item variable taken from an item instantiated multiple times from the same // assessmentItemRef (through the use of selection withReplacement) is taken from the last instance // submitted if submission is simultaneous, otherwise it is undefined. $this->assertSame(null, $result); $variableProcessor->setExpression($occurenceVariableExpression); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\QtiFloat', $result); $this->assertEquals(1.0, $result->getValue()); $session->moveNext(); // Q01.2 $session->beginAttempt(); $session->endAttempt(new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new QtiIdentifier('ChoiceB'))))); $variableProcessor->setExpression($variableExpr); $result = $variableProcessor->process(); $this->assertSame(null, $result); // $occurenceVariableExpression still targets Q01.1 $variableProcessor->setExpression($occurenceVariableExpression); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\QtiFloat', $result); $this->assertEquals(1.0, $result->getValue()); // $occurenceVariableExpression now targets Q01.2 $occurenceVariableExpression->setIdentifier('Q01.2.SCORE'); $result = $variableProcessor->process(); $this->assertInstanceOf('qtism\\common\\datatypes\\QtiFloat', $result); $this->assertEquals(0.0, $result->getValue()); }