Skip to content

Commit

Permalink
Merge pull request #2 from ppetersvx/bug/fix-empty-local-namespace
Browse files Browse the repository at this point in the history
Bug/fix empty local namespace
  • Loading branch information
Marcelh1983 authored Sep 14, 2023
2 parents 169649f + e1d807f commit 70203fb
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 42 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,6 @@ ASALocalRun/
.localhistory/
Console.ScoringEngine/appsettings.local.json
nuget.config

# NCrunch extension
*.ncrunchsolution
57 changes: 31 additions & 26 deletions Scoring.Tests/ResponseProcessingTests/GeneralTests.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using Moq;
using Citolab.QTI.ScoringEngine.Interfaces;
using Citolab.QTI.ScoringEngine.Const;
using Citolab.QTI.ScoringEngine.Helpers;
using Citolab.QTI.ScoringEngine.Model;
using Xunit;
using Citolab.QTI.ScoringEngine.ResponseProcessing;
using Microsoft.Extensions.Logging;
using Citolab.QTI.ScoringEngine.Helpers;
using System;
using Castle.Core.Logging;
using Moq;
using Xunit;
using ILogger = Microsoft.Extensions.Logging.ILogger;

namespace Citolab.QTI.ScoringEngine.Tests.Business
{
public class GeneralTests
{

/// <summary>
/// Verify that the SCORE node is updated
/// </summary>
Expand All @@ -30,12 +25,12 @@ public void Rescore_Update_OutcomeVariable()
var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_Update_OutcomeVariable.xml")));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/ITM-50066.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

var scoreValue = assessmentResult.GetScoreForItem("ITM-50066", "SCORE");
Assert.Equal("1", scoreValue);
}

/// <summary>
/// BUG: https://github.com/Citolab/qti-scoring-engine/issues/1
/// </summary>
Expand All @@ -47,7 +42,6 @@ public void Rescore_Update_No_Double_Outcomes()
var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_Update_OutcomeVariable.xml")));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/ITM-50066.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);
var itemResult = assessmentResult.FindElementsByElementAndAttributeValue("itemResult", "identifier", "ITM-50066").FirstOrDefault();
var numberOfOutcomeScoreTotalElements = itemResult.FindElementsByElementAndAttributeValue("outcomeVariable", "identifier", "SCORE").Count();
Expand All @@ -66,7 +60,6 @@ public void Rescore_Update_OutcomeVariable_Incorrect()
// make response incorrect
assessmentResult.ChangeResponse("ITM-50066", "RESPONSE", "A");


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

var scoreValue = assessmentResult.GetScoreForItem("ITM-50066", "SCORE");
Expand All @@ -84,7 +77,6 @@ public void Add_OutcomeVariable_Not_In_AssessmentResult()
var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_Add_OutcomeVariable.xml")));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/ITM-50066.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

var scoreValue = assessmentResult.GetScoreForItem("ITM-50066", "SCORE");
Expand All @@ -96,7 +88,6 @@ public void Add_OutcomeVariable_Not_In_AssessmentResult()
/// Verify that the score will be zero when the given response doesn't match the correct answer
/// </summary>


/// <summary>
/// MH: this used to throw an exception, but now response processing is applied it succeeds
/// </summary>
Expand All @@ -108,7 +99,6 @@ public void ResponseProcessing_No_Correct_Response()
var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_Add_OutcomeVariable.xml")));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/ITM-50066_No_Correct_Response.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

var scoreValue = assessmentResult.GetScoreForItem("ITM-50066", "SCORE");
Expand All @@ -127,7 +117,6 @@ public void NoResponseDeclaringDontChangeManualScore()
Assert.Equal("2", scoreValue);
}


/// <summary>
/// Verify that the score is equal to zero and everything work without a candidateResponse node
/// </summary>
Expand All @@ -139,17 +128,12 @@ public void No_Candidate_Response()
var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_No_Candidate_Response.xml")));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/ITM-50069.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

var scoreValue = assessmentResult.GetScoreForItem("ITM-50069", "SCORE");
Assert.Equal("0", scoreValue);
}





/// <summary>
/// Verify that an exception is thrown when an item has interpolation but no identifier/variable can be found in the LookupOutcomeValue element
/// </summary>
Expand All @@ -162,13 +146,11 @@ public void ResponseProcessing_Interpolation_LogsError_No_Identifier_In_LookupOu
var assessmentResult = new AssessmentResult(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/AssessmentResult_Interpolation.xml")));
var assessmentItem = new AssessmentItem(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/2x/ResponseProcessing/083-Verklanking-Speciale-Tekens_No_Identifier_For_Variable_In_LookupOutcomeValue.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, mockLogger.Object);
//No outcome identifier could be found for the raw score to use with interpolation.
mockLogger.VerifyLog((state, t) => state.ContainsValue("No outcome identifier could be found for the raw score to use with interpolation."), LogLevel.Error, 1);
}


[Fact]
public void ResponseProcessing_30_ExternalMachine()
{
Expand All @@ -177,7 +159,6 @@ public void ResponseProcessing_30_ExternalMachine()
var assessmentResult = new AssessmentResult(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/30/ResponseProcessing/IMS-examples/assessment_result_external_machine.xml")));
var assessmentItem = new AssessmentItem(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/30/ResponseProcessing/IMS-examples/text-entry-qti3.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, mockLogger.Object);

var scoreValue = assessmentResult.GetScoreForItem("textEntry", "SCORE");
Expand All @@ -192,12 +173,36 @@ public void ResponseProcessing_30_Human()
var assessmentResult = new AssessmentResult(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/30/ResponseProcessing/IMS-examples/assessment_result_human.xml")));
var assessmentItem = new AssessmentItem(mockLogger.Object, XDocument.Load(File.OpenRead("Resources/30/ResponseProcessing/IMS-examples/text-entry-qti3.xml")), TestHelper.GetExpressionFactory());


ResponseProcessor.Process(assessmentItem, assessmentResult, mockLogger.Object);

var scoreValue = assessmentResult.GetScoreForItem("textEntry", "SCORE");
// variable should be untouched when human scored
Assert.Equal("1", scoreValue);
}

[Theory]
[InlineData("Resources/30/ResponseProcessing/IMS-examples/assessment_result_external_machine.xml", "Resources/30/ResponseProcessing/IMS-examples/text-entry-qti3.xml")]
[InlineData("Resources/2x/ResponseProcessing/AssessmentResult_Update_OutcomeVariable.xml", "Resources/2x/ResponseProcessing/ITM-50066.xml")]
public void ResponseProcessing_Should_Keep_Local_Namespace(string assessmentResultFile, string assessmentItemFile)
{
var logger = new Mock<ILogger>().Object;

var assessmentResult = new AssessmentResult(logger, XDocument.Load(File.OpenRead(assessmentResultFile)));
var assessmentItem = new AssessmentItem(logger, XDocument.Load(File.OpenRead(assessmentItemFile)), TestHelper.GetExpressionFactory());

var result = ResponseProcessor.Process(assessmentItem, assessmentResult, logger);

Assert.NotNull(result);

// Empty xmlns check can only be done using a raw xml read on an XmlDocument (XDocument filters them out)
var rawXml = result.ToString();
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(rawXml);
string xpathQuery = "//*[namespace-uri() = '' and local-name() != '']";

// No empty xmlns should be found
XmlNodeList nodesWithEmptyXmlns = xmlDoc.SelectNodes(xpathQuery);
Assert.Empty(nodesWithEmptyXmlns);
}
}
}
}
7 changes: 7 additions & 0 deletions Scoring.Tests/ScoringEngine.Tests.v3.ncrunchproject
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<ProjectConfiguration>
<Settings>
<HiddenComponentWarnings>
<Value>LongTestTimesWithoutParallelExecution</Value>
</HiddenComponentWarnings>
</Settings>
</ProjectConfiguration>
28 changes: 13 additions & 15 deletions Scoring/Model/AssessmentResult.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using Microsoft.Extensions.Logging;
using Citolab.QTI.ScoringEngine.Const;
using Citolab.QTI.ScoringEngine.Helpers;
using Citolab.QTI.ScoringEngine.Interfaces;
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Citolab.QTI.ScoringEngine.Helpers;
using Citolab.QTI.ScoringEngine.Interfaces;
using Citolab.QTI.ScoringEngine.ResponseProcessing;
using Microsoft.Extensions.Logging;

namespace Citolab.QTI.ScoringEngine.Model
{
Expand All @@ -20,6 +16,7 @@ internal class AssessmentResult : XDocument
public string SourcedId { get; set; }

private readonly ILogger _logger;

public AssessmentResult(ILogger logger, XDocument assessmentResult) : base(assessmentResult)
{
_logger = logger;
Expand All @@ -37,6 +34,7 @@ public void InitItemResults()
return GetResult<ItemResult>(itemResultElement);
}).ToDictionary(itemResult => itemResult.Identifier, itemResult => itemResult);
}

public void InitTestResults()
{
TestResults = Root
Expand Down Expand Up @@ -101,14 +99,15 @@ public void PersistItemResultOutcome(string itemIdentifier, string outcomeIdenti
{
outcomeVariable = outcome.ToElement().AddDefaultNamespace(Root.GetDefaultNamespace());
itemResultElement.Add(outcomeVariable.AddDefaultNamespace(Root.GetDefaultNamespace()));
} else if (outcomeVariable.GetAttributeValue("external-scored") == "human") {
}
else if (outcomeVariable.GetAttributeValue("external-scored") == "human")
{
// leave human scored outcomes alone
// do nothing
}
else
else
{
outcomeVariable.ReplaceWith(outcome.ToElement());

outcomeVariable.ReplaceWith(outcome.ToElement().AddDefaultNamespace(Root.GetDefaultNamespace()));
}
//if (outcome.Value != null)
//{
Expand All @@ -132,7 +131,7 @@ public void PersistTestResultOutcome(string testIdentifier, string outcomeIdenti

if (outcomeVariable != null)
{
outcomeVariable.ReplaceWith(outcome.ToElement().AddDefaultNamespace(Root.GetDefaultNamespace()));
outcomeVariable.ReplaceWith(outcome.ToElement().AddDefaultNamespace(Root.GetDefaultNamespace()));
}
else
{
Expand All @@ -159,7 +158,6 @@ public void PersistTestResultOutcome(string testIdentifier, string outcomeIdenti
{
return new OutcomeVariable
{
Identifier = outcomeVariable.Identifier(),
BaseType = outcomeVariable.GetAttributeValue("baseType").ToBaseType(),
Cardinality = outcomeVariable.GetAttributeValue("cardinality").ToCardinality(),
Expand All @@ -183,4 +181,4 @@ public void PersistTestResultOutcome(string testIdentifier, string outcomeIdenti
};
}
}
}
}
2 changes: 1 addition & 1 deletion Scoring/ScoringEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<RootNamespace>Citolab.QTI.ScoringEngine</RootNamespace>
<ProjectGuid>{2A7091CD-6A49-4B7B-85BB-A140C8B5397C}</ProjectGuid>
<PackageId>Citolab.QTI.ScoringEngine</PackageId>
<Version>1.2.1</Version>
<Version>1.2.2</Version>
<Company>Cito</Company>
<Copyright>Stichting Cito Instituut voor Toetsontwikkeling, Arnhem (2023)</Copyright>
<Authors>Citolab</Authors>
Expand Down
3 changes: 3 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 1.2.2
* fixed empty xmlns in assessmentResult
*
## 1.2.1
* fixed parsing float fails on specific cultures

Expand Down

0 comments on commit 70203fb

Please sign in to comment.