@@ -33,7 +33,7 @@ final class ProcessedCodeCoverageData
3333 */
3434 private $ functionCoverage = [];
3535
36- public function initializeFilesThatAreSeenTheFirstTime (RawCodeCoverageData $ rawData ): void
36+ public function initializeUnseenData (RawCodeCoverageData $ rawData ): void
3737 {
3838 foreach ($ rawData ->lineCoverage () as $ file => $ lines ) {
3939 if (!isset ($ this ->lineCoverage [$ file ])) {
@@ -46,17 +46,11 @@ public function initializeFilesThatAreSeenTheFirstTime(RawCodeCoverageData $rawD
4646 }
4747
4848 foreach ($ rawData ->functionCoverage () as $ file => $ functions ) {
49- if (!isset ($ this ->functionCoverage [$ file ])) {
50- $ this ->functionCoverage [$ file ] = $ functions ;
51-
52- foreach ($ this ->functionCoverage [$ file ] as $ functionName => $ functionData ) {
53- foreach (\array_keys ($ this ->functionCoverage [$ file ][$ functionName ]['branches ' ]) as $ branchId ) {
54- $ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ]['hit ' ] = [];
55- }
56-
57- foreach (\array_keys ($ this ->functionCoverage [$ file ][$ functionName ]['paths ' ]) as $ pathId ) {
58- $ this ->functionCoverage [$ file ][$ functionName ]['paths ' ][$ pathId ]['hit ' ] = [];
59- }
49+ foreach ($ functions as $ functionName => $ functionData ) {
50+ if (isset ($ this ->functionCoverage [$ file ][$ functionName ])) {
51+ $ this ->initPreviouslySeenFunction ($ file , $ functionName , $ functionData );
52+ } else {
53+ $ this ->initPreviouslyUnseenFunction ($ file , $ functionName , $ functionData );
6054 }
6155 }
6256 }
@@ -107,6 +101,11 @@ public function lineCoverage(): array
107101 return $ this ->lineCoverage ;
108102 }
109103
104+ public function setFunctionCoverage (array $ functionCoverage ): void
105+ {
106+ $ this ->functionCoverage = $ functionCoverage ;
107+ }
108+
110109 public function functionCoverage (): array
111110 {
112111 \ksort ($ this ->functionCoverage );
@@ -169,6 +168,12 @@ public function merge(self $newData): void
169168 }
170169
171170 foreach ($ functions as $ functionName => $ functionData ) {
171+ if (isset ($ this ->functionCoverage [$ file ][$ functionName ])) {
172+ $ this ->initPreviouslySeenFunction ($ file , $ functionName , $ functionData );
173+ } else {
174+ $ this ->initPreviouslyUnseenFunction ($ file , $ functionName , $ functionData );
175+ }
176+
172177 foreach ($ functionData ['branches ' ] as $ branchId => $ branchData ) {
173178 $ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ]['hit ' ] = \array_unique (\array_merge ($ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ]['hit ' ], $ branchData ['hit ' ]));
174179 }
@@ -206,4 +211,42 @@ private function priorityForLine(array $data, int $line): int
206211
207212 return 4 ;
208213 }
214+
215+ /**
216+ * For a function we have never seen before, copy all data over and simply init the 'hit' array
217+ */
218+ private function initPreviouslyUnseenFunction (string $ file , string $ functionName , array $ functionData ): void
219+ {
220+ $ this ->functionCoverage [$ file ][$ functionName ] = $ functionData ;
221+
222+ foreach (\array_keys ($ functionData ['branches ' ]) as $ branchId ) {
223+ $ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ]['hit ' ] = [];
224+ }
225+
226+ foreach (\array_keys ($ functionData ['paths ' ]) as $ pathId ) {
227+ $ this ->functionCoverage [$ file ][$ functionName ]['paths ' ][$ pathId ]['hit ' ] = [];
228+ }
229+ }
230+
231+ /**
232+ * For a function we have seen before, only copy over and init the 'hit' array for any unseen branches and paths.
233+ * Techniques such as mocking and where the contents of a file are different vary during tests (e.g. compiling
234+ * containers) mean that the functions inside a file cannot be relied upon to be static.
235+ */
236+ private function initPreviouslySeenFunction (string $ file , string $ functionName , array $ functionData ): void
237+ {
238+ foreach ($ functionData ['branches ' ] as $ branchId => $ branchData ) {
239+ if (!isset ($ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ])) {
240+ $ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ] = $ branchData ;
241+ $ this ->functionCoverage [$ file ][$ functionName ]['branches ' ][$ branchId ]['hit ' ] = [];
242+ }
243+ }
244+
245+ foreach ($ functionData ['paths ' ] as $ pathId => $ pathData ) {
246+ if (!isset ($ this ->functionCoverage [$ file ][$ functionName ]['paths ' ][$ pathId ])) {
247+ $ this ->functionCoverage [$ file ][$ functionName ]['paths ' ][$ pathId ] = $ pathData ;
248+ $ this ->functionCoverage [$ file ][$ functionName ]['paths ' ][$ pathId ]['hit ' ] = [];
249+ }
250+ }
251+ }
209252}
0 commit comments