Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.00% covered (success)
92.00%
23 / 25
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportPublisher
92.00% covered (success)
92.00%
23 / 25
50.00% covered (danger)
50.00%
1 / 2
10.05
0.00% covered (danger)
0.00%
0 / 1
 publish
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 aggregate
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\WptHarness;
6
7/**
8 * Serialises a `TestResult[]` ledger into the published artefacts:
9 *
10 *   - `var/wpt/report.json`   — machine-readable, full per-test rows
11 *   - `var/wpt/summary.md`    — human-readable summary (counts per
12 *                               bucket, top failure clusters, deltas
13 *                               vs prior run)
14 *   - `docs/site/standards/spec-coverage/wpt-report.md` — published
15 *                                                        dashboard
16 *
17 * Phase 4A.5 implements all three writers. The JSON ledger is the
18 * input to Phase 4A.6 (PR comment delta) and to the spec inventory
19 * regenerator (`composer spec-status`).
20 */
21final class ReportPublisher
22{
23    /**
24     * @param list<TestResult> $results
25     */
26    public function publish(array $results, string $outputDir): void
27    {
28        unset($results, $outputDir);
29        throw new \RuntimeException('4A.5 not yet implemented');
30    }
31
32    /**
33     * Aggregate the bucket counts for a result set. Used by both
34     * publish() and the summary writer.
35     *
36     * @param list<TestResult> $results
37     * @return array{
38     *     pass: int,
39     *     fail: int,
40     *     outOfScope: int,
41     *     pendingSubstrate: int,
42     *     skipped: int,
43     *     harnessError: int,
44     *     inScopeTotal: int,
45     *     inScopePassRate: float
46     * }
47     */
48    public static function aggregate(array $results): array
49    {
50        $counts = [
51            'pass' => 0,
52            'fail' => 0,
53            'outOfScope' => 0,
54            'pendingSubstrate' => 0,
55            'skipped' => 0,
56            'harnessError' => 0,
57        ];
58        foreach ($results as $result) {
59            $counts[match ($result->status) {
60                TestStatus::Pass => 'pass',
61                TestStatus::Fail => 'fail',
62                TestStatus::OutOfScope => 'outOfScope',
63                TestStatus::PendingSubstrate => 'pendingSubstrate',
64                TestStatus::Skipped => 'skipped',
65                TestStatus::HarnessError => 'harnessError',
66            }]++;
67        }
68        $inScopeTotal = $counts['pass'] + $counts['fail'];
69        // PHP `int / int` returns int when divisible — force float so
70        // the rate is always a float in [0.0, 1.0].
71        $inScopePassRate = $inScopeTotal > 0 ? (float) $counts['pass'] / $inScopeTotal : 0.0;
72        return [
73            ...$counts,
74            'inScopeTotal' => $inScopeTotal,
75            'inScopePassRate' => $inScopePassRate,
76        ];
77    }
78}