From d8495ac9f798bf7713bb76a242c1faf490cacdff Mon Sep 17 00:00:00 2001 From: = Date: Thu, 28 Jul 2016 15:09:57 +0200 Subject: [PATCH] Stronger type juggling in setOutcomeValue rule processor. --- .../rules/SetOutcomeValueProcessor.php | 5 ++ .../rules/SetOutcomeValueProcessorTest.php | 54 +++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/qtism/runtime/rules/SetOutcomeValueProcessor.php b/qtism/runtime/rules/SetOutcomeValueProcessor.php index bbf65216e..af88c5514 100644 --- a/qtism/runtime/rules/SetOutcomeValueProcessor.php +++ b/qtism/runtime/rules/SetOutcomeValueProcessor.php @@ -116,6 +116,11 @@ public function process() { if ($val !== null && $var->getCardinality() === Cardinality::SINGLE) { $baseType = $var->getBaseType(); + // If we are trying to put a container in a scalar, let's make some changes... + if (($val->getCardinality() === Cardinality::MULTIPLE || $val->getCardinality() === Cardinality::ORDERED) && count($val) > 0) { + $val = $val[0]; + } + if ($baseType === BaseType::INTEGER && $val instanceof QtiFloat) { $val = new QtiInteger(intval($val->getValue())); } diff --git a/test/qtism/runtime/rules/SetOutcomeValueProcessorTest.php b/test/qtism/runtime/rules/SetOutcomeValueProcessorTest.php index d6a3e92d6..060026618 100644 --- a/test/qtism/runtime/rules/SetOutcomeValueProcessorTest.php +++ b/test/qtism/runtime/rules/SetOutcomeValueProcessorTest.php @@ -97,11 +97,12 @@ public function testSetOutcomeValueWrongJugglingMultipleOne() { $processor->process(); } - public function testSetOutcomeValueWrongJugglingMultipleTwo() { + public function testSetOutcomeValueJugglingMultiple() { $rule = $this->createComponentFromXml(' 1337.1337 + 7777.7777 '); @@ -110,10 +111,57 @@ public function testSetOutcomeValueWrongJugglingMultipleTwo() { $score = new OutcomeVariable('SCORE', Cardinality::SINGLE, BaseType::INTEGER); $state = new State(array($score)); $processor->setState($state); - - $this->setExpectedException('qtism\\runtime\\rules\\RuleProcessingException'); $processor->process(); + + // In this case, juggling will put the first entry of the multiple container + // in the target single cardinality variable. The float value is then changed into an integer value. + $processor->process(); + $this->assertEquals(1337, $state['SCORE']->getValue()); } + + public function testSetOutcomeValueJugglingOrdered() { + $rule = $this->createComponentFromXml(' + + + 1337.1337 + 7777.7777 + + + '); + + $processor = new SetOutcomeValueProcessor($rule); + $score = new OutcomeVariable('SCORE', Cardinality::SINGLE, BaseType::INTEGER); + $state = new State(array($score)); + $processor->setState($state); + + // In this case, juggling will put the first entry of the multiple container + // in the target single cardinality variable. The float value is then changed into an integer value. + $processor->process(); + $this->assertEquals(1337, $state['SCORE']->getValue()); + } + + public function testSetOutcomeValueWrongJugglingMultipleBecauseWrongBaseType() { + $rule = $this->createComponentFromXml(' + + + hello + world + + + '); + + $processor = new SetOutcomeValueProcessor($rule); + $score = new OutcomeVariable('SCORE', Cardinality::SINGLE, BaseType::INTEGER); + $state = new State(array($score)); + $processor->setState($state); + + $this->setExpectedException( + 'qtism\\runtime\\rules\\RuleProcessingException', + 'Unable to set value hello to variable \'SCORE\' (cardinality = single, baseType = integer).' + ); + + $processor->process(); + } public function testSetOutcomeValueModerate() { $rule = $this->createComponentFromXml('