Skip to content

Commit ff15fd7

Browse files
authored
Fix coverage static analysis cache and move util for reuse (#1840)
1 parent a120f0f commit ff15fd7

File tree

10 files changed

+97
-74
lines changed

10 files changed

+97
-74
lines changed

.github/workflows/test-unit.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
ACCEPT_EULA: Y
107107
SA_PASSWORD: atk4_pass
108108
oracle:
109-
image: gvenzl/oracle-xe:18
109+
image: gvenzl/oracle-xe:18-slim-faststart
110110
env:
111111
ORACLE_PASSWORD: atk4_pass
112112
steps:
@@ -147,7 +147,7 @@ jobs:
147147
php -r '(new PDO("mysql:host=mariadb", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
148148
php -r '(new PDO("pgsql:host=postgres;dbname=atk4_test", "atk4_test_user", "atk4_pass"))->exec("ALTER ROLE atk4_test_user CONNECTION LIMIT 1");'
149149
/usr/lib/oracle/setup.sh
150-
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
150+
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage; fi
151151
152152
- name: "Run tests: SQLite"
153153
run: |
@@ -266,7 +266,7 @@ jobs:
266266
ACCEPT_EULA: Y
267267
SA_PASSWORD: atk4_pass
268268
oracle:
269-
image: gvenzl/oracle-xe:18
269+
image: gvenzl/oracle-xe:18-slim-faststart
270270
env:
271271
ORACLE_PASSWORD: atk4_pass
272272
steps:
@@ -351,7 +351,7 @@ jobs:
351351
php -r '(new PDO("mysql:host=mariadb", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
352352
php -r '(new PDO("pgsql:host=postgres;dbname=atk4_test", "atk4_test_user", "atk4_pass"))->exec("ALTER ROLE atk4_test_user CONNECTION LIMIT 1");'
353353
/usr/lib/oracle/setup.sh
354-
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
354+
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage; fi
355355
ci_wait_until () { timeout 30 sh -c "until { $1 2> /dev/null; }; do sleep 0.02; done" || timeout 15 sh -c "$1" || { echo "health timeout: $1"; exit 1; }; }
356356
php -d opcache.enable_cli=1 -S 127.0.0.1:8888 > /dev/null 2>&1 &
357357
ci_wait_until 'nc -w 1 127.0.0.1 8888'

codecov.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
ignore:
2-
- src/Behat
3-
- demos
4-
- docs
5-
- tools
61
comment: false
72
coverage:
83
status:
94
project:
105
default:
116
target: auto
12-
threshold: 0.025
7+
threshold: 0.015
138
patch: false
149
changes: false

demos/form-control/multiline.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919

2020
/** @var Model $inventoryItemClass */
2121
$inventoryItemClass = AnonymousClassNameCache::get_class(fn () => new class() extends Model {
22-
/** @var Persistence */
23-
public $countryPersistence;
22+
public Persistence $countryPersistence;
2423

2524
protected function init(): void
2625
{

demos/index.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
/** @var \Atk4\Ui\App $app */
1313
require_once __DIR__ . '/init-app.php';
1414

15-
Header::addTo($app)->set('Welcome to Agile Toolkit Demo!!');
15+
Header::addTo($app)->set('Welcome to Agile Toolkit Demo!');
1616

1717
$t = Text::addTo(View::addTo($app, [false, 'class.green' => true, 'ui' => 'segment']));
1818
$t->addParagraph('Take a quick stroll through some of the amazing features of Agile Toolkit.');
1919

2020
Button::addTo($app, ['Begin the demo..', 'class.huge primary fluid' => true, 'iconRight' => 'right arrow'])
2121
->link('tutorial/intro.php');
2222

23-
Header::addTo($app)->set('What is new in Agile Toolkit 2.0');
23+
Header::addTo($app)->set('What is new in Agile Toolkit');
2424

2525
$t = Text::addTo(View::addTo($app, [false, 'class.green' => true, 'ui' => 'segment']));
2626
$t->addParagraph('In this version of Agile Toolkit we introduce "User Actions"!');

demos/init-app.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace Atk4\Ui\Demos;
66

77
use Atk4\Data\Persistence;
8+
use Atk4\Ui\App;
9+
use Atk4\Ui\Behat\CoverageUtil;
810
use Atk4\Ui\Button;
911
use Atk4\Ui\Exception;
1012
use Atk4\Ui\Layout;
@@ -14,12 +16,15 @@
1416
require_once __DIR__ . '/init-autoloader.php';
1517

1618
// collect coverage for HTTP tests 1/2
17-
if (file_exists(__DIR__ . '/CoverageUtil.php') && !class_exists(\PHPUnit\Framework\TestCase::class, false)) {
18-
require_once __DIR__ . '/CoverageUtil.php';
19-
\CoverageUtil::start();
19+
$coverageSaveFx = null;
20+
if (is_dir(__DIR__ . '/../coverage') && !CoverageUtil::isCalledFromPhpunit()) {
21+
CoverageUtil::startFromPhpunitConfig(__DIR__ . '/..');
22+
$coverageSaveFx = function (): void {
23+
CoverageUtil::saveData(__DIR__ . '/../coverage');
24+
};
2025
}
2126

22-
$app = new \Atk4\Ui\App([
27+
$app = new App([
2328
'callExit' => (bool) ($_GET['APP_CALL_EXIT'] ?? true),
2429
'catchExceptions' => (bool) ($_GET['APP_CATCH_EXCEPTIONS'] ?? true),
2530
'alwaysRun' => (bool) ($_GET['APP_ALWAYS_RUN'] ?? true),
@@ -35,11 +40,10 @@
3540
}
3641

3742
// collect coverage for HTTP tests 2/2
38-
if (file_exists(__DIR__ . '/CoverageUtil.php') && !class_exists(\PHPUnit\Framework\TestCase::class, false)) {
39-
$app->onHook(\Atk4\Ui\App::HOOK_BEFORE_EXIT, function () {
40-
\CoverageUtil::saveData();
41-
});
43+
if ($coverageSaveFx !== null) {
44+
$app->onHook(App::HOOK_BEFORE_EXIT, $coverageSaveFx);
4245
}
46+
unset($coverageSaveFx);
4347

4448
final class AnonymousClassNameCache
4549
{

phpunit.xml.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<directory>src</directory>
2525
<directory>tests</directory>
2626
</include>
27+
<exclude>
28+
<directory>src/Behat</directory>
29+
</exclude>
2730
<report>
2831
<php outputFile="coverage/phpunit.cov" />
2932
</report>

src/App.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,16 @@ class App
8181
/**
8282
* Will be set to true after app->run() is called, which may be done automatically
8383
* on exit.
84-
*
85-
* @var bool
8684
*/
87-
public $runCalled = false;
85+
public bool $runCalled = false;
8886

8987
/**
9088
* Will be set to true, when exit is called. Sometimes exit is intercepted by shutdown
9189
* handler and we don't want to execute 'beforeExit' multiple times.
92-
*
93-
* @var bool
9490
*/
95-
private $exitCalled = false;
91+
private bool $exitCalled = false;
9692

97-
/** @var bool */
98-
public $isRendering = false;
93+
public bool $isRendering = false;
9994

10095
/** @var UiPersistence */
10196
public $uiPersistence;

src/Behat/CoverageUtil.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Atk4\Ui\Behat;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use SebastianBergmann\CodeCoverage\CodeCoverage;
9+
use SebastianBergmann\CodeCoverage\Driver\Selector as DriverSelector;
10+
use SebastianBergmann\CodeCoverage\Filter;
11+
use SebastianBergmann\CodeCoverage\Report;
12+
13+
class CoverageUtil
14+
{
15+
private static ?CodeCoverage $coverage = null;
16+
17+
private function __construct()
18+
{
19+
// zeroton
20+
}
21+
22+
public static function start(Filter $filter): void
23+
{
24+
if (self::$coverage !== null) {
25+
throw new \Error('Coverage already started');
26+
}
27+
28+
self::$coverage = new CodeCoverage((new DriverSelector())->forLineCoverage($filter), $filter);
29+
self::$coverage->cacheStaticAnalysis(sys_get_temp_dir() . '/phpunit-coverage.' . md5(__DIR__) . '.cache');
30+
self::$coverage->start(self::class);
31+
}
32+
33+
public static function startFromPhpunitConfig(string $phpunitConfigDir): void
34+
{
35+
$filter = new Filter();
36+
37+
$phpunitCoverageConfig = simplexml_load_file($phpunitConfigDir . '/phpunit.xml.dist')->coverage;
38+
foreach ($phpunitCoverageConfig->include->directory as $path) {
39+
$filter->includeDirectory($phpunitConfigDir . '/' . $path);
40+
}
41+
foreach ($phpunitCoverageConfig->exclude->directory as $path) {
42+
$filter->excludeDirectory($phpunitConfigDir . '/' . $path);
43+
}
44+
45+
static::start($filter);
46+
}
47+
48+
public static function saveData(string $outputDir): void
49+
{
50+
$outputFile = $outputDir . '/' . basename($_SERVER['SCRIPT_NAME'] ?? 'unknown', '.php') . '-' . hash('sha256', microtime(true) . random_bytes(64)) . '.cov';
51+
52+
self::$coverage->stop();
53+
$writer = new Report\PHP();
54+
$writer->process(self::$coverage, $outputFile);
55+
self::$coverage = null;
56+
}
57+
58+
public static function isCalledFromPhpunit(): bool
59+
{
60+
foreach (debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
61+
if (is_a($frame['class'] ?? null, TestCase::class, true)) {
62+
return true;
63+
}
64+
}
65+
66+
return false;
67+
}
68+
}

tests/DemosTest.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,11 @@ class DemosTest extends TestCase
3131
/** @const string */
3232
protected const DEMOS_DIR = self::ROOT_DIR . '/demos';
3333

34-
/** @var array */
35-
private static $_serverSuperglobalBackup;
34+
private static array $_serverSuperglobalBackup;
3635

37-
/** @var Persistence Initialized DB connection */
38-
private static $_db;
36+
private static ?Persistence $_db = null;
3937

40-
/** @var array */
41-
private static $_failedParentTests = [];
38+
private static array $_failedParentTests = [];
4239

4340
public static function setUpBeforeClass(): void
4441
{

tools/CoverageUtil.php

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)