Passed
Pull Request — master (#698)
by Konrad
04:54 queued 02:04
created

PagesTest::testPullRequest698NoFontsSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 11
c 2
b 0
f 1
nc 1
nop 0
dl 0
loc 26
rs 9.9
1
<?php
2
3
/**
4
 * @file This file is part of the PdfParser library.
5
 *
6
 * @author  Konrad Abicht <[email protected]>
7
 *
8
 * @date    2024-04-19
9
 *
10
 * @license LGPLv3
11
 *
12
 * @url     <https://github.com/smalot/pdfparser>
13
 *
14
 * PdfParser is a pdf library written in PHP, extraction oriented.
15
 * Copyright (C) 2017 - Sébastien MALOT <[email protected]>
16
 *
17
 * This program is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Lesser General Public License as published by
19
 * the Free Software Foundation, either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU Lesser General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Lesser General Public License
28
 * along with this program.
29
 * If not, see <http://www.pdfparser.org/sites/default/LICENSE.txt>.
30
 */
31
32
namespace PHPUnitTests\Integration;
33
34
use PHPUnitTests\TestCase;
35
use Smalot\PdfParser\Document;
36
use Smalot\PdfParser\Element\ElementArray;
37
use Smalot\PdfParser\Font;
38
use Smalot\PdfParser\Header;
39
use Smalot\PdfParser\Page;
40
use Smalot\PdfParser\Pages;
41
use Smalot\PdfParser\Parser;
42
43
/**
44
 * @internal only for test purposes
45
 */
46
class PagesDummy extends Pages
47
{
48
    /**
49
     * The purpose of this function is to bypass the tedious
50
     * work to setup instances which lead to a valid $fonts variable.
51
     *
52
     * @param array<\Smalot\PdfParser\Font> $fonts
53
     *
54
     * @return void
55
     */
56
    public function setFonts($fonts)
57
    {
58
        $this->fonts = $fonts;
59
    }
60
}
61
62
class PagesTest extends TestCase
63
{
64
    /**
65
     * If fonts are not stored in Page instances but in the Pages instance.
66
     *
67
     *      Pages
68
     *        |   `--- fonts = Font[]           <=== will be used to override fonts in Page1 ...
69
     *        |
70
     *        |
71
     *        `--+ Page1
72
     *        |         `--- fonts = null       <=== Will be overwritten with the content of Pages.fonts
73
     *        `--+ ...
74
     *
75
     * @see https://github.com/smalot/pdfparser/pull/698
76
     */
77
    public function testPullRequest698NoFontsSet(): void
78
    {
79
        $document = $this->createMock(Document::class);
80
81
        // Create a Page mock and tell PHPUnit that its setFonts has to be called once
82
        // otherwise an error is raised
83
        $page1 = $this->createMock(Page::class);
84
        $page1->expects($this->once())->method('setFonts');
85
86
        // setup header
87
        $header = new Header([
88
            'Kids' => new ElementArray([
89
                $page1,
90
            ]),
91
        ], $document);
92
93
        $font1 = $this->createMock(Font::class);
94
95
        // Preset fonts variable so we don't have to prepare all the
96
        // prerequisites manually (like creating a Ressources instance
97
        // with Font instances, see Pages::setupFonts())
98
        $pages = new PagesDummy($document, $header);
99
        $pages->setFonts([$font1]);
100
101
        // We expect setFonts is called on $page1, therefore no assertion here
102
        $pages->getPages(true);
103
    }
104
105
    /**
106
     * Dont override fonts list in a Page instance, if available.
107
     *
108
     *      Pages
109
     *        |   `--- fonts = Font[]           <=== Has to be ignored because fonts in Page1 is set
110
     *        |
111
     *        |
112
     *        `--+ Page1
113
     *        |         `--- fonts = Font[]     <=== must not be overwritten
114
     *        `--+ ...
115
     *
116
     * @see https://github.com/smalot/pdfparser/pull/698
117
     */
118
    public function testPullRequest698DontOverride(): void
119
    {
120
        $document = $this->createMock(Document::class);
121
122
        // Setup an empty Page instance and insert a Font instance.
123
        // We wanna see later on, if $font2 is overwritten by $font1.
124
        $font2 = new Font($document);
125
        $page1 = new Page($document);
126
        $page1->setFonts([$font2]);
127
128
        // setup header
129
        $header = new Header([
130
            'Kids' => new ElementArray([
131
                $page1,
132
            ]),
133
        ], $document);
134
135
        $font1 = $this->createMock(Font::class);
136
137
        $pages = new PagesDummy($document, $header);
138
        $pages->setFonts([$font1]);
139
140
        // Trigger setupFonts method in $pages
141
        $pages->getPages(true);
142
143
        // Note:
144
        // $font1 and $font2 are intenionally not both of the same type.
145
        // One is a mock and the other one a real instance of Font.
146
        // This way we can simply check the return value of getFonts here.
147
        // If both were one of the other, we had to use a different assertation approach.
148
        $this->assertEquals([$font2], $page1->getFonts());
149
    }
150
151
    /**
152
     * In this example a Document instance is created, which has one Pages instance with a few Font instances.
153
     * With the new functionality, related Font instances are passed down to related Page instances.
154
     *
155
     * @see https://github.com/smalot/pdfparser/pull/698
156
     */
157
    public function testPullRequest698WithoutUsageOfSetFonts(): void
158
    {
159
        $path = $this->rootDir.'/samples/grouped-by-generator/RichDocument_Generated_by_Libreoffice-6.4_PDF-v1.4.pdf';
160
        $document = (new Parser())->parseFile($path);
161
162
        // get Pages instance from generated Document instance
163
        $objectsOfTypePages = $document->getObjectsByType('Pages');
164
        $this->assertEquals(1, \count($objectsOfTypePages));
165
166
        $pagesInstance = array_values($objectsOfTypePages)[0];
167
168
        // collect Font instance(s) of Page instances
169
        $fonts = [];
170
        foreach ($pagesInstance->getPages() as $page) {
171
            foreach ($page->getFonts() as $font) {
172
                $fonts[$font->getName()] = $font;
173
            }
174
        }
175
176
        // collect Font instance(s) of Pages instance itself
177
        $list = $pagesInstance->get('Resources')->get('Font')->getHeader()->getElements();
178
        $fontsToCompareAgainst = [];
179
        foreach ($list as $font) {
180
            $fontsToCompareAgainst[$font->getName()] = $font;
181
        }
182
183
        // check if font names are equal
184
        $this->assertEquals(
185
            array_keys($fonts),
186
            array_keys($fontsToCompareAgainst)
187
        );
188
    }
189
}
190