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