Skip to content
Snippets Groups Projects
Commit 74a068fd authored by srosse's avatar srosse
Browse files

OO-2962: fix wrong feedback rule by single choice assessment builder for QTI 2.1

parent d5696d09
No related branches found
No related tags found
No related merge requests found
......@@ -41,7 +41,6 @@ import uk.ac.ed.ph.jqtiplus.node.expression.general.MapResponse;
import uk.ac.ed.ph.jqtiplus.node.expression.general.Variable;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.IsNull;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.Match;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.Not;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.Sum;
import uk.ac.ed.ph.jqtiplus.node.item.AssessmentItem;
import uk.ac.ed.ph.jqtiplus.node.item.CorrectResponse;
......@@ -317,11 +316,10 @@ public class SingleChoiceAssessmentItemBuilder extends SimpleChoiceAssessmentIte
/*
<responseCondition>
<responseIf>
<not>
<isNull>
<variable identifier="RESPONSE_1" />
</isNull>
</not>
<match>
<variable identifier="RESPONSE_1" />
<correct identifier="RESPONSE_1" />
</match>
<setOutcomeValue identifier="SCORE">
<sum>
<variable identifier="SCORE" />
......@@ -330,7 +328,7 @@ public class SingleChoiceAssessmentItemBuilder extends SimpleChoiceAssessmentIte
</setOutcomeValue>
<setOutcomeValue identifier="FEEDBACKBASIC">
<baseValue baseType="identifier">
incorrect
correct
</baseValue>
</setOutcomeValue>
</responseIf>
......@@ -339,17 +337,20 @@ public class SingleChoiceAssessmentItemBuilder extends SimpleChoiceAssessmentIte
ResponseIf responseIf = new ResponseIf(rule);
rule.setResponseIf(responseIf);
Not not = new Not(responseIf);
responseIf.getExpressions().add(not);
IsNull isNull = new IsNull(not);
not.getExpressions().add(isNull);
Variable responseVar = new Variable(isNull);
ComplexReferenceIdentifier choiceResponseIdentifier
= ComplexReferenceIdentifier.parseString(choiceInteraction.getResponseIdentifier().toString());
responseVar.setIdentifier(choiceResponseIdentifier);
isNull.getExpressions().add(responseVar);
{// match the correct answer
Match match = new Match(responseIf);
responseIf.getExpressions().add(match);
Variable responseVar = new Variable(match);
ComplexReferenceIdentifier choiceResponseIdentifier
= ComplexReferenceIdentifier.parseString(choiceInteraction.getResponseIdentifier().toString());
responseVar.setIdentifier(choiceResponseIdentifier);
match.getExpressions().add(responseVar);
Correct correct = new Correct(match);
correct.setIdentifier(choiceResponseIdentifier);
match.getExpressions().add(correct);
}
{// outcome score
SetOutcomeValue scoreOutcome = new SetOutcomeValue(responseIf);
......@@ -369,9 +370,40 @@ public class SingleChoiceAssessmentItemBuilder extends SimpleChoiceAssessmentIte
}
{//outcome feedback
SetOutcomeValue incorrectOutcomeValue = new SetOutcomeValue(responseIf);
SetOutcomeValue correctOutcomeValue = new SetOutcomeValue(responseIf);
correctOutcomeValue.setIdentifier(QTI21Constants.FEEDBACKBASIC_IDENTIFIER);
responseIf.getResponseRules().add(correctOutcomeValue);
BaseValue correctValue = new BaseValue(correctOutcomeValue);
correctValue.setBaseTypeAttrValue(BaseType.IDENTIFIER);
correctValue.setSingleValue(QTI21Constants.CORRECT_IDENTIFIER_VALUE);
correctOutcomeValue.setExpression(correctValue);
}
ResponseElse responseElse = new ResponseElse(rule);
rule.setResponseElse(responseElse);
{//outcome score
SetOutcomeValue scoreOutcome = new SetOutcomeValue(responseElse);
scoreOutcome.setIdentifier(QTI21Constants.SCORE_IDENTIFIER);
responseElse.getResponseRules().add(scoreOutcome);
Sum sum = new Sum(scoreOutcome);
scoreOutcome.getExpressions().add(sum);
Variable scoreVar = new Variable(sum);
scoreVar.setIdentifier(QTI21Constants.SCORE_CLX_IDENTIFIER);
sum.getExpressions().add(scoreVar);
MapResponse mapResponse = new MapResponse(sum);
mapResponse.setIdentifier(choiceInteraction.getResponseIdentifier());
sum.getExpressions().add(mapResponse);
}
{// outcome feedback
SetOutcomeValue incorrectOutcomeValue = new SetOutcomeValue(responseElse);
incorrectOutcomeValue.setIdentifier(QTI21Constants.FEEDBACKBASIC_IDENTIFIER);
responseIf.getResponseRules().add(incorrectOutcomeValue);
responseElse.getResponseRules().add(incorrectOutcomeValue);
BaseValue incorrectValue = new BaseValue(incorrectOutcomeValue);
incorrectValue.setBaseTypeAttrValue(BaseType.IDENTIFIER);
......
......@@ -19,15 +19,26 @@
*/
package org.olat.ims.qti21.model.xml;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.WebappHelper;
import org.olat.fileresource.types.ImsQTI21Resource.PathResourceLocator;
import org.olat.ims.qti21.QTI21Constants;
import org.olat.ims.qti21.model.xml.interactions.SimpleChoiceAssessmentItemBuilder.ScoreEvaluation;
import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder;
......@@ -39,8 +50,13 @@ import uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.SimpleChoice;
import uk.ac.ed.ph.jqtiplus.reading.AssessmentObjectXmlLoader;
import uk.ac.ed.ph.jqtiplus.reading.QtiXmlReader;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentItem;
import uk.ac.ed.ph.jqtiplus.running.ItemSessionController;
import uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer;
import uk.ac.ed.ph.jqtiplus.types.Identifier;
import uk.ac.ed.ph.jqtiplus.types.ResponseData;
import uk.ac.ed.ph.jqtiplus.types.StringResponseData;
import uk.ac.ed.ph.jqtiplus.value.FloatValue;
import uk.ac.ed.ph.jqtiplus.value.Value;
import uk.ac.ed.ph.jqtiplus.xmlutils.locators.ResourceLocator;
/**
......@@ -51,6 +67,8 @@ import uk.ac.ed.ph.jqtiplus.xmlutils.locators.ResourceLocator;
*/
public class SingleChoiceAssessmentItemBuilderTest {
private static final OLog log = Tracing.createLoggerFor(SingleChoiceAssessmentItemBuilderTest.class);
/**
* Check if a bare bone multiple choice created with our builder make a valid assessmentItem.
*
......@@ -92,6 +110,55 @@ public class SingleChoiceAssessmentItemBuilderTest {
Assert.assertEquals(ScoreEvaluation.allCorrectAnswers, itemBuilder.getScoreEvaluationMode());
}
@Test
public void createSingleAssessmentItem_allCorrectAnswers() throws IOException {
QtiSerializer qtiSerializer = new QtiSerializer(new JqtiExtensionManager());
SingleChoiceAssessmentItemBuilder itemBuilder = new SingleChoiceAssessmentItemBuilder("Single choice", "Single choice", qtiSerializer);
itemBuilder.setQuestion("<p>Hello</p>");
ChoiceInteraction interaction = itemBuilder.getChoiceInteraction();
SimpleChoice choice1 = AssessmentItemFactory.createSimpleChoice(interaction, "One", "sc");
SimpleChoice choice2 = AssessmentItemFactory.createSimpleChoice(interaction, "Two", "sc");
SimpleChoice choice3 = AssessmentItemFactory.createSimpleChoice(interaction, "Three", "sc");
List<SimpleChoice> choiceList = new ArrayList<>();
choiceList.add(choice1);
choiceList.add(choice2);
choiceList.add(choice3);
itemBuilder.setSimpleChoices(choiceList);
itemBuilder.setCorrectAnswer(choice2.getIdentifier());
itemBuilder.setMaxScore(3.0d);
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.allCorrectAnswers);
itemBuilder.build();
File itemFile = new File(WebappHelper.getTmpDir(), "scAssessmentItem" + UUID.randomUUID() + ".xml");
try(FileOutputStream out = new FileOutputStream(itemFile)) {
qtiSerializer.serializeJqtiObject(itemBuilder.getAssessmentItem(), out);
} catch(Exception e) {
log.error("", e);
}
{// correct answers
Map<Identifier, ResponseData> responseMap = new HashMap<>();
Identifier responseIdentifier = itemBuilder.getInteraction().getResponseIdentifier();
responseMap.put(responseIdentifier, new StringResponseData(choice2.getIdentifier().toString()));
ItemSessionController itemSessionController = RunningItemHelper.run(itemFile, responseMap);
Value score = itemSessionController.getItemSessionState().getOutcomeValue(QTI21Constants.SCORE_IDENTIFIER);
Assert.assertEquals(new FloatValue(3.0d), score);
}
{// wrong answer
Map<Identifier, ResponseData> responseMap = new HashMap<>();
Identifier responseIdentifier = itemBuilder.getInteraction().getResponseIdentifier();
responseMap.put(responseIdentifier, new StringResponseData(choice3.getIdentifier().toString()));
ItemSessionController itemSessionController = RunningItemHelper.run(itemFile, responseMap);
Value score = itemSessionController.getItemSessionState().getOutcomeValue(QTI21Constants.SCORE_IDENTIFIER);
Assert.assertEquals(new FloatValue(0.0d), score);
}
FileUtils.deleteDirsAndFiles(itemFile.toPath());
}
private AssessmentItem loadAssessmentItem(URL itemUrl) throws URISyntaxException {
QtiXmlReader qtiXmlReader = new QtiXmlReader(new JqtiExtensionManager());
ResourceLocator fileResourceLocator = new PathResourceLocator(Paths.get(itemUrl.toURI()));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment