public function testBasicSelection() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/runtime/selection_and_ordering.xml'); $testPart = $doc->getDocumentComponent()->getComponentByIdentifier('testPart'); $this->assertEquals('testPart', $testPart->getIdentifier()); $s01 = $doc->getDocumentComponent()->getComponentByIdentifier('S01', true); $this->assertEquals('S01', $s01->getIdentifier()); // Prepare route selection of S01A. $s01a = $doc->getDocumentComponent()->getComponentByIdentifier('S01A', true); $this->assertEquals('S01A', $s01a->getIdentifier()); $s01aRoute = new SelectableRoute(); foreach ($s01a->getSectionParts() as $sectionPart) { $s01aRoute->addRouteItem($sectionPart, $s01a, $testPart, $doc->getDocumentComponent()); } // Prepare route selection of S01B. $s01b = $doc->getDocumentComponent()->getComponentByIdentifier('S01B', true); $this->assertEquals('S01B', $s01b->getIdentifier()); $s01bRoute = new SelectableRoute(); foreach ($s01b->getSectionParts() as $sectionPart) { $s01bRoute->addRouteItem($sectionPart, $s01b, $testPart, $doc->getDocumentComponent()); } $selection = new BasicSelection($s01, new SelectableRouteCollection(array($s01aRoute, $s01bRoute))); $selectedRoutes = $selection->select(); $selectedRoute = new SelectableRoute(); foreach ($selectedRoutes as $r) { $selectedRoute->appendRoute($r); } $routeCheck1 = self::isRouteCorrect($selectedRoute, array('Q1', 'Q2', 'Q3')); $routeCheck2 = self::isRouteCorrect($selectedRoute, array('Q4', 'Q5', 'Q6')); $this->assertFalse($routeCheck1 === true && $routeCheck2 === true); $this->assertTrue($routeCheck1 === true || $routeCheck2 === true); }
/** * Contains the logic of creating the Route of a brand new AssessmentTestSession object. * The resulting Route object will be injected in the created AssessmentTestSession. * * @param \qtism\data\AssessmentTest $test * @return \qtism\runtime\tests\Route A newly instantiated Route object. */ protected function createRoute(AssessmentTest $test) { $routeStack = array(); foreach ($test->getTestParts() as $testPart) { $assessmentSectionStack = array(); foreach ($testPart->getAssessmentSections() as $assessmentSection) { $trail = array(); $mark = array(); array_push($trail, $assessmentSection); while (count($trail) > 0) { $current = array_pop($trail); if (!in_array($current, $mark, true) && $current instanceof AssessmentSection) { // 1st pass on assessmentSection. $currentAssessmentSection = $current; array_push($assessmentSectionStack, $currentAssessmentSection); array_push($mark, $current); array_push($trail, $current); foreach (array_reverse($current->getSectionParts()->getArrayCopy()) as $sectionPart) { array_push($trail, $sectionPart); } } elseif (in_array($current, $mark, true)) { // 2nd pass on assessmentSection. // Pop N routeItems where N is the children count of $current. $poppedRoutes = array(); for ($i = 0; $i < count($current->getSectionParts()); $i++) { $poppedRoutes[] = array_pop($routeStack); } $selection = new BasicSelection($current, new SelectableRouteCollection(array_reverse($poppedRoutes))); $selectedRoutes = $selection->select(); // Shuffling can be applied on selected routes. // $route will contain the final result of the selection + ordering. $ordering = new BasicOrdering($current, $selectedRoutes); $selectedRoutes = $ordering->order(); $route = new SelectableRoute($current->isFixed(), $current->isRequired(), $current->isVisible(), $current->mustKeepTogether()); foreach ($selectedRoutes as $r) { $route->appendRoute($r); } // Add to the last item of the selection the branch rules of the AssessmentSection/testPart // on which the selection is applied... Only if the route contains something (empty assessmentSection edge case). if ($route->count() > 0) { $route->getLastRouteItem()->addBranchRules($current->getBranchRules()); // Do the same as for branch rules for pre conditions, except that they must be // attached on the first item of the route. $route->getFirstRouteItem()->addPreConditions($current->getPreConditions()); } array_push($routeStack, $route); array_pop($assessmentSectionStack); } elseif ($current instanceof AssessmentItemRef) { // leaf node. $route = new SelectableRoute($current->isFixed(), $current->isRequired()); $route->addRouteItem($current, new AssessmentSectionCollection($assessmentSectionStack), $testPart, $test); array_push($routeStack, $route); } } } } $finalRoutes = $routeStack; $route = new SelectableRoute(); foreach ($finalRoutes as $finalRoute) { $route->appendRoute($finalRoute); } return $route; }