diff --git a/qtism/data/content/xhtml/html5/Rb.php b/qtism/data/content/xhtml/html5/Rb.php
new file mode 100644
index 000000000..72a50a8f6
--- /dev/null
+++ b/qtism/data/content/xhtml/html5/Rb.php
@@ -0,0 +1,35 @@
+getContent()->getArrayCopy();
} elseif ($component instanceof Figcaption) {
return $component->getContent()->getArrayCopy();
+ } elseif ($component instanceof Ruby) {
+ return $component->getContent()->getArrayCopy();
+ } elseif ($component instanceof Rb) {
+ return $component->getContent()->getArrayCopy();
+ } elseif ($component instanceof Rp) {
+ return $component->getContent()->getArrayCopy();
+ } elseif ($component instanceof Rt) {
+ return $component->getContent()->getArrayCopy();
}
}
@@ -338,6 +354,10 @@ protected function getChildrenElements(DOMElement $element)
return self::getChildElements($element);
} elseif ($localName === 'simpleMatchSet') {
return $this->getChildElementsByTagName($element, 'simpleAssociableChoice');
+ } elseif ($localName === Figure::QTI_CLASS_NAME_FIGURE) {
+ return $this->getChildElementsByTagName($element, [Figcaption::QTI_CLASS_NAME_FIGCAPTION, Img::QTI_CLASS_NAME_IMG]);
+ } elseif ($localName === Ruby::QTI_CLASS_NAME) {
+ return $this->getChildElementsByTagName($element, [Rb::QTI_CLASS_NAME, Rp::QTI_CLASS_NAME, Rt::QTI_CLASS_NAME]);
} elseif ($localName === 'gapImg') {
return $this->getChildElementsByTagName($element, 'object');
} elseif ($element->localName === 'infoControl') {
diff --git a/qtism/data/storage/xml/marshalling/MarshallerFactory.php b/qtism/data/storage/xml/marshalling/MarshallerFactory.php
index 377b6ee27..1ef5068e5 100644
--- a/qtism/data/storage/xml/marshalling/MarshallerFactory.php
+++ b/qtism/data/storage/xml/marshalling/MarshallerFactory.php
@@ -421,7 +421,7 @@ public function createMarshaller($object, array $args = [])
}
} catch (ReflectionException $e) {
$msg = "No marshaller implementation could be found for component '${qtiClassName}'.";
- throw new RuntimeException($msg, 0, $e);
+ throw new MarshallerNotFoundException($msg, 0, $e);
}
$marshaller = $this->instantiateMarshaller($class, $args);
diff --git a/qtism/data/storage/xml/marshalling/Qti22MarshallerFactory.php b/qtism/data/storage/xml/marshalling/Qti22MarshallerFactory.php
index 6281e1c13..85a36a9b2 100644
--- a/qtism/data/storage/xml/marshalling/Qti22MarshallerFactory.php
+++ b/qtism/data/storage/xml/marshalling/Qti22MarshallerFactory.php
@@ -26,6 +26,10 @@
use qtism\common\utils\Reflection;
use qtism\data\content\xhtml\html5\Figcaption;
use qtism\data\content\xhtml\html5\Figure;
+use qtism\data\content\xhtml\html5\Rb;
+use qtism\data\content\xhtml\html5\Rp;
+use qtism\data\content\xhtml\html5\Rt;
+use qtism\data\content\xhtml\html5\Ruby;
use ReflectionClass;
/**
@@ -42,6 +46,10 @@ public function __construct()
parent::__construct();
$this->addMappingEntry(Figure::QTI_CLASS_NAME_FIGURE, Html5ContentMarshaller::class);
$this->addMappingEntry(Figcaption::QTI_CLASS_NAME_FIGCAPTION, Html5ContentMarshaller::class);
+ $this->addMappingEntry(Ruby::QTI_CLASS_NAME, Html5ContentMarshaller::class);
+ $this->addMappingEntry(Rb::QTI_CLASS_NAME, Html5ContentMarshaller::class);
+ $this->addMappingEntry(Rp::QTI_CLASS_NAME, Html5ContentMarshaller::class);
+ $this->addMappingEntry(Rt::QTI_CLASS_NAME, Html5ContentMarshaller::class);
}
/**
diff --git a/qtism/data/storage/xml/marshalling/RecursiveMarshaller.php b/qtism/data/storage/xml/marshalling/RecursiveMarshaller.php
index 9c339aea1..76c6909a6 100644
--- a/qtism/data/storage/xml/marshalling/RecursiveMarshaller.php
+++ b/qtism/data/storage/xml/marshalling/RecursiveMarshaller.php
@@ -221,14 +221,16 @@ protected function marshall(QtiComponent $component)
// Hierarchical node, 1st pass.
$this->mark($node);
$this->pushTrail($node); // repush for a further pass.
- $children = array_reverse($this->getChildrenComponents($node)); // next nodes to explore.
+ $childrenComponentList = $this->getChildrenComponents($node) ?? [];
+ $children = array_reverse($childrenComponentList); // next nodes to explore.
foreach ($children as $c) {
$this->pushTrail($c);
}
- } elseif ($this->isMarked($node)) {
+ } elseif ($this->isMarked($node) && !$node instanceof DOMElement) {
// Push the result on the trail.
- $finals = $this->emptyFinal(count($this->getChildrenComponents($node)));
+ $childrenComponentList = $this->getChildrenComponents($node) ?? [];
+ $finals = $this->emptyFinal(count($childrenComponentList));
$marshaller = $this->getMarshallerFactory()->createMarshaller($node);
$element = $marshaller->marshallChildrenKnown($node, $finals);
$this->pushProcessed($element);
diff --git a/qtism/runtime/rendering/markup/xhtml/XhtmlRenderingEngine.php b/qtism/runtime/rendering/markup/xhtml/XhtmlRenderingEngine.php
index 1af27086e..42ec91fe5 100644
--- a/qtism/runtime/rendering/markup/xhtml/XhtmlRenderingEngine.php
+++ b/qtism/runtime/rendering/markup/xhtml/XhtmlRenderingEngine.php
@@ -23,6 +23,12 @@
namespace qtism\runtime\rendering\markup\xhtml;
+use OAT\Library\QtiItemJsonCompilation\Rt;
+use qtism\data\content\xhtml\html5\Figcaption;
+use qtism\data\content\xhtml\html5\Figure;
+use qtism\data\content\xhtml\html5\Rb;
+use qtism\data\content\xhtml\html5\Rp;
+use qtism\data\content\xhtml\html5\Ruby;
use qtism\runtime\rendering\markup\AbstractMarkupRenderingEngine;
/**
@@ -154,6 +160,11 @@ public function __construct()
$this->registerRenderer('positionObjectStage', new PositionObjectStageRenderer());
$this->registerRenderer('assessmentItem', new AssessmentItemRenderer());
$this->registerRenderer('printedVariable', new PrintedVariableRenderer());
+ $this->registerRenderer(Figure::QTI_CLASS_NAME_FIGURE, new ExternalQtiComponentRenderer());
+ $this->registerRenderer(Figcaption::QTI_CLASS_NAME_FIGCAPTION, new ExternalQtiComponentRenderer());
+ $this->registerRenderer(Ruby::QTI_CLASS_NAME, new ExternalQtiComponentRenderer());
+ $this->registerRenderer(Rb::QTI_CLASS_NAME, new ExternalQtiComponentRenderer());
+ $this->registerRenderer(Rp::QTI_CLASS_NAME, new ExternalQtiComponentRenderer());
// External QTI Components.
$this->registerRenderer('math', new MathRenderer());
diff --git a/test/qtismtest/data/content/xhtml/html5/Html5LayoutElementTest.php b/test/qtismtest/data/content/xhtml/html5/Html5LayoutElementTest.php
index 8f0ed57f3..355fb981c 100644
--- a/test/qtismtest/data/content/xhtml/html5/Html5LayoutElementTest.php
+++ b/test/qtismtest/data/content/xhtml/html5/Html5LayoutElementTest.php
@@ -21,7 +21,9 @@ public function testCreateWithValues(): void
$lang = 'en';
$label = 'This is the label.';
- $subject = new FakeHtml5LayoutElement($title, $role, $id, $class, $lang, $label);
+ $subject = $this->getMockForAbstractClass(Html5LayoutElement::class, [
+ $title, $role, $id, $class, $lang, $label
+ ]);
self::assertSame($title, $subject->getTitle());
self::assertEquals(Role::getConstantByName($role), $subject->getRole());
@@ -34,7 +36,7 @@ public function testCreateWithValues(): void
public function testCreateWithDefaultValues(): void
{
- $subject = new FakeHtml5LayoutElement();
+ $subject = $this->getMockForAbstractClass(Html5LayoutElement::class);
self::assertSame('', $subject->getTitle());
self::assertSame('', $subject->getId());
@@ -46,7 +48,7 @@ public function testCreateWithDefaultValues(): void
public function testSetContent(): void
{
- $subject = new FakeHtml5LayoutElement();
+ $subject = $this->getMockForAbstractClass(Html5LayoutElement::class);
$content = new FlowCollection(
[
new P(),
@@ -61,11 +63,3 @@ public function testSetContent(): void
self::assertEquals($content, $subject->getComponents());
}
}
-
-class FakeHtml5LayoutElement extends Html5LayoutElement
-{
- public function getQtiClassName(): string
- {
- return '';
- }
-}
diff --git a/test/qtismtest/data/content/xhtml/html5/RbTest.php b/test/qtismtest/data/content/xhtml/html5/RbTest.php
new file mode 100644
index 000000000..923b1780c
--- /dev/null
+++ b/test/qtismtest/data/content/xhtml/html5/RbTest.php
@@ -0,0 +1,57 @@
+getId());
+ self::assertEquals($class, $subject->getClass());
+ }
+
+ public function testCreateWithDefaultValues(): void
+ {
+ $subject = new Rb();
+
+ self::assertEquals('', $subject->getId());
+ self::assertEquals('', $subject->getClass());
+ }
+
+ public function testGetQtiClassName(): void
+ {
+ $subject = new Rb();
+
+ self::assertEquals(self::SUBJECT_QTI_CLASS, $subject->getQtiClassName());
+ }
+}
diff --git a/test/qtismtest/data/content/xhtml/html5/RpTest.php b/test/qtismtest/data/content/xhtml/html5/RpTest.php
new file mode 100644
index 000000000..e548e92cc
--- /dev/null
+++ b/test/qtismtest/data/content/xhtml/html5/RpTest.php
@@ -0,0 +1,57 @@
+getId());
+ self::assertEquals($class, $subject->getClass());
+ }
+
+ public function testCreateWithDefaultValues(): void
+ {
+ $subject = new Rp();
+
+ self::assertEquals('', $subject->getId());
+ self::assertEquals('', $subject->getClass());
+ }
+
+ public function testGetQtiClassName(): void
+ {
+ $subject = new Rp();
+
+ self::assertEquals(self::SUBJECT_QTI_CLASS, $subject->getQtiClassName());
+ }
+}
diff --git a/test/qtismtest/data/content/xhtml/html5/RtTest.php b/test/qtismtest/data/content/xhtml/html5/RtTest.php
new file mode 100644
index 000000000..c6e034165
--- /dev/null
+++ b/test/qtismtest/data/content/xhtml/html5/RtTest.php
@@ -0,0 +1,57 @@
+getId());
+ self::assertEquals($class, $subject->getClass());
+ }
+
+ public function testCreateWithDefaultValues(): void
+ {
+ $subject = new Rt();
+
+ self::assertEquals('', $subject->getId());
+ self::assertEquals('', $subject->getClass());
+ }
+
+ public function testGetQtiClassName(): void
+ {
+ $subject = new Rt();
+
+ self::assertEquals(self::SUBJECT_QTI_CLASS, $subject->getQtiClassName());
+ }
+}
diff --git a/test/qtismtest/data/content/xhtml/html5/RubyTest.php b/test/qtismtest/data/content/xhtml/html5/RubyTest.php
new file mode 100644
index 000000000..3226b331e
--- /dev/null
+++ b/test/qtismtest/data/content/xhtml/html5/RubyTest.php
@@ -0,0 +1,57 @@
+getId());
+ self::assertEquals($class, $subject->getClass());
+ }
+
+ public function testCreateWithDefaultValues(): void
+ {
+ $subject = new Ruby();
+
+ self::assertEquals('', $subject->getId());
+ self::assertEquals('', $subject->getClass());
+ }
+
+ public function testGetQtiClassName(): void
+ {
+ $subject = new Ruby();
+
+ self::assertEquals(self::SUBJECT_QTI_CLASS, $subject->getQtiClassName());
+ }
+}
diff --git a/test/qtismtest/data/storage/xml/marshalling/Html5ElementMarshallerTest.php b/test/qtismtest/data/storage/xml/marshalling/Html5ElementMarshallerTest.php
new file mode 100644
index 000000000..88626032a
--- /dev/null
+++ b/test/qtismtest/data/storage/xml/marshalling/Html5ElementMarshallerTest.php
@@ -0,0 +1,300 @@
+',
+ $this->namespaceTag(Figure::QTI_CLASS_NAME_FIGURE),
+ $id,
+ $class,
+ $lang,
+ $label,
+ $title,
+ $role
+ );
+
+ $html5Element = new Figure($title, Role::getConstantByName($role), $id, $class, $lang, $label);
+
+ $this->assertMarshalling($expected, $html5Element);
+ }
+
+ /**
+ * @throws MarshallerNotFoundException
+ * @throws MarshallingException
+ */
+ public function testMarshall22WithDefaultValues(): void
+ {
+ $expected = '<' . $this->namespaceTag(Figure::QTI_CLASS_NAME_FIGURE) . '/>';
+
+ $html5Element = new Figure();
+
+ $this->assertMarshalling($expected, $html5Element);
+ }
+
+ /**
+ * @throws MarshallerNotFoundException
+ */
+ public function testUnmarshall22(): void
+ {
+ $title = 'the title';
+ $role = 'note';
+ $id = 'Identifier';
+ $class = 'a css class';
+ $lang = 'es';
+ $label = 'A label';
+
+ $xml = sprintf(
+ '<%s id="%s" class="%s" xml:lang="%s" label="%s" title="%s" role="%s"/>',
+ $this->namespaceTag(Figure::QTI_CLASS_NAME_FIGURE),
+ $id,
+ $class,
+ $lang,
+ $label,
+ $title,
+ $role
+ );
+
+ $expected = new Figure($title, Role::getConstantByName($role), $id, $class, $lang, $label);
+
+ $this->assertUnmarshalling($expected, $xml);
+ }
+
+ /**
+ * @throws MarshallerNotFoundException
+ */
+ public function testUnmarshall22WithDefaultValues(): void
+ {
+ $xml = '<' . $this->namespaceTag(Figure::QTI_CLASS_NAME_FIGURE) . '/>';
+
+ $expected = new Figure();
+
+ $this->assertUnmarshalling($expected, $xml);
+ }
+
+ public function testRubyMarshaller()
+ {
+ $id = 'id';
+ $class = 'testclass';
+
+ $expected = sprintf(
+ '<%1$s id="%2$s" class="%3$s"><%4$s>真%4$s><%5$s>まこと%5$s><%6$s>真%6$s>%7$s>',
+ $this->namespaceTag(Ruby::QTI_CLASS_NAME),
+ $id,
+ $class,
+ $this->prefixTag(Rt::QTI_CLASS_NAME),
+ $this->prefixTag(Rb::QTI_CLASS_NAME),
+ $this->prefixTag(Rp::QTI_CLASS_NAME),
+ $this->prefixTag(Ruby::QTI_CLASS_NAME)
+ );
+
+ $rb = new Rb();
+ $rb->setContent(new FlowCollection([new TextRun('まこと')]));
+
+ $rt = new Rt();
+ $rt->setContent(new FlowCollection([new TextRun('真')]));
+
+ $rp = new Rp();
+ $rp->setContent(new FlowCollection([new TextRun('真')]));
+
+ $object = new Ruby(null, null, $id, $class);
+ $object->setContent(new FlowCollection([ $rt, $rb, $rp]));
+
+ $this->assertMarshalling($expected, $object);
+ }
+ /**
+ * @throws MarshallerNotFoundException
+ * @throws MarshallingException
+ */
+ public function testRubyMarshall22WithDefaultValues(): void
+ {
+ $expected = sprintf(
+ '<%s/>',
+ $this->namespaceTag(Ruby::QTI_CLASS_NAME)
+ );
+
+ $ruby = new Ruby();
+
+ $this->assertMarshalling($expected, $ruby);
+ }
+
+ /**
+ * @throws MarshallerNotFoundException
+ */
+ public function testRubyUnMarshallerDoesNotExistInQti21(): void
+ {
+ $this->assertHtml5UnmarshallingOnlyInQti22AndAbove(
+ sprintf(
+ '<%s>%s>',
+ $this->namespaceTag(Ruby::QTI_CLASS_NAME),
+ $this->prefixTag(Ruby::QTI_CLASS_NAME)
+ ),
+ Ruby::QTI_CLASS_NAME
+ );
+ }
+
+ /**
+ * @throws MarshallerNotFoundException
+ */
+ public function testRubyUnmarshall22(): void
+ {
+ $id = 'id';
+ $class = 'testclass';
+
+ $xml = sprintf(
+ '<%1$s id="%2$s" class="%3$s">%4$s>',
+ $this->namespaceTag(Ruby::QTI_CLASS_NAME),
+ $id,
+ $class,
+ $this->prefixTag(Ruby::QTI_CLASS_NAME)
+ );
+
+ $expected = new Ruby(null, null, $id, $class);
+
+ $this->assertUnmarshalling($expected, $xml);
+ }
+
+ public function testRubyUnmarshall22WithDefaultValues(): void
+ {
+ $xml = sprintf(
+ '<%s>%s>',
+ $this->namespaceTag(Ruby::QTI_CLASS_NAME),
+ $this->prefixTag(Ruby::QTI_CLASS_NAME)
+ );
+
+ $expected = new Ruby();
+
+ $this->assertUnmarshalling($expected, $xml);
+ }
+
+ /**
+ * @param Html5Element $object
+ * @param string $elementName
+ * @throws MarshallerNotFoundException
+ * @throws MarshallingException
+ */
+ protected function assertHtml5MarshallingOnlyInQti22AndAbove(Html5Element $object, string $elementName): void
+ {
+ $this->expectException(MarshallerNotFoundException::class);
+ $this->expectExceptionMessage('No mapping entry found for QTI class name \'' . $elementName . '\'.');
+ $marshaller = $this->getMarshallerFactory('2.1.0')->createMarshaller($object);
+ $marshaller->marshall($object);
+ }
+
+ /**
+ * @param string $xml
+ * @param string $elementName
+ * @throws MarshallerNotFoundException
+ */
+ public function assertHtml5UnmarshallingOnlyInQti22AndAbove(string $xml, string $elementName): void
+ {
+ $element = $this->createDOMElement($xml);
+ $this->expectException(MarshallerNotFoundException::class);
+ $this->expectExceptionMessage(sprintf(
+ "No marshaller implementation could be found for component '%s'.",
+ $elementName
+ ));
+ $marshaller = $this->getMarshallerFactory('2.1.0')->createMarshaller($element);
+ $marshaller->unmarshall($element);
+ }
+
+ /**
+ * @param string $expected
+ * @param Html5Element $object
+ * @param Marshaller|null $marshaller Optional marshaller to use for marshalling he object.
+ * @throws MarshallerNotFoundException
+ * @throws MarshallingException
+ */
+ protected function assertMarshalling(string $expected, Html5Element $object, Marshaller $marshaller = null): void
+ {
+ if ($marshaller === null) {
+ $marshaller = $this->getMarshallerFactory('2.2.0')->createMarshaller($object);
+ }
+ $element = $marshaller->marshall($object);
+
+ $dom = new DOMDocument('1.0', 'UTF-8');
+ $element = $dom->importNode($element, true);
+ $this->assertEquals($expected, $dom->saveXML($element));
+ }
+
+ /**
+ * @param Html5Element $expected
+ * @param string $xml
+ * @param Marshaller|null $marshaller Optional marshaller to use for marshalling he object.
+ * @throws MarshallerNotFoundException
+ */
+ protected function assertUnmarshalling(Html5Element $expected, string $xml, Marshaller $marshaller = null): void
+ {
+ $element = $this->createDOMElement($xml);
+
+ if ($marshaller === null) {
+ $marshaller = $this->getMarshallerFactory('2.2.0')->createMarshaller($element);
+ }
+
+ $component = $marshaller->unmarshall($element);
+ $this::assertEquals($expected, $component);
+ }
+
+ /**
+ * @param string $xml
+ * @param string $exception
+ * @param string $message
+ * @throws MarshallerNotFoundException
+ */
+ public function assertUnmarshallingException(string $xml, string $exception, string $message): void
+ {
+ $element = $this->createDOMElement($xml);
+ $marshaller = $this->getMarshallerFactory('2.2.0')->createMarshaller($element);
+
+ $this->expectException($exception);
+ $this->expectExceptionMessage($message);
+
+ $marshaller->unmarshall($element);
+ }
+
+ protected function namespaceTag(string $tagName): string
+ {
+ return $this->prefixTag($tagName) . ' xmlns:' . self::HTML5_PREFIX . '="' . self::HTML5_NAMESPACE . '"';
+ }
+
+ protected function prefixTag(string $tagName): string
+ {
+ return self::HTML5_PREFIX . ':' . $tagName;
+ }
+}
diff --git a/test/qtismtest/data/storage/xml/marshalling/Html5LayoutMarshallerTest.php b/test/qtismtest/data/storage/xml/marshalling/Html5LayoutMarshallerTest.php
index 80e2bea36..24c90f6f3 100644
--- a/test/qtismtest/data/storage/xml/marshalling/Html5LayoutMarshallerTest.php
+++ b/test/qtismtest/data/storage/xml/marshalling/Html5LayoutMarshallerTest.php
@@ -3,6 +3,7 @@
namespace qtismtest\data\storage\xml\marshalling;
use DOMDocument;
+use qtism\data\storage\xml\marshalling\MarshallerNotFoundException;
use \RuntimeException;
use qtism\data\content\FlowCollection;
use qtism\data\content\TextRun;
@@ -78,7 +79,7 @@ public function testMarshallerBelow2p2Fails(): void
$figure = new Figure();
$figure->setContent(new FlowCollection([$figCaption]));
- $this->expectException(RuntimeException::class);
+ $this->expectException(MarshallerNotFoundException::class);
$this->expectExceptionMessage(
"No marshaller implementation could be found for component 'figure'."
);
diff --git a/test/qtismtest/data/storage/xml/marshalling/MarshallerTest.php b/test/qtismtest/data/storage/xml/marshalling/MarshallerTest.php
index 039259ec9..c987a1f64 100644
--- a/test/qtismtest/data/storage/xml/marshalling/MarshallerTest.php
+++ b/test/qtismtest/data/storage/xml/marshalling/MarshallerTest.php
@@ -7,13 +7,11 @@
use qtism\common\enums\BaseType;
use qtism\data\expressions\BaseValue;
use qtism\data\ItemSessionControl;
-use qtism\data\QtiComponent;
use qtism\data\storage\xml\marshalling\ItemSessionControlMarshaller;
use qtism\data\storage\xml\marshalling\Marshaller;
use qtismtest\QtiSmTestCase;
use ReflectionClass;
use RuntimeException;
-use stdClass;
/**
* Class MarshallerTest
@@ -87,7 +85,7 @@ public function testGetChildElementsByTagName()
// We should find only 2 direct child elements.
$dom->loadXML('');
$element = $dom->documentElement;
- $marshaller = new FakeMarshaller('2.1.0');
+ $marshaller = $this->getMockForAbstractClass(Marshaller::class, ['2.1.0']);
$this::assertCount(2, $marshaller->getChildElementsByTagName($element, 'child'));
}
@@ -97,7 +95,7 @@ public function testGetChildElementsByTagNameMultiple()
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadXML('');
$element = $dom->documentElement;
- $marshaller = new FakeMarshaller('2.1.0');
+ $marshaller = $this->getMockForAbstractClass(Marshaller::class, ['2.1.0']);
$this::assertCount(3, $marshaller->getChildElementsByTagName($element, ['child', 'grandChild']));
}
@@ -110,7 +108,7 @@ public function testGetChildElementsByTagNameEmpty()
// should be found.
$dom->loadXML('');
$element = $dom->documentElement;
- $marshaller = new FakeMarshaller('2.1.0');
+ $marshaller = $this->getMockForAbstractClass(Marshaller::class, ['2.1.0']);
$this::assertCount(0, $marshaller->getChildElementsByTagName($element, 'child'));
}
@@ -178,32 +176,3 @@ public function testNoSuchMagicMethod()
$marshaller->hello();
}
}
-
-
-
-
-
-
-class FakeMarshaller extends Marshaller
-{
- /**
- * @inheritDoc
- */
- protected function marshall(QtiComponent $component)
- {
- }
-
- /**
- * @inheritDoc
- */
- protected function unmarshall(DOMElement $element)
- {
- }
-
- /**
- * @inheritDoc
- */
- public function getExpectedQtiClassName()
- {
- }
-}
diff --git a/test/qtismtest/runtime/expressions/VariableProcessorTest.php b/test/qtismtest/runtime/expressions/VariableProcessorTest.php
index 3b69068a2..8f8ca62b3 100644
--- a/test/qtismtest/runtime/expressions/VariableProcessorTest.php
+++ b/test/qtismtest/runtime/expressions/VariableProcessorTest.php
@@ -105,12 +105,12 @@ public function testWeighted()
$variableExpr = $this->createComponentFromXml('');
$variableProcessor->setExpression($variableExpr);
$result = $variableProcessor->process();
- $this::assertEquals(11.11, $result[0]->getValue());
- $this::assertEquals(13.31, $result[1]->getValue());
+ $this::assertEquals(11.11, round($result[0]->getValue(), 2));
+ $this::assertEquals(13.31, round($result[1]->getValue(), 2));
// The value in the state must be unchanged.
$stateVal = $assessmentTestSession['Q01.var2'];
- $this::assertEquals(10.1, $stateVal[0]->getValue());
- $this::assertEquals(12.1, $stateVal[1]->getValue());
+ $this::assertEquals(10.1, round($stateVal[0]->getValue(), 1));
+ $this::assertEquals(12.1, round($stateVal[1]->getValue(), 1));
}
public function testMultipleOccurences()
diff --git a/test/samples/custom/items/2_2/ruby_html5.xml b/test/samples/custom/items/2_2/ruby_html5.xml
new file mode 100644
index 000000000..f8097d298
--- /dev/null
+++ b/test/samples/custom/items/2_2/ruby_html5.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
村田
+
+ 真
+ まこと
+
+
の出身地はどこですか
+
+
+
+ 選びなさい
+
+
+ 北海道
+ ほっかいどう
+
+
+ 東北
+ 北陸
+ 関東
+ 甲信越
+ 近畿
+ 関西
+ 四国
+ 中国
+ 九州
+
+
+
+
\ No newline at end of file