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