diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bb4d4a5..dbf61cb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -25,7 +25,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 7.1 + php-version: 7.2 extensions: dom, xml coverage: xdebug - name: Create directory public/coverage @@ -35,12 +35,13 @@ jobs: - name: Build Coverage Report run: XDEBUG_MODE=coverage ./vendor/bin/phpunit -c ./ --coverage-text --coverage-html ./public/coverage ### PHPDoc - #- name: Create directory public/docs - # run: mkdir ./public/docs - #- name: Install PhpDocumentor - # run: wget https://phpdoc.org/phpDocumentor.phar && chmod +x phpDocumentor.phar - #- name: Build Documentation - # run: ./phpDocumentor.phar run -d ./src -t ./public/docs + - name: Create directory public/docs + run: mkdir ./public/docs + - name: Install PhpDocumentor + ## Support PHP 7.2 + run: wget https://github.com/phpDocumentor/phpDocumentor/releases/download/v3.0.0/phpDocumentor.phar && chmod +x phpDocumentor.phar + - name: Build Documentation + run: ./phpDocumentor.phar run -d ./src -t ./public/docs ### Deploy - name: Deploy diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index f9d1981..42d7d97 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -81,7 +81,7 @@ jobs: with: php-version: ${{ matrix.php }} extensions: xml - coverage: ${{ (matrix.php == '7.1') && 'xdebug' || 'none' }} + coverage: ${{ (matrix.php == '8.1') && 'xdebug' || 'none' }} - uses: actions/checkout@v4 @@ -89,15 +89,15 @@ jobs: run: composer install --ansi --prefer-dist --no-interaction --no-progress - name: Run PHPUnit - if: matrix.php != '7.1' + if: matrix.php != '8.1' run: ./vendor/bin/phpunit -c phpunit.xml.dist - name: Run PHPUnit (w CodeCoverage) - if: matrix.php == '7.1' - run: ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover build/clover.xml + if: matrix.php == '8.1' + run: XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover build/clover.xml - name: Upload coverage results to Coveralls - if: matrix.php == '7.1' + if: matrix.php == '8.1' env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | diff --git a/.gitignore b/.gitignore index 0c5a060..bda65ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .php_cs.cache +.php-cs-fixer.cache .phpunit.cache .phpunit.result.cache composer.lock diff --git a/composer.json b/composer.json index cc67ec6..4bf7786 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,7 @@ "name": "phpoffice/math", "description": "Math - Manipulate Math Formula", "keywords": ["PHP","mathml", "officemathml"], + "homepage": "https://phpoffice.github.io/Math/", "type": "library", "license": "MIT", "autoload": { @@ -22,7 +23,7 @@ "ext-xml": "*" }, "require-dev": { - "phpunit/phpunit": ">=7.0", + "phpunit/phpunit": "^7.0 || ^9.0", "phpstan/phpstan": "^0.12.88 || ^1.0.0" } } diff --git a/docs/changes/0.1.0.md b/docs/changes/0.1.0.md index 8eaafd5..81ceb3d 100644 --- a/docs/changes/0.1.0.md +++ b/docs/changes/0.1.0.md @@ -4,6 +4,7 @@ - Initial version by [@Progi1984](https://github/Progi1984) - MathML Reader : Support for Semantics by [@Progi1984](https://github/Progi1984) in [#4](https://github.com/PHPOffice/Math/pull/4) +- PHPUnit : Improved Unit Tests by [@Progi1984](https://github/Progi1984) in [#8](https://github.com/PHPOffice/Math/pull/8) ## Bug fixes diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ddf5283..5017e4d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -21,4 +21,9 @@ + + + src + + \ No newline at end of file diff --git a/src/Math/Element/AbstractElement.php b/src/Math/Element/AbstractElement.php index 3888de9..3b1981c 100644 --- a/src/Math/Element/AbstractElement.php +++ b/src/Math/Element/AbstractElement.php @@ -2,30 +2,6 @@ namespace PhpOffice\Math\Element; -use PhpOffice\Math\Math; - abstract class AbstractElement { - /** - * @var Math|AbstractGroupElement|null - */ - protected $parent; - - /** - * @param Math|AbstractGroupElement|null $parent - */ - public function setParent($parent): self - { - $this->parent = $parent; - - return $this; - } - - /** - * @return Math|AbstractGroupElement|null - */ - public function getParent() - { - return $this->parent; - } } diff --git a/src/Math/Element/AbstractGroupElement.php b/src/Math/Element/AbstractGroupElement.php index 85d97f3..4bc925c 100644 --- a/src/Math/Element/AbstractGroupElement.php +++ b/src/Math/Element/AbstractGroupElement.php @@ -12,7 +12,6 @@ abstract class AbstractGroupElement extends AbstractElement public function add(AbstractElement $element): self { $this->elements[] = $element; - $element->setParent($this); return $this; } @@ -23,8 +22,6 @@ public function remove(AbstractElement $element): self return $child != $element; }); - $element->setParent(null); - return $this; } diff --git a/src/Math/Element/Fraction.php b/src/Math/Element/Fraction.php index 511ac99..8812998 100644 --- a/src/Math/Element/Fraction.php +++ b/src/Math/Element/Fraction.php @@ -14,6 +14,12 @@ class Fraction extends AbstractElement */ protected $numerator; + public function __construct(AbstractElement $numerator, AbstractElement $denominator) + { + $this->setNumerator($numerator); + $this->setDenominator($denominator); + } + public function getDenominator(): AbstractElement { return $this->denominator; diff --git a/src/Math/Element/Superscript.php b/src/Math/Element/Superscript.php index 11f1a93..e3a68cc 100644 --- a/src/Math/Element/Superscript.php +++ b/src/Math/Element/Superscript.php @@ -14,6 +14,12 @@ class Superscript extends AbstractElement */ protected $superscript; + public function __construct(AbstractElement $base, AbstractElement $superscript) + { + $this->setBase($base); + $this->setSuperscript($superscript); + } + public function getBase(): AbstractElement { return $this->base; diff --git a/src/Math/Exception/InvalidInputException.php b/src/Math/Exception/InvalidInputException.php new file mode 100644 index 0000000..d0bd5fc --- /dev/null +++ b/src/Math/Exception/InvalidInputException.php @@ -0,0 +1,7 @@ +elements[] = $element; - $element->setParent($this); - - return $this; - } - - /** - * @param Element\AbstractElement $element - * - * @return self - */ - public function remove(Element\AbstractElement $element): self - { - $this->elements = array_filter($this->elements, function ($child) use ($element) { - return $child != $element; - }); - $element->setParent(null); - - return $this; - } - - /** - * @return AbstractElement[] - */ - public function getElements(): array - { - return $this->elements; - } } diff --git a/src/Math/Reader/MathML.php b/src/Math/Reader/MathML.php index 21185fe..4d50a28 100644 --- a/src/Math/Reader/MathML.php +++ b/src/Math/Reader/MathML.php @@ -6,8 +6,9 @@ use DOMElement; use DOMNode; use DOMXPath; -use Exception; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\InvalidInputException; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; class MathML implements ReaderInterface @@ -74,15 +75,19 @@ protected function getElement(DOMNode $nodeElement): Element\AbstractElement $nodeValue = trim($nodeElement->nodeValue); switch ($nodeElement->nodeName) { case 'mfrac': - $element = new Element\Fraction(); $nodeList = $this->xpath->query('*', $nodeElement); if ($nodeList && $nodeList->length == 2) { - $element - ->setNumerator($this->getElement($nodeList->item(0))) - ->setDenominator($this->getElement($nodeList->item(1))); + return new Element\Fraction( + $this->getElement($nodeList->item(0)), + $this->getElement($nodeList->item(1)) + ); } - return $element; + throw new InvalidInputException(sprintf( + '%s : The tag `%s` has not two subelements', + __METHOD__, + $nodeElement->nodeName + )); case 'mi': return new Element\Identifier($nodeValue); case 'mn': @@ -105,19 +110,23 @@ protected function getElement(DOMNode $nodeElement): Element\AbstractElement case 'mrow': return new Element\Row(); case 'msup': - $element = new Element\Superscript(); $nodeList = $this->xpath->query('*', $nodeElement); if ($nodeList && $nodeList->length == 2) { - $element - ->setBase($this->getElement($nodeList->item(0))) - ->setSuperscript($this->getElement($nodeList->item(1))); + return new Element\Superscript( + $this->getElement($nodeList->item(0)), + $this->getElement($nodeList->item(1)) + ); } - return $element; + throw new InvalidInputException(sprintf( + '%s : The tag `%s` has not two subelements', + __METHOD__, + $nodeElement->nodeName + )); case 'semantics': return new Element\Semantics(); default: - throw new Exception(sprintf( + throw new NotImplementedException(sprintf( '%s : The tag `%s` is not implemented', __METHOD__, $nodeElement->nodeName diff --git a/src/Math/Reader/OfficeMathML.php b/src/Math/Reader/OfficeMathML.php index 0f46874..c856023 100644 --- a/src/Math/Reader/OfficeMathML.php +++ b/src/Math/Reader/OfficeMathML.php @@ -5,8 +5,9 @@ use DOMDocument; use DOMNode; use DOMXPath; -use Exception; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\InvalidInputException; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; class OfficeMathML implements ReaderInterface @@ -66,29 +67,40 @@ protected function getElement(DOMNode $nodeElement): Element\AbstractElement { switch ($nodeElement->nodeName) { case 'm:f': - $element = new Element\Fraction(); // Numerator $nodeNumerator = $this->xpath->query('m:num/m:r/m:t', $nodeElement); if ($nodeNumerator && $nodeNumerator->length == 1) { $value = $nodeNumerator->item(0)->nodeValue; if (is_numeric($value)) { - $element->setNumerator(new Element\Numeric(floatval($value))); + $numerator = new Element\Numeric(floatval($value)); } else { - $element->setNumerator(new Element\Identifier($value)); + $numerator = new Element\Identifier($value); } + } else { + throw new InvalidInputException(sprintf( + '%s : The tag `%s` has no numerator defined', + __METHOD__, + $nodeElement->nodeName + )); } // Denominator $nodeDenominator = $this->xpath->query('m:den/m:r/m:t', $nodeElement); if ($nodeDenominator && $nodeDenominator->length == 1) { $value = $nodeDenominator->item(0)->nodeValue; if (is_numeric($value)) { - $element->setDenominator(new Element\Numeric(floatval($value))); + $denominator = new Element\Numeric(floatval($value)); } else { - $element->setDenominator(new Element\Identifier($value)); + $denominator = new Element\Identifier($value); } + } else { + throw new InvalidInputException(sprintf( + '%s : The tag `%s` has no denominator defined', + __METHOD__, + $nodeElement->nodeName + )); } - return $element; + return new Element\Fraction($numerator, $denominator); case 'm:r': $nodeText = $this->xpath->query('m:t', $nodeElement); if ($nodeText && $nodeText->length == 1) { @@ -103,11 +115,15 @@ protected function getElement(DOMNode $nodeElement): Element\AbstractElement return new Element\Identifier($value); } - return new Element\Identifier(''); + throw new InvalidInputException(sprintf( + '%s : The tag `%s` has no tag `m:t` defined', + __METHOD__, + $nodeElement->nodeName + )); case 'm:oMath': return new Element\Row(); default: - throw new Exception(sprintf( + throw new NotImplementedException(sprintf( '%s : The tag `%s` is not implemented', __METHOD__, $nodeElement->nodeName diff --git a/src/Math/Writer/MathML.php b/src/Math/Writer/MathML.php index 76d1a64..d8905f0 100644 --- a/src/Math/Writer/MathML.php +++ b/src/Math/Writer/MathML.php @@ -2,8 +2,8 @@ namespace PhpOffice\Math\Writer; -use Exception; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use XMLWriter; @@ -38,9 +38,11 @@ public function write(Math $math): string protected function writeElementItem(Element\AbstractElement $element): void { + $tagName = $this->getElementTagName($element); + // Element\AbstractGroupElement if ($element instanceof Element\AbstractGroupElement) { - $this->output->startElement($this->getElementTagName($element)); + $this->output->startElement($tagName); foreach ($element->getElements() as $childElement) { $this->writeElementItem($childElement); } @@ -51,7 +53,7 @@ protected function writeElementItem(Element\AbstractElement $element): void // Element\Superscript if ($element instanceof Element\Superscript) { - $this->output->startElement($this->getElementTagName($element)); + $this->output->startElement($tagName); $this->writeElementItem($element->getBase()); $this->writeElementItem($element->getSuperscript()); $this->output->endElement(); @@ -61,7 +63,7 @@ protected function writeElementItem(Element\AbstractElement $element): void // Element\Fraction if ($element instanceof Element\Fraction) { - $this->output->startElement($this->getElementTagName($element)); + $this->output->startElement($tagName); $this->writeElementItem($element->getNumerator()); $this->writeElementItem($element->getDenominator()); $this->output->endElement(); @@ -72,18 +74,20 @@ protected function writeElementItem(Element\AbstractElement $element): void if ($element instanceof Element\Identifier || $element instanceof Element\Numeric || $element instanceof Element\Operator) { - $this->output->startElement($this->getElementTagName($element)); + $this->output->startElement($tagName); $this->output->text((string) $element->getValue()); $this->output->endElement(); return; } - throw new Exception(sprintf( + /* + throw new NotImplementedException(sprintf( '%s : The class `%s` is not implemented', __METHOD__, get_class($element) )); + */ } protected function getElementTagName(Element\AbstractElement $element): string @@ -93,11 +97,13 @@ protected function getElementTagName(Element\AbstractElement $element): string return 'mrow'; } if ($element instanceof Element\AbstractGroupElement) { - throw new Exception(sprintf( + /* + throw new NotImplementedException(sprintf( '%s : The element of the class `%s` has no tag name', __METHOD__, get_class($element) )); + */ } if ($element instanceof Element\Superscript) { @@ -116,7 +122,7 @@ protected function getElementTagName(Element\AbstractElement $element): string return 'mo'; } - throw new Exception(sprintf( + throw new NotImplementedException(sprintf( '%s : The element of the class `%s` has no tag name', __METHOD__, get_class($element) diff --git a/src/Math/Writer/OfficeMathML.php b/src/Math/Writer/OfficeMathML.php index 11153ab..e06b8f4 100644 --- a/src/Math/Writer/OfficeMathML.php +++ b/src/Math/Writer/OfficeMathML.php @@ -2,8 +2,8 @@ namespace PhpOffice\Math\Writer; -use Exception; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use XMLWriter; @@ -37,13 +37,11 @@ public function write(Math $math): string protected function writeElementItem(Element\AbstractElement $element): void { - // Element\AbstractGroupElement - if ($element instanceof Element\AbstractGroupElement) { - $this->output->startElement($this->getElementTagName($element)); + // Element\Row + if ($element instanceof Element\Row) { foreach ($element->getElements() as $childElement) { $this->writeElementItem($childElement); } - $this->output->endElement(); return; } @@ -74,29 +72,28 @@ protected function writeElementItem(Element\AbstractElement $element): void return; } - throw new Exception(sprintf( - '%s : The class `%s` is not implemented', - __METHOD__, - get_class($element) - )); + // Check if managed + $this->getElementTagName($element); } protected function getElementTagName(Element\AbstractElement $element): string { // Group if ($element instanceof Element\AbstractGroupElement) { - throw new Exception(sprintf( + /* + throw new NotImplementedException(sprintf( '%s : The element of the class `%s` has no tag name', __METHOD__, get_class($element) )); + */ } if ($element instanceof Element\Fraction) { return 'm:f'; } - throw new Exception(sprintf( + throw new NotImplementedException(sprintf( '%s : The element of the class `%s` has no tag name', __METHOD__, get_class($element) diff --git a/tests/Math/Element/AbstractGroupElementTest.php b/tests/Math/Element/AbstractGroupElementTest.php new file mode 100644 index 0000000..c192e2f --- /dev/null +++ b/tests/Math/Element/AbstractGroupElementTest.php @@ -0,0 +1,46 @@ +assertIsArray($row->getElements()); + $this->assertCount(0, $row->getElements()); + } + + public function testAdd(): void + { + $identifierA = new Element\Identifier('a'); + $row = new Element\Row(); + + $this->assertCount(0, $row->getElements()); + + $this->assertInstanceOf(Element\AbstractGroupElement::class, $row->add($identifierA)); + + $this->assertCount(1, $row->getElements()); + $this->assertEquals([$identifierA], $row->getElements()); + } + + public function testRemove(): void + { + $identifierA = new Element\Identifier('a'); + + $row = new Element\Row(); + $row->add($identifierA); + + $this->assertCount(1, $row->getElements()); + + $this->assertInstanceOf(Element\AbstractGroupElement::class, $row->remove($identifierA)); + + $this->assertCount(0, $row->getElements()); + } +} diff --git a/tests/Math/Element/FractionTest.php b/tests/Math/Element/FractionTest.php new file mode 100644 index 0000000..61b5224 --- /dev/null +++ b/tests/Math/Element/FractionTest.php @@ -0,0 +1,49 @@ +assertEquals($identifierA, $fraction->getNumerator()); + $this->assertEquals($identifierB, $fraction->getDenominator()); + } + + public function testBase(): void + { + $identifierA = new Element\Identifier('a'); + $identifierB = new Element\Identifier('b'); + $identifierC = new Element\Identifier('c'); + + $fraction = new Fraction($identifierA, $identifierB); + + $this->assertEquals($identifierA, $fraction->getNumerator()); + $this->assertInstanceOf(Fraction::class, $fraction->setNumerator($identifierC)); + $this->assertEquals($identifierC, $fraction->getNumerator()); + } + + public function testFraction(): void + { + $identifierA = new Element\Identifier('a'); + $identifierB = new Element\Identifier('b'); + $identifierC = new Element\Identifier('c'); + + $fraction = new Fraction($identifierA, $identifierB); + + $this->assertEquals($identifierB, $fraction->getDenominator()); + $this->assertInstanceOf(Fraction::class, $fraction->setDenominator($identifierC)); + $this->assertEquals($identifierC, $fraction->getDenominator()); + } +} diff --git a/tests/Math/Element/IdentifierTest.php b/tests/Math/Element/IdentifierTest.php new file mode 100644 index 0000000..ed5c9fa --- /dev/null +++ b/tests/Math/Element/IdentifierTest.php @@ -0,0 +1,18 @@ +assertEquals('x', $operator->getValue()); + } +} diff --git a/tests/Math/Element/NumericTest.php b/tests/Math/Element/NumericTest.php new file mode 100644 index 0000000..ac64927 --- /dev/null +++ b/tests/Math/Element/NumericTest.php @@ -0,0 +1,18 @@ +assertEquals(2, $numeric->getValue()); + } +} diff --git a/tests/Math/Element/OperatorTest.php b/tests/Math/Element/OperatorTest.php new file mode 100644 index 0000000..8ce6f08 --- /dev/null +++ b/tests/Math/Element/OperatorTest.php @@ -0,0 +1,18 @@ +assertEquals('+', $operator->getValue()); + } +} diff --git a/tests/Math/Element/SemanticsTest.php b/tests/Math/Element/SemanticsTest.php new file mode 100644 index 0000000..0ab4cc9 --- /dev/null +++ b/tests/Math/Element/SemanticsTest.php @@ -0,0 +1,34 @@ +assertIsArray($semantics->getAnnotations()); + $this->assertCount(0, $semantics->getAnnotations()); + } + + public function testAnnotation(): void + { + $semantics = new Semantics(); + + $this->assertIsArray($semantics->getAnnotations()); + $this->assertCount(0, $semantics->getAnnotations()); + + $this->assertInstanceOf(Semantics::class, $semantics->addAnnotation('encoding', 'content')); + $this->assertEquals(['encoding' => 'content'], $semantics->getAnnotations()); + $this->assertCount(1, $semantics->getAnnotations()); + + $this->assertEquals('content', $semantics->getAnnotation('encoding')); + $this->assertNull($semantics->getAnnotation('notexisting')); + } +} diff --git a/tests/Math/Element/SuperscriptTest.php b/tests/Math/Element/SuperscriptTest.php new file mode 100644 index 0000000..2080b77 --- /dev/null +++ b/tests/Math/Element/SuperscriptTest.php @@ -0,0 +1,46 @@ +assertInstanceOf(Element\Identifier::class, $superscript->getBase()); + $this->assertInstanceOf(Element\Identifier::class, $superscript->getSuperscript()); + } + + public function testBase(): void + { + $identifierA = new Element\Identifier('a'); + $identifierB = new Element\Identifier('b'); + $identifierC = new Element\Identifier('c'); + + $superscript = new Superscript($identifierA, $identifierB); + + $this->assertEquals($identifierA, $superscript->getBase()); + $this->assertInstanceOf(Superscript::class, $superscript->setBase($identifierC)); + $this->assertEquals($identifierC, $superscript->getBase()); + } + + public function testSuperscript(): void + { + $identifierA = new Element\Identifier('a'); + $identifierB = new Element\Identifier('b'); + $identifierC = new Element\Identifier('c'); + + $superscript = new Superscript($identifierA, $identifierB); + + $this->assertEquals($identifierB, $superscript->getSuperscript()); + $this->assertInstanceOf(Superscript::class, $superscript->setSuperscript($identifierC)); + $this->assertEquals($identifierC, $superscript->getSuperscript()); + } +} diff --git a/tests/Math/Reader/MathMLTest.php b/tests/Math/Reader/MathMLTest.php index 69483d3..cd1ab0d 100644 --- a/tests/Math/Reader/MathMLTest.php +++ b/tests/Math/Reader/MathMLTest.php @@ -5,15 +5,14 @@ namespace Tests\PhpOffice\Math\Reader; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\InvalidInputException; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use PhpOffice\Math\Reader\MathML; use PHPUnit\Framework\TestCase; class MathMLTest extends TestCase { - /** - * @covers \MathML::read - */ public function testReadBasic(): void { $content = ' @@ -94,9 +93,6 @@ public function testReadBasic(): void $this->assertEquals('c', $subElement->getValue()); } - /** - * @covers \MathML::read - */ public function testReadFraction(): void { $content = ' @@ -152,9 +148,40 @@ public function testReadFraction(): void $this->assertEquals('d', $denominator->getValue()); } - /** - * @covers \MathML::read - */ + public function testReadFractionInvalid(): void + { + $this->expectException(InvalidInputException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\MathML::getElement : The tag `mfrac` has not two subelements'); + + $content = ' + + + + a + + '; + + $reader = new MathML(); + $math = $reader->read($content); + } + + public function testReadSuperscriptInvalid(): void + { + $this->expectException(InvalidInputException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\MathML::getElement : The tag `msup` has not two subelements'); + + $content = ' + + + + a + + '; + + $reader = new MathML(); + $math = $reader->read($content); + } + public function testReadSemantics(): void { $content = ' @@ -196,4 +223,21 @@ public function testReadSemantics(): void $this->assertCount(1, $element->getAnnotations()); $this->assertEquals('{π} over {2} + { a } * 2', $element->getAnnotation('StarMath 5.0')); } + + public function testReadNotImplemented(): void + { + $this->expectException(NotImplementedException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\MathML::getElement : The tag `mnotexisting` is not implemented'); + + $content = ' + + + + a + + '; + + $reader = new MathML(); + $math = $reader->read($content); + } } diff --git a/tests/Math/Reader/OfficeMathMLTest.php b/tests/Math/Reader/OfficeMathMLTest.php index c88bf60..2bc8d88 100644 --- a/tests/Math/Reader/OfficeMathMLTest.php +++ b/tests/Math/Reader/OfficeMathMLTest.php @@ -5,22 +5,21 @@ namespace Tests\PhpOffice\Math\Reader; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\InvalidInputException; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use PhpOffice\Math\Reader\OfficeMathML; use PHPUnit\Framework\TestCase; class OfficeMathMLTest extends TestCase { - /** - * @covers \OfficeMathML::read - */ public function testRead(): void { $content = ' - π - 2 + 2 + π '; @@ -44,18 +43,15 @@ public function testRead(): void /** @var Element\Identifier $numerator */ $numerator = $subElement->getNumerator(); - $this->assertInstanceOf(Element\Identifier::class, $numerator); - $this->assertEquals('π', $numerator->getValue()); + $this->assertInstanceOf(Element\Numeric::class, $numerator); + $this->assertEquals(2, $numerator->getValue()); /** @var Element\Numeric $denominator */ $denominator = $subElement->getDenominator(); - $this->assertInstanceOf(Element\Numeric::class, $denominator); - $this->assertEquals(2, $denominator->getValue()); + $this->assertInstanceOf(Element\Identifier::class, $denominator); + $this->assertEquals('π', $denominator->getValue()); } - /** - * @covers \OfficeMathML::read - */ public function testReadWithWTag(): void { $content = ' @@ -130,4 +126,72 @@ public function testReadWithWTag(): void $this->assertInstanceOf(Element\Numeric::class, $element); $this->assertEquals(2, $element->getValue()); } + + public function testReadFractionNoNumerator(): void + { + $this->expectException(InvalidInputException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\OfficeMathML::getElement : The tag `m:f` has no numerator defined'); + + $content = ' + + + 2 + + + '; + + $reader = new OfficeMathML(); + $math = $reader->read($content); + } + + public function testReadFractionNoDenominator(): void + { + $this->expectException(InvalidInputException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\OfficeMathML::getElement : The tag `m:f` has no denominator defined'); + + $content = ' + + + π + + + '; + + $reader = new OfficeMathML(); + $math = $reader->read($content); + } + + public function testReadBasicNoText(): void + { + $this->expectException(InvalidInputException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\OfficeMathML::getElement : The tag `m:r` has no tag `m:t` defined'); + + $content = ' + + + a + + + '; + + $reader = new OfficeMathML(); + $math = $reader->read($content); + } + + public function testReadNotImplemented(): void + { + $this->expectException(NotImplementedException::class); + $this->expectExceptionMessage('PhpOffice\Math\Reader\OfficeMathML::getElement : The tag `m:mnotexisting` is not implemented'); + + $content = ' + + + π + + + '; + + $reader = new OfficeMathML(); + $math = $reader->read($content); + } } diff --git a/tests/Math/Writer/MathMLTest.php b/tests/Math/Writer/MathMLTest.php index 6355446..fe22f48 100644 --- a/tests/Math/Writer/MathMLTest.php +++ b/tests/Math/Writer/MathMLTest.php @@ -5,14 +5,12 @@ namespace Tests\PhpOffice\Math\Writer; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use PhpOffice\Math\Writer\MathML; class MathMLTest extends WriterTestCase { - /** - * @covers \MathML::write - */ public function testWrite(): void { $opTimes = new Element\Operator('⁢'); @@ -25,9 +23,10 @@ public function testWrite(): void $row->add(new Element\Identifier('a')); $row->add(clone $opTimes); - $superscript = new Element\Superscript(); - $superscript->setBase(new Element\Identifier('x')); - $superscript->setSuperscript(new Element\Numeric(2)); + $superscript = new Element\Superscript( + new Element\Identifier('x'), + new Element\Numeric(2) + ); $row->add($superscript); $row->add(new Element\Operator('+')); @@ -55,18 +54,14 @@ public function testWrite(): void $this->assertIsSchemaMathMLValid($output); } - /** - * @covers \OfficeMathML::write - */ public function testWriteFraction(): void { $math = new Math(); - $fraction = new Element\Fraction(); - $fraction - ->setDenominator(new Element\Numeric(2)) - ->setNumerator(new Element\Identifier('π')) - ; + $fraction = new Element\Fraction( + new Element\Identifier('π'), + new Element\Numeric(2) + ); $math->add($fraction); $writer = new MathML(); @@ -84,4 +79,26 @@ public function testWriteFraction(): void $this->assertEquals($expected, $output); $this->assertIsSchemaMathMLValid($output); } + + public function testWriteNotImplemented(): void + { + $this->expectException(NotImplementedException::class); + if (method_exists($this, 'expectExceptionMessageRegExp')) { + $this->expectExceptionMessageRegExp('/PhpOffice\\\Math\\\Writer\\\MathML::getElementTagName : The element of the class/'); + $this->expectExceptionMessageRegExp('/has no tag name/'); + } else { + // @phpstan-ignore-next-line + $this->expectExceptionMessageMatches('/PhpOffice\\\Math\\\Writer\\\MathML::getElementTagName : The element of the class/'); + // @phpstan-ignore-next-line + $this->expectExceptionMessageMatches('/has no tag name/'); + } + + $math = new Math(); + + $object = new class() extends Element\AbstractElement {}; + $math->add($object); + + $writer = new MathML(); + $output = $writer->write($math); + } } diff --git a/tests/Math/Writer/OfficeMathMLTest.php b/tests/Math/Writer/OfficeMathMLTest.php index 68d2016..385e868 100644 --- a/tests/Math/Writer/OfficeMathMLTest.php +++ b/tests/Math/Writer/OfficeMathMLTest.php @@ -5,23 +5,20 @@ namespace Tests\PhpOffice\Math\Writer; use PhpOffice\Math\Element; +use PhpOffice\Math\Exception\NotImplementedException; use PhpOffice\Math\Math; use PhpOffice\Math\Writer\OfficeMathML; class OfficeMathMLTest extends WriterTestCase { - /** - * @covers \OfficeMathML::write - */ public function testWriteFraction(): void { $math = new Math(); - $fraction = new Element\Fraction(); - $fraction - ->setDenominator(new Element\Numeric(2)) - ->setNumerator(new Element\Identifier('π')) - ; + $fraction = new Element\Fraction( + new Element\Identifier('π'), + new Element\Numeric(2) + ); $math->add($fraction); $writer = new OfficeMathML(); @@ -37,4 +34,46 @@ public function testWriteFraction(): void . ''; $this->assertEquals($expected, $output); } + + public function testWriteRow(): void + { + $math = new Math(); + + $row = new Element\Row(); + $math->add($row); + + $row->add(new Element\Identifier('x')); + + $writer = new OfficeMathML(); + $output = $writer->write($math); + + $expected = '' + . '' + . 'x' + . '' + . ''; + $this->assertEquals($expected, $output); + } + + public function testWriteNotImplemented(): void + { + $this->expectException(NotImplementedException::class); + if (method_exists($this, 'expectExceptionMessageRegExp')) { + $this->expectExceptionMessageRegExp('/PhpOffice\\\Math\\\Writer\\\OfficeMathML::getElementTagName : The element of the class/'); + $this->expectExceptionMessageRegExp('/has no tag name/'); + } else { + // @phpstan-ignore-next-line + $this->expectExceptionMessageMatches('/PhpOffice\\\Math\\\Writer\\\OfficeMathML::getElementTagName : The element of the class/'); + // @phpstan-ignore-next-line + $this->expectExceptionMessageMatches('/has no tag name/'); + } + + $math = new Math(); + + $object = new class() extends Element\AbstractElement {}; + $math->add($object); + + $writer = new OfficeMathML(); + $output = $writer->write($math); + } }