├── .gitignore
├── tests
├── di.xml
├── Stubs
│ ├── install-config-mysql.stub
│ └── Magento
│ │ └── Framework
│ │ └── ObjectManager
│ │ └── Factory
│ │ └── AbstractFactory.stub
├── Fakes
│ └── CurrentWorkingDirectoryFake.php
├── FileSystem
│ └── TemporaryFileTest.php
├── Service
│ └── FileSystem
│ │ └── CurrentWorkingDirectoryTest.php
├── Validate
│ ├── Validators
│ │ ├── TheConfigFileExistsTest.php
│ │ ├── IsMagentoInstallationTest.php
│ │ ├── PhpUnitFileExistsTest.php
│ │ ├── RabbitMqCredentialsAreValidTest.php
│ │ └── MysqlCredentialsAreValidTest.php
│ └── ValidateSetupTest.php
└── Magento
│ └── ErrorOutputTest.php
├── src
├── Exceptions
│ ├── FailingForUnknownReason.php
│ ├── InstanceFailingException.php
│ └── InvalidConfigurationException.php
├── Stubs
│ ├── MagentoModule
│ │ ├── etc
│ │ │ ├── di.stub
│ │ │ └── module.stub
│ │ ├── registration.stub
│ │ └── Test
│ │ │ └── AlwaysSucceedingTest.stub
│ ├── ReadConfig.stub
│ └── ModuleFixer.stub
├── Validate
│ ├── Validators
│ │ ├── ValidatorContract.php
│ │ ├── TheConfigFileExists.php
│ │ ├── IsMagentoInstallation.php
│ │ ├── PhpUnitFileExists.php
│ │ ├── MysqlCredentialsAreValid.php
│ │ └── AmpqCredentialsAreValid.php
│ └── ValidateSetup.php
├── External
│ ├── Amqp.php
│ └── Mysql.php
├── FileSystem
│ ├── TemporaryFile.php
│ ├── CurrentWorkingDirectory.php
│ ├── Folder.php
│ └── ReadMysqlConfig.php
├── Revive.php
├── Application
│ └── Configure.php
├── functions.php
├── Magento
│ ├── FixModule.php
│ ├── ModuleManager.php
│ ├── ErrorOutput.php
│ ├── IntegrationTests.php
│ └── TestRunner.php
└── Commands
│ └── TestDebug.php
├── .travis.yml
├── phpunit.xml.dist
├── composer.json
├── README.md
├── CreatePhar.php
└── composer.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/tests/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Exceptions/FailingForUnknownReason.php:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Stubs/MagentoModule/registration.stub:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Stubs/ReadConfig.stub:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 | tests
16 |
17 |
18 |
19 |
20 | src/
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/Stubs/install-config-mysql.stub:
--------------------------------------------------------------------------------
1 | 'localhost',
9 | 'db-user' => '{username}',
10 | 'db-password' => '{password}',
11 | 'db-name' => '{database}',
12 | 'db-prefix' => '',
13 | 'backend-frontname' => 'backend',
14 | 'admin-user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
15 | 'admin-password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
16 | 'admin-email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
17 | 'admin-firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
18 | 'admin-lastname' => \Magento\TestFramework\Bootstrap::ADMIN_LASTNAME,
19 | 'amqp-host' => 'localhost',
20 | 'amqp-port' => '5672',
21 | 'amqp-user' => 'guest',
22 | 'amqp-password' => 'guest',
23 | ];
24 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "michielgerritsen/revive",
3 | "description": "Revive your project by adding integration tests to your Magento 2 store",
4 | "require": {
5 | "symfony/console": "^4.3",
6 | "illuminate/container": "^5.8",
7 | "symfony/process": "^4.3",
8 | "mikey179/vfsstream": "^1.6",
9 | "ext-json": "*"
10 | },
11 | "require-dev": {
12 | "phpunit/phpunit": "^7.5"
13 | },
14 | "authors": [
15 | {
16 | "name": "Michiel Gerritsen",
17 | "email": "michiel@controlaltdelete.nl"
18 | }
19 | ],
20 | "autoload": {
21 | "psr-4": {
22 | "MichielGerritsen\\Revive\\": "src"
23 | },
24 | "files": ["src/functions.php"]
25 | },
26 | "autoload-dev": {
27 | "psr-4": {
28 | "MichielGerritsen\\Revive\\Test\\": "tests"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Stubs/MagentoModule/Test/AlwaysSucceedingTest.stub:
--------------------------------------------------------------------------------
1 | assertTrue(true);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Exceptions/InstanceFailingException.php:
--------------------------------------------------------------------------------
1 | files[] = $path;
33 |
34 | return $path;
35 | }
36 |
37 | public function __destruct()
38 | {
39 | foreach ($this->files as $file) {
40 | unlink($file);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Revive.php:
--------------------------------------------------------------------------------
1 | singleton(CurrentWorkingDirectory::class);
27 |
28 | $application = new Application();
29 | (new Configure())->options($application->getDefinition());
30 |
31 | $application->add(container()->make(TestDebug::class));
32 |
33 | $application->run();
34 |
--------------------------------------------------------------------------------
/src/External/Mysql.php:
--------------------------------------------------------------------------------
1 | addOption(
29 | new InputOption(
30 | '--root-dir',
31 | null,
32 | InputOption::VALUE_OPTIONAL,
33 | 'Where to find the Magento installation?'
34 | )
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Exceptions/InvalidConfigurationException.php:
--------------------------------------------------------------------------------
1 | getOption('root-dir')) {
33 | $this->directory = $input->getOption('root-dir');
34 | return;
35 | }
36 |
37 | $this->directory = getcwd();
38 | }
39 |
40 | public function get()
41 | {
42 | return $this->directory;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/Fakes/CurrentWorkingDirectoryFake.php:
--------------------------------------------------------------------------------
1 | stream) {
34 | $this->stream = vfsStream::setup('magentoDirectory');
35 | }
36 |
37 | return $this->stream;
38 | }
39 |
40 | public function get()
41 | {
42 | return $this->stream()->url();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Stubs/ModuleFixer.stub:
--------------------------------------------------------------------------------
1 | getConstructor()->getParameters();
7 |
8 | $xml = simplexml_load_file('{$diPath}');
9 |
10 | $child = $xml->addChild('type');
11 | $child->addAttribute('name', '{$class}');
12 |
13 | $argumentsNode = $child->addChild('arguments');
14 |
15 | function getParameterClassName(ReflectionParameter $param) {
16 | preg_match('/(.*) \$/s', $param->__toString(), $matches);
17 |
18 | return isset($matches[1]) ? trim($matches[1]) : null;
19 | }
20 |
21 | /** @var \ReflectionParameter $param */
22 | foreach($arguments as $param) {
23 | $className = getParameterClassName($param);
24 | if (!$className) {
25 | continue;
26 | }
27 |
28 | $argumentNode = $argumentsNode->addChild('argument', $className . '\Proxy');
29 | $argumentNode->addAttribute('name', $param->name);
30 | $argumentNode->addAttribute('xsi:type', 'object', 'http://www.w3.org/2001/XMLSchema-instance');
31 | }
32 |
33 | $arguments = ['directory' => 'path/to/directory', 'folder' => 'path/to/folder/class'];
34 |
35 | $dom = new \DOMDocument('1.0');
36 | $dom->preserveWhiteSpace = false;
37 | $dom->formatOutput = true;
38 | $dom->loadXML($xml->asXML());
39 |
40 | $dom->save('{$diPath}');
41 |
--------------------------------------------------------------------------------
/tests/FileSystem/TemporaryFileTest.php:
--------------------------------------------------------------------------------
1 | make(TemporaryFile::class);
30 |
31 | $path = $instance->generate();
32 |
33 | $this->assertTrue(file_exists($path));
34 | }
35 |
36 | public function testDeletesFilesOnDestruction()
37 | {
38 | /** @var TemporaryFile $instance */
39 | $instance = container()->make(TemporaryFile::class);
40 |
41 | $path = $instance->generate();
42 |
43 | $instance = null;
44 |
45 | $this->assertFalse(file_exists($path));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Revive
2 |
3 | Got a Magento 2 store where the integration test always fails with some database errors? You can do an attempt to fix them manually by [following this blogpost](https://www.michiel-gerritsen.com/debugging-the-magento-2-integration-test-setup/), or use this tool. This tried to find the root cause of why your tests are failing and apply a fix for them.
4 |
5 | 
6 |
7 | (In this example the error was valid)
8 |
9 | ## What's in the name?
10 |
11 | We've been all in that place: A shiny new project. You can do everything right this time! But as times goes by and deadlines needs to get meet, testing may not be very high on you priority list. When you finally want to start writing tests it turns out that your test setup is broken.
12 |
13 | That's why it's called Revive: It helps you to revive this feeling at the start of the project: You ARE going to do this better this. Heck, you've already got this far that you are trying to run integration tests.
14 |
15 | ## Usage
16 |
17 | You have 2 options to use Revive:
18 |
19 | - Download `revive.phar` from the [release tab](https://github.com/michielgerritsen/revive/releases).
20 | - Clone this repository and run `composer install`. You can then use revive by using `php src/revive.php --root-dir=/path/to/your/magento/installation`.
21 |
22 | ## Testing
23 |
24 | You can run the tests using PHPUnit:
25 |
26 | `vendor/bin/phpunit`
27 |
--------------------------------------------------------------------------------
/CreatePhar.php:
--------------------------------------------------------------------------------
1 | buildFromDirectory('./build');
40 |
41 | // pointing main file which requires all classes
42 | $phar->setDefaultStub('src/Revive.php', 'src/Revive.php');
43 |
44 | // plus - compressing it into gzip
45 | $phar->compress(Phar::GZ);
46 | $phar->compressFiles(Phar::GZ);
47 |
48 | echo $pharFile . ' successfully created' . PHP_EOL;
49 |
50 | if (file_exists($pharFile . '.gz')) {
51 | unlink($pharFile . '.gz');
52 | }
53 |
54 | exec('rm -rf build');
55 |
--------------------------------------------------------------------------------
/tests/Service/FileSystem/CurrentWorkingDirectoryTest.php:
--------------------------------------------------------------------------------
1 | flush();
32 |
33 | /** @var CurrentWorkingDirectory $instance */
34 | $instance = container()->make(CurrentWorkingDirectory::class);
35 |
36 | $input = new StringInput('--root-dir=/test/directory/path');
37 | $definition = new InputDefinition;
38 | container()->make(Configure::class)->options($definition);
39 | $input->bind($definition);
40 |
41 | $instance->setFromInput($input);
42 |
43 | $this->assertEquals('/test/directory/path', $instance->get());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/functions.php:
--------------------------------------------------------------------------------
1 | bind(ValidateSetup::class, function () {
35 | return new ValidateSetup(
36 | container()->make(CurrentWorkingDirectory::class),
37 | [
38 | container()->make(\MichielGerritsen\Revive\Validate\Validators\IsMagentoInstallation::class),
39 | container()->make(\MichielGerritsen\Revive\Validate\Validators\TheConfigFileExists::class),
40 | container()->make(\MichielGerritsen\Revive\Validate\Validators\PhpUnitFileExists::class),
41 | container()->make(\MichielGerritsen\Revive\Validate\Validators\MysqlCredentialsAreValid::class),
42 | container()->make(\MichielGerritsen\Revive\Validate\Validators\AmpqCredentialsAreValid::class),
43 | ]
44 | );
45 | });
46 |
--------------------------------------------------------------------------------
/src/Validate/Validators/TheConfigFileExists.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
34 | }
35 |
36 | public function shouldContinue(): bool
37 | {
38 | return false;
39 | }
40 |
41 | public function validate(): bool
42 | {
43 | return file_exists($this->directory->get() . '/dev/tests/integration/etc/install-config-mysql.php');
44 | }
45 |
46 | public function getErrors(): array
47 | {
48 | return [
49 | 'The `dev/tests/integration/etc/install-config-mysql.php` file is missing. See this page on how to prepare to run the ' .
50 | 'integration tests: https://devdocs.magento.com/guides/v2.3/test/integration/integration_test_execution.html'
51 | ];
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/FileSystem/Folder.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
32 | }
33 |
34 | /**
35 | * @param string $directory
36 | */
37 | public function emptyFolder($directory)
38 | {
39 | foreach (glob($directory . '/*') as $directory) {
40 | $this->deleteFolder($directory);
41 | }
42 | }
43 |
44 | /**
45 | * @param string $directory
46 | */
47 | public function deleteFolder($directory)
48 | {
49 | $it = new \RecursiveDirectoryIterator($directory, \RecursiveDirectoryIterator::SKIP_DOTS);
50 | $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
51 | foreach ($files as $file) {
52 | if ($file->isDir()) {
53 | rmdir($file->getRealPath());
54 | } else {
55 | unlink($file->getRealPath());
56 | }
57 | }
58 |
59 | rmdir($directory);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Validate/Validators/IsMagentoInstallation.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
41 | }
42 |
43 | public function validate(): bool
44 | {
45 | foreach (static::REQUIRED_FILES as $file) {
46 | if (!file_exists($this->directory->get() . '/' . $file)) {
47 | return false;
48 | }
49 | }
50 |
51 | return true;
52 | }
53 |
54 | public function shouldContinue(): bool
55 | {
56 | return false;
57 | }
58 |
59 | public function getErrors(): array
60 | {
61 | return [
62 | 'The current directory (' . $this->directory->get() . ') is not a Magento directory',
63 | ];
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Validate/Validators/PhpUnitFileExists.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
34 | }
35 |
36 | public function shouldContinue(): bool
37 | {
38 | return true;
39 | }
40 |
41 | public function validate(): bool
42 | {
43 | $paths = [
44 | 'dev/tests/integration/phpunit.xml',
45 | 'dev/tests/quick-integration/phpunit.xml',
46 | ];
47 |
48 | foreach ($paths as $path) {
49 | if (file_exists($this->directory->get() . '/' . $path)) {
50 | return true;
51 | }
52 | }
53 |
54 | return false;
55 | }
56 |
57 | public function getErrors(): array
58 | {
59 | return [
60 | 'The `dev/tests/integration/phpunit.xml` file is missing. See this page on how to prepare to run the ' .
61 | 'integration tests: https://devdocs.magento.com/guides/v2.3/test/integration/integration_test_execution.html'
62 | ];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Validate/Validators/MysqlCredentialsAreValid.php:
--------------------------------------------------------------------------------
1 | config = $config;
41 | $this->mysql = $mysql;
42 | }
43 |
44 | public function validate(): bool
45 | {
46 | $config = $this->config->read();
47 |
48 | if (empty($config['db-host']) || empty($config['db-name'])) {
49 | return false;
50 | }
51 |
52 | return $this->mysql->testConnection(
53 | $config['db-host'],
54 | $config['db-port'],
55 | $config['db-name'],
56 | $config['db-user'],
57 | $config['db-password']
58 | );
59 | }
60 |
61 | public function shouldContinue(): bool
62 | {
63 | return true;
64 | }
65 |
66 | public function getErrors(): array
67 | {
68 | return [
69 | 'Please check your mysql settings in `dev/tests/integration/etc/install-config-mysql.php` ' .
70 | 'as these are invalid',
71 | ];
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Validate/ValidateSetup.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
48 | $this->validators = $validators;
49 | }
50 |
51 | public function validate()
52 | {
53 | $result = true;
54 |
55 | foreach ($this->validators as $validator) {
56 | if (!$validator->validate()) {
57 | $this->addErrors($validator->getErrors());
58 | $result = false;
59 |
60 | if (!$validator->shouldContinue()) {
61 | break;
62 | }
63 | }
64 | }
65 |
66 | return $result;
67 | }
68 |
69 | public function getErrors()
70 | {
71 | return $this->errors;
72 | }
73 |
74 | private function addErrors(array $errors)
75 | {
76 | $this->errors = array_merge($this->errors, $errors);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/Validate/Validators/TheConfigFileExistsTest.php:
--------------------------------------------------------------------------------
1 | singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
31 |
32 | $directory = container()->make(CurrentWorkingDirectory::class)->get();
33 |
34 | mkdir($directory . '/dev/tests/integration/etc', 0777, true);
35 | touch($directory . '/dev/tests/integration/etc/install-config-mysql.php');
36 |
37 | /** @var TheConfigFileExists $instance */
38 | $instance = container()->make(TheConfigFileExists::class);
39 |
40 | $this->assertTrue($instance->validate());
41 | }
42 |
43 | public function testGetErrors()
44 | {
45 | /** @var TheConfigFileExists $instance */
46 | $instance = container()->make(TheConfigFileExists::class);
47 |
48 | $errors = $instance->getErrors();
49 |
50 | $this->assertContains(
51 | 'The `dev/tests/integration/etc/install-config-mysql.php` file is missing.',
52 | $errors[0]
53 | );
54 | }
55 |
56 | public function testShouldContinue()
57 | {
58 | $this->assertFalse(container()->make(TheConfigFileExists::class)->shouldContinue());
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Magento/FixModule.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
35 | }
36 |
37 | public function proxyDependenciesFor($class)
38 | {
39 | $replacements = [
40 | '{$autoloadPath}' => $this->directory->get() . '/vendor/autoload.php',
41 | '{$diPath}' => $this->directory->get() . '/app/code/MichielGerritsen/ReviveFixes/etc/di.xml',
42 | '{$class}' => $class,
43 | ];
44 |
45 | $moduleFixerContent = str_replace(
46 | array_keys($replacements),
47 | array_values($replacements),
48 | file_get_contents(__DIR__ . '/../Stubs/ModuleFixer.stub')
49 | );
50 |
51 | $path = tempnam(sys_get_temp_dir(), 'revive');
52 |
53 | file_put_contents($path, $moduleFixerContent);
54 | file_put_contents($this->directory->get() . '/debugger.php', $moduleFixerContent);
55 |
56 | $process = new Process([PHP_BINARY, $path]);
57 |
58 | $process->run(function ($type, $buffer) {
59 | if (Process::ERR === $type) {
60 | echo 'ERR > ' . $buffer;
61 | } else {
62 | echo 'OUT > ' . $buffer;
63 | }
64 | });
65 |
66 | unlink($path);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Validate/Validators/AmpqCredentialsAreValid.php:
--------------------------------------------------------------------------------
1 | config = $config;
41 | $this->amqp = $amqp;
42 | }
43 |
44 | public function validate(): bool
45 | {
46 | $config = $this->config->read();
47 |
48 | if (empty($config['amqp-host']) ||
49 | empty($config['amqp-port']) ||
50 | empty($config['amqp-user']) ||
51 | empty($config['amqp-password'])
52 | ) {
53 | return true;
54 | }
55 |
56 | return $this->amqp->testConnection(
57 | $config['amqp-host'],
58 | $config['amqp-port'],
59 | $config['amqp-user'],
60 | $config['amqp-password']
61 | );
62 | }
63 |
64 | public function shouldContinue(): bool
65 | {
66 | return true;
67 | }
68 |
69 | public function getErrors(): array
70 | {
71 | return [
72 | 'You have AMPQ variables in your `dev/tests/integration/etc/install-config-mysql.php` file, but these ' .
73 | 'are invalid. If you don\'t plan on using AMPQ just remove them.'
74 | ];
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Magento/ModuleManager.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
34 | }
35 |
36 | public function getPath()
37 | {
38 | return $this->directory->get() . '/app/code/MichielGerritsen/ReviveFixes/';
39 | }
40 |
41 | public function createIntegrationTestModule()
42 | {
43 | // TODO: Check if the module exists.
44 |
45 | $modulePath = $this->getPath();
46 |
47 | if (file_exists($modulePath)) {
48 | return;
49 | }
50 |
51 | mkdir($modulePath . 'etc/', 0777, true);
52 | mkdir($modulePath . 'Test/', 0777, true);
53 |
54 | $stubPath = __DIR__ . '/../Stubs/MagentoModule/';
55 | $diXml = file_get_contents($stubPath . 'etc/di.stub');
56 | $moduleXml = file_get_contents($stubPath . 'etc/module.stub');
57 | $registrationPhp = file_get_contents($stubPath . 'registration.stub');
58 | $testPhp = file_get_contents($stubPath . '/Test/AlwaysSucceedingTest.stub');
59 |
60 | file_put_contents($modulePath . 'etc/di.xml', $diXml);
61 | file_put_contents($modulePath . 'etc/module.xml', $moduleXml);
62 | file_put_contents($modulePath . 'registration.php', $registrationPhp);
63 | file_put_contents($modulePath . 'Test/AlwaysSucceedingTest.php', $testPhp);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/Validate/Validators/IsMagentoInstallationTest.php:
--------------------------------------------------------------------------------
1 | assertFalse(container()->make(IsMagentoInstallation::class)->shouldContinue());
31 | }
32 |
33 | public function testGetErrors()
34 | {
35 | $this->assertCount(1, container()->make(IsMagentoInstallation::class)->getErrors());
36 | }
37 |
38 | /**
39 | * @testWith [0]
40 | * [1]
41 | * [2]
42 | * [3]
43 | */
44 | public function testTheConfigFileShouldExists($unexisting)
45 | {
46 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
47 |
48 | $directory = container()->make(CurrentWorkingDirectory::class);
49 |
50 | $files = IsMagentoInstallation::REQUIRED_FILES;
51 | unset($files[$unexisting]);
52 |
53 | foreach ($files as $file) {
54 | $path = $directory->get() . '/' . $file;
55 | mkdir(dirname($path), 0755, true);
56 | touch($path);
57 | }
58 |
59 | $this->assertFalse(container()->make(IsMagentoInstallation::class)->validate());
60 | }
61 |
62 | public function testValidatesIfAllFilesExists()
63 | {
64 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
65 |
66 | $directory = container()->make(CurrentWorkingDirectory::class);
67 |
68 | foreach (IsMagentoInstallation::REQUIRED_FILES as $file) {
69 | $path = $directory->get() . '/' . $file;
70 | mkdir(dirname($path), 0755, true);
71 | touch($path);
72 | }
73 |
74 | $this->assertTrue(container()->make(IsMagentoInstallation::class)->validate());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/tests/Validate/Validators/PhpUnitFileExistsTest.php:
--------------------------------------------------------------------------------
1 | singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
31 | $directory = container()->make(CurrentWorkingDirectory::class)->get();
32 |
33 | mkdir($directory . '/dev/tests/integration', 0777, true);
34 | touch($directory . '/dev/tests/integration/phpunit.xml');
35 |
36 | /** @var PhpUnitFileExists $instance */
37 | $instance = container()->make(PhpUnitFileExists::class);
38 |
39 | $this->assertTrue($instance->validate());
40 | }
41 |
42 | public function testSupportsTheQuickIntegration()
43 | {
44 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
45 | $directory = container()->make(CurrentWorkingDirectory::class)->get();
46 |
47 | mkdir($directory . '/dev/tests/quick-integration', 0777, true);
48 | touch($directory . '/dev/tests/quick-integration/phpunit.xml');
49 |
50 | /** @var PhpUnitFileExists $instance */
51 | $instance = container()->make(PhpUnitFileExists::class);
52 |
53 | $this->assertTrue($instance->validate());
54 | }
55 |
56 | public function testGetErrors()
57 | {
58 | /** @var PhpUnitFileExists $instance */
59 | $instance = container()->make(PhpUnitFileExists::class);
60 |
61 | $errors = $instance->getErrors();
62 |
63 | $this->assertContains(
64 | 'The `dev/tests/integration/phpunit.xml` file is missing.',
65 | $errors[0]
66 | );
67 | }
68 |
69 | public function testShouldContinue()
70 | {
71 | $this->assertTrue(container()->make(PhpUnitFileExists::class)->shouldContinue());
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/FileSystem/ReadMysqlConfig.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
61 | $this->temporaryFile = $temporaryFile;
62 | }
63 |
64 | /**
65 | * @param string $contents
66 | * @return array
67 | * @throws \Exception
68 | */
69 | public function read()
70 | {
71 | if ($this->contents) {
72 | return $this->contents;
73 | }
74 |
75 | $path = $this->temporaryFile->generate();
76 |
77 | file_put_contents(
78 | $path,
79 | file_get_contents(__DIR__ . '/../Stubs/ReadConfig.stub')
80 | );
81 |
82 | $process = new Process(
83 | [PHP_BINARY, $path],
84 | $this->directory->get()
85 | );
86 |
87 | $process->run();
88 |
89 | $output = $process->getOutput();
90 | $contents = $this->fillBlanks(json_decode($output, JSON_OBJECT_AS_ARRAY));
91 |
92 | if ($process->getExitCode()) {
93 | throw new \Exception('Unable to get mysql credentials: ' . PHP_EOL . $process->getOutput());
94 | }
95 |
96 | $this->contents = $contents;
97 | return $contents;
98 | }
99 |
100 | private function fillBlanks($contents)
101 | {
102 | foreach (static::REQUIRED_KEYS as $key) {
103 | if (!array_key_exists($key, $contents)) {
104 | $contents[$key] = '';
105 | }
106 | }
107 |
108 | return $contents;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/tests/Validate/Validators/RabbitMqCredentialsAreValidTest.php:
--------------------------------------------------------------------------------
1 | createMock(ReadMysqlConfig::class);
33 | $readMysqlConfigMock->method('read')->willReturn([]);
34 |
35 | /** @var AmpqCredentialsAreValid $instance */
36 | $instance = container()->make(AmpqCredentialsAreValid::class, [
37 | 'config' => $readMysqlConfigMock,
38 | ]);
39 |
40 | $this->assertTrue($instance->validate());
41 | }
42 |
43 | /**
44 | * @param $connectionSuccess
45 | * @param $expected
46 | * @throws \Illuminate\Contracts\Container\BindingResolutionException
47 | *
48 | * @testWith [true, true]
49 | * [false, false]
50 | */
51 | public function testReturnsTheCorrectStatusDependingOnTheConnectionResult($connectionSuccess, $expected)
52 | {
53 | $readMysqlConfigMock = $this->createMock(ReadMysqlConfig::class);
54 | $readMysqlConfigMock->method('read')->willReturn([
55 | 'amqp-host' => 'localhost',
56 | 'amqp-port' => '15672',
57 | 'amqp-user' => 'guest',
58 | 'amqp-password' => 'guest',
59 | ]);
60 |
61 | $amqpMock = $this->createMock(Amqp::class);
62 | $amqpMock->expects($this->once())->method('testConnection')->willReturn($connectionSuccess);
63 |
64 | /** @var AmpqCredentialsAreValid $instance */
65 | $instance = container()->make(AmpqCredentialsAreValid::class, [
66 | 'config' => $readMysqlConfigMock,
67 | 'amqp' => $amqpMock,
68 | ]);
69 |
70 | $this->assertSame($expected, $instance->validate());
71 | }
72 |
73 | public function testGetErrors()
74 | {
75 | $this->assertCount(1, container()->make(AmpqCredentialsAreValid::class)->getErrors());
76 | }
77 |
78 | public function testShouldContinue()
79 | {
80 | $this->assertTrue(container()->make(AmpqCredentialsAreValid::class)->shouldContinue());
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/Validate/Validators/MysqlCredentialsAreValidTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(container()->make(MysqlCredentialsAreValid::class)->shouldContinue());
33 | }
34 |
35 | public function testGetErrors()
36 | {
37 | $this->assertNotEmpty(container()->make(MysqlCredentialsAreValid::class)->getErrors()[0]);
38 | }
39 |
40 | public function testFailsIfThereIsNoConnectionData()
41 | {
42 | $readMysqlConfigMock = $this->createMock(ReadMysqlConfig::class);
43 | $readMysqlConfigMock->method('read')->willReturn([
44 | 'db-host' => '',
45 | 'db-port' => '',
46 | 'db-name' => '',
47 | 'db-user' => '',
48 | 'db-password' => '',
49 | ]);
50 |
51 | /** @var MysqlCredentialsAreValid $instance */
52 | $instance = container()->make(MysqlCredentialsAreValid::class, [
53 | 'config' => $readMysqlConfigMock,
54 | ]);
55 |
56 | $this->assertFalse($instance->validate());
57 | }
58 |
59 | /**
60 | * @param $connectionResult
61 | * @param $expected
62 | * @throws \Illuminate\Contracts\Container\BindingResolutionException
63 | *
64 | * @testWith [false, false]
65 | * [true, true]
66 | */
67 | public function testValidatesDependingOnTheStatus($connectionResult, $expected)
68 | {
69 | $mysqlMock = $this->createMock(Mysql::class);
70 | $mysqlMock->expects($this->once())->method('testConnection')->willReturn($connectionResult);
71 |
72 | $readMysqlConfigMock = $this->createMock(ReadMysqlConfig::class);
73 | $readMysqlConfigMock->method('read')->willReturn([
74 | 'db-host' => 'localhost',
75 | 'db-port' => '',
76 | 'db-name' => 'database',
77 | 'db-user' => '',
78 | 'db-password' => '',
79 | ]);
80 |
81 | /** @var MysqlCredentialsAreValid $instance */
82 | $instance = container()->make(MysqlCredentialsAreValid::class, [
83 | 'mysql' => $mysqlMock,
84 | 'config' => $readMysqlConfigMock,
85 | ]);
86 |
87 | $this->assertSame($expected, $instance->validate());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Magento/ErrorOutput.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
44 | }
45 |
46 | public function patch()
47 | {
48 | foreach ($this->paths as $path) {
49 | $this->patchFile($this->directory->get() . '/' . $path);
50 | }
51 | }
52 |
53 | private function patchFile($path)
54 | {
55 | if (!file_exists($path)) {
56 | return;
57 | }
58 |
59 | $contents = $this->originalContents = file_get_contents($path);
60 |
61 | if (strpos($contents, 'json_encode([\'instance\' => $item[\'instance\']])') !== false) {
62 | return;
63 | }
64 |
65 | $result = str_replace(
66 | '$array[$key] = $this->objectManager->get($item[\'instance\']);',
67 | 'try {
68 | $array[$key] = $this->objectManager->get($item[\'instance\']);
69 | } catch (\Exception $exception) {
70 | file_put_contents(
71 | getenv(\'DEBUG_TMPFILE\'),
72 | json_encode([\'instance\' => $item[\'instance\']])
73 | );
74 |
75 | throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));
76 | }',
77 | $contents
78 | );
79 |
80 | file_put_contents($path, $result);
81 | }
82 |
83 | public function undo()
84 | {
85 | if (!$this->originalContents) {
86 | return;
87 | }
88 |
89 | foreach ($this->paths as $path) {
90 | $fullPath = $this->directory->get() . '/' . $path;
91 |
92 | if (file_exists($fullPath)) {
93 | file_put_contents($fullPath, $this->originalContents);
94 | }
95 | }
96 | }
97 |
98 | public function __destruct()
99 | {
100 | $this->undo();
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Magento/IntegrationTests.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
65 | $this->temporaryFile = $temporaryFile;
66 | $this->folder = $folder;
67 | $this->moduleManager = $moduleManager;
68 | }
69 |
70 | private function createProcess()
71 | {
72 | $this->path = $this->temporaryFile->generate();
73 |
74 | $this->folder->emptyFolder($this->directory->get() . '/dev/tests/integration/tmp/');
75 |
76 | $this->process = new Process(
77 | [
78 | '../../../vendor/bin/phpunit',
79 | $this->moduleManager->getPath() . '/Test/',
80 | ],
81 | $this->directory->get() . '/dev/tests/integration/',
82 | ['DEBUG_TMPFILE' => $this->path],
83 | null,
84 | null
85 | );
86 |
87 | return $this->process;
88 | }
89 |
90 | public function run()
91 | {
92 | return $this->createProcess()->run();
93 | }
94 |
95 | public function runVerbose(OutputInterface $output)
96 | {
97 | $this->createProcess()->run(function ($type, $buffer) use ($output) {
98 | if (Process::ERR === $type) {
99 | $output->writeln('' . $buffer . '');
100 | } else {
101 | $output->writeln($buffer);
102 | }
103 | });
104 | }
105 |
106 | public function wasRunSuccessful()
107 | {
108 | return !$this->process->getExitCode();
109 | }
110 |
111 | public function getFailingInstance()
112 | {
113 | $json = json_decode(file_get_contents($this->path), JSON_OBJECT_AS_ARRAY);
114 |
115 | return $json['instance'];
116 | }
117 |
118 | public function getLogs()
119 | {
120 | return $this->process->getOutput();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/Magento/TestRunner.php:
--------------------------------------------------------------------------------
1 | integrationTests = $integrationTests;
42 | $this->fixModule = $fixModule;
43 | }
44 |
45 | public function execute(OutputInterface $output)
46 | {
47 | $run = 1;
48 | $failingInstance = null;
49 | $patchedInstances = [];
50 | while (true) {
51 | $start = microtime(true);
52 | $output->writeln('');
53 | $output->writeln('Starting run #' . $run);
54 |
55 | if (!$output->isVeryVerbose()) {
56 | $this->integrationTests->run();
57 | } else {
58 | $this->integrationTests->runVerbose($output);
59 | }
60 |
61 | if ($this->integrationTests->wasRunSuccessful()) {
62 | break;
63 | }
64 |
65 | $currentFailingInstance = $this->integrationTests->getFailingInstance();
66 |
67 | if ($currentFailingInstance && $currentFailingInstance == $failingInstance) {
68 | $output->writeln($this->integrationTests->getLogs());
69 |
70 | throw InstanceFailingException::withInstance($failingInstance);
71 | }
72 |
73 | $patchedInstances[] = $currentFailingInstance;
74 | if (!$currentFailingInstance) {
75 | $output->writeln($this->integrationTests->getLogs());
76 |
77 | throw new FailingForUnknownReason(
78 | 'It looks like there are no instances that are failing (anymore), but the test command still ' .
79 | 'fails for unknown reasons. Usually this is caused by setup scripts that are failing'
80 | );
81 | }
82 |
83 | $this->fixModule->proxyDependenciesFor($currentFailingInstance);
84 | $output->writeln('The class ' . $currentFailingInstance . ' is patched.');
85 |
86 | $end = microtime(true);
87 | $execution_time = round(($end - $start) / 60, 2);
88 |
89 | $output->writeln('Completed run ' . $run . ' in ' . $execution_time . ' minutes');
90 | $run++;
91 |
92 | if ($run == 50) {
93 | $output->writeln($this->integrationTests->getLogs());
94 |
95 | $output->writeln(
96 | 'We tried to run the tests 50 times but without success. Please check the logs ' .
97 | 'to see what is going on. If they look good just try again.'
98 | );
99 | break;
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/tests/Validate/ValidateSetupTest.php:
--------------------------------------------------------------------------------
1 | createMock(ValidatorContract::class);
30 | $validator1->method('validate')->willReturn(true);
31 |
32 | $validator2 = $this->createMock(ValidatorContract::class);
33 | $validator2->method('validate')->willReturn(false);
34 |
35 | $validator3 = $this->createMock(ValidatorContract::class);
36 | $validator3->method('validate')->willReturn(true);
37 |
38 | container()->flush();
39 | $instance = container()->make(ValidateSetup::class, [
40 | 'validators' => [
41 | $validator1,
42 | $validator2,
43 | $validator3,
44 | ]
45 | ]);
46 |
47 | $this->assertFalse($instance->validate());
48 | }
49 |
50 | public function testSucceedsIfAllValidatorAreValid()
51 | {
52 | $validator = $this->createMock(ValidatorContract::class);
53 | $validator->method('validate')->willReturn(true);
54 |
55 | container()->flush();
56 | $instance = container()->make(ValidateSetup::class, [
57 | 'validators' => [$validator]
58 | ]);
59 |
60 | $this->assertTrue($instance->validate());
61 | }
62 |
63 | public function testCollectsErrors()
64 | {
65 | $validator1 = $this->createMock(ValidatorContract::class);
66 | $validator1->method('validate')->willReturn(false);
67 | $validator1->method('getErrors')->willReturn(['error 1']);
68 | $validator1->method('shouldContinue')->willReturn(true);
69 |
70 | $validator2 = $this->createMock(ValidatorContract::class);
71 | $validator2->method('validate')->willReturn(false);
72 | $validator2->method('getErrors')->willReturn(['error 2']);
73 | $validator2->method('shouldContinue')->willReturn(true);
74 |
75 | container()->flush();
76 | $instance = container()->make(ValidateSetup::class, [
77 | 'validators' => [$validator1, $validator2]
78 | ]);
79 |
80 | $instance->validate();
81 |
82 | $this->assertCount(2, $instance->getErrors());
83 | $this->assertTrue(in_array('error 1', $instance->getErrors()));
84 | $this->assertTrue(in_array('error 2', $instance->getErrors()));
85 | }
86 |
87 | public function testSkipTheRestOfTheValidatorsIfNeeded()
88 | {
89 | $validator1 = $this->createMock(ValidatorContract::class);
90 | $validator1->expects($this->once())->method('validate')->willReturn(false);
91 | $validator1->method('shouldContinue')->willReturn(false);
92 |
93 | $validator2 = $this->createMock(ValidatorContract::class);
94 | $validator2->expects($this->never())->method('validate');
95 |
96 | container()->flush();
97 | $instance = container()->make(ValidateSetup::class, [
98 | 'validators' => [$validator1, $validator2]
99 | ]);
100 |
101 | $instance->validate();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Commands/TestDebug.php:
--------------------------------------------------------------------------------
1 | directory = $directory;
71 | $this->moduleManager = $moduleManager;
72 | $this->errorOutput = $errorOutput;
73 | $this->validateSetup = $validateSetup;
74 | $this->testRunner = $testRunner;
75 | }
76 |
77 | protected function execute(InputInterface $input, OutputInterface $output)
78 | {
79 | $this->directory->setFromInput($input);
80 |
81 | $io = new SymfonyStyle($input, $output);
82 |
83 | // Validate installation.
84 | if (!$this->validateSetup->validate()) {
85 | $width = (new Terminal())->getWidth();
86 |
87 | $message = 'There are some errors found, please fix these before continuing:';
88 |
89 | $output->writeln('');
90 | $output->writeln('' . str_repeat(' ', $width) . '');
91 | $output->writeln(' ' . $message . str_repeat(' ', $width - strlen($message) - 2) . '');
92 | $output->writeln('' . str_repeat(' ', $width) . '');
93 | $io->listing($this->validateSetup->getErrors($output));
94 | return 255;
95 | }
96 |
97 | // Place our code to read the exceptions.
98 | $output->writeln('Patching your Magento installation');
99 | $this->errorOutput->patch();
100 |
101 | // Create the module
102 | $this->moduleManager->createIntegrationTestModule();
103 |
104 | // Run the installation.
105 | $output->writeln('You installation is verified. We are now starting the first run. This can take quite a while.');
106 |
107 | try {
108 | $this->testRunner->execute($output);
109 | } finally {
110 | // Undo our manual fixes.
111 | $this->errorOutput->undo();
112 | }
113 |
114 | $io->success(
115 | 'It looks like we succefully did a test run. We placed some fixes in the ' .
116 | '`app/code/MichielGerritsen/ReviveFixes` folder. Please review them and adjust where needed.'
117 | );
118 | $io->success('Now go and build something awesome!');
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/tests/Magento/ErrorOutputTest.php:
--------------------------------------------------------------------------------
1 | make(CurrentWorkingDirectory::class);
35 |
36 | $filePath = $directory->get() . '/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php';
37 | $stub = file_get_contents(__DIR__ . '/../Stubs/Magento/Framework/ObjectManager/Factory/AbstractFactory.stub');
38 |
39 | mkdir($directory->get() . '/vendor/magento/framework/ObjectManager/Factory/', 0777, true);
40 | file_put_contents($filePath, $stub);
41 |
42 | return $filePath;
43 | }
44 |
45 | public function testThatOurCodeIsPlaced()
46 | {
47 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
48 |
49 | $filePath = $this->prepareStubs();
50 |
51 | /** @var ErrorOutput $instance */
52 | $instance = container()->make(ErrorOutput::class);
53 | $instance->patch();
54 |
55 | $this->assertContains(
56 | 'throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));',
57 | file_get_contents($filePath)
58 | );
59 | }
60 |
61 | public function testThePatchIsUndone()
62 | {
63 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
64 |
65 | $filePath = $this->prepareStubs();
66 |
67 | /** @var ErrorOutput $instance */
68 | $instance = container()->make(ErrorOutput::class);
69 | $instance->patch();
70 |
71 | $this->assertContains(
72 | 'throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));',
73 | file_get_contents($filePath)
74 | );
75 |
76 | $instance->undo();
77 |
78 | $this->assertNotContains(
79 | 'throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));',
80 | file_get_contents($filePath)
81 | );
82 | }
83 |
84 | public function testRestoresFilesOnDestruction()
85 | {
86 | container()->singleton(CurrentWorkingDirectory::class, CurrentWorkingDirectoryFake::class);
87 |
88 | $filePath = $this->prepareStubs();
89 |
90 | /** @var ErrorOutput $instance */
91 | $instance = container()->make(ErrorOutput::class);
92 | $instance->patch();
93 |
94 | $this->assertContains(
95 | 'throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));',
96 | file_get_contents($filePath)
97 | );
98 |
99 | $instance = null;
100 |
101 | $this->assertNotContains(
102 | 'throw new \Exception(\'Failing command: \' . $key . \' instance: \' . $item[\'instance\'] . \' JSON: \' . json_encode([\'instance\' => $item[\'instance\']]));',
103 | file_get_contents($filePath)
104 | );
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/tests/Stubs/Magento/Framework/ObjectManager/Factory/AbstractFactory.stub:
--------------------------------------------------------------------------------
1 | config = $config;
60 | $this->objectManager = $objectManager;
61 | $this->definitions = $definitions ?: $this->getDefinitions();
62 | $this->globalArguments = $globalArguments;
63 | }
64 |
65 | /**
66 | * Set object manager
67 | *
68 | * @param ObjectManagerInterface $objectManager
69 | *
70 | * @return void
71 | */
72 | public function setObjectManager(ObjectManagerInterface $objectManager)
73 | {
74 | $this->objectManager = $objectManager;
75 | }
76 |
77 | /**
78 | * Set global arguments
79 | *
80 | * @param array $arguments
81 | *
82 | * @return void
83 | */
84 | public function setArguments($arguments)
85 | {
86 | $this->globalArguments = $arguments;
87 | }
88 |
89 | /**
90 | * @return \Magento\Framework\ObjectManager\DefinitionInterface
91 | */
92 | public function getDefinitions()
93 | {
94 | if ($this->definitions === null) {
95 | $this->definitions = new \Magento\Framework\ObjectManager\Definition\Runtime();
96 | }
97 | return $this->definitions;
98 | }
99 |
100 | /**
101 | * Create object
102 | *
103 | * @param string $type
104 | * @param array $args
105 | *
106 | * @return object
107 | *
108 | */
109 | protected function createObject($type, $args)
110 | {
111 | return new $type(...array_values($args));
112 | }
113 |
114 | /**
115 | * Resolve an argument
116 | *
117 | * @param array &$argument
118 | * @param string $paramType
119 | * @param mixed $paramDefault
120 | * @param string $paramName
121 | * @param string $requestedType
122 | *
123 | * @return void
124 | *
125 | * @SuppressWarnings(PHPMD.CyclomaticComplexity)
126 | */
127 | protected function resolveArgument(&$argument, $paramType, $paramDefault, $paramName, $requestedType)
128 | {
129 | if ($paramType && $argument !== $paramDefault && !is_object($argument)) {
130 | $argumentType = $argument['instance'];
131 | if (!isset($argument['instance']) || $argument !== (array)$argument) {
132 | throw new \UnexpectedValueException(
133 | 'Invalid parameter configuration provided for $' . $paramName . ' argument of ' . $requestedType
134 | );
135 | }
136 |
137 | if (isset($argument['shared'])) {
138 | $isShared = $argument['shared'];
139 | } else {
140 | $isShared = $this->config->isShared($argumentType);
141 | }
142 |
143 | if ($isShared) {
144 | $argument = $this->objectManager->get($argumentType);
145 | } else {
146 | $argument = $this->objectManager->create($argumentType);
147 | }
148 | } elseif ($argument === (array)$argument) {
149 | if (isset($argument['argument'])) {
150 | if (isset($this->globalArguments[$argument['argument']])) {
151 | $argument = $this->globalArguments[$argument['argument']];
152 | } else {
153 | $argument = $paramDefault;
154 | }
155 | } elseif (!empty($argument)) {
156 | $this->parseArray($argument);
157 | }
158 | }
159 | }
160 |
161 | /**
162 | * Parse array argument
163 | *
164 | * @param array $array
165 | *
166 | * @return void
167 | */
168 | protected function parseArray(&$array)
169 | {
170 | foreach ($array as $key => $item) {
171 | if ($item === (array)$item) {
172 | if (isset($item['instance'])) {
173 | if (isset($item['shared'])) {
174 | $isShared = $item['shared'];
175 | } else {
176 | $isShared = $this->config->isShared($item['instance']);
177 | }
178 |
179 | if ($isShared) {
180 | $array[$key] = $this->objectManager->get($item['instance']);
181 | } else {
182 | $array[$key] = $this->objectManager->create($item['instance']);
183 | }
184 | } elseif (isset($item['argument'])) {
185 | if (isset($this->globalArguments[$item['argument']])) {
186 | $array[$key] = $this->globalArguments[$item['argument']];
187 | } else {
188 | $array[$key] = null;
189 | }
190 | } else {
191 | $this->parseArray($array[$key]);
192 | }
193 | }
194 | }
195 | }
196 |
197 | /**
198 | * Resolve constructor arguments
199 | *
200 | * @param string $requestedType
201 | * @param array $parameters
202 | * @param array $arguments
203 | *
204 | * @return array
205 | *
206 | * @throws \UnexpectedValueException
207 | * @throws \BadMethodCallException
208 | */
209 | protected function resolveArgumentsInRuntime($requestedType, array $parameters, array $arguments = [])
210 | {
211 | $resolvedArguments = [];
212 | foreach ($parameters as $parameter) {
213 | list($paramName, $paramType, $paramRequired, $paramDefault) = $parameter;
214 | $argument = null;
215 | if (!empty($arguments) && (isset($arguments[$paramName]) || array_key_exists($paramName, $arguments))) {
216 | $argument = $arguments[$paramName];
217 | } elseif ($paramRequired) {
218 | if ($paramType) {
219 | $argument = ['instance' => $paramType];
220 | } else {
221 | $this->creationStack = [];
222 | throw new \BadMethodCallException(
223 | 'Missing required argument $' . $paramName . ' of ' . $requestedType . '.'
224 | );
225 | }
226 | } else {
227 | $argument = $paramDefault;
228 | }
229 |
230 | $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType);
231 |
232 | $resolvedArguments[] = $argument;
233 | }
234 | return $resolvedArguments;
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "f9240ff4fac9a6798cac361425f2f938",
8 | "packages": [
9 | {
10 | "name": "doctrine/inflector",
11 | "version": "v1.3.0",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/doctrine/inflector.git",
15 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a",
20 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": "^7.1"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": "^6.2"
28 | },
29 | "type": "library",
30 | "extra": {
31 | "branch-alias": {
32 | "dev-master": "1.3.x-dev"
33 | }
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
38 | }
39 | },
40 | "notification-url": "https://packagist.org/downloads/",
41 | "license": [
42 | "MIT"
43 | ],
44 | "authors": [
45 | {
46 | "name": "Roman Borschel",
47 | "email": "roman@code-factory.org"
48 | },
49 | {
50 | "name": "Benjamin Eberlei",
51 | "email": "kontakt@beberlei.de"
52 | },
53 | {
54 | "name": "Guilherme Blanco",
55 | "email": "guilhermeblanco@gmail.com"
56 | },
57 | {
58 | "name": "Jonathan Wage",
59 | "email": "jonwage@gmail.com"
60 | },
61 | {
62 | "name": "Johannes Schmitt",
63 | "email": "schmittjoh@gmail.com"
64 | }
65 | ],
66 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
67 | "homepage": "http://www.doctrine-project.org",
68 | "keywords": [
69 | "inflection",
70 | "pluralize",
71 | "singularize",
72 | "string"
73 | ],
74 | "time": "2018-01-09T20:05:19+00:00"
75 | },
76 | {
77 | "name": "illuminate/container",
78 | "version": "v5.8.31",
79 | "source": {
80 | "type": "git",
81 | "url": "https://github.com/illuminate/container.git",
82 | "reference": "7afee1ef2cb53190a98d727ea77096b6a610c05e"
83 | },
84 | "dist": {
85 | "type": "zip",
86 | "url": "https://api.github.com/repos/illuminate/container/zipball/7afee1ef2cb53190a98d727ea77096b6a610c05e",
87 | "reference": "7afee1ef2cb53190a98d727ea77096b6a610c05e",
88 | "shasum": ""
89 | },
90 | "require": {
91 | "illuminate/contracts": "5.8.*",
92 | "illuminate/support": "5.8.*",
93 | "php": "^7.1.3",
94 | "psr/container": "^1.0"
95 | },
96 | "type": "library",
97 | "extra": {
98 | "branch-alias": {
99 | "dev-master": "5.8-dev"
100 | }
101 | },
102 | "autoload": {
103 | "psr-4": {
104 | "Illuminate\\Container\\": ""
105 | }
106 | },
107 | "notification-url": "https://packagist.org/downloads/",
108 | "license": [
109 | "MIT"
110 | ],
111 | "authors": [
112 | {
113 | "name": "Taylor Otwell",
114 | "email": "taylor@laravel.com"
115 | }
116 | ],
117 | "description": "The Illuminate Container package.",
118 | "homepage": "https://laravel.com",
119 | "time": "2019-07-16T13:14:16+00:00"
120 | },
121 | {
122 | "name": "illuminate/contracts",
123 | "version": "v5.8.31",
124 | "source": {
125 | "type": "git",
126 | "url": "https://github.com/illuminate/contracts.git",
127 | "reference": "00fc6afee788fa07c311b0650ad276585f8aef96"
128 | },
129 | "dist": {
130 | "type": "zip",
131 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/00fc6afee788fa07c311b0650ad276585f8aef96",
132 | "reference": "00fc6afee788fa07c311b0650ad276585f8aef96",
133 | "shasum": ""
134 | },
135 | "require": {
136 | "php": "^7.1.3",
137 | "psr/container": "^1.0",
138 | "psr/simple-cache": "^1.0"
139 | },
140 | "type": "library",
141 | "extra": {
142 | "branch-alias": {
143 | "dev-master": "5.8-dev"
144 | }
145 | },
146 | "autoload": {
147 | "psr-4": {
148 | "Illuminate\\Contracts\\": ""
149 | }
150 | },
151 | "notification-url": "https://packagist.org/downloads/",
152 | "license": [
153 | "MIT"
154 | ],
155 | "authors": [
156 | {
157 | "name": "Taylor Otwell",
158 | "email": "taylor@laravel.com"
159 | }
160 | ],
161 | "description": "The Illuminate Contracts package.",
162 | "homepage": "https://laravel.com",
163 | "time": "2019-07-30T13:57:21+00:00"
164 | },
165 | {
166 | "name": "illuminate/support",
167 | "version": "v5.8.31",
168 | "source": {
169 | "type": "git",
170 | "url": "https://github.com/illuminate/support.git",
171 | "reference": "60fdf2cd0fe8092947f42add1681c34fa252af33"
172 | },
173 | "dist": {
174 | "type": "zip",
175 | "url": "https://api.github.com/repos/illuminate/support/zipball/60fdf2cd0fe8092947f42add1681c34fa252af33",
176 | "reference": "60fdf2cd0fe8092947f42add1681c34fa252af33",
177 | "shasum": ""
178 | },
179 | "require": {
180 | "doctrine/inflector": "^1.1",
181 | "ext-json": "*",
182 | "ext-mbstring": "*",
183 | "illuminate/contracts": "5.8.*",
184 | "nesbot/carbon": "^1.26.3 || ^2.0",
185 | "php": "^7.1.3"
186 | },
187 | "conflict": {
188 | "tightenco/collect": "<5.5.33"
189 | },
190 | "suggest": {
191 | "illuminate/filesystem": "Required to use the composer class (5.8.*).",
192 | "moontoast/math": "Required to use ordered UUIDs (^1.1).",
193 | "ramsey/uuid": "Required to use Str::uuid() (^3.7).",
194 | "symfony/process": "Required to use the composer class (^4.2).",
195 | "symfony/var-dumper": "Required to use the dd function (^4.2).",
196 | "vlucas/phpdotenv": "Required to use the env helper (^3.3)."
197 | },
198 | "type": "library",
199 | "extra": {
200 | "branch-alias": {
201 | "dev-master": "5.8-dev"
202 | }
203 | },
204 | "autoload": {
205 | "psr-4": {
206 | "Illuminate\\Support\\": ""
207 | },
208 | "files": [
209 | "helpers.php"
210 | ]
211 | },
212 | "notification-url": "https://packagist.org/downloads/",
213 | "license": [
214 | "MIT"
215 | ],
216 | "authors": [
217 | {
218 | "name": "Taylor Otwell",
219 | "email": "taylor@laravel.com"
220 | }
221 | ],
222 | "description": "The Illuminate Support package.",
223 | "homepage": "https://laravel.com",
224 | "time": "2019-08-06T08:53:24+00:00"
225 | },
226 | {
227 | "name": "mikey179/vfsstream",
228 | "version": "v1.6.7",
229 | "source": {
230 | "type": "git",
231 | "url": "https://github.com/bovigo/vfsStream.git",
232 | "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb"
233 | },
234 | "dist": {
235 | "type": "zip",
236 | "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb",
237 | "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb",
238 | "shasum": ""
239 | },
240 | "require": {
241 | "php": ">=5.3.0"
242 | },
243 | "require-dev": {
244 | "phpunit/phpunit": "^4.5|^5.0"
245 | },
246 | "type": "library",
247 | "extra": {
248 | "branch-alias": {
249 | "dev-master": "1.6.x-dev"
250 | }
251 | },
252 | "autoload": {
253 | "psr-0": {
254 | "org\\bovigo\\vfs\\": "src/main/php"
255 | }
256 | },
257 | "notification-url": "https://packagist.org/downloads/",
258 | "license": [
259 | "BSD-3-Clause"
260 | ],
261 | "authors": [
262 | {
263 | "name": "Frank Kleine",
264 | "role": "Developer",
265 | "homepage": "http://frankkleine.de/"
266 | }
267 | ],
268 | "description": "Virtual file system to mock the real file system in unit tests.",
269 | "homepage": "http://vfs.bovigo.org/",
270 | "time": "2019-08-01T01:38:37+00:00"
271 | },
272 | {
273 | "name": "nesbot/carbon",
274 | "version": "2.22.3",
275 | "source": {
276 | "type": "git",
277 | "url": "https://github.com/briannesbitt/Carbon.git",
278 | "reference": "738fbd8d80b2c5e158fda76c29c2de432fcc6f7e"
279 | },
280 | "dist": {
281 | "type": "zip",
282 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/738fbd8d80b2c5e158fda76c29c2de432fcc6f7e",
283 | "reference": "738fbd8d80b2c5e158fda76c29c2de432fcc6f7e",
284 | "shasum": ""
285 | },
286 | "require": {
287 | "ext-json": "*",
288 | "php": "^7.1.8 || ^8.0",
289 | "symfony/translation": "^3.4 || ^4.0"
290 | },
291 | "require-dev": {
292 | "friendsofphp/php-cs-fixer": "^2.14 || ^3.0",
293 | "kylekatarnls/multi-tester": "^1.1",
294 | "phpmd/phpmd": "dev-php-7.1-compatibility",
295 | "phpstan/phpstan": "^0.11",
296 | "phpunit/phpunit": "^7.5 || ^8.0",
297 | "squizlabs/php_codesniffer": "^3.4"
298 | },
299 | "bin": [
300 | "bin/carbon"
301 | ],
302 | "type": "library",
303 | "extra": {
304 | "laravel": {
305 | "providers": [
306 | "Carbon\\Laravel\\ServiceProvider"
307 | ]
308 | }
309 | },
310 | "autoload": {
311 | "psr-4": {
312 | "Carbon\\": "src/Carbon/"
313 | }
314 | },
315 | "notification-url": "https://packagist.org/downloads/",
316 | "license": [
317 | "MIT"
318 | ],
319 | "authors": [
320 | {
321 | "name": "Brian Nesbitt",
322 | "email": "brian@nesbot.com",
323 | "homepage": "http://nesbot.com"
324 | },
325 | {
326 | "name": "kylekatarnls",
327 | "homepage": "http://github.com/kylekatarnls"
328 | }
329 | ],
330 | "description": "A simple API extension for DateTime.",
331 | "homepage": "http://carbon.nesbot.com",
332 | "keywords": [
333 | "date",
334 | "datetime",
335 | "time"
336 | ],
337 | "time": "2019-08-07T12:36:44+00:00"
338 | },
339 | {
340 | "name": "psr/container",
341 | "version": "1.0.0",
342 | "source": {
343 | "type": "git",
344 | "url": "https://github.com/php-fig/container.git",
345 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
346 | },
347 | "dist": {
348 | "type": "zip",
349 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
350 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
351 | "shasum": ""
352 | },
353 | "require": {
354 | "php": ">=5.3.0"
355 | },
356 | "type": "library",
357 | "extra": {
358 | "branch-alias": {
359 | "dev-master": "1.0.x-dev"
360 | }
361 | },
362 | "autoload": {
363 | "psr-4": {
364 | "Psr\\Container\\": "src/"
365 | }
366 | },
367 | "notification-url": "https://packagist.org/downloads/",
368 | "license": [
369 | "MIT"
370 | ],
371 | "authors": [
372 | {
373 | "name": "PHP-FIG",
374 | "homepage": "http://www.php-fig.org/"
375 | }
376 | ],
377 | "description": "Common Container Interface (PHP FIG PSR-11)",
378 | "homepage": "https://github.com/php-fig/container",
379 | "keywords": [
380 | "PSR-11",
381 | "container",
382 | "container-interface",
383 | "container-interop",
384 | "psr"
385 | ],
386 | "time": "2017-02-14T16:28:37+00:00"
387 | },
388 | {
389 | "name": "psr/simple-cache",
390 | "version": "1.0.1",
391 | "source": {
392 | "type": "git",
393 | "url": "https://github.com/php-fig/simple-cache.git",
394 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
395 | },
396 | "dist": {
397 | "type": "zip",
398 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
399 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
400 | "shasum": ""
401 | },
402 | "require": {
403 | "php": ">=5.3.0"
404 | },
405 | "type": "library",
406 | "extra": {
407 | "branch-alias": {
408 | "dev-master": "1.0.x-dev"
409 | }
410 | },
411 | "autoload": {
412 | "psr-4": {
413 | "Psr\\SimpleCache\\": "src/"
414 | }
415 | },
416 | "notification-url": "https://packagist.org/downloads/",
417 | "license": [
418 | "MIT"
419 | ],
420 | "authors": [
421 | {
422 | "name": "PHP-FIG",
423 | "homepage": "http://www.php-fig.org/"
424 | }
425 | ],
426 | "description": "Common interfaces for simple caching",
427 | "keywords": [
428 | "cache",
429 | "caching",
430 | "psr",
431 | "psr-16",
432 | "simple-cache"
433 | ],
434 | "time": "2017-10-23T01:57:42+00:00"
435 | },
436 | {
437 | "name": "symfony/console",
438 | "version": "v4.3.3",
439 | "source": {
440 | "type": "git",
441 | "url": "https://github.com/symfony/console.git",
442 | "reference": "8b0ae5742ce9aaa8b0075665862c1ca397d1c1d9"
443 | },
444 | "dist": {
445 | "type": "zip",
446 | "url": "https://api.github.com/repos/symfony/console/zipball/8b0ae5742ce9aaa8b0075665862c1ca397d1c1d9",
447 | "reference": "8b0ae5742ce9aaa8b0075665862c1ca397d1c1d9",
448 | "shasum": ""
449 | },
450 | "require": {
451 | "php": "^7.1.3",
452 | "symfony/polyfill-mbstring": "~1.0",
453 | "symfony/polyfill-php73": "^1.8",
454 | "symfony/service-contracts": "^1.1"
455 | },
456 | "conflict": {
457 | "symfony/dependency-injection": "<3.4",
458 | "symfony/event-dispatcher": "<4.3",
459 | "symfony/process": "<3.3"
460 | },
461 | "provide": {
462 | "psr/log-implementation": "1.0"
463 | },
464 | "require-dev": {
465 | "psr/log": "~1.0",
466 | "symfony/config": "~3.4|~4.0",
467 | "symfony/dependency-injection": "~3.4|~4.0",
468 | "symfony/event-dispatcher": "^4.3",
469 | "symfony/lock": "~3.4|~4.0",
470 | "symfony/process": "~3.4|~4.0",
471 | "symfony/var-dumper": "^4.3"
472 | },
473 | "suggest": {
474 | "psr/log": "For using the console logger",
475 | "symfony/event-dispatcher": "",
476 | "symfony/lock": "",
477 | "symfony/process": ""
478 | },
479 | "type": "library",
480 | "extra": {
481 | "branch-alias": {
482 | "dev-master": "4.3-dev"
483 | }
484 | },
485 | "autoload": {
486 | "psr-4": {
487 | "Symfony\\Component\\Console\\": ""
488 | },
489 | "exclude-from-classmap": [
490 | "/Tests/"
491 | ]
492 | },
493 | "notification-url": "https://packagist.org/downloads/",
494 | "license": [
495 | "MIT"
496 | ],
497 | "authors": [
498 | {
499 | "name": "Fabien Potencier",
500 | "email": "fabien@symfony.com"
501 | },
502 | {
503 | "name": "Symfony Community",
504 | "homepage": "https://symfony.com/contributors"
505 | }
506 | ],
507 | "description": "Symfony Console Component",
508 | "homepage": "https://symfony.com",
509 | "time": "2019-07-24T17:13:59+00:00"
510 | },
511 | {
512 | "name": "symfony/polyfill-mbstring",
513 | "version": "v1.12.0",
514 | "source": {
515 | "type": "git",
516 | "url": "https://github.com/symfony/polyfill-mbstring.git",
517 | "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
518 | },
519 | "dist": {
520 | "type": "zip",
521 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
522 | "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
523 | "shasum": ""
524 | },
525 | "require": {
526 | "php": ">=5.3.3"
527 | },
528 | "suggest": {
529 | "ext-mbstring": "For best performance"
530 | },
531 | "type": "library",
532 | "extra": {
533 | "branch-alias": {
534 | "dev-master": "1.12-dev"
535 | }
536 | },
537 | "autoload": {
538 | "psr-4": {
539 | "Symfony\\Polyfill\\Mbstring\\": ""
540 | },
541 | "files": [
542 | "bootstrap.php"
543 | ]
544 | },
545 | "notification-url": "https://packagist.org/downloads/",
546 | "license": [
547 | "MIT"
548 | ],
549 | "authors": [
550 | {
551 | "name": "Nicolas Grekas",
552 | "email": "p@tchwork.com"
553 | },
554 | {
555 | "name": "Symfony Community",
556 | "homepage": "https://symfony.com/contributors"
557 | }
558 | ],
559 | "description": "Symfony polyfill for the Mbstring extension",
560 | "homepage": "https://symfony.com",
561 | "keywords": [
562 | "compatibility",
563 | "mbstring",
564 | "polyfill",
565 | "portable",
566 | "shim"
567 | ],
568 | "time": "2019-08-06T08:03:45+00:00"
569 | },
570 | {
571 | "name": "symfony/polyfill-php73",
572 | "version": "v1.12.0",
573 | "source": {
574 | "type": "git",
575 | "url": "https://github.com/symfony/polyfill-php73.git",
576 | "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188"
577 | },
578 | "dist": {
579 | "type": "zip",
580 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188",
581 | "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188",
582 | "shasum": ""
583 | },
584 | "require": {
585 | "php": ">=5.3.3"
586 | },
587 | "type": "library",
588 | "extra": {
589 | "branch-alias": {
590 | "dev-master": "1.12-dev"
591 | }
592 | },
593 | "autoload": {
594 | "psr-4": {
595 | "Symfony\\Polyfill\\Php73\\": ""
596 | },
597 | "files": [
598 | "bootstrap.php"
599 | ],
600 | "classmap": [
601 | "Resources/stubs"
602 | ]
603 | },
604 | "notification-url": "https://packagist.org/downloads/",
605 | "license": [
606 | "MIT"
607 | ],
608 | "authors": [
609 | {
610 | "name": "Nicolas Grekas",
611 | "email": "p@tchwork.com"
612 | },
613 | {
614 | "name": "Symfony Community",
615 | "homepage": "https://symfony.com/contributors"
616 | }
617 | ],
618 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
619 | "homepage": "https://symfony.com",
620 | "keywords": [
621 | "compatibility",
622 | "polyfill",
623 | "portable",
624 | "shim"
625 | ],
626 | "time": "2019-08-06T08:03:45+00:00"
627 | },
628 | {
629 | "name": "symfony/process",
630 | "version": "v4.3.3",
631 | "source": {
632 | "type": "git",
633 | "url": "https://github.com/symfony/process.git",
634 | "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c"
635 | },
636 | "dist": {
637 | "type": "zip",
638 | "url": "https://api.github.com/repos/symfony/process/zipball/856d35814cf287480465bb7a6c413bb7f5f5e69c",
639 | "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c",
640 | "shasum": ""
641 | },
642 | "require": {
643 | "php": "^7.1.3"
644 | },
645 | "type": "library",
646 | "extra": {
647 | "branch-alias": {
648 | "dev-master": "4.3-dev"
649 | }
650 | },
651 | "autoload": {
652 | "psr-4": {
653 | "Symfony\\Component\\Process\\": ""
654 | },
655 | "exclude-from-classmap": [
656 | "/Tests/"
657 | ]
658 | },
659 | "notification-url": "https://packagist.org/downloads/",
660 | "license": [
661 | "MIT"
662 | ],
663 | "authors": [
664 | {
665 | "name": "Fabien Potencier",
666 | "email": "fabien@symfony.com"
667 | },
668 | {
669 | "name": "Symfony Community",
670 | "homepage": "https://symfony.com/contributors"
671 | }
672 | ],
673 | "description": "Symfony Process Component",
674 | "homepage": "https://symfony.com",
675 | "time": "2019-05-30T16:10:05+00:00"
676 | },
677 | {
678 | "name": "symfony/service-contracts",
679 | "version": "v1.1.5",
680 | "source": {
681 | "type": "git",
682 | "url": "https://github.com/symfony/service-contracts.git",
683 | "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d"
684 | },
685 | "dist": {
686 | "type": "zip",
687 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d",
688 | "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d",
689 | "shasum": ""
690 | },
691 | "require": {
692 | "php": "^7.1.3",
693 | "psr/container": "^1.0"
694 | },
695 | "suggest": {
696 | "symfony/service-implementation": ""
697 | },
698 | "type": "library",
699 | "extra": {
700 | "branch-alias": {
701 | "dev-master": "1.1-dev"
702 | }
703 | },
704 | "autoload": {
705 | "psr-4": {
706 | "Symfony\\Contracts\\Service\\": ""
707 | }
708 | },
709 | "notification-url": "https://packagist.org/downloads/",
710 | "license": [
711 | "MIT"
712 | ],
713 | "authors": [
714 | {
715 | "name": "Nicolas Grekas",
716 | "email": "p@tchwork.com"
717 | },
718 | {
719 | "name": "Symfony Community",
720 | "homepage": "https://symfony.com/contributors"
721 | }
722 | ],
723 | "description": "Generic abstractions related to writing services",
724 | "homepage": "https://symfony.com",
725 | "keywords": [
726 | "abstractions",
727 | "contracts",
728 | "decoupling",
729 | "interfaces",
730 | "interoperability",
731 | "standards"
732 | ],
733 | "time": "2019-06-13T11:15:36+00:00"
734 | },
735 | {
736 | "name": "symfony/translation",
737 | "version": "v4.3.3",
738 | "source": {
739 | "type": "git",
740 | "url": "https://github.com/symfony/translation.git",
741 | "reference": "4e3e39cc485304f807622bdc64938e4633396406"
742 | },
743 | "dist": {
744 | "type": "zip",
745 | "url": "https://api.github.com/repos/symfony/translation/zipball/4e3e39cc485304f807622bdc64938e4633396406",
746 | "reference": "4e3e39cc485304f807622bdc64938e4633396406",
747 | "shasum": ""
748 | },
749 | "require": {
750 | "php": "^7.1.3",
751 | "symfony/polyfill-mbstring": "~1.0",
752 | "symfony/translation-contracts": "^1.1.2"
753 | },
754 | "conflict": {
755 | "symfony/config": "<3.4",
756 | "symfony/dependency-injection": "<3.4",
757 | "symfony/yaml": "<3.4"
758 | },
759 | "provide": {
760 | "symfony/translation-implementation": "1.0"
761 | },
762 | "require-dev": {
763 | "psr/log": "~1.0",
764 | "symfony/config": "~3.4|~4.0",
765 | "symfony/console": "~3.4|~4.0",
766 | "symfony/dependency-injection": "~3.4|~4.0",
767 | "symfony/finder": "~2.8|~3.0|~4.0",
768 | "symfony/http-kernel": "~3.4|~4.0",
769 | "symfony/intl": "~3.4|~4.0",
770 | "symfony/service-contracts": "^1.1.2",
771 | "symfony/var-dumper": "~3.4|~4.0",
772 | "symfony/yaml": "~3.4|~4.0"
773 | },
774 | "suggest": {
775 | "psr/log-implementation": "To use logging capability in translator",
776 | "symfony/config": "",
777 | "symfony/yaml": ""
778 | },
779 | "type": "library",
780 | "extra": {
781 | "branch-alias": {
782 | "dev-master": "4.3-dev"
783 | }
784 | },
785 | "autoload": {
786 | "psr-4": {
787 | "Symfony\\Component\\Translation\\": ""
788 | },
789 | "exclude-from-classmap": [
790 | "/Tests/"
791 | ]
792 | },
793 | "notification-url": "https://packagist.org/downloads/",
794 | "license": [
795 | "MIT"
796 | ],
797 | "authors": [
798 | {
799 | "name": "Fabien Potencier",
800 | "email": "fabien@symfony.com"
801 | },
802 | {
803 | "name": "Symfony Community",
804 | "homepage": "https://symfony.com/contributors"
805 | }
806 | ],
807 | "description": "Symfony Translation Component",
808 | "homepage": "https://symfony.com",
809 | "time": "2019-07-18T10:34:59+00:00"
810 | },
811 | {
812 | "name": "symfony/translation-contracts",
813 | "version": "v1.1.5",
814 | "source": {
815 | "type": "git",
816 | "url": "https://github.com/symfony/translation-contracts.git",
817 | "reference": "cb4b18ad7b92a26e83b65dde940fab78339e6f3c"
818 | },
819 | "dist": {
820 | "type": "zip",
821 | "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/cb4b18ad7b92a26e83b65dde940fab78339e6f3c",
822 | "reference": "cb4b18ad7b92a26e83b65dde940fab78339e6f3c",
823 | "shasum": ""
824 | },
825 | "require": {
826 | "php": "^7.1.3"
827 | },
828 | "suggest": {
829 | "symfony/translation-implementation": ""
830 | },
831 | "type": "library",
832 | "extra": {
833 | "branch-alias": {
834 | "dev-master": "1.1-dev"
835 | }
836 | },
837 | "autoload": {
838 | "psr-4": {
839 | "Symfony\\Contracts\\Translation\\": ""
840 | }
841 | },
842 | "notification-url": "https://packagist.org/downloads/",
843 | "license": [
844 | "MIT"
845 | ],
846 | "authors": [
847 | {
848 | "name": "Nicolas Grekas",
849 | "email": "p@tchwork.com"
850 | },
851 | {
852 | "name": "Symfony Community",
853 | "homepage": "https://symfony.com/contributors"
854 | }
855 | ],
856 | "description": "Generic abstractions related to translation",
857 | "homepage": "https://symfony.com",
858 | "keywords": [
859 | "abstractions",
860 | "contracts",
861 | "decoupling",
862 | "interfaces",
863 | "interoperability",
864 | "standards"
865 | ],
866 | "time": "2019-06-13T11:15:36+00:00"
867 | }
868 | ],
869 | "packages-dev": [
870 | {
871 | "name": "doctrine/instantiator",
872 | "version": "1.2.0",
873 | "source": {
874 | "type": "git",
875 | "url": "https://github.com/doctrine/instantiator.git",
876 | "reference": "a2c590166b2133a4633738648b6b064edae0814a"
877 | },
878 | "dist": {
879 | "type": "zip",
880 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
881 | "reference": "a2c590166b2133a4633738648b6b064edae0814a",
882 | "shasum": ""
883 | },
884 | "require": {
885 | "php": "^7.1"
886 | },
887 | "require-dev": {
888 | "doctrine/coding-standard": "^6.0",
889 | "ext-pdo": "*",
890 | "ext-phar": "*",
891 | "phpbench/phpbench": "^0.13",
892 | "phpstan/phpstan-phpunit": "^0.11",
893 | "phpstan/phpstan-shim": "^0.11",
894 | "phpunit/phpunit": "^7.0"
895 | },
896 | "type": "library",
897 | "extra": {
898 | "branch-alias": {
899 | "dev-master": "1.2.x-dev"
900 | }
901 | },
902 | "autoload": {
903 | "psr-4": {
904 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
905 | }
906 | },
907 | "notification-url": "https://packagist.org/downloads/",
908 | "license": [
909 | "MIT"
910 | ],
911 | "authors": [
912 | {
913 | "name": "Marco Pivetta",
914 | "email": "ocramius@gmail.com",
915 | "homepage": "http://ocramius.github.com/"
916 | }
917 | ],
918 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
919 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
920 | "keywords": [
921 | "constructor",
922 | "instantiate"
923 | ],
924 | "time": "2019-03-17T17:37:11+00:00"
925 | },
926 | {
927 | "name": "myclabs/deep-copy",
928 | "version": "1.9.1",
929 | "source": {
930 | "type": "git",
931 | "url": "https://github.com/myclabs/DeepCopy.git",
932 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72"
933 | },
934 | "dist": {
935 | "type": "zip",
936 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72",
937 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72",
938 | "shasum": ""
939 | },
940 | "require": {
941 | "php": "^7.1"
942 | },
943 | "replace": {
944 | "myclabs/deep-copy": "self.version"
945 | },
946 | "require-dev": {
947 | "doctrine/collections": "^1.0",
948 | "doctrine/common": "^2.6",
949 | "phpunit/phpunit": "^7.1"
950 | },
951 | "type": "library",
952 | "autoload": {
953 | "psr-4": {
954 | "DeepCopy\\": "src/DeepCopy/"
955 | },
956 | "files": [
957 | "src/DeepCopy/deep_copy.php"
958 | ]
959 | },
960 | "notification-url": "https://packagist.org/downloads/",
961 | "license": [
962 | "MIT"
963 | ],
964 | "description": "Create deep copies (clones) of your objects",
965 | "keywords": [
966 | "clone",
967 | "copy",
968 | "duplicate",
969 | "object",
970 | "object graph"
971 | ],
972 | "time": "2019-04-07T13:18:21+00:00"
973 | },
974 | {
975 | "name": "phar-io/manifest",
976 | "version": "1.0.3",
977 | "source": {
978 | "type": "git",
979 | "url": "https://github.com/phar-io/manifest.git",
980 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
981 | },
982 | "dist": {
983 | "type": "zip",
984 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
985 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
986 | "shasum": ""
987 | },
988 | "require": {
989 | "ext-dom": "*",
990 | "ext-phar": "*",
991 | "phar-io/version": "^2.0",
992 | "php": "^5.6 || ^7.0"
993 | },
994 | "type": "library",
995 | "extra": {
996 | "branch-alias": {
997 | "dev-master": "1.0.x-dev"
998 | }
999 | },
1000 | "autoload": {
1001 | "classmap": [
1002 | "src/"
1003 | ]
1004 | },
1005 | "notification-url": "https://packagist.org/downloads/",
1006 | "license": [
1007 | "BSD-3-Clause"
1008 | ],
1009 | "authors": [
1010 | {
1011 | "name": "Arne Blankerts",
1012 | "role": "Developer",
1013 | "email": "arne@blankerts.de"
1014 | },
1015 | {
1016 | "name": "Sebastian Heuer",
1017 | "role": "Developer",
1018 | "email": "sebastian@phpeople.de"
1019 | },
1020 | {
1021 | "name": "Sebastian Bergmann",
1022 | "role": "Developer",
1023 | "email": "sebastian@phpunit.de"
1024 | }
1025 | ],
1026 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
1027 | "time": "2018-07-08T19:23:20+00:00"
1028 | },
1029 | {
1030 | "name": "phar-io/version",
1031 | "version": "2.0.1",
1032 | "source": {
1033 | "type": "git",
1034 | "url": "https://github.com/phar-io/version.git",
1035 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
1036 | },
1037 | "dist": {
1038 | "type": "zip",
1039 | "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
1040 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
1041 | "shasum": ""
1042 | },
1043 | "require": {
1044 | "php": "^5.6 || ^7.0"
1045 | },
1046 | "type": "library",
1047 | "autoload": {
1048 | "classmap": [
1049 | "src/"
1050 | ]
1051 | },
1052 | "notification-url": "https://packagist.org/downloads/",
1053 | "license": [
1054 | "BSD-3-Clause"
1055 | ],
1056 | "authors": [
1057 | {
1058 | "name": "Arne Blankerts",
1059 | "role": "Developer",
1060 | "email": "arne@blankerts.de"
1061 | },
1062 | {
1063 | "name": "Sebastian Heuer",
1064 | "role": "Developer",
1065 | "email": "sebastian@phpeople.de"
1066 | },
1067 | {
1068 | "name": "Sebastian Bergmann",
1069 | "role": "Developer",
1070 | "email": "sebastian@phpunit.de"
1071 | }
1072 | ],
1073 | "description": "Library for handling version information and constraints",
1074 | "time": "2018-07-08T19:19:57+00:00"
1075 | },
1076 | {
1077 | "name": "phpdocumentor/reflection-common",
1078 | "version": "1.0.1",
1079 | "source": {
1080 | "type": "git",
1081 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
1082 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
1083 | },
1084 | "dist": {
1085 | "type": "zip",
1086 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
1087 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
1088 | "shasum": ""
1089 | },
1090 | "require": {
1091 | "php": ">=5.5"
1092 | },
1093 | "require-dev": {
1094 | "phpunit/phpunit": "^4.6"
1095 | },
1096 | "type": "library",
1097 | "extra": {
1098 | "branch-alias": {
1099 | "dev-master": "1.0.x-dev"
1100 | }
1101 | },
1102 | "autoload": {
1103 | "psr-4": {
1104 | "phpDocumentor\\Reflection\\": [
1105 | "src"
1106 | ]
1107 | }
1108 | },
1109 | "notification-url": "https://packagist.org/downloads/",
1110 | "license": [
1111 | "MIT"
1112 | ],
1113 | "authors": [
1114 | {
1115 | "name": "Jaap van Otterdijk",
1116 | "email": "opensource@ijaap.nl"
1117 | }
1118 | ],
1119 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
1120 | "homepage": "http://www.phpdoc.org",
1121 | "keywords": [
1122 | "FQSEN",
1123 | "phpDocumentor",
1124 | "phpdoc",
1125 | "reflection",
1126 | "static analysis"
1127 | ],
1128 | "time": "2017-09-11T18:02:19+00:00"
1129 | },
1130 | {
1131 | "name": "phpdocumentor/reflection-docblock",
1132 | "version": "4.3.1",
1133 | "source": {
1134 | "type": "git",
1135 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
1136 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c"
1137 | },
1138 | "dist": {
1139 | "type": "zip",
1140 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
1141 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
1142 | "shasum": ""
1143 | },
1144 | "require": {
1145 | "php": "^7.0",
1146 | "phpdocumentor/reflection-common": "^1.0.0",
1147 | "phpdocumentor/type-resolver": "^0.4.0",
1148 | "webmozart/assert": "^1.0"
1149 | },
1150 | "require-dev": {
1151 | "doctrine/instantiator": "~1.0.5",
1152 | "mockery/mockery": "^1.0",
1153 | "phpunit/phpunit": "^6.4"
1154 | },
1155 | "type": "library",
1156 | "extra": {
1157 | "branch-alias": {
1158 | "dev-master": "4.x-dev"
1159 | }
1160 | },
1161 | "autoload": {
1162 | "psr-4": {
1163 | "phpDocumentor\\Reflection\\": [
1164 | "src/"
1165 | ]
1166 | }
1167 | },
1168 | "notification-url": "https://packagist.org/downloads/",
1169 | "license": [
1170 | "MIT"
1171 | ],
1172 | "authors": [
1173 | {
1174 | "name": "Mike van Riel",
1175 | "email": "me@mikevanriel.com"
1176 | }
1177 | ],
1178 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
1179 | "time": "2019-04-30T17:48:53+00:00"
1180 | },
1181 | {
1182 | "name": "phpdocumentor/type-resolver",
1183 | "version": "0.4.0",
1184 | "source": {
1185 | "type": "git",
1186 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
1187 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
1188 | },
1189 | "dist": {
1190 | "type": "zip",
1191 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
1192 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
1193 | "shasum": ""
1194 | },
1195 | "require": {
1196 | "php": "^5.5 || ^7.0",
1197 | "phpdocumentor/reflection-common": "^1.0"
1198 | },
1199 | "require-dev": {
1200 | "mockery/mockery": "^0.9.4",
1201 | "phpunit/phpunit": "^5.2||^4.8.24"
1202 | },
1203 | "type": "library",
1204 | "extra": {
1205 | "branch-alias": {
1206 | "dev-master": "1.0.x-dev"
1207 | }
1208 | },
1209 | "autoload": {
1210 | "psr-4": {
1211 | "phpDocumentor\\Reflection\\": [
1212 | "src/"
1213 | ]
1214 | }
1215 | },
1216 | "notification-url": "https://packagist.org/downloads/",
1217 | "license": [
1218 | "MIT"
1219 | ],
1220 | "authors": [
1221 | {
1222 | "name": "Mike van Riel",
1223 | "email": "me@mikevanriel.com"
1224 | }
1225 | ],
1226 | "time": "2017-07-14T14:27:02+00:00"
1227 | },
1228 | {
1229 | "name": "phpspec/prophecy",
1230 | "version": "1.8.1",
1231 | "source": {
1232 | "type": "git",
1233 | "url": "https://github.com/phpspec/prophecy.git",
1234 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
1235 | },
1236 | "dist": {
1237 | "type": "zip",
1238 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
1239 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
1240 | "shasum": ""
1241 | },
1242 | "require": {
1243 | "doctrine/instantiator": "^1.0.2",
1244 | "php": "^5.3|^7.0",
1245 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
1246 | "sebastian/comparator": "^1.1|^2.0|^3.0",
1247 | "sebastian/recursion-context": "^1.0|^2.0|^3.0"
1248 | },
1249 | "require-dev": {
1250 | "phpspec/phpspec": "^2.5|^3.2",
1251 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
1252 | },
1253 | "type": "library",
1254 | "extra": {
1255 | "branch-alias": {
1256 | "dev-master": "1.8.x-dev"
1257 | }
1258 | },
1259 | "autoload": {
1260 | "psr-4": {
1261 | "Prophecy\\": "src/Prophecy"
1262 | }
1263 | },
1264 | "notification-url": "https://packagist.org/downloads/",
1265 | "license": [
1266 | "MIT"
1267 | ],
1268 | "authors": [
1269 | {
1270 | "name": "Konstantin Kudryashov",
1271 | "email": "ever.zet@gmail.com",
1272 | "homepage": "http://everzet.com"
1273 | },
1274 | {
1275 | "name": "Marcello Duarte",
1276 | "email": "marcello.duarte@gmail.com"
1277 | }
1278 | ],
1279 | "description": "Highly opinionated mocking framework for PHP 5.3+",
1280 | "homepage": "https://github.com/phpspec/prophecy",
1281 | "keywords": [
1282 | "Double",
1283 | "Dummy",
1284 | "fake",
1285 | "mock",
1286 | "spy",
1287 | "stub"
1288 | ],
1289 | "time": "2019-06-13T12:50:23+00:00"
1290 | },
1291 | {
1292 | "name": "phpunit/php-code-coverage",
1293 | "version": "6.1.4",
1294 | "source": {
1295 | "type": "git",
1296 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1297 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
1298 | },
1299 | "dist": {
1300 | "type": "zip",
1301 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
1302 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
1303 | "shasum": ""
1304 | },
1305 | "require": {
1306 | "ext-dom": "*",
1307 | "ext-xmlwriter": "*",
1308 | "php": "^7.1",
1309 | "phpunit/php-file-iterator": "^2.0",
1310 | "phpunit/php-text-template": "^1.2.1",
1311 | "phpunit/php-token-stream": "^3.0",
1312 | "sebastian/code-unit-reverse-lookup": "^1.0.1",
1313 | "sebastian/environment": "^3.1 || ^4.0",
1314 | "sebastian/version": "^2.0.1",
1315 | "theseer/tokenizer": "^1.1"
1316 | },
1317 | "require-dev": {
1318 | "phpunit/phpunit": "^7.0"
1319 | },
1320 | "suggest": {
1321 | "ext-xdebug": "^2.6.0"
1322 | },
1323 | "type": "library",
1324 | "extra": {
1325 | "branch-alias": {
1326 | "dev-master": "6.1-dev"
1327 | }
1328 | },
1329 | "autoload": {
1330 | "classmap": [
1331 | "src/"
1332 | ]
1333 | },
1334 | "notification-url": "https://packagist.org/downloads/",
1335 | "license": [
1336 | "BSD-3-Clause"
1337 | ],
1338 | "authors": [
1339 | {
1340 | "name": "Sebastian Bergmann",
1341 | "role": "lead",
1342 | "email": "sebastian@phpunit.de"
1343 | }
1344 | ],
1345 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1346 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1347 | "keywords": [
1348 | "coverage",
1349 | "testing",
1350 | "xunit"
1351 | ],
1352 | "time": "2018-10-31T16:06:48+00:00"
1353 | },
1354 | {
1355 | "name": "phpunit/php-file-iterator",
1356 | "version": "2.0.2",
1357 | "source": {
1358 | "type": "git",
1359 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1360 | "reference": "050bedf145a257b1ff02746c31894800e5122946"
1361 | },
1362 | "dist": {
1363 | "type": "zip",
1364 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
1365 | "reference": "050bedf145a257b1ff02746c31894800e5122946",
1366 | "shasum": ""
1367 | },
1368 | "require": {
1369 | "php": "^7.1"
1370 | },
1371 | "require-dev": {
1372 | "phpunit/phpunit": "^7.1"
1373 | },
1374 | "type": "library",
1375 | "extra": {
1376 | "branch-alias": {
1377 | "dev-master": "2.0.x-dev"
1378 | }
1379 | },
1380 | "autoload": {
1381 | "classmap": [
1382 | "src/"
1383 | ]
1384 | },
1385 | "notification-url": "https://packagist.org/downloads/",
1386 | "license": [
1387 | "BSD-3-Clause"
1388 | ],
1389 | "authors": [
1390 | {
1391 | "name": "Sebastian Bergmann",
1392 | "role": "lead",
1393 | "email": "sebastian@phpunit.de"
1394 | }
1395 | ],
1396 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1397 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1398 | "keywords": [
1399 | "filesystem",
1400 | "iterator"
1401 | ],
1402 | "time": "2018-09-13T20:33:42+00:00"
1403 | },
1404 | {
1405 | "name": "phpunit/php-text-template",
1406 | "version": "1.2.1",
1407 | "source": {
1408 | "type": "git",
1409 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1410 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1411 | },
1412 | "dist": {
1413 | "type": "zip",
1414 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1415 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1416 | "shasum": ""
1417 | },
1418 | "require": {
1419 | "php": ">=5.3.3"
1420 | },
1421 | "type": "library",
1422 | "autoload": {
1423 | "classmap": [
1424 | "src/"
1425 | ]
1426 | },
1427 | "notification-url": "https://packagist.org/downloads/",
1428 | "license": [
1429 | "BSD-3-Clause"
1430 | ],
1431 | "authors": [
1432 | {
1433 | "name": "Sebastian Bergmann",
1434 | "role": "lead",
1435 | "email": "sebastian@phpunit.de"
1436 | }
1437 | ],
1438 | "description": "Simple template engine.",
1439 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1440 | "keywords": [
1441 | "template"
1442 | ],
1443 | "time": "2015-06-21T13:50:34+00:00"
1444 | },
1445 | {
1446 | "name": "phpunit/php-timer",
1447 | "version": "2.1.2",
1448 | "source": {
1449 | "type": "git",
1450 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1451 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
1452 | },
1453 | "dist": {
1454 | "type": "zip",
1455 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
1456 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
1457 | "shasum": ""
1458 | },
1459 | "require": {
1460 | "php": "^7.1"
1461 | },
1462 | "require-dev": {
1463 | "phpunit/phpunit": "^7.0"
1464 | },
1465 | "type": "library",
1466 | "extra": {
1467 | "branch-alias": {
1468 | "dev-master": "2.1-dev"
1469 | }
1470 | },
1471 | "autoload": {
1472 | "classmap": [
1473 | "src/"
1474 | ]
1475 | },
1476 | "notification-url": "https://packagist.org/downloads/",
1477 | "license": [
1478 | "BSD-3-Clause"
1479 | ],
1480 | "authors": [
1481 | {
1482 | "name": "Sebastian Bergmann",
1483 | "role": "lead",
1484 | "email": "sebastian@phpunit.de"
1485 | }
1486 | ],
1487 | "description": "Utility class for timing",
1488 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1489 | "keywords": [
1490 | "timer"
1491 | ],
1492 | "time": "2019-06-07T04:22:29+00:00"
1493 | },
1494 | {
1495 | "name": "phpunit/php-token-stream",
1496 | "version": "3.1.0",
1497 | "source": {
1498 | "type": "git",
1499 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1500 | "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a"
1501 | },
1502 | "dist": {
1503 | "type": "zip",
1504 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e899757bb3df5ff6e95089132f32cd59aac2220a",
1505 | "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a",
1506 | "shasum": ""
1507 | },
1508 | "require": {
1509 | "ext-tokenizer": "*",
1510 | "php": "^7.1"
1511 | },
1512 | "require-dev": {
1513 | "phpunit/phpunit": "^7.0"
1514 | },
1515 | "type": "library",
1516 | "extra": {
1517 | "branch-alias": {
1518 | "dev-master": "3.1-dev"
1519 | }
1520 | },
1521 | "autoload": {
1522 | "classmap": [
1523 | "src/"
1524 | ]
1525 | },
1526 | "notification-url": "https://packagist.org/downloads/",
1527 | "license": [
1528 | "BSD-3-Clause"
1529 | ],
1530 | "authors": [
1531 | {
1532 | "name": "Sebastian Bergmann",
1533 | "email": "sebastian@phpunit.de"
1534 | }
1535 | ],
1536 | "description": "Wrapper around PHP's tokenizer extension.",
1537 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1538 | "keywords": [
1539 | "tokenizer"
1540 | ],
1541 | "time": "2019-07-25T05:29:42+00:00"
1542 | },
1543 | {
1544 | "name": "phpunit/phpunit",
1545 | "version": "7.5.14",
1546 | "source": {
1547 | "type": "git",
1548 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1549 | "reference": "2834789aeb9ac182ad69bfdf9ae91856a59945ff"
1550 | },
1551 | "dist": {
1552 | "type": "zip",
1553 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2834789aeb9ac182ad69bfdf9ae91856a59945ff",
1554 | "reference": "2834789aeb9ac182ad69bfdf9ae91856a59945ff",
1555 | "shasum": ""
1556 | },
1557 | "require": {
1558 | "doctrine/instantiator": "^1.1",
1559 | "ext-dom": "*",
1560 | "ext-json": "*",
1561 | "ext-libxml": "*",
1562 | "ext-mbstring": "*",
1563 | "ext-xml": "*",
1564 | "myclabs/deep-copy": "^1.7",
1565 | "phar-io/manifest": "^1.0.2",
1566 | "phar-io/version": "^2.0",
1567 | "php": "^7.1",
1568 | "phpspec/prophecy": "^1.7",
1569 | "phpunit/php-code-coverage": "^6.0.7",
1570 | "phpunit/php-file-iterator": "^2.0.1",
1571 | "phpunit/php-text-template": "^1.2.1",
1572 | "phpunit/php-timer": "^2.1",
1573 | "sebastian/comparator": "^3.0",
1574 | "sebastian/diff": "^3.0",
1575 | "sebastian/environment": "^4.0",
1576 | "sebastian/exporter": "^3.1",
1577 | "sebastian/global-state": "^2.0",
1578 | "sebastian/object-enumerator": "^3.0.3",
1579 | "sebastian/resource-operations": "^2.0",
1580 | "sebastian/version": "^2.0.1"
1581 | },
1582 | "conflict": {
1583 | "phpunit/phpunit-mock-objects": "*"
1584 | },
1585 | "require-dev": {
1586 | "ext-pdo": "*"
1587 | },
1588 | "suggest": {
1589 | "ext-soap": "*",
1590 | "ext-xdebug": "*",
1591 | "phpunit/php-invoker": "^2.0"
1592 | },
1593 | "bin": [
1594 | "phpunit"
1595 | ],
1596 | "type": "library",
1597 | "extra": {
1598 | "branch-alias": {
1599 | "dev-master": "7.5-dev"
1600 | }
1601 | },
1602 | "autoload": {
1603 | "classmap": [
1604 | "src/"
1605 | ]
1606 | },
1607 | "notification-url": "https://packagist.org/downloads/",
1608 | "license": [
1609 | "BSD-3-Clause"
1610 | ],
1611 | "authors": [
1612 | {
1613 | "name": "Sebastian Bergmann",
1614 | "role": "lead",
1615 | "email": "sebastian@phpunit.de"
1616 | }
1617 | ],
1618 | "description": "The PHP Unit Testing framework.",
1619 | "homepage": "https://phpunit.de/",
1620 | "keywords": [
1621 | "phpunit",
1622 | "testing",
1623 | "xunit"
1624 | ],
1625 | "time": "2019-07-15T06:24:08+00:00"
1626 | },
1627 | {
1628 | "name": "sebastian/code-unit-reverse-lookup",
1629 | "version": "1.0.1",
1630 | "source": {
1631 | "type": "git",
1632 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1633 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
1634 | },
1635 | "dist": {
1636 | "type": "zip",
1637 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1638 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1639 | "shasum": ""
1640 | },
1641 | "require": {
1642 | "php": "^5.6 || ^7.0"
1643 | },
1644 | "require-dev": {
1645 | "phpunit/phpunit": "^5.7 || ^6.0"
1646 | },
1647 | "type": "library",
1648 | "extra": {
1649 | "branch-alias": {
1650 | "dev-master": "1.0.x-dev"
1651 | }
1652 | },
1653 | "autoload": {
1654 | "classmap": [
1655 | "src/"
1656 | ]
1657 | },
1658 | "notification-url": "https://packagist.org/downloads/",
1659 | "license": [
1660 | "BSD-3-Clause"
1661 | ],
1662 | "authors": [
1663 | {
1664 | "name": "Sebastian Bergmann",
1665 | "email": "sebastian@phpunit.de"
1666 | }
1667 | ],
1668 | "description": "Looks up which function or method a line of code belongs to",
1669 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1670 | "time": "2017-03-04T06:30:41+00:00"
1671 | },
1672 | {
1673 | "name": "sebastian/comparator",
1674 | "version": "3.0.2",
1675 | "source": {
1676 | "type": "git",
1677 | "url": "https://github.com/sebastianbergmann/comparator.git",
1678 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
1679 | },
1680 | "dist": {
1681 | "type": "zip",
1682 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
1683 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
1684 | "shasum": ""
1685 | },
1686 | "require": {
1687 | "php": "^7.1",
1688 | "sebastian/diff": "^3.0",
1689 | "sebastian/exporter": "^3.1"
1690 | },
1691 | "require-dev": {
1692 | "phpunit/phpunit": "^7.1"
1693 | },
1694 | "type": "library",
1695 | "extra": {
1696 | "branch-alias": {
1697 | "dev-master": "3.0-dev"
1698 | }
1699 | },
1700 | "autoload": {
1701 | "classmap": [
1702 | "src/"
1703 | ]
1704 | },
1705 | "notification-url": "https://packagist.org/downloads/",
1706 | "license": [
1707 | "BSD-3-Clause"
1708 | ],
1709 | "authors": [
1710 | {
1711 | "name": "Jeff Welch",
1712 | "email": "whatthejeff@gmail.com"
1713 | },
1714 | {
1715 | "name": "Volker Dusch",
1716 | "email": "github@wallbash.com"
1717 | },
1718 | {
1719 | "name": "Bernhard Schussek",
1720 | "email": "bschussek@2bepublished.at"
1721 | },
1722 | {
1723 | "name": "Sebastian Bergmann",
1724 | "email": "sebastian@phpunit.de"
1725 | }
1726 | ],
1727 | "description": "Provides the functionality to compare PHP values for equality",
1728 | "homepage": "https://github.com/sebastianbergmann/comparator",
1729 | "keywords": [
1730 | "comparator",
1731 | "compare",
1732 | "equality"
1733 | ],
1734 | "time": "2018-07-12T15:12:46+00:00"
1735 | },
1736 | {
1737 | "name": "sebastian/diff",
1738 | "version": "3.0.2",
1739 | "source": {
1740 | "type": "git",
1741 | "url": "https://github.com/sebastianbergmann/diff.git",
1742 | "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
1743 | },
1744 | "dist": {
1745 | "type": "zip",
1746 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
1747 | "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
1748 | "shasum": ""
1749 | },
1750 | "require": {
1751 | "php": "^7.1"
1752 | },
1753 | "require-dev": {
1754 | "phpunit/phpunit": "^7.5 || ^8.0",
1755 | "symfony/process": "^2 || ^3.3 || ^4"
1756 | },
1757 | "type": "library",
1758 | "extra": {
1759 | "branch-alias": {
1760 | "dev-master": "3.0-dev"
1761 | }
1762 | },
1763 | "autoload": {
1764 | "classmap": [
1765 | "src/"
1766 | ]
1767 | },
1768 | "notification-url": "https://packagist.org/downloads/",
1769 | "license": [
1770 | "BSD-3-Clause"
1771 | ],
1772 | "authors": [
1773 | {
1774 | "name": "Kore Nordmann",
1775 | "email": "mail@kore-nordmann.de"
1776 | },
1777 | {
1778 | "name": "Sebastian Bergmann",
1779 | "email": "sebastian@phpunit.de"
1780 | }
1781 | ],
1782 | "description": "Diff implementation",
1783 | "homepage": "https://github.com/sebastianbergmann/diff",
1784 | "keywords": [
1785 | "diff",
1786 | "udiff",
1787 | "unidiff",
1788 | "unified diff"
1789 | ],
1790 | "time": "2019-02-04T06:01:07+00:00"
1791 | },
1792 | {
1793 | "name": "sebastian/environment",
1794 | "version": "4.2.2",
1795 | "source": {
1796 | "type": "git",
1797 | "url": "https://github.com/sebastianbergmann/environment.git",
1798 | "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404"
1799 | },
1800 | "dist": {
1801 | "type": "zip",
1802 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
1803 | "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
1804 | "shasum": ""
1805 | },
1806 | "require": {
1807 | "php": "^7.1"
1808 | },
1809 | "require-dev": {
1810 | "phpunit/phpunit": "^7.5"
1811 | },
1812 | "suggest": {
1813 | "ext-posix": "*"
1814 | },
1815 | "type": "library",
1816 | "extra": {
1817 | "branch-alias": {
1818 | "dev-master": "4.2-dev"
1819 | }
1820 | },
1821 | "autoload": {
1822 | "classmap": [
1823 | "src/"
1824 | ]
1825 | },
1826 | "notification-url": "https://packagist.org/downloads/",
1827 | "license": [
1828 | "BSD-3-Clause"
1829 | ],
1830 | "authors": [
1831 | {
1832 | "name": "Sebastian Bergmann",
1833 | "email": "sebastian@phpunit.de"
1834 | }
1835 | ],
1836 | "description": "Provides functionality to handle HHVM/PHP environments",
1837 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1838 | "keywords": [
1839 | "Xdebug",
1840 | "environment",
1841 | "hhvm"
1842 | ],
1843 | "time": "2019-05-05T09:05:15+00:00"
1844 | },
1845 | {
1846 | "name": "sebastian/exporter",
1847 | "version": "3.1.0",
1848 | "source": {
1849 | "type": "git",
1850 | "url": "https://github.com/sebastianbergmann/exporter.git",
1851 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
1852 | },
1853 | "dist": {
1854 | "type": "zip",
1855 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
1856 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
1857 | "shasum": ""
1858 | },
1859 | "require": {
1860 | "php": "^7.0",
1861 | "sebastian/recursion-context": "^3.0"
1862 | },
1863 | "require-dev": {
1864 | "ext-mbstring": "*",
1865 | "phpunit/phpunit": "^6.0"
1866 | },
1867 | "type": "library",
1868 | "extra": {
1869 | "branch-alias": {
1870 | "dev-master": "3.1.x-dev"
1871 | }
1872 | },
1873 | "autoload": {
1874 | "classmap": [
1875 | "src/"
1876 | ]
1877 | },
1878 | "notification-url": "https://packagist.org/downloads/",
1879 | "license": [
1880 | "BSD-3-Clause"
1881 | ],
1882 | "authors": [
1883 | {
1884 | "name": "Jeff Welch",
1885 | "email": "whatthejeff@gmail.com"
1886 | },
1887 | {
1888 | "name": "Volker Dusch",
1889 | "email": "github@wallbash.com"
1890 | },
1891 | {
1892 | "name": "Bernhard Schussek",
1893 | "email": "bschussek@2bepublished.at"
1894 | },
1895 | {
1896 | "name": "Sebastian Bergmann",
1897 | "email": "sebastian@phpunit.de"
1898 | },
1899 | {
1900 | "name": "Adam Harvey",
1901 | "email": "aharvey@php.net"
1902 | }
1903 | ],
1904 | "description": "Provides the functionality to export PHP variables for visualization",
1905 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1906 | "keywords": [
1907 | "export",
1908 | "exporter"
1909 | ],
1910 | "time": "2017-04-03T13:19:02+00:00"
1911 | },
1912 | {
1913 | "name": "sebastian/global-state",
1914 | "version": "2.0.0",
1915 | "source": {
1916 | "type": "git",
1917 | "url": "https://github.com/sebastianbergmann/global-state.git",
1918 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
1919 | },
1920 | "dist": {
1921 | "type": "zip",
1922 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1923 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1924 | "shasum": ""
1925 | },
1926 | "require": {
1927 | "php": "^7.0"
1928 | },
1929 | "require-dev": {
1930 | "phpunit/phpunit": "^6.0"
1931 | },
1932 | "suggest": {
1933 | "ext-uopz": "*"
1934 | },
1935 | "type": "library",
1936 | "extra": {
1937 | "branch-alias": {
1938 | "dev-master": "2.0-dev"
1939 | }
1940 | },
1941 | "autoload": {
1942 | "classmap": [
1943 | "src/"
1944 | ]
1945 | },
1946 | "notification-url": "https://packagist.org/downloads/",
1947 | "license": [
1948 | "BSD-3-Clause"
1949 | ],
1950 | "authors": [
1951 | {
1952 | "name": "Sebastian Bergmann",
1953 | "email": "sebastian@phpunit.de"
1954 | }
1955 | ],
1956 | "description": "Snapshotting of global state",
1957 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1958 | "keywords": [
1959 | "global state"
1960 | ],
1961 | "time": "2017-04-27T15:39:26+00:00"
1962 | },
1963 | {
1964 | "name": "sebastian/object-enumerator",
1965 | "version": "3.0.3",
1966 | "source": {
1967 | "type": "git",
1968 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1969 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
1970 | },
1971 | "dist": {
1972 | "type": "zip",
1973 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
1974 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
1975 | "shasum": ""
1976 | },
1977 | "require": {
1978 | "php": "^7.0",
1979 | "sebastian/object-reflector": "^1.1.1",
1980 | "sebastian/recursion-context": "^3.0"
1981 | },
1982 | "require-dev": {
1983 | "phpunit/phpunit": "^6.0"
1984 | },
1985 | "type": "library",
1986 | "extra": {
1987 | "branch-alias": {
1988 | "dev-master": "3.0.x-dev"
1989 | }
1990 | },
1991 | "autoload": {
1992 | "classmap": [
1993 | "src/"
1994 | ]
1995 | },
1996 | "notification-url": "https://packagist.org/downloads/",
1997 | "license": [
1998 | "BSD-3-Clause"
1999 | ],
2000 | "authors": [
2001 | {
2002 | "name": "Sebastian Bergmann",
2003 | "email": "sebastian@phpunit.de"
2004 | }
2005 | ],
2006 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
2007 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
2008 | "time": "2017-08-03T12:35:26+00:00"
2009 | },
2010 | {
2011 | "name": "sebastian/object-reflector",
2012 | "version": "1.1.1",
2013 | "source": {
2014 | "type": "git",
2015 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
2016 | "reference": "773f97c67f28de00d397be301821b06708fca0be"
2017 | },
2018 | "dist": {
2019 | "type": "zip",
2020 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
2021 | "reference": "773f97c67f28de00d397be301821b06708fca0be",
2022 | "shasum": ""
2023 | },
2024 | "require": {
2025 | "php": "^7.0"
2026 | },
2027 | "require-dev": {
2028 | "phpunit/phpunit": "^6.0"
2029 | },
2030 | "type": "library",
2031 | "extra": {
2032 | "branch-alias": {
2033 | "dev-master": "1.1-dev"
2034 | }
2035 | },
2036 | "autoload": {
2037 | "classmap": [
2038 | "src/"
2039 | ]
2040 | },
2041 | "notification-url": "https://packagist.org/downloads/",
2042 | "license": [
2043 | "BSD-3-Clause"
2044 | ],
2045 | "authors": [
2046 | {
2047 | "name": "Sebastian Bergmann",
2048 | "email": "sebastian@phpunit.de"
2049 | }
2050 | ],
2051 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
2052 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
2053 | "time": "2017-03-29T09:07:27+00:00"
2054 | },
2055 | {
2056 | "name": "sebastian/recursion-context",
2057 | "version": "3.0.0",
2058 | "source": {
2059 | "type": "git",
2060 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
2061 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
2062 | },
2063 | "dist": {
2064 | "type": "zip",
2065 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
2066 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
2067 | "shasum": ""
2068 | },
2069 | "require": {
2070 | "php": "^7.0"
2071 | },
2072 | "require-dev": {
2073 | "phpunit/phpunit": "^6.0"
2074 | },
2075 | "type": "library",
2076 | "extra": {
2077 | "branch-alias": {
2078 | "dev-master": "3.0.x-dev"
2079 | }
2080 | },
2081 | "autoload": {
2082 | "classmap": [
2083 | "src/"
2084 | ]
2085 | },
2086 | "notification-url": "https://packagist.org/downloads/",
2087 | "license": [
2088 | "BSD-3-Clause"
2089 | ],
2090 | "authors": [
2091 | {
2092 | "name": "Jeff Welch",
2093 | "email": "whatthejeff@gmail.com"
2094 | },
2095 | {
2096 | "name": "Sebastian Bergmann",
2097 | "email": "sebastian@phpunit.de"
2098 | },
2099 | {
2100 | "name": "Adam Harvey",
2101 | "email": "aharvey@php.net"
2102 | }
2103 | ],
2104 | "description": "Provides functionality to recursively process PHP variables",
2105 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
2106 | "time": "2017-03-03T06:23:57+00:00"
2107 | },
2108 | {
2109 | "name": "sebastian/resource-operations",
2110 | "version": "2.0.1",
2111 | "source": {
2112 | "type": "git",
2113 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
2114 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
2115 | },
2116 | "dist": {
2117 | "type": "zip",
2118 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
2119 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
2120 | "shasum": ""
2121 | },
2122 | "require": {
2123 | "php": "^7.1"
2124 | },
2125 | "type": "library",
2126 | "extra": {
2127 | "branch-alias": {
2128 | "dev-master": "2.0-dev"
2129 | }
2130 | },
2131 | "autoload": {
2132 | "classmap": [
2133 | "src/"
2134 | ]
2135 | },
2136 | "notification-url": "https://packagist.org/downloads/",
2137 | "license": [
2138 | "BSD-3-Clause"
2139 | ],
2140 | "authors": [
2141 | {
2142 | "name": "Sebastian Bergmann",
2143 | "email": "sebastian@phpunit.de"
2144 | }
2145 | ],
2146 | "description": "Provides a list of PHP built-in functions that operate on resources",
2147 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
2148 | "time": "2018-10-04T04:07:39+00:00"
2149 | },
2150 | {
2151 | "name": "sebastian/version",
2152 | "version": "2.0.1",
2153 | "source": {
2154 | "type": "git",
2155 | "url": "https://github.com/sebastianbergmann/version.git",
2156 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
2157 | },
2158 | "dist": {
2159 | "type": "zip",
2160 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
2161 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
2162 | "shasum": ""
2163 | },
2164 | "require": {
2165 | "php": ">=5.6"
2166 | },
2167 | "type": "library",
2168 | "extra": {
2169 | "branch-alias": {
2170 | "dev-master": "2.0.x-dev"
2171 | }
2172 | },
2173 | "autoload": {
2174 | "classmap": [
2175 | "src/"
2176 | ]
2177 | },
2178 | "notification-url": "https://packagist.org/downloads/",
2179 | "license": [
2180 | "BSD-3-Clause"
2181 | ],
2182 | "authors": [
2183 | {
2184 | "name": "Sebastian Bergmann",
2185 | "role": "lead",
2186 | "email": "sebastian@phpunit.de"
2187 | }
2188 | ],
2189 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
2190 | "homepage": "https://github.com/sebastianbergmann/version",
2191 | "time": "2016-10-03T07:35:21+00:00"
2192 | },
2193 | {
2194 | "name": "symfony/polyfill-ctype",
2195 | "version": "v1.12.0",
2196 | "source": {
2197 | "type": "git",
2198 | "url": "https://github.com/symfony/polyfill-ctype.git",
2199 | "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
2200 | },
2201 | "dist": {
2202 | "type": "zip",
2203 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
2204 | "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
2205 | "shasum": ""
2206 | },
2207 | "require": {
2208 | "php": ">=5.3.3"
2209 | },
2210 | "suggest": {
2211 | "ext-ctype": "For best performance"
2212 | },
2213 | "type": "library",
2214 | "extra": {
2215 | "branch-alias": {
2216 | "dev-master": "1.12-dev"
2217 | }
2218 | },
2219 | "autoload": {
2220 | "psr-4": {
2221 | "Symfony\\Polyfill\\Ctype\\": ""
2222 | },
2223 | "files": [
2224 | "bootstrap.php"
2225 | ]
2226 | },
2227 | "notification-url": "https://packagist.org/downloads/",
2228 | "license": [
2229 | "MIT"
2230 | ],
2231 | "authors": [
2232 | {
2233 | "name": "Gert de Pagter",
2234 | "email": "BackEndTea@gmail.com"
2235 | },
2236 | {
2237 | "name": "Symfony Community",
2238 | "homepage": "https://symfony.com/contributors"
2239 | }
2240 | ],
2241 | "description": "Symfony polyfill for ctype functions",
2242 | "homepage": "https://symfony.com",
2243 | "keywords": [
2244 | "compatibility",
2245 | "ctype",
2246 | "polyfill",
2247 | "portable"
2248 | ],
2249 | "time": "2019-08-06T08:03:45+00:00"
2250 | },
2251 | {
2252 | "name": "theseer/tokenizer",
2253 | "version": "1.1.3",
2254 | "source": {
2255 | "type": "git",
2256 | "url": "https://github.com/theseer/tokenizer.git",
2257 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
2258 | },
2259 | "dist": {
2260 | "type": "zip",
2261 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
2262 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
2263 | "shasum": ""
2264 | },
2265 | "require": {
2266 | "ext-dom": "*",
2267 | "ext-tokenizer": "*",
2268 | "ext-xmlwriter": "*",
2269 | "php": "^7.0"
2270 | },
2271 | "type": "library",
2272 | "autoload": {
2273 | "classmap": [
2274 | "src/"
2275 | ]
2276 | },
2277 | "notification-url": "https://packagist.org/downloads/",
2278 | "license": [
2279 | "BSD-3-Clause"
2280 | ],
2281 | "authors": [
2282 | {
2283 | "name": "Arne Blankerts",
2284 | "email": "arne@blankerts.de",
2285 | "role": "Developer"
2286 | }
2287 | ],
2288 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2289 | "time": "2019-06-13T22:48:21+00:00"
2290 | },
2291 | {
2292 | "name": "webmozart/assert",
2293 | "version": "1.4.0",
2294 | "source": {
2295 | "type": "git",
2296 | "url": "https://github.com/webmozart/assert.git",
2297 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
2298 | },
2299 | "dist": {
2300 | "type": "zip",
2301 | "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
2302 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
2303 | "shasum": ""
2304 | },
2305 | "require": {
2306 | "php": "^5.3.3 || ^7.0",
2307 | "symfony/polyfill-ctype": "^1.8"
2308 | },
2309 | "require-dev": {
2310 | "phpunit/phpunit": "^4.6",
2311 | "sebastian/version": "^1.0.1"
2312 | },
2313 | "type": "library",
2314 | "extra": {
2315 | "branch-alias": {
2316 | "dev-master": "1.3-dev"
2317 | }
2318 | },
2319 | "autoload": {
2320 | "psr-4": {
2321 | "Webmozart\\Assert\\": "src/"
2322 | }
2323 | },
2324 | "notification-url": "https://packagist.org/downloads/",
2325 | "license": [
2326 | "MIT"
2327 | ],
2328 | "authors": [
2329 | {
2330 | "name": "Bernhard Schussek",
2331 | "email": "bschussek@gmail.com"
2332 | }
2333 | ],
2334 | "description": "Assertions to validate method input/output with nice error messages.",
2335 | "keywords": [
2336 | "assert",
2337 | "check",
2338 | "validate"
2339 | ],
2340 | "time": "2018-12-25T11:19:39+00:00"
2341 | }
2342 | ],
2343 | "aliases": [],
2344 | "minimum-stability": "stable",
2345 | "stability-flags": [],
2346 | "prefer-stable": false,
2347 | "prefer-lowest": false,
2348 | "platform": [],
2349 | "platform-dev": []
2350 | }
2351 |
--------------------------------------------------------------------------------