Passed
Push — master ( 142ace...2d4116 )
by Yahya
10:50 queued 04:36
created

UnitTest::testExtractFromFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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