99 */
1010namespace SebastianBergmann \CodeCoverage \Report ;
1111
12- use function count ;
1312use function dirname ;
1413use function file_put_contents ;
15- use function range ;
16- use function time ;
17- use DOMImplementation ;
1814use SebastianBergmann \CodeCoverage \CodeCoverage ;
1915use SebastianBergmann \CodeCoverage \Driver \WriteOperationFailedException ;
20- use SebastianBergmann \CodeCoverage \Node \ File ;
16+ use SebastianBergmann \CodeCoverage \Report \ Cobertura \ CoberturaCoverage ;
2117use SebastianBergmann \CodeCoverage \Util \Filesystem ;
2218
2319final class Cobertura
@@ -27,268 +23,7 @@ final class Cobertura
2723 */
2824 public function process (CodeCoverage $ coverage , ?string $ target = null ): string
2925 {
30- $ time = (string ) time ();
31-
32- $ report = $ coverage ->getReport ();
33-
34- $ implementation = new DOMImplementation ;
35-
36- $ documentType = $ implementation ->createDocumentType (
37- 'coverage ' ,
38- '' ,
39- 'http://cobertura.sourceforge.net/xml/coverage-04.dtd '
40- );
41-
42- $ document = $ implementation ->createDocument ('' , '' , $ documentType );
43- $ document ->xmlVersion = '1.0 ' ;
44- $ document ->encoding = 'UTF-8 ' ;
45- $ document ->formatOutput = true ;
46-
47- $ coverageElement = $ document ->createElement ('coverage ' );
48-
49- $ linesValid = $ report ->numberOfExecutableLines ();
50- $ linesCovered = $ report ->numberOfExecutedLines ();
51- $ lineRate = $ linesValid === 0 ? 0 : ($ linesCovered / $ linesValid );
52- $ coverageElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
53-
54- $ branchesValid = $ report ->numberOfExecutableBranches ();
55- $ branchesCovered = $ report ->numberOfExecutedBranches ();
56- $ branchRate = $ branchesValid === 0 ? 0 : ($ branchesCovered / $ branchesValid );
57- $ coverageElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
58-
59- $ coverageElement ->setAttribute ('lines-covered ' , (string ) $ report ->numberOfExecutedLines ());
60- $ coverageElement ->setAttribute ('lines-valid ' , (string ) $ report ->numberOfExecutableLines ());
61- $ coverageElement ->setAttribute ('branches-covered ' , (string ) $ report ->numberOfExecutedBranches ());
62- $ coverageElement ->setAttribute ('branches-valid ' , (string ) $ report ->numberOfExecutableBranches ());
63- $ coverageElement ->setAttribute ('complexity ' , '' );
64- $ coverageElement ->setAttribute ('version ' , '0.4 ' );
65- $ coverageElement ->setAttribute ('timestamp ' , $ time );
66-
67- $ document ->appendChild ($ coverageElement );
68-
69- $ sourcesElement = $ document ->createElement ('sources ' );
70- $ coverageElement ->appendChild ($ sourcesElement );
71-
72- $ sourceElement = $ document ->createElement ('source ' , $ report ->pathAsString ());
73- $ sourcesElement ->appendChild ($ sourceElement );
74-
75- $ packagesElement = $ document ->createElement ('packages ' );
76- $ coverageElement ->appendChild ($ packagesElement );
77-
78- $ complexity = 0 ;
79-
80- foreach ($ report as $ item ) {
81- if (!$ item instanceof File) {
82- continue ;
83- }
84-
85- $ packageElement = $ document ->createElement ('package ' );
86- $ packageComplexity = 0 ;
87-
88- $ packageElement ->setAttribute ('name ' , str_replace ($ report ->pathAsString () . DIRECTORY_SEPARATOR , '' , $ item ->pathAsString ()));
89-
90- $ linesValid = $ item ->numberOfExecutableLines ();
91- $ linesCovered = $ item ->numberOfExecutedLines ();
92- $ lineRate = $ linesValid === 0 ? 0 : ($ linesCovered / $ linesValid );
93-
94- $ packageElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
95-
96- $ branchesValid = $ item ->numberOfExecutableBranches ();
97- $ branchesCovered = $ item ->numberOfExecutedBranches ();
98- $ branchRate = $ branchesValid === 0 ? 0 : ($ branchesCovered / $ branchesValid );
99-
100- $ packageElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
101-
102- $ packageElement ->setAttribute ('complexity ' , '' );
103- $ packagesElement ->appendChild ($ packageElement );
104-
105- $ classesElement = $ document ->createElement ('classes ' );
106-
107- $ packageElement ->appendChild ($ classesElement );
108-
109- $ classes = $ item ->classesAndTraits ();
110- $ coverageData = $ item ->lineCoverageData ();
111-
112- foreach ($ classes as $ className => $ class ) {
113- $ complexity += $ class ['ccn ' ];
114- $ packageComplexity += $ class ['ccn ' ];
115-
116- if (!empty ($ class ['package ' ]['namespace ' ])) {
117- $ className = $ class ['package ' ]['namespace ' ] . '\\' . $ className ;
118- }
119-
120- $ linesValid = $ class ['executableLines ' ];
121- $ linesCovered = $ class ['executedLines ' ];
122- $ lineRate = $ linesValid === 0 ? 0 : ($ linesCovered / $ linesValid );
123-
124- $ branchesValid = $ class ['executableBranches ' ];
125- $ branchesCovered = $ class ['executedBranches ' ];
126- $ branchRate = $ branchesValid === 0 ? 0 : ($ branchesCovered / $ branchesValid );
127-
128- $ classElement = $ document ->createElement ('class ' );
129-
130- $ classElement ->setAttribute ('name ' , $ className );
131- $ classElement ->setAttribute ('filename ' , str_replace ($ report ->pathAsString () . DIRECTORY_SEPARATOR , '' , $ item ->pathAsString ()));
132- $ classElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
133- $ classElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
134- $ classElement ->setAttribute ('complexity ' , (string ) $ class ['ccn ' ]);
135-
136- $ classesElement ->appendChild ($ classElement );
137-
138- $ methodsElement = $ document ->createElement ('methods ' );
139-
140- $ classElement ->appendChild ($ methodsElement );
141-
142- $ classLinesElement = $ document ->createElement ('lines ' );
143-
144- $ classElement ->appendChild ($ classLinesElement );
145-
146- foreach ($ class ['methods ' ] as $ methodName => $ method ) {
147- if ($ method ['executableLines ' ] === 0 ) {
148- continue ;
149- }
150-
151- preg_match ("/\((.*?)\)/ " , $ method ['signature ' ], $ signature );
152-
153- $ linesValid = $ method ['executableLines ' ];
154- $ linesCovered = $ method ['executedLines ' ];
155- $ lineRate = $ linesValid === 0 ? 0 : ($ linesCovered / $ linesValid );
156-
157- $ branchesValid = $ method ['executableBranches ' ];
158- $ branchesCovered = $ method ['executedBranches ' ];
159- $ branchRate = $ branchesValid === 0 ? 0 : ($ branchesCovered / $ branchesValid );
160-
161- $ methodElement = $ document ->createElement ('method ' );
162-
163- $ methodElement ->setAttribute ('name ' , $ methodName );
164- $ methodElement ->setAttribute ('signature ' , $ signature [1 ]);
165- $ methodElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
166- $ methodElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
167- $ methodElement ->setAttribute ('complexity ' , (string ) $ method ['ccn ' ]);
168-
169- $ methodLinesElement = $ document ->createElement ('lines ' );
170-
171- $ methodElement ->appendChild ($ methodLinesElement );
172-
173- foreach (range ($ method ['startLine ' ], $ method ['endLine ' ]) as $ line ) {
174- if (!isset ($ coverageData [$ line ]) || $ coverageData [$ line ] === null ) {
175- continue ;
176- }
177- $ methodLineElement = $ document ->createElement ('line ' );
178-
179- $ methodLineElement ->setAttribute ('number ' , (string ) $ line );
180- $ methodLineElement ->setAttribute ('hits ' , (string ) count ($ coverageData [$ line ]));
181-
182- $ methodLinesElement ->appendChild ($ methodLineElement );
183-
184- $ classLineElement = $ methodLineElement ->cloneNode ();
185-
186- $ classLinesElement ->appendChild ($ classLineElement );
187- }
188-
189- $ methodsElement ->appendChild ($ methodElement );
190- }
191- }
192-
193- if ($ report ->numberOfFunctions () === 0 ) {
194- $ packageElement ->setAttribute ('complexity ' , (string ) $ packageComplexity );
195-
196- continue ;
197- }
198-
199- $ functionsComplexity = 0 ;
200- $ functionsLinesValid = 0 ;
201- $ functionsLinesCovered = 0 ;
202- $ functionsBranchesValid = 0 ;
203- $ functionsBranchesCovered = 0 ;
204-
205- $ classElement = $ document ->createElement ('class ' );
206- $ classElement ->setAttribute ('name ' , basename ($ item ->pathAsString ()));
207- $ classElement ->setAttribute ('filename ' , str_replace ($ report ->pathAsString () . DIRECTORY_SEPARATOR , '' , $ item ->pathAsString ()));
208-
209- $ methodsElement = $ document ->createElement ('methods ' );
210-
211- $ classElement ->appendChild ($ methodsElement );
212-
213- $ classLinesElement = $ document ->createElement ('lines ' );
214-
215- $ classElement ->appendChild ($ classLinesElement );
216-
217- $ functions = $ report ->functions ();
218-
219- foreach ($ functions as $ functionName => $ function ) {
220- if ($ function ['executableLines ' ] === 0 ) {
221- continue ;
222- }
223-
224- $ complexity += $ function ['ccn ' ];
225- $ packageComplexity += $ function ['ccn ' ];
226- $ functionsComplexity += $ function ['ccn ' ];
227-
228- $ linesValid = $ function ['executableLines ' ];
229- $ linesCovered = $ function ['executedLines ' ];
230- $ lineRate = $ linesValid === 0 ? 0 : ($ linesCovered / $ linesValid );
231-
232- $ functionsLinesValid += $ linesValid ;
233- $ functionsLinesCovered += $ linesCovered ;
234-
235- $ branchesValid = $ function ['executableBranches ' ];
236- $ branchesCovered = $ function ['executedBranches ' ];
237- $ branchRate = $ branchesValid === 0 ? 0 : ($ branchesCovered / $ branchesValid );
238-
239- $ functionsBranchesValid += $ branchesValid ;
240- $ functionsBranchesCovered += $ branchesValid ;
241-
242- $ methodElement = $ document ->createElement ('method ' );
243-
244- $ methodElement ->setAttribute ('name ' , $ functionName );
245- $ methodElement ->setAttribute ('signature ' , $ function ['signature ' ]);
246- $ methodElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
247- $ methodElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
248- $ methodElement ->setAttribute ('complexity ' , (string ) $ function ['ccn ' ]);
249-
250- $ methodLinesElement = $ document ->createElement ('lines ' );
251-
252- $ methodElement ->appendChild ($ methodLinesElement );
253-
254- foreach (range ($ function ['startLine ' ], $ function ['endLine ' ]) as $ line ) {
255- if (!isset ($ coverageData [$ line ]) || $ coverageData [$ line ] === null ) {
256- continue ;
257- }
258- $ methodLineElement = $ document ->createElement ('line ' );
259-
260- $ methodLineElement ->setAttribute ('number ' , (string ) $ line );
261- $ methodLineElement ->setAttribute ('hits ' , (string ) count ($ coverageData [$ line ]));
262-
263- $ methodLinesElement ->appendChild ($ methodLineElement );
264-
265- $ classLineElement = $ methodLineElement ->cloneNode ();
266-
267- $ classLinesElement ->appendChild ($ classLineElement );
268- }
269-
270- $ methodsElement ->appendChild ($ methodElement );
271- }
272-
273- $ packageElement ->setAttribute ('complexity ' , (string ) $ packageComplexity );
274-
275- if ($ functionsLinesValid === 0 ) {
276- continue ;
277- }
278-
279- $ lineRate = $ functionsLinesCovered / $ functionsLinesValid ;
280- $ branchRate = $ functionsBranchesValid === 0 ? 0 : ($ functionsBranchesCovered / $ functionsBranchesValid );
281-
282- $ classElement ->setAttribute ('line-rate ' , (string ) $ lineRate );
283- $ classElement ->setAttribute ('branch-rate ' , (string ) $ branchRate );
284- $ classElement ->setAttribute ('complexity ' , (string ) $ functionsComplexity );
285-
286- $ classesElement ->appendChild ($ classElement );
287- }
288-
289- $ coverageElement ->setAttribute ('complexity ' , (string ) $ complexity );
290-
291- $ buffer = $ document ->saveXML ();
26+ $ buffer = CoberturaCoverage::create ($ coverage ->getReport ())->generateDocument ()->saveXML ();
29227
29328 if ($ target !== null ) {
29429 Filesystem::createDirectory (dirname ($ target ));
0 commit comments