UnitTest::testInitializingFormatter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Tests;
6
7
use DOMSelector\DOMSelector;
8
use DOMSelector\Formatters\Decimal;
9
use DOMSelector\Formatters\Integer;
10
use DOMSelector\Providers\TypeProvider;
11
use Exception;
12
use GuzzleHttp\Client;
13
use GuzzleHttp\Exception\RequestException;
14
use GuzzleHttp\Handler\MockHandler;
15
use GuzzleHttp\HandlerStack;
16
use GuzzleHttp\Psr7\Request;
17
use Mockery;
18
use PHPUnit\Framework\TestCase;
19
use Psr\Http\Client\ClientExceptionInterface;
20
use Psr\Http\Client\ClientInterface;
21
use Psr\Http\Message\ResponseInterface;
22
use Psr\Http\Message\StreamInterface;
23
24
class UnitTest extends TestCase
25
{
26
    public function testYamlLoaders()
27
    {
28
        $selector1 = DOMSelector::fromYamlString(file_get_contents('tests/data/files/basic.yaml'));
29
        $selector2 = DOMSelector::fromYamlFile('tests/data/files/basic.yaml');
30
31
        $this->assertInstanceOf(DOMSelector::class, $selector1);
32
        $this->assertInstanceOf(DOMSelector::class, $selector2);
33
        $this->assertSame($selector1->getConfig(), $selector2->getConfig());
34
    }
35
36
    /**
37
     * @throws Exception
38
     */
39
    public function testExtractFromFile()
40
    {
41
        $selector = new DOMSelector([
42
            'h1' => [
43
                'css'  => 'div.jumbotron h1',
44
                'type' => 'Text',
45
            ],
46
        ]);
47
48
        $this->assertSame('My First Bootstrap Page', $selector->extractFromFile('tests/data/files/basic.html')['h1']);
49
    }
50
51
    /**
52
     * @throws Exception
53
     */
54
    public function testExtractFromFileException()
55
    {
56
        $selector = new DOMSelector([]);
57
58
        $this->expectException(Exception::class);
59
60
        $selector->extractFromFile('this-file-doesnt-exists.html');
61
    }
62
63
    /**
64
     * @throws Exception
65
     * @throws ClientExceptionInterface
66
     */
67
    public function testExtractFromUrl()
68
    {
69
        $streamMock = Mockery::mock(StreamInterface::class);
70
        /** @phpstan-ignore-next-line */
71
        $streamMock
72
            ->shouldReceive('getContents')
73
            ->once()
74
            ->andReturn(\file_get_contents('tests/data/files/basic.html'));
75
        $responseMock = Mockery::mock(ResponseInterface::class);
76
        /** @phpstan-ignore-next-line */
77
        $responseMock
78
            ->shouldReceive('getBody')
79
            ->once()
80
            ->andReturn($streamMock);
81
        $clientMock = Mockery::mock(ClientInterface::class);
82
        /** @phpstan-ignore-next-line */
83
        $clientMock
84
            ->shouldReceive('sendRequest')
85
            ->once()
86
            ->andReturn($responseMock);
87
88
        $selector = new DOMSelector([
89
            'h1' => [
90
                'css'  => 'div.jumbotron h1',
91
                'type' => 'Text',
92
            ],
93
        ]);
94
        $extracted = $selector->extractFromUrl('https://example.com/', $clientMock);
95
        $this->assertSame('My First Bootstrap Page', $extracted['h1']);
96
    }
97
98
    public function testExtractFromUrlException()
99
    {
100
        $mock = new MockHandler([
101
            new RequestException('Error Communicating with Server', new Request('GET', 'test')),
102
        ]);
103
104
        $handlerStack = HandlerStack::create($mock);
105
        $client = new Client(['handler' => $handlerStack]);
106
107
        $this->expectException(Exception::class);
108
109
        $selector = new DOMSelector([]);
110
        $selector->extractFromUrl('https://example.com/', $client);
111
    }
112
113
    public function testTypeAttribute()
114
    {
115
        $yaml_string = '
116
        img:
117
            css: "img"
118
            type: Attribute
119
            attribute: width';
120
121
        $selector = DOMSelector::fromYamlString($yaml_string)
122
            ->extract('<img src="photo.jpg" width="80" height="80" />');
123
124
        $this->assertEquals(80, $selector['img']);
125
    }
126
127
    public function testAttributeWithSingleFormatter()
128
    {
129
        $yaml_string = '
130
        width:
131
            css: "img"
132
            type: Attribute
133
            attribute: width
134
            format: 
135
                - Integer';
136
137
        $selector = DOMSelector::fromYamlString($yaml_string, [new Integer()])
138
            ->extract('<img src="photo.jpg" width="200" height="200" />');
139
140
        $this->assertSame('integer', gettype($selector['width']));
141
        $this->assertSame(1000, $selector['width'] * 5);
142
    }
143
144
    public function testAttributeWithMultipleFormat()
145
    {
146
        $yaml_string = '
147
        width:
148
            css: "img"
149
            type: Attribute
150
            attribute: width
151
            format: 
152
                - Integer
153
                - Decimal
154
        height:
155
            css: "img"
156
            type: Attribute
157
            attribute: height
158
            format: 
159
                - Decimal
160
                - Integer';
161
162
        $selector = DOMSelector::fromYamlString($yaml_string, [new Integer(), new Decimal()])
163
            ->extract('<img src="photo.jpg" width="200" height="200" />');
164
165
        $this->assertSame('double', gettype($selector['width']));
166
        $this->assertSame(200.00, $selector['width']);
167
        $this->assertSame('integer', gettype($selector['height']));
168
        $this->assertSame(200, $selector['height']);
169
        $this->assertEquals($selector['width'], $selector['height']);
170
        $this->assertNotSame($selector['width'], $selector['height']);
171
    }
172
173
    public function testTypeHtml()
174
    {
175
        $yaml_string = '
176
        content:
177
            css: "ul li"
178
            type: Html
179
        text:
180
            css: "ul"
181
            type: Text';
182
183
        $selector = DOMSelector::fromYamlString($yaml_string)
184
            ->extract('<ul><li><strong>STRONG!</strong></li></ul>');
185
186
        $this->assertEquals('<strong>STRONG!</strong>', $selector['content']);
187
        $this->assertEquals('STRONG!', $selector['text']);
188
    }
189
190
    public function testTypeImage()
191
    {
192
        $yaml_string = '
193
        img:
194
            css: "img"
195
            type: Image';
196
197
        $selector = DOMSelector::fromYamlString($yaml_string)
198
            ->extract('<img src="photo.jpg" width="80" height="80" />');
199
200
        $this->assertEquals('photo.jpg', $selector['img']);
201
    }
202
203
    public function testTypeLink()
204
    {
205
        $yaml_string = '
206
        link:
207
            css: "a"
208
            type: Link
209
        text:
210
            css: "a"
211
            type: Text';
212
213
        $selector = DOMSelector::fromYamlString($yaml_string)
214
            ->extract('<div><a href="https://example.com/">Click Here!</a> </div>');
215
216
        $this->assertEquals('https://example.com/', $selector['link']);
217
        $this->assertEquals('Click Here!', $selector['text']);
218
    }
219
220
    public function testTypeText()
221
    {
222
        $yaml_string = '
223
        content:
224
            css: "h1"
225
            type: Text';
226
227
        $selector = DOMSelector::fromYamlString($yaml_string)->extract('<div><h1>Hey Bro :)</h1></div>');
228
229
        $this->assertEquals('Hey Bro :)', $selector['content']);
230
    }
231
232
    public function testMissingCss()
233
    {
234
        $yaml_string = '
235
        content:
236
            type: Text';
237
238
        $selector = DOMSelector::fromYamlString($yaml_string)->extract('<div></div>');
239
240
        $this->assertEquals([], $selector['content']);
241
    }
242
243
    public function testDefaultItemType()
244
    {
245
        $yaml_string = '
246
        content:
247
            css: "div"';
248
249
        $selector = DOMSelector::fromYamlString($yaml_string)
250
            ->extract('<div><h1><a href="https://example.com/">Click Here!</a></h1></div>');
251
252
        $this->assertEquals('Click Here!', $selector['content']);
253
    }
254
255
    public function testGetChildItem()
256
    {
257
        $yaml_string = '
258
        items:
259
            css: "div.items"
260
            type: Text
261
            children:
262
                name:
263
                    css: "p"
264
                    type: Text
265
                value:
266
                    css: "span"
267
                    type: Text';
268
269
        $selector = DOMSelector::fromYamlString($yaml_string)
270
            ->extract('<div class="items"><p>key</p><span>value</span></div>');
271
272
        $this->assertEquals([
273
            'items' => [
274
                'name'  => 'key',
275
                'value' => 'value',
276
            ],
277
        ], $selector);
278
    }
279
280
    public function testMultiple()
281
    {
282
        $yaml_string = '
283
        items:
284
            css: "ul.items li"
285
            multiple: True';
286
287
        $selector = DOMSelector::fromYamlString($yaml_string)
288
            ->extract('<ul class="items"><li>One</li><li>Two</li><li>Three</li></ul>');
289
290
        $this->assertEquals([
291
            'items' => [
292
                'One', 'Two', 'Three',
293
            ],
294
        ], $selector);
295
    }
296
297
    public function testMultipleWithChildren()
298
    {
299
        $yaml_string = '
300
        items:
301
            css: "ul li"
302
            multiple: True
303
            children:
304
                firstname:
305
                    css: ".key"
306
                    type: Text
307
                lastname:
308
                    css: ".value"
309
                    type: Text';
310
311
        $html = '
312
        <ul>
313
            <li><p class="key">John</p><p class="value">Doe</p></li>
314
            <li><p class="key">Jane</p><p class="value">Doe</p></li>
315
        </ul>';
316
317
        $selector = DOMSelector::fromYamlString($yaml_string)->extract($html);
318
319
        $this->assertEquals([
320
            'items' => [
321
                0 => [
322
                    'firstname' => 'John',
323
                    'lastname'  => 'Doe',
324
                ],
325
                1 => [
326
                    'firstname' => 'Jane',
327
                    'lastname'  => 'Doe',
328
                ],
329
            ],
330
        ], $selector);
331
    }
332
333
    public function testInitializingFormatter()
334
    {
335
        $yaml_string = '
336
        test:
337
            css: "h1"
338
            type: Text';
339
340
        $selector = DOMSelector::fromYamlString($yaml_string, [new Integer()]);
341
342
        $this->assertEquals(['Integer' => new Integer()], $selector->getFormatters());
343
        $this->assertEquals('Integer', $selector->getFormatter('Integer')->getName());
344
    }
345
346
    public function testFormatterSingle()
347
    {
348
        $yaml_string = '
349
        string:
350
            css: "p"
351
            type: Text
352
        integer:
353
            css: "p"
354
            type: Text
355
            format: Integer';
356
357
        $selector = DOMSelector::fromYamlString($yaml_string, [new Integer()])->extract('<p>1</p>');
358
359
        $this->assertEquals('string', gettype($selector['string']));
360
        $this->assertEquals('integer', gettype($selector['integer']));
361
    }
362
363
    public function testFormatterMultiple()
364
    {
365
        $yaml_string = '
366
        decimal:
367
            css: "p"
368
            type: Text
369
            format: 
370
                - Integer
371
                - Decimal';
372
373
        $selector = DOMSelector::fromYamlString($yaml_string, [new Integer(), new Decimal()])->extract('<p>1</p>');
374
375
        $this->assertSame(1.00, $selector['decimal']);
376
        $this->assertSame('double', gettype($selector['decimal']));
377
    }
378
379
    public function testTypeProviderTypes()
380
    {
381
        $typeProvider = new TypeProvider();
382
383
        $this->assertTrue(count($typeProvider->types()) > 0);
384
    }
385
386
    public function testTypeProviderInvalidTypeException()
387
    {
388
        $this->expectExceptionObject(new Exception('TypeIsNotExists not found!'));
389
390
        $typeProvider = new TypeProvider();
391
        $typeProvider->add('TypeIsNotExists');
392
    }
393
}
394