Passed
Pull Request — master (#33)
by Melech
03:22
created

Formatter::tests()   B

Complexity

Conditions 7
Paths 17

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 15
c 1
b 0
f 0
nc 17
nop 1
dl 0
loc 30
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Test\Output\Formatters;
15
16
use Valkyrja\Application\Application;
17
use Valkyrja\Test\Exceptions\AssertFailureException;
18
use Valkyrja\Test\Output\Formatter as Contract;
19
use Valkyrja\Test\Output\Results;
20
use Valkyrja\Test\Test;
21
22
use function count;
23
use function strlen;
24
25
use const PHP_EOL;
26
27
/**
28
 * Class Formatter.
29
 *
30
 * @author Melech Mizrachi
31
 */
32
class Formatter implements Contract
33
{
34
    /**
35
     * @inheritDoc
36
     */
37
    public function title(): string
38
    {
39
        return "Valkyrja Unit Testing {$this->getTitleVersion()} by Melech Mizrachi and contributors.";
40
    }
41
42
    /**
43
     * @inheritDoc
44
     */
45
    public function meta(): string
46
    {
47
        return "Time: {$this->getMetaTime()}, Memory: {$this->getMetaMemory()}";
48
    }
49
50
    /**
51
     * @inheritDoc
52
     */
53
    public function tests(Results $results): string
54
    {
55
        $tests = $results->getTests();
56
57
        $testsFormatted = '';
58
59
        foreach ($tests as $test) {
60
            if ($testsFormatted !== '' && (strlen($testsFormatted) % 80) === 0) {
61
                $testsFormatted .= PHP_EOL;
62
            }
63
64
            $assert = $test->getAssert();
65
            $result = $this->getTestSuccess();
66
67
            if ($assert->getWarnings()) {
68
                $result = $this->getTestWarning();
69
            }
70
71
            if ($assert->getErrors()) {
72
                $result = $this->getTestError();
73
            }
74
75
            if ($test->shouldSkip()) {
76
                $result = $this->getTestSkip();
77
            }
78
79
            $testsFormatted .= $result;
80
        }
81
82
        return $testsFormatted;
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88
    public function completed(Results $results): string
89
    {
90
        $tests  = $results->getTests();
91
        $total  = count($tests);
92
        $failed = 0;
93
94
        foreach ($tests as $test) {
95
            $assert = $test->getAssert();
96
97
            if ($assert->getErrors()) {
98
                $failed++;
99
            }
100
        }
101
102
        $count         = $total - $failed;
103
        $percentPassed = ($count / $total) * 100;
104
105
        return $this->getCompleted($count, $total, $percentPassed);
106
    }
107
108
    /**
109
     * @inheritDoc
110
     */
111
    public function results(Results $results): string
112
    {
113
        $tests  = $results->getTests();
114
        $status = $this->getResultsOk();
115
116
        $totalTests      = count($tests);
117
        $totalErrors     = 0;
118
        $totalSkipped    = 0;
119
        $totalWarnings   = 0;
120
        $totalAssertions = 0;
121
122
        foreach ($tests as $test) {
123
            $assert = $test->getAssert();
124
125
            $totalAssertions += count($assert->getAssertions());
126
127
            if ($assert->getWarnings()) {
128
                $status = $this->getResultsWarning();
129
130
                $totalWarnings++;
131
            }
132
133
            if ($assert->getErrors()) {
134
                $status = $this->getResultsError();
135
136
                $totalErrors++;
137
            }
138
139
            if ($test->shouldSkip()) {
140
                $totalSkipped++;
141
            }
142
        }
143
144
        return $this->getResults($status, $totalTests, $totalAssertions, $totalSkipped, $totalWarnings, $totalErrors);
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150
    public function issues(Results $results): string
151
    {
152
        $tests  = $results->getTests();
153
        $issues = [];
154
        $num    = 1;
155
156
        foreach ($tests as $test) {
157
            $assert = $test->getAssert();
158
159
            if ($errors = $assert->getErrors()) {
160
                $error    = $errors[0];
161
                $issues[] = $this->getIssuesIssue($num, $test, $error);
162
163
                $num++;
164
            }
165
        }
166
167
        if (empty($issues)) {
168
            return $this->getIssuesBlank();
169
        }
170
171
        return $this->getIssues($issues);
172
    }
173
174
    /**
175
     * @inheritDoc
176
     */
177
    public function sectionSpacing(): string
178
    {
179
        return PHP_EOL . PHP_EOL;
180
    }
181
182
    /**
183
     * Get the title's version formatted.
184
     */
185
    protected function getTitleVersion(): string
186
    {
187
        return Application::VERSION;
188
    }
189
190
    /**
191
     * Get the meta's time formatted.
192
     */
193
    protected function getMetaTime(): string
194
    {
195
        return '0';
196
    }
197
198
    /**
199
     * Get the meta's memory formatted.
200
     */
201
    protected function getMetaMemory(): string
202
    {
203
        return (string) memory_get_peak_usage();
204
    }
205
206
    /**
207
     * Get the test's success formatted.
208
     */
209
    protected function getTestSuccess(): string
210
    {
211
        return '.';
212
    }
213
214
    /**
215
     * Get the test's warning formatted.
216
     */
217
    protected function getTestWarning(): string
218
    {
219
        return 'W';
220
    }
221
222
    /**
223
     * Get the test's error formatted.
224
     */
225
    protected function getTestError(): string
226
    {
227
        return 'E';
228
    }
229
230
    /**
231
     * Get the test's skip formatted.
232
     */
233
    protected function getTestSkip(): string
234
    {
235
        return 'S';
236
    }
237
238
    /**
239
     * Get the completed full text formatted.
240
     */
241
    protected function getCompleted(int $count, int $total, float|int $percentPassed): string
242
    {
243
        return "{$this->getCompletedCount($count)} / {$this->getCompletedTotal($total)}"
244
            . " ({$this->getCompletedPercentPassed($percentPassed)}%) Completed";
245
    }
246
247
    /**
248
     * Get the completed's count formatted.
249
     */
250
    protected function getCompletedCount(int $count): string
251
    {
252
        return (string) $count;
253
    }
254
255
    /**
256
     * Get the completed's total formatted.
257
     */
258
    protected function getCompletedTotal(int $total): string
259
    {
260
        return (string) $total;
261
    }
262
263
    /**
264
     * Get the completed's percent passed formatted.
265
     */
266
    protected function getCompletedPercentPassed(float|int $percentPassed): string
267
    {
268
        return (string) $percentPassed;
269
    }
270
271
    /**
272
     * Get the results' ok status formatted.
273
     */
274
    protected function getResultsOk(): string
275
    {
276
        return 'OK';
277
    }
278
279
    /**
280
     * Get the results' warning status formatted.
281
     */
282
    protected function getResultsWarning(): string
283
    {
284
        return 'Warning';
285
    }
286
287
    /**
288
     * Get the results' error status formatted.
289
     */
290
    protected function getResultsError(): string
291
    {
292
        return 'Error';
293
    }
294
295
    /**
296
     * Get the results full text formatted.
297
     */
298
    protected function getResults(string $status, int $totalTests, int $totalAssertions, int $totalSkipped, int $totalWarnings, int $totalErrors): string
299
    {
300
        return $status
301
            . ' ('
302
            . $this->getResultsTotalTests($totalTests)
303
            . $this->getResultsTotalAssertions($totalAssertions)
304
            . $this->getResultsTotalErrors($totalErrors)
305
            . $this->getResultsTotalSkipped($totalSkipped)
306
            . $this->getResultsTotalWarnings($totalWarnings)
307
            . ')';
308
    }
309
310
    /**
311
     * Get the results full text total tests formatted.
312
     */
313
    protected function getResultsTotalTests(int $totalTests): string
314
    {
315
        return "{$this->getResultsTotalTestsCount($totalTests)} {$this->getResultsTotalTestsGrammar($totalTests)}";
316
    }
317
318
    /**
319
     * Get the results full text total tests count formatted.
320
     */
321
    protected function getResultsTotalTestsCount(int $totalTests): string
322
    {
323
        return (string) $totalTests;
324
    }
325
326
    /**
327
     * Get the results full text total tests grammar formatted.
328
     */
329
    protected function getResultsTotalTestsGrammar(int $totalTests): string
330
    {
331
        return $totalTests === 1
332
            ? 'test'
333
            : 'tests';
334
    }
335
336
    /**
337
     * Get the results full text total assertions formatted.
338
     */
339
    protected function getResultsTotalAssertions(int $totalAssertions): string
340
    {
341
        return ", {$this->getResultsTotalAssertionsCount($totalAssertions)} {$this->getResultsTotalAssertionsGrammar($totalAssertions)}";
342
    }
343
344
    /**
345
     * Get the results full text total assertions count formatted.
346
     */
347
    protected function getResultsTotalAssertionsCount(int $totalAssertions): string
348
    {
349
        return (string) $totalAssertions;
350
    }
351
352
    /**
353
     * Get the results full text total assertions grammar formatted.
354
     */
355
    protected function getResultsTotalAssertionsGrammar(int $totalAssertions): string
356
    {
357
        return $totalAssertions === 1
358
            ? 'assertion'
359
            : 'assertions';
360
    }
361
362
    /**
363
     * Get the results full text total errors formatted.
364
     */
365
    protected function getResultsTotalErrors(int $totalErrors): string
366
    {
367
        if ($totalErrors <= 0) {
368
            return '';
369
        }
370
371
        return ", {$this->getResultsTotalErrorsCount($totalErrors)} {$this->getResultsTotalErrorsGrammar($totalErrors)}, ";
372
    }
373
374
    /**
375
     * Get the results full text total errors count formatted.
376
     */
377
    protected function getResultsTotalErrorsCount(int $totalErrors): string
378
    {
379
        return (string) $totalErrors;
380
    }
381
382
    /**
383
     * Get the results full text total errors grammar formatted.
384
     */
385
    protected function getResultsTotalErrorsGrammar(int $totalErrors): string
386
    {
387
        return $totalErrors === 1
388
            ? 'error'
389
            : 'errors';
390
    }
391
392
    /**
393
     * Get the results full text total warnings formatted.
394
     */
395
    protected function getResultsTotalWarnings(int $totalWarnings): string
396
    {
397
        if ($totalWarnings <= 0) {
398
            return '';
399
        }
400
401
        return ", {$this->getResultsTotalWarningsCount($totalWarnings)} {$this->getResultsTotalWarningsGrammar($totalWarnings)}, ";
402
    }
403
404
    /**
405
     * Get the results full text total warnings count formatted.
406
     */
407
    protected function getResultsTotalWarningsCount(int $totalWarnings): string
408
    {
409
        return (string) $totalWarnings;
410
    }
411
412
    /**
413
     * Get the results full text total warnings grammar formatted.
414
     */
415
    protected function getResultsTotalWarningsGrammar(int $totalWarnings): string
416
    {
417
        return $totalWarnings === 1
418
            ? 'warning'
419
            : 'warnings';
420
    }
421
422
    /**
423
     * Get the results full text total skipped formatted.
424
     */
425
    protected function getResultsTotalSkipped(int $totalSkipped): string
426
    {
427
        if ($totalSkipped <= 0) {
428
            return '';
429
        }
430
431
        return ", {$this->getResultsTotalSkippedCount($totalSkipped)} {$this->getResultsTotalSkippedGrammar($totalSkipped)}, ";
432
    }
433
434
    /**
435
     * Get the results full text total skipped count formatted.
436
     */
437
    protected function getResultsTotalSkippedCount(int $totalSkipped): string
438
    {
439
        return (string) $totalSkipped;
440
    }
441
442
    /**
443
     * Get the results full text total skipped grammar formatted.
444
     */
445
    protected function getResultsTotalSkippedGrammar(int $totalSkipped): string
0 ignored issues
show
Unused Code introduced by
The parameter $totalSkipped is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

445
    protected function getResultsTotalSkippedGrammar(/** @scrutinizer ignore-unused */ int $totalSkipped): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
446
    {
447
        return 'skipped';
448
    }
449
450
    /**
451
     * Get the issues' issue formatted.
452
     */
453
    protected function getIssuesIssue(int $num, Test $test, AssertFailureException $error): string
454
    {
455
        return "{$this->getIssuesIssueNum($num)} {$this->getIssuesIssueName($test)}"
456
            . $this->getIssuesIssueMessage($error)
457
            . $this->getIssuesIssueTrace($error);
458
    }
459
460
    /**
461
     * Get the issues' issue num formatted.
462
     */
463
    protected function getIssuesIssueNum(int $num): string
464
    {
465
        return "{$num})";
466
    }
467
468
    /**
469
     * Get the issues' issue num formatted.
470
     */
471
    protected function getIssuesIssueName(Test $test): string
472
    {
473
        return $test->getName();
474
    }
475
476
    /**
477
     * Get the issues' issue message formatted.
478
     */
479
    protected function getIssuesIssueMessage(AssertFailureException $error): string
480
    {
481
        return PHP_EOL . $error->getMessage();
482
    }
483
484
    /**
485
     * Get the issues' issue trace formatted.
486
     */
487
    protected function getIssuesIssueTrace(AssertFailureException $error): string
488
    {
489
        return PHP_EOL . $error->getTraceAsString();
490
    }
491
492
    /**
493
     * Get the issues' blank (no errors) formatted.
494
     */
495
    protected function getIssuesBlank(): string
496
    {
497
        return '';
498
    }
499
500
    /**
501
     * Get the issues' count full formatted.
502
     */
503
    protected function getIssuesCountFull(int $count): string
504
    {
505
        return "There {$this->getIssuesCountGrammar($count)} {$this->getIssuesCount($count)} {$this->getIssuesCountErrorGrammar($count)}:";
506
    }
507
508
    /**
509
     * Get the issues' count formatted.
510
     */
511
    protected function getIssuesCount(int $count): string
512
    {
513
        return (string) $count;
514
    }
515
516
    /**
517
     * Get the issues' count grammar formatted.
518
     */
519
    protected function getIssuesCountGrammar(int $count): string
520
    {
521
        return $count === 1
522
            ? 'was'
523
            : 'were';
524
    }
525
526
    /**
527
     * Get the issues' count error grammar formatted.
528
     */
529
    protected function getIssuesCountErrorGrammar(int $count): string
530
    {
531
        return $count === 1
532
            ? 'error'
533
            : 'errors';
534
    }
535
536
    /**
537
     * Get the issues full text formatted.
538
     */
539
    protected function getIssues(array $issues): string
540
    {
541
        return $this->sectionSpacing()
542
            . $this->getIssuesCountFull(count($issues))
543
            . $this->sectionSpacing()
544
            . implode($this->sectionSpacing(), $issues);
545
    }
546
}
547