public function testSimpleCase() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/tokenhighlight.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); // Has <hottextInteraction> as the first and only interaction /** @var HottextInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('hottextInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof HottextInteraction); // And its prompt is mapped correctly to item body $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // Assert we have 3 hottext elements /** @var Hottext[] $hottexts */ $hottexts = $interaction->getComponentsByClassName('hottext', true)->getArrayCopy(true); $this->assertEquals(3, $interaction->getComponentsByClassName('hottext', true)->count()); $this->assertEquals('TOKEN_0', $hottexts[0]->getIdentifier()); $this->assertEquals('Risus et tincidunt turpis facilisis.', QtiMarshallerUtil::marshallCollection($hottexts[0]->getComponents())); $this->assertEquals('TOKEN_1', $hottexts[1]->getIdentifier()); $this->assertEquals('Curabitur eu nulla justo. Curabitur vulputate ut nisl et bibendum. ' . 'Nunc diam enim, porta sed eros vitae. dignissim, et tincidunt turpis facilisis.', QtiMarshallerUtil::marshallCollection($hottexts[1]->getComponents())); $this->assertEquals('TOKEN_2', $hottexts[2]->getIdentifier()); $this->assertEquals('Curabitur eu nulla justo. Curabitur vulputate ut nisl et bibendum.', QtiMarshallerUtil::marshallCollection($hottexts[2]->getComponents())); // Assert we have the correct response processing template $responseProcessingTemplate = $assessmentItem->getResponseProcessing()->getTemplate(); $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $responseProcessingTemplate); // Assert we have the correct response declaration values and map entries /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(BaseType::IDENTIFIER, $responseDeclaration->getBaseType()); $this->assertEquals(Cardinality::MULTIPLE, $responseDeclaration->getCardinality()); /** @var Value[] $values */ $values = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertEquals('TOKEN_0', $values[0]->getValue()); $this->assertEquals('TOKEN_2', $values[1]->getValue()); $this->assertNull($responseDeclaration->getMapping()); }
public function testShorttextQuestionWithSimpleValidation() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/shorttext.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); // Has <textEntryInteraction> as the first and only interaction /** @var TextEntryInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('textEntryInteraction', true)->getArrayCopy()[0]; // Test basic attributes $this->assertTrue($interaction instanceof TextEntryInteraction); $this->assertEquals('placeholdertext', $interaction->getPlaceholderText()); $this->assertEquals(15, $interaction->getExpectedLength()); // Shorttext shall have one simple `map_response` <responseDeclaration> and <responseProcessing> /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MAP_RESPONSE, $assessmentItem->getResponseProcessing()->getTemplate()); /** @var Value[] $values */ $values = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertEquals('hello', $values[0]->getValue()); $this->assertEquals('anotherhello', $values[1]->getValue()); /** @var MapEntry[] $mapEntries */ $mapEntries = $responseDeclaration->getMapping()->getMapEntries()->getArrayCopy(true); $this->assertEquals('hello', $mapEntries[0]->getMapKey()); $this->assertEquals(2, $mapEntries[0]->getMappedValue()); $this->assertEquals('anotherhello', $mapEntries[1]->getMapKey()); $this->assertEquals(1, $mapEntries[1]->getMappedValue()); // Check itembody is correct that the stimulus is appended before $itemBodyContent = QtiMarshallerUtil::marshallCollection($assessmentItem->getItemBody()->getComponents()); $expectedString = '<p>[This is the stem.]</p><div><textEntryInteraction responseIdentifier="shorttexttestreference" expectedLength="15" placeholderText="placeholdertext" label="shorttexttestreference"/></div>'; $this->assertEquals($expectedString, $itemBodyContent); }
public function testSimpleCaseWithNoValidation() { $stimulus = '<strong>Where is Learnosity office in Australia located?</strong>'; $options = ['ChoiceA' => 'Melbourne', 'ChoiceB' => 'Sydney', 'ChoiceC' => 'Jakarta']; $question = $this->buildMcq($options); $question->set_stimulus($stimulus); $mcqMapper = new McqMapper(); /** @var ChoiceInteraction $interaction */ list($interaction, $responseDeclaration, $responseProcessing) = $mcqMapper->convert($question, 'testIdentifier', 'testIdentifierLabel'); // Check usual $this->assertTrue($interaction instanceof ChoiceInteraction); $this->assertEquals('testIdentifier', $interaction->getResponseIdentifier()); $this->assertEquals('testIdentifierLabel', $interaction->getLabel()); $this->assertEquals($stimulus, QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents())); $this->assertNull($responseDeclaration); $this->assertNull($responseProcessing); // Check `options` mapping are correct /** @var SimpleChoice[] $choices */ $choices = $interaction->getSimpleChoices()->getArrayCopy(true); $this->assertEquals('ChoiceA', $choices[0]->getIdentifier()); $this->assertEquals('Melbourne', QtiMarshallerUtil::marshallCollection($choices[0]->getContent())); $this->assertEquals('ChoiceB', $choices[1]->getIdentifier()); $this->assertEquals('Sydney', QtiMarshallerUtil::marshallCollection($choices[1]->getContent())); $this->assertEquals('ChoiceC', $choices[2]->getIdentifier()); $this->assertEquals('Jakarta', QtiMarshallerUtil::marshallCollection($choices[2]->getContent())); // Check the default values are correct $this->assertEquals(1, $interaction->getMaxChoices()); $this->assertEquals(1, $interaction->getMinChoices()); $this->assertEquals(Orientation::VERTICAL, $interaction->getOrientation()); }
public function testSimpleCase() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/orderlist.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); /** @var OrderInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('orderInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof OrderInteraction); // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // Assert its choices are correct /** @var SimpleChoice[] $simpleChoices */ $simpleChoices = $interaction->getSimpleChoices()->getArrayCopy(true); $this->assertEquals('CHOICE_0', $simpleChoices[0]->getIdentifier()); $this->assertEquals('[Choice A]', QtiMarshallerUtil::marshallCollection($simpleChoices[0]->getComponents())); $this->assertEquals('CHOICE_1', $simpleChoices[1]->getIdentifier()); $this->assertEquals('[Choice B]', QtiMarshallerUtil::marshallCollection($simpleChoices[1]->getComponents())); $this->assertEquals('CHOICE_2', $simpleChoices[2]->getIdentifier()); $this->assertEquals('[Choice C]', QtiMarshallerUtil::marshallCollection($simpleChoices[2]->getComponents())); $this->assertEquals('CHOICE_3', $simpleChoices[3]->getIdentifier()); $this->assertEquals('[Choice D]', QtiMarshallerUtil::marshallCollection($simpleChoices[3]->getComponents())); // Also assert its validation is match_correct and correct /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(Cardinality::ORDERED, $responseDeclaration->getCardinality()); /** @var Value[] $correctResponseValues */ $correctResponseValues = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertEquals('CHOICE_3', $correctResponseValues[0]->getValue()); $this->assertEquals('CHOICE_1', $correctResponseValues[1]->getValue()); $this->assertEquals('CHOICE_0', $correctResponseValues[2]->getValue()); $this->assertEquals('CHOICE_2', $correctResponseValues[3]->getValue()); $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $assessmentItem->getResponseProcessing()->getTemplate()); }
public function testSingularResponsesWithNoValidation() { $question = $this->buildSimpleChoiceMatrixQuestion(); /** @var MatchInteraction $interaction */ $mapper = new ChoicematrixMapper(); list($interaction, $responseDeclaration, $responseProcessing) = $mapper->convert($question, 'testIdentifier', 'testIdentifier'); $this->assertEquals('My stimulus string', QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents())); $this->assertFalse($interaction->mustShuffle()); $this->assertEquals(2, $interaction->getMaxAssociations()); $this->assertEquals(2, $interaction->getMinAssociations()); // Assert its source choices (stems) /** @var SimpleAssociableChoice[] $stemAssociableChoices */ $stemAssociableChoices = $interaction->getSourceChoices()->getSimpleAssociableChoices()->getArrayCopy(true); $this->assertEquals('Stem 1', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[0]->getContent())); $this->assertEquals('STEM_0', $stemAssociableChoices[0]->getIdentifier()); $this->assertEquals('Stem 2', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[1]->getContent())); $this->assertEquals('STEM_1', $stemAssociableChoices[1]->getIdentifier()); foreach ($stemAssociableChoices as $choice) { $this->assertEquals(1, $choice->getMatchMax()); $this->assertEquals(1, $choice->getMatchMin()); } // Assert its target choices (options) /** @var SimpleAssociableChoice[] $optionAssociableChoices */ $optionAssociableChoices = $interaction->getTargetChoices()->getSimpleAssociableChoices()->getArrayCopy(true); $this->assertEquals('Option 1', QtiMarshallerUtil::marshallCollection($optionAssociableChoices[0]->getContent())); $this->assertEquals('OPTION_0', $optionAssociableChoices[0]->getIdentifier()); $this->assertEquals('Option 2', QtiMarshallerUtil::marshallCollection($optionAssociableChoices[1]->getContent())); $this->assertEquals('OPTION_1', $optionAssociableChoices[1]->getIdentifier()); $this->assertEquals('Option 3', QtiMarshallerUtil::marshallCollection($optionAssociableChoices[2]->getContent())); $this->assertEquals('OPTION_2', $optionAssociableChoices[2]->getIdentifier()); foreach ($optionAssociableChoices as $choice) { $this->assertEquals(2, $choice->getMatchMax()); $this->assertEquals(1, $choice->getMatchMin()); } }
public function testMappingSimpleQuestionWithNoValidation() { $placeholder = 'placeholdertest'; $stimulus = '<strong>stimulushere</strong>'; $questionReference = 'questionReferenceOne'; $question = new plaintext('plaintext'); $question->set_placeholder($placeholder); $question->set_stimulus($stimulus); $mapper = new PlaintextMapper(); /** @var ExtendedTextInteraction $interaction */ list($interaction, $responseDeclaration, $responseProcessing) = $mapper->convert($question, $questionReference, $questionReference); // No validation shall be mapped for longtext $this->assertNull($responseDeclaration); $this->assertNull($responseProcessing); // Assert question mapped correctly to ExtendedTextInteraction $this->assertTrue($interaction instanceof ExtendedTextInteraction); $this->assertEquals($questionReference, $interaction->getResponseIdentifier()); $this->assertEquals($questionReference, $interaction->getLabel()); $this->assertEquals($stimulus, QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents())); $this->assertEquals($placeholder, $interaction->getPlaceholderText()); // Assert question mapped correctly with default values $this->assertEquals(TextFormat::PLAIN, $interaction->getFormat()); $this->assertEquals(1, $interaction->getMinStrings()); $this->assertEquals(1, $interaction->getMaxStrings()); }
public function getQuestionType() { /* @var QtiExtendedTextInteraction $interaction */ $interaction = $this->interaction; $longtext = new longtext('longtext'); LogService::log('No validation mapping supported for this interaction. Ignoring any ' . '<responseProcessing> and <responseDeclaration> if any'); if (!empty($interaction->getPrompt())) { $promptContent = $interaction->getPrompt()->getContent(); $longtext->set_stimulus(QtiMarshallerUtil::marshallCollection($promptContent)); } if ($interaction->getPlaceholderText()) { $longtext->set_placeholder($interaction->getPlaceholderText()); } /** As per QTI spec * When multiple strings are accepted, expectedLength applies to each string. * `expectedLength` works as a only as a 'hint' to student so we do not want to force a hard limit */ if ($interaction->getExpectedLength() > 0) { $maxStrings = $interaction->getMaxStrings() > 0 ? $interaction->getMaxStrings() : 1; $expectedLength = $interaction->getExpectedLength() / 5; $longtext->set_max_length($maxStrings * $expectedLength); $longtext->set_submit_over_limit(true); } return $longtext; }
public function testSimpleCase() { /** @var AssessmentItem $assessmentItem */ $question = json_decode($this->getFixtureFileContents('learnosityjsons/data_clozedropdown.json'), true); $assessmentItem = $this->convertToAssessmentItem($question); $interactions = $assessmentItem->getComponentsByClassName('inlineChoiceInteraction', true)->getArrayCopy(); /** @var InlineChoiceInteraction $interactionOne */ $interactionOne = $interactions[0]; /** @var InlineChoiceInteraction $interactionTwo */ $interactionTwo = $interactions[1]; $this->assertTrue($interactionOne instanceof InlineChoiceInteraction); $this->assertTrue($interactionTwo instanceof InlineChoiceInteraction); $content = QtiMarshallerUtil::marshallCollection($assessmentItem->getItemBody()->getContent()); $this->assertNotEmpty($content); // Assert response processing template $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $assessmentItem->getResponseProcessing()->getTemplate()); // Assert response declarations $responseDeclarations = $assessmentItem->getResponseDeclarations()->getArrayCopy(); /** @var ResponseDeclaration $responseDeclarationOne */ $responseDeclarationOne = $responseDeclarations[0]; /** @var ResponseDeclaration $responseDeclarationTwo */ $responseDeclarationTwo = $responseDeclarations[1]; // Check has the correct identifiers, also correct `correctResponse` values $this->assertEquals($responseDeclarationOne->getIdentifier(), $interactionOne->getResponseIdentifier()); $this->assertNull($responseDeclarationOne->getMapping()); $this->assertEquals('INLINECHOICE_2', $responseDeclarationOne->getCorrectResponse()->getValues()->getArrayCopy()[0]->getValue()); $this->assertEquals('Choice C', QtiMarshallerUtil::marshallCollection($interactionOne->getComponentByIdentifier('INLINECHOICE_2')->getComponents())); $this->assertEquals($responseDeclarationTwo->getIdentifier(), $interactionTwo->getResponseIdentifier()); $this->assertNull($responseDeclarationTwo->getMapping()); $this->assertEquals('INLINECHOICE_1', $responseDeclarationTwo->getCorrectResponse()->getValues()->getArrayCopy()[0]->getValue()); $this->assertEquals('Choice B', QtiMarshallerUtil::marshallCollection($interactionTwo->getComponentByIdentifier('INLINECHOICE_1')->getComponents())); }
public function getPrompt() { if ($this->interaction->getPrompt() instanceof Prompt) { $promptContent = $this->interaction->getPrompt()->getContent(); return QtiMarshallerUtil::marshallCollection($promptContent); } return ''; }
public function testMappingItemWithSharedPassage() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/item_mcq_sharedpassage.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); /** @var Object $object */ $object = $assessmentItem->getComponentsByClassName('object', true)->getArrayCopy()[0]; $this->assertEquals('text/html', $object->getType()); $this->assertEquals('<p>This is the content of my shared passage</p>', QtiMarshallerUtil::marshallCollection($object->getComponents())); }
private function buildTemplate(ItemBody $itemBody, array $interactionXmls) { // Build item's HTML content $content = QtiMarshallerUtil::marshallCollection($itemBody->getComponents()); foreach ($interactionXmls as $interactionXml) { $content = str_replace($interactionXml, '{{response}}', $content); } return $content; }
private function buildOptions(SimpleChoiceCollection $simpleChoices) { /* @var $choice SimpleChoice */ $options = []; foreach ($simpleChoices as $key => $choice) { // Store 'SimpleChoice' identifier to key for validation purposes $options[] = ['label' => QtiMarshallerUtil::marshallCollection($choice->getContent()), 'value' => $choice->getIdentifier()]; } return $options; }
protected function buildPossibleResponseMapping(QtiGraphicGapMatchInteraction $interaction) { $possibleResponseMapping = []; $gapChoices = $interaction->getGapImgs(); /** @var GapChoice $gapChoice */ foreach ($gapChoices as $gapChoice) { $gapChoiceContent = QtiMarshallerUtil::marshallCollection($gapChoice->getComponents()); $possibleResponseMapping[$gapChoice->getIdentifier()] = $gapChoiceContent; } return $possibleResponseMapping; }
private function buildOptions(SimpleMatchSet $simpleMatchSet, &$mapping) { $options = []; $choiceCollection = $simpleMatchSet->getSimpleAssociableChoices(); /** @var SimpleAssociableChoice $choice */ foreach ($choiceCollection as $choice) { $contentStr = QtiMarshallerUtil::marshallCollection($choice->getContent()); $options[] = $contentStr; $mapping[$choice->getIdentifier()] = count($options) - 1; } return $options; }
public function getQuestionType() { /** @var HotspotInteraction $interaction */ $interaction = $this->interaction; $imageObject = $interaction->getObject(); // Yes, width and height is necessary unfortunately if ($imageObject->getHeight() < 0 || $imageObject->getWidth() < 0) { throw new MappingException('Hotspot interaction image object need to specifiy both width and height for conversion'); } // Slab the image object $hotspot = new hotspot('hotspot'); $hotspot->set_image($this->buildHotspotImage($imageObject)); // Support mapping for <prompt> if ($interaction->getPrompt() instanceof Prompt) { $promptContent = $interaction->getPrompt()->getContent(); $hotspot->set_stimulus(QtiMarshallerUtil::marshallCollection($promptContent)); } // Map the hotspot areas $areas = $this->buildAreas($interaction->getHotspotChoices(), $imageObject); $hotspot->set_areas($areas); // Setup the area attributes with assumption // TODO: Let's say the default fill is always clear, and the stroke would be blackish $globalAttributes = new hotspot_area_attributes_global(); $globalAttributes->set_fill("rgba(0,0,0,0)"); $globalAttributes->set_stroke("rgba(25, 90, 107, 0.5)"); $areaAttributes = new hotspot_area_attributes(); $areaAttributes->set_global($globalAttributes); $hotspot->set_area_attributes($areaAttributes); // Partial support for @maxChoices // @maxChoices of 0 or more than 1 would then would set `multiple_responses` to true $maxChoices = $interaction->getMaxChoices(); if ($maxChoices !== 1) { if ($maxChoices !== 0 && $maxChoices !== count($areas)) { // We do not support specifying amount of areas LogService::log("Allowing multiple responses of max " . count($areas) . " options, however " . "maxChoices of {$maxChoices} would be ignored since we can't support exact number"); } $hotspot->set_multiple_responses(true); } // Ignoring @minChoices if (!empty($interaction->getMinChoices())) { LogService::log('Attribute minChoices is not supported. Thus, ignored'); } // Build validation $validationBuilder = new HotspotInteractionValidationBuilder($this->responseDeclaration, $areas, $maxChoices); $validation = $validationBuilder->buildValidation($this->responseProcessingTemplate); if (!empty($validation)) { $hotspot->set_validation($validation); } return $hotspot; }
public function testSimpleCase() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/choicematrix.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); /** @var MatchInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('matchInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof MatchInteraction); // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // Assert its source choices (stems) /** @var SimpleAssociableChoice[] $stemAssociableChoices */ $stemAssociableChoices = $interaction->getSourceChoices()->getSimpleAssociableChoices()->getArrayCopy(true); $this->assertEquals('[Stem 1]', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[0]->getContent())); $this->assertEquals('STEM_0', $stemAssociableChoices[0]->getIdentifier()); $this->assertEquals('[Stem 2]', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[1]->getContent())); $this->assertEquals('STEM_1', $stemAssociableChoices[1]->getIdentifier()); $this->assertEquals('[Stem 3]', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[2]->getContent())); $this->assertEquals('STEM_2', $stemAssociableChoices[2]->getIdentifier()); $this->assertEquals('[Stem 4]', QtiMarshallerUtil::marshallCollection($stemAssociableChoices[3]->getContent())); $this->assertEquals('STEM_3', $stemAssociableChoices[3]->getIdentifier()); foreach ($stemAssociableChoices as $choice) { $this->assertEquals(1, $choice->getMatchMax()); $this->assertEquals(1, $choice->getMatchMin()); } // Assert its target choices (options) /** @var SimpleAssociableChoice[] $optionAssociableChoices */ $optionAssociableChoices = $interaction->getTargetChoices()->getSimpleAssociableChoices()->getArrayCopy(true); $this->assertEquals('True', QtiMarshallerUtil::marshallCollection($optionAssociableChoices[0]->getContent())); $this->assertEquals('OPTION_0', $optionAssociableChoices[0]->getIdentifier()); $this->assertEquals('False', QtiMarshallerUtil::marshallCollection($optionAssociableChoices[1]->getContent())); $this->assertEquals('OPTION_1', $optionAssociableChoices[1]->getIdentifier()); foreach ($optionAssociableChoices as $choice) { $this->assertEquals(4, $choice->getMatchMax()); $this->assertEquals(1, $choice->getMatchMin()); } // Assert its valdation, woo hooo! $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $assessmentItem->getResponseProcessing()->getTemplate()); /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(Cardinality::MULTIPLE, $responseDeclaration->getCardinality()); $this->assertEquals(BaseType::DIRECTED_PAIR, $responseDeclaration->getBaseType()); /** @var Value[] $values */ $values = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertDirectPair($values[0]->getValue(), 'STEM_0', 'OPTION_0'); $this->assertDirectPair($values[1]->getValue(), 'STEM_1', 'OPTION_1'); $this->assertDirectPair($values[2]->getValue(), 'STEM_2', 'OPTION_1'); $this->assertDirectPair($values[3]->getValue(), 'STEM_3', 'OPTION_0'); $this->assertNull($responseDeclaration->getMapping()); }
public function getQuestionType() { /* @var \qtism\data\content\interactions\InlineChoiceInteraction $interaction */ $interaction = $this->validateInteraction($this->interaction); $template = '{{response}}'; foreach ($interaction->getContent() as $inlineChoice) { $this->choicesMapping[$inlineChoice->getIdentifier()] = QtiMarshallerUtil::marshallCollection($inlineChoice->getContent()); } $question = new clozedropdown('clozedropdown', $template, [array_values($this->choicesMapping)]); $validation = $this->buildValidation(); if ($validation) { $question->set_validation($validation); } return $question; }
public function testSimpleCase() { /** @var AssessmentItem $assessmentItem */ $question = json_decode($this->getFixtureFileContents('learnosityjsons/data_clozetext.json'), true); $assessmentItem = $this->convertToAssessmentItem($question); $interactions = $assessmentItem->getComponentsByClassName('textEntryInteraction', true)->getArrayCopy(); /** @var TextEntryInteraction $interactionOne */ $interactionOne = $interactions[0]; /** @var TextEntryInteraction $interactionTwo */ $interactionTwo = $interactions[1]; $this->assertTrue($interactionOne instanceof TextEntryInteraction); $this->assertTrue($interactionTwo instanceof TextEntryInteraction); $this->assertEquals(15, $interactionOne->getExpectedLength()); $this->assertEquals(15, $interactionTwo->getExpectedLength()); $content = QtiMarshallerUtil::marshallCollection($assessmentItem->getItemBody()->getContent()); $this->assertNotEmpty($content); // Assert response declarations $responseDeclarations = $assessmentItem->getResponseDeclarations()->getArrayCopy(); /** @var ResponseDeclaration $responseDeclarationOne */ $responseDeclarationOne = $responseDeclarations[0]; /** @var ResponseDeclaration $responseDeclarationTwo */ $responseDeclarationTwo = $responseDeclarations[1]; // Check has the correct identifiers $this->assertEquals($responseDeclarationOne->getIdentifier(), $interactionOne->getResponseIdentifier()); $this->assertEquals($responseDeclarationTwo->getIdentifier(), $interactionTwo->getResponseIdentifier()); // Also correct `correctResponse` values $this->assertEquals('responseone', $responseDeclarationOne->getCorrectResponse()->getValues()->getArrayCopy()[0]->getValue()); $this->assertEquals('otherresponseone', $responseDeclarationOne->getCorrectResponse()->getValues()->getArrayCopy()[1]->getValue()); $this->assertEquals('anotherresponseone', $responseDeclarationOne->getCorrectResponse()->getValues()->getArrayCopy()[2]->getValue()); $this->assertEquals('responsetwo', $responseDeclarationTwo->getCorrectResponse()->getValues()->getArrayCopy()[0]->getValue()); $this->assertEquals('otherresponsetwo', $responseDeclarationTwo->getCorrectResponse()->getValues()->getArrayCopy()[1]->getValue()); $this->assertEquals('anotherresponsetwo', $responseDeclarationTwo->getCorrectResponse()->getValues()->getArrayCopy()[2]->getValue()); // Also correct `mapping` entries $this->assertEquals('responseone', $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[0]->getMapKey()); $this->assertEquals(3, $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[0]->getMappedValue()); $this->assertEquals('otherresponseone', $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[1]->getMapKey()); $this->assertEquals(2, $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[1]->getMappedValue()); $this->assertEquals('anotherresponseone', $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[2]->getMapKey()); $this->assertEquals(1, $responseDeclarationOne->getMapping()->getMapEntries()->getArrayCopy()[2]->getMappedValue()); $this->assertEquals('responsetwo', $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[0]->getMapKey()); $this->assertEquals(3, $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[0]->getMappedValue()); $this->assertEquals('otherresponsetwo', $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[1]->getMapKey()); $this->assertEquals(2, $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[1]->getMappedValue()); $this->assertEquals('anotherresponsetwo', $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[2]->getMapKey()); $this->assertEquals(1, $responseDeclarationTwo->getMapping()->getMapEntries()->getArrayCopy()[2]->getMappedValue()); // Assert response processing template $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MAP_RESPONSE, $assessmentItem->getResponseProcessing()->getTemplate()); }
public function map($itemReference, ItemBody $itemBody, QtiComponentCollection $interactionComponents, QtiComponentCollection $responseDeclarations = null, ResponseProcessingTemplate $responseProcessingTemplate = null) { $this->itemReference = $itemReference; $questionsXmls = []; $responseDeclarationsMap = []; if ($responseDeclarations) { /** @var ResponseDeclaration $responseDeclaration */ foreach ($responseDeclarations as $responseDeclaration) { $responseDeclarationsMap[$responseDeclaration->getIdentifier()] = $responseDeclaration; } } foreach ($interactionComponents as $component) { /* @var $component Interaction */ $questionReference = $this->itemReference . '_' . $component->getResponseIdentifier(); // Process <responseDeclaration> $responseDeclaration = isset($responseDeclarationsMap[$component->getResponseIdentifier()]) ? $responseDeclarationsMap[$component->getResponseIdentifier()] : null; $mapper = $this->getMapperInstance($component->getQtiClassName(), [$component, $responseDeclaration, $responseProcessingTemplate]); $question = $mapper->getQuestionType(); $this->questions[$questionReference] = new Question($question->get_type(), $questionReference, $question); $questionsXmls[$questionReference] = ['qtiClassName' => $component->getQtiClassName(), 'responseIdentifier' => $component->getResponseIdentifier()]; } // Build item's HTML content $extraContentHtml = new SimpleHtmlDom(); if (!$extraContentHtml->load(QtiMarshallerUtil::marshallCollection($itemBody->getComponents()), false)) { throw new \Exception('Issues with the content for itemBody, it might not be valid'); } foreach ($questionsXmls as $questionReference => $interactionData) { // Append this question span to our `item` content as it is $this->content .= '<span class="learnosity-response question-' . $questionReference . '"></span>'; // Clean up interaction HTML content $qtiClassName = $interactionData['qtiClassName']; $responseIdentifier = $interactionData['responseIdentifier']; $toFind = $qtiClassName . '[responseIdentifier="' . $responseIdentifier . '"]'; foreach ($extraContentHtml->find($toFind) as &$tag) { $tag->outertext = ''; } } $extraContent = $extraContentHtml->save(); // Making assumption question always has stimulus `right`? // So, prepend the extra content on the stimulus on the first question if (!empty(trim($extraContent))) { $firstQuestionReference = key($this->questions); $newStimulus = $extraContent . $this->questions[$firstQuestionReference]->get_data()->get_stimulus(); $this->questions[$firstQuestionReference]->get_data()->set_stimulus($newStimulus); LogService::log('Extra <itemBody> content is prepended to question stimulus and please verify as this `might` break item content structure'); } return true; }
public function testSimpleCommonCase() { /** @var AssessmentItem $assessmentItem */ $question = json_decode($this->getFixtureFileContents('learnosityjsons/data_imageclozeassociation.json'), true); $assessmentItem = $this->convertToAssessmentItem($question); /** @var GraphicGapMatchInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('graphicGapMatchInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof GraphicGapMatchInteraction); // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // And its gapimages mapped well /** @var GapImg[] $gapImages */ $gapImages = $interaction->getGapImgs()->getArrayCopy(); $this->assertEquals(3, count($gapImages)); $this->assertEquals('CHOICE_0', $gapImages[0]->getIdentifier()); $object0 = $gapImages[0]->getComponents()->current(); $this->assertEquals('image/png', $object0->getType()); $this->assertEquals(56, $object0->getWidth()); $this->assertEquals(13, $object0->getHeight()); $this->assertEquals('CHOICE_1', $gapImages[1]->getIdentifier()); $object1 = $gapImages[1]->getComponents()->current(); $this->assertEquals('image/png', $object1->getType()); $this->assertEquals(56, $object1->getWidth()); $this->assertEquals(13, $object1->getHeight()); $this->assertEquals('CHOICE_2', $gapImages[2]->getIdentifier()); $object2 = $gapImages[2]->getComponents()->current(); $this->assertEquals('image/png', $object2->getType()); $this->assertEquals(100, $object2->getWidth()); $this->assertEquals(100, $object2->getHeight()); // And its associableHotspot // TODO: Do more through assert with coords and matchmax/matchmin check $this->assertEquals(3, $interaction->getAssociableHotspots()->count()); // And its response processing and response declaration $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $assessmentItem->getResponseProcessing()->getTemplate()); /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(Cardinality::MULTIPLE, $responseDeclaration->getCardinality()); $this->assertEquals(BaseType::DIRECTED_PAIR, $responseDeclaration->getBaseType()); /** @var Value[] $values */ $values = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertDirectPair($values[0]->getValue(), 'ASSOCIABLEHOTSPOT_0', 'CHOICE_2'); $this->assertDirectPair($values[1]->getValue(), 'ASSOCIABLEHOTSPOT_1', 'CHOICE_1'); $this->assertDirectPair($values[2]->getValue(), 'ASSOCIABLEHOTSPOT_2', 'CHOICE_0'); // And, we don't have mapping because we simply won't $this->assertEquals(null, $responseDeclaration->getMapping()); }
public function testSimpleWithNoValidation() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/item_plaintext.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); // Plaintext shall have no <responseDeclaration> and <responseProcessing> $this->assertEquals(0, $assessmentItem->getResponseDeclarations()->count()); $this->assertNull($assessmentItem->getResponseProcessing()); // Has <extendedTextInteraction> as the first and only interaction /** @var ExtendedTextInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('extendedTextInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof ExtendedTextInteraction); // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>Write an essay</p>', $promptString); // And it is a HTML text by default $this->assertEquals(TextFormat::PLAIN, $interaction->getFormat()); }
private function buildTemplate(QtiGapMatchInteraction $interaction) { $templateCollection = new QtiComponentCollection(); foreach ($interaction->getComponents() as $component) { // Ignore `prompt` and the `gapChoice` since they are going to be mapped somewhere else :) if (!$component instanceof Prompt && !$component instanceof GapChoice) { $templateCollection->attach($component); } } $gapIdentifiers = []; $content = QtiMarshallerUtil::marshallCollection($templateCollection); foreach ($interaction->getComponentsByClassName('gap', true) as $gap) { /** @var Gap $gap */ $gapIdentifiers[] = $gap->getIdentifier(); $gapString = QtiMarshallerUtil::marshall($gap); $content = str_replace($gapString, '{{response}}', $content); } return [$content, $gapIdentifiers]; }
protected function marshallChildrenKnown(QtiComponent $component, array $elements) { /** @var Object $component */ switch ($this->getMIMEType($component->getType())) { case self::MIME_IMAGE: $this->checkObjectComponents($component, '<img> tag'); $element = self::getDOMCradle()->createElement('img'); $element->setAttribute('src', $component->getData()); return $element; break; case self::MIME_AUDIO: $this->checkObjectComponents($component, '`audioplayer` feature'); $element = self::getDOMCradle()->createElement('span'); $element->setAttribute('class', 'learnosity-feature'); $element->setAttribute('data-type', 'audioplayer'); $element->setAttribute('data-src', $component->getData()); return $element; break; case self::MIME_VIDEO: $this->checkObjectComponents($component, '`videoplayer` feature'); $element = self::getDOMCradle()->createElement('span'); $element->setAttribute('class', 'learnosity-feature'); $element->setAttribute('data-type', 'videoplayer'); $element->setAttribute('data-src', $component->getData()); return $element; break; case self::MIME_HTML: $fragment = self::getDOMCradle()->createDocumentFragment(); $fragment->appendXML(QtiMarshallerUtil::marshallCollection(ContentCollectionBuilder::buildFlowCollectionContent($component->getComponents()))); $element = self::getDOMCradle()->createElement('div'); $element->setAttribute('data-type', 'sharedpassage'); $element->appendChild($fragment); return $element; break; default: // TODO: Need to think external HTML object file, what we are going to do with them? // Just parse <object> as default LogService::log('Unknown <object> MIME type, outputting <object> as it is'); return parent::marshallChildrenKnown($component, $elements); } }
public function testSimpleCase() { $data = json_decode($this->getFixtureFileContents('learnosityjsons/data_hotspot.json'), true); $assessmentItem = $this->convertToAssessmentItem($data); // Simple validation on <responseDeclaration> and <responseProcessing> $this->assertEquals(1, $assessmentItem->getResponseDeclarations()->count()); $this->assertNotNull($assessmentItem->getResponseProcessing()); // Get dah interaction /** @var HotspotInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('hotspotInteraction', true)->getArrayCopy()[0]; // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // All the choices also mapped properly /** @var HotspotChoice[] $choices */ $choices = $interaction->getHotspotChoices()->getArrayCopy(true); $this->assertEquals($choices[0]->getIdentifier(), 'CHOICE_0'); $this->assertEquals($choices[0]->getShape(), QtiShape::POLY); // QtiShape shall be POLY $this->assertEquals($choices[0]->getCoords()->count(), 96); $this->assertEquals($choices[1]->getIdentifier(), 'CHOICE_1'); $this->assertEquals($choices[2]->getIdentifier(), 'CHOICE_2'); $this->assertEquals($choices[3]->getIdentifier(), 'CHOICE_3'); // Check `minChoices` and `maxChoices` $this->assertEquals(0, $interaction->getMinChoices()); $this->assertEquals(1, $interaction->getMaxChoices()); // Simple validation on <responseDeclaration> and <responseProcessing> $this->assertEquals(1, $assessmentItem->getResponseDeclarations()->count()); $this->assertNotNull($assessmentItem->getResponseProcessing()); // Check the response declaration looks good /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy(true)[$interaction->getResponseIdentifier()]; $this->assertEquals(BaseType::IDENTIFIER, $responseDeclaration->getBaseType()); $this->assertEquals(Cardinality::SINGLE, $responseDeclaration->getCardinality()); $correctResponse = $responseDeclaration->getCorrectResponse(); $this->assertTrue($correctResponse instanceof CorrectResponse); /** @var Value[] $values */ $values = $correctResponse->getValues()->getArrayCopy(true); $this->assertEquals($values[0]->getValue(), 'CHOICE_0'); $this->assertNull($responseDeclaration->getMapping()); }
public function testWithNoValidation() { $template = '<p><span class="lrn_token">Hello</span></p>' . '<p><span class="lrn_token">Welcome to my world!</span></p>' . '<p><span class="lrn_token">Brown sugar</span></p>'; $question = new tokenhighlight('tokenhighlight', $template, 'custom'); $mapper = new TokenhighlightMapper(); /** @var HottextInteraction $interaction */ list($interaction, $responseDeclaration, $responseProcessing) = $mapper->convert($question, 'testIdentifier', 'testIdentifierLabel'); $this->assertTrue($interaction instanceof HottextInteraction); $this->assertNull($responseDeclaration); $this->assertNull($responseProcessing); // Assert those hottext /** @var Hottext[] $hottexts */ $hottexts = $interaction->getComponentsByClassName('hottext', true)->getArrayCopy(true); $this->assertEquals(3, $interaction->getComponentsByClassName('hottext', true)->count()); $this->assertEquals('TOKEN_0', $hottexts[0]->getIdentifier()); $this->assertEquals('Hello', QtiMarshallerUtil::marshallCollection($hottexts[0]->getComponents())); $this->assertEquals('TOKEN_1', $hottexts[1]->getIdentifier()); $this->assertEquals('Welcome to my world!', QtiMarshallerUtil::marshallCollection($hottexts[1]->getComponents())); $this->assertEquals('TOKEN_2', $hottexts[2]->getIdentifier()); $this->assertEquals('Brown sugar', QtiMarshallerUtil::marshallCollection($hottexts[2]->getComponents())); }
public function getQuestionType() { /* @var QtiOrderInteraction $interaction */ $interaction = $this->interaction; if (!$this->validate($interaction)) { return null; } $list = []; $this->orderMapping = []; /** @var SimpleChoice $simpleChoice */ foreach ($interaction->getSimpleChoices() as $simpleChoice) { $this->orderMapping[$simpleChoice->getIdentifier()] = count($this->orderMapping); $list[] = QtiMarshallerUtil::marshallCollection($simpleChoice->getContent()); } $question = new orderlist('orderlist', $list); $question->set_stimulus($this->getPrompt()); // Build `validation` object $validation = $this->buildValidation(); if ($validation) { $question->set_validation($validation); } return $question; }
public function testWithNoValidation() { $orderlist = $this->buildOrderlist(['ant', 'elephant', 'dog'], 'Order these animal from big to small'); /** @var orderlist_validation $validation */ $orderlistMapper = new OrderlistMapper(); list($interaction, $responseDeclaration, $responseProcessing) = $orderlistMapper->convert($orderlist, 'testIdentifier', 'testIdentifierLabel'); $this->assertNull($responseDeclaration); $this->assertNull($responseProcessing); /** @var OrderInteraction $interaction */ $this->assertTrue($interaction instanceof OrderInteraction); $this->assertEquals(false, $interaction->mustShuffle()); $this->assertEquals(-1, $interaction->getMaxChoices()); $this->assertEquals(-1, $interaction->getMinChoices()); $this->assertEquals(Orientation::VERTICAL, $interaction->getOrientation()); /** @var SimpleChoice[] $choices */ $choices = $interaction->getSimpleChoices()->getArrayCopy(true); $this->assertEquals('CHOICE_0', $choices[0]->getIdentifier()); $this->assertEquals('ant', QtiMarshallerUtil::marshallCollection($choices[0]->getComponents())); $this->assertEquals('CHOICE_1', $choices[1]->getIdentifier()); $this->assertEquals('elephant', QtiMarshallerUtil::marshallCollection($choices[1]->getComponents())); $this->assertEquals('CHOICE_2', $choices[2]->getIdentifier()); $this->assertEquals('dog', QtiMarshallerUtil::marshallCollection($choices[2]->getComponents())); }
public function testSimpleCommonCase() { /** @var AssessmentItem $assessmentItem */ $question = json_decode($this->getFixtureFileContents('learnosityjsons/data_clozeassociation.json'), true); $assessmentItem = $this->convertToAssessmentItem($question); /** @var GapMatchInteraction $interaction */ $interaction = $assessmentItem->getComponentsByClassName('gapMatchInteraction', true)->getArrayCopy()[0]; $this->assertTrue($interaction instanceof GapMatchInteraction); $this->assertFalse($interaction->mustShuffle()); // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('<p>[This is the stem.]</p>', $promptString); // And its choices mapped well /** @var GapText[] $gapChoices */ $gapChoices = $interaction->getGapChoices()->getArrayCopy(); $this->assertEquals(2, count($gapChoices)); $this->assertEquals('CHOICE_0', $gapChoices[0]->getIdentifier()); $this->assertEquals('Choice A', QtiMarshallerUtil::marshallCollection($gapChoices[0]->getContent())); $this->assertEquals('CHOICE_1', $gapChoices[1]->getIdentifier()); $this->assertEquals('Choice B', QtiMarshallerUtil::marshallCollection($gapChoices[1]->getContent())); // And its gaps $content = QtiMarshallerUtil::marshallCollection($interaction->getContent()); $expectedContent = '<p>Risus <gap identifier="GAP_0"/>, et tincidunt turpis facilisis. Curabitur eu nulla justo. Curabitur vulputate ut nisl et bibendum. Nunc diam enim, porta sed eros vitae. <gap identifier="GAP_1"/> dignissim, et tincidunt turpis facilisis. Curabitur eu nulla justo. Curabitur vulputate ut nisl et bibendum.</p>'; $this->assertEquals($expectedContent, $content); // And its response processing and response declaration $this->assertEquals(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT, $assessmentItem->getResponseProcessing()->getTemplate()); /** @var ResponseDeclaration $responseDeclaration */ $responseDeclaration = $assessmentItem->getResponseDeclarations()->getArrayCopy()[0]; $this->assertEquals(Cardinality::MULTIPLE, $responseDeclaration->getCardinality()); $this->assertEquals(BaseType::DIRECTED_PAIR, $responseDeclaration->getBaseType()); /** @var Value[] $values */ $values = $responseDeclaration->getCorrectResponse()->getValues()->getArrayCopy(true); $this->assertDirectPair($values[0]->getValue(), 'GAP_0', 'CHOICE_0'); $this->assertDirectPair($values[1]->getValue(), 'GAP_1', 'CHOICE_1'); // And, we don't have mapping because we simply won't $this->assertEquals(null, $responseDeclaration->getMapping()); }
private function buildTemplate(HottextInteraction $interaction) { $templateCollection = new QtiComponentCollection(); foreach ($interaction->getComponents() as $component) { // Ignore `prompt` since its going to be mapped to `stimulus` if (!$component instanceof Prompt) { $templateCollection->attach($component); } } $content = QtiMarshallerUtil::marshallCollection($templateCollection); foreach ($interaction->getComponentsByClassName('hottext') as $hottext) { /** @var Hottext $hottext */ $hottextString = QtiMarshallerUtil::marshall($hottext); $tokenSpan = new span(); $tokenSpan->setClass('lrn_token'); $inlineCollection = new InlineCollection(); foreach ($hottext->getComponents() as $c) { $inlineCollection->attach($c); } $tokenSpan->setContent($inlineCollection); $content = str_replace($hottextString, QtiMarshallerUtil::marshall($tokenSpan), $content); } return $content; }
private function assertInteractionTwo(ChoiceInteraction $interaction, ResponseDeclaration $responseDeclaration) { // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('Pick the odd one out', $promptString); // All the choices also mapped properly /** @var SimpleChoice[] $simpleChoices */ $simpleChoices = $interaction->getSimpleChoices()->getArrayCopy(true); $this->assertEquals($simpleChoices[0]->getIdentifier(), 'CHOICE_0'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[0]->getContent()), 'Tomato'); $this->assertEquals($simpleChoices[1]->getIdentifier(), 'CHOICE_1'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[1]->getContent()), 'Orange'); $this->assertEquals($simpleChoices[2]->getIdentifier(), 'CHOICE_2'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[2]->getContent()), 'Celery'); $this->assertEquals($simpleChoices[3]->getIdentifier(), 'CHOICE_3'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[3]->getContent()), 'Pear'); // Check usual stuff $this->assertEquals(1, $interaction->getMinChoices()); $this->assertEquals(1, $interaction->getMaxChoices()); $this->assertFalse($interaction->mustShuffle()); $this->assertEquals(Orientation::HORIZONTAL, $interaction->getOrientation()); // Check the response declaration fine for mcq with multiple responses $this->assertEquals(BaseType::IDENTIFIER, $responseDeclaration->getBaseType()); $this->assertEquals(Cardinality::SINGLE, $responseDeclaration->getCardinality()); $correctResponse = $responseDeclaration->getCorrectResponse(); $this->assertTrue($correctResponse instanceof CorrectResponse); /** @var Value[] $values */ $values = $correctResponse->getValues()->getArrayCopy(true); $this->assertEquals($values[0]->getValue(), 'CHOICE_2'); $this->assertNull($responseDeclaration->getMapping()); }