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());
 }
    /**
     * Instantiate a basic item session for an adaptive, non-timeDependent item with two variables:
     *
     * * RESPONSE (single, identifier, correctResponse = 'ChoiceB'
     * * SCORE (single, float, defaultValue = 0.0)
     *
     * The responseProcessing sets:
     *
     * * SCORE to 0, completionStatus to 'incomplete', if the response is not 'ChoiceB'.
     * * SCORE to 1, completionStatus to 'complete', if the response is 'ChoiceB'.
     *
     * @return \qtism\runtime\tests\AssessmentItemSession
     */
    protected static function instantiateBasicAdaptiveAssessmentItem(Duration $acceptableLatency = null)
    {
        $itemRef = self::createExtendedAssessmentItemRefFromXml('
            <assessmentItemRef identifier="Q01" href="./Q01.xml" adaptive="true" timeDependent="false">
                <responseDeclaration identifier="RESPONSE" cardinality="single" baseType="identifier">
					<correctResponse>
						<value>ChoiceB</value>
					</correctResponse>
				</responseDeclaration>
                <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float">
					<defaultValue>
						<value>0.0</value>
					</defaultValue>
				</outcomeDeclaration>
	
                <!-- The candidate is allowed to attempt the item until he provides the correct answer -->
                <responseProcessing>
                    <responseCondition>
                        <responseIf>
                            <match>
                                <variable identifier="RESPONSE"/>
                                <baseValue baseType="identifier">ChoiceB</baseValue>
                            </match>
                            <setOutcomeValue identifier="SCORE">
                                <baseValue baseType="float">1</baseValue>
                            </setOutcomeValue>
                            <setOutcomeValue identifier="completionStatus">
                                <baseValue baseType="identifier">completed</baseValue>
                            </setOutcomeValue>
                        </responseIf>
                        <responseElse>
                            <setOutcomeValue identifier="SCORE">
                                <baseValue baseType="float">0</baseValue>
                            </setOutcomeValue>
                            <setOutcomeValue identifier="completionStatus">
                                <baseValue baseType="identifier">incomplete</baseValue>
                            </setOutcomeValue>
                        </responseElse>
                    </responseCondition>
                </responseProcessing>
            </assessmentItemRef>
        ');
        $manager = new SessionManager();
        if (is_null($acceptableLatency) === false) {
            $manager->setAcceptableLatency($acceptableLatency);
        }
        return new AssessmentItemSession($itemRef, $manager);
    }
 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());
 }
Example #9
0
 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());
 }
Example #12
0
 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());
 }