2
2
3
3
namespace ShipMonk \ComposerDependencyAnalyser \Result ;
4
4
5
+ use DOMDocument ;
5
6
use ShipMonk \ComposerDependencyAnalyser \CliOptions ;
6
7
use ShipMonk \ComposerDependencyAnalyser \Config \Configuration ;
7
8
use ShipMonk \ComposerDependencyAnalyser \Config \Ignore \UnusedErrorIgnore ;
8
9
use ShipMonk \ComposerDependencyAnalyser \Config \Ignore \UnusedSymbolIgnore ;
9
10
use ShipMonk \ComposerDependencyAnalyser \Printer ;
10
11
use ShipMonk \ComposerDependencyAnalyser \SymbolKind ;
11
12
use function array_fill_keys ;
12
- use function array_reduce ;
13
13
use function count ;
14
+ use function extension_loaded ;
14
15
use function htmlspecialchars ;
15
16
use function implode ;
16
17
use function sprintf ;
17
18
use function strlen ;
18
19
use function strpos ;
19
20
use function substr ;
21
+ use function trim ;
20
22
use const ENT_COMPAT ;
21
23
use const ENT_XML1 ;
24
+ use const LIBXML_NOEMPTYTAG ;
22
25
use const PHP_INT_MAX ;
23
26
24
27
class JunitFormatter implements ResultFormatter
@@ -120,9 +123,13 @@ public function format(
120
123
$ xml .= $ this ->createUnusedIgnoresTestSuite ($ unusedIgnores );
121
124
}
122
125
126
+ if ($ hasError ) {
127
+ $ xml .= sprintf ('<!-- %s --> ' , $ this ->getUsagesComment ($ maxShownUsages ));
128
+ }
129
+
123
130
$ xml .= '</testsuites> ' ;
124
131
125
- $ this ->printer ->print ($ xml );
132
+ $ this ->printer ->print ($ this -> prettyPrintXml ( $ xml) );
126
133
127
134
if ($ hasError ) {
128
135
return 255 ;
@@ -154,30 +161,18 @@ private function createSymbolBasedTestSuite(string $title, array $errors, int $m
154
161
foreach ($ errors as $ symbol => $ usages ) {
155
162
$ xml .= sprintf ('<testcase name="%s"> ' , $ this ->escape ($ symbol ));
156
163
157
- if ($ maxShownUsages > 1 ) {
158
- $ failureUsage = [];
164
+ $ failureUsage = [];
159
165
160
- foreach ($ usages as $ index => $ usage ) {
161
- $ failureUsage [] = $ this ->relativizeUsage ($ usage );
166
+ foreach ($ usages as $ index => $ usage ) {
167
+ $ failureUsage [] = $ this ->relativizeUsage ($ usage );
162
168
163
- if ($ index === $ maxShownUsages - 1 ) {
164
- $ restUsagesCount = count ($ usages ) - $ index - 1 ;
165
-
166
- if ($ restUsagesCount > 0 ) {
167
- $ failureUsage [] = "+ {$ restUsagesCount } more " ;
168
- break ;
169
- }
170
- }
169
+ if ($ index === $ maxShownUsages ) {
170
+ break ;
171
171
}
172
-
173
- $ xml .= sprintf ('<failure>%s</failure> ' , $ this ->escape (implode ('\n ' , $ failureUsage )));
174
- } else {
175
- $ firstUsage = $ usages [0 ];
176
- $ restUsagesCount = count ($ usages ) - 1 ;
177
- $ rest = $ restUsagesCount > 0 ? " (+ {$ restUsagesCount } more) " : '' ;
178
- $ xml .= sprintf ('<failure>in %s%s</failure> ' , $ this ->escape ($ this ->relativizeUsage ($ firstUsage )), $ rest );
179
172
}
180
173
174
+ $ xml .= sprintf ('<failure>%s</failure> ' , $ this ->escape (implode ("\n" , $ failureUsage )));
175
+
181
176
$ xml .= '</testcase> ' ;
182
177
}
183
178
@@ -195,7 +190,24 @@ private function createPackageBasedTestSuite(string $title, array $errors, int $
195
190
196
191
foreach ($ errors as $ packageName => $ usagesPerClassname ) {
197
192
$ xml .= sprintf ('<testcase name="%s"> ' , $ this ->escape ($ packageName ));
198
- $ xml .= sprintf ('<failure>%s</failure> ' , $ this ->escape (implode ('\n ' , $ this ->createUsages ($ usagesPerClassname , $ maxShownUsages ))));
193
+
194
+ $ printedSymbols = 0 ;
195
+
196
+ foreach ($ usagesPerClassname as $ symbol => $ usages ) {
197
+ $ printedSymbols ++;
198
+ $ xml .= sprintf (
199
+ '<failure message="%s">%s</failure> ' ,
200
+ $ symbol ,
201
+ $ this ->escape (
202
+ implode ("\n" , $ this ->createUsages ($ usages , $ maxShownUsages ))
203
+ )
204
+ );
205
+
206
+ if ($ printedSymbols === $ maxShownUsages ) {
207
+ break ;
208
+ }
209
+ }
210
+
199
211
$ xml .= '</testcase> ' ;
200
212
}
201
213
@@ -205,59 +217,19 @@ private function createPackageBasedTestSuite(string $title, array $errors, int $
205
217
}
206
218
207
219
/**
208
- * @param array<string, list<SymbolUsage>> $usagesPerSymbol
220
+ * @param list<SymbolUsage> $usages
209
221
* @return list<string>
210
222
*/
211
- private function createUsages (array $ usagesPerSymbol , int $ maxShownUsages ): array
223
+ private function createUsages (array $ usages , int $ maxShownUsages ): array
212
224
{
213
225
$ usageMessages = [];
214
226
215
- if ($ maxShownUsages === 1 ) {
216
- $ countOfAllUsages = array_reduce (
217
- $ usagesPerSymbol ,
218
- static function (int $ carry , array $ usages ): int {
219
- return $ carry + count ($ usages );
220
- },
221
- 0
222
- );
227
+ foreach ($ usages as $ index => $ usage ) {
228
+ $ usageMessages [] = $ this ->relativizeUsage ($ usage );
223
229
224
- foreach ($ usagesPerSymbol as $ symbol => $ usages ) {
225
- $ firstUsage = $ usages [0 ];
226
- $ restUsagesCount = $ countOfAllUsages - 1 ;
227
- $ rest = $ countOfAllUsages > 1 ? " (+ {$ restUsagesCount } more) " : '' ;
228
- $ usageMessages [] = "e.g. {$ symbol } in {$ this ->relativizeUsage ($ firstUsage )}$ rest " ;
230
+ if ($ index === $ maxShownUsages - 1 ) {
229
231
break ;
230
232
}
231
- } else {
232
- $ classnamesPrinted = 0 ;
233
-
234
- foreach ($ usagesPerSymbol as $ symbol => $ usages ) {
235
- $ classnamesPrinted ++;
236
-
237
- $ usageMessages [] = $ symbol ;
238
-
239
- foreach ($ usages as $ index => $ usage ) {
240
- $ usageMessages [] = " {$ this ->relativizeUsage ($ usage )}" ;
241
-
242
- if ($ index === $ maxShownUsages - 1 ) {
243
- $ restUsagesCount = count ($ usages ) - $ index - 1 ;
244
-
245
- if ($ restUsagesCount > 0 ) {
246
- $ usageMessages [] = " + {$ restUsagesCount } more " ;
247
- break ;
248
- }
249
- }
250
- }
251
-
252
- if ($ classnamesPrinted === $ maxShownUsages ) {
253
- $ restSymbolsCount = count ($ usagesPerSymbol ) - $ classnamesPrinted ;
254
-
255
- if ($ restSymbolsCount > 0 ) {
256
- $ usageMessages [] = " + {$ restSymbolsCount } more symbol " . ($ restSymbolsCount > 1 ? 's ' : '' );
257
- break ;
258
- }
259
- }
260
- }
261
233
}
262
234
263
235
return $ usageMessages ;
@@ -323,4 +295,37 @@ private function escape(string $string): string
323
295
return htmlspecialchars ($ string , ENT_XML1 | ENT_COMPAT , 'UTF-8 ' );
324
296
}
325
297
298
+ private function prettyPrintXml (string $ inputXml ): string
299
+ {
300
+ if (!extension_loaded ('dom ' ) || !extension_loaded ('libxml ' )) {
301
+ return $ inputXml ;
302
+ }
303
+
304
+ $ dom = new DOMDocument ();
305
+ $ dom ->preserveWhiteSpace = false ;
306
+ $ dom ->formatOutput = true ;
307
+ $ dom ->loadXML ($ inputXml );
308
+
309
+ $ outputXml = $ dom ->saveXML (null , LIBXML_NOEMPTYTAG );
310
+
311
+ if ($ outputXml === false ) {
312
+ return $ inputXml ;
313
+ }
314
+
315
+ return trim ($ outputXml );
316
+ }
317
+
318
+ private function getUsagesComment (int $ maxShownUsages ): string
319
+ {
320
+ if ($ maxShownUsages === PHP_INT_MAX ) {
321
+ return 'showing all failure usages ' ;
322
+ }
323
+
324
+ if ($ maxShownUsages === 1 ) {
325
+ return 'showing only first example failure usage ' ;
326
+ }
327
+
328
+ return sprintf ('showing only first %d example failure usages ' , $ maxShownUsages );
329
+ }
330
+
326
331
}
0 commit comments