Skip to content

Commit efd9aa3

Browse files
[Bridge/PhpUnit] Add bin/simple-phpunit wrapper (=phpunit - yaml - prophecy)
1 parent c9bb833 commit efd9aa3

File tree

3 files changed

+206
-20
lines changed

3 files changed

+206
-20
lines changed

TextUI/Command.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,4 @@ protected function createRunner()
2323
{
2424
return new TestRunner($this->arguments['loader']);
2525
}
26-
27-
/**
28-
* {@inheritdoc}
29-
*/
30-
protected function handleBootstrap($filename)
31-
{
32-
parent::handleBootstrap($filename);
33-
34-
// By default, we want PHPUnit's autoloader before Symfony's one
35-
if (!getenv('SYMFONY_PHPUNIT_OVERLOAD')) {
36-
$filename = realpath(stream_resolve_include_path($filename));
37-
$symfonyLoader = realpath(dirname(PHPUNIT_COMPOSER_INSTALL).'/../../../vendor/autoload.php');
38-
39-
if ($filename === $symfonyLoader) {
40-
$symfonyLoader = require $symfonyLoader;
41-
$symfonyLoader->unregister();
42-
$symfonyLoader->register(false);
43-
}
44-
}
45-
}
4626
}

bin/simple-phpunit

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the Symfony package.
6+
*
7+
* (c) Fabien Potencier <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
// Please update when phpunit needs to be reinstalled with fresh deps:
14+
// Cache-Id-Version: 2016-09-12 09:00 UTC
15+
16+
error_reporting(-1);
17+
18+
// PHPUnit 4.8 does not support PHP 7, while 5.1 requires PHP 5.6+
19+
$PHPUNIT_VERSION = PHP_VERSION_ID >= 50600 ? '5.1' : '4.8';
20+
$oldPwd = getcwd();
21+
$PHPUNIT_DIR = getenv('SYMFONY_PHPUNIT_DIR') ?: (__DIR__.'/.phpunit');
22+
$PHP = defined('PHP_BINARY') ? PHP_BINARY : 'php';
23+
$PHP = escapeshellarg($PHP);
24+
if ('phpdbg' === PHP_SAPI) {
25+
$PHP .= ' -qrr';
26+
}
27+
28+
$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar`))
29+
? $PHP.' '.escapeshellarg($COMPOSER)
30+
: 'composer';
31+
32+
if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__FILE__) !== @file_get_contents("$PHPUNIT_DIR/.$PHPUNIT_VERSION.md5")) {
33+
// Build a standalone phpunit without symfony/yaml nor prophecy
34+
35+
@mkdir($PHPUNIT_DIR);
36+
chdir($PHPUNIT_DIR);
37+
if (file_exists("phpunit-$PHPUNIT_VERSION")) {
38+
passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION"));
39+
}
40+
if (extension_loaded('openssl') && ini_get('allow_url_fopen')) {
41+
stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb'));
42+
} else {
43+
@unlink("$PHPUNIT_VERSION.zip");
44+
passthru("wget https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip");
45+
}
46+
$zip = new ZipArchive();
47+
$zip->open("$PHPUNIT_VERSION.zip");
48+
$zip->extractTo(getcwd());
49+
$zip->close();
50+
chdir("phpunit-$PHPUNIT_VERSION");
51+
passthru("$COMPOSER remove --no-update phpspec/prophecy");
52+
passthru("$COMPOSER remove --no-update symfony/yaml");
53+
if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) {
54+
passthru("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\"");
55+
}
56+
passthru("$COMPOSER require --dev --no-update symfony/phpunit-bridge \">=3.2@dev\"");
57+
passthru("$COMPOSER install --prefer-dist --no-progress --ansi", $exit);
58+
if ($exit) {
59+
exit($exit);
60+
}
61+
file_put_contents('phpunit', <<<'EOPHP'
62+
<?php
63+
64+
define('PHPUNIT_COMPOSER_INSTALL', __DIR__.'/vendor/autoload.php');
65+
require PHPUNIT_COMPOSER_INSTALL;
66+
Symfony\Bridge\PhpUnit\TextUI\Command::main();
67+
68+
EOPHP
69+
);
70+
chdir('..');
71+
file_put_contents(".$PHPUNIT_VERSION.md5", md5_file(__FILE__));
72+
chdir($oldPwd);
73+
74+
}
75+
76+
$cmd = array_map('escapeshellarg', $argv);
77+
$exit = 0;
78+
79+
if (isset($argv[1]) && 'symfony' === $argv[1] && !file_exists('symfony') && file_exists('src/Symfony')) {
80+
$argv[1] = 'src/Symfony';
81+
}
82+
if (isset($argv[1]) && is_dir($argv[1]) && !file_exists($argv[1].'/phpunit.xml.dist')) {
83+
array_shift($cmd);
84+
}
85+
86+
$cmd[0] = sprintf('%s %s --colors=always', $PHP, escapeshellarg("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit"));
87+
$cmd = str_replace('%', '%%', implode(' ', $cmd)).' %1$s';
88+
89+
if ('\\' === DIRECTORY_SEPARATOR) {
90+
$cmd = 'cmd /v:on /d /c "('.$cmd.')%2$s"';
91+
} else {
92+
$cmd .= '%2$s';
93+
}
94+
95+
if (isset($argv[1]) && is_dir($argv[1]) && !file_exists($argv[1].'/phpunit.xml.dist')) {
96+
// Find Symfony components in plain php for Windows portability
97+
98+
$finder = new RecursiveDirectoryIterator($argv[1], FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::UNIX_PATHS);
99+
$finder = new RecursiveIteratorIterator($finder);
100+
$finder->setMaxDepth(getenv('SYMFONY_PHPUNIT_MAX_DEPTH') ?: 3);
101+
102+
$skippedTests = isset($_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS']) ? $_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS'] : false;
103+
$runningProcs = array();
104+
105+
foreach ($finder as $file => $fileInfo) {
106+
if ('phpunit.xml.dist' === $file) {
107+
$component = dirname($fileInfo->getPathname());
108+
109+
// Run phpunit tests in parallel
110+
111+
if ($skippedTests) {
112+
putenv("SYMFONY_PHPUNIT_SKIPPED_TESTS=$component/$skippedTests");
113+
}
114+
115+
$c = escapeshellarg($component);
116+
117+
if ($proc = proc_open(sprintf($cmd, $c, " > $c/phpunit.stdout 2> $c/phpunit.stderr"), array(), $pipes)) {
118+
$runningProcs[$component] = $proc;
119+
} else {
120+
$exit = 1;
121+
echo "\033[41mKO\033[0m $component\n\n";
122+
}
123+
}
124+
}
125+
126+
// Fixes for colors support on appveyor
127+
// See https://github.com/appveyor/ci/issues/373
128+
$colorFixes = array(
129+
array("S\033[0m\033[0m\033[36m\033[1mS", "E\033[0m\033[0m\033[31m\033[1mE", "I\033[0m\033[0m\033[33m\033[1mI", "F\033[0m\033[0m\033[41m\033[37mF"),
130+
array("SS", "EE", "II", "FF"),
131+
);
132+
$colorFixes[0] = array_merge($colorFixes[0], $colorFixes[0]);
133+
$colorFixes[1] = array_merge($colorFixes[1], $colorFixes[1]);
134+
135+
while ($runningProcs) {
136+
usleep(300000);
137+
$terminatedProcs = array();
138+
foreach ($runningProcs as $component => $proc) {
139+
$procStatus = proc_get_status($proc);
140+
if (!$procStatus['running']) {
141+
$terminatedProcs[$component] = $procStatus['exitcode'];
142+
unset($runningProcs[$component]);
143+
proc_close($proc);
144+
}
145+
}
146+
147+
foreach ($terminatedProcs as $component => $procStatus) {
148+
foreach (array('out', 'err') as $file) {
149+
$file = "$component/phpunit.std$file";
150+
151+
if ('\\' === DIRECTORY_SEPARATOR) {
152+
$h = fopen($file, 'rb');
153+
while (false !== $line = fgets($h)) {
154+
echo str_replace($colorFixes[0], $colorFixes[1], preg_replace(
155+
'/(\033\[[0-9]++);([0-9]++m)(?:(.)(\033\[0m))?/',
156+
"$1m\033[$2$3$4$4",
157+
$line
158+
));
159+
}
160+
fclose($h);
161+
} else {
162+
readfile($file);
163+
}
164+
unlink($file);
165+
}
166+
167+
// Fail on any individual component failures but ignore some error codes on Windows when APCu is enabled:
168+
// STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409)
169+
// STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005)
170+
// STATUS_HEAP_CORRUPTION (-1073740940/0xC0000374)
171+
if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) {
172+
$exit = $procStatus;
173+
echo "\033[41mKO\033[0m $component\n\n";
174+
} else {
175+
echo "\033[32mOK\033[0m $component\n\n";
176+
}
177+
}
178+
}
179+
} elseif (!isset($argv[1]) || 'install' !== $argv[1] || file_exists('install')) {
180+
// Run regular phpunit in a subprocess
181+
182+
$errFile = tempnam(sys_get_temp_dir(), 'phpunit.stderr.');
183+
if ($proc = proc_open(sprintf($cmd, '', ' 2> '.escapeshellarg($errFile)), array(1 => array('pipe', 'w')), $pipes)) {
184+
stream_copy_to_stream($pipes[1], STDOUT);
185+
fclose($pipes[1]);
186+
$exit = proc_close($proc);
187+
188+
readfile($errFile);
189+
unlink($errFile);
190+
}
191+
192+
if (!file_exists($component = array_pop($argv))) {
193+
$component = basename($oldcwd);
194+
}
195+
196+
if ($exit) {
197+
echo "\033[41mKO\033[0m $component\n\n";
198+
} else {
199+
echo "\033[32mOK\033[0m $component\n\n";
200+
}
201+
}
202+
203+
exit($exit);

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
"/Tests/"
3131
]
3232
},
33+
"bin": [
34+
"bin/simple-phpunit"
35+
],
3336
"minimum-stability": "dev",
3437
"extra": {
3538
"branch-alias": {

0 commit comments

Comments
 (0)