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

CollectionTest::testGetExtendedNodes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 19
rs 9.8666
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\TestCase\Html\NodeTestCase;
8
use AbterPhp\Framework\TestDouble\I18n\MockTranslatorFactory;
9
10
class CollectionTest extends NodeTestCase
11
{
12
    /**
13
     * @return array
14
     */
15
    public function toStringReturnsRawContentByDefaultProvider(): array
16
    {
17
        return [
18
            'string'  => ['foo', 'foo'],
19
            'INode'   => [new Node('foo'), 'foo'],
20
            'INode[]' => [[new Node('foo')], 'foo'],
21
        ];
22
    }
23
24
    /**
25
     * @dataProvider toStringReturnsRawContentByDefaultProvider
26
     *
27
     * @param mixed  $rawContent
28
     * @param string $expectedResult
29
     */
30
    public function testToStringReturnsRawContentByDefault($rawContent, string $expectedResult)
31
    {
32
        $sut = $this->createNode($rawContent);
33
34
        $this->assertStringContainsString($expectedResult, (string)$sut);
35
    }
36
37
    /**
38
     * @return array
39
     */
40
    public function toStringCanReturnTranslatedContentProvider(): array
41
    {
42
        $translations = ['foo' => 'bar'];
43
44
        return [
45
            'string'  => ['foo', $translations, 'bar'],
46
            'INode'   => [new Node('foo'), $translations, 'bar'],
47
            'INode[]' => [[new Node('foo')], $translations, 'bar'],
48
        ];
49
    }
50
51
    /**
52
     * @dataProvider toStringCanReturnTranslatedContentProvider
53
     *
54
     * @param mixed  $rawContent
55
     * @param string $expectedResult
56
     */
57
    public function testToStringCanReturnTranslatedContent($rawContent, array $translations, string $expectedResult)
58
    {
59
        $translatorMock = MockTranslatorFactory::createSimpleTranslator($this, $translations);
60
61
        $sut = $this->createNode($rawContent);
62
63
        $sut->setTranslator($translatorMock);
64
65
        $this->assertStringContainsString($expectedResult, (string)$sut);
66
    }
67
68
    /**
69
     * @dataProvider isMatchProvider
70
     *
71
     * @param string|null $className
72
     * @param string[]    $intents
73
     * @param int|null    $expectedResult
74
     */
75
    public function testIsMatch(?string $className, array $intents, bool $expectedResult)
76
    {
77
        $sut = $this->createNode();
78
        $sut->setIntent('foo', 'bar');
79
80
        $actualResult = $sut->isMatch($className, ...$intents);
81
82
        $this->assertSame($expectedResult, $actualResult);
83
    }
84
85
    public function testCountWithoutOffset()
86
    {
87
        $expectedResult = 2;
88
89
        $node1 = new Node('1');
90
        $node2 = new Node('2');
91
92
        $sut = $this->createNode();
93
94
        $sut[] = $node1;
95
        $sut[] = $node2;
96
97
        $this->assertSame($expectedResult, count($sut));
98
    }
99
100
    public function testCountWithExplicitOffset()
101
    {
102
        $expectedResult = 2;
103
104
        $node1 = new Node('1');
105
        $node2 = new Node('2');
106
107
        $sut = $this->createNode();
108
109
        $sut[0] = $node1;
110
        $sut[1] = $node2;
111
112
        $this->assertSame($expectedResult, count($sut));
113
    }
114
115
    public function testCountWithMixedOffset()
116
    {
117
        $node1 = new Node('1');
118
        $node2 = new Node('2');
119
120
        $expectedCount = 5;
121
122
        $sut = $this->createNode();
123
124
        $sut[]  = $node1;
125
        $sut[]  = $node1;
126
        $sut[1] = $node2;
127
        $sut[2] = $node1;
128
        $sut[3] = $node1;
129
        $sut[]  = $node1;
130
131
        $this->assertSame($expectedCount, count($sut));
132
    }
133
134
    public function testArrayAccessWithoutOffset()
135
    {
136
        $node1 = new Node('1');
137
        $node2 = new Node('2');
138
139
        $sut = $this->createNode();
140
141
        $sut[] = $node1;
142
        $sut[] = $node2;
143
144
        $this->assertSame($node1, $sut[0]);
145
        $this->assertSame($node2, $sut[1]);
146
    }
147
148
    public function testArrayAccessWithExplicitOffset()
149
    {
150
        $node1 = new Node('1');
151
        $node2 = new Node('2');
152
153
        $sut = $this->createNode();
154
155
        $sut[0] = $node1;
156
        $sut[1] = $node2;
157
158
        $this->assertSame($node1, $sut[0]);
159
        $this->assertSame($node2, $sut[1]);
160
    }
161
162
    public function testArrayAccessThrowExceptionWhenMadeDirty()
163
    {
164
        $this->expectException(\InvalidArgumentException::class);
165
166
        $node1 = new Node('1');
167
168
        $sut = $this->createNode();
169
170
        $sut[1] = $node1;
171
    }
172
173
    public function testArrayAccessWithMixedOffset()
174
    {
175
        $node1 = new Node('1');
176
        $node2 = new Node('2');
177
178
        $expectedNodes = [0 => $node1, 1 => $node2, 2 => $node1, 3 => $node1, 4 => $node1];
179
180
        $sut = $this->createNode();
181
182
        $sut[]  = $node1;
183
        $sut[]  = $node1;
184
        $sut[1] = $node2;
185
        $sut[2] = $node1;
186
        $sut[3] = $node1;
187
        $sut[]  = $node1;
188
189
        $this->assertEquals($expectedNodes, $sut->getExtendedNodes());
190
    }
191
192
    /**
193
     * @return array
194
     */
195
    public function contentFailureProvider(): array
196
    {
197
        return [
198
            'bool'                    => [true],
199
            'non-node object'         => [new \StdClass()],
200
            'string wrapped'          => [['']],
201
            'non-node object wrapped' => [[new \StdClass()]],
202
            'node double wrapped'     => [[[new Node()]]],
203
        ];
204
    }
205
206
    /**
207
     * @dataProvider contentFailureProvider
208
     */
209
    public function testConstructFailure($item)
210
    {
211
        $this->expectException(\InvalidArgumentException::class);
212
213
        $this->createNode($item);
214
    }
215
216
    /**
217
     * @dataProvider contentFailureProvider
218
     */
219
    public function testSetContentFailure($item)
220
    {
221
        $this->expectException(\InvalidArgumentException::class);
222
223
        $sut = $this->createNode();
224
225
        $sut->setContent($item);
226
    }
227
228
    /**
229
     * @return array
230
     */
231
    public function offsetSetFailureProvider(): array
232
    {
233
        $contentFailure = $this->contentFailureProvider();
234
235
        $offsetFailure = [
236
            'string'       => ['foo'],
237
            'node wrapped' => [[new Node()]],
238
        ];
239
240
        return array_merge($contentFailure, $offsetFailure);
241
    }
242
243
    /**
244
     * @dataProvider offsetSetFailureProvider
245
     */
246
    public function testArrayAccessFailureWithoutOffset($item)
247
    {
248
        $this->expectException(\InvalidArgumentException::class);
249
250
        $sut = $this->createNode();
251
252
        $sut[] = $item;
253
    }
254
255
    /**
256
     * @dataProvider offsetSetFailureProvider
257
     */
258
    public function testArrayAccessFailureWithExplicitOffset($item)
259
    {
260
        $this->expectException(\InvalidArgumentException::class);
261
262
        $sut = $this->createNode();
263
264
        $sut[] = $item;
265
    }
266
267
    public function testArrayAccessUnset()
268
    {
269
        $node1 = new Node('1');
270
271
        $sut = $this->createNode();
272
273
        $sut[] = $node1;
274
275
        $this->assertTrue($sut->offsetExists(0));
276
277
        unset($sut[0]);
278
279
        $this->assertfalse($sut->offsetExists(0));
280
    }
281
282
    public function testSetContent()
283
    {
284
        $node1 = new Node('1');
285
        $node2 = new Node('2');
286
287
        $expectedNodes = [new Node('3')];
288
289
        $sut = $this->createNode();
290
291
        $sut[]  = $node1;
292
        $sut[]  = $node1;
293
        $sut[1] = $node2;
294
        $sut[2] = $node1;
295
        $sut[3] = $node1;
296
        $sut[]  = $node1;
297
298
        $sut->setContent('3');
299
300
        $actualResult = $sut->getNodes();
301
302
        $this->assertEquals($expectedNodes, $actualResult);
303
    }
304
305
    public function testGetNodes()
306
    {
307
        $node1 = new Node('1');
308
        $node2 = new Node(new Node('2'));
309
310
        $expectedNodes = [$node1, $node2, $node1, $node1, $node1];
311
312
        $sut = $this->createNode();
313
314
        $sut[]  = $node1;
315
        $sut[]  = $node1;
316
        $sut[1] = $node2;
317
        $sut[2] = $node1;
318
        $sut[3] = $node1;
319
        $sut[]  = $node1;
320
321
        $actualResult = $sut->getNodes();
322
323
        $this->assertEquals($expectedNodes, $actualResult);
324
    }
325
326
    public function testGetExtendedNodes()
327
    {
328
        $node1 = new Node('1');
329
        $node2 = new Node(new Node('2'));
330
331
        $expectedNodes = [$node1, $node2, $node1, $node1, $node1];
332
333
        $sut = $this->createNode();
334
335
        $sut[]  = $node1;
336
        $sut[]  = $node1;
337
        $sut[1] = $node2;
338
        $sut[2] = $node1;
339
        $sut[3] = $node1;
340
        $sut[]  = $node1;
341
342
        $actualResult = $sut->getExtendedNodes();
343
344
        $this->assertEquals($expectedNodes, $actualResult);
345
    }
346
347
    public function testGetDescendantNodes()
348
    {
349
        $node1 = new Node('1');
350
        $node2 = new Node(new Node('2'));
351
352
        $expectedNodes = [$node1, $node2, $node1, $node1, $node1];
353
354
        $sut = $this->createNode();
355
356
        $sut[]  = $node1;
357
        $sut[]  = $node1;
358
        $sut[1] = $node2;
359
        $sut[2] = $node1;
360
        $sut[3] = $node1;
361
        $sut[]  = $node1;
362
363
        $actualResult = $sut->getDescendantNodes();
364
365
        $this->assertEquals($expectedNodes, $actualResult);
366
    }
367
368
    public function testGetExtendedDescendantNodes()
369
    {
370
        $node1 = new Node('1');
371
        $node2 = new Node(new Node('2'));
372
373
        $expectedNodes = [$node1, $node2, $node1, $node1, $node1];
374
375
        $sut = $this->createNode();
376
377
        $sut[]  = $node1;
378
        $sut[]  = $node1;
379
        $sut[1] = $node2;
380
        $sut[2] = $node1;
381
        $sut[3] = $node1;
382
        $sut[]  = $node1;
383
384
        $actualResult = $sut->getExtendedDescendantNodes();
385
386
        $this->assertEquals($expectedNodes, $actualResult);
387
    }
388
389
    public function testIterator()
390
    {
391
        $node1 = new Node('1');
392
        $node2 = new Node('2');
393
394
        $expectedKeys  = [0, 1, 2, 3, 4];
395
        $expectedNodes = [$node1, $node2, $node1, $node1, $node1];
396
397
        $sut = $this->createNode();
398
399
        $sut[]  = $node1;
400
        $sut[]  = $node1;
401
        $sut[1] = $node2;
402
        $sut[2] = $node1;
403
        $sut[3] = $node1;
404
        $sut[]  = $node1;
405
406
        $pos = 0;
407
        foreach ($sut as $key => $node) {
408
            $this->assertSame($expectedKeys[$pos], $key);
409
            $this->assertSame($expectedNodes[$pos], $node);
410
            $pos++;
411
        }
412
    }
413
414
    public function testGetRawContentReturnsNonTranslatedContent()
415
    {
416
        $this->assertTrue(true, 'No need to test getRawContent');
417
    }
418
419
    /**
420
     * @return array
421
     */
422
    public function insertBeforeProvider(): array
423
    {
424
        $needle = new Node('1');
425
        $node2  = new Node('2');
426
        $node3  = new Node('3');
427
428
        return [
429
            'empty-content'                  => [
430
                [],
431
                $needle,
432
                [$node2],
433
                false,
434
                [],
435
            ],
436
            'only-non-matching-content'      => [
437
                [$node2, $node3],
438
                $needle,
439
                [$needle, $node3],
440
                false,
441
                [$node2, $node3],
442
            ],
443
            'only-non-matching-content-deep' => [
444
                [$node2, $node3, new Collection([$node2, $node3])],
445
                $needle,
446
                [$needle, $node3],
447
                false,
448
                [$node2, $node3, new Collection([$node2, $node3])],
449
            ],
450
            'only-matching-content'          => [
451
                [$needle],
452
                $needle,
453
                [$node2, $node3],
454
                true,
455
                [$node2, $node3, $needle],
456
            ],
457
            'non-first-matching-content'     => [
458
                [$node2, $needle],
459
                $needle,
460
                [$node3, $node3],
461
                true,
462
                [$node2, $node3, $node3, $needle],
463
            ],
464
            'deep-first-matching-content'    => [
465
                [$node2, new Collection([$node2, $needle])],
466
                $needle,
467
                [$node3, $node3],
468
                true,
469
                [$node2, new Collection([$node2, $node3, $node3, $needle])],
470
            ],
471
        ];
472
    }
473
474
    /**
475
     * @dataProvider insertBeforeProvider
476
     *
477
     * @param INode[] $content
478
     * @param INode   $nodeToFind
479
     * @param INode[] $nodesToInsert
480
     * @param bool    $expectedResult
481
     * @param INode[] $expectedNodes
482
     */
483
    public function testInsertBefore(
484
        array $content,
485
        INode $nodeToFind,
486
        array $nodesToInsert,
487
        bool $expectedResult,
488
        array $expectedNodes
489
    ) {
490
        $sut = $this->createNode($content);
491
492
        $actualResult = $sut->insertBefore($nodeToFind, ...$nodesToInsert);
493
494
        $this->assertSame($expectedResult, $actualResult);
495
        $this->assertEquals($expectedNodes, $sut->getNodes());
496
    }
497
498
    /**
499
     * @return array
500
     */
501
    public function insertAfterProvider(): array
502
    {
503
        $needle = new Node('1');
504
        $node2  = new Node('2');
505
        $node3  = new Node('3');
506
507
        return [
508
            'empty-content'                  => [
509
                [],
510
                $needle,
511
                [$node2],
512
                false,
513
                [],
514
            ],
515
            'only-non-matching-content'      => [
516
                [$node2, $node3],
517
                $needle,
518
                [$needle, $node3],
519
                false,
520
                [$node2, $node3],
521
            ],
522
            'only-non-matching-content-deep' => [
523
                [$node2, $node3, new Collection([$node2, $node3])],
524
                $needle,
525
                [$needle, $node3],
526
                false,
527
                [$node2, $node3, new Collection([$node2, $node3])],
528
            ],
529
            'only-matching-content'          => [
530
                [$needle],
531
                $needle,
532
                [$node2, $node3],
533
                true,
534
                [$needle, $node2, $node3],
535
            ],
536
            'non-last-matching-content'      => [
537
                [$needle, $node2],
538
                $needle,
539
                [$node3, $node3],
540
                true,
541
                [$needle, $node3, $node3, $node2],
542
            ],
543
            'deep-first-matching-content'    => [
544
                [$node2, new Collection([$node2, $needle])],
545
                $needle,
546
                [$node3, $node3],
547
                true,
548
                [$node2, new Collection([$node2, $needle, $node3, $node3])],
549
            ],
550
        ];
551
    }
552
553
    /**
554
     * @dataProvider insertAfterProvider
555
     *
556
     * @param INode[] $content
557
     * @param INode   $nodeToFind
558
     * @param INode[] $nodesToInsert
559
     * @param bool    $expectedResult
560
     * @param INode[] $expectedNodes
561
     */
562
    public function testInsertAfter(
563
        array $content,
564
        INode $nodeToFind,
565
        array $nodesToInsert,
566
        bool $expectedResult,
567
        array $expectedNodes
568
    ) {
569
        $sut = $this->createNode($content);
570
571
        $actualResult = $sut->insertAfter($nodeToFind, ...$nodesToInsert);
572
573
        $this->assertSame($expectedResult, $actualResult);
574
        $this->assertEquals($expectedNodes, $sut->getNodes());
575
    }
576
577
    /**
578
     * @return array
579
     */
580
    public function replaceProvider(): array
581
    {
582
        $needle = new Node('1');
583
        $node2  = new Node('2');
584
        $node3  = new Node('3');
585
586
        return [
587
            'empty-content'                  => [
588
                [],
589
                $needle,
590
                [$node2],
591
                false,
592
                [],
593
            ],
594
            'only-non-matching-content'      => [
595
                [$node2, $node3],
596
                $needle,
597
                [$needle, $node3],
598
                false,
599
                [$node2, $node3],
600
            ],
601
            'only-non-matching-content-deep' => [
602
                [$node2, $node3, new Collection([$node2, $node3])],
603
                $needle,
604
                [$needle, $node3],
605
                false,
606
                [$node2, $node3, new Collection([$node2, $node3])],
607
            ],
608
            'only-matching-content'          => [
609
                [$needle],
610
                $needle,
611
                [$node2, $node3],
612
                true,
613
                [$node2, $node3],
614
            ],
615
            'non-first-matching-content'     => [
616
                [$node2, $needle],
617
                $needle,
618
                [$node3, $node3],
619
                true,
620
                [$node2, $node3, $node3],
621
            ],
622
            'non-last-matching-content'      => [
623
                [$needle, $node2],
624
                $needle,
625
                [$node3, $node3],
626
                true,
627
                [$node3, $node3, $node2],
628
            ],
629
            'deep-first-matching-content'    => [
630
                [$node2, new Collection([$node2, $needle])],
631
                $needle,
632
                [$node3, $node3],
633
                true,
634
                [$node2, new Collection([$node2, $node3, $node3])],
635
            ],
636
        ];
637
    }
638
639
    /**
640
     * @dataProvider replaceProvider
641
     *
642
     * @param INode[] $content
643
     * @param INode   $nodeToFind
644
     * @param INode[] $nodesToInsert
645
     * @param bool    $expectedResult
646
     * @param INode[] $expectedNodes
647
     */
648
    public function testReplace(
649
        array $content,
650
        INode $nodeToFind,
651
        array $nodesToInsert,
652
        bool $expectedResult,
653
        array $expectedNodes
654
    ) {
655
        $sut = $this->createNode($content);
656
657
        $actualResult = $sut->replace($nodeToFind, ...$nodesToInsert);
658
659
        $this->assertSame($expectedResult, $actualResult);
660
        $this->assertEquals($expectedNodes, $sut->getNodes());
661
    }
662
663
    /**
664
     * @return array
665
     */
666
    public function removeProvider(): array
667
    {
668
        $needle = new Node('1');
669
        $node2  = new Node('2');
670
        $node3  = new Node('3');
671
672
        return [
673
            'empty-content'                  => [
674
                [],
675
                $needle,
676
                false,
677
                [],
678
            ],
679
            'only-non-matching-content'      => [
680
                [$node2, $node3],
681
                $needle,
682
                false,
683
                [$node2, $node3],
684
            ],
685
            'only-non-matching-content-deep' => [
686
                [$node2, $node3, new Collection([$node2, $node3])],
687
                $needle,
688
                false,
689
                [$node2, $node3, new Collection([$node2, $node3])],
690
            ],
691
            'only-matching-content'          => [
692
                [$needle],
693
                $needle,
694
                true,
695
                [],
696
            ],
697
            'non-first-matching-content'     => [
698
                [$node2, $needle],
699
                $needle,
700
                true,
701
                [$node2],
702
            ],
703
            'non-last-matching-content'      => [
704
                [$needle, $node2],
705
                $needle,
706
                true,
707
                [$node2],
708
            ],
709
            'deep-first-matching-content'    => [
710
                [$node2, new Collection([$node2, $needle])],
711
                $needle,
712
                true,
713
                [$node2, new Collection([$node2])],
714
            ],
715
        ];
716
    }
717
718
    /**
719
     * @dataProvider removeProvider
720
     *
721
     * @param INode[] $content
722
     * @param INode   $nodeToFind
723
     * @param bool    $expectedResult
724
     * @param INode[] $expectedNodes
725
     */
726
    public function testRemove(
727
        array $content,
728
        INode $nodeToFind,
729
        bool $expectedResult,
730
        array $expectedNodes
731
    ) {
732
        $sut = $this->createNode($content);
733
734
        $actualResult = $sut->remove($nodeToFind);
735
736
        $this->assertSame($expectedResult, $actualResult);
737
        $this->assertEquals($expectedNodes, $sut->getNodes());
738
    }
739
740
    /**
741
     * @return array
742
     */
743
    public function isMatchProvider(): array
744
    {
745
        return [
746
            'INode-no-intent'               => [INode::class, [], true],
747
            'INode-foo-intent'              => [INode::class, ['foo'], true],
748
            'INode-bar-intent'              => [INode::class, ['bar'], true],
749
            'INode-foo-and-bar-intent'      => [INode::class, ['foo', 'bar'], true],
750
            'fail-IComponent-foo-intent'    => [IComponent::class, ['foo'], false],
751
            'fail-Component-foo-intent'     => [Component::class, ['foo'], false],
752
            'fail-INode-baz-intent'         => [INode::class, ['baz'], false],
753
            'fail-INode-foo-and-baz-intent' => [INode::class, ['foo', 'baz'], false],
754
            'fail-Node-foo-intent'          => [Node::class, ['foo'], false],
755
        ];
756
    }
757
758
    /**
759
     * @return array
760
     */
761
    public function hasIntentProvider(): array
762
    {
763
        return [
764
            [[], 'foo', false],
765
            [['foo'], 'foo', true],
766
            [['bar'], 'foo', false],
767
            [['foo', 'bar', 'baz'], 'bar', true],
768
        ];
769
    }
770
771
    /**
772
     * @dataProvider hasIntentProvider
773
     *
774
     * @param array  $intents
775
     * @param string $intentToCheck
776
     * @param bool   $expectedResult
777
     */
778
    public function testHasIntentChecksIfAGivenIntentHasBeenSet(
779
        array $intents,
780
        string $intentToCheck,
781
        bool $expectedResult
782
    ) {
783
        $sut = $this->createNode();
784
785
        $sut->setIntent(...$intents);
786
787
        $actualResult = $sut->hasIntent($intentToCheck);
788
789
        $this->assertSame($expectedResult, $actualResult);
790
    }
791
792
    /**
793
     * @param INode[]|INode|string|null $content
794
     *
795
     * @return Collection
796
     */
797
    private function createNode($content = null): INode
798
    {
799
        return new Collection($content);
800
    }
801
}
802