diff --git a/src/qtism/common/datatypes/QtiList.php b/src/qtism/common/datatypes/QtiList.php new file mode 100644 index 000000000..f21861f69 --- /dev/null +++ b/src/qtism/common/datatypes/QtiList.php @@ -0,0 +1,120 @@ + + * @license GPLv2 + */ + +namespace qtism\common\datatypes; + +use qtism\common\enums\BaseType; +use qtism\common\enums\Cardinality; + +class QtiList implements QtiDatatype +{ + /** + * A value from the BaseType enumeration. + * + * @var int + */ + private $baseType; + + /** + * An array of QTI base type elements. + * + * @var array + */ + private $items; + + /** + * Create a new QtiList object. + * + * @param string $type + * @param array $items + */ + public function __construct(string $type, array $items) + { + $this->baseType = BaseType::getConstantByName($type); + $this->items = $items; + } + + /** + * Return array of items that QtiList contains. + * + * @return array + */ + public function getItems() + { + return $this->items; + } + + /** + * Get the baseType of the value. This method systematically returns + * the BaseType value. + * + * @return int A value from the BaseType enumeration. + */ + public function getBaseType() + { + return $this->baseType; + } + + /** + * Get the cardinality of the value. This method systematically returns + * the Cardinality::MULTIPLE value. + * + * @return int + */ + public function getCardinality() + { + return Cardinality::MULTIPLE; + } + + /** + * Check if two instance of QtiList are equal. + * + * @param mixed $obj + * @return bool + */ + public function equals($obj) + { + if (!($obj instanceof QtiList)) { + return false; + } + + $originalItems = $obj->getItems(); + $itemsToCompare = $this->getItems(); + + for ($i = 0; $i < count($originalItems); $i++) { + if (!$originalItems[$i]->equals($itemsToCompare[$i])) { + return false; + } + } + + return true; + } + + /** + * @return string + */ + public function __toString() + { + return '[' . implode(', ', $this->items) . ']'; + } +} diff --git a/src/qtism/runtime/pci/json/Unmarshaller.php b/src/qtism/runtime/pci/json/Unmarshaller.php index 984737c5b..44bb7f594 100644 --- a/src/qtism/runtime/pci/json/Unmarshaller.php +++ b/src/qtism/runtime/pci/json/Unmarshaller.php @@ -36,6 +36,7 @@ use qtism\common\datatypes\QtiIdentifier; use qtism\common\datatypes\QtiInteger; use qtism\common\datatypes\QtiIntOrIdentifier; +use qtism\common\datatypes\QtiList; use qtism\common\datatypes\QtiPair; use qtism\common\datatypes\QtiPoint; use qtism\common\datatypes\QtiString; @@ -201,12 +202,31 @@ public function unmarshall($json) if (isset($v['base']) || (array_key_exists('base', $v) && $v['base'] === null)) { $unit = ['base' => $v['base']]; + $unmarshallItem = $this->unmarshallUnit($unit); + } elseif (isset($v['list']) || (array_key_exists('list', $v) && $v['list'] === null)) { + $list = $v['list']; + $listNewItems = []; + + $baseType = key($list); + $listItems = $list[$baseType]; + + foreach ($listItems as $listItem) { + $listItemToConvert = [ + 'base' => [$baseType => $listItem] + ]; + $listNewItems[] = $this->unmarshallUnit($listItemToConvert); + } + + $unmarshallItem = new QtiList($baseType, $listNewItems); } else { + // No value found, let's go for a null value. $unit = ['base' => null]; + $unmarshallItem = $this->unmarshallUnit($unit); } - $returnValue[$v['name']] = $this->unmarshallUnit($unit); + $returnValue[$v['name']] = $unmarshallItem; + } return $returnValue; diff --git a/test/qtismtest/common/datatypes/ListTest.php b/test/qtismtest/common/datatypes/ListTest.php new file mode 100644 index 000000000..dd30c09db --- /dev/null +++ b/test/qtismtest/common/datatypes/ListTest.php @@ -0,0 +1,61 @@ +equals($list2)); + $this::assertTrue($list2->equals($list1)); + $this::assertTrue($list1->equals($list1)); + + $int1 = new QtiInteger(5); + $int2 = new QtiInteger(6); + + $list3 = new QtiList('integer', [$int1, $int2]); + $list4 = new QtiList('integer', [$int1, $int2]); + + $this::assertTrue($list3->equals($list4)); + } + + public function testReturnsFalseWhenListIsDifferent() + { + $str1 = new QtiString('first'); + $str2 = new QtiString('second'); + + $list1 = new QtiList('string', [$str1, $str2]); + $list2 = new QtiList('string', [$str2, $str1]); + + $this::assertFalse($list2->equals($list1)); + } + + public function testConvertsToString() + { + $str1 = new QtiString('first'); + $str2 = new QtiString('second'); + + $list1 = new QtiList('string', [$str1, $str2]); + $this::assertEquals('[first, second]', (string)$list1); + } + + public function testSetBaseType() + { + $str1 = new QtiString('first'); + $list1 = new QtiList('string', [$str1]); + + $this::assertEquals(4, $list1->getBaseType()); + } + +} \ No newline at end of file diff --git a/test/qtismtest/runtime/pci/json/JsonUnmarshallerTest.php b/test/qtismtest/runtime/pci/json/JsonUnmarshallerTest.php index 108d2f9a0..18a837e94 100644 --- a/test/qtismtest/runtime/pci/json/JsonUnmarshallerTest.php +++ b/test/qtismtest/runtime/pci/json/JsonUnmarshallerTest.php @@ -375,4 +375,29 @@ public function unmarshallInvalidProvider() ['{ "record" : [ { "namez" } ] '], ]; } + + public function testUnmarshallListType() + { + $unmarshaller = self::createUnmarshaller(); + $json = ' + { + "record": [ + { "name" : "Søyler", "list": {"string" : ["SØYLE 1: navn=1, verdi=3", "SØYLE 2: navn=1, verdi=4"] } } + ] + } + '; + + $container = $unmarshaller->unmarshall($json); + $list = $container->getArrayCopy(true); + + $key = "Søyler"; + + $this::assertTrue(array_key_exists($key, $list) ); + + $list = $list[$key]; + $items = $list->getItems(); + + $this::assertEquals("SØYLE 1: navn=1, verdi=3", $items[0]->getValue()); + $this::assertEquals("SØYLE 2: navn=1, verdi=4", $items[1]->getValue()); + } }