Passed
Pull Request — master (#1)
by Peter
07:07
created

ComponentTest::isMatchProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 12
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Html;
6
7
use AbterPhp\Framework\TestDouble\I18n\MockTranslatorFactory;
8
9
class ComponentTest extends CollectionTest
10
{
11
    public function testDefaultToString()
12
    {
13
        $sut = $this->createNode();
14
15
        $this->assertSame('<span></span>', (string)$sut);
16
    }
17
18
    /**
19
     * @return array
20
     */
21
    public function toStringWithTranslationProvider(): array
22
    {
23
        return [
24
            ['AAA', ['AAA' => 'BBB'], '<span>BBB</span>'],
25
        ];
26
    }
27
28
    /**
29
     * @dataProvider toStringWithTranslationProvider
30
     *
31
     * @param        $content
32
     * @param array  $translations
33
     * @param string $expectedResult
34
     */
35
    public function testToStringWithTranslation($content, array $translations, string $expectedResult)
36
    {
37
        $translator = MockTranslatorFactory::createSimpleTranslator($this, $translations);
38
39
        $sut = $this->createNode($content);
40
        $sut->setTranslator($translator);
41
42
        $this->assertSame($expectedResult, (string)$sut);
43
    }
44
45
    /**
46
     * @return array
47
     */
48
    public function toStringReturnsRawContentByDefaultProvider(): array
49
    {
50
        return [
51
            'string'  => ['foo', '<span>foo</span>'],
52
            'INode'   => [new Node('foo'), '<span>foo</span>'],
53
            'INode[]' => [[new Node('foo')], '<span>foo</span>'],
54
        ];
55
    }
56
57
    /**
58
     * @return array
59
     */
60
    public function toStringCanReturnTranslatedContentProvider(): array
61
    {
62
        $translations = ['foo' => 'bar'];
63
64
        return [
65
            'string'  => ['foo', $translations, '<span>bar</span>'],
66
            'INode'   => [new Node('foo'), $translations, '<span>bar</span>'],
67
            'INode[]' => [[new Node('foo')], $translations, '<span>bar</span>'],
68
        ];
69
    }
70
71
    public function testSetIntentsCanOverwriteExistingIntents()
72
    {
73
        $sut = $this->createNode();
74
75
        $sut->setIntent('foo');
76
        $sut->setIntent('bar', 'baz');
77
78
        $this->assertEquals(['bar', 'baz'], $sut->getIntents());
79
    }
80
81
    public function testAddIntentAppendsToExistingIntents()
82
    {
83
        $sut = $this->createNode();
84
85
        $sut->setIntent('foo');
86
        $sut->addIntent('bar', 'baz');
87
88
        $this->assertEquals(['foo', 'bar', 'baz'], $sut->getIntents());
89
    }
90
91
    public function testHasAttributeWithNonEmptyAttribute()
92
    {
93
        $sut = $this->createNode();
94
95
        $this->assertFalse($sut->hasAttribute('foo'));
96
97
        $sut->setAttribute('foo', 'bar');
98
99
        $this->assertTrue($sut->hasAttribute('foo'));
100
    }
101
102
    /**
103
     * @return array
104
     */
105
    public function getAttributeProvider(): array
106
    {
107
        return [
108
            [null, null],
109
            ['bar', 'bar'],
110
            [['bar'], 'bar'],
111
            ['foo bar', 'foo bar'],
112
            ['foo foo bar', 'foo bar'],
113
            [['foo', 'foo', 'bar', 'foo bar', 'bar'], 'foo bar'],
114
        ];
115
    }
116
117
    /**
118
     * @dataProvider getAttributeProvider
119
     *
120
     * @param             $value
121
     * @param string|null $expectedResult
122
     */
123
    public function testGetAttributes($value, ?string $expectedResult)
124
    {
125
        $key = 'foo';
126
127
        $sut = $this->createNode();
128
129
        $values = (array)$value;
130
        $sut->setAttribute($key, ...$values);
131
132
        $actualResult = $sut->getAttributes();
133
134
        $this->assertEquals([$key => $expectedResult], $actualResult);
135
    }
136
137
    public function testHasAttributeWithEmptyAttribute()
138
    {
139
        $sut = $this->createNode();
140
141
        $this->assertFalse($sut->hasAttribute('foo'));
142
143
        $sut->setAttribute('foo', null);
144
145
        $this->assertTrue($sut->hasAttribute('foo'));
146
    }
147
148
    public function testHasAttributeWithMissingAttributeSet()
149
    {
150
        $sut = $this->createNode();
151
152
        $this->assertFalse($sut->hasAttribute('foo'));
153
154
        $sut->setAttribute('foo');
155
156
        $this->assertTrue($sut->hasAttribute('foo'));
157
    }
158
159
    /**
160
     * @dataProvider getAttributeProvider
161
     *
162
     * @param             $value
163
     * @param string|null $expectedResult
164
     */
165
    public function testGetAttribute($value, ?string $expectedResult)
166
    {
167
        $key = 'foo';
168
169
        $sut = $this->createNode();
170
171
        $values = (array)$value;
172
        $sut->setAttribute($key, ...$values);
173
174
        $actualResult = $sut->getAttribute($key);
175
176
        $this->assertEquals($expectedResult, $actualResult);
177
    }
178
179
    /**
180
     * @dataProvider getAttributeProvider
181
     *
182
     * @param             $value
183
     * @param string|null $expectedResult
184
     */
185
    public function testUnsetAttribute($value, ?string $expectedResult)
186
    {
187
        $key = 'foo';
188
189
        $sut = $this->createNode();
190
191
        $values = (array)$value;
192
        $sut->setAttribute($key, ...$values);
193
194
        $actualResult = $sut->getAttribute($key);
195
        $this->assertEquals($expectedResult, $actualResult);
196
197
        $sut->unsetAttribute($key);
198
199
        $repeatedResult = $sut->getAttribute($key);
200
201
        $this->assertNull($repeatedResult);
202
    }
203
204
    public function testUnsetAttributeWorksOnNotSetAttributes()
205
    {
206
        $key = 'foo';
207
208
        $sut = $this->createNode();
209
210
        $sut->unsetAttribute($key);
211
212
        $result = $sut->getAttribute($key);
213
214
        $this->assertNull($result);
215
    }
216
217
    public function testSetAttributesOverridesExistingAttributesSet()
218
    {
219
        $originalAttributes = ['foo' => 'bar'];
220
        $newAttributes      = ['bar' => 'baz'];
221
        $expectedResult     = $newAttributes;
222
223
        $sut = $this->createNode();
224
        $sut->setAttributes($originalAttributes);
225
226
        $sut->setAttributes($newAttributes);
227
228
        $actualResult = $sut->getAttributes();
229
        $this->assertEquals($expectedResult, $actualResult);
230
    }
231
232
    public function testAddAttributesOverridesExistingAttributesSet()
233
    {
234
        $originalAttributes = ['foo' => 'bar', 'bar' => 'foo'];
235
        $newAttributes      = ['bar' => 'baz'];
236
        $expectedResult     = ['foo' => 'bar', 'bar' => 'baz'];
237
238
        $sut = $this->createNode();
239
        $sut->setAttributes($originalAttributes);
240
241
        $sut->addAttributes($newAttributes);
242
243
        $actualResult = $sut->getAttributes();
244
        $this->assertEquals($expectedResult, $actualResult);
245
    }
246
247
    public function testSetAttributeOverridesExistingAttributeSet()
248
    {
249
        $key                = 'bar';
250
        $originalAttributes = ['foo' => 'bar', 'bar' => 'foo'];
251
        $newAttributes      = ['bar' => 'baz'];
252
        $expectedResult     = ['foo' => 'bar', 'bar' => 'baz'];
253
254
        $sut = $this->createNode();
255
        $sut->setAttributes($originalAttributes);
256
257
        $sut->setAttribute($key, $newAttributes[$key]);
258
259
        $actualResult = $sut->getAttributes();
260
        $this->assertEquals($expectedResult, $actualResult);
261
    }
262
263
    public function testAppendToAttributeKeepsExistingAttributeSet()
264
    {
265
        $key                = 'bar';
266
        $originalAttributes = ['foo' => 'bar', 'bar' => 'foo'];
267
        $newAttributes      = ['bar' => 'baz'];
268
        $expectedResult     = ['foo' => 'bar', 'bar' => 'foo baz'];
269
270
        $sut = $this->createNode();
271
        $sut->setAttributes($originalAttributes);
272
273
        $sut->appendToAttribute($key, $newAttributes[$key]);
274
275
        $actualResult = $sut->getAttributes();
276
        $this->assertEquals($expectedResult, $actualResult);
277
    }
278
279
    public function testAppendToClassKeepsExistingAttributeSet()
280
    {
281
        $originalAttributes = ['foo' => 'bar', 'class' => 'foo'];
282
        $newClasses         = ['class1', 'class2'];
283
        $expectedResult     = ['foo' => 'bar', 'class' => 'foo class1 class2'];
284
285
        $sut = $this->createNode();
286
        $sut->setAttributes($originalAttributes);
287
288
        $sut->appendToClass(...$newClasses);
289
290
        $actualResult = $sut->getAttributes();
291
        $this->assertEquals($expectedResult, $actualResult);
292
    }
293
294
    /**
295
     * @return array
296
     */
297
    public function findProvider(): array
298
    {
299
        $node1 = new Node('1');
300
        $node2 = new Node('2');
301
302
        return [
303
            [[], $node1, null],
304
            [[$node2], $node1, null],
305
            [[$node1, $node2], $node1, 0],
306
            [[$node1, $node2], $node2, 1],
307
        ];
308
    }
309
310
    /**
311
     * @dataProvider findProvider
312
     *
313
     * @param INode[]  $content
314
     * @param INode    $nodeToFind
315
     * @param int|null $expectedResult
316
     */
317
    public function testFind(array $content, INode $nodeToFind, ?int $expectedResult)
318
    {
319
        $sut = $this->createNode($content);
320
321
        $actualResult = $sut->find($nodeToFind);
322
323
        $this->assertSame($expectedResult, $actualResult);
324
    }
325
326
    /**
327
     * @return array
328
     */
329
    public function isMatchProvider(): array
330
    {
331
        return [
332
            'INode-no-intent'               => [INode::class, [], true],
333
            'INode-foo-intent'              => [INode::class, ['foo'], true],
334
            'INode-bar-intent'              => [INode::class, ['bar'], true],
335
            'INode-foo-and-bar-intent'      => [INode::class, ['foo', 'bar'], true],
336
            'IComponent-foo-intent'         => [IComponent::class, ['foo'], true],
337
            'Component-foo-intent'          => [Component::class, ['foo'], true],
338
            'fail-INode-baz-intent'         => [INode::class, ['baz'], false],
339
            'fail-INode-foo-and-baz-intent' => [INode::class, ['foo', 'baz'], false],
340
            'fail-Node-foo-intent'          => [Node::class, ['foo'], false],
341
        ];
342
    }
343
344
    /**
345
     * @return array
346
     */
347
    public function findFirstChildProvider(): array
348
    {
349
        $node0       = new Node('0');
350
        $component1  = (new Component('1'))->setIntent('foo');
351
        $component2  = (new Component('2'))->setIntent('bar');
352
        $component3  = (new Component('3'))->setIntent('foo', 'bar');
353
        $notFindable = new Collection((new Component('4'))->setIntent('foo', 'baz'));
354
        $content     = [$node0, $component1, $component2, $component3, $notFindable];
355
356
        return [
357
            'INode-no-intent'               => [$content, INode::class, [], $component1],
358
            'INode-foo-intent'              => [$content, INode::class, ['foo'], $component1],
359
            'INode-bar-intent'              => [$content, INode::class, ['bar'], $component2],
360
            'INode-foo-and-bar-intent'      => [$content, INode::class, ['foo', 'bar'], $component3],
361
            'IComponent-foo-intent'         => [$content, IComponent::class, ['foo'], $component1],
362
            'Component-foo-intent'          => [$content, Component::class, ['foo'], $component1],
363
            'fail-INode-baz-intent'         => [$content, INode::class, ['baz'], null],
364
            'fail-INode-foo-and-baz-intent' => [$content, INode::class, ['foo', 'baz'], null],
365
            'fail-Node-foo-intent'          => [$content, Node::class, ['foo'], null],
366
        ];
367
    }
368
369
    /**
370
     * @dataProvider findFirstChildProvider
371
     *
372
     * @param INode[]     $content
373
     * @param string|null $className
374
     * @param string[]    $intents
375
     * @param INode|null  $expectedResult
376
     */
377
    public function testFindFirstChild(array $content, ?string $className, array $intents, ?INode $expectedResult)
378
    {
379
        $sut = $this->createNode($content);
380
381
        $actualResult = $sut->findFirstChild($className, ...$intents);
382
383
        $this->assertSame($expectedResult, $actualResult);
384
    }
385
386
    /**
387
     * @return array
388
     */
389
    public function collectProvider(): array
390
    {
391
        $node0   = new Node('0');
392
        $node1   = new Node('1', ['foo']);
393
        $node2   = new Node('2', ['bar']);
394
        $node3   = new Node('3', ['foo', 'bar']);
395
        $coll1   = new Collection([$node1, $node2]);
396
        $coll2   = new Collection([$node3, $node0, $coll1, $node1]);
397
        $content = [$node1, $node0, $node2, $coll2, $node3];
398
399
        $level0Expected     = [$node1, $node0, $node2, $coll2, $node3];
400
        $level1Expected     = [$node1, $node0, $node2, $coll2, $node3, $node0, $coll1, $node1, $node3];
401
        $defaultExpected    = [$node1, $node0, $node2, $coll2, $node3, $node0, $coll1, $node1, $node2, $node1, $node3];
402
        $fooOnlyExpected    = [$node1, $node3, $node1, $node1, $node3];
403
        $fooBarOnlyExpected = [$node3, $node3];
404
405
        return [
406
            '0-depth'       => [$content, null, 0, [], $level0Expected],
407
            '1-depth'       => [$content, null, 1, [], $level1Expected],
408
            'default'       => [$content, null, -1, [], $defaultExpected],
409
            'inode-only'    => [$content, INode::class, -1, [], $defaultExpected],
410
            'stdclass-only' => [$content, \stdClass::class, -1, [], []],
411
            'foo-only'      => [$content, null, -1, ['foo'], $fooOnlyExpected],
412
            'foo-bar-only'  => [$content, null, -1, ['foo', 'bar'], $fooBarOnlyExpected],
413
        ];
414
    }
415
416
    /**
417
     * @dataProvider collectProvider
418
     *
419
     * @param INode[]     $content
420
     * @param string|null $className
421
     * @param int         $depth
422
     * @param string[]    $intents
423
     * @param INode[]     $expectedResult
424
     */
425
    public function testCollect(array $content, ?string $className, int $depth, array $intents, array $expectedResult)
426
    {
427
        $sut = $this->createNode($content);
428
429
        $actualResult = $sut->collect($className, $intents, $depth);
430
431
        $this->assertEquals($expectedResult, $actualResult);
432
    }
433
434
    /**
435
     * @dataProvider toStringReturnsRawContentByDefaultProvider
436
     *
437
     * @param mixed  $rawContent
438
     * @param string $expectedResult
439
     */
440
    public function testToStringReturnsRawContentByDefault($rawContent, string $expectedResult)
441
    {
442
        $sut = $this->createNode($rawContent);
443
444
        $this->assertStringContainsString($expectedResult, (string)$sut);
445
    }
446
447
    /**
448
     * @dataProvider toStringCanReturnTranslatedContentProvider
449
     *
450
     * @param mixed $rawContent
451
     * @param string $expectedResult
452
     */
453
    public function testToStringCanReturnTranslatedContent($rawContent, array $translations, string $expectedResult)
454
    {
455
        $translatorMock = MockTranslatorFactory::createSimpleTranslator($this, $translations);
456
457
        $sut = $this->createNode($rawContent);
458
459
        $sut->setTranslator($translatorMock);
460
461
        $this->assertStringContainsString($expectedResult, (string)$sut);
462
    }
463
464
    /**
465
     * @dataProvider isMatchProvider
466
     *
467
     * @param string|null $className
468
     * @param string[]    $intents
469
     * @param int|null    $expectedResult
470
     */
471
    public function testIsMatch(?string $className, array $intents, bool $expectedResult)
472
    {
473
        $sut = $this->createNode();
474
        $sut->setIntent('foo', 'bar');
475
476
        $actualResult = $sut->isMatch($className, ...$intents);
477
478
        $this->assertSame($expectedResult, $actualResult);
479
    }
480
481
    /**
482
     * @param INode[]|INode|string|null $content
483
     *
484
     * @return Component
485
     */
486
    private function createNode($content = null): INode
487
    {
488
        return new Component($content);
489
    }
490
}
491