* @author Nicolas Grekas
*/
@@ -90,6 +91,9 @@ class CurlDownloader
$this->authHelper = new AuthHelper($io, $config);
}
+ /**
+ * @return int internal job id
+ */
public function download($resolve, $reject, $origin, $url, $options, $copyTo = null)
{
$attributes = array();
@@ -101,6 +105,9 @@ class CurlDownloader
return $this->initDownload($resolve, $reject, $origin, $url, $options, $copyTo, $attributes);
}
+ /**
+ * @return int internal job id
+ */
private function initDownload($resolve, $reject, $origin, $url, $options, $copyTo = null, array $attributes = array())
{
$attributes = array_merge(array(
@@ -199,8 +206,29 @@ class CurlDownloader
}
$this->checkCurlResult(curl_multi_add_handle($this->multiHandle, $curlHandle));
-// TODO progress
+ // TODO progress
//$params['notification'](STREAM_NOTIFY_RESOLVE, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0, false);
+
+ return (int) $curlHandle;
+ }
+
+ public function abortRequest($id)
+ {
+ if (isset($this->jobs[$id]) && isset($this->jobs[$id]['handle'])) {
+ $job = $this->jobs[$id];
+ curl_multi_remove_handle($this->multiHandle, $job['handle']);
+ curl_close($job['handle']);
+ if (is_resource($job['headerHandle'])) {
+ fclose($job['headerHandle']);
+ }
+ if (is_resource($job['bodyHandle'])) {
+ fclose($job['bodyHandle']);
+ }
+ if ($job['filename']) {
+ @unlink($job['filename'].'~');
+ }
+ unset($this->jobs[$id]);
+ }
}
public function tick()
@@ -235,7 +263,7 @@ class CurlDownloader
$statusCode = null;
$response = null;
try {
-// TODO progress
+ // TODO progress
//$this->onProgress($curlHandle, $job['callback'], $progress, $job['progress']);
if (CURLE_OK !== $errno || $error) {
throw new TransportException($error);
@@ -285,8 +313,6 @@ class CurlDownloader
// fail 4xx and 5xx responses and capture the response
if ($statusCode >= 400 && $statusCode <= 599) {
throw $this->failResponse($job, $response, $response->getStatusMessage());
-// TODO progress
-// $this->io->overwriteError("Downloading (failed)", false);
}
if ($job['attributes']['storeAuth']) {
diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php
index 2fa8fa716..889fae07e 100644
--- a/src/Composer/Util/HttpDownloader.php
+++ b/src/Composer/Util/HttpDownloader.php
@@ -31,6 +31,7 @@ class HttpDownloader
const STATUS_STARTED = 2;
const STATUS_COMPLETED = 3;
const STATUS_FAILED = 4;
+ const STATUS_ABORTED = 5;
private $io;
private $config;
@@ -44,6 +45,7 @@ class HttpDownloader
private $rfs;
private $idGen = 0;
private $disabled;
+ private $allowAsync = false;
/**
* @param IOInterface $io The IO instance
@@ -139,6 +141,10 @@ class HttpDownloader
'origin' => Url::getOrigin($this->config, $request['url']),
);
+ if (!$sync && !$this->allowAsync) {
+ throw new \LogicException('You must use the HttpDownloader instance which is part of a Composer\Loop instance to be able to run async http requests');
+ }
+
// capture username/password from URL if there is one
if (preg_match('{^https?://([^:/]+):([^@/]+)@([^/]+)}i', $request['url'], $match)) {
$this->io->setAuthentication($job['origin'], rawurldecode($match[1]), rawurldecode($match[2]));
@@ -179,8 +185,20 @@ class HttpDownloader
$downloader = $this;
$io = $this->io;
+ $curl = $this->curl;
- $canceler = function () {};
+ $canceler = function () use (&$job, $curl) {
+ if ($job['status'] === self::STATUS_QUEUED) {
+ $job['status'] = self::STATUS_ABORTED;
+ }
+ if ($job['status'] !== self::STATUS_STARTED) {
+ return;
+ }
+ $job['status'] = self::STATUS_ABORTED;
+ if (isset($job['curl_id'])) {
+ $curl->abortRequest($job['curl_id']);
+ }
+ };
$promise = new Promise($resolver, $canceler);
$promise->then(function ($response) use (&$job, $downloader) {
@@ -189,7 +207,6 @@ class HttpDownloader
// TODO 3.0 this should be done directly on $this when PHP 5.3 is dropped
$downloader->markJobDone();
- $downloader->scheduleNextJob();
return $response;
}, function ($e) use (&$job, $downloader) {
@@ -197,7 +214,6 @@ class HttpDownloader
$job['exception'] = $e;
$downloader->markJobDone();
- $downloader->scheduleNextJob();
throw $e;
});
@@ -239,9 +255,9 @@ class HttpDownloader
}
if ($job['request']['copyTo']) {
- $this->curl->download($resolve, $reject, $origin, $url, $options, $job['request']['copyTo']);
+ $job['curl_id'] = $this->curl->download($resolve, $reject, $origin, $url, $options, $job['request']['copyTo']);
} else {
- $this->curl->download($resolve, $reject, $origin, $url, $options);
+ $job['curl_id'] = $this->curl->download($resolve, $reject, $origin, $url, $options);
}
}
@@ -253,51 +269,60 @@ class HttpDownloader
$this->runningJobs--;
}
- /**
- * @private
- */
- public function scheduleNextJob()
- {
- foreach ($this->jobs as $job) {
- if ($job['status'] === self::STATUS_QUEUED) {
- $this->startJob($job['id']);
- if ($this->runningJobs >= $this->maxJobs) {
- return;
- }
- }
- }
- }
-
- public function wait($index = null, $progress = false)
+ public function wait($index = null)
{
while (true) {
- if ($this->curl) {
- $this->curl->tick();
- }
-
- if (null !== $index) {
- if ($this->jobs[$index]['status'] === self::STATUS_COMPLETED || $this->jobs[$index]['status'] === self::STATUS_FAILED) {
- return;
- }
- } else {
- $done = true;
- foreach ($this->jobs as $job) {
- if (!in_array($job['status'], array(self::STATUS_COMPLETED, self::STATUS_FAILED), true)) {
- $done = false;
- break;
- } elseif (!$job['sync']) {
- unset($this->jobs[$job['id']]);
- }
- }
- if ($done) {
- return;
- }
+ if (!$this->countActiveJobs($index)) {
+ return;
}
usleep(1000);
}
}
+ /**
+ * @internal
+ */
+ public function enableAsync()
+ {
+ $this->allowAsync = true;
+ }
+
+ /**
+ * @internal
+ *
+ * @return int number of active (queued or started) jobs
+ */
+ public function countActiveJobs($index = null)
+ {
+ if ($this->runningJobs < $this->maxJobs) {
+ foreach ($this->jobs as $job) {
+ if ($job['status'] === self::STATUS_QUEUED && $this->runningJobs < $this->maxJobs) {
+ $this->startJob($job['id']);
+ }
+ }
+ }
+
+ if ($this->curl) {
+ $this->curl->tick();
+ }
+
+ if (null !== $index) {
+ return $this->jobs[$index]['status'] < self::STATUS_COMPLETED ? 1 : 0;
+ }
+
+ $active = 0;
+ foreach ($this->jobs as $job) {
+ if ($job['status'] < self::STATUS_COMPLETED) {
+ $active++;
+ } elseif (!$job['sync']) {
+ unset($this->jobs[$job['id']]);
+ }
+ }
+
+ return $active;
+ }
+
private function getResponse($index)
{
if (!isset($this->jobs[$index])) {
diff --git a/src/Composer/Util/Loop.php b/src/Composer/Util/Loop.php
index dfaa2ac53..00159d562 100644
--- a/src/Composer/Util/Loop.php
+++ b/src/Composer/Util/Loop.php
@@ -14,6 +14,7 @@ namespace Composer\Util;
use Composer\Util\HttpDownloader;
use React\Promise\Promise;
+use Symfony\Component\Console\Helper\ProgressBar;
/**
* @author Jordi Boggiano
@@ -21,13 +22,22 @@ use React\Promise\Promise;
class Loop
{
private $httpDownloader;
+ private $processExecutor;
+ private $currentPromises;
- public function __construct(HttpDownloader $httpDownloader)
+ public function __construct(HttpDownloader $httpDownloader = null, ProcessExecutor $processExecutor = null)
{
$this->httpDownloader = $httpDownloader;
+ if ($this->httpDownloader) {
+ $this->httpDownloader->enableAsync();
+ }
+ $this->processExecutor = $processExecutor;
+ if ($this->processExecutor) {
+ $this->processExecutor->enableAsync();
+ }
}
- public function wait(array $promises)
+ public function wait(array $promises, ProgressBar $progress = null)
{
/** @var \Exception|null */
$uncaught = null;
@@ -39,10 +49,52 @@ class Loop
}
);
- $this->httpDownloader->wait();
+ $this->currentPromises = $promises;
+ if ($progress) {
+ $totalJobs = 0;
+ if ($this->httpDownloader) {
+ $totalJobs += $this->httpDownloader->countActiveJobs();
+ }
+ if ($this->processExecutor) {
+ $totalJobs += $this->processExecutor->countActiveJobs();
+ }
+ $progress->start($totalJobs);
+ }
+
+ while (true) {
+ $activeJobs = 0;
+
+ if ($this->httpDownloader) {
+ $activeJobs += $this->httpDownloader->countActiveJobs();
+ }
+ if ($this->processExecutor) {
+ $activeJobs += $this->processExecutor->countActiveJobs();
+ }
+
+ if ($progress) {
+ $progress->setProgress($progress->getMaxSteps() - $activeJobs);
+ }
+
+ if (!$activeJobs) {
+ break;
+ }
+
+ usleep(5000);
+ }
+
+ $this->currentPromises = null;
if ($uncaught) {
throw $uncaught;
}
}
+
+ public function abortJobs()
+ {
+ if ($this->currentPromises) {
+ foreach ($this->currentPromises as $promise) {
+ $promise->cancel();
+ }
+ }
+ }
}
diff --git a/src/Composer/Util/ProcessExecutor.php b/src/Composer/Util/ProcessExecutor.php
index a30a04d15..96b9235c8 100644
--- a/src/Composer/Util/ProcessExecutor.php
+++ b/src/Composer/Util/ProcessExecutor.php
@@ -16,18 +16,32 @@ use Composer\IO\IOInterface;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessUtils;
use Symfony\Component\Process\Exception\RuntimeException;
+use React\Promise\Promise;
/**
* @author Robert Schƶnthal
+ * @author Jordi Boggiano
*/
class ProcessExecutor
{
+ const STATUS_QUEUED = 1;
+ const STATUS_STARTED = 2;
+ const STATUS_COMPLETED = 3;
+ const STATUS_FAILED = 4;
+ const STATUS_ABORTED = 5;
+
protected static $timeout = 300;
protected $captureOutput;
protected $errorOutput;
protected $io;
+ private $jobs = array();
+ private $runningJobs = 0;
+ private $maxJobs = 10;
+ private $idGen = 0;
+ private $allowAsync = false;
+
public function __construct(IOInterface $io = null)
{
$this->io = $io;
@@ -112,6 +126,192 @@ class ProcessExecutor
return $process->getExitCode();
}
+ /**
+ * starts a process on the commandline in async mode
+ *
+ * @param string $command the command to execute
+ * @param mixed $output the output will be written into this var if passed by ref
+ * if a callable is passed it will be used as output handler
+ * @param string $cwd the working directory
+ * @return int statuscode
+ */
+ public function executeAsync($command, $cwd = null)
+ {
+ if (!$this->allowAsync) {
+ throw new \LogicException('You must use the ProcessExecutor instance which is part of a Composer\Loop instance to be able to run async processes');
+ }
+
+ $job = array(
+ 'id' => $this->idGen++,
+ 'status' => self::STATUS_QUEUED,
+ 'command' => $command,
+ 'cwd' => $cwd,
+ );
+
+ $resolver = function ($resolve, $reject) use (&$job) {
+ $job['status'] = ProcessExecutor::STATUS_QUEUED;
+ $job['resolve'] = $resolve;
+ $job['reject'] = $reject;
+ };
+
+ $self = $this;
+ $io = $this->io;
+
+ $canceler = function () use (&$job) {
+ if ($job['status'] === self::STATUS_QUEUED) {
+ $job['status'] = self::STATUS_ABORTED;
+ }
+ if ($job['status'] !== self::STATUS_STARTED) {
+ return;
+ }
+ $job['status'] = self::STATUS_ABORTED;
+ try {
+ if (defined('SIGINT')) {
+ $job['process']->signal(SIGINT);
+ }
+ } catch (\Exception $e) {
+ // signal can throw in various conditions, but we don't care if it fails
+ }
+ $job['process']->stop(1);
+ };
+
+ $promise = new Promise($resolver, $canceler);
+ $promise = $promise->then(function () use (&$job, $self) {
+ if ($job['process']->isSuccessful()) {
+ $job['status'] = ProcessExecutor::STATUS_COMPLETED;
+ } else {
+ $job['status'] = ProcessExecutor::STATUS_FAILED;
+ }
+
+ // TODO 3.0 this should be done directly on $this when PHP 5.3 is dropped
+ $self->markJobDone();
+
+ return $job['process'];
+ }, function ($e) use (&$job, $self) {
+ $job['status'] = ProcessExecutor::STATUS_FAILED;
+
+ $self->markJobDone();
+
+ throw $e;
+ });
+ $this->jobs[$job['id']] =& $job;
+
+ if ($this->runningJobs < $this->maxJobs) {
+ $this->startJob($job['id']);
+ }
+
+ return $promise;
+ }
+
+ private function startJob($id)
+ {
+ $job =& $this->jobs[$id];
+ if ($job['status'] !== self::STATUS_QUEUED) {
+ return;
+ }
+
+ // start job
+ $job['status'] = self::STATUS_STARTED;
+ $this->runningJobs++;
+
+ $command = $job['command'];
+ $cwd = $job['cwd'];
+
+ if ($this->io && $this->io->isDebug()) {
+ $safeCommand = preg_replace_callback('{://(?P[^:/\s]+):(?P[^@\s/]+)@}i', function ($m) {
+ if (preg_match('{^[a-f0-9]{12,}$}', $m['user'])) {
+ return '://***:***@';
+ }
+
+ return '://'.$m['user'].':***@';
+ }, $command);
+ $safeCommand = preg_replace("{--password (.*[^\\\\]\') }", '--password \'***\' ', $safeCommand);
+ $this->io->writeError('Executing async command ('.($cwd ?: 'CWD').'): '.$safeCommand);
+ }
+
+ // make sure that null translate to the proper directory in case the dir is a symlink
+ // and we call a git command, because msysgit does not handle symlinks properly
+ if (null === $cwd && Platform::isWindows() && false !== strpos($command, 'git') && getcwd()) {
+ $cwd = realpath(getcwd());
+ }
+
+ // TODO in v3, commands should be passed in as arrays of cmd + args
+ if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
+ $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout());
+ } else {
+ $process = new Process($command, $cwd, null, null, static::getTimeout());
+ }
+
+ $job['process'] = $process;
+
+ $process->start();
+ }
+
+ public function wait($index = null)
+ {
+ while (true) {
+ if (!$this->countActiveJobs($index)) {
+ return;
+ }
+
+ usleep(1000);
+ }
+ }
+
+ /**
+ * @internal
+ */
+ public function enableAsync()
+ {
+ $this->allowAsync = true;
+ }
+
+ /**
+ * @internal
+ *
+ * @return int number of active (queued or started) jobs
+ */
+ public function countActiveJobs($index = null)
+ {
+ // tick
+ foreach ($this->jobs as $job) {
+ if ($job['status'] === self::STATUS_STARTED) {
+ if (!$job['process']->isRunning()) {
+ call_user_func($job['resolve'], $job['process']);
+ }
+ }
+
+ if ($this->runningJobs < $this->maxJobs) {
+ if ($job['status'] === self::STATUS_QUEUED) {
+ $this->startJob($job['id']);
+ }
+ }
+ }
+
+ if (null !== $index) {
+ return $this->jobs[$index]['status'] < self::STATUS_COMPLETED ? 1 : 0;
+ }
+
+ $active = 0;
+ foreach ($this->jobs as $job) {
+ if ($job['status'] < self::STATUS_COMPLETED) {
+ $active++;
+ } else {
+ unset($this->jobs[$job['id']]);
+ }
+ }
+
+ return $active;
+ }
+
+ /**
+ * @private
+ */
+ public function markJobDone()
+ {
+ $this->runningJobs--;
+ }
+
public function splitLines($output)
{
$output = trim($output);
diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php
index c7077afbb..4bac6a88f 100644
--- a/src/Composer/Util/RemoteFilesystem.php
+++ b/src/Composer/Util/RemoteFilesystem.php
@@ -20,6 +20,7 @@ use Composer\Util\HttpDownloader;
use Composer\Util\Http\Response;
/**
+ * @internal
* @author FranƧois Pluchino
* @author Jordi Boggiano
* @author Nils Adermann
@@ -54,8 +55,9 @@ class RemoteFilesystem
* @param Config $config The config
* @param array $options The options
* @param bool $disableTls
+ * @param AuthHelper $authHelper
*/
- public function __construct(IOInterface $io, Config $config, array $options = array(), $disableTls = false)
+ public function __construct(IOInterface $io, Config $config, array $options = array(), $disableTls = false, AuthHelper $authHelper = null)
{
$this->io = $io;
@@ -70,7 +72,7 @@ class RemoteFilesystem
// handle the other externally set options normally.
$this->options = array_replace_recursive($this->options, $options);
$this->config = $config;
- $this->authHelper = new AuthHelper($io, $config);
+ $this->authHelper = isset($authHelper) ? $authHelper : new AuthHelper($io, $config);
}
/**
diff --git a/tests/Composer/Test/Downloader/FileDownloaderTest.php b/tests/Composer/Test/Downloader/FileDownloaderTest.php
index c86ffa2f7..ba8f95db9 100644
--- a/tests/Composer/Test/Downloader/FileDownloaderTest.php
+++ b/tests/Composer/Test/Downloader/FileDownloaderTest.php
@@ -139,8 +139,8 @@ class FileDownloaderTest extends TestCase
->will($this->returnValue($path.'/vendor'));
try {
- $promise = $downloader->download($packageMock, $path);
$loop = new Loop($this->httpDownloader);
+ $promise = $downloader->download($packageMock, $path);
$loop->wait(array($promise));
$this->fail('Download was expected to throw');
@@ -225,8 +225,8 @@ class FileDownloaderTest extends TestCase
touch($dlFile);
try {
- $promise = $downloader->download($packageMock, $path);
$loop = new Loop($this->httpDownloader);
+ $promise = $downloader->download($packageMock, $path);
$loop->wait(array($promise));
$this->fail('Download was expected to throw');
@@ -296,8 +296,8 @@ class FileDownloaderTest extends TestCase
mkdir(dirname($dlFile), 0777, true);
touch($dlFile);
- $promise = $downloader->download($newPackage, $path, $oldPackage);
$loop = new Loop($this->httpDownloader);
+ $promise = $downloader->download($newPackage, $path, $oldPackage);
$loop->wait(array($promise));
$downloader->update($oldPackage, $newPackage, $path);
diff --git a/tests/Composer/Test/Downloader/XzDownloaderTest.php b/tests/Composer/Test/Downloader/XzDownloaderTest.php
index f770b0d35..6996d67f6 100644
--- a/tests/Composer/Test/Downloader/XzDownloaderTest.php
+++ b/tests/Composer/Test/Downloader/XzDownloaderTest.php
@@ -70,8 +70,8 @@ class XzDownloaderTest extends TestCase
$downloader = new XzDownloader($io, $config, $httpDownloader = new HttpDownloader($io, $this->getMockBuilder('Composer\Config')->getMock()), null, null, null);
try {
- $promise = $downloader->download($packageMock, $this->testDir.'/install-path');
$loop = new Loop($httpDownloader);
+ $promise = $downloader->download($packageMock, $this->testDir.'/install-path');
$loop->wait(array($promise));
$downloader->install($packageMock, $this->testDir.'/install-path');
diff --git a/tests/Composer/Test/Downloader/ZipDownloaderTest.php b/tests/Composer/Test/Downloader/ZipDownloaderTest.php
index e3bbe45a8..dc0f55aec 100644
--- a/tests/Composer/Test/Downloader/ZipDownloaderTest.php
+++ b/tests/Composer/Test/Downloader/ZipDownloaderTest.php
@@ -60,9 +60,6 @@ class ZipDownloaderTest extends TestCase
}
}
- /**
- * @group only
- */
public function testErrorMessages()
{
if (!class_exists('ZipArchive')) {
@@ -92,8 +89,8 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', false);
try {
- $promise = $downloader->download($this->package, $path = sys_get_temp_dir().'/composer-zip-test');
$loop = new Loop($this->httpDownloader);
+ $promise = $downloader->download($this->package, $path = sys_get_temp_dir().'/composer-zip-test');
$loop->wait(array($promise));
$downloader->install($this->package, $path);
@@ -125,7 +122,8 @@ class ZipDownloaderTest extends TestCase
->will($this->returnValue(false));
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
/**
@@ -150,12 +148,10 @@ class ZipDownloaderTest extends TestCase
->will($this->throwException(new \ErrorException('Not a directory')));
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
- /**
- * @group only
- */
public function testZipArchiveOnlyGood()
{
if (!class_exists('ZipArchive')) {
@@ -174,45 +170,66 @@ class ZipDownloaderTest extends TestCase
->will($this->returnValue(true));
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
/**
* @expectedException \Exception
- * @expectedExceptionMessage Failed to execute (1) unzip
+ * @expectedExceptionMessage Failed to extract : (1) unzip
*/
public function testSystemUnzipOnlyFailed()
{
- if (!class_exists('ZipArchive')) {
- $this->markTestSkipped('zip extension missing');
- }
-
+ $this->setPrivateProperty('isWindows', false);
$this->setPrivateProperty('hasSystemUnzip', true);
$this->setPrivateProperty('hasZipArchive', false);
+
+ $procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
+ $procMock->expects($this->any())
+ ->method('getExitCode')
+ ->will($this->returnValue(1));
+ $procMock->expects($this->any())
+ ->method('isSuccessful')
+ ->will($this->returnValue(false));
+ $procMock->expects($this->any())
+ ->method('getErrorOutput')
+ ->will($this->returnValue('output'));
+
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
$processExecutor->expects($this->at(0))
- ->method('execute')
- ->will($this->returnValue(1));
+ ->method('executeAsync')
+ ->will($this->returnValue(\React\Promise\resolve($procMock)));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
public function testSystemUnzipOnlyGood()
{
- if (!class_exists('ZipArchive')) {
- $this->markTestSkipped('zip extension missing');
- }
-
+ $this->setPrivateProperty('isWindows', false);
$this->setPrivateProperty('hasSystemUnzip', true);
$this->setPrivateProperty('hasZipArchive', false);
+
+ $procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
+ $procMock->expects($this->any())
+ ->method('getExitCode')
+ ->will($this->returnValue(0));
+ $procMock->expects($this->any())
+ ->method('isSuccessful')
+ ->will($this->returnValue(true));
+ $procMock->expects($this->any())
+ ->method('getErrorOutput')
+ ->will($this->returnValue('output'));
+
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
$processExecutor->expects($this->at(0))
- ->method('execute')
- ->will($this->returnValue(0));
+ ->method('executeAsync')
+ ->will($this->returnValue(\React\Promise\resolve($procMock)));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
public function testNonWindowsFallbackGood()
@@ -225,10 +242,21 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', true);
$this->setPrivateProperty('hasZipArchive', true);
+ $procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
+ $procMock->expects($this->any())
+ ->method('getExitCode')
+ ->will($this->returnValue(1));
+ $procMock->expects($this->any())
+ ->method('isSuccessful')
+ ->will($this->returnValue(false));
+ $procMock->expects($this->any())
+ ->method('getErrorOutput')
+ ->will($this->returnValue('output'));
+
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
$processExecutor->expects($this->at(0))
- ->method('execute')
- ->will($this->returnValue(1));
+ ->method('executeAsync')
+ ->will($this->returnValue(\React\Promise\resolve($procMock)));
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
$zipArchive->expects($this->at(0))
@@ -238,9 +266,10 @@ class ZipDownloaderTest extends TestCase
->method('extractTo')
->will($this->returnValue(true));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
/**
@@ -257,10 +286,21 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', true);
$this->setPrivateProperty('hasZipArchive', true);
+ $procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
+ $procMock->expects($this->any())
+ ->method('getExitCode')
+ ->will($this->returnValue(1));
+ $procMock->expects($this->any())
+ ->method('isSuccessful')
+ ->will($this->returnValue(false));
+ $procMock->expects($this->any())
+ ->method('getErrorOutput')
+ ->will($this->returnValue('output'));
+
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
$processExecutor->expects($this->at(0))
- ->method('execute')
- ->will($this->returnValue(1));
+ ->method('executeAsync')
+ ->will($this->returnValue(\React\Promise\resolve($procMock)));
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
$zipArchive->expects($this->at(0))
@@ -270,9 +310,10 @@ class ZipDownloaderTest extends TestCase
->method('extractTo')
->will($this->returnValue(false));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
public function testWindowsFallbackGood()
@@ -298,9 +339,10 @@ class ZipDownloaderTest extends TestCase
->method('extractTo')
->will($this->returnValue(false));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
}
/**
@@ -330,9 +372,28 @@ class ZipDownloaderTest extends TestCase
->method('extractTo')
->will($this->returnValue(false));
- $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
+ $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
- $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
+ $this->wait($promise);
+ }
+
+ private function wait($promise)
+ {
+ if (null === $promise) {
+ return;
+ }
+
+ $e = null;
+ $promise->then(function () {
+ // noop
+ }, function ($ex) use (&$e) {
+ $e = $ex;
+ });
+
+ if ($e) {
+ throw $e;
+ }
}
}
@@ -350,6 +411,6 @@ class MockedZipDownloader extends ZipDownloader
public function extract(PackageInterface $package, $file, $path)
{
- parent::extract($package, $file, $path);
+ return parent::extract($package, $file, $path);
}
}
diff --git a/tests/Composer/Test/Fixtures/installer/aliases-with-require-dev.test b/tests/Composer/Test/Fixtures/installer/aliases-with-require-dev.test
new file mode 100644
index 000000000..28229eb87
--- /dev/null
+++ b/tests/Composer/Test/Fixtures/installer/aliases-with-require-dev.test
@@ -0,0 +1,90 @@
+--TEST--
+Aliases are loaded when splitting require-dev from require (https://github.com/composer/composer/issues/8954)
+--COMPOSER--
+{
+ "repositories": [
+ {
+ "type": "package",
+ "package": [
+ {
+ "name": "a/aliased", "version": "dev-next", "replace": { "a/aliased-replaced": "self.version" }
+ },
+ {
+ "name": "b/requirer", "version": "2.3.0",
+ "require": { "a/aliased-replaced": "^4.0" }
+ },
+ {
+ "name": "a/aliased2", "version": "dev-next", "replace": { "a/aliased-replaced2": "self.version" }
+ },
+ {
+ "name": "b/requirer2", "version": "2.3.0",
+ "require": { "a/aliased-replaced": "^4.0", "a/aliased-replaced2": "^4.0" }
+ }
+ ]
+ }
+ ],
+ "require": {
+ "a/aliased": "dev-next as 4.1.0-RC2",
+ "b/requirer": "2.3.0"
+ },
+ "require-dev": {
+ "a/aliased2": "dev-next as 4.1.0-RC2",
+ "b/requirer2": "2.3.0"
+ }
+}
+--RUN--
+update
+--EXPECT-LOCK--
+{
+ "packages": [
+ {
+ "name": "a/aliased", "version": "dev-next",
+ "type": "library",
+ "replace": { "a/aliased-replaced": "self.version" }
+ },
+ {
+ "name": "b/requirer", "version": "2.3.0",
+ "require": { "a/aliased-replaced": "^4.0" },
+ "type": "library"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "a/aliased2", "version": "dev-next",
+ "type": "library",
+ "replace": { "a/aliased-replaced2": "self.version" }
+ },
+ {
+ "name": "b/requirer2", "version": "2.3.0",
+ "require": { "a/aliased-replaced": "^4.0", "a/aliased-replaced2": "^4.0" },
+ "type": "library"
+ }
+ ],
+ "aliases": [{
+ "package": "a/aliased2",
+ "version": "dev-next",
+ "alias": "4.1.0-RC2",
+ "alias_normalized": "4.1.0.0-RC2"
+ }, {
+ "package": "a/aliased",
+ "version": "dev-next",
+ "alias": "4.1.0-RC2",
+ "alias_normalized": "4.1.0.0-RC2"
+ }],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "a/aliased": 20,
+ "a/aliased2": 20
+ },
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
+--EXPECT--
+Installing a/aliased (dev-next)
+Marking a/aliased (4.1.0-RC2) as installed, alias of a/aliased (dev-next)
+Installing b/requirer (2.3.0)
+Installing a/aliased2 (dev-next)
+Marking a/aliased2 (4.1.0-RC2) as installed, alias of a/aliased2 (dev-next)
+Installing b/requirer2 (2.3.0)
diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4795-2.test b/tests/Composer/Test/Fixtures/installer/github-issues-4795-2.test
index b8968c35b..62bda3d7d 100644
--- a/tests/Composer/Test/Fixtures/installer/github-issues-4795-2.test
+++ b/tests/Composer/Test/Fixtures/installer/github-issues-4795-2.test
@@ -2,8 +2,8 @@
See Github issue #4795 ( github.com/composer/composer/issues/4795 ).
-Composer\Installer::whitelistUpdateDependencies should not output a warning for dependencies that need to be updated
-that are also a root package, when that root package is also explicitly whitelisted.
+Composer\Installer::allowListUpdateDependencies should not output a warning for dependencies that need to be updated
+that are also a root package, when that root package is also explicitly allowed.
--COMPOSER--
{
diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4795.test b/tests/Composer/Test/Fixtures/installer/github-issues-4795.test
index dc722c379..39803f725 100644
--- a/tests/Composer/Test/Fixtures/installer/github-issues-4795.test
+++ b/tests/Composer/Test/Fixtures/installer/github-issues-4795.test
@@ -2,8 +2,8 @@
See Github issue #4795 ( github.com/composer/composer/issues/4795 ).
-Composer\Installer::whitelistUpdateDependencies intentionally ignores root requirements even if said package is also a
-dependency of one the requirements that is whitelisted for update.
+Composer\Installer::allowListUpdateDependencies intentionally ignores root requirements even if said package is also a
+dependency of one the requirements that is allowed for update.
--COMPOSER--
{
diff --git a/tests/Composer/Test/Fixtures/installer/install-from-lock-removes-package.test b/tests/Composer/Test/Fixtures/installer/install-from-lock-removes-package.test
index b996ff65b..4160fac55 100644
--- a/tests/Composer/Test/Fixtures/installer/install-from-lock-removes-package.test
+++ b/tests/Composer/Test/Fixtures/installer/install-from-lock-removes-package.test
@@ -6,8 +6,8 @@ Install from a lock file that deleted a package
{
"type": "package",
"package": [
- { "name": "whitelisted/pkg", "version": "1.1.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "fixed/dependency": "1.0.0", "old/dependency": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.1.0" },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "fixed/dependency": "1.0.0", "old/dependency": "1.0.0" } },
{ "name": "fixed/dependency", "version": "1.1.0" },
{ "name": "fixed/dependency", "version": "1.0.0" },
{ "name": "old/dependency", "version": "1.0.0" }
@@ -15,14 +15,14 @@ Install from a lock file that deleted a package
}
],
"require": {
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"fixed/dependency": "1.*"
}
}
--LOCK--
{
"packages": [
- { "name": "whitelisted/pkg", "version": "1.1.0" },
+ { "name": "allowed/pkg", "version": "1.1.0" },
{ "name": "fixed/dependency", "version": "1.0.0" }
],
"packages-dev": [],
@@ -33,7 +33,7 @@ Install from a lock file that deleted a package
}
--INSTALLED--
[
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
{ "name": "fixed/dependency", "version": "1.0.0" },
{ "name": "old/dependency", "version": "1.0.0" }
]
@@ -41,4 +41,4 @@ Install from a lock file that deleted a package
install
--EXPECT--
Removing old/dependency (1.0.0)
-Upgrading whitelisted/pkg (1.0.0 => 1.1.0)
+Upgrading allowed/pkg (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test b/tests/Composer/Test/Fixtures/installer/partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test
index f45f6d528..614c87515 100644
--- a/tests/Composer/Test/Fixtures/installer/partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test
+++ b/tests/Composer/Test/Fixtures/installer/partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test
@@ -1,5 +1,5 @@
--TEST--
-Partial update forces updates dev reference from lock file for non whitelisted packages
+Partial update forces updates dev reference from lock file for non allowed packages
--COMPOSER--
{
"repositories": [
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-locked-require.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-locked-require.test
index 0f009ae6f..317f2396d 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-locked-require.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-locked-require.test
@@ -1,13 +1,13 @@
--TEST--
-Update with a package whitelist only updates those packages if they are not present in composer.json
+Update with a package allow list only updates those packages if they are not present in composer.json
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
- { "name": "whitelisted/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0", "fixed/dependency": "1.*" } },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0", "fixed/dependency": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "fixed/dependency", "version": "1.1.0", "require": { "fixed/sub-dependency": "1.*" } },
@@ -18,13 +18,13 @@ Update with a package whitelist only updates those packages if they are not pres
}
],
"require": {
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"fixed/dependency": "1.*"
}
}
--INSTALLED--
[
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "fixed/dependency", "version": "1.0.0", "require": { "fixed/sub-dependency": "1.*" } },
{ "name": "fixed/sub-dependency", "version": "1.0.0" }
@@ -32,7 +32,7 @@ Update with a package whitelist only updates those packages if they are not pres
--LOCK--
{
"packages": [
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0", "fixed/dependency": "1.*" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "fixed/dependency", "version": "1.0.0", "require": { "fixed/sub-dependency": "1.*" } },
{ "name": "fixed/sub-dependency", "version": "1.0.0" }
@@ -47,7 +47,7 @@ Update with a package whitelist only updates those packages if they are not pres
"platform-dev": []
}
--RUN--
-update whitelisted/pkg dependency/pkg
+update allowed/pkg dependency/pkg
--EXPECT--
Upgrading dependency/pkg (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg (1.0.0 => 1.1.0)
+Upgrading allowed/pkg (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-all-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-all-dependencies.test
index 95fd639f2..5c796181a 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-all-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-all-dependencies.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist pattern and all-dependencies flag updates packages and their dependencies, even if defined as root dependency, matching the pattern
+Update with a package allow list pattern and all-dependencies flag updates packages and their dependencies, even if defined as root dependency, matching the pattern
--COMPOSER--
{
"repositories": [
@@ -8,10 +8,10 @@ Update with a package whitelist pattern and all-dependencies flag updates packag
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.1.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg-component1", "version": "1.1.0" },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -23,8 +23,8 @@ Update with a package whitelist pattern and all-dependencies flag updates packag
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg-component1": "1.*",
- "whitelisted/pkg-component2": "1.*",
+ "allowed/pkg-component1": "1.*",
+ "allowed/pkg-component2": "1.*",
"dependency/pkg": "1.*",
"unrelated/pkg": "1.*"
}
@@ -32,8 +32,8 @@ Update with a package whitelist pattern and all-dependencies flag updates packag
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -42,8 +42,8 @@ Update with a package whitelist pattern and all-dependencies flag updates packag
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -58,8 +58,8 @@ Update with a package whitelist pattern and all-dependencies flag updates packag
"platform-dev": []
}
--RUN--
-update whitelisted/pkg-* --with-all-dependencies
+update allowed/pkg-* --with-all-dependencies
--EXPECT--
-Upgrading whitelisted/pkg-component1 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component1 (1.0.0 => 1.1.0)
Upgrading dependency/pkg (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg-component2 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component2 (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-dependencies.test
index d40a924ab..d82138384 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-dependencies.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those packages and their dependencies matching the pattern but no dependencies defined as roo package
+Update with a package allow list only updates those packages and their dependencies matching the pattern but no dependencies defined as roo package
--COMPOSER--
{
"repositories": [
@@ -8,10 +8,10 @@ Update with a package whitelist only updates those packages and their dependenci
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.1.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*", "root/pkg-dependency": "1.*" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*", "root/pkg-dependency": "1.*" } },
+ { "name": "allowed/pkg-component1", "version": "1.1.0" },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*", "root/pkg-dependency": "1.*" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*", "root/pkg-dependency": "1.*" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "root/pkg-dependency", "version": "1.1.0" },
@@ -25,8 +25,8 @@ Update with a package whitelist only updates those packages and their dependenci
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg-component1": "1.*",
- "whitelisted/pkg-component2": "1.*",
+ "allowed/pkg-component1": "1.*",
+ "allowed/pkg-component2": "1.*",
"root/pkg-dependency": "1.*",
"unrelated/pkg": "1.*"
}
@@ -34,8 +34,8 @@ Update with a package whitelist only updates those packages and their dependenci
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "root/pkg-dependency", "version": "1.0.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -45,8 +45,8 @@ Update with a package whitelist only updates those packages and their dependenci
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "root/pkg-dependency", "version": "1.0.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -60,8 +60,8 @@ Update with a package whitelist only updates those packages and their dependenci
"prefer-lowest": false
}
--RUN--
-update whitelisted/pkg-* --with-dependencies
+update allowed/pkg-* --with-dependencies
--EXPECT--
-Upgrading whitelisted/pkg-component1 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component1 (1.0.0 => 1.1.0)
Upgrading dependency/pkg (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg-component2 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component2 (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-root-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-root-dependencies.test
index 55a07b118..5cabcbb4a 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-root-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-with-root-dependencies.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those packages and their dependencies matching the pattern
+Update with a package allow list only updates those packages and their dependencies matching the pattern
--COMPOSER--
{
"repositories": [
@@ -8,16 +8,16 @@ Update with a package whitelist only updates those packages and their dependenci
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.1.0", "require": { "whitelisted/pkg-component2": "1.1.0" } },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0", "require": { "whitelisted/pkg-component2": "1.0.0" } },
- { "name": "whitelisted/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0", "whitelisted/pkg-component5": "1.0.0" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
- { "name": "whitelisted/pkg-component3", "version": "1.1.0", "require": { "whitelisted/pkg-component4": "1.1.0" } },
- { "name": "whitelisted/pkg-component3", "version": "1.0.0", "require": { "whitelisted/pkg-component4": "1.0.0" } },
- { "name": "whitelisted/pkg-component4", "version": "1.1.0" },
- { "name": "whitelisted/pkg-component4", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component5", "version": "1.1.0" },
- { "name": "whitelisted/pkg-component5", "version": "1.0.0" },
+ { "name": "allowed/pkg-component1", "version": "1.1.0", "require": { "allowed/pkg-component2": "1.1.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0", "require": { "allowed/pkg-component2": "1.0.0" } },
+ { "name": "allowed/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0", "allowed/pkg-component5": "1.0.0" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component3", "version": "1.1.0", "require": { "allowed/pkg-component4": "1.1.0" } },
+ { "name": "allowed/pkg-component3", "version": "1.0.0", "require": { "allowed/pkg-component4": "1.0.0" } },
+ { "name": "allowed/pkg-component4", "version": "1.1.0" },
+ { "name": "allowed/pkg-component4", "version": "1.0.0" },
+ { "name": "allowed/pkg-component5", "version": "1.1.0" },
+ { "name": "allowed/pkg-component5", "version": "1.0.0" },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -29,20 +29,20 @@ Update with a package whitelist only updates those packages and their dependenci
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg-component1": "1.*",
- "whitelisted/pkg-component2": "1.*",
- "whitelisted/pkg-component3": "1.0.0",
+ "allowed/pkg-component1": "1.*",
+ "allowed/pkg-component2": "1.*",
+ "allowed/pkg-component3": "1.0.0",
"unrelated/pkg": "1.*"
}
}
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0", "require": { "whitelisted/pkg-component2": "1.0.0" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
- { "name": "whitelisted/pkg-component3", "version": "1.0.0", "require": { "whitelisted/pkg-component4": "1.0.0" } },
- { "name": "whitelisted/pkg-component4", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component5", "version": "1.0.0" },
+ { "name": "allowed/pkg-component1", "version": "1.0.0", "require": { "allowed/pkg-component2": "1.0.0" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component3", "version": "1.0.0", "require": { "allowed/pkg-component4": "1.0.0" } },
+ { "name": "allowed/pkg-component4", "version": "1.0.0" },
+ { "name": "allowed/pkg-component5", "version": "1.0.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -51,11 +51,11 @@ Update with a package whitelist only updates those packages and their dependenci
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0", "require": { "whitelisted/pkg-component2": "1.0.0" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
- { "name": "whitelisted/pkg-component3", "version": "1.0.0", "require": { "whitelisted/pkg-component4": "1.0.0" } },
- { "name": "whitelisted/pkg-component4", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component5", "version": "1.0.0" },
+ { "name": "allowed/pkg-component1", "version": "1.0.0", "require": { "allowed/pkg-component2": "1.0.0" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component3", "version": "1.0.0", "require": { "allowed/pkg-component4": "1.0.0" } },
+ { "name": "allowed/pkg-component4", "version": "1.0.0" },
+ { "name": "allowed/pkg-component5", "version": "1.0.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -70,8 +70,8 @@ Update with a package whitelist only updates those packages and their dependenci
"platform-dev": []
}
--RUN--
-update whitelisted/pkg-* foobar --with-dependencies
+update allowed/pkg-* foobar --with-dependencies
--EXPECT--
Upgrading dependency/pkg (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg-component2 (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg-component1 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component2 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component1 (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-without-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-without-dependencies.test
index 6cd1d7778..6ceec16b2 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-without-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns-without-dependencies.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those packages matching the pattern
+Update with a package allow list only updates those packages matching the pattern
--COMPOSER--
{
"repositories": [
@@ -8,10 +8,10 @@ Update with a package whitelist only updates those packages matching the pattern
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.1.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg-component1", "version": "1.1.0" },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -23,16 +23,16 @@ Update with a package whitelist only updates those packages matching the pattern
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg-component1": "1.*",
- "whitelisted/pkg-component2": "1.*",
+ "allowed/pkg-component1": "1.*",
+ "allowed/pkg-component2": "1.*",
"unrelated/pkg": "1.*"
}
}
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -41,8 +41,8 @@ Update with a package whitelist only updates those packages matching the pattern
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component1", "version": "1.0.0" },
- { "name": "whitelisted/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg-component1", "version": "1.0.0" },
+ { "name": "allowed/pkg-component2", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -55,7 +55,7 @@ Update with a package whitelist only updates those packages matching the pattern
"prefer-lowest": false
}
--RUN--
-update whitelisted/pkg-*
+update allowed/pkg-*
--EXPECT--
-Upgrading whitelisted/pkg-component1 (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg-component2 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component1 (1.0.0 => 1.1.0)
+Upgrading allowed/pkg-component2 (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns.test
index 738f0af74..fde1c9eab 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-patterns.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those corresponding to the pattern
+Update with a package allow list only updates those corresponding to the pattern
--COMPOSER--
{
"repositories": [
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-removes-unused.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-removes-unused.test
index 9360bc2f6..7f2299566 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-removes-unused.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-removes-unused.test
@@ -1,13 +1,13 @@
--TEST--
-Update with a package whitelist removes unused packages
+Update with a package allow list removes unused packages
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
- { "name": "whitelisted/pkg", "version": "1.1.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "fixed/dependency": "1.0.0", "old/dependency": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.1.0" },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "fixed/dependency": "1.0.0", "old/dependency": "1.0.0" } },
{ "name": "fixed/dependency", "version": "1.1.0" },
{ "name": "fixed/dependency", "version": "1.0.0" },
{ "name": "old/dependency", "version": "1.0.0" }
@@ -15,20 +15,20 @@ Update with a package whitelist removes unused packages
}
],
"require": {
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"fixed/dependency": "1.*"
}
}
--INSTALLED--
[
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
{ "name": "fixed/dependency", "version": "1.0.0" },
{ "name": "old/dependency", "version": "1.0.0" }
]
--LOCK--
{
"packages": [
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "old/dependency": "1.0.0", "fixed/dependency": "1.0.0" } },
{ "name": "fixed/dependency", "version": "1.0.0" },
{ "name": "old/dependency", "version": "1.0.0" }
],
@@ -42,7 +42,7 @@ Update with a package whitelist removes unused packages
"platform-dev": []
}
--RUN--
-update --with-dependencies whitelisted/pkg
+update --with-dependencies allowed/pkg
--EXPECT--
Removing old/dependency (1.0.0)
-Upgrading whitelisted/pkg (1.0.0 => 1.1.0)
+Upgrading allowed/pkg (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependencies.test
index 079ad9d2b..5b02b7d0d 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependencies.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those packages and their dependencies listed as command arguments
+Update with a package allow list only updates those packages and their dependencies listed as command arguments
--COMPOSER--
{
"repositories": [
@@ -8,8 +8,8 @@ Update with a package whitelist only updates those packages and their dependenci
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0" } },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -21,14 +21,14 @@ Update with a package whitelist only updates those packages and their dependenci
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"unrelated/pkg": "1.*"
}
}
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -37,7 +37,7 @@ Update with a package whitelist only updates those packages and their dependenci
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -50,7 +50,7 @@ Update with a package whitelist only updates those packages and their dependenci
"prefer-lowest": false
}
--RUN--
-update whitelisted/pkg --with-dependencies
+update allowed/pkg --with-dependencies
--EXPECT--
Upgrading dependency/pkg (1.0.0 => 1.1.0)
-Upgrading whitelisted/pkg (1.0.0 => 1.1.0)
+Upgrading allowed/pkg (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependency-conflict.test b/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependency-conflict.test
index 299c505cb..abdc48979 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependency-conflict.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependency-conflict.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates whitelisted packages if no dependency conflicts
+Update with a package allow list only updates allowed packages if no dependency conflicts
--COMPOSER--
{
"repositories": [
@@ -8,8 +8,8 @@ Update with a package whitelist only updates whitelisted packages if no dependen
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0" } },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.1.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -21,14 +21,14 @@ Update with a package whitelist only updates whitelisted packages if no dependen
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"unrelated/pkg": "1.*"
}
}
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -37,7 +37,7 @@ Update with a package whitelist only updates whitelisted packages if no dependen
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.0.0" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -50,5 +50,5 @@ Update with a package whitelist only updates whitelisted packages if no dependen
"prefer-lowest": false
}
--RUN--
-update whitelisted/pkg
+update allowed/pkg
--EXPECT--
diff --git a/tests/Composer/Test/Fixtures/installer/update-allow-list.test b/tests/Composer/Test/Fixtures/installer/update-allow-list.test
index a02e00c4b..593375442 100644
--- a/tests/Composer/Test/Fixtures/installer/update-allow-list.test
+++ b/tests/Composer/Test/Fixtures/installer/update-allow-list.test
@@ -1,5 +1,5 @@
--TEST--
-Update with a package whitelist only updates those packages listed as command arguments
+Update with a package allow list only updates those packages listed as command arguments
--COMPOSER--
{
"repositories": [
@@ -8,8 +8,8 @@ Update with a package whitelist only updates those packages listed as command ar
"package": [
{ "name": "fixed/pkg", "version": "1.1.0" },
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.1.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
{ "name": "dependency/pkg", "version": "1.1.0" },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.1.0", "require": { "unrelated/pkg-dependency": "1.*" } },
@@ -21,14 +21,14 @@ Update with a package whitelist only updates those packages listed as command ar
],
"require": {
"fixed/pkg": "1.*",
- "whitelisted/pkg": "1.*",
+ "allowed/pkg": "1.*",
"unrelated/pkg": "1.*"
}
}
--INSTALLED--
[
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency": "1.*" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -37,7 +37,7 @@ Update with a package whitelist only updates those packages listed as command ar
{
"packages": [
{ "name": "fixed/pkg", "version": "1.0.0" },
- { "name": "whitelisted/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
+ { "name": "allowed/pkg", "version": "1.0.0", "require": { "dependency/pkg": "1.*" } },
{ "name": "dependency/pkg", "version": "1.0.0" },
{ "name": "unrelated/pkg", "version": "1.0.0", "require": { "unrelated/pkg-dependency": "1.*" } },
{ "name": "unrelated/pkg-dependency", "version": "1.0.0" }
@@ -52,6 +52,6 @@ Update with a package whitelist only updates those packages listed as command ar
"platform-dev": []
}
--RUN--
-update whitelisted/pkg
+update allowed/pkg
--EXPECT--
-Upgrading whitelisted/pkg (1.0.0 => 1.1.0)
+Upgrading allowed/pkg (1.0.0 => 1.1.0)
diff --git a/tests/Composer/Test/Fixtures/installer/update-changes-url.test b/tests/Composer/Test/Fixtures/installer/update-changes-url.test
index 4831c7705..521b5611a 100644
--- a/tests/Composer/Test/Fixtures/installer/update-changes-url.test
+++ b/tests/Composer/Test/Fixtures/installer/update-changes-url.test
@@ -3,10 +3,10 @@ Update updates URLs for updated packages if they have changed
a/a is dev and gets everything updated as it updates to a new ref
b/b is a tag and gets everything updated by updating the package URL directly
-c/c is a tag and not whitelisted and remains unchanged
+c/c is a tag and not allowlisted and remains unchanged
d/d is dev but with a #ref so it should get URL updated but not the reference
e/e is dev and newly installed with a #ref so it should get the correct URL but with the #111 ref
-f/f is dev but not whitelisted and remains unchanged
+f/f is dev but not allowlisted and remains unchanged
g/g is dev and installed in a different ref than the #ref, so it gets updated and gets the new URL but not the new ref
--COMPOSER--
{
diff --git a/tests/Composer/Test/Fixtures/installer/update-with-all-dependencies.test b/tests/Composer/Test/Fixtures/installer/update-with-all-dependencies.test
index a950b247a..e9fc88ef9 100644
--- a/tests/Composer/Test/Fixtures/installer/update-with-all-dependencies.test
+++ b/tests/Composer/Test/Fixtures/installer/update-with-all-dependencies.test
@@ -2,7 +2,7 @@
See Github issue #6661 ( github.com/composer/composer/issues/6661 ).
-When `--with-all-dependencies` is used, Composer\Installer::whitelistUpdateDependencies should update the dependencies of all whitelisted packages, even if the dependency is a root requirement.
+When `--with-all-dependencies` is used, Composer should update the dependencies of all allowed packages, even if the dependency is a root requirement.
--COMPOSER--
{
diff --git a/tests/Composer/Test/Mock/FactoryMock.php b/tests/Composer/Test/Mock/FactoryMock.php
index 608d572dd..a073f0ab7 100644
--- a/tests/Composer/Test/Mock/FactoryMock.php
+++ b/tests/Composer/Test/Mock/FactoryMock.php
@@ -23,6 +23,7 @@ use Composer\EventDispatcher\EventDispatcher;
use Composer\IO\IOInterface;
use Composer\Test\TestCase;
use Composer\Util\Loop;
+use Composer\Util\ProcessExecutor;
class FactoryMock extends Factory
{
@@ -47,7 +48,7 @@ class FactoryMock extends Factory
return new InstallationManagerMock();
}
- protected function createDefaultInstallers(Installer\InstallationManager $im, Composer $composer, IOInterface $io)
+ protected function createDefaultInstallers(Installer\InstallationManager $im, Composer $composer, IOInterface $io, ProcessExecutor $process = null)
{
}
diff --git a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php
index 45a635437..9204e6fa6 100644
--- a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php
+++ b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php
@@ -18,6 +18,7 @@ use Composer\Package\Archiver\ArchiveManager;
use Composer\Package\PackageInterface;
use Composer\Util\Loop;
use Composer\Test\Mock\FactoryMock;
+use Composer\Util\ProcessExecutor;
class ArchiveManagerTest extends ArchiverTest
{
@@ -36,7 +37,8 @@ class ArchiveManagerTest extends ArchiverTest
$dm = $factory->createDownloadManager(
$io = new NullIO,
$config = FactoryMock::createConfig(),
- $httpDownloader = $factory->createHttpDownloader($io, $config)
+ $httpDownloader = $factory->createHttpDownloader($io, $config),
+ new ProcessExecutor($io)
);
$loop = new Loop($httpDownloader);
$this->manager = $factory->createArchiveManager($factory->createConfig(), $dm, $loop);
diff --git a/tests/Composer/Test/Package/BasePackageTest.php b/tests/Composer/Test/Package/BasePackageTest.php
index 33d384d69..5f5f17cd1 100644
--- a/tests/Composer/Test/Package/BasePackageTest.php
+++ b/tests/Composer/Test/Package/BasePackageTest.php
@@ -81,7 +81,7 @@ class BasePackageTest extends TestCase
$createPackage = function ($arr) use ($self) {
$package = $self->getMockForAbstractClass('\Composer\Package\BasePackage', array(), '', false);
$package->expects($self->once())->method('isDev')->will($self->returnValue(true));
- $package->expects($self->once())->method('getSourceType')->will($self->returnValue('git'));
+ $package->expects($self->any())->method('getSourceType')->will($self->returnValue('git'));
$package->expects($self->once())->method('getPrettyVersion')->will($self->returnValue('PrettyVersion'));
$package->expects($self->any())->method('getSourceReference')->will($self->returnValue($arr['sourceReference']));
diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
index 4fcbbb431..01e3be4ce 100644
--- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php
+++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
@@ -189,16 +189,19 @@ class ComposerRepositoryTest extends TestCase
->getMock();
$httpDownloader->expects($this->at(0))
+ ->method('enableAsync');
+
+ $httpDownloader->expects($this->at(1))
->method('get')
->with($url = 'http://example.org/packages.json')
->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array('search' => '/search.json?q=%query%&type=%type%'))));
- $httpDownloader->expects($this->at(1))
+ $httpDownloader->expects($this->at(2))
->method('get')
->with($url = 'http://example.org/search.json?q=foo&type=composer-plugin')
->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode($result)));
- $httpDownloader->expects($this->at(2))
+ $httpDownloader->expects($this->at(3))
->method('get')
->with($url = 'http://example.org/search.json?q=foo&type=library')
->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array())));
@@ -291,6 +294,9 @@ class ComposerRepositoryTest extends TestCase
->getMock();
$httpDownloader->expects($this->at(0))
+ ->method('enableAsync');
+
+ $httpDownloader->expects($this->at(1))
->method('get')
->with($url = 'http://example.org/packages.json')
->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array(
diff --git a/tests/Composer/Test/Repository/PlatformRepositoryTest.php b/tests/Composer/Test/Repository/PlatformRepositoryTest.php
index aa51a2fc6..519aadb31 100644
--- a/tests/Composer/Test/Repository/PlatformRepositoryTest.php
+++ b/tests/Composer/Test/Repository/PlatformRepositoryTest.php
@@ -14,11 +14,15 @@ namespace Composer\Test\Repository;
use Composer\Repository\PlatformRepository;
use Composer\Test\TestCase;
+use Composer\Util\ProcessExecutor;
+use Composer\Package\Version\VersionParser;
use Composer\Util\Platform;
use Symfony\Component\Process\ExecutableFinder;
-class PlatformRepositoryTest extends TestCase {
- public function testHHVMVersionWhenExecutingInHHVM() {
+class PlatformRepositoryTest extends TestCase
+{
+ public function testHHVMVersionWhenExecutingInHHVM()
+ {
if (!defined('HHVM_VERSION_ID')) {
$this->markTestSkipped('Not running with HHVM');
return;
@@ -36,7 +40,8 @@ class PlatformRepositoryTest extends TestCase {
);
}
- public function testHHVMVersionWhenExecutingInPHP() {
+ public function testHHVMVersionWhenExecutingInPHP()
+ {
if (defined('HHVM_VERSION_ID')) {
$this->markTestSkipped('Running with HHVM');
return;
@@ -54,17 +59,18 @@ class PlatformRepositoryTest extends TestCase {
if ($hhvm === null) {
$this->markTestSkipped('HHVM is not installed');
}
- $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
- $process->expects($this->once())->method('execute')->will($this->returnCallback(
- function($command, &$out) {
- $this->assertContains('HHVM_VERSION', $command);
- $out = '4.0.1-dev';
- return 0;
- }
- ));
- $repository = new PlatformRepository(array(), array(), $process);
+ $repository = new PlatformRepository(array(), array());
$package = $repository->findPackage('hhvm', '*');
$this->assertNotNull($package, 'failed to find HHVM package');
- $this->assertSame('4.0.1.0-dev', $package->getVersion());
+
+ $process = new ProcessExecutor();
+ $exitCode = $process->execute(
+ ProcessExecutor::escape($hhvm).
+ ' --php -d hhvm.jit=0 -r "echo HHVM_VERSION;" 2>/dev/null',
+ $version
+ );
+ $parser = new VersionParser;
+
+ $this->assertSame($parser->normalize($version), $package->getVersion());
}
}
diff --git a/tests/Composer/Test/Util/RemoteFilesystemTest.php b/tests/Composer/Test/Util/RemoteFilesystemTest.php
index fe4f213c6..361dd1669 100644
--- a/tests/Composer/Test/Util/RemoteFilesystemTest.php
+++ b/tests/Composer/Test/Util/RemoteFilesystemTest.php
@@ -12,32 +12,25 @@
namespace Composer\Test\Util;
+use Composer\Config;
+use Composer\IO\ConsoleIO;
+use Composer\IO\IOInterface;
+use Composer\Util\AuthHelper;
use Composer\Util\RemoteFilesystem;
use Composer\Test\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
+use ReflectionMethod;
+use ReflectionProperty;
class RemoteFilesystemTest extends TestCase
{
- private function getConfigMock()
- {
- $config = $this->getMockBuilder('Composer\Config')->getMock();
- $config->expects($this->any())
- ->method('get')
- ->will($this->returnCallback(function ($key) {
- if ($key === 'github-domains' || $key === 'gitlab-domains') {
- return array();
- }
- }));
-
- return $config;
- }
-
public function testGetOptionsForUrl()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$io
->expects($this->once())
->method('hasAuthentication')
- ->will($this->returnValue(false))
+ ->willReturn(false)
;
$res = $this->callGetOptionsForUrl($io, array('http://example.org', array()));
@@ -46,16 +39,16 @@ class RemoteFilesystemTest extends TestCase
public function testGetOptionsForUrlWithAuthorization()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$io
->expects($this->once())
->method('hasAuthentication')
- ->will($this->returnValue(true))
+ ->willReturn(true)
;
$io
->expects($this->once())
->method('getAuthentication')
- ->will($this->returnValue(array('username' => 'login', 'password' => 'password')))
+ ->willReturn(array('username' => 'login', 'password' => 'password'))
;
$options = $this->callGetOptionsForUrl($io, array('http://example.org', array()));
@@ -71,17 +64,17 @@ class RemoteFilesystemTest extends TestCase
public function testGetOptionsForUrlWithStreamOptions()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$io
->expects($this->once())
->method('hasAuthentication')
- ->will($this->returnValue(true))
+ ->willReturn(true)
;
$io
->expects($this->once())
->method('getAuthentication')
- ->will($this->returnValue(array('username' => null, 'password' => null)))
+ ->willReturn(array('username' => null, 'password' => null))
;
$streamOptions = array('ssl' => array(
@@ -94,17 +87,17 @@ class RemoteFilesystemTest extends TestCase
public function testGetOptionsForUrlWithCallOptionsKeepsHeader()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$io
->expects($this->once())
->method('hasAuthentication')
- ->will($this->returnValue(true))
+ ->willReturn(true)
;
$io
->expects($this->once())
->method('getAuthentication')
- ->will($this->returnValue(array('username' => null, 'password' => null)))
+ ->willReturn(array('username' => null, 'password' => null))
;
$streamOptions = array('http' => array(
@@ -127,14 +120,14 @@ class RemoteFilesystemTest extends TestCase
public function testCallbackGetFileSize()
{
- $fs = new RemoteFilesystem($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getConfigMock());
+ $fs = new RemoteFilesystem($this->getIOInterfaceMock(), $this->getConfigMock());
$this->callCallbackGet($fs, STREAM_NOTIFY_FILE_SIZE_IS, 0, '', 0, 0, 20);
$this->assertAttributeEquals(20, 'bytesMax', $fs);
}
public function testCallbackGetNotifyProgress()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$io
->expects($this->once())
->method('overwriteError')
@@ -150,21 +143,21 @@ class RemoteFilesystemTest extends TestCase
public function testCallbackGetPassesThrough404()
{
- $fs = new RemoteFilesystem($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getConfigMock());
+ $fs = new RemoteFilesystem($this->getIOInterfaceMock(), $this->getConfigMock());
$this->assertNull($this->callCallbackGet($fs, STREAM_NOTIFY_FAILURE, 0, 'HTTP/1.1 404 Not Found', 404, 0, 0));
}
public function testGetContents()
{
- $fs = new RemoteFilesystem($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getConfigMock());
+ $fs = new RemoteFilesystem($this->getIOInterfaceMock(), $this->getConfigMock());
$this->assertContains('testGetContents', $fs->getContents('http://example.org', 'file://'.__FILE__));
}
public function testCopy()
{
- $fs = new RemoteFilesystem($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getConfigMock());
+ $fs = new RemoteFilesystem($this->getIOInterfaceMock(), $this->getConfigMock());
$file = tempnam(sys_get_temp_dir(), 'c');
$this->assertTrue($fs->copy('http://example.org', 'file://'.__FILE__, $file));
@@ -173,17 +166,96 @@ class RemoteFilesystemTest extends TestCase
unlink($file);
}
+ /**
+ * @expectedException \Composer\Downloader\TransportException
+ */
+ public function testCopyWithNoRetryOnFailure()
+ {
+ $fs = $this->getRemoteFilesystemWithMockedMethods(array('getRemoteContents'));
+
+ $fs->expects($this->once())->method('getRemoteContents')
+ ->willReturnCallback(function ($originUrl, $fileUrl, $ctx, &$http_response_header) {
+
+ $http_response_header = array('http/1.1 401 unauthorized');
+
+ return '';
+
+ });
+
+
+ $file = tempnam(sys_get_temp_dir(), 'z');
+ unlink($file);
+
+ $fs->copy(
+ 'http://example.org',
+ 'file://' . __FILE__,
+ $file,
+ true,
+ array('retry-auth-failure' => false)
+ );
+ }
+
+ public function testCopyWithSuccessOnRetry()
+ {
+ $authHelper = $this->getAuthHelperWithMockedMethods(array('promptAuthIfNeeded'));
+ $fs = $this->getRemoteFilesystemWithMockedMethods(array('getRemoteContents'), $authHelper);
+
+ $authHelper->expects($this->once())
+ ->method('promptAuthIfNeeded')
+ ->willReturn(array(
+ 'storeAuth' => true,
+ 'retry' => true
+ ));
+
+ $fs->expects($this->at(0))
+ ->method('getRemoteContents')
+ ->willReturnCallback(function ($originUrl, $fileUrl, $ctx, &$http_response_header) {
+
+ $http_response_header = array('http/1.1 401 unauthorized');
+
+ return '';
+
+ });
+
+ $fs->expects($this->at(1))
+ ->method('getRemoteContents')
+ ->willReturnCallback(function ($originUrl, $fileUrl, $ctx, &$http_response_header) {
+
+ $http_response_header = array('http/1.1 200 OK');
+
+ return 'copy(
+ 'http://example.org',
+ 'file://' . __FILE__,
+ $file,
+ true,
+ array('retry-auth-failure' => true)
+ );
+
+ $this->assertTrue($copyResult);
+ $this->assertFileExists($file);
+ $this->assertContains('Copied', file_get_contents($file));
+
+ unlink($file);
+ }
+
/**
* @group TLS
*/
public function testGetOptionsForUrlCreatesSecureTlsDefaults()
{
- $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ $io = $this->getIOInterfaceMock();
$res = $this->callGetOptionsForUrl($io, array('example.org', array('ssl' => array('cafile' => '/some/path/file.crt'))), array(), 'http://www.example.org');
$this->assertTrue(isset($res['ssl']['ciphers']));
- $this->assertRegExp("|!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA|", $res['ssl']['ciphers']);
+ $this->assertRegExp('|!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA|', $res['ssl']['ciphers']);
$this->assertTrue($res['ssl']['verify_peer']);
$this->assertTrue($res['ssl']['SNI_enabled']);
$this->assertEquals(7, $res['ssl']['verify_depth']);
@@ -220,6 +292,7 @@ class RemoteFilesystemTest extends TestCase
*/
public function testBitBucketPublicDownload($url, $contents)
{
+ /** @var ConsoleIO $io */
$io = $this
->getMockBuilder('Composer\IO\ConsoleIO')
->disableOriginalConstructor()
@@ -242,6 +315,7 @@ class RemoteFilesystemTest extends TestCase
*/
public function testBitBucketPublicDownloadWithAuthConfigured($url, $contents)
{
+ /** @var MockObject|ConsoleIO $io */
$io = $this
->getMockBuilder('Composer\IO\ConsoleIO')
->disableOriginalConstructor()
@@ -249,13 +323,12 @@ class RemoteFilesystemTest extends TestCase
$domains = array();
$io
- ->expects($this->any())
->method('hasAuthentication')
- ->will($this->returnCallback(function ($arg) use (&$domains) {
+ ->willReturnCallback(function ($arg) use (&$domains) {
$domains[] = $arg;
// first time is called with bitbucket.org, then it redirects to bbuseruploads.s3.amazonaws.com so next time we have no auth configured
return $arg === 'bitbucket.org';
- }));
+ });
$io
->expects($this->at(1))
->method('getAuthentication')
@@ -275,11 +348,11 @@ class RemoteFilesystemTest extends TestCase
$this->assertEquals(array('bitbucket.org', 'bbuseruploads.s3.amazonaws.com'), $domains);
}
- protected function callGetOptionsForUrl($io, array $args = array(), array $options = array(), $fileUrl = '')
+ private function callGetOptionsForUrl($io, array $args = array(), array $options = array(), $fileUrl = '')
{
$fs = new RemoteFilesystem($io, $this->getConfigMock(), $options);
- $ref = new \ReflectionMethod($fs, 'getOptionsForUrl');
- $prop = new \ReflectionProperty($fs, 'fileUrl');
+ $ref = new ReflectionMethod($fs, 'getOptionsForUrl');
+ $prop = new ReflectionProperty($fs, 'fileUrl');
$ref->setAccessible(true);
$prop->setAccessible(true);
@@ -288,17 +361,80 @@ class RemoteFilesystemTest extends TestCase
return $ref->invokeArgs($fs, $args);
}
- protected function callCallbackGet(RemoteFilesystem $fs, $notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
+ /**
+ * @return MockObject|Config
+ */
+ private function getConfigMock()
{
- $ref = new \ReflectionMethod($fs, 'callbackGet');
+ $config = $this->getMockBuilder('Composer\Config')->getMock();
+ $config
+ ->method('get')
+ ->willReturnCallback(function ($key) {
+ if ($key === 'github-domains' || $key === 'gitlab-domains') {
+ return array();
+ }
+
+ return null;
+ });
+
+ return $config;
+ }
+
+ private function callCallbackGet(RemoteFilesystem $fs, $notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
+ {
+ $ref = new ReflectionMethod($fs, 'callbackGet');
$ref->setAccessible(true);
$ref->invoke($fs, $notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax);
}
- protected function setAttribute($object, $attribute, $value)
+ private function setAttribute($object, $attribute, $value)
{
- $attr = new \ReflectionProperty($object, $attribute);
+ $attr = new ReflectionProperty($object, $attribute);
$attr->setAccessible(true);
$attr->setValue($object, $value);
}
+
+ /**
+ * @return MockObject|IOInterface
+ */
+ private function getIOInterfaceMock()
+ {
+ return $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+ }
+
+ /**
+ * @param array $mockedMethods
+ * @param AuthHelper $authHelper
+ *
+ * @return RemoteFilesystem|MockObject
+ */
+ private function getRemoteFilesystemWithMockedMethods(array $mockedMethods, AuthHelper $authHelper = null)
+ {
+ return $this->getMockBuilder('Composer\Util\RemoteFilesystem')
+ ->setConstructorArgs(array(
+ $this->getIOInterfaceMock(),
+ $this->getConfigMock(),
+ array(),
+ false,
+ $authHelper
+ ))
+ ->setMethods($mockedMethods)
+ ->getMock();
+ }
+
+ /**
+ * @param array $mockedMethods
+ *
+ * @return AuthHelper|MockObject
+ */
+ private function getAuthHelperWithMockedMethods(array $mockedMethods)
+ {
+ return $this->getMockBuilder('Composer\Util\AuthHelper')
+ ->setConstructorArgs(array(
+ $this->getIOInterfaceMock(),
+ $this->getConfigMock()
+ ))
+ ->setMethods($mockedMethods)
+ ->getMock();
+ }
}