public function buildValidation(ResponseProcessingTemplate $responseProcessingTemplate)
 {
     try {
         switch ($responseProcessingTemplate->getTemplate()) {
             case ResponseProcessingTemplate::MATCH_CORRECT:
                 return $this->getMatchCorrectTemplateValidation();
             case ResponseProcessingTemplate::MAP_RESPONSE:
             case ResponseProcessingTemplate::CC2_MAP_RESPONSE:
                 return $this->getMapResponseTemplateValidation();
             case ResponseProcessingTemplate::NONE:
                 if (!empty($this->responseDeclaration)) {
                     // If the response processing template is not set, simply check whether `mapping` or `correctResponse` exists and
                     // simply use `em
                     if (!empty($this->responseDeclaration->getMapping()) && $this->responseDeclaration->getMapping()->getMapEntries()->count() > 0) {
                         LogService::log('Response processing is not set, the `validation` object is assumed to be mapped based on `mapping` map entries elements');
                         return $this->getMapResponseTemplateValidation();
                     }
                     if (!empty($this->responseDeclaration->getCorrectResponse()) && $this->responseDeclaration->getCorrectResponse()->getValues()->count() > 0) {
                         LogService::log('Response processing is not set, the `validation` object is assumed to be mapped based on `correctResponse` values elements');
                         return $this->getMatchCorrectTemplateValidation();
                     }
                 }
                 return $this->getNoTemplateResponsesValidation();
             default:
                 LogService::log('Unrecognised response processing template. Validation is not available');
         }
     } catch (MappingException $e) {
         LogService::log('Validation is not available. Critical error: ' . $e->getMessage());
     }
     return null;
 }
 public function testShouldHandleMatchCorrectValidationWithoutMultipleResponses()
 {
     $interaction = MatchInteractionBuilder::buildMatchInteraction('testMatchInteraction', [['A' => 'Item A', 'B' => 'Item B'], ['C' => 'Item C', 'D' => 'Item D']]);
     $interaction->setMaxAssociations(2);
     $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect();
     $validResponseIdentifier = [new QtiDirectedPair('A', 'D'), new QtiDirectedPair('B', 'C')];
     $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', $validResponseIdentifier);
     $mapper = new MatchInteractionMapper($interaction, $responseDeclaration, $responseProcessingTemplate);
     /** @var choicematrix $choicematrix */
     $choicematrix = $mapper->getQuestionType();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\choicematrix', $choicematrix);
     $this->assertEquals('choicematrix', $choicematrix->get_type());
     $this->assertCount(2, $choicematrix->get_options());
     $this->assertContains('Item C', $choicematrix->get_options());
     $this->assertContains('Item D', $choicematrix->get_options());
     $this->assertCount(2, $choicematrix->get_stems());
     $this->assertContains('Item A', $choicematrix->get_stems());
     $this->assertContains('Item B', $choicematrix->get_stems());
     $validation = $choicematrix->get_validation();
     $this->assertTrue($validation instanceof choicematrix_validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     $validResponse = $validation->get_valid_response();
     $this->assertTrue($validResponse instanceof choicematrix_validation_valid_response);
     $this->assertEquals(1, $validResponse->get_score());
     $this->assertEquals([[1], [0]], $validResponse->get_value());
     $this->assertFalse($choicematrix->get_multiple_responses());
 }
 public function testSimpleCaseWithMapResponseValidation()
 {
     $interaction = InlineChoiceInteractionBuilder::buildSimple('testIdentifier', ['sydney' => 'Sydney', 'melbourne' => 'Melbourne', 'canberra' => 'Canberra']);
     $responseDeclaration = ResponseDeclarationBuilder::buildWithMapping('testIdentifier', ['sydney' => ['0.5', false], 'melbourne' => ['1', true]]);
     $mapper = new InlineChoiceInteractionMapper($interaction, $responseDeclaration, ResponseProcessingTemplate::mapResponse());
     $question = $mapper->getQuestionType();
     $this->assertNotNull($question);
     $this->assertEquals('clozedropdown', $question->get_type());
     // Should populate possible responses
     $this->assertCount(1, $question->get_possible_responses());
     $this->assertCount(3, $question->get_possible_responses()[0]);
     $this->assertContains('Sydney', $question->get_possible_responses()[0]);
     $this->assertContains('Melbourne', $question->get_possible_responses()[0]);
     $this->assertContains('Canberra', $question->get_possible_responses()[0]);
     // Should have validation object
     $validation = $question->get_validation();
     $this->assertNotNull($validation);
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\clozedropdown_validation', $validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     // Should set both `valid_response` and `alt_responses` for multiple correct values
     // Also, the highest value should be put as `valid_response`
     $validResponse = $validation->get_valid_response();
     $this->assertNotNull($validResponse);
     $this->assertEquals(1, $validResponse->get_score());
     $this->assertEquals(["Melbourne"], $validResponse->get_value());
     $altResponses = $validation->get_alt_responses();
     $this->assertNotNull($altResponses);
     $this->assertCount(1, $altResponses);
     $this->assertEquals(0.5, $altResponses[0]->get_score());
     $this->assertEquals(["Sydney"], $altResponses[0]->get_value());
 }
 public function __construct($questionReference, ItemBody $itemBody, QtiComponentCollection $responseDeclarations = null, ResponseProcessingTemplate $responseProcessingTemplate = null)
 {
     $this->questionReference = $questionReference;
     $this->itemBody = $itemBody;
     $this->responseProcessingTemplate = empty($responseProcessingTemplate) ? ResponseProcessingTemplate::none() : $responseProcessingTemplate;
     if (!empty($responseDeclarations)) {
         foreach ($responseDeclarations as $responseDeclaration) {
             $this->responseDeclarations[$responseDeclaration->getIdentifier()] = $responseDeclaration;
         }
     }
 }
 public function testHotspotWithCircleShape()
 {
     $interaction = HotspotInteractionBuilder::buildWithCircleShapesChoices('testIdentifier');
     $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect();
     $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', ['A']);
     $mapper = new HotspotInteractionMapper($interaction, $responseDeclaration, $responseProcessingTemplate);
     $question = $mapper->getQuestionType();
     $this->assertEquals('hotspot', $question->get_type());
     $this->assertNotEmpty($question->get_area_attributes()->get_global());
     // Assert areas calculation is correct
     $areas = $question->get_areas();
     $this->assertEquals([['x' => 33.5, 'y' => 43.93], ['x' => 41.26, 'y' => 43.93], ['x' => 41.26, 'y' => 38.21], ['x' => 33.5, 'y' => 38.21]], $areas['A']);
     $this->assertEquals([['x' => 53.4, 'y' => 68.56999999999999], ['x' => 61.17, 'y' => 68.56999999999999], ['x' => 61.17, 'y' => 62.86], ['x' => 53.4, 'y' => 62.86]], $areas['B']);
     // Assert exact match validation
     $validation = $question->get_validation();
     $this->assertNotNull($validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     $this->assertEquals(1, $validation->get_valid_response()->get_score());
     $this->assertEquals([0], $validation->get_valid_response()->get_value());
 }
 public function testWithMapResponseValidation()
 {
     $interaction = $this->buildHottextInteraction('identifierOne');
     $interaction->setMaxChoices(2);
     $responseDeclaration = ResponseDeclarationBuilder::buildWithMapping('identifierOne', ['A' => [4], 'C' => [1]]);
     $mapper = new HottextInteractionMapper($interaction, $responseDeclaration, ResponseProcessingTemplate::mapResponse());
     $question = $mapper->getQuestionType();
     $this->assertNotNull($question);
     $this->assertEquals('tokenhighlight', $question->get_type());
     $validation = $question->get_validation();
     $this->assertNotNull($validation);
     $this->assertEquals(5, $validation->get_valid_response()->get_score());
     $this->assertEquals([2, 0], $validation->get_valid_response()->get_value());
     $altResponses = $validation->get_alt_responses();
     $this->assertNotNull($altResponses);
     $this->assertCount(2, $altResponses);
     $this->assertEquals([0], $altResponses[0]->get_value());
     $this->assertEquals(4, $altResponses[0]->get_score());
     $this->assertEquals([2], $altResponses[1]->get_value());
     $this->assertEquals(1, $altResponses[1]->get_score());
 }
 public function testShouldHandleMatchCorrectValidation()
 {
     $testOrderInteraction = OrderInteractionBuilder::buildOrderInteraction('testOrderInteraction', ['A' => 'Order A', 'B' => 'Order B', 'C' => 'Order C'], 'testPrompt');
     $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect();
     $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', ['C', 'B', 'A']);
     $mapper = new OrderInteractionMapper($testOrderInteraction, $responseDeclaration, $responseProcessingTemplate);
     /** @var orderlist $q */
     $q = $mapper->getQuestionType();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\orderlist', $q);
     $this->assertEquals('orderlist', $q->get_type());
     $this->assertEquals('testPrompt', $q->get_stimulus());
     $this->assertEquals(['Order A', 'Order B', 'Order C'], $q->get_list());
     $validation = $q->get_validation();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\orderlist_validation', $validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     /** @var orderlist_validation_valid_response $validResponse */
     $validResponse = $validation->get_valid_response();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\orderlist_validation_valid_response', $validResponse);
     $this->assertEquals(1, $validResponse->get_score());
     $this->assertEquals([2, 1, 0], $validResponse->get_value());
     $this->assertNull($validation->get_alt_responses());
 }
 public function testInvalidResponseProcessingTemplate()
 {
     $interaction = new \qtism\data\content\interactions\TextEntryInteraction('testIdentifier');
     $mapper = new TextEntryInteractionMapper($interaction, null, ResponseProcessingTemplate::getFromTemplateUrl(''));
     $question = $mapper->getQuestionType();
     $this->assertCount(1, LogService::read());
 }
 public function testInvalidResponseProcessingTemplate()
 {
     $itemBody = $this->buildItemBodyWithSingleInteraction();
     $responseDeclarations = new QtiComponentCollection();
     $responseDeclarations->attach(ResponseDeclarationBuilder::buildWithMapping('testIdentifierOne', ['Sydney' => [2, false], 'sydney' => [1, false]]));
     $mapper = new MergedTextEntryInteractionMapper('dummyReference', $itemBody, $responseDeclarations, ResponseProcessingTemplate::getFromTemplateUrl(''));
     $question = $mapper->getQuestionType();
     $this->assertNotNull($question);
     $this->assertNull($question->get_validation());
     $this->assertCount(1, LogService::read());
 }
 public function testSingleInteractionWithMapResponseValidation()
 {
     $itemBody = $this->buildItemBodyWithSingleInteraction();
     $responseDeclarations = new QtiComponentCollection();
     $responseDeclarations->attach(ResponseDeclarationBuilder::buildWithMapping('testIdentifierOne', ['canberra' => [0.5, false], 'sydney' => [2, false]]));
     $mapper = new MergedInlineChoiceInteractionMapper('dummyQuestionReference', $itemBody, $responseDeclarations, ResponseProcessingTemplate::mapResponse());
     $question = $mapper->getQuestionType();
     // Should map question correctly with `validation` object of `exactMatch` scoring type
     $this->assertNotNull($question);
     $this->assertEquals('<p>The Matrix movie is filmed at {{response}}. Boo!</p>', $question->get_template());
     $this->assertEquals('clozedropdown', $question->get_type());
     // Should set both `valid_response` and `alt_responses` for multiple correct values
     $validation = $question->get_validation();
     $this->assertNotNull($validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     $validResponse = $validation->get_valid_response();
     $this->assertNotNull($validResponse);
     $this->assertEquals(2, $validResponse->get_score());
     $this->assertEquals(["Sydney"], $validResponse->get_value());
     $altResponses = $validation->get_alt_responses();
     $this->assertNotNull($altResponses);
     $this->assertCount(1, $altResponses);
     $this->assertEquals(0.5, $altResponses[0]->get_score());
     $this->assertEquals(["Canberra"], $altResponses[0]->get_value());
 }
 public function testMapResponseWithSwappedValuePair()
 {
     $testInteraction = GapMatchInteractionBuilder::buildGapMatchInteraction('testGapMatchInteraction', ['A' => 'Gap A', 'B' => 'Gap B'], ['C' => 'http://img_C', 'D' => 'http://img_D'], ['G1', 'G2']);
     $responseProcessingTemplate = ResponseProcessingTemplate::mapResponse();
     $validResponseIdentifier = ['G1 A' => [1, false], 'G1 B' => [2, false], 'G2 C' => [3, false], 'G2 B' => [4, false], 'D G1' => [5, false]];
     $responseDeclaration = ResponseDeclarationBuilder::buildWithMapping('testIdentifier', $validResponseIdentifier, 'QtiDirectedPair');
     $mapper = new GapMatchInteractionMapper($testInteraction, $responseDeclaration, $responseProcessingTemplate);
     /** @var clozeassociation $q */
     $q = $mapper->getQuestionType();
     $validation = $q->get_validation();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\clozeassociation_validation', $validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     $validResponse = $validation->get_valid_response();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\clozeassociation_validation_valid_response', $validResponse);
     $this->assertEquals(9, $validResponse->get_score());
     $this->assertEquals(['<img src="http://img_D"/>', 'Gap B'], $validResponse->get_value());
     $altResponses = $validation->get_alt_responses();
     $this->assertCount(5, $altResponses);
     $this->assertEquals(8, $altResponses[0]->get_score());
     $this->assertEquals(['<img src="http://img_D"/>', '<img src="http://img_C"/>'], $altResponses[0]->get_value());
     $this->assertEquals(6, $altResponses[1]->get_score());
     $this->assertEquals(['Gap B', 'Gap B'], $altResponses[1]->get_value());
     $this->assertEquals(5, $altResponses[2]->get_score());
     $this->assertEquals(['Gap A', 'Gap B'], $altResponses[2]->get_value());
     $this->assertEquals(5, $altResponses[3]->get_score());
     $this->assertEquals(['Gap B', '<img src="http://img_C"/>'], $altResponses[3]->get_value());
     $this->assertEquals(4, $altResponses[4]->get_score());
     $this->assertEquals(['Gap A', '<img src="http://img_C"/>'], $altResponses[4]->get_value());
 }
 public function __construct(Interaction $interaction, ResponseDeclaration $responseDeclaration = null, ResponseProcessingTemplate $responseProcessingTemplate = null)
 {
     $this->interaction = $interaction;
     $this->responseDeclaration = $responseDeclaration;
     $this->responseProcessingTemplate = empty($responseProcessingTemplate) ? ResponseProcessingTemplate::none() : $responseProcessingTemplate;
 }
Example #13
0
 private function getResponseProcessingTemplate(ResponseProcessing $responseProcessing = null)
 {
     if ($responseProcessing === null) {
         return ResponseProcessingTemplate::none();
     }
     if ($responseProcessing->getResponseRules()->count()) {
         LogService::log('Does not support custom response processing on <responseProcessing>. Ignoring <responseProcessing>');
         return ResponseProcessingTemplate::unsupported();
     }
     if (!empty($responseProcessing->getTemplateLocation())) {
         LogService::log('Does not support \'templateLocation\' on <responseProcessing>. Ignoring <responseProcessing>');
         return ResponseProcessingTemplate::unsupported();
     }
     if (!empty($responseProcessing->getTemplate())) {
         return ResponseProcessingTemplate::getFromTemplateUrl($responseProcessing->getTemplate());
     }
     return ResponseProcessingTemplate::none();
 }
 public function testHasMinChoice()
 {
     $validResponseIdentifier = ['one', 'two'];
     $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', $validResponseIdentifier);
     $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect();
     $optionsMap = ['one' => 'Label One', 'two' => 'Label Two', 'three' => 'Label Three'];
     $interaction = ChoiceInteractionBuilder::buildSimple('testIdentifier', $optionsMap);
     $interaction->setMinChoices(1);
     $interactionMapper = new ChoiceInteractionMapper($interaction, $responseDeclaration, $responseProcessingTemplate);
     $interactionMapper->getQuestionType();
     $this->assertTrue(count(LogService::read()) === 1);
 }
 public function testMatchCorrectValidation()
 {
     $bgObject = new Object('http://img.png', 'image/png');
     $bgObject->setWidth(100);
     $bgObject->setHeight(200);
     $testInteraction = GraphicGapInteractionBuilder::build('testInteraction', $bgObject, ['A' => 'img_A.png', 'B' => 'img_B.png'], ['G1' => [0, 0, 10, 10], 'G2' => [30, 40, 50, 60]]);
     $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect();
     $validResponseIdentifier = [new QtiDirectedPair('A', 'G1'), new QtiDirectedPair('A', 'G2'), new QtiDirectedPair('B', 'G1')];
     $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', $validResponseIdentifier);
     $mapper = new GraphicGapMatchInteractionMapper($testInteraction, $responseDeclaration, $responseProcessingTemplate);
     /** @var imageclozeassociation $q */
     $q = $mapper->getQuestionType();
     $this->assertEquals('imageclozeassociation', $q->get_type());
     $this->assertEquals(['<img src="img_A.png"/>', '<img src="img_B.png"/>'], $q->get_possible_responses());
     $this->assertTrue($q->get_duplicate_responses());
     $this->assertEquals([['x' => 0, 'y' => 0], ['x' => 30, 'y' => 20]], $q->get_response_positions());
     $img = $q->get_image();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_image', $img);
     $this->assertEquals('http://img.png', $img->get_src());
     /** @var imageclozeassociation_validation $validation */
     $validation = $q->get_validation();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_validation', $validation);
     $this->assertEquals('exactMatch', $validation->get_scoring_type());
     /** @var imageclozeassociation_validation_valid_response $validResponse */
     $validResponse = $validation->get_valid_response();
     $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_validation_valid_response', $validResponse);
     $this->assertEquals(1, $validResponse->get_score());
     $this->assertEquals(['<img src="img_A.png"/>', '<img src="img_A.png"/>'], $validResponse->get_value());
     $altResponses = $validation->get_alt_responses();
     $this->assertCount(1, $altResponses);
     $this->assertEquals(1, $altResponses[0]->get_score());
     $this->assertEquals(['<img src="img_B.png"/>', '<img src="img_A.png"/>'], $altResponses[0]->get_value());
 }