Skip to content

Commit

Permalink
feature: add support of 'list' type
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita committed Oct 22, 2021
1 parent 8af0f5d commit 57d3aad
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 1 deletion.
120 changes: 120 additions & 0 deletions src/qtism/common/datatypes/QtiList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
* @author Nikita Kazakevich <nickita.kazakevich@taotesting.com>
* @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) . ']';
}
}
21 changes: 20 additions & 1 deletion src/qtism/runtime/pci/json/Unmarshaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -201,12 +202,30 @@ 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;
Expand Down
61 changes: 61 additions & 0 deletions test/qtismtest/common/datatypes/ListTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace qtismtest\common\datatypes;

use qtism\common\datatypes\QtiInteger;
use qtism\common\datatypes\QtiList;
use qtism\common\datatypes\QtiString;
use qtismtest\QtiSmTestCase;

class ListTest extends QtiSmTestCase
{
public function testReturnsTrueWhenListIsEqualTo()
{
$str1 = new QtiString('first');
$str2 = new QtiString('second');

$list1 = new QtiList('string', [$str1, $str2]);
$list2 = new QtiList('string', [$str1, $str2]);

$this::assertTrue($list1->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());
}

}
25 changes: 25 additions & 0 deletions test/qtismtest/runtime/pci/json/JsonUnmarshallerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

0 comments on commit 57d3aad

Please sign in to comment.