@@ -354,30 +354,21 @@ public function append(array $data, $id = null, bool $append = true, $linesToBeC
354
354
355
355
foreach ($ fileData ['lines ' ] as $ line => $ lineCoverage ) {
356
356
if ($ lineCoverage === Driver::LINE_EXECUTED ) {
357
- if ($ this ->data [$ file ]['lines ' ][$ line ] === null ) {
358
- $ this ->data [$ file ]['lines ' ][$ line ] = [
359
- 'pathCovered ' => false ,
360
- 'tests ' => [$ id ],
361
- ];
362
- } elseif (!\in_array ($ id , $ this ->data [$ file ]['lines ' ][$ line ]['tests ' ], true )) {
363
- $ this ->data [$ file ]['lines ' ][$ line ]['tests ' ][] = [$ id ];
364
- }
357
+ $ this ->addCoverageLinePathCovered ($ file , $ line , false );
358
+ $ this ->addCoverageLineTest ($ file , $ line , $ id );
365
359
}
366
360
}
367
361
368
362
foreach ($ fileData ['functions ' ] as $ function => $ functionCoverage ) {
369
363
foreach ($ functionCoverage ['branches ' ] as $ branch => $ branchCoverage ) {
370
- if ($ branchCoverage ['hit ' ] === 1 ) {
371
- $ this ->data [$ file ]['branches ' ][$ function ][$ branch ]['hit ' ] = 1 ;
372
- if (!\in_array ($ id , $ this ->data [$ file ]['branches ' ][$ function ][$ branch ]['tests ' ], true )) {
373
- $ this ->data [$ file ]['branches ' ][$ function ][$ branch ]['tests ' ][] = $ id ;
374
- }
364
+ if (($ branchCoverage ['hit ' ] ?? 0 ) === 1 ) {
365
+ $ this ->addCoverageBranchHit ($ file , $ function , $ branch , $ branchCoverage ['hit ' ] ?? 0 );
366
+ $ this ->addCoverageBranchTest ($ file , $ function , $ branch , $ id );
375
367
}
376
368
}
369
+
377
370
foreach ($ functionCoverage ['paths ' ] as $ path => $ pathCoverage ) {
378
- if ($ pathCoverage ['hit ' ] === 1 && $ this ->data [$ file ]['paths ' ][$ function ][$ path ]['hit ' ] === 0 ) {
379
- $ this ->data [$ file ]['paths ' ][$ function ][$ path ]['hit ' ] = 1 ;
380
- }
371
+ $ this ->addCoveragePathHit ($ file , $ function , $ path , $ pathCoverage ['hit ' ] ?? 0 );
381
372
}
382
373
}
383
374
}
@@ -396,11 +387,13 @@ public function merge(self $that): void
396
387
\array_merge ($ this ->filter ->getWhitelistedFiles (), $ that ->filter ()->getWhitelistedFiles ())
397
388
);
398
389
399
- // I don't know how / why this works, but it should be refactored to ->getData()
400
- foreach ($ that ->getData () as $ file => $ fileData ) {
401
- if (!isset ($ this ->data [$ file ])) {
390
+ $ thisData = $ this ->getData ();
391
+ $ thatData = $ that ->getData ();
392
+
393
+ foreach ($ thatData as $ file => $ fileData ) {
394
+ if (!isset ($ thisData [$ file ])) {
402
395
if (!$ this ->filter ->isFiltered ($ file )) {
403
- $ this -> data [$ file ] = $ fileData ;
396
+ $ thisData [$ file ] = $ fileData ;
404
397
}
405
398
406
399
continue ;
@@ -409,30 +402,30 @@ public function merge(self $that): void
409
402
// we should compare the lines if any of two contains data
410
403
$ compareLineNumbers = \array_unique (
411
404
\array_merge (
412
- \array_keys ($ this -> data [$ file ]['lines ' ]),
413
- \array_keys ($ that -> data [$ file ]['lines ' ]) // can this be $fileData?
405
+ \array_keys ($ thisData [$ file ]['lines ' ]),
406
+ \array_keys ($ thatData [$ file ]['lines ' ]) // can this be $fileData?
414
407
)
415
408
);
416
409
417
410
foreach ($ compareLineNumbers as $ line ) {
418
- $ thatPriority = $ this ->getLinePriority ($ that -> data [$ file ]['lines ' ], $ line );
419
- $ thisPriority = $ this ->getLinePriority ($ this -> data [$ file ]['lines ' ], $ line );
411
+ $ thatPriority = $ this ->getLinePriority ($ thatData [$ file ]['lines ' ], $ line );
412
+ $ thisPriority = $ this ->getLinePriority ($ thisData [$ file ]['lines ' ], $ line );
420
413
421
414
if ($ thatPriority > $ thisPriority ) {
422
- $ this -> data [$ file ]['lines ' ][$ line ] = $ that -> data [$ file ]['lines ' ][$ line ];
423
- } elseif ($ thatPriority === $ thisPriority && \is_array ($ this -> data [$ file ]['lines ' ][$ line ])) {
415
+ $ thisData [$ file ]['lines ' ][$ line ] = $ thatData [$ file ]['lines ' ][$ line ];
416
+ } elseif ($ thatPriority === $ thisPriority && \is_array ($ thisData [$ file ]['lines ' ][$ line ])) {
424
417
if ($ line ['pathCovered ' ] === true ) {
425
- $ this -> data [$ file ]['lines ' ][' line ' ]['pathCovered ' ] = $ line ['pathCovered ' ];
418
+ $ thisData [$ file ]['lines ' ][$ line ]['pathCovered ' ] = $ line ['pathCovered ' ];
426
419
}
427
- $ this -> data [$ file ]['lines ' ][$ line ] = \array_unique (
428
- \array_merge ($ this -> data [$ file ]['lines ' ][$ line ], $ that -> data [$ file ]['lines ' ][$ line ])
420
+ $ thisData [$ file ]['lines ' ][$ line ] = \array_unique (
421
+ \array_merge ($ thisData [$ file ]['lines ' ][$ line ], $ thatData [$ file ]['lines ' ][$ line ])
429
422
);
430
423
}
431
424
}
432
425
}
433
426
434
- $ this ->tests = \array_merge ($ this ->tests , $ that ->getTests ());
435
- $ this ->report = null ;
427
+ $ this ->tests = \array_merge ($ this ->tests , $ that ->getTests ());
428
+ $ this ->setData ( $ thisData ) ;
436
429
}
437
430
438
431
public function setCacheTokens (bool $ flag ): void
@@ -517,12 +510,9 @@ public function setDetermineBranchCoverage(bool $flag): void
517
510
*
518
511
* During a merge, a higher number is better.
519
512
*
520
- * @param array $data
521
- * @param int $line
522
- *
523
513
* @return int
524
514
*/
525
- private function getLinePriority ($ data , $ line )
515
+ private function getLinePriority (array $ data , int $ line )
526
516
{
527
517
if (!\array_key_exists ($ line , $ data )) {
528
518
return 1 ;
@@ -557,7 +547,10 @@ private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, ar
557
547
throw new MissingCoversAnnotationException ;
558
548
}
559
549
560
- $ data = [];
550
+ $ data = [
551
+ 'lines ' => [],
552
+ 'functions ' => [],
553
+ ];
561
554
562
555
return ;
563
556
}
@@ -568,7 +561,7 @@ private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, ar
568
561
569
562
if ($ this ->checkForUnintentionallyCoveredCode &&
570
563
(!$ this ->currentId instanceof TestCase ||
571
- (!$ this ->currentId ->isMedium () && !$ this ->currentId ->isLarge ()))) {
564
+ (!$ this ->currentId ->isMedium () && !$ this ->currentId ->isLarge ()))) {
572
565
$ this ->performUnintentionallyCoveredCodeCheck ($ data , $ linesToBeCovered , $ linesToBeUsed );
573
566
}
574
567
@@ -580,7 +573,11 @@ private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, ar
580
573
581
574
foreach (\array_keys ($ data ) as $ filename ) {
582
575
$ _linesToBeCovered = \array_flip ($ linesToBeCovered [$ filename ]);
583
- $ data [$ filename ] = \array_intersect_key ($ data [$ filename ], $ _linesToBeCovered );
576
+
577
+ $ data [$ filename ]['lines ' ] = \array_intersect_key (
578
+ $ data [$ filename ],
579
+ $ _linesToBeCovered
580
+ );
584
581
}
585
582
}
586
583
@@ -604,24 +601,210 @@ private function applyIgnoredLinesFilter(array &$data): void
604
601
}
605
602
606
603
foreach ($ this ->getLinesToBeIgnored ($ filename ) as $ line ) {
607
- unset($ data [$ filename ][$ line ]);
604
+ unset($ data [$ filename ][' lines ' ][ $ line ]);
608
605
}
609
606
}
610
607
}
611
608
612
609
private function initializeFilesThatAreSeenTheFirstTime (array $ data ): void
613
610
{
614
- foreach ($ data as $ file => $ lines ) {
615
- if (!isset ($ this ->data [$ file ]) && $ this ->filter ->isFile ($ file )) {
616
- $ this ->data [$ file ] = [];
611
+ foreach ($ data as $ file => $ fileData ) {
612
+ if (isset ($ this ->data [$ file ]) || !$ this ->filter ->isFile ($ file )) {
613
+ continue ;
614
+ }
615
+ $ this ->initializeFileCoverageData ($ file );
617
616
618
- foreach ($ lines as $ k => $ v ) {
619
- $ this ->data [$ file ][$ k ] = $ v === -2 ? null : [];
617
+ // If this particular line is identified as not covered, mark it as null
618
+ foreach ($ fileData ['lines ' ] as $ lineNumber => $ flag ) {
619
+ if ($ flag === Driver::LINE_NOT_EXECUTABLE ) {
620
+ $ this ->data [$ file ]['lines ' ][$ lineNumber ] = null ;
621
+ }
622
+ }
623
+
624
+ foreach ($ fileData ['functions ' ] as $ functionName => $ functionData ) {
625
+ // @todo - should this have a helper to merge covered paths?
626
+ $ this ->data [$ file ]['paths ' ][$ functionName ] = $ functionData ['paths ' ];
627
+
628
+ foreach ($ functionData ['branches ' ] as $ branchIndex => $ branchData ) {
629
+ $ this ->addCoverageBranchHit ($ file , $ functionName , $ branchIndex , $ branchData ['hit ' ]);
630
+ $ this ->addCoverageBranchLineStart ($ file , $ functionName , $ branchIndex , $ branchData ['line_start ' ]);
631
+ $ this ->addCoverageBranchLineEnd ($ file , $ functionName , $ branchIndex , $ branchData ['line_end ' ]);
632
+
633
+ for ($ curLine = $ branchData ['line_start ' ]; $ curLine < $ branchData ['line_end ' ]; $ curLine ++) {
634
+ if (isset ($ this ->data [$ file ]['lines ' ][$ curLine ])) {
635
+ $ this ->addCoverageLinePathCovered ($ file , $ curLine , (bool ) $ branchData ['hit ' ]);
636
+ }
637
+ }
620
638
}
621
639
}
622
640
}
623
641
}
624
642
643
+ private function initializeFileCoverageData (string $ file ): void
644
+ {
645
+ if (!isset ($ this ->data [$ file ]) && $ this ->filter ->isFile ($ file )) {
646
+ $ this ->data [$ file ] = [
647
+ 'lines ' => [],
648
+ 'branches ' => [],
649
+ 'paths ' => [],
650
+ ];
651
+ }
652
+ }
653
+
654
+ private function addCoverageLinePathCovered (string $ file , int $ lineNumber , bool $ isCovered ): void
655
+ {
656
+ $ this ->initializeFileCoverageData ($ file );
657
+
658
+ // Initialize the data coverage array for this line
659
+ if (!isset ($ this ->data [$ file ]['lines ' ][$ lineNumber ])) {
660
+ $ this ->data [$ file ]['lines ' ][$ lineNumber ] = [
661
+ 'pathCovered ' => false ,
662
+ 'tests ' => [],
663
+ ];
664
+ }
665
+
666
+ $ this ->data [$ file ]['lines ' ][$ lineNumber ]['pathCovered ' ] = $ isCovered ;
667
+ }
668
+
669
+ private function addCoverageLineTest (string $ file , int $ lineNumber , string $ testId ): void
670
+ {
671
+ $ this ->initializeFileCoverageData ($ file );
672
+
673
+ // Initialize the data coverage array for this line
674
+ if (!isset ($ this ->data [$ file ]['lines ' ][$ lineNumber ])) {
675
+ $ this ->data [$ file ]['lines ' ][$ lineNumber ] = [
676
+ 'pathCovered ' => false ,
677
+ 'tests ' => [],
678
+ ];
679
+ }
680
+
681
+ if (!\in_array ($ testId , $ this ->data [$ file ]['lines ' ][$ lineNumber ]['tests ' ], true )) {
682
+ $ this ->data [$ file ]['lines ' ][$ lineNumber ]['tests ' ][] = $ testId ;
683
+ }
684
+ }
685
+
686
+ private function addCoverageBranchHit (string $ file , string $ functionName , int $ branchIndex , int $ hit ): void
687
+ {
688
+ $ this ->initializeFileCoverageData ($ file );
689
+
690
+ if (!\array_key_exists ($ functionName , $ this ->data [$ file ]['branches ' ])) {
691
+ $ this ->data [$ file ]['branches ' ][$ functionName ] = [];
692
+ }
693
+
694
+ if (!\array_key_exists ($ branchIndex , $ this ->data [$ file ]['branches ' ][$ functionName ])) {
695
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ] = [
696
+ 'hit ' => 0 ,
697
+ 'line_start ' => 0 ,
698
+ 'line_end ' => 0 ,
699
+ 'tests ' => [],
700
+ ];
701
+ }
702
+
703
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['hit ' ] = \max (
704
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['hit ' ],
705
+ $ hit
706
+ );
707
+ }
708
+
709
+ private function addCoverageBranchLineStart (
710
+ string $ file ,
711
+ string $ functionName ,
712
+ int $ branchIndex ,
713
+ int $ lineStart
714
+ ): void {
715
+ $ this ->initializeFileCoverageData ($ file );
716
+
717
+ if (!\array_key_exists ($ functionName , $ this ->data [$ file ]['branches ' ])) {
718
+ $ this ->data [$ file ]['branches ' ][$ functionName ] = [];
719
+ }
720
+
721
+ if (!\array_key_exists ($ branchIndex , $ this ->data [$ file ]['branches ' ][$ functionName ])) {
722
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ] = [
723
+ 'hit ' => 0 ,
724
+ 'line_start ' => 0 ,
725
+ 'line_end ' => 0 ,
726
+ 'tests ' => [],
727
+ ];
728
+ }
729
+
730
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['line_start ' ] = $ lineStart ;
731
+ }
732
+
733
+ private function addCoverageBranchLineEnd (
734
+ string $ file ,
735
+ string $ functionName ,
736
+ int $ branchIndex ,
737
+ int $ lineEnd
738
+ ): void {
739
+ $ this ->initializeFileCoverageData ($ file );
740
+
741
+ if (!\array_key_exists ($ functionName , $ this ->data [$ file ]['branches ' ])) {
742
+ $ this ->data [$ file ]['branches ' ][$ functionName ] = [];
743
+ }
744
+
745
+ if (!\array_key_exists ($ branchIndex , $ this ->data [$ file ]['branches ' ][$ functionName ])) {
746
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ] = [
747
+ 'hit ' => 0 ,
748
+ 'line_start ' => 0 ,
749
+ 'line_end ' => 0 ,
750
+ 'tests ' => [],
751
+ ];
752
+ }
753
+
754
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['line_end ' ] = $ lineEnd ;
755
+ }
756
+
757
+ private function addCoverageBranchTest (
758
+ string $ file ,
759
+ string $ functionName ,
760
+ int $ branchIndex ,
761
+ string $ testId
762
+ ): void {
763
+ $ this ->initializeFileCoverageData ($ file );
764
+
765
+ if (!\array_key_exists ($ functionName , $ this ->data [$ file ]['branches ' ])) {
766
+ $ this ->data [$ file ]['branches ' ][$ functionName ] = [];
767
+ }
768
+
769
+ if (!\array_key_exists ($ branchIndex , $ this ->data [$ file ]['branches ' ][$ functionName ])) {
770
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ] = [
771
+ 'hit ' => 0 ,
772
+ 'line_start ' => 0 ,
773
+ 'line_end ' => 0 ,
774
+ 'tests ' => [],
775
+ ];
776
+ }
777
+
778
+ if (!\in_array ($ testId , $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['tests ' ], true )) {
779
+ $ this ->data [$ file ]['branches ' ][$ functionName ][$ branchIndex ]['tests ' ][] = $ testId ;
780
+ }
781
+ }
782
+
783
+ private function addCoveragePathHit (
784
+ string $ file ,
785
+ string $ functionName ,
786
+ int $ pathId ,
787
+ int $ hit
788
+ ): void {
789
+ $ this ->initializeFileCoverageData ($ file );
790
+
791
+ if (!\array_key_exists ($ functionName , $ this ->data [$ file ]['paths ' ])) {
792
+ $ this ->data [$ file ]['paths ' ][$ functionName ] = [];
793
+ }
794
+
795
+ if (!\array_key_exists ($ pathId , $ this ->data [$ file ]['paths ' ][$ functionName ])) {
796
+ $ this ->data [$ file ]['paths ' ][$ functionName ][$ pathId ] = [
797
+ 'hit ' => 0 ,
798
+ 'path ' => [],
799
+ ];
800
+ }
801
+
802
+ $ this ->data [$ file ]['paths ' ][$ functionName ][$ pathId ]['hit ' ] = \max (
803
+ $ this ->data [$ file ]['paths ' ][$ functionName ][$ pathId ]['hit ' ],
804
+ $ hit
805
+ );
806
+ }
807
+
625
808
/**
626
809
* @throws CoveredCodeNotExecutedException
627
810
* @throws InvalidArgumentException
@@ -643,12 +826,15 @@ private function addUncoveredFilesFromWhitelist(): void
643
826
continue ;
644
827
}
645
828
646
- $ data [$ uncoveredFile ] = [];
829
+ $ data [$ uncoveredFile ] = [
830
+ 'lines ' => [],
831
+ 'functions ' => [],
832
+ ];
647
833
648
834
$ lines = \count (\file ($ uncoveredFile ));
649
835
650
- for ($ i = 1 ; $ i <= $ lines ; $ i ++) {
651
- $ data [$ uncoveredFile ][$ i ] = Driver::LINE_NOT_EXECUTED ;
836
+ for ($ line = 1 ; $ line <= $ lines ; $ line ++) {
837
+ $ data [$ uncoveredFile ][' lines ' ][ $ line ] = Driver::LINE_NOT_EXECUTED ;
652
838
}
653
839
}
654
840
@@ -852,10 +1038,10 @@ private function performUnintentionallyCoveredCodeCheck(array &$data, array $lin
852
1038
853
1039
$ unintentionallyCoveredUnits = [];
854
1040
855
- foreach ($ data as $ file => $ _data ) {
856
- foreach ($ _data as $ line => $ flag ) {
857
- if ($ flag === 1 && !isset ($ allowedLines [$ file ][$ line ])) {
858
- $ unintentionallyCoveredUnits [] = $ this ->wizard ->lookup ($ file , $ line );
1041
+ foreach ($ data as $ file => $ fileData ) {
1042
+ foreach ($ fileData [ ' lines ' ] as $ lineNumber => $ flag ) {
1043
+ if ($ flag === 1 && !isset ($ allowedLines [$ file ][$ lineNumber ])) {
1044
+ $ unintentionallyCoveredUnits [] = $ this ->wizard ->lookup ($ file , $ lineNumber );
859
1045
}
860
1046
}
861
1047
}
0 commit comments