Skip to content

Commit 6b58664

Browse files
committed
Add: Unit tests for full EPub3 codebase
1 parent 9929f8f commit 6b58664

File tree

19 files changed

+635
-13
lines changed

19 files changed

+635
-13
lines changed

src/PhpWord/Writer/EPub3/Element/AbstractElement.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,22 @@
2727
*/
2828
abstract class AbstractElement extends Word2007AbstractElement
2929
{
30+
/**
31+
* Get class name of writer element based on read element
32+
*
33+
* @param \PhpOffice\PhpWord\Element\AbstractElement $element
34+
* @return string
35+
* @throws \PhpOffice\PhpWord\Exception\Exception
36+
*/
37+
public static function getElementClass($element)
38+
{
39+
$elementClass = str_replace('PhpOffice\\PhpWord\\Element\\', '', get_class($element));
40+
$writerClass = 'PhpOffice\\PhpWord\\Writer\\EPub3\\Element\\' . $elementClass;
41+
42+
if (!class_exists($writerClass)) {
43+
throw new \PhpOffice\PhpWord\Exception\Exception("Writer element class {$writerClass} not found.");
44+
}
45+
46+
return $writerClass;
47+
}
3048
}

src/PhpWord/Writer/EPub3/Element/Image.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ class Image extends AbstractElement
1515
public function write(): void
1616
{
1717
$xmlWriter = $this->getXmlWriter();
18+
$xmlWriter->setIndent(false);
1819
$element = $this->getElement();
1920
if (!$element instanceof ImageElement) {
2021
return;
2122
}
2223
$mediaIndex = $element->getMediaIndex();
23-
$target = 'media/image' . $mediaIndex . '.' . $element->getImageType();
24+
$target = 'media/image' . $mediaIndex . '.' . $element->getImageExtension();
2425
if (!$this->withoutP) {
2526
$xmlWriter->startElement('p');
2627
}

src/PhpWord/Writer/EPub3/Element/Text.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class Text extends AbstractElement
1515
public function write(): void
1616
{
1717
$xmlWriter = $this->getXmlWriter();
18+
$xmlWriter->setIndent(true);
19+
$xmlWriter->setIndentString(' ');
1820
$element = $this->getElement();
1921
if (!$element instanceof \PhpOffice\PhpWord\Element\Text) {
2022
return;
@@ -25,7 +27,7 @@ public function write(): void
2527

2628
if (!$this->withoutP) {
2729
$xmlWriter->startElement('p');
28-
if (!empty($paragraphStyle)) {
30+
if (is_string($paragraphStyle) && $paragraphStyle !== '') {
2931
$xmlWriter->writeAttribute('class', $paragraphStyle);
3032
}
3133
}
@@ -61,13 +63,15 @@ private function writeTrackChanges(?TrackChange $trackChange, bool $isStart): vo
6163

6264
$xmlWriter = $this->getXmlWriter();
6365
if ($trackChange->getChangeType() === TrackChange::INSERTED) {
66+
$xmlWriter->writeRaw("\n ");
6467
$xmlWriter->startElement('ins');
6568
$xmlWriter->writeAttribute('class', 'phpword-change');
6669
$xmlWriter->writeAttribute('data-change-id', $trackChange->getElementId());
6770
if (!$isStart) {
6871
$xmlWriter->endElement();
6972
}
7073
} elseif ($trackChange->getChangeType() === TrackChange::DELETED) {
74+
$xmlWriter->writeRaw("\n ");
7175
$xmlWriter->startElement('del');
7276
$xmlWriter->writeAttribute('class', 'phpword-change');
7377
$xmlWriter->writeAttribute('data-change-id', $trackChange->getElementId());
@@ -76,4 +80,4 @@ private function writeTrackChanges(?TrackChange $trackChange, bool $isStart): vo
7680
}
7781
}
7882
}
79-
}
83+
}

src/PhpWord/Writer/EPub3/Part.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* This file is part of PHPWord - A pure PHP library for reading and writing
5+
* word processing documents.
6+
*
7+
* PHPWord is free software distributed under the terms of the GNU Lesser
8+
* General Public License version 3 as published by the Free Software Foundation.
9+
*
10+
* For the full copyright and license information, please read the LICENSE
11+
* file that was distributed with this source code. For the full list of
12+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
13+
*
14+
* @see https://github.com/PHPOffice/PHPWord
15+
*
16+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17+
*/
18+
19+
namespace PhpOffice\PhpWord\Writer\EPub3;
20+
21+
use PhpOffice\PhpWord\Exception\Exception;
22+
23+
/**
24+
* Factory class for EPub3 parts
25+
*/
26+
class Part
27+
{
28+
/**
29+
* Get the fully qualified class name for a specific part type
30+
*
31+
* @param string $type The type of part (Content, Manifest, Meta, Mimetype)
32+
* @return string The fully qualified class name
33+
* @throws Exception If the part type is invalid
34+
*/
35+
public static function getPartClass(string $type): string
36+
{
37+
$class = 'PhpOffice\\PhpWord\\Writer\\EPub3\\Part\\' . $type;
38+
39+
if (!class_exists($class)) {
40+
throw new Exception("Invalid part type: {$type}");
41+
}
42+
43+
return $class;
44+
}
45+
}

src/PhpWord/Writer/EPub3/Part/Meta.php

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,63 @@
1818

1919
namespace PhpOffice\PhpWord\Writer\EPub3\Part;
2020

21+
use PhpOffice\PhpWord\Shared\XMLWriter;
22+
2123
/**
2224
* Class for EPub3 metadata part.
2325
*/
2426
class Meta extends AbstractPart
2527
{
28+
/**
29+
* Get XML Writer
30+
*
31+
* @return \PhpOffice\PhpWord\Shared\XMLWriter
32+
*/
33+
protected function getXmlWriter()
34+
{
35+
$xmlWriter = new XMLWriter();
36+
$xmlWriter->openMemory();
37+
$xmlWriter->startDocument('1.0', 'UTF-8');
38+
39+
return $xmlWriter;
40+
}
41+
2642
/**
2743
* Write part content.
2844
*
2945
* @return string
3046
*/
31-
public function write()
47+
public function write(): string
3248
{
33-
$content = '<?xml version="1.0" encoding="UTF-8"?>';
34-
$content .= '<metadata xmlns="http://www.idpf.org/2007/opf">';
35-
$content .= '<dc:title>Sample EPub3 Document</dc:title>';
36-
$content .= '<dc:language>en</dc:language>';
37-
$content .= '<dc:identifier id="bookid">urn:uuid:12345</dc:identifier>';
38-
$content .= '<meta property="dcterms:modified">2023-01-01T00:00:00Z</meta>';
39-
$content .= '</metadata>';
40-
41-
return $content;
49+
$xmlWriter = $this->getXmlWriter();
50+
51+
$xmlWriter->startElement('metadata');
52+
$xmlWriter->writeAttribute('xmlns', 'http://www.idpf.org/2007/opf');
53+
$xmlWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
54+
55+
// Write basic metadata
56+
$title = $this->getParentWriter()->getPhpWord()->getDocInfo()->getTitle() ?: 'Sample EPub3 Document';
57+
$xmlWriter->writeRaw('<dc:title>' . htmlspecialchars($title, ENT_QUOTES) . '</dc:title>');
58+
$xmlWriter->writeElement('dc:language', 'en');
59+
$xmlWriter->writeElement('dc:identifier', 'urn:uuid:12345');
60+
$xmlWriter->writeAttribute('id', 'bookid');
61+
62+
// Write document info if available
63+
$docInfo = $this->getParentWriter()->getPhpWord()->getDocInfo();
64+
if ($docInfo) {
65+
if ($docInfo->getCreator()) {
66+
$xmlWriter->writeElement('dc:creator', $docInfo->getCreator());
67+
}
68+
}
69+
70+
// Write modification date
71+
$xmlWriter->startElement('meta');
72+
$xmlWriter->writeAttribute('property', 'dcterms:modified');
73+
$xmlWriter->text('2023-01-01T00:00:00Z');
74+
$xmlWriter->endElement();
75+
76+
$xmlWriter->endElement(); // metadata
77+
78+
return $xmlWriter->getData();
4279
}
4380
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpWordTests\Writer\EPub3\Element;
4+
5+
use PhpOffice\PhpWord\Element\Image;
6+
use PhpOffice\PhpWord\Style\Image as ImageStyle;
7+
use PhpOffice\PhpWord\Writer\EPub3\Element\Image as ImageWriter;
8+
use PHPUnit\Framework\TestCase;
9+
use PhpOffice\PhpWord\Shared\XMLWriter;
10+
11+
class ImageTest extends TestCase
12+
{
13+
/**
14+
* @var XMLWriter
15+
*/
16+
private $xmlWriter;
17+
18+
/**
19+
* @var Image
20+
*/
21+
private $element;
22+
23+
/**
24+
* @var ImageWriter
25+
*/
26+
private $writer;
27+
28+
protected function setUp(): void
29+
{
30+
$this->xmlWriter = new XMLWriter();
31+
$style = new ImageStyle();
32+
$style->setWidth(100);
33+
$style->setHeight(100);
34+
$this->element = new Image('tests/PhpWordTests/_files/images/earth.jpg', $style);
35+
$this->writer = new ImageWriter($this->xmlWriter, $this->element);
36+
}
37+
38+
public function testWrite(): void
39+
{
40+
$this->writer->write();
41+
42+
$expected = '<p><img src="media/image.jpg" style="width:500px;height:500px;"/></p>';
43+
$this->assertEquals($expected, $this->xmlWriter->getData());
44+
}
45+
46+
public function testWriteWithoutP(): void
47+
{
48+
$style = new ImageStyle();
49+
$style->setWidth(100);
50+
$style->setHeight(100);
51+
$this->element = new Image('tests/PhpWordTests/_files/images/earth.jpg', $style);
52+
$this->writer = new ImageWriter($this->xmlWriter, $this->element, true);
53+
54+
$this->writer->write();
55+
56+
$expected = '<img src="media/image.jpg" style="width:500px;height:500px;"/>';
57+
$this->assertEquals($expected, $this->xmlWriter->getData());
58+
}
59+
60+
public function testWriteWithInvalidElement(): void
61+
{
62+
$invalidElement = $this->createMock(\PhpOffice\PhpWord\Element\AbstractElement::class);
63+
$writer = new ImageWriter($this->xmlWriter, $invalidElement);
64+
65+
$writer->write();
66+
67+
$this->assertEquals('', $this->xmlWriter->getData());
68+
}
69+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpWordTests\Writer\EPub3\Element;
4+
5+
use PhpOffice\PhpWord\Element\Text;
6+
use PhpOffice\PhpWord\Element\TrackChange;
7+
use PhpOffice\PhpWord\Writer\EPub3\Element\Text as TextWriter;
8+
use PHPUnit\Framework\TestCase;
9+
use PhpOffice\PhpWord\Shared\XMLWriter;
10+
11+
class TextTest extends TestCase
12+
{
13+
/**
14+
* @var XMLWriter
15+
*/
16+
private $xmlWriter;
17+
18+
/**
19+
* @var Text
20+
*/
21+
private $element;
22+
23+
/**
24+
* @var TextWriter
25+
*/
26+
private $writer;
27+
28+
protected function setUp(): void
29+
{
30+
$this->xmlWriter = new XMLWriter();
31+
$this->element = new Text('Sample Text');
32+
$this->writer = new TextWriter($this->xmlWriter, $this->element);
33+
}
34+
35+
public function testWrite(): void
36+
{
37+
$this->writer->write();
38+
39+
$expected = "<p>\n <span>Sample Text</span>\n</p>\n";
40+
$this->assertEquals($expected, $this->xmlWriter->getData());
41+
}
42+
43+
public function testWriteWithFontStyle(): void
44+
{
45+
$this->element->setFontStyle('customStyle');
46+
47+
$this->writer->write();
48+
49+
$expected = "<p>\n <span class=\"customStyle\">Sample Text</span>\n</p>\n";
50+
$this->assertEquals($expected, $this->xmlWriter->getData());
51+
}
52+
53+
public function testWriteWithParagraphStyle(): void
54+
{
55+
$this->element->setParagraphStyle('paragraphStyle');
56+
57+
$this->writer->write();
58+
59+
$expected = "<p class=\"paragraphStyle\">\n <span>Sample Text</span>\n</p>\n";
60+
$this->assertEquals($expected, $this->xmlWriter->getData());
61+
}
62+
63+
public function testWriteWithoutP(): void
64+
{
65+
$text = new Text('Sample Text');
66+
$xmlWriter = new XMLWriter();
67+
$this->writer = new TextWriter($xmlWriter, $text, true);
68+
69+
$this->writer->write();
70+
71+
$expected = "<span>Sample Text</span>\n";
72+
$this->assertEquals($expected, $xmlWriter->getData());
73+
}
74+
75+
public function testWriteWithInvalidElement(): void
76+
{
77+
$invalidElement = $this->createMock(\PhpOffice\PhpWord\Element\AbstractElement::class);
78+
$writer = new TextWriter($this->xmlWriter, $invalidElement);
79+
80+
$writer->write();
81+
82+
$this->assertEquals('', $this->xmlWriter->getData());
83+
}
84+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpWordTests\Writer\EPub3;
4+
5+
use PhpOffice\PhpWord\Element\Text;
6+
use PhpOffice\PhpWord\Writer\EPub3\Element\AbstractElement;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class ElementTest extends TestCase
10+
{
11+
public function testGetElementClass(): void
12+
{
13+
$element = new Text('test');
14+
$class = AbstractElement::getElementClass($element);
15+
16+
$this->assertEquals('PhpOffice\\PhpWord\\Writer\\EPub3\\Element\\Text', $class);
17+
}
18+
19+
public function testGetElementClassWithInvalidElement(): void
20+
{
21+
$this->expectException(\PhpOffice\PhpWord\Exception\Exception::class);
22+
23+
$element = new \stdClass();
24+
AbstractElement::getElementClass($element);
25+
}
26+
}

0 commit comments

Comments
 (0)